feat: better styling, add new track
This commit is contained in:
@@ -65,7 +65,7 @@ button:focus {
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background-color: rgba(0,0,0,0.25);
|
background-color: rgba(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ type BeatGroupInitOptions = {
|
|||||||
barCount: number;
|
barCount: number;
|
||||||
isLooping: boolean;
|
isLooping: boolean;
|
||||||
timeSigUp: number;
|
timeSigUp: number;
|
||||||
beats: BeatInitOptions[],
|
beats?: BeatInitOptions[],
|
||||||
loopLength?: number,
|
loopLength?: number,
|
||||||
forceFullBars?: boolean,
|
forceFullBars?: boolean,
|
||||||
useAutoBeatLength?: boolean,
|
useAutoBeatLength?: boolean,
|
||||||
}
|
};
|
||||||
|
|
||||||
export const enum BeatGroupEvents {
|
export const enum BeatGroupEvents {
|
||||||
BeatOrderChanged="BGE0",
|
BeatOrderChanged="BGE0",
|
||||||
@@ -206,6 +206,16 @@ export default class BeatGroup implements IPublisher<BeatGroupEvents | BeatEvent
|
|||||||
}
|
}
|
||||||
|
|
||||||
addBeat(options?: BeatInitOptions): Beat {
|
addBeat(options?: BeatInitOptions): Beat {
|
||||||
|
options = {
|
||||||
|
timeSig: {
|
||||||
|
up: this.timeSigUp,
|
||||||
|
down: 4,
|
||||||
|
},
|
||||||
|
bars: this.barCount,
|
||||||
|
isLooping: this.globalIsLooping,
|
||||||
|
loopLength: this.globalLoopLength,
|
||||||
|
...options
|
||||||
|
};
|
||||||
const newBeat = new Beat(options);
|
const newBeat = new Beat(options);
|
||||||
this.beats.push(newBeat);
|
this.beats.push(newBeat);
|
||||||
this.beatKeyMap[newBeat.getKey()] = this.beats.length;
|
this.beatKeyMap[newBeat.getKey()] = this.beats.length;
|
||||||
|
|||||||
10
src/main.ts
10
src/main.ts
@@ -3,14 +3,12 @@ import BeatGroup from "./BeatGroup";
|
|||||||
import RootView from "./ui/Root/RootView";
|
import RootView from "./ui/Root/RootView";
|
||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
bars: 10,
|
barCount: 2,
|
||||||
timeSig: {
|
isLooping: false,
|
||||||
down: 4,
|
timeSigUp: 8,
|
||||||
up: 4,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const mainBeatGroup = new BeatGroup();
|
const mainBeatGroup = new BeatGroup(defaultSettings);
|
||||||
mainBeatGroup.addBeat({
|
mainBeatGroup.addBeat({
|
||||||
name: "LF"
|
name: "LF"
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ export default class BeatUnitView extends UINode implements ISubscriber {
|
|||||||
this.subscription.unbind();
|
this.subscription.unbind();
|
||||||
this.beatUnit = beatUnit;
|
this.beatUnit = beatUnit;
|
||||||
this.setupBindings();
|
this.setupBindings();
|
||||||
this.rebuild();
|
|
||||||
this.redraw();
|
this.redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
.beat-group {
|
.beat-group {
|
||||||
|
padding: 1em;
|
||||||
|
overflow-x: scroll;
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
import UINode, {UINodeOptions} from "../UINode";
|
import UINode, {UINodeOptions} from "../UINode";
|
||||||
import BeatGroup from "../../BeatGroup";
|
import BeatGroup, {BeatGroupEvents} from "../../BeatGroup";
|
||||||
import BeatView from "./Beat/BeatView";
|
import BeatView from "./Beat/BeatView";
|
||||||
|
import "./BeatGroup.css";
|
||||||
|
import ISubscriber from "../../Subscriber";
|
||||||
|
import {IPublisher} from "../../Publisher";
|
||||||
|
|
||||||
export type BeatGroupUINodeOptions = UINodeOptions & {
|
export type BeatGroupUINodeOptions = UINodeOptions & {
|
||||||
title: string,
|
title: string,
|
||||||
beatGroup: BeatGroup,
|
beatGroup: BeatGroup,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class BeatGroupView extends UINode {
|
export default class BeatGroupView extends UINode implements ISubscriber {
|
||||||
private title: string;
|
private title: string;
|
||||||
private beatGroup: BeatGroup;
|
private beatGroup: BeatGroup;
|
||||||
private beatViews: BeatView[] = [];
|
private beatViews: BeatView[] = [];
|
||||||
@@ -16,6 +19,13 @@ export default class BeatGroupView extends UINode {
|
|||||||
super(options);
|
super(options);
|
||||||
this.beatGroup = options.beatGroup;
|
this.beatGroup = options.beatGroup;
|
||||||
this.title = options.title;
|
this.title = options.title;
|
||||||
|
this.beatGroup.addSubscriber(this, BeatGroupEvents.BeatListChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
notify<T extends string | number>(publisher: IPublisher<T>, event: "all" | T[] | T): void {
|
||||||
|
if (event === BeatGroupEvents.BeatListChanged) {
|
||||||
|
this.redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuild(): HTMLDivElement {
|
rebuild(): HTMLDivElement {
|
||||||
|
|||||||
@@ -97,20 +97,24 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
|
|||||||
UINode.make("div", {
|
UINode.make("div", {
|
||||||
classes: ["beat-group-settings-options"],
|
classes: ["beat-group-settings-options"],
|
||||||
subs: [
|
subs: [
|
||||||
UINode.make("div", {
|
|
||||||
classes: ["beat-group-settings-bar-count", "beat-group-settings-option"],
|
|
||||||
subs: [
|
|
||||||
this.barCountInput.render(),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
UINode.make("div", {
|
UINode.make("div", {
|
||||||
classes: ["beat-group-settings-boxes", "beat-group-settings-option"],
|
classes: ["beat-group-settings-boxes", "beat-group-settings-option"],
|
||||||
subs: [
|
subs: [
|
||||||
this.timeSigUpInput.render(),
|
this.timeSigUpInput.render(),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
UINode.make("div", {
|
||||||
|
classes: ["beat-group-settings-bar-count", "beat-group-settings-option"],
|
||||||
|
subs: [
|
||||||
|
this.barCountInput.render(),
|
||||||
|
],
|
||||||
|
}),
|
||||||
this.loopSettingsView.render(),
|
this.loopSettingsView.render(),
|
||||||
this.autoBeatOptions,
|
this.autoBeatOptions,
|
||||||
|
UINode.make("button", {
|
||||||
|
innerText: "New Track",
|
||||||
|
onclick: () => this.beatGroup.addBeat(),
|
||||||
|
})
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ export type BeatSettingsViewUINodeOptions = UINodeOptions & {
|
|||||||
export default class BeatSettingsView extends UINode implements ISubscriber {
|
export default class BeatSettingsView extends UINode implements ISubscriber {
|
||||||
private beat: Beat;
|
private beat: Beat;
|
||||||
private visible = false;
|
private visible = false;
|
||||||
private timeSigUp!: NumberInputView;
|
private nameInput!: HTMLInputElement;
|
||||||
private timeSigDown!: NumberInputView;
|
|
||||||
private barCountInput!: NumberInputView;
|
|
||||||
private loopSettingsView!: BeatLikeLoopSettingsView;
|
private loopSettingsView!: BeatLikeLoopSettingsView;
|
||||||
|
|
||||||
constructor(options: BeatSettingsViewUINodeOptions) {
|
constructor(options: BeatSettingsViewUINodeOptions) {
|
||||||
@@ -29,11 +27,8 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
notify<T extends string | number>(publisher: IPublisher<T>, event: "all" | T[] | T): void {
|
notify<T extends string | number>(publisher: IPublisher<T>, event: "all" | T[] | T): void {
|
||||||
if (event === BeatEvents.NewTimeSig) {
|
if (event === BeatEvents.NewName) {
|
||||||
this.timeSigUp.setValue(this.beat.getTimeSigUp());
|
this.nameInput.value = this.beat.getName();
|
||||||
this.timeSigDown.setValue(this.beat.getTimeSigDown());
|
|
||||||
} else if (event === BeatEvents.NewBarCount) {
|
|
||||||
this.barCountInput.setValue(this.beat.getBarCount());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,37 +47,15 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
|
|||||||
|
|
||||||
rebuild(): HTMLElement {
|
rebuild(): HTMLElement {
|
||||||
this.loopSettingsView = new BeatLikeLoopSettingsView({beatLike: this.beat});
|
this.loopSettingsView = new BeatLikeLoopSettingsView({beatLike: this.beat});
|
||||||
this.timeSigUp = new NumberInputView({
|
this.nameInput = UINode.make("input", {
|
||||||
initialValue: this.beat.getTimeSigUp(),
|
value: this.beat.getName(),
|
||||||
setter: (value: number) => this.beat.setBarCount(value),
|
type: "text",
|
||||||
getter: () => this.beat.getBarCount(),
|
oninput: (event: Event) => this.beat.setName((event.target as HTMLInputElement).value),
|
||||||
});
|
|
||||||
this.timeSigDown = new NumberInputView({
|
|
||||||
initialValue: this.beat.getTimeSigDown(),
|
|
||||||
setter: (value: number) => this.beat.setBarCount(value),
|
|
||||||
getter: () => this.beat.getBarCount(),
|
|
||||||
});
|
|
||||||
this.barCountInput = new NumberInputView({
|
|
||||||
label: "Bar Count:",
|
|
||||||
initialValue: this.beat.getBarCount(),
|
|
||||||
setter: (value: number) => this.beat.setBarCount(value),
|
|
||||||
getter: () => this.beat.getBarCount(),
|
|
||||||
});
|
});
|
||||||
this.node = UINode.make("div", {
|
this.node = UINode.make("div", {
|
||||||
classes: ["beat-settings"],
|
classes: ["beat-settings"],
|
||||||
subs: [
|
subs: [
|
||||||
UINode.make("div", {
|
this.nameInput,
|
||||||
classes: ["beat-settings-time-sig", "beat-settings-option-group", "beat-settings-option"],
|
|
||||||
subs: [
|
|
||||||
UINode.make("label", {innerText: "Time Signature:"}),
|
|
||||||
this.timeSigUp.render(),
|
|
||||||
this.timeSigDown.render(),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
UINode.make("div", {
|
|
||||||
classes: ["beat-settings-bar", "beat-settings-option-group", "beat-settings-option"],
|
|
||||||
subs: [this.barCountInput.render()],
|
|
||||||
}),
|
|
||||||
this.loopSettingsView.render(),
|
this.loopSettingsView.render(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
|
overflow: hidden;
|
||||||
color: var(--color-p-light);
|
color: var(--color-p-light);
|
||||||
background-color: var(--color-bg-dark);
|
background-color: var(--color-bg-dark);
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@@ -36,12 +37,15 @@
|
|||||||
.root-beat-stage-container {
|
.root-beat-stage-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: calc(100vw - 30em);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.root-beat-stage {
|
.root-beat-stage {
|
||||||
|
max-width: calc(100vw - 30em);
|
||||||
|
overflow: hidden;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ export default abstract class UINode {
|
|||||||
|
|
||||||
redraw(): void {
|
redraw(): void {
|
||||||
const oldNode = this.node;
|
const oldNode = this.node;
|
||||||
this.render();
|
|
||||||
if (!oldNode || !this.node) {
|
if (!oldNode || !this.node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const parent = this.node.parentElement;
|
const parent = this.node.parentElement;
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent.replaceChild(oldNode, this.node);
|
this.node = this.rebuild();
|
||||||
|
parent.replaceChild(this.node, oldNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user