diff --git a/web/src/components/canvas/canvas-context-menu.tsx b/web/src/components/canvas/canvas-context-menu.tsx index b1dff8817..51d230c26 100644 --- a/web/src/components/canvas/canvas-context-menu.tsx +++ b/web/src/components/canvas/canvas-context-menu.tsx @@ -1,12 +1,13 @@ import { AnimatePresence, useReducedMotion } from "motion/react"; import { useEffect, useState, type CSSProperties, type ReactNode } from "react"; -import { ArrowLeft, Check, ChevronRight, Clapperboard, Clipboard, Copy, FolderOpen, FolderPlus, Image as ImageIcon, Layers3, Link2, Maximize2, Music2, PanelTop, Pencil, Plus, Redo2, Tags, Trash2, Type, Undo2, Upload, UserRound, Video } from "lucide-react"; +import { ArrowLeft, Check, ChevronRight, Clipboard, Copy, FolderOpen, FolderPlus, Image as ImageIcon, Layers3, Link2, Maximize2, PanelTop, Pencil, Plus, Redo2, Tags, Trash2, Undo2, Upload, UserRound } from "lucide-react"; +import { CanvasCreateMenu, type CanvasCreateCommand } from "@/components/canvas/canvas-create-menu"; import { aceternityMotion } from "@/lib/aceternity-motion"; import { SpotlightSurface } from "@/components/ui/aceternity/spotlight-surface"; -import { CanvasCreateCommandGrid, type CanvasCreateCommand } from "@/components/canvas/canvas-create-command-grid"; import { canvasThemes } from "@/lib/canvas-theme"; import { canvasNodeAssetCategory } from "@/lib/canvas/canvas-node-asset"; +import { resolveAddNodeMenuCommands, type AddNodeMenuContext } from "@/lib/canvas/tool-registry"; import { useThemeStore } from "@/stores/use-theme-store"; import { CanvasNodeType, type CanvasNodeData, type CanvasWorkspaceMode, type ContextMenuState, type Position } from "@/types/canvas"; @@ -32,6 +33,7 @@ type CanvasNodeContextMenuProps = { canPaste: boolean; onClose: () => void; onAddNode: (type: CanvasNodeType) => void; + onChooseStyle: () => void; onOpenDirector: (position: Position) => void; onUpload: () => void; onOpenAssets: () => void; @@ -63,6 +65,7 @@ export function CanvasNodeContextMenu({ canPaste, onClose, onAddNode, + onChooseStyle, onOpenDirector, onUpload, onOpenAssets, @@ -234,6 +237,7 @@ export function CanvasNodeContextMenu({ isProjectLinked={isProjectLinked} reducedMotion={Boolean(reducedMotion)} onAddNode={(type) => runAction(() => onAddNode(type))} + onChooseStyle={() => runAction(onChooseStyle)} onOpenDirector={() => runAction(() => onOpenDirector(menu.position))} onUpload={() => runAction(onUpload)} onOpenAssets={() => runAction(onOpenAssets)} @@ -245,27 +249,35 @@ export function CanvasNodeContextMenu({ ); } -function AddNodeContextMenu({ parentPosition, workspaceMode, isProjectLinked, reducedMotion, onAddNode, onOpenDirector, onUpload, onOpenAssets, onOpenProjectCharacters }: { parentPosition: { left: number; top: number }; workspaceMode: CanvasWorkspaceMode; isProjectLinked: boolean; reducedMotion: boolean; onAddNode: (type: CanvasNodeType) => void; onOpenDirector: () => void; onUpload: () => void; onOpenAssets: () => void; onOpenProjectCharacters: () => void }) { +function AddNodeContextMenu({ parentPosition, workspaceMode, isProjectLinked, reducedMotion, onAddNode, onChooseStyle, onOpenDirector, onUpload, onOpenAssets, onOpenProjectCharacters }: { parentPosition: { left: number; top: number }; workspaceMode: CanvasWorkspaceMode; isProjectLinked: boolean; reducedMotion: boolean; onAddNode: (type: CanvasNodeType) => void; onChooseStyle: () => void; onOpenDirector: () => void; onUpload: () => void; onOpenAssets: () => void; onOpenProjectCharacters: () => void }) { const theme = canvasThemes[useThemeStore((state) => state.theme)]; const left = getSubmenuLeft(parentPosition.left); - const simpleMode = workspaceMode === "simple"; - const nodeCommands: CanvasCreateCommand[] = [ - { id: "text", label: "文本", icon: , onClick: () => onAddNode(CanvasNodeType.Text) }, - { id: "drawing", label: "绘图", icon: , onClick: () => onAddNode(CanvasNodeType.Drawing) }, - { id: "script", label: "分镜脚本", icon: , badge: "核心", onClick: () => onAddNode(CanvasNodeType.Script) }, - ...(!simpleMode ? [{ id: "frame", label: "背板", icon: , onClick: () => onAddNode(CanvasNodeType.Frame) }] : []), - { id: "image", label: "图片", icon: , onClick: () => onAddNode(CanvasNodeType.Image) }, - { id: "video", label: "视频", icon: