feat: unify AI edit workflow
This commit is contained in:
@@ -27,6 +27,7 @@ export const commandIds = {
|
||||
selectionAddLayer: "selection.addLayer",
|
||||
toolSetActive: "tool.setActive",
|
||||
toolSetGenerateSettings: "tool.setGenerateSettings",
|
||||
toolChooseGenerateIntent: "tool.chooseGenerateIntent",
|
||||
toolSetBrushSettings: "tool.setBrushSettings",
|
||||
toolSetChromaKeySettings: "tool.setChromaKeySettings",
|
||||
toolSetMagicWandSettings: "tool.setMagicWandSettings",
|
||||
|
||||
@@ -89,10 +89,10 @@ export type { CommandRegistry } from "./registry";
|
||||
export { createCommandRegistry } from "./registry";
|
||||
export { selectionAddLayerCommand, selectionClearCommand, selectionCommands, selectionSetCommand } from "./selection";
|
||||
export type { SelectionAddLayerPayload, SelectionSetPayload } from "./selection";
|
||||
export { toolCommands, toolEnterMaskEditCommand, toolEnterTemporaryPanCommand, toolExitMaskEditCommand, toolExitTemporaryPanCommand, toolSetActiveCommand, toolSetBrushPreviewCommand, toolSetBrushSettingsCommand, toolSetBrushStrokePreviewCommand, toolSetChromaKeySettingsCommand, toolSetGenerateSettingsCommand, toolSetMagicWandSettingsCommand, toolSetMaskViewModeCommand } from "./tool";
|
||||
export { toolChooseGenerateIntentCommand, toolCommands, toolEnterMaskEditCommand, toolEnterTemporaryPanCommand, toolExitMaskEditCommand, toolExitTemporaryPanCommand, toolSetActiveCommand, toolSetBrushPreviewCommand, toolSetBrushSettingsCommand, toolSetBrushStrokePreviewCommand, toolSetChromaKeySettingsCommand, toolSetGenerateSettingsCommand, toolSetMagicWandSettingsCommand, toolSetMaskViewModeCommand } from "./tool";
|
||||
export { transformBeginCommand, transformCommands, transformEndCommand, transformSetBoundsCommand, transformUpdateCommand } from "./transform";
|
||||
export type { TransformBeginPayload, TransformSetBoundsPayload, TransformUpdatePayload } from "./transform";
|
||||
export type { ToolEnterMaskEditPayload, ToolSetActivePayload, ToolSetBrushPreviewPayload, ToolSetBrushSettingsPayload, ToolSetBrushStrokePreviewPayload, ToolSetChromaKeySettingsPayload, ToolSetGenerateSettingsPayload, ToolSetMagicWandSettingsPayload, ToolSetMaskViewModePayload } from "./tool";
|
||||
export type { ToolChooseGenerateIntentPayload, ToolEnterMaskEditPayload, ToolSetActivePayload, ToolSetBrushPreviewPayload, ToolSetBrushSettingsPayload, ToolSetBrushStrokePreviewPayload, ToolSetChromaKeySettingsPayload, ToolSetGenerateSettingsPayload, ToolSetMagicWandSettingsPayload, ToolSetMaskViewModePayload } from "./tool";
|
||||
export {
|
||||
viewportCommands,
|
||||
viewportPanCommand,
|
||||
|
||||
@@ -44,7 +44,7 @@ import type {
|
||||
CommandPaletteSetSelectedIndexPayload,
|
||||
} from "./palette";
|
||||
import type { SelectionAddLayerPayload, SelectionSetPayload } from "./selection";
|
||||
import type { ToolEnterMaskEditPayload, ToolSetActivePayload, ToolSetBrushPreviewPayload, ToolSetBrushSettingsPayload, ToolSetBrushStrokePreviewPayload, ToolSetChromaKeySettingsPayload, ToolSetGenerateSettingsPayload, ToolSetMagicWandSettingsPayload, ToolSetMaskViewModePayload } from "./tool";
|
||||
import type { ToolChooseGenerateIntentPayload, ToolEnterMaskEditPayload, ToolSetActivePayload, ToolSetBrushPreviewPayload, ToolSetBrushSettingsPayload, ToolSetBrushStrokePreviewPayload, ToolSetChromaKeySettingsPayload, ToolSetGenerateSettingsPayload, ToolSetMagicWandSettingsPayload, ToolSetMaskViewModePayload } from "./tool";
|
||||
import type { TransformBeginPayload, TransformSetBoundsPayload, TransformUpdatePayload } from "./transform";
|
||||
import type { WorkspaceSetPanelPayload } from "./workspace";
|
||||
import type { EditorSetPointerSessionPayload } from "./editor";
|
||||
@@ -86,6 +86,7 @@ export type CommandPayloads = {
|
||||
[commandIds.selectionAddLayer]: SelectionAddLayerPayload;
|
||||
[commandIds.toolSetActive]: ToolSetActivePayload;
|
||||
[commandIds.toolSetGenerateSettings]: ToolSetGenerateSettingsPayload;
|
||||
[commandIds.toolChooseGenerateIntent]: ToolChooseGenerateIntentPayload;
|
||||
[commandIds.toolSetBrushSettings]: ToolSetBrushSettingsPayload;
|
||||
[commandIds.toolSetChromaKeySettings]: ToolSetChromaKeySettingsPayload;
|
||||
[commandIds.toolSetMagicWandSettings]: ToolSetMagicWandSettingsPayload;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { createInitialAppState } from "@editor/initial-state";
|
||||
import { toolEnterMaskEditCommand, toolEnterTemporaryPanCommand, toolExitMaskEditCommand, toolExitTemporaryPanCommand, toolSetActiveCommand, toolSetBrushPreviewCommand, toolSetBrushSettingsCommand, toolSetBrushStrokePreviewCommand, toolSetChromaKeySettingsCommand, toolSetGenerateSettingsCommand, toolSetMaskViewModeCommand } from "./tool";
|
||||
import { toolChooseGenerateIntentCommand, toolEnterMaskEditCommand, toolEnterTemporaryPanCommand, toolExitMaskEditCommand, toolExitTemporaryPanCommand, toolSetActiveCommand, toolSetBrushPreviewCommand, toolSetBrushSettingsCommand, toolSetBrushStrokePreviewCommand, toolSetChromaKeySettingsCommand, toolSetGenerateSettingsCommand, toolSetMaskViewModeCommand } from "./tool";
|
||||
|
||||
const defaultBrush = { color: "#111827", size: 8, hardness: 100 };
|
||||
const defaultChromaKey = { color: "#00ff00", tolerance: 32, softness: 24, feather: 0, choke: 0, despeckle: 0, spill: 50 };
|
||||
@@ -60,6 +60,15 @@ describe("tool commands", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("maps user intents to supported generation modes and a compatible architecture", () => {
|
||||
const zImage = toolSetGenerateSettingsCommand.execute({ state: createInitialAppState("Test") }, { architecture: "z-image" });
|
||||
const replace = toolChooseGenerateIntentCommand.execute({ state: zImage }, { intent: "replace" });
|
||||
const variations = toolChooseGenerateIntentCommand.execute({ state: replace }, { intent: "variations" });
|
||||
|
||||
expect(replace.editor.tools.generate).toMatchObject({ architecture: "sdxl", mode: "inpaint" });
|
||||
expect(variations.editor.tools.generate).toMatchObject({ architecture: "sdxl", mode: "image-to-image" });
|
||||
});
|
||||
|
||||
test("sets and clears brush preview", () => {
|
||||
const showing = toolSetBrushPreviewCommand.execute({ state: createInitialAppState("Test") }, { position: { x: 10, y: 20 } });
|
||||
const cleared = toolSetBrushPreviewCommand.execute({ state: showing }, undefined);
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Layer } from "@core/layer";
|
||||
import { getLayerMask } from "@core/layer-mask-utils";
|
||||
import type { MaskViewMode } from "@editor/state";
|
||||
import { generateArchitectureDefaults } from "@editor/tools";
|
||||
import type { BrushSettings, ChromaKeySettings, GenerateSettings, MagicWandSettings, ToolId } from "@editor/tools";
|
||||
import type { BrushSettings, ChromaKeySettings, GenerateIntent, GenerateSettings, MagicWandSettings, ToolId } from "@editor/tools";
|
||||
import type { Command } from "./command";
|
||||
import { commandIds } from "./ids";
|
||||
|
||||
@@ -16,6 +16,7 @@ export type ToolSetActivePayload = {
|
||||
export type ToolSetBrushSettingsPayload = Partial<BrushSettings>;
|
||||
|
||||
export type ToolSetGenerateSettingsPayload = Partial<GenerateSettings>;
|
||||
export type ToolChooseGenerateIntentPayload = { intent: GenerateIntent };
|
||||
|
||||
export type ToolSetChromaKeySettingsPayload = Partial<ChromaKeySettings>;
|
||||
|
||||
@@ -120,6 +121,25 @@ export const toolSetGenerateSettingsCommand: Command<ToolSetGenerateSettingsPayl
|
||||
},
|
||||
};
|
||||
|
||||
const modeByGenerateIntent: Record<GenerateIntent, GenerateSettings["mode"]> = {
|
||||
create: "text-to-image",
|
||||
replace: "inpaint",
|
||||
extend: "outpaint",
|
||||
variations: "image-to-image",
|
||||
};
|
||||
|
||||
export const toolChooseGenerateIntentCommand: Command<ToolChooseGenerateIntentPayload> = {
|
||||
id: commandIds.toolChooseGenerateIntent,
|
||||
name: "Choose AI edit intent",
|
||||
execute({ state }, payload) {
|
||||
const mode = modeByGenerateIntent[payload.intent];
|
||||
const architecture = generateArchitectureDefaults[state.editor.tools.generate.architecture].supportedModes.includes(mode)
|
||||
? state.editor.tools.generate.architecture
|
||||
: "sdxl";
|
||||
return toolSetGenerateSettingsCommand.execute({ state }, { architecture, mode });
|
||||
},
|
||||
};
|
||||
|
||||
export const toolSetBrushSettingsCommand: Command<ToolSetBrushSettingsPayload> = {
|
||||
id: commandIds.toolSetBrushSettings,
|
||||
name: "Set brush settings",
|
||||
@@ -339,6 +359,7 @@ export const toolExitTemporaryPanCommand: Command = {
|
||||
export const toolCommands = [
|
||||
toolSetActiveCommand,
|
||||
toolSetGenerateSettingsCommand,
|
||||
toolChooseGenerateIntentCommand,
|
||||
toolSetBrushSettingsCommand,
|
||||
toolSetChromaKeySettingsCommand,
|
||||
toolSetMagicWandSettingsCommand,
|
||||
|
||||
Reference in New Issue
Block a user