115 lines
3.0 KiB
TypeScript
115 lines
3.0 KiB
TypeScript
import type { LayerId } from "@core/id";
|
|
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<BrushSettings>;
|
|
|
|
export type ToolSetMaskEditLayerPayload = {
|
|
layerId?: LayerId;
|
|
};
|
|
|
|
export const toolSetActiveCommand: Command<ToolSetActivePayload> = {
|
|
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<ToolSetBrushSettingsPayload> = {
|
|
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 toolSetMaskEditLayerCommand: Command<ToolSetMaskEditLayerPayload> = {
|
|
id: commandIds.toolSetMaskEditLayer,
|
|
name: "Set mask edit layer",
|
|
execute({ state }, payload) {
|
|
return {
|
|
...state,
|
|
editor: {
|
|
...state.editor,
|
|
maskEditLayerId: payload.layerId,
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
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, toolSetMaskEditLayerCommand, toolEnterTemporaryPanCommand, toolExitTemporaryPanCommand] satisfies Command<unknown>[];
|
|
|
|
function clampNumber(value: number, min: number, max: number) {
|
|
if (!Number.isFinite(value)) return min;
|
|
return Math.max(min, Math.min(max, value));
|
|
}
|