diff --git a/apps/editor/src/ui/editor-app.tsx b/apps/editor/src/ui/editor-app.tsx index 52c23bf..b49dd73 100644 --- a/apps/editor/src/ui/editor-app.tsx +++ b/apps/editor/src/ui/editor-app.tsx @@ -89,7 +89,6 @@ import { createCreatorPathSteps, type CreatorPathStep } from "../creator-path"; import { AiContextSummary, AiProviderBoundary, - AssetStudioSidebar, BuildWorkspace, CollapsedPanelRail, iconSize, @@ -263,13 +262,9 @@ import { aiStudioReducer, initialAiStudioState } from "./features/ai/ai-studio-s import { AiStudioSteps } from "./features/ai/ai-studio-steps"; import { AiStudioWorkspace } from "./features/ai/ai-studio-workspace"; import { assetStudioReducer, initialAssetStudioState, type AssetStudioTool } from "./features/assets/asset-studio-state"; -import { AssetStudioWorkspace } from "./features/assets/asset-studio-workspace"; -import { AssetStudioPreview } from "./features/assets/asset-studio-preview"; -import { AssetStudioToolPanel } from "./features/assets/asset-studio-tool-panel"; +import { AssetStudioLaunchpad } from "./features/assets/asset-studio-launchpad"; import { initialSceneStudioState, sceneStudioReducer } from "./features/scenes/scene-studio-state"; -import { SceneTree } from "./features/scenes/scene-tree"; -import { SceneViewport } from "./features/scenes/scene-viewport"; -import { ScenesWorkspace } from "./features/scenes/scenes-workspace"; +import { SceneTreeLaunchpad, ScenesLaunchpad } from "./features/scenes/scenes-launchpad"; import { buildProjectResourceIndex, filterProjectResources, @@ -8104,39 +8099,43 @@ export function EditorApp({ gateway: injectedGateway }: EditorAppProps = {}) { } if (workspace === "scene") { return ( - ); } @@ -9712,108 +9711,117 @@ export function EditorApp({ gateway: injectedGateway }: EditorAppProps = {}) { ) : workspace === "assets" ? ( - -
- - - -
{activeAssetTool === "animation" ? (
Character Gym @@ -10125,7 +10133,7 @@ export function EditorApp({ gateway: injectedGateway }: EditorAppProps = {}) {
) : null} -
+ ) : workspace === "narrative" && currentFlowDraft ? ( ) : ( - - - + }} + actions={{ + viewport: { + boundsForGenerationGuideShape, + generationGuideColor, + insertGenerationGuidePointFromEvent, + insertWalkAreaPointFromEvent, + onCreateActor: createActor, + onCreateHotspot: createHotspot, + onCreateSceneLayer: createSceneLayer, + onSelectActor: selectActor, + onSelectHotspot: selectHotspot, + onSelectPickup: selectPickup, + onSelectPlayerInScene: selectPlayerInScene, + onSetActiveSceneTool: setActiveSceneTool, + onSetSceneInspectorTarget: setSceneInspectorTarget, + onSetSelectedGenerationGuideId: setSelectedGenerationGuideId, + onStartActorInteraction: startActorInteraction, + onStartActorSpotInteraction: startActorSpotInteraction, + onStartGenerationGuidePointInteraction: startGenerationGuidePointInteraction, + onStartGenerationGuideShapeInteraction: startGenerationGuideShapeInteraction, + onStartHotspotInteraction: startHotspotInteraction, + onStartHotspotSpotInteraction: startHotspotSpotInteraction, + onStartPickupInteraction: startPickupInteraction, + onStartPlayerStartInteraction: startPlayerStartInteraction, + onStartWalkAreaPointInteraction: startWalkAreaPointInteraction, + updateSceneDraft + } + }} + /> )} diff --git a/apps/editor/src/ui/features/assets/asset-studio-launchpad.tsx b/apps/editor/src/ui/features/assets/asset-studio-launchpad.tsx new file mode 100644 index 0000000..d829d95 --- /dev/null +++ b/apps/editor/src/ui/features/assets/asset-studio-launchpad.tsx @@ -0,0 +1,55 @@ +import type { ComponentProps, ReactNode } from "react"; +import { AssetStudioSidebar } from "../../editor-shell"; +import { AssetStudioPreview, type AssetStudioPreviewProps } from "./asset-studio-preview"; +import { AssetStudioToolPanel, type AssetStudioToolPanelProps } from "./asset-studio-tool-panel"; +import { + AssetStudioWorkspace, + type AssetStudioWorkspaceModel +} from "./asset-studio-workspace"; + +type AssetStudioSidebarProps = ComponentProps; + +type ActionKeys = { + [Key in keyof T]-?: T[Key] extends (...args: never[]) => unknown ? Key : never; +}[keyof T]; + +type ModelPart = Omit>; +type ActionsPart = Pick>; + +export interface AssetStudioLaunchpadModel { + preview: ModelPart; + sidebar: ModelPart; + toolPanel: ModelPart; + workspace: AssetStudioWorkspaceModel; +} + +export interface AssetStudioLaunchpadActions { + preview: ActionsPart; + sidebar: ActionsPart; + toolPanel: ActionsPart; +} + +export interface AssetStudioLaunchpadProps { + actions: AssetStudioLaunchpadActions; + children?: ReactNode; + model: AssetStudioLaunchpadModel; +} + +/** + * Asset Studio's composition boundary. The composition root supplies a + * serializable view model and explicit action groups; feature agents can own + * the preview, tool panel, and future animation surface without reaching into + * EditorGateway or sibling workspace state. + */ +export function AssetStudioLaunchpad({ actions, children, model }: AssetStudioLaunchpadProps) { + return ( + +
+ + + +
+ {children} +
+ ); +} diff --git a/apps/editor/src/ui/features/scenes/scenes-launchpad.tsx b/apps/editor/src/ui/features/scenes/scenes-launchpad.tsx new file mode 100644 index 0000000..0aa1bc2 --- /dev/null +++ b/apps/editor/src/ui/features/scenes/scenes-launchpad.tsx @@ -0,0 +1,46 @@ +import { SceneTree, type SceneTreeProps } from "./scene-tree"; +import { SceneViewport, type SceneViewportProps } from "./scene-viewport"; +import { + ScenesWorkspace, + type ScenesWorkspaceModel +} from "./scenes-workspace"; + +type ActionKeys = { + [Key in keyof T]-?: T[Key] extends (...args: never[]) => unknown ? Key : never; +}[keyof T]; + +type ModelPart = Omit>; +type ActionsPart = Pick>; + +export interface ScenesLaunchpadModel { + viewport: ModelPart; + workspace: ScenesWorkspaceModel; +} + +export interface ScenesLaunchpadActions { + viewport: ActionsPart; +} + +export interface ScenesLaunchpadProps { + actions: ScenesLaunchpadActions; + model: ScenesLaunchpadModel; +} + +export interface SceneTreeLaunchpadProps { + actions: ActionsPart; + model: ModelPart; +} + +/** Scene navigator boundary for the parallel Scenes workstream. */ +export function SceneTreeLaunchpad({ actions, model }: SceneTreeLaunchpadProps) { + return ; +} + +/** Scene viewport boundary for the parallel Scenes workstream. */ +export function ScenesLaunchpad({ actions, model }: ScenesLaunchpadProps) { + return ( + + + + ); +}