feat: finished adding painting features, added eraser
This commit is contained in:
690
package-lock.json
generated
690
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@
|
|||||||
"@typescript-eslint/parser": "^5.26.0",
|
"@typescript-eslint/parser": "^5.26.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"eslint": "^8.16.0",
|
"eslint": "^8.16.0",
|
||||||
"typescript": "^4.7.2",
|
"typescript": "^4.9.4",
|
||||||
"vite": "^2.9.9"
|
"vite": "^3.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,11 @@
|
|||||||
import Track from "@/Track";
|
import Track from "@/Track";
|
||||||
import { IPublisher, ISubscriber, Publisher } from "@djledda/ladder";
|
import { IPublisher, ISubscriber, Publisher } from "@djledda/ladder";
|
||||||
|
|
||||||
export const enum TrackUnitType {
|
export const TrackUnitTypeList = [ "Normal", "GhostNote", "Accent", "GhostNoteAccent" ] as const;
|
||||||
Normal="tut-0",
|
export type TrackUnitType = typeof TrackUnitTypeList[number];
|
||||||
GhostNote="tut-1",
|
|
||||||
Accent="tut-2",
|
|
||||||
GhostNoteAccent="tut-3",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TrackUnitStickingType =
|
export const TrackUnitStickingTypeList = [ "none", "lh", "rh", "lf", "rf" ] as const;
|
||||||
| "none"
|
export type TrackUnitStickingType = typeof TrackUnitStickingTypeList[number];
|
||||||
| "lh"
|
|
||||||
| "rh"
|
|
||||||
| "lf"
|
|
||||||
| "rf";
|
|
||||||
|
|
||||||
export const enum TrackUnitEvent {
|
export const enum TrackUnitEvent {
|
||||||
Toggle="tue-0",
|
Toggle="tue-0",
|
||||||
@@ -23,12 +15,6 @@ export const enum TrackUnitEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
||||||
private static readonly TypeRotation = [
|
|
||||||
TrackUnitType.Normal,
|
|
||||||
TrackUnitType.GhostNote,
|
|
||||||
TrackUnitType.Accent,
|
|
||||||
TrackUnitType.GhostNoteAccent,
|
|
||||||
] as const;
|
|
||||||
private publisher: Publisher<TrackUnitEvent, TrackUnit> = new Publisher<TrackUnitEvent, TrackUnit>(this);
|
private publisher: Publisher<TrackUnitEvent, TrackUnit> = new Publisher<TrackUnitEvent, TrackUnit>(this);
|
||||||
private on = false;
|
private on = false;
|
||||||
private typeIndex = 0;
|
private typeIndex = 0;
|
||||||
@@ -42,7 +28,7 @@ export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
|||||||
}) {
|
}) {
|
||||||
this.parent = options.parent;
|
this.parent = options.parent;
|
||||||
this.on = options.on ?? false;
|
this.on = options.on ?? false;
|
||||||
this.setType(options.type ?? TrackUnitType.Normal);
|
this.setType(options.type ?? "Normal");
|
||||||
}
|
}
|
||||||
|
|
||||||
addSubscriber(subscriber: ISubscriber<TrackUnitEvent>, eventType: TrackUnitEvent[]): { unbind: () => void } {
|
addSubscriber(subscriber: ISubscriber<TrackUnitEvent>, eventType: TrackUnitEvent[]): { unbind: () => void } {
|
||||||
@@ -67,13 +53,12 @@ export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setType(type: TrackUnitType): void {
|
setType(type: TrackUnitType): void {
|
||||||
this.typeIndex = TrackUnit.TypeRotation.indexOf(type);
|
this.typeIndex = TrackUnitTypeList.indexOf(type);
|
||||||
this.publisher.notifySubs(TrackUnitEvent.TypeChange);
|
this.publisher.notifySubs(TrackUnitEvent.TypeChange);
|
||||||
this.parent.alertDeepChange();
|
this.parent.alertDeepChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
setStickingType(type: TrackUnitStickingType) {
|
setStickingType(type: TrackUnitStickingType) {
|
||||||
console.log('set stickin');
|
|
||||||
this.stickingType = type;
|
this.stickingType = type;
|
||||||
this.publisher.notifySubs(TrackUnitEvent.TypeChange);
|
this.publisher.notifySubs(TrackUnitEvent.TypeChange);
|
||||||
this.parent.alertDeepChange();
|
this.parent.alertDeepChange();
|
||||||
@@ -84,11 +69,11 @@ export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getType(): TrackUnitType {
|
getType(): TrackUnitType {
|
||||||
return TrackUnit.TypeRotation[this.typeIndex];
|
return TrackUnitTypeList[this.typeIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
rotateType(): void {
|
rotateType(): void {
|
||||||
if (this.typeIndex === TrackUnit.TypeRotation.length - 1) {
|
if (this.typeIndex === TrackUnitTypeList.length - 1) {
|
||||||
this.typeIndex = 0;
|
this.typeIndex = 0;
|
||||||
} else {
|
} else {
|
||||||
this.typeIndex += 1;
|
this.typeIndex += 1;
|
||||||
|
|||||||
@@ -138,23 +138,6 @@
|
|||||||
transition: background-color 200ms;
|
transition: background-color 200ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.root-toolbox {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.root-toolbox .toolbox-button {
|
|
||||||
padding: 1em;
|
|
||||||
cursor: pointer;
|
|
||||||
color: black;
|
|
||||||
background-color: var(--color-ui-neutral-dark);
|
|
||||||
}
|
|
||||||
.root-toolbox .toolbox-button:hover {
|
|
||||||
background-color: var(--color-ui-neutral-dark-hover);
|
|
||||||
}
|
|
||||||
.root-toolbox .toolbox-button.active {
|
|
||||||
background-color: var(--color-ui-neutral-dark-active);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 900px) {
|
@media screen and (max-width: 900px) {
|
||||||
.sidebar-visible .root-sidebar {
|
.sidebar-visible .root-sidebar {
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -181,8 +181,8 @@ export default class RootView extends Rung<HTMLDivElement> {
|
|||||||
<div classes={["root", "sidebar-visible"]}>
|
<div classes={["root", "sidebar-visible"]}>
|
||||||
<this.Sidebar/>
|
<this.Sidebar/>
|
||||||
<div className={"root-beat-stage-container"}>
|
<div className={"root-beat-stage-container"}>
|
||||||
<div className={"root-beat-stage"}>
|
|
||||||
{this.toolboxView}
|
{this.toolboxView}
|
||||||
|
<div className={"root-beat-stage"}>
|
||||||
{this.beatView}
|
{this.beatView}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export default class TrackView extends Rung implements ISubscriber<EventTypeSubs
|
|||||||
private title: HTMLHeadingElement;
|
private title: HTMLHeadingElement;
|
||||||
private trackUnitViews: TrackUnitView[] = [];
|
private trackUnitViews: TrackUnitView[] = [];
|
||||||
private trackUnitViewBlock: HTMLElement | null = null;
|
private trackUnitViewBlock: HTMLElement | null = null;
|
||||||
private lastHoveredTrackUnitView: TrackUnitView | null = null;
|
|
||||||
private sub: ISubscription | null = null;
|
private sub: ISubscription | null = null;
|
||||||
private state: AppState;
|
private state: AppState;
|
||||||
static deselectingUnits = false;
|
static deselectingUnits = false;
|
||||||
@@ -79,8 +78,8 @@ export default class TrackView extends Rung implements ISubscriber<EventTypeSubs
|
|||||||
} else {
|
} else {
|
||||||
view = new TrackUnitView({ trackUnit });
|
view = new TrackUnitView({ trackUnit });
|
||||||
this.trackUnitViews.push(view);
|
this.trackUnitViews.push(view);
|
||||||
view.onHover(() => this.onTrackUnitViewHover(view));
|
view.onHover(() => this.applyCurrentToolToTrackUnit(view));
|
||||||
view.onMouseDown((event: MouseEvent) => this.onTrackUnitClick(event.button, i));
|
view.onMouseDown((event: MouseEvent) => this.onTrackUnitClick(event.button, view));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,28 +87,32 @@ export default class TrackView extends Rung implements ISubscriber<EventTypeSubs
|
|||||||
deadViews.forEach(trackUnitView => trackUnitView.setUnit(null));
|
deadViews.forEach(trackUnitView => trackUnitView.setUnit(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private onTrackUnitClick(button: number, index: number) {
|
private onTrackUnitClick(button: number, view: TrackUnitView) {
|
||||||
if (button === 0) {
|
if (button === 0) {
|
||||||
TrackView.selectingUnits = true;
|
TrackView.selectingUnits = true;
|
||||||
} else if (button === 2) {
|
} else if (button === 2) {
|
||||||
TrackView.deselectingUnits = true;
|
TrackView.deselectingUnits = true;
|
||||||
}
|
}
|
||||||
|
this.applyCurrentToolToTrackUnit(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onTrackUnitViewHover(trackUnitView: TrackUnitView) {
|
private applyCurrentToolToTrackUnit(trackUnitView: TrackUnitView) {
|
||||||
this.lastHoveredTrackUnitView = trackUnitView;
|
if (this.state.selectedTool === "sticking") {
|
||||||
if (TrackView.selectingUnits) {
|
if (TrackView.selectingUnits) {
|
||||||
if (this.state.selectedTool === 'sticking') {
|
trackUnitView.setStickingType(this.state.activeStickingType);
|
||||||
this.lastHoveredTrackUnitView.setStickingType(this.state.activeStickingType);
|
|
||||||
} else if (this.state.selectedTool === 'track-unit-type') {
|
|
||||||
this.lastHoveredTrackUnitView.turnOn();
|
|
||||||
this.lastHoveredTrackUnitView.setType(this.state.activeTrackUnitType);
|
|
||||||
}
|
|
||||||
} else if (TrackView.deselectingUnits) {
|
} else if (TrackView.deselectingUnits) {
|
||||||
if (this.state.selectedTool === 'sticking') {
|
trackUnitView.setStickingType("none");
|
||||||
this.lastHoveredTrackUnitView.setStickingType("none");
|
}
|
||||||
} else if (this.state.selectedTool === 'track-unit-type') {
|
} else if (this.state.selectedTool === "track-unit-type") {
|
||||||
this.lastHoveredTrackUnitView.turnOff();
|
if (TrackView.selectingUnits) {
|
||||||
|
trackUnitView.turnOn();
|
||||||
|
trackUnitView.setType(this.state.activeTrackUnitType);
|
||||||
|
} else if (TrackView.deselectingUnits) {
|
||||||
|
trackUnitView.turnOff();
|
||||||
|
}
|
||||||
|
} else if (this.state.selectedTool === "eraser") {
|
||||||
|
if (TrackView.selectingUnits || TrackView.deselectingUnits) {
|
||||||
|
trackUnitView.turnOff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-unit:hover {
|
.track-unit.highlightable:hover {
|
||||||
border-color: #5f5f5f;
|
border-color: #5f5f5f;
|
||||||
background-color: #5f5f5f;
|
background-color: #5f5f5f;
|
||||||
transition: none;
|
transition: none;
|
||||||
@@ -22,34 +22,28 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-unit.track-unit-on {
|
.track-unit.on {
|
||||||
border-color: var(--color-ui-accent);
|
border-color: var(--color-ui-accent);
|
||||||
background-color: var(--color-ui-accent);
|
background-color: var(--color-ui-accent);
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-unit.track-unit-on:hover {
|
.track-unit.on.highlightable:hover {
|
||||||
border-color: var(--color-ui-accent-hover);
|
border-color: var(--color-ui-accent-hover);
|
||||||
background-color: var(--color-ui-accent-hover);
|
background-color: var(--color-ui-accent-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-unit.track-unit-on.track-unit-accent {
|
.track-unit.on.Accent {
|
||||||
border-color: var(--color-ui-neutral-light);
|
border-color: var(--color-ui-neutral-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-unit.track-unit-on.track-unit-ghost {
|
.track-unit.on.Ghost {
|
||||||
opacity: 60%;
|
opacity: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-unit.track-unit-on.track-unit-lh {
|
.track-unit .icon-view {
|
||||||
content: 'hello';
|
display: none;
|
||||||
}
|
}
|
||||||
.track-unit.track-unit-on.track-unit-lf {
|
.track-unit.on.icon-visible .icon-view {
|
||||||
content: 'world';
|
display: block;
|
||||||
}
|
|
||||||
.track-unit.track-unit-on.track-unit-rh {
|
|
||||||
content: 'world2';
|
|
||||||
}
|
|
||||||
.track-unit.track-unit-on.track-unit-rf {
|
|
||||||
content: 'world';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import TrackUnit, { TrackUnitEvent, TrackUnitStickingType, TrackUnitType } from "@/TrackUnit";
|
import TrackUnit, { TrackUnitEvent, TrackUnitStickingType, TrackUnitType } from "@/TrackUnit";
|
||||||
import "./TrackUnit.css";
|
import "./TrackUnit.css";
|
||||||
import { h, IPublisher, ISubscriber, ISubscription, Publisher, Rung, RungOptions } from "@djledda/ladder";
|
import { Capsule, h, IPublisher, ISubscriber, ISubscription, Publisher, Rung, RungOptions } from "@djledda/ladder";
|
||||||
|
import IconView, { IconName } from "@/ui/Widgets/Icon/IconView";
|
||||||
|
|
||||||
export type TrackUnitUINodeOptions = RungOptions & {
|
export type TrackUnitUINodeOptions = RungOptions & {
|
||||||
trackUnit: TrackUnit,
|
trackUnit: TrackUnit,
|
||||||
@@ -13,7 +14,23 @@ const EventTypeSubscriptions = [
|
|||||||
];
|
];
|
||||||
type EventTypeSubscriptions = typeof EventTypeSubscriptions[number];
|
type EventTypeSubscriptions = typeof EventTypeSubscriptions[number];
|
||||||
|
|
||||||
export default class TrackUnitView extends Rung<HTMLElement> implements ISubscriber<EventTypeSubscriptions> {
|
export const StickingTypeIconMap = {
|
||||||
|
none: null,
|
||||||
|
lf: 'lf',
|
||||||
|
lh: 'lh',
|
||||||
|
rf: 'rf',
|
||||||
|
rh: 'rh',
|
||||||
|
} as const satisfies Readonly<Record<TrackUnitStickingType, IconName | null>>;
|
||||||
|
|
||||||
|
const TypeClasses = [ "Ghost", "Accent" ] as const;
|
||||||
|
export const TrackUnitTypeClassMap = {
|
||||||
|
"Normal": [],
|
||||||
|
"GhostNote": ["Ghost"],
|
||||||
|
"Accent": ["Accent"],
|
||||||
|
"GhostNoteAccent": ["Ghost", "Accent"],
|
||||||
|
} as const satisfies Readonly<Record<TrackUnitType, Readonly<string[]>>>;
|
||||||
|
|
||||||
|
export default class TrackUnitView extends Rung<HTMLDivElement> implements ISubscriber<EventTypeSubscriptions> {
|
||||||
private trackUnit: TrackUnit;
|
private trackUnit: TrackUnit;
|
||||||
private subscription: ISubscription | null = null;
|
private subscription: ISubscription | null = null;
|
||||||
private publisher: IPublisher<TrackUnitEvent> = new Publisher<TrackUnitEvent, TrackUnitView>(this);
|
private publisher: IPublisher<TrackUnitEvent> = new Publisher<TrackUnitEvent, TrackUnitView>(this);
|
||||||
@@ -21,6 +38,7 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
|||||||
private mouseDownListeners: ((ev: MouseEvent) => void)[] = [];
|
private mouseDownListeners: ((ev: MouseEvent) => void)[] = [];
|
||||||
private hoverListeners: ((ev: MouseEvent) => void)[] = [];
|
private hoverListeners: ((ev: MouseEvent) => void)[] = [];
|
||||||
private blockNextMouseUp = false;
|
private blockNextMouseUp = false;
|
||||||
|
private icon: IconView = new IconView({ iconName: 'list' });
|
||||||
|
|
||||||
constructor(options: TrackUnitUINodeOptions) {
|
constructor(options: TrackUnitUINodeOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
@@ -57,12 +75,6 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
|||||||
private handleMouseDown(ev: MouseEvent): void {
|
private handleMouseDown(ev: MouseEvent): void {
|
||||||
if (ev.button === 1) {
|
if (ev.button === 1) {
|
||||||
this.trackUnit.rotateType();
|
this.trackUnit.rotateType();
|
||||||
} else {
|
|
||||||
this.rotationTimeout = this.rotationTimeout || setTimeout(() => {
|
|
||||||
this.trackUnit.rotateType();
|
|
||||||
this.blockNextMouseUp = true;
|
|
||||||
this.rotationTimeout = null;
|
|
||||||
}, 400);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +86,6 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
|||||||
}
|
}
|
||||||
|
|
||||||
private handleMouseUp(ev: MouseEvent): void {
|
private handleMouseUp(ev: MouseEvent): void {
|
||||||
if (this.rotationTimeout) {
|
|
||||||
clearTimeout(this.rotationTimeout);
|
|
||||||
this.rotationTimeout = null;
|
|
||||||
}
|
|
||||||
if (!this.blockNextMouseUp) {
|
if (!this.blockNextMouseUp) {
|
||||||
this.mouseDownListeners.forEach(listener => listener(ev));
|
this.mouseDownListeners.forEach(listener => listener(ev));
|
||||||
}
|
}
|
||||||
@@ -103,8 +111,10 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
|||||||
}
|
}
|
||||||
|
|
||||||
setStickingType(type: TrackUnitStickingType): void {
|
setStickingType(type: TrackUnitStickingType): void {
|
||||||
|
if (this.trackUnit.isOn()) {
|
||||||
this.trackUnit.setStickingType(type);
|
this.trackUnit.setStickingType(type);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setType(type: TrackUnitType): void {
|
setType(type: TrackUnitType): void {
|
||||||
this.trackUnit.setType(type);
|
this.trackUnit.setType(type);
|
||||||
@@ -115,16 +125,17 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
|||||||
}
|
}
|
||||||
|
|
||||||
turnOff(): void {
|
turnOff(): void {
|
||||||
|
this.trackUnit.setStickingType("none");
|
||||||
this.trackUnit.setOn(false);
|
this.trackUnit.setOn(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
notify(publisher: unknown, event: EventTypeSubscriptions): void {
|
notify(publisher: unknown, event: EventTypeSubscriptions): void {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case TrackUnitEvent.On:
|
case TrackUnitEvent.On:
|
||||||
this.render().classList.add("track-unit-on");
|
this.render().classList.add("on");
|
||||||
break;
|
break;
|
||||||
case TrackUnitEvent.Off:
|
case TrackUnitEvent.Off:
|
||||||
this.render().classList.remove("track-unit-on");
|
this.render().classList.remove("on");
|
||||||
break;
|
break;
|
||||||
case TrackUnitEvent.TypeChange:
|
case TrackUnitEvent.TypeChange:
|
||||||
this.syncTrackUnitType();
|
this.syncTrackUnitType();
|
||||||
@@ -133,43 +144,55 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
|||||||
}
|
}
|
||||||
|
|
||||||
private syncStickingType(type: TrackUnitStickingType) {
|
private syncStickingType(type: TrackUnitStickingType) {
|
||||||
const node = this.render();
|
if (StickingTypeIconMap[this.trackUnit.getStickingType()]) {
|
||||||
node.classList.remove("track-unit-lh");
|
this.render().classList.add("icon-visible");
|
||||||
node.classList.remove("track-unit-rh");
|
} else {
|
||||||
node.classList.remove("track-unit-lf");
|
this.render().classList.remove("icon-visible");
|
||||||
node.classList.remove("track-unit-rf");
|
}
|
||||||
if (type !== "none") {
|
const icon = StickingTypeIconMap[this.trackUnit.getStickingType()];
|
||||||
node.classList.add(`track-unit-${ type }`);
|
if (icon) {
|
||||||
|
this.icon.setIcon(icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private syncTrackUnitType() {
|
private syncTrackUnitType() {
|
||||||
switch (this.trackUnit.getType()) {
|
for (const className of TypeClasses) {
|
||||||
case TrackUnitType.Normal:
|
this.render().classList.remove(className);
|
||||||
this.render().classList.remove("track-unit-ghost");
|
}
|
||||||
this.render().classList.remove("track-unit-accent");
|
for (const className of TrackUnitTypeClassMap[this.trackUnit.getType()]) {
|
||||||
break;
|
this.render().classList.add(className);
|
||||||
case TrackUnitType.GhostNote:
|
|
||||||
this.render().classList.add("track-unit-ghost");
|
|
||||||
this.render().classList.remove("track-unit-accent");
|
|
||||||
break;
|
|
||||||
case TrackUnitType.Accent:
|
|
||||||
this.render().classList.remove("track-unit-ghost");
|
|
||||||
this.render().classList.add("track-unit-accent");
|
|
||||||
break;
|
|
||||||
case TrackUnitType.GhostNoteAccent:
|
|
||||||
this.render().classList.add("track-unit-ghost");
|
|
||||||
this.render().classList.add("track-unit-accent");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build(): HTMLElement {
|
static getClasses(options: { on: boolean, stickingType: TrackUnitStickingType, type: TrackUnitType, highlightable?: boolean }) {
|
||||||
const classes = ["track-unit"];
|
const classes = ["track-unit"];
|
||||||
if (this.trackUnit.isOn()) {
|
if (options.on) {
|
||||||
classes.push("track-unit-on");
|
classes.push("on");
|
||||||
}
|
}
|
||||||
return <div classes={classes} oncontextmenu={() => false} /> as HTMLElement;
|
if (StickingTypeIconMap[options.stickingType]) {
|
||||||
|
classes.push("icon-visible");
|
||||||
|
}
|
||||||
|
if (options.type) {
|
||||||
|
classes.push(...TrackUnitTypeClassMap[options.type]);
|
||||||
|
}
|
||||||
|
if (options.highlightable) {
|
||||||
|
classes.push("highlightable");
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
const classes = TrackUnitView.getClasses({
|
||||||
|
on: this.trackUnit.isOn(),
|
||||||
|
stickingType: this.trackUnit.getStickingType(),
|
||||||
|
type: this.trackUnit.getType(),
|
||||||
|
highlightable: true,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div classes={classes} oncontextmenu={() => false}>
|
||||||
|
{this.icon}
|
||||||
|
</div>
|
||||||
|
) as HTMLDivElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
onHover(cb: () => void): void {
|
onHover(cb: () => void): void {
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
|
import { h, Rung, RungOptions } from "@djledda/ladder";
|
||||||
import "./Icon.css";
|
import "./Icon.css";
|
||||||
|
|
||||||
import List from "assets/svgs/list.svg";
|
import List from "assets/svgs/list.svg";
|
||||||
import ArrowClockwise from "assets/svgs/arrow-clockwise.svg";
|
import ArrowClockwise from "assets/svgs/arrow-clockwise.svg";
|
||||||
import Trash from "assets/svgs/trash.svg";
|
import Trash from "assets/svgs/trash.svg";
|
||||||
import Snowflake from "assets/svgs/snowflake.svg";
|
import Snowflake from "assets/svgs/snowflake.svg";
|
||||||
import { h, Rung, RungOptions } from "@djledda/ladder";
|
import LeftHand from "assets/svgs/LH.png";
|
||||||
|
import RightHand from "assets/svgs/RH.png";
|
||||||
|
import LeftFoot from "assets/svgs/LF.png";
|
||||||
|
import RightFoot from "assets/svgs/RF.png";
|
||||||
|
|
||||||
const IconUrlMap = {
|
const IconUrlMap = {
|
||||||
arrowClockwise: ArrowClockwise,
|
arrowClockwise: ArrowClockwise,
|
||||||
list: List,
|
list: List,
|
||||||
trash: Trash,
|
trash: Trash,
|
||||||
snowflake: Snowflake,
|
snowflake: Snowflake,
|
||||||
|
lh: LeftHand,
|
||||||
|
rh: RightHand,
|
||||||
|
lf: LeftFoot,
|
||||||
|
rf: RightFoot,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type IconName = keyof typeof IconUrlMap;
|
export type IconName = keyof typeof IconUrlMap;
|
||||||
@@ -19,7 +28,7 @@ export type IconViewOptions = RungOptions & {
|
|||||||
color?: string,
|
color?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class IconView extends Rung {
|
export default class IconView extends Rung<HTMLDivElement> {
|
||||||
private iconUrl: string;
|
private iconUrl: string;
|
||||||
private color: string | null;
|
private color: string | null;
|
||||||
|
|
||||||
@@ -29,10 +38,19 @@ export default class IconView extends Rung {
|
|||||||
this.iconUrl = IconUrlMap[options.iconName];
|
this.iconUrl = IconUrlMap[options.iconName];
|
||||||
}
|
}
|
||||||
|
|
||||||
build(): HTMLSpanElement {
|
setIcon(name: IconName) {
|
||||||
const icon = <div className={"icon-view"} /> as HTMLDivElement;
|
this.iconUrl = IconUrlMap[name];
|
||||||
|
this.render().style.cssText = this.cssText();
|
||||||
|
}
|
||||||
|
|
||||||
|
cssText() {
|
||||||
const colorString = this.color ? `--icon-bg:${this.color}` : "";
|
const colorString = this.color ? `--icon-bg:${this.color}` : "";
|
||||||
icon.style.cssText = `-webkit-mask-image: url(${this.iconUrl}); mask-image: url(${this.iconUrl});${colorString}`;
|
return `-webkit-mask-image: url(${this.iconUrl}); mask-image: url(${this.iconUrl});${colorString ?? ''}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
const icon = <div className={"icon-view"} /> as HTMLDivElement;
|
||||||
|
icon.style.cssText = this.cssText();
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user