adding new states/tools
This commit is contained in:
@@ -8,6 +8,13 @@ export const enum TrackUnitType {
|
||||
GhostNoteAccent="tut-3",
|
||||
}
|
||||
|
||||
export type TrackUnitStickingType =
|
||||
| "none"
|
||||
| "lh"
|
||||
| "rh"
|
||||
| "lf"
|
||||
| "rf";
|
||||
|
||||
export const enum TrackUnitEvent {
|
||||
Toggle="tue-0",
|
||||
On="tue-1",
|
||||
@@ -15,7 +22,6 @@ export const enum TrackUnitEvent {
|
||||
TypeChange="tue-3",
|
||||
}
|
||||
|
||||
|
||||
export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
||||
private static readonly TypeRotation = [
|
||||
TrackUnitType.Normal,
|
||||
@@ -26,6 +32,7 @@ export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
||||
private publisher: Publisher<TrackUnitEvent, TrackUnit> = new Publisher<TrackUnitEvent, TrackUnit>(this);
|
||||
private on = false;
|
||||
private typeIndex = 0;
|
||||
private stickingType: TrackUnitStickingType = "none";
|
||||
private parent: Track;
|
||||
|
||||
constructor(options: {
|
||||
@@ -65,6 +72,17 @@ export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
||||
this.parent.alertDeepChange();
|
||||
}
|
||||
|
||||
setStickingType(type: TrackUnitStickingType) {
|
||||
console.log('set stickin');
|
||||
this.stickingType = type;
|
||||
this.publisher.notifySubs(TrackUnitEvent.TypeChange);
|
||||
this.parent.alertDeepChange();
|
||||
}
|
||||
|
||||
getStickingType() {
|
||||
return this.stickingType;
|
||||
}
|
||||
|
||||
getType(): TrackUnitType {
|
||||
return TrackUnit.TypeRotation[this.typeIndex];
|
||||
}
|
||||
@@ -86,5 +104,6 @@ export default class TrackUnit implements IPublisher<TrackUnitEvent> {
|
||||
mimic(trackUnit: TrackUnit): void {
|
||||
this.setOn(trackUnit.isOn());
|
||||
this.setType(trackUnit.getType());
|
||||
this.setStickingType(trackUnit.getStickingType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ import Beat, { BeatEvents } from "@/Beat";
|
||||
import TrackView from "@/ui/Track/TrackView";
|
||||
import "./Beat.css";
|
||||
import EditableTextFieldView from "@/ui/Widgets/EditableTextFIeld/EditableTextFieldView";
|
||||
import AppState from "@/AppState";
|
||||
|
||||
export type BeatUINodeOptions = RungOptions & {
|
||||
state: AppState,
|
||||
beat: Beat,
|
||||
orientation?: "horizontal" | "vertical",
|
||||
};
|
||||
@@ -21,9 +23,11 @@ export default class BeatView extends Rung<HTMLElement> implements ISubscriber<E
|
||||
private titles: HTMLHeadingElement[] = [];
|
||||
private currentOrientation: "vertical" | "horizontal";
|
||||
private subscription: ISubscription;
|
||||
private state: AppState;
|
||||
|
||||
constructor(options: BeatUINodeOptions) {
|
||||
super(options);
|
||||
this.state = options.state;
|
||||
this.beat = options.beat;
|
||||
this.currentOrientation = options.orientation ?? "horizontal";
|
||||
this.subscription = this.beat.addSubscriber(this, EventTypeSubscriptions);
|
||||
@@ -53,7 +57,7 @@ export default class BeatView extends Rung<HTMLElement> implements ISubscriber<E
|
||||
}
|
||||
this.trackViews[i].setTrack(track);
|
||||
} else {
|
||||
this.trackViews.push(new TrackView({ track: this.beat.getTrackByIndex(i) }));
|
||||
this.trackViews.push(new TrackView({ state: this.state, track: this.beat.getTrackByIndex(i) }));
|
||||
this.titles.push(this.trackViews[i].getTitleNode());
|
||||
this.titles[this.titles.length - 1].classList.add("beat-track-title");
|
||||
}
|
||||
|
||||
@@ -138,6 +138,23 @@
|
||||
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) {
|
||||
.sidebar-visible .root-sidebar {
|
||||
left: 0;
|
||||
|
||||
@@ -4,7 +4,9 @@ import "./Root.css";
|
||||
import BeatSettingsView from "@/ui/BeatSettings/BeatSettingsView";
|
||||
import IconView from "@/ui/Widgets/Icon/IconView";
|
||||
import BeatStore from "@/BeatStore";
|
||||
import { Capsule, h, frag, Rung, RungOptions, ICapsule } from "@djledda/ladder";
|
||||
import { Capsule, h, frag, Rung, RungOptions, ICapsule, ISubscriber } from "@djledda/ladder";
|
||||
import AppState from "@/AppState";
|
||||
import ToolboxView from "./ToolboxView";
|
||||
|
||||
export type RootUINodeOptions = RungOptions & {
|
||||
title: string,
|
||||
@@ -22,6 +24,8 @@ export default class RootView extends Rung<HTMLDivElement> {
|
||||
private showHideSidebarButton = Capsule.new<HTMLDivElement | null>(null);
|
||||
private sidebarActive = true;
|
||||
private sidebarLeftTabs = Capsule.new<HTMLDivElement | null>(null);
|
||||
private state = new AppState();
|
||||
private toolboxView: ToolboxView;
|
||||
|
||||
constructor(options: RootUINodeOptions) {
|
||||
super(options);
|
||||
@@ -29,6 +33,7 @@ export default class RootView extends Rung<HTMLDivElement> {
|
||||
loadFromLocalStorage: true,
|
||||
autoSave: true,
|
||||
});
|
||||
this.toolboxView = new ToolboxView({ state: this.state });
|
||||
this.activeBeat = this.beatStore.getActiveBeat();
|
||||
this.activeBeat.watch((newVal) => {
|
||||
this.beatSettingsView.setBeat(newVal);
|
||||
@@ -36,6 +41,7 @@ export default class RootView extends Rung<HTMLDivElement> {
|
||||
});
|
||||
this.currentOrientation = this.beatStore.getSavedOrientation() ?? options.orientation ?? "horizontal";
|
||||
this.beatView = new BeatView({
|
||||
state: this.state,
|
||||
beat: this.activeBeat.val,
|
||||
orientation: this.currentOrientation,
|
||||
});
|
||||
@@ -169,12 +175,14 @@ export default class RootView extends Rung<HTMLDivElement> {
|
||||
</div> as HTMLElement;
|
||||
};
|
||||
|
||||
|
||||
build() {
|
||||
return (
|
||||
<div classes={["root", "sidebar-visible"]}>
|
||||
<this.Sidebar/>
|
||||
<div className={"root-beat-stage-container"}>
|
||||
<div className={"root-beat-stage"}>
|
||||
{this.toolboxView}
|
||||
{this.beatView}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,10 @@ import Track, { TrackEvents } from "@/Track";
|
||||
import TrackUnitView from "@/ui/TrackUnit/TrackUnitView";
|
||||
import "./Track.css";
|
||||
import { Capsule, h, ISubscriber, ISubscription, Rung, RungOptions } from "@djledda/ladder";
|
||||
import AppState from "@/AppState";
|
||||
|
||||
export type TrackUINodeOptions = RungOptions & {
|
||||
state: AppState,
|
||||
track: Track,
|
||||
};
|
||||
|
||||
@@ -24,11 +26,13 @@ export default class TrackView extends Rung implements ISubscriber<EventTypeSubs
|
||||
private trackUnitViewBlock: HTMLElement | null = null;
|
||||
private lastHoveredTrackUnitView: TrackUnitView | null = null;
|
||||
private sub: ISubscription | null = null;
|
||||
private state: AppState;
|
||||
static deselectingUnits = false;
|
||||
static selectingUnits = false;
|
||||
|
||||
constructor(options: TrackUINodeOptions) {
|
||||
super(options);
|
||||
this.state = options.state;
|
||||
this.title = <h3></h3> as HTMLHeadingElement;
|
||||
this.setTrack(options.track);
|
||||
}
|
||||
@@ -89,18 +93,26 @@ export default class TrackView extends Rung implements ISubscriber<EventTypeSubs
|
||||
TrackView.selectingUnits = true;
|
||||
} else if (button === 2) {
|
||||
TrackView.deselectingUnits = true;
|
||||
this.track.getUnitByIndex(index)?.setOn(false);
|
||||
}
|
||||
}
|
||||
|
||||
private onTrackUnitViewHover(trackUnitView: TrackUnitView) {
|
||||
this.lastHoveredTrackUnitView = trackUnitView;
|
||||
if (TrackView.selectingUnits) {
|
||||
if (this.state.selectedTool === 'sticking') {
|
||||
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) {
|
||||
if (this.state.selectedTool === 'sticking') {
|
||||
this.lastHoveredTrackUnitView.setStickingType("none");
|
||||
} else if (this.state.selectedTool === 'track-unit-type') {
|
||||
this.lastHoveredTrackUnitView.turnOff();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private buildTrackUnitViewBlock(): void {
|
||||
const trackUnitNodes: HTMLElement[] = [];
|
||||
|
||||
@@ -40,3 +40,16 @@
|
||||
.track-unit.track-unit-on.track-unit-ghost {
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
.track-unit.track-unit-on.track-unit-lh {
|
||||
content: 'hello';
|
||||
}
|
||||
.track-unit.track-unit-on.track-unit-lf {
|
||||
content: 'world';
|
||||
}
|
||||
.track-unit.track-unit-on.track-unit-rh {
|
||||
content: 'world2';
|
||||
}
|
||||
.track-unit.track-unit-on.track-unit-rf {
|
||||
content: 'world';
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import TrackUnit, { TrackUnitEvent, TrackUnitType } from "@/TrackUnit";
|
||||
import TrackUnit, { TrackUnitEvent, TrackUnitStickingType, TrackUnitType } from "@/TrackUnit";
|
||||
import "./TrackUnit.css";
|
||||
import { h, IPublisher, ISubscriber, ISubscription, Publisher, Rung, RungOptions } from "@djledda/ladder";
|
||||
|
||||
@@ -57,8 +57,7 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
||||
private handleMouseDown(ev: MouseEvent): void {
|
||||
if (ev.button === 1) {
|
||||
this.trackUnit.rotateType();
|
||||
} else if (ev.button === 0) {
|
||||
this.toggle();
|
||||
} else {
|
||||
this.rotationTimeout = this.rotationTimeout || setTimeout(() => {
|
||||
this.trackUnit.rotateType();
|
||||
this.blockNextMouseUp = true;
|
||||
@@ -103,6 +102,14 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
||||
this.trackUnit.toggle();
|
||||
}
|
||||
|
||||
setStickingType(type: TrackUnitStickingType): void {
|
||||
this.trackUnit.setStickingType(type);
|
||||
}
|
||||
|
||||
setType(type: TrackUnitType): void {
|
||||
this.trackUnit.setType(type);
|
||||
}
|
||||
|
||||
turnOn(): void {
|
||||
this.trackUnit.setOn(true);
|
||||
}
|
||||
@@ -120,6 +127,23 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
||||
this.render().classList.remove("track-unit-on");
|
||||
break;
|
||||
case TrackUnitEvent.TypeChange:
|
||||
this.syncTrackUnitType();
|
||||
this.syncStickingType(this.trackUnit.getStickingType());
|
||||
}
|
||||
}
|
||||
|
||||
private syncStickingType(type: TrackUnitStickingType) {
|
||||
const node = this.render();
|
||||
node.classList.remove("track-unit-lh");
|
||||
node.classList.remove("track-unit-rh");
|
||||
node.classList.remove("track-unit-lf");
|
||||
node.classList.remove("track-unit-rf");
|
||||
if (type !== "none") {
|
||||
node.classList.add(`track-unit-${ type }`);
|
||||
}
|
||||
}
|
||||
|
||||
private syncTrackUnitType() {
|
||||
switch (this.trackUnit.getType()) {
|
||||
case TrackUnitType.Normal:
|
||||
this.render().classList.remove("track-unit-ghost");
|
||||
@@ -138,8 +162,6 @@ export default class TrackUnitView extends Rung<HTMLElement> implements ISubscri
|
||||
this.render().classList.add("track-unit-accent");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
build(): HTMLElement {
|
||||
|
||||
Reference in New Issue
Block a user