diff --git a/src/Beat.ts b/src/Beat.ts index 03ed271..68a2ff1 100644 --- a/src/Beat.ts +++ b/src/Beat.ts @@ -8,6 +8,7 @@ export interface BeatManager { } type BeatGroupInitOptions = { + displaySticking?: boolean, barCount: number; isLooping: boolean; timeSigUp: number; @@ -24,6 +25,7 @@ const BeatSerialSchema = z.object({ globalLoopLength: z.number(), globalIsLooping: z.boolean(), useAutoBeatLength: z.boolean(), + displaySticking: z.boolean(), barSettingsLocked: z.boolean(), name: z.string(), }); @@ -44,7 +46,7 @@ export class Beat extends EffectScoped { barSettingsLocked: Ref; name: Ref; saveDirty = ref(false); - displaySticking = ref(false); + displaySticking: Ref; constructor(opts: BeatGroupInitOptions) { super(); @@ -91,6 +93,7 @@ export class Beat extends EffectScoped { this.useAutoBeatLength = ref(opts.useAutoBeatLength ?? false); this.barSettingsLocked = computed(() => this.useAutoBeatLength.value); this.name = ref(opts.name ?? `Beat-${ this.id }`); + this.displaySticking = ref(opts.displaySticking ?? false); watch([this.barCount, this.timeSigUp, this.name], ([newBarCount, newTimeSigUp]) => { for (const track of this.tracks.value) { @@ -169,6 +172,7 @@ export class Beat extends EffectScoped { serialise(): Readonly { return { + displaySticking: this.displaySticking.value, tracks: this.tracks.value.map(track => track.serialise()), barCount: this.barCount.value, timeSigUp: this.timeSigUp.value, @@ -189,6 +193,7 @@ export function deserialise(serial: unknown): Beat | null { } const beat = parse.data; const newBeat = Beat.asScoped({ + displaySticking: beat.displaySticking, loopLength: beat.globalLoopLength, barCount: beat.barCount, isLooping: beat.globalIsLooping, diff --git a/src/Track.ts b/src/Track.ts index fd7e2f6..2bb5434 100644 --- a/src/Track.ts +++ b/src/Track.ts @@ -4,6 +4,7 @@ import type { BeatManager } from "./Beat"; import { z } from "zod"; export type TrackInitOptions = { + visible?: boolean, manager: BeatManager, timeSig?: { up: number, @@ -28,6 +29,7 @@ const TrackSerialSchema = z.object({ barCount: z.number(), loopLength: z.number(), looping: z.boolean(), + visible: z.boolean(), }); export type TrackSerial = z.infer; @@ -46,21 +48,22 @@ export function deserialise(serial: unknown, manager: BeatManager) { if (!parse.success) { throw new Error("Invalid track serial."); } - const beat = parse.data; - const units = beat.units.isOn.map((isOn, i) => ({ + const track = parse.data; + const units = track.units.isOn.map((isOn, i) => ({ on: isOn, - type: beat.units.type[i] ?? 0, - stickingType: beat.units.stickingType[i] ?? null, + type: track.units.type[i] ?? 0, + stickingType: track.units.stickingType[i] ?? null, })); return Track.asScoped({ + visible: track.visible, manager, - barCount: beat.barCount, - isLooping: beat.looping, - loopLength: beat.loopLength, - name: beat.name, + barCount: track.barCount, + isLooping: track.looping, + loopLength: track.loopLength, + name: track.name, timeSig: { - up: beat.timeSigUp, - down: beat.timeSigDown, + up: track.timeSigUp, + down: track.timeSigDown, }, units, }); @@ -83,6 +86,7 @@ export class Track extends EffectScoped { barCount: Ref; loopLength: Ref; looping: Ref; + visible: Ref; constructor(options: TrackInitOptions) { super(); @@ -125,6 +129,7 @@ export class Track extends EffectScoped { }, }); this.looping = ref(options?.isLooping ?? false); + this.visible = ref(options?.visible ?? true); watch(this.unitRecord, () => this.manager.notifyChange()); watch([this.barCount, this.timeSigDown, this.timeSigUp], () => this.updateTrackUnitLength(), { immediate: true }); @@ -170,6 +175,7 @@ export class Track extends EffectScoped { serialise(): Readonly { return { + visible: this.visible.value, name: this.name.value, timeSigUp: this.timeSigUp.value, timeSigDown: this.timeSigDown.value, diff --git a/src/ui/Beat/Beat.vue b/src/ui/Beat/Beat.vue index 6ba39b9..9101bfd 100644 --- a/src/ui/Beat/Beat.vue +++ b/src/ui/Beat/Beat.vue @@ -22,7 +22,7 @@ @change="onMove" item-key="index">