import type { BrushSettings, ToolId } from "@editor/tools"; import type { Command } from "./command"; import { commandIds } from "./ids"; export type ToolSetActivePayload = { tool: ToolId; }; export type ToolSetBrushSettingsPayload = Partial; export const toolSetActiveCommand: Command = { id: commandIds.toolSetActive, name: "Set active tool", execute({ state }, payload) { return { ...state, editor: { ...state.editor, tools: { ...state.editor.tools, activeTool: payload.tool, interactionMode: { type: "tool", tool: payload.tool }, }, }, }; }, }; export const toolSetBrushSettingsCommand: Command = { id: commandIds.toolSetBrushSettings, name: "Set brush settings", execute({ state }, payload) { return { ...state, editor: { ...state.editor, tools: { ...state.editor.tools, brush: { color: payload.color ?? state.editor.tools.brush.color, size: clampNumber(payload.size ?? state.editor.tools.brush.size, 1, 200), hardness: clampNumber(payload.hardness ?? state.editor.tools.brush.hardness, 0, 100), }, }, }, }; }, }; export const toolEnterTemporaryPanCommand: Command = { id: commandIds.toolEnterTemporaryPan, name: "Enter temporary pan", execute({ state }) { if (state.editor.tools.interactionMode.type === "temporary-pan") return state; return { ...state, editor: { ...state.editor, tools: { ...state.editor.tools, interactionMode: { type: "temporary-pan", previousTool: state.editor.tools.activeTool }, }, }, }; }, }; export const toolExitTemporaryPanCommand: Command = { id: commandIds.toolExitTemporaryPan, name: "Exit temporary pan", execute({ state }) { const mode = state.editor.tools.interactionMode; if (mode.type !== "temporary-pan") return state; return { ...state, editor: { ...state.editor, tools: { ...state.editor.tools, activeTool: mode.previousTool, interactionMode: { type: "tool", tool: mode.previousTool }, }, }, }; }, }; export const toolCommands = [toolSetActiveCommand, toolSetBrushSettingsCommand, toolEnterTemporaryPanCommand, toolExitTemporaryPanCommand] satisfies Command[]; function clampNumber(value: number, min: number, max: number) { if (!Number.isFinite(value)) return min; return Math.max(min, Math.min(max, value)); }