This commit is contained in:
2024-06-01 21:10:05 +02:00
parent 79f4e6c098
commit 80647dce80
5 changed files with 38 additions and 15 deletions

View File

@@ -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<boolean>;
name: Ref<string>;
saveDirty = ref(false);
displaySticking = ref(false);
displaySticking: Ref<boolean>;
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<BeatSerial> {
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,

View File

@@ -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<typeof TrackSerialSchema>;
@@ -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<number>;
loopLength: Ref<number>;
looping: Ref<boolean>;
visible: Ref<boolean>;
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<TrackSerial> {
return {
visible: this.visible.value,
name: this.name.value,
timeSigUp: this.timeSigUp.value,
timeSigDown: this.timeSigDown.value,

View File

@@ -22,7 +22,7 @@
@change="onMove"
item-key="index">
<template #item="{ element }">
<div class="beat-line">
<div v-if="element.track.visible.value" class="beat-line">
<editable-text-field class="track-name" v-model="element.track.name.value" />
<span class="handle"><icon color="var(--color-ui-neutral-dark)" icon-name="list" /></span>
<track-view :beat-index="beatIndex"
@@ -44,7 +44,7 @@
import Draggable from "vuedraggable";
import { TrackUnitStickingTypeList, type Track } from "@/Track";
import Icon from "@/ui/Widgets/Icon/Icon.vue";
import { StickingTypeIconMap } from "../TrackUnit/trackUnit";
import { StickingTypeIconMap } from "../TrackUnit/trackUnit";
const props = defineProps<{
beatIndex: number,

View File

@@ -12,12 +12,16 @@
<div class="loop-settings-option" :class="{ hide: !track.looping.value }">
<number-input v-model="track.loopLength.value" />
</div>
<div class="visibility">
<icon color="var(--color-ui-neutral-dark)" :icon-name="track.visible.value ? 'eye' : 'eyeOff'" @click="track.visible.value = !track.visible.value"/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import NumberInput from "@/ui/Widgets/NumberInput/NumberInput.vue";
import Icon from "@/ui/Widgets/Icon/Icon.vue";
import BoolBox from "@/ui/Widgets/BoolBox/BoolBox.vue";
import ActionButton from "@/ui/Widgets/ActionButton/ActionButton.vue";
import EditableTextField from "@/ui/Widgets/EditableTextField/EditableTextField.vue";
@@ -39,7 +43,7 @@
min-width: 100%;
height: 2em;
}
p
.track-settings-title-container > div {
width: 100%;
font-weight: bold;
@@ -81,4 +85,8 @@ p
flex: auto;
padding-right: 1em;
}
.visibility {
cursor: pointer;
}
</style>

View File

@@ -11,6 +11,8 @@ import Eraser from "@/assets/svgs/eraser-fill.svg";
import Upload from "@/assets/svgs/upload.svg";
import Floppy from "@/assets/svgs/floppy2-fill.svg";
import Delete from "@/assets/svgs/delete.svg";
import Eye from "@/assets/svgs/eye.svg";
import EyeOff from "@/assets/svgs/eye-off.svg";
export const IconUrlMap = {
arrowClockwise: ArrowClockwise,
@@ -26,6 +28,8 @@ export const IconUrlMap = {
upload: Upload,
save: Floppy,
delete: Delete,
eye: Eye,
eyeOff: EyeOff,
} as const;
export type IconName = keyof typeof IconUrlMap;