42 lines
2.1 KiB
TypeScript
42 lines
2.1 KiB
TypeScript
export const INPUT_MODAL_SCHEMA_VERSION = 1 as const;
|
|
|
|
export type InputModalKind = "NONE" | "TOUCH_NAVIGATION" | "PEN_STROKE";
|
|
|
|
export interface InputModalState {
|
|
schemaVersion: typeof INPUT_MODAL_SCHEMA_VERSION;
|
|
kind: InputModalKind;
|
|
activePointerIds: number[];
|
|
cancelled: boolean;
|
|
navigationRevision: number;
|
|
mainCommitCount: number;
|
|
}
|
|
|
|
export function createInputModalState(): InputModalState {
|
|
return { schemaVersion: 1, kind: "NONE", activePointerIds: [], cancelled: false, navigationRevision: 0, mainCommitCount: 0 };
|
|
}
|
|
|
|
export function beginTouch(state: InputModalState, pointerId: number): InputModalState {
|
|
if (!Number.isSafeInteger(pointerId) || pointerId < 0) throw new Error("POINTER_ID_INVALID");
|
|
const ids = state.activePointerIds.includes(pointerId) ? state.activePointerIds : [...state.activePointerIds, pointerId].sort((a, b) => a - b);
|
|
return { ...state, kind: "TOUCH_NAVIGATION", activePointerIds: ids, cancelled: false, navigationRevision: ids.length >= 2 && state.activePointerIds.length < 2 ? state.navigationRevision + 1 : state.navigationRevision };
|
|
}
|
|
|
|
export function cancelInputModal(state: InputModalState): InputModalState {
|
|
return { ...state, kind: "NONE", activePointerIds: [], cancelled: true };
|
|
}
|
|
|
|
export function endTouch(state: InputModalState, pointerId: number): InputModalState {
|
|
const ids = state.activePointerIds.filter((id) => id !== pointerId);
|
|
return { ...state, kind: ids.length > 0 ? "TOUCH_NAVIGATION" : "NONE", activePointerIds: ids };
|
|
}
|
|
|
|
export function beginPenStroke(state: InputModalState, pointerId: number): InputModalState {
|
|
if (!Number.isSafeInteger(pointerId) || pointerId < 0) throw new Error("POINTER_ID_INVALID");
|
|
return { ...state, kind: "PEN_STROKE", activePointerIds: [pointerId], cancelled: false };
|
|
}
|
|
|
|
export function commitPenStroke(state: InputModalState, pointerId: number): InputModalState {
|
|
if (state.kind !== "PEN_STROKE" || !state.activePointerIds.includes(pointerId) || state.cancelled) return state;
|
|
return { ...state, kind: "NONE", activePointerIds: [], mainCommitCount: state.mainCommitCount + 1 };
|
|
}
|