From fce6ce88fba1c2aa71ad713b108d48065e341611 Mon Sep 17 00:00:00 2001 From: Sig <62321214+sigprogramming@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:35:50 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[project-sequencer-statemachine]=20?= =?UTF-8?q?=E3=83=84=E3=83=BC=E3=83=AB=E3=81=AB=E5=AF=BE=E5=BF=9C=20(#2517?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sing/sequencerStateMachine/common.ts | 27 +++++- src/sing/sequencerStateMachine/index.ts | 12 ++- .../states/addNoteState.ts | 6 +- .../states/drawPitchState.ts | 6 +- .../states/drawPitchToolIdleState.ts | 51 +++++++++++ .../states/editNotesToolIdleState.ts | 91 +++++++++++++++++++ .../states/erasePitchState.ts | 6 +- .../states/erasePitchToolIdleState.ts | 42 +++++++++ .../states/moveNoteState.ts | 6 +- .../states/resizeNoteLeftState.ts | 6 +- .../states/resizeNoteRightState.ts | 6 +- ...leState.ts => selectNotesToolIdleState.ts} | 71 +++++---------- .../states/selectNotesWithRectState.ts | 10 +- 13 files changed, 282 insertions(+), 58 deletions(-) create mode 100644 src/sing/sequencerStateMachine/states/drawPitchToolIdleState.ts create mode 100644 src/sing/sequencerStateMachine/states/editNotesToolIdleState.ts create mode 100644 src/sing/sequencerStateMachine/states/erasePitchToolIdleState.ts rename src/sing/sequencerStateMachine/states/{idleState.ts => selectNotesToolIdleState.ts} (55%) diff --git a/src/sing/sequencerStateMachine/common.ts b/src/sing/sequencerStateMachine/common.ts index fe59057e5c..b0776c660c 100644 --- a/src/sing/sequencerStateMachine/common.ts +++ b/src/sing/sequencerStateMachine/common.ts @@ -86,10 +86,28 @@ export type PartialStore = { export type Context = ComputedRefs & Refs & { readonly store: PartialStore }; +export type IdleStateId = + | "selectNotesToolIdle" + | "editNotesToolIdle" + | "drawPitchToolIdle" + | "erasePitchToolIdle"; + export type SequencerStateDefinitions = StateDefinitions< [ { - id: "idle"; + id: "selectNotesToolIdle"; + factoryArgs: undefined; + }, + { + id: "editNotesToolIdle"; + factoryArgs: undefined; + }, + { + id: "drawPitchToolIdle"; + factoryArgs: undefined; + }, + { + id: "erasePitchToolIdle"; factoryArgs: undefined; }, { @@ -97,6 +115,7 @@ export type SequencerStateDefinitions = StateDefinitions< factoryArgs: { cursorPosAtStart: PositionOnSequencer; targetTrackId: TrackId; + returnStateId: IdleStateId; }; }, { @@ -106,6 +125,7 @@ export type SequencerStateDefinitions = StateDefinitions< targetTrackId: TrackId; targetNoteIds: Set; mouseDownNoteId: NoteId; + returnStateId: IdleStateId; }; }, { @@ -115,6 +135,7 @@ export type SequencerStateDefinitions = StateDefinitions< targetTrackId: TrackId; targetNoteIds: Set; mouseDownNoteId: NoteId; + returnStateId: IdleStateId; }; }, { @@ -124,12 +145,14 @@ export type SequencerStateDefinitions = StateDefinitions< targetTrackId: TrackId; targetNoteIds: Set; mouseDownNoteId: NoteId; + returnStateId: IdleStateId; }; }, { id: "selectNotesWithRect"; factoryArgs: { cursorPosAtStart: PositionOnSequencer; + returnStateId: IdleStateId; }; }, { @@ -137,6 +160,7 @@ export type SequencerStateDefinitions = StateDefinitions< factoryArgs: { cursorPosAtStart: PositionOnSequencer; targetTrackId: TrackId; + returnStateId: IdleStateId; }; }, { @@ -144,6 +168,7 @@ export type SequencerStateDefinitions = StateDefinitions< factoryArgs: { cursorPosAtStart: PositionOnSequencer; targetTrackId: TrackId; + returnStateId: IdleStateId; }; }, ] diff --git a/src/sing/sequencerStateMachine/index.ts b/src/sing/sequencerStateMachine/index.ts index 5eff85b6e0..0450f5477a 100644 --- a/src/sing/sequencerStateMachine/index.ts +++ b/src/sing/sequencerStateMachine/index.ts @@ -5,7 +5,10 @@ import { } from "@/sing/sequencerStateMachine/common"; import { StateMachine } from "@/sing/stateMachine"; -import { IdleState } from "@/sing/sequencerStateMachine/states/idleState"; +import { SelectNotesToolIdleState } from "@/sing/sequencerStateMachine/states/selectNotesToolIdleState"; +import { EditNotesToolIdleState } from "@/sing/sequencerStateMachine/states/editNotesToolIdleState"; +import { DrawPitchToolIdleState } from "@/sing/sequencerStateMachine/states/drawPitchToolIdleState"; +import { ErasePitchToolIdleState } from "@/sing/sequencerStateMachine/states/erasePitchToolIdleState"; import { AddNoteState } from "@/sing/sequencerStateMachine/states/addNoteState"; import { MoveNoteState } from "@/sing/sequencerStateMachine/states/moveNoteState"; import { ResizeNoteLeftState } from "@/sing/sequencerStateMachine/states/resizeNoteLeftState"; @@ -17,7 +20,10 @@ import { ErasePitchState } from "@/sing/sequencerStateMachine/states/erasePitchS export const createSequencerStateMachine = (context: Context) => { return new StateMachine( { - idle: () => new IdleState(), + selectNotesToolIdle: () => new SelectNotesToolIdleState(), + editNotesToolIdle: () => new EditNotesToolIdleState(), + drawPitchToolIdle: () => new DrawPitchToolIdleState(), + erasePitchToolIdle: () => new ErasePitchToolIdleState(), addNote: (args) => new AddNoteState(args), moveNote: (args) => new MoveNoteState(args), resizeNoteLeft: (args) => new ResizeNoteLeftState(args), @@ -26,7 +32,7 @@ export const createSequencerStateMachine = (context: Context) => { drawPitch: (args) => new DrawPitchState(args), erasePitch: (args) => new ErasePitchState(args), }, - new IdleState(), + new SelectNotesToolIdleState(), context, ); }; diff --git a/src/sing/sequencerStateMachine/states/addNoteState.ts b/src/sing/sequencerStateMachine/states/addNoteState.ts index d4633bdfcd..a56fdd2421 100644 --- a/src/sing/sequencerStateMachine/states/addNoteState.ts +++ b/src/sing/sequencerStateMachine/states/addNoteState.ts @@ -2,6 +2,7 @@ import { SetNextState, State } from "@/sing/stateMachine"; import { Context, getGuideLineTicks, + IdleStateId, Input, PositionOnSequencer, SequencerStateDefinitions, @@ -22,6 +23,7 @@ export class AddNoteState private readonly cursorPosAtStart: PositionOnSequencer; private readonly targetTrackId: TrackId; + private readonly returnStateId: IdleStateId; private currentCursorPos: PositionOnSequencer; private innerContext: @@ -35,9 +37,11 @@ export class AddNoteState constructor(args: { cursorPosAtStart: PositionOnSequencer; targetTrackId: TrackId; + returnStateId: IdleStateId; }) { this.cursorPosAtStart = args.cursorPosAtStart; this.targetTrackId = args.targetTrackId; + this.returnStateId = args.returnStateId; this.currentCursorPos = args.cursorPosAtStart; } @@ -119,7 +123,7 @@ export class AddNoteState this.innerContext.executePreviewProcess = true; } else if (input.mouseEvent.type === "mouseup") { if (mouseButton === "LEFT_BUTTON") { - setNextState("idle", undefined); + setNextState(this.returnStateId, undefined); } } } diff --git a/src/sing/sequencerStateMachine/states/drawPitchState.ts b/src/sing/sequencerStateMachine/states/drawPitchState.ts index de8f9819f8..ac8a7006e3 100644 --- a/src/sing/sequencerStateMachine/states/drawPitchState.ts +++ b/src/sing/sequencerStateMachine/states/drawPitchState.ts @@ -1,6 +1,7 @@ import { SetNextState, State } from "@/sing/stateMachine"; import { Context, + IdleStateId, Input, PositionOnSequencer, SequencerStateDefinitions, @@ -20,6 +21,7 @@ export class DrawPitchState private readonly cursorPosAtStart: PositionOnSequencer; private readonly targetTrackId: TrackId; + private readonly returnStateId: IdleStateId; private currentCursorPos: PositionOnSequencer; @@ -34,9 +36,11 @@ export class DrawPitchState constructor(args: { cursorPosAtStart: PositionOnSequencer; targetTrackId: TrackId; + returnStateId: IdleStateId; }) { this.cursorPosAtStart = args.cursorPosAtStart; this.targetTrackId = args.targetTrackId; + this.returnStateId = args.returnStateId; this.currentCursorPos = args.cursorPosAtStart; } @@ -158,7 +162,7 @@ export class DrawPitchState this.innerContext.executePreviewProcess = true; } else if (input.mouseEvent.type === "mouseup") { if (mouseButton === "LEFT_BUTTON") { - setNextState("idle", undefined); + setNextState(this.returnStateId, undefined); } } } diff --git a/src/sing/sequencerStateMachine/states/drawPitchToolIdleState.ts b/src/sing/sequencerStateMachine/states/drawPitchToolIdleState.ts new file mode 100644 index 0000000000..c344fc35ec --- /dev/null +++ b/src/sing/sequencerStateMachine/states/drawPitchToolIdleState.ts @@ -0,0 +1,51 @@ +import { SetNextState, State } from "@/sing/stateMachine"; +import { + Context, + Input, + SequencerStateDefinitions, +} from "@/sing/sequencerStateMachine/common"; +import { getButton } from "@/sing/viewHelper"; +import { isOnCommandOrCtrlKeyDown } from "@/store/utility"; + +export class DrawPitchToolIdleState + implements State +{ + readonly id = "drawPitchToolIdle"; + + onEnter() {} + + process({ + input, + context, + setNextState, + }: { + input: Input; + context: Context; + setNextState: SetNextState; + }) { + const mouseButton = getButton(input.mouseEvent); + const selectedTrackId = context.selectedTrackId.value; + + if ( + input.mouseEvent.type === "mousedown" && + mouseButton === "LEFT_BUTTON" && + input.targetArea === "SequencerBody" + ) { + if (isOnCommandOrCtrlKeyDown(input.mouseEvent)) { + setNextState("erasePitch", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + returnStateId: this.id, + }); + } else { + setNextState("drawPitch", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + returnStateId: this.id, + }); + } + } + } + + onExit() {} +} diff --git a/src/sing/sequencerStateMachine/states/editNotesToolIdleState.ts b/src/sing/sequencerStateMachine/states/editNotesToolIdleState.ts new file mode 100644 index 0000000000..8837ec0262 --- /dev/null +++ b/src/sing/sequencerStateMachine/states/editNotesToolIdleState.ts @@ -0,0 +1,91 @@ +import { SetNextState, State } from "@/sing/stateMachine"; +import { + Context, + executeNotesSelectionProcess, + getGuideLineTicks, + Input, + SequencerStateDefinitions, +} from "@/sing/sequencerStateMachine/common"; +import { getButton, isSelfEventTarget } from "@/sing/viewHelper"; +import { isOnCommandOrCtrlKeyDown } from "@/store/utility"; + +export class EditNotesToolIdleState + implements State +{ + readonly id = "editNotesToolIdle"; + + onEnter() {} + + process({ + input, + context, + setNextState, + }: { + input: Input; + context: Context; + setNextState: SetNextState; + }) { + const mouseButton = getButton(input.mouseEvent); + const selectedTrackId = context.selectedTrackId.value; + + if (input.targetArea === "SequencerBody") { + context.guideLineTicks.value = getGuideLineTicks( + input.cursorPos, + context, + ); + } + + if ( + input.mouseEvent.type === "mousedown" && + mouseButton === "LEFT_BUTTON" && + isSelfEventTarget(input.mouseEvent) + ) { + if (input.targetArea === "SequencerBody") { + if (input.mouseEvent.shiftKey) { + setNextState("selectNotesWithRect", { + cursorPosAtStart: input.cursorPos, + returnStateId: this.id, + }); + } else if (isOnCommandOrCtrlKeyDown(input.mouseEvent)) { + void context.store.actions.DESELECT_ALL_NOTES(); + } else { + void context.store.actions.DESELECT_ALL_NOTES(); + setNextState("addNote", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + returnStateId: this.id, + }); + } + } else if (input.targetArea === "Note") { + executeNotesSelectionProcess(context, input.mouseEvent, input.note); + setNextState("moveNote", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + targetNoteIds: context.selectedNoteIds.value, + mouseDownNoteId: input.note.id, + returnStateId: this.id, + }); + } else if (input.targetArea === "NoteLeftEdge") { + executeNotesSelectionProcess(context, input.mouseEvent, input.note); + setNextState("resizeNoteLeft", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + targetNoteIds: context.selectedNoteIds.value, + mouseDownNoteId: input.note.id, + returnStateId: this.id, + }); + } else if (input.targetArea === "NoteRightEdge") { + executeNotesSelectionProcess(context, input.mouseEvent, input.note); + setNextState("resizeNoteRight", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + targetNoteIds: context.selectedNoteIds.value, + mouseDownNoteId: input.note.id, + returnStateId: this.id, + }); + } + } + } + + onExit() {} +} diff --git a/src/sing/sequencerStateMachine/states/erasePitchState.ts b/src/sing/sequencerStateMachine/states/erasePitchState.ts index c1ee27f93c..ec5289c286 100644 --- a/src/sing/sequencerStateMachine/states/erasePitchState.ts +++ b/src/sing/sequencerStateMachine/states/erasePitchState.ts @@ -1,6 +1,7 @@ import { SetNextState, State } from "@/sing/stateMachine"; import { Context, + IdleStateId, Input, PositionOnSequencer, SequencerStateDefinitions, @@ -15,6 +16,7 @@ export class ErasePitchState private readonly cursorPosAtStart: PositionOnSequencer; private readonly targetTrackId: TrackId; + private readonly returnStateId: IdleStateId; private currentCursorPos: PositionOnSequencer; @@ -28,9 +30,11 @@ export class ErasePitchState constructor(args: { cursorPosAtStart: PositionOnSequencer; targetTrackId: TrackId; + returnStateId: IdleStateId; }) { this.cursorPosAtStart = args.cursorPosAtStart; this.targetTrackId = args.targetTrackId; + this.returnStateId = args.returnStateId; this.currentCursorPos = args.cursorPosAtStart; } @@ -106,7 +110,7 @@ export class ErasePitchState this.innerContext.executePreviewProcess = true; } else if (input.mouseEvent.type === "mouseup") { if (mouseButton === "LEFT_BUTTON") { - setNextState("idle", undefined); + setNextState(this.returnStateId, undefined); } } } diff --git a/src/sing/sequencerStateMachine/states/erasePitchToolIdleState.ts b/src/sing/sequencerStateMachine/states/erasePitchToolIdleState.ts new file mode 100644 index 0000000000..b369482749 --- /dev/null +++ b/src/sing/sequencerStateMachine/states/erasePitchToolIdleState.ts @@ -0,0 +1,42 @@ +import { SetNextState, State } from "@/sing/stateMachine"; +import { + Context, + Input, + SequencerStateDefinitions, +} from "@/sing/sequencerStateMachine/common"; +import { getButton } from "@/sing/viewHelper"; + +export class ErasePitchToolIdleState + implements State +{ + readonly id = "erasePitchToolIdle"; + + onEnter() {} + + process({ + input, + context, + setNextState, + }: { + input: Input; + context: Context; + setNextState: SetNextState; + }) { + const mouseButton = getButton(input.mouseEvent); + const selectedTrackId = context.selectedTrackId.value; + + if ( + input.mouseEvent.type === "mousedown" && + mouseButton === "LEFT_BUTTON" && + input.targetArea === "SequencerBody" + ) { + setNextState("erasePitch", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + returnStateId: this.id, + }); + } + } + + onExit() {} +} diff --git a/src/sing/sequencerStateMachine/states/moveNoteState.ts b/src/sing/sequencerStateMachine/states/moveNoteState.ts index a68d526437..5f6eb4b379 100644 --- a/src/sing/sequencerStateMachine/states/moveNoteState.ts +++ b/src/sing/sequencerStateMachine/states/moveNoteState.ts @@ -7,6 +7,7 @@ import { TrackId, NoteId } from "@/type/preload"; import { Context, getGuideLineTicks, + IdleStateId, Input, PositionOnSequencer, SequencerStateDefinitions, @@ -21,6 +22,7 @@ export class MoveNoteState private readonly targetTrackId: TrackId; private readonly targetNoteIds: Set; private readonly mouseDownNoteId: NoteId; + private readonly returnStateId: IdleStateId; private currentCursorPos: PositionOnSequencer; @@ -39,6 +41,7 @@ export class MoveNoteState targetTrackId: TrackId; targetNoteIds: Set; mouseDownNoteId: NoteId; + returnStateId: IdleStateId; }) { if (!args.targetNoteIds.has(args.mouseDownNoteId)) { throw new Error("mouseDownNoteId is not included in targetNoteIds."); @@ -47,6 +50,7 @@ export class MoveNoteState this.targetTrackId = args.targetTrackId; this.targetNoteIds = args.targetNoteIds; this.mouseDownNoteId = args.mouseDownNoteId; + this.returnStateId = args.returnStateId; this.currentCursorPos = args.cursorPosAtStart; } @@ -146,7 +150,7 @@ export class MoveNoteState this.innerContext.executePreviewProcess = true; } else if (input.mouseEvent.type === "mouseup") { if (mouseButton === "LEFT_BUTTON") { - setNextState("idle", undefined); + setNextState(this.returnStateId, undefined); } } } diff --git a/src/sing/sequencerStateMachine/states/resizeNoteLeftState.ts b/src/sing/sequencerStateMachine/states/resizeNoteLeftState.ts index 77b072d1e3..be8ae3494b 100644 --- a/src/sing/sequencerStateMachine/states/resizeNoteLeftState.ts +++ b/src/sing/sequencerStateMachine/states/resizeNoteLeftState.ts @@ -6,6 +6,7 @@ import { TrackId, NoteId } from "@/type/preload"; import { Context, getGuideLineTicks, + IdleStateId, Input, PositionOnSequencer, SequencerStateDefinitions, @@ -21,6 +22,7 @@ export class ResizeNoteLeftState private readonly targetTrackId: TrackId; private readonly targetNoteIds: Set; private readonly mouseDownNoteId: NoteId; + private readonly returnStateId: IdleStateId; private currentCursorPos: PositionOnSequencer; @@ -39,6 +41,7 @@ export class ResizeNoteLeftState targetTrackId: TrackId; targetNoteIds: Set; mouseDownNoteId: NoteId; + returnStateId: IdleStateId; }) { if (!args.targetNoteIds.has(args.mouseDownNoteId)) { throw new Error("mouseDownNoteId is not included in targetNoteIds."); @@ -47,6 +50,7 @@ export class ResizeNoteLeftState this.targetTrackId = args.targetTrackId; this.targetNoteIds = args.targetNoteIds; this.mouseDownNoteId = args.mouseDownNoteId; + this.returnStateId = args.returnStateId; this.currentCursorPos = args.cursorPosAtStart; } @@ -143,7 +147,7 @@ export class ResizeNoteLeftState input.mouseEvent.type === "mouseup" && mouseButton === "LEFT_BUTTON" ) { - setNextState("idle", undefined); + setNextState(this.returnStateId, undefined); } } } diff --git a/src/sing/sequencerStateMachine/states/resizeNoteRightState.ts b/src/sing/sequencerStateMachine/states/resizeNoteRightState.ts index 2dd08b92c2..4cd1df8335 100644 --- a/src/sing/sequencerStateMachine/states/resizeNoteRightState.ts +++ b/src/sing/sequencerStateMachine/states/resizeNoteRightState.ts @@ -4,6 +4,7 @@ import { NoteId, TrackId } from "@/type/preload"; import { Context, getGuideLineTicks, + IdleStateId, Input, PositionOnSequencer, SequencerStateDefinitions, @@ -20,6 +21,7 @@ export class ResizeNoteRightState private readonly targetTrackId: TrackId; private readonly targetNoteIds: Set; private readonly mouseDownNoteId: NoteId; + private readonly returnStateId: IdleStateId; private currentCursorPos: PositionOnSequencer; @@ -38,6 +40,7 @@ export class ResizeNoteRightState targetTrackId: TrackId; targetNoteIds: Set; mouseDownNoteId: NoteId; + returnStateId: IdleStateId; }) { if (!args.targetNoteIds.has(args.mouseDownNoteId)) { throw new Error("mouseDownNoteId is not included in targetNoteIds."); @@ -46,6 +49,7 @@ export class ResizeNoteRightState this.targetTrackId = args.targetTrackId; this.targetNoteIds = args.targetNoteIds; this.mouseDownNoteId = args.mouseDownNoteId; + this.returnStateId = args.returnStateId; this.currentCursorPos = args.cursorPosAtStart; } @@ -141,7 +145,7 @@ export class ResizeNoteRightState input.mouseEvent.type === "mouseup" && mouseButton === "LEFT_BUTTON" ) { - setNextState("idle", undefined); + setNextState(this.returnStateId, undefined); } } } diff --git a/src/sing/sequencerStateMachine/states/idleState.ts b/src/sing/sequencerStateMachine/states/selectNotesToolIdleState.ts similarity index 55% rename from src/sing/sequencerStateMachine/states/idleState.ts rename to src/sing/sequencerStateMachine/states/selectNotesToolIdleState.ts index 286ca8087d..c65ce5a95e 100644 --- a/src/sing/sequencerStateMachine/states/idleState.ts +++ b/src/sing/sequencerStateMachine/states/selectNotesToolIdleState.ts @@ -7,12 +7,11 @@ import { SequencerStateDefinitions, } from "@/sing/sequencerStateMachine/common"; import { getButton, isSelfEventTarget } from "@/sing/viewHelper"; -import { isOnCommandOrCtrlKeyDown } from "@/store/utility"; -export class IdleState +export class SelectNotesToolIdleState implements State { - readonly id = "idle"; + readonly id = "selectNotesToolIdle"; onEnter() {} @@ -28,30 +27,20 @@ export class IdleState const mouseButton = getButton(input.mouseEvent); const selectedTrackId = context.selectedTrackId.value; - if (context.editTarget.value === "NOTE") { - if (input.targetArea === "SequencerBody") { - context.guideLineTicks.value = getGuideLineTicks( - input.cursorPos, - context, - ); - } - if ( - input.mouseEvent.type === "mousedown" && - mouseButton === "LEFT_BUTTON" && - isSelfEventTarget(input.mouseEvent) - ) { + if (input.targetArea === "SequencerBody") { + context.guideLineTicks.value = getGuideLineTicks( + input.cursorPos, + context, + ); + } + + if (mouseButton === "LEFT_BUTTON" && isSelfEventTarget(input.mouseEvent)) { + if (input.mouseEvent.type === "mousedown") { if (input.targetArea === "SequencerBody") { - if (input.mouseEvent.shiftKey) { - setNextState("selectNotesWithRect", { - cursorPosAtStart: input.cursorPos, - }); - } else { - void context.store.actions.DESELECT_ALL_NOTES(); - setNextState("addNote", { - cursorPosAtStart: input.cursorPos, - targetTrackId: selectedTrackId, - }); - } + setNextState("selectNotesWithRect", { + cursorPosAtStart: input.cursorPos, + returnStateId: this.id, + }); } else if (input.targetArea === "Note") { executeNotesSelectionProcess(context, input.mouseEvent, input.note); setNextState("moveNote", { @@ -59,6 +48,7 @@ export class IdleState targetTrackId: selectedTrackId, targetNoteIds: context.selectedNoteIds.value, mouseDownNoteId: input.note.id, + returnStateId: this.id, }); } else if (input.targetArea === "NoteLeftEdge") { executeNotesSelectionProcess(context, input.mouseEvent, input.note); @@ -67,6 +57,7 @@ export class IdleState targetTrackId: selectedTrackId, targetNoteIds: context.selectedNoteIds.value, mouseDownNoteId: input.note.id, + returnStateId: this.id, }); } else if (input.targetArea === "NoteRightEdge") { executeNotesSelectionProcess(context, input.mouseEvent, input.note); @@ -75,28 +66,16 @@ export class IdleState targetTrackId: selectedTrackId, targetNoteIds: context.selectedNoteIds.value, mouseDownNoteId: input.note.id, + returnStateId: this.id, }); } - } - } else if (context.editTarget.value === "PITCH") { - if ( - input.mouseEvent.type === "mousedown" && - mouseButton === "LEFT_BUTTON" && - input.targetArea === "SequencerBody" - ) { - // TODO: Ctrlが押されているときではなく、 - // ピッチ削除ツールのときにErasePitchStateに遷移するようにする - if (isOnCommandOrCtrlKeyDown(input.mouseEvent)) { - setNextState("erasePitch", { - cursorPosAtStart: input.cursorPos, - targetTrackId: selectedTrackId, - }); - } else { - setNextState("drawPitch", { - cursorPosAtStart: input.cursorPos, - targetTrackId: selectedTrackId, - }); - } + } else if (input.mouseEvent.type === "dblclick") { + void context.store.actions.DESELECT_ALL_NOTES(); + setNextState("addNote", { + cursorPosAtStart: input.cursorPos, + targetTrackId: selectedTrackId, + returnStateId: this.id, + }); } } } diff --git a/src/sing/sequencerStateMachine/states/selectNotesWithRectState.ts b/src/sing/sequencerStateMachine/states/selectNotesWithRectState.ts index 22294cb871..fd8beaf2ac 100644 --- a/src/sing/sequencerStateMachine/states/selectNotesWithRectState.ts +++ b/src/sing/sequencerStateMachine/states/selectNotesWithRectState.ts @@ -1,6 +1,7 @@ import { SetNextState, State } from "@/sing/stateMachine"; import { Context, + IdleStateId, Input, PositionOnSequencer, SequencerStateDefinitions, @@ -15,12 +16,17 @@ export class SelectNotesWithRectState readonly id = "selectNotesWithRect"; private readonly cursorPosAtStart: PositionOnSequencer; + private readonly returnStateId: IdleStateId; private currentCursorPos: PositionOnSequencer; private additive: boolean; - constructor(args: { cursorPosAtStart: PositionOnSequencer }) { + constructor(args: { + cursorPosAtStart: PositionOnSequencer; + returnStateId: IdleStateId; + }) { this.cursorPosAtStart = args.cursorPosAtStart; + this.returnStateId = args.returnStateId; this.currentCursorPos = args.cursorPosAtStart; this.additive = false; @@ -63,7 +69,7 @@ export class SelectNotesWithRectState mouseButton === "LEFT_BUTTON" ) { this.additive = isOnCommandOrCtrlKeyDown(input.mouseEvent); - setNextState("idle", undefined); + setNextState(this.returnStateId, undefined); } } }