refactor: loads of sensible renaming
This commit is contained in:
@@ -1,65 +1,15 @@
|
||||
.beat > * {
|
||||
padding-right: 1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.vertical-mode .beat > * {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.beat-unit-block {
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
.vertical-mode .beat-unit-block {
|
||||
height: auto;
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
.beat-title {
|
||||
width: 3em;
|
||||
line-height: 32px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.vertical-mode .beat-title {
|
||||
display: block;
|
||||
width: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.beat-spacer {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
.vertical-mode .beat-spacer {
|
||||
display: block;
|
||||
width: 2em;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.beat-main {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.vertical-mode .beat-main {
|
||||
width: 2em;
|
||||
margin-right: 4px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.beat-settings-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.beat {
|
||||
width: max-content;
|
||||
margin-bottom: 4px;
|
||||
padding: 1em;
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
width: inherit;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.vertical-mode .beat {
|
||||
display: inline-block;
|
||||
}
|
||||
height: inherit;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -1,177 +1,87 @@
|
||||
import UINode, {h, UINodeOptions} from "@/ui/UINode";
|
||||
import Beat, {BeatEvents} from "@/Beat";
|
||||
import ISubscriber from "@/Subscriber";
|
||||
import BeatUnitView from "@/ui/BeatUnit/BeatUnitView";
|
||||
import TrackView from "@/ui/Track/TrackView";
|
||||
import "./Beat.css";
|
||||
import ISubscriber from "@/Subscriber";
|
||||
import {ISubscription} from "@/Publisher";
|
||||
import Ref from "@/Ref";
|
||||
|
||||
export type BeatUINodeOptions = UINodeOptions & {
|
||||
title: string,
|
||||
beat: Beat,
|
||||
orientation?: "horizontal" | "vertical",
|
||||
};
|
||||
|
||||
const EventTypeSubscriptions = [
|
||||
BeatEvents.NewName,
|
||||
BeatEvents.NewTimeSig,
|
||||
BeatEvents.NewBarCount,
|
||||
BeatEvents.DisplayTypeChanged,
|
||||
BeatEvents.LoopLengthChanged,
|
||||
BeatEvents.TrackListChanged
|
||||
];
|
||||
|
||||
type EventTypeSubscriptions = FlatArray<typeof EventTypeSubscriptions, 1>;
|
||||
|
||||
export default class BeatView extends UINode implements ISubscriber<EventTypeSubscriptions> {
|
||||
private beat!: Beat;
|
||||
private title = new Ref<HTMLHeadingElement | null>(null);
|
||||
private beatUnitViews: BeatUnitView[] = [];
|
||||
private beatUnitViewBlock: HTMLElement | null = null;
|
||||
private lastHoveredBeatUnitView: BeatUnitView | null = null;
|
||||
private sub: ISubscription | null = null;
|
||||
static deselectingUnits = false;
|
||||
static selectingUnits = false;
|
||||
private title: string;
|
||||
private beat: Beat;
|
||||
private trackViews: TrackView[] = [];
|
||||
private currentOrientation: "vertical" | "horizontal";
|
||||
private subscription: ISubscription;
|
||||
|
||||
constructor(options: BeatUINodeOptions) {
|
||||
super(options);
|
||||
this.setBeat(options.beat);
|
||||
}
|
||||
|
||||
setBeat(beat: Beat | null): void {
|
||||
if (beat) {
|
||||
this.beat = beat;
|
||||
this.sub?.unbind();
|
||||
this.sub = this.beat.addSubscriber(this, EventTypeSubscriptions);
|
||||
this.redraw();
|
||||
} else {
|
||||
this.sub?.unbind();
|
||||
}
|
||||
this.beat = options.beat;
|
||||
this.title = options.title;
|
||||
this.currentOrientation = options.orientation ?? "horizontal";
|
||||
this.subscription = this.beat.addSubscriber(this, EventTypeSubscriptions);
|
||||
this.setupBeatViews();
|
||||
}
|
||||
|
||||
notify(publisher: unknown, event: EventTypeSubscriptions): void {
|
||||
switch (event) {
|
||||
case BeatEvents.NewName:
|
||||
this.title.val!.innerText = this.beat.getName();
|
||||
break;
|
||||
case BeatEvents.NewTimeSig:
|
||||
case BeatEvents.NewBarCount:
|
||||
case BeatEvents.DisplayTypeChanged:
|
||||
case BeatEvents.LoopLengthChanged:
|
||||
this.setupBeatUnits();
|
||||
break;
|
||||
if (event === BeatEvents.TrackListChanged) {
|
||||
this.setupBeatViews();
|
||||
this.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
private rebuildBeatUnitViews() {
|
||||
const beatUnitCount = this.beat.getBarCount() * this.beat.getTimeSigUp();
|
||||
for (let i = 0; i < beatUnitCount; i++) {
|
||||
const beatUnit = this.beat.getUnitByIndex(i);
|
||||
if (beatUnit) {
|
||||
let view: BeatUnitView;
|
||||
if (this.beatUnitViews[i]) {
|
||||
view = this.beatUnitViews[i];
|
||||
view.setUnit(beatUnit);
|
||||
} else {
|
||||
view = new BeatUnitView({beatUnit});
|
||||
this.beatUnitViews.push(view);
|
||||
view.onHover(() => this.onBeatViewHover(view));
|
||||
view.onMouseDown((event: MouseEvent) => this.onBeatUnitClick(event.button, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
const deadViews = this.beatUnitViews.splice(beatUnitCount, this.beatUnitViews.length - beatUnitCount);
|
||||
deadViews.forEach(beatUnitView => beatUnitView.setUnit(null));
|
||||
}
|
||||
|
||||
private onBeatUnitClick(button: number, index: number) {
|
||||
if (button === 0) {
|
||||
BeatView.selectingUnits = true;
|
||||
this.beat.getUnitByIndex(index)?.toggle();
|
||||
} else if (button === 2) {
|
||||
BeatView.deselectingUnits = true;
|
||||
this.beat.getUnitByIndex(index)?.setOn(false);
|
||||
}
|
||||
}
|
||||
|
||||
private onBeatViewHover(beatView: BeatUnitView) {
|
||||
this.lastHoveredBeatUnitView = beatView;
|
||||
if (BeatView.selectingUnits) {
|
||||
this.lastHoveredBeatUnitView.turnOn();
|
||||
} else if (BeatView.deselectingUnits) {
|
||||
this.lastHoveredBeatUnitView.turnOff();
|
||||
}
|
||||
}
|
||||
|
||||
private buildBeatUnitViewBlock(): void {
|
||||
const beatUnitNodes: HTMLElement[] = [];
|
||||
for (let i = 0; i < this.beatUnitViews.length; i++) {
|
||||
beatUnitNodes.push(this.beatUnitViews[i].render());
|
||||
}
|
||||
if (this.beatUnitViewBlock) {
|
||||
this.beatUnitViewBlock.replaceChildren(...beatUnitNodes);
|
||||
} else {
|
||||
this.beatUnitViewBlock = h("div", {
|
||||
classes: ["beat-unit-block"],
|
||||
}, [
|
||||
...beatUnitNodes
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private respaceBeatUnits(): void {
|
||||
if (!this.beatUnitViewBlock) {
|
||||
return;
|
||||
}
|
||||
this.beatUnitViewBlock.querySelectorAll(".beat-spacer").forEach(spacer => spacer.remove());
|
||||
const barLength = this.beat.getTimeSigUp();
|
||||
const barCount = this.beat.getBarCount();
|
||||
let bars = 0;
|
||||
let i = -1;
|
||||
let spacersInserted = false;
|
||||
while (!spacersInserted) {
|
||||
i += barLength;
|
||||
const newSpacer = h("div", {classes: ["beat-spacer"]});
|
||||
const leftNeighbour = this.beatUnitViewBlock.children.item(i);
|
||||
if (leftNeighbour) {
|
||||
leftNeighbour.insertAdjacentElement("afterend", newSpacer);
|
||||
private setupBeatViews(): void {
|
||||
const newCount = this.beat.getTrackCount();
|
||||
for (let i = 0; i < newCount; i++) {
|
||||
const beat = this.beat.getTrackByIndex(i);
|
||||
if (beat && this.trackViews[i]) {
|
||||
this.trackViews[i].setBeat(beat);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
bars++;
|
||||
if (bars === barCount) {
|
||||
spacersInserted = true;
|
||||
this.trackViews.push(new TrackView({track: this.beat.getTrackByIndex(i)}));
|
||||
}
|
||||
}
|
||||
const deadTrackViews = this.trackViews.splice(newCount, this.trackViews.length - newCount);
|
||||
deadTrackViews.forEach(beatView => beatView.setBeat(null));
|
||||
if (this.currentOrientation === "horizontal") {
|
||||
this.reverseDisplayOrder();
|
||||
}
|
||||
}
|
||||
|
||||
private setupBeatUnits(): void {
|
||||
this.rebuildBeatUnitViews();
|
||||
this.buildBeatUnitViewBlock();
|
||||
this.respaceBeatUnits();
|
||||
setOrientation(orientation: "vertical" | "horizontal"): void {
|
||||
if (this.currentOrientation !== orientation) {
|
||||
this.reverseDisplayOrder();
|
||||
this.currentOrientation = orientation;
|
||||
}
|
||||
}
|
||||
|
||||
build(): HTMLElement {
|
||||
this.setupBeatUnits();
|
||||
if (!this.beatUnitViewBlock) {
|
||||
throw new Error("Beat unit block setup failed!");
|
||||
}
|
||||
private reverseDisplayOrder(): void {
|
||||
this.trackViews.reverse();
|
||||
this.getNode().classList.toggle("vertical");
|
||||
this.redraw();
|
||||
}
|
||||
|
||||
setBeatGroup(newBeatGroup: Beat): void {
|
||||
this.beat = newBeatGroup;
|
||||
this.subscription.unbind();
|
||||
this.subscription = this.beat.addSubscriber(this, BeatEvents.TrackListChanged);
|
||||
this.setupBeatViews();
|
||||
this.redraw();
|
||||
}
|
||||
|
||||
build(): HTMLDivElement {
|
||||
return h("div", {
|
||||
classes: ["beat"],
|
||||
}, [
|
||||
h("div", {
|
||||
classes: ["beat-main"],
|
||||
}, [
|
||||
h("h3", {
|
||||
innerText: this.beat.getName(),
|
||||
saveTo: this.title,
|
||||
classes: ["beat-title"],
|
||||
}),
|
||||
this.beatUnitViewBlock,
|
||||
]),
|
||||
},[
|
||||
...this.trackViews
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("mouseup", () => {
|
||||
BeatView.selectingUnits = false;
|
||||
BeatView.deselectingUnits = false;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user