@dailies-studio/shot-editor 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.vite/manifest.json +382 -0
- package/dist/assets/AgentPanel-CQejLbiX.js +2 -0
- package/dist/assets/AgentPanel-DJEphah0.css +1 -0
- package/dist/assets/AgentQuestionDialog-BqkD0kXF.js +1 -0
- package/dist/assets/CodeStudio-Dv4ihHpz.js +23 -0
- package/dist/assets/CommentsPanel-B4yhhT1T.js +1 -0
- package/dist/assets/ComponentLibraryRail-Ch_dsAru.js +1 -0
- package/dist/assets/ComponentStage-BRhRotyH.js +1 -0
- package/dist/assets/CurvePane-BjFVabKX.css +1 -0
- package/dist/assets/CurvePane-R22WzllJ.js +1 -0
- package/dist/assets/ExportDialog-CWLQWTmG.js +2 -0
- package/dist/assets/FontPicker-DWKaYL7F.js +1 -0
- package/dist/assets/FontPicker-v0IOIArM.css +1 -0
- package/dist/assets/GenerateDrawer-Bh3SqDKt.js +2 -0
- package/dist/assets/InsertDrawer-Ce1fod1L.js +1 -0
- package/dist/assets/LibraryBrowser-D9sEGz5w.js +2 -0
- package/dist/assets/MakeItYoursSection-CMO4319_.js +2 -0
- package/dist/assets/MaterialGraphCanvas-BFzl4wWR.js +23 -0
- package/dist/assets/MaterialGraphCanvas-BIUD59ik.css +1 -0
- package/dist/assets/MaterialWorkspace-CqTWqaRA.js +14 -0
- package/dist/assets/PreferencesDialog-CBf9_OoD.js +1 -0
- package/dist/assets/PresetsSection-CUEaoCVU.js +1 -0
- package/dist/assets/SoundHistory-BeS8EW1h.js +1 -0
- package/dist/assets/SoundMode-BmcZru3i.js +3 -0
- package/dist/assets/StockSounds-DdAUGRYK.js +1 -0
- package/dist/assets/TemplateFieldSection-CaeXpLFo.js +1 -0
- package/dist/assets/VersionHistoryPanel-CxG6XhNP.js +1 -0
- package/dist/assets/board-B88EPuLO.css +1 -0
- package/dist/assets/board-CL-he7SL.js +3 -0
- package/dist/assets/components-0oOSPN0l.js +1 -0
- package/dist/assets/googleFontRanges-gp32wJMo.js +1 -0
- package/dist/assets/googleFonts-BNon6M7X.js +1 -0
- package/dist/assets/iconsAndAliases-DL7gXP5j.js +1863 -0
- package/dist/assets/index-4F5NQmI8.css +1 -0
- package/dist/assets/index-BGHQGV5z.js +117 -0
- package/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/assets/libraryModel-CpIwfFha.js +1 -0
- package/dist/assets/lucide-6iK64tTB.js +9319 -0
- package/dist/assets/motionStamp-CH-Hew4E.js +1 -0
- package/dist/assets/takeMeasure-Tdg0TxEi.js +1 -0
- package/dist/assets/webmcp-BsB9gxWC.js +2 -0
- package/dist/index.html +34 -3
- package/package.json +12 -9
- package/src/addFamilies.ts +66 -0
- package/src/api.ts +1631 -55
- package/src/app/App.tsx +977 -198
- package/src/app/lazyPanel.tsx +137 -0
- package/src/app/lazySurfaces.tsx +203 -0
- package/src/audio/index.tsx +41 -10
- package/src/audio/meter.ts +485 -0
- package/src/audio/meterMath.ts +273 -0
- package/src/audio/meterStore.ts +155 -0
- package/src/audio/offlineMix.ts +289 -0
- package/src/audio/preview.ts +928 -118
- package/src/bridge.ts +15 -5
- package/src/bridgeTypes.ts +1611 -36
- package/src/channels.ts +17 -32
- package/src/fonts/googleFonts.ts +4 -0
- package/src/hostApi.ts +174 -0
- package/src/icons.tsx +770 -0
- package/src/layerWords.ts +61 -0
- package/src/main.tsx +56 -4
- package/src/panels/ResizeHandle.tsx +33 -43
- package/src/panels/agent/AgentDots.tsx +36 -0
- package/src/panels/agent/AgentPanel.tsx +119 -43
- package/src/panels/agent/AgentQuestionDialog.tsx +202 -0
- package/src/panels/agent/agent.css +113 -97
- package/src/panels/agent/agentGate.ts +35 -0
- package/src/panels/code/CodeDefaultsPanel.tsx +345 -0
- package/src/panels/code/CodeStudio.tsx +373 -0
- package/src/panels/code/FileTree.tsx +265 -0
- package/src/panels/code/codeBufferGuard.ts +52 -0
- package/src/panels/code/codeParts.tsx +321 -0
- package/src/panels/comments/CommentComposer.tsx +239 -0
- package/src/panels/comments/CommentThread.tsx +346 -0
- package/src/panels/comments/CommentsPanel.tsx +336 -0
- package/src/panels/comments/InboxButton.tsx +131 -0
- package/src/panels/comments/MentionMenu.tsx +98 -0
- package/src/panels/comments/parts.tsx +171 -0
- package/src/panels/export/ExportDialog.tsx +919 -96
- package/src/panels/export/ExportScrim.tsx +57 -0
- package/src/panels/files/AssetsTab.tsx +656 -0
- package/src/panels/files/FilePanel.tsx +1466 -216
- package/src/panels/files/LayerMarks.tsx +40 -0
- package/src/panels/files/LeftColumn.tsx +37 -0
- package/src/panels/files/McpSection.tsx +690 -47
- package/src/panels/files/MissingAssetsNotice.tsx +60 -0
- package/src/panels/files/assetDrag.ts +79 -0
- package/src/panels/files/resourceParts.tsx +255 -0
- package/src/panels/fonts/FontPicker.tsx +762 -0
- package/src/panels/fonts/faceCache.ts +207 -0
- package/src/panels/fonts/fontPicker.css +271 -0
- package/src/panels/fonts/pickerModel.ts +265 -0
- package/src/panels/fonts/pickerRequest.ts +46 -0
- package/src/panels/header/AccountAvatar.tsx +76 -0
- package/src/panels/header/AgentChip.tsx +77 -0
- package/src/panels/header/AppMenu.tsx +213 -0
- package/src/panels/header/Header.tsx +564 -84
- package/src/panels/header/HistoryControls.tsx +31 -5
- package/src/panels/header/PresenceStack.tsx +329 -0
- package/src/panels/header/ProjectTitle.tsx +232 -0
- package/src/panels/header/ShareButton.tsx +59 -0
- package/src/panels/header/StatusBadges.tsx +358 -27
- package/src/panels/header/SyncDeletedDialog.tsx +88 -0
- package/src/panels/header/ZoomControls.tsx +46 -15
- package/src/panels/header/agentHandoff.ts +52 -0
- package/src/panels/header/leave.ts +26 -0
- package/src/panels/help/HelpSection.tsx +189 -163
- package/src/panels/insert/InsertDrawer.tsx +723 -0
- package/src/panels/insert/iconSet.ts +109 -0
- package/src/panels/inspector/ExposeDot.tsx +117 -0
- package/src/panels/inspector/FramingRows.tsx +314 -44
- package/src/panels/inspector/InspectorFooter.tsx +91 -0
- package/src/panels/inspector/InspectorHead.tsx +425 -0
- package/src/panels/inspector/InspectorPanel.tsx +408 -124
- package/src/panels/inspector/KeyframeDot.tsx +373 -0
- package/src/panels/inspector/KeyframeSection.tsx +257 -0
- package/src/panels/inspector/MarkerSection.tsx +55 -11
- package/src/panels/inspector/ParamRow.tsx +84 -53
- package/src/panels/inspector/RightColumn.tsx +152 -0
- package/src/panels/inspector/TimeSection.tsx +866 -0
- package/src/panels/inspector/animate/EaseControl.tsx +244 -0
- package/src/panels/inspector/animate/PresetsSection.tsx +135 -0
- package/src/panels/inspector/animate/ShotSection.tsx +562 -48
- package/src/panels/inspector/design/AlignRow.tsx +95 -31
- package/src/panels/inspector/design/AppearanceSection.tsx +118 -9
- package/src/panels/inspector/design/ClonerSection.tsx +323 -62
- package/src/panels/inspector/design/ComponentSection.tsx +50 -43
- package/src/panels/inspector/design/CornerSection.tsx +45 -14
- package/src/panels/inspector/design/DefinitionProps.tsx +315 -0
- package/src/panels/inspector/design/DefinitionSection.tsx +136 -0
- package/src/panels/inspector/design/DeviceSection.tsx +210 -0
- package/src/panels/inspector/design/FillSection.tsx +83 -51
- package/src/panels/inspector/design/FontField.tsx +196 -0
- package/src/panels/inspector/design/HtmlSection.tsx +23 -12
- package/src/panels/inspector/design/InstanceSection.tsx +373 -154
- package/src/panels/inspector/design/MaskSection.tsx +84 -0
- package/src/panels/inspector/design/MaterialSection.tsx +177 -0
- package/src/panels/inspector/design/MediaSection.tsx +273 -120
- package/src/panels/inspector/design/MeshSection.tsx +910 -82
- package/src/panels/inspector/design/PaintRows.tsx +550 -0
- package/src/panels/inspector/design/PlateStyleSection.tsx +177 -0
- package/src/panels/inspector/design/ShadowSection.tsx +221 -48
- package/src/panels/inspector/design/SplineFollowSection.tsx +235 -0
- package/src/panels/inspector/design/StrokeSection.tsx +228 -43
- package/src/panels/inspector/design/TemplateFieldSection.tsx +57 -0
- package/src/panels/inspector/design/TransformSection.tsx +244 -50
- package/src/panels/inspector/design/TypographySection.tsx +679 -110
- package/src/panels/inspector/layout.ts +295 -0
- package/src/panels/inspector/propValue.ts +199 -0
- package/src/panels/inspector/scene/CameraSection.tsx +232 -22
- package/src/panels/inspector/scene/EffectsSection.tsx +722 -71
- package/src/panels/inspector/scene/MakeItYoursSection.tsx +180 -0
- package/src/panels/inspector/scene/SceneDocSection.tsx +191 -0
- package/src/panels/inspector/scene/SceneSection.tsx +219 -44
- package/src/panels/inspector/scene/TransitionSection.tsx +523 -72
- package/src/panels/inspector/storyboard/StoryboardReferenceSection.tsx +593 -0
- package/src/panels/inspector/storyboard/VideoStill.tsx +120 -0
- package/src/panels/inspector/timeModel.ts +190 -0
- package/src/panels/inspector/useDocWrite.ts +438 -146
- package/src/panels/library/LibraryBrowser.tsx +435 -0
- package/src/panels/library/LibraryGrid.tsx +190 -0
- package/src/panels/library/LibraryPreviewPanel.tsx +349 -0
- package/src/panels/library/LibraryRail.tsx +84 -0
- package/src/panels/library/LibrarySoundPanel.tsx +293 -0
- package/src/panels/library/SoundHistory.tsx +245 -0
- package/src/panels/library/StockSounds.tsx +390 -0
- package/src/panels/library/libraryModel.ts +147 -0
- package/src/panels/library/stockSearch.ts +77 -0
- package/src/panels/maskMarks.tsx +117 -0
- package/src/panels/material/MaterialCommentNode.tsx +54 -0
- package/src/panels/material/MaterialGraphCanvas.tsx +861 -0
- package/src/panels/material/MaterialGraphMenu.tsx +45 -0
- package/src/panels/material/MaterialGroupNode.tsx +56 -0
- package/src/panels/material/MaterialLibrary.tsx +253 -0
- package/src/panels/material/MaterialNode.tsx +453 -0
- package/src/panels/material/MaterialNodePalette.tsx +349 -0
- package/src/panels/material/MaterialParameterControls.tsx +525 -0
- package/src/panels/material/MaterialRerouteNode.tsx +42 -0
- package/src/panels/material/MaterialWorkspace.tsx +501 -0
- package/src/panels/material/NodePreview.tsx +70 -0
- package/src/panels/material/flowModel.ts +441 -0
- package/src/panels/material/parameterValues.ts +231 -0
- package/src/panels/material/previewScheduler.ts +235 -0
- package/src/panels/material/reactFlow.css +6 -0
- package/src/panels/material/socketGlyph.ts +85 -0
- package/src/panels/material/viewportMemory.ts +58 -0
- package/src/panels/preferences/PreferencesDialog.tsx +215 -0
- package/src/panels/share/ShareComponentDialog.tsx +247 -0
- package/src/panels/stage/StageMenu.tsx +35 -5
- package/src/panels/stage/StagePanel.tsx +338 -23
- package/src/panels/stage/cellSlots.tsx +70 -0
- package/src/panels/storyboard/BoardCanvas.tsx +739 -0
- package/src/panels/storyboard/BoardCursors.tsx +158 -0
- package/src/panels/storyboard/BoardDropDialog.tsx +161 -0
- package/src/panels/storyboard/BoardPlan.tsx +42 -0
- package/src/panels/storyboard/ComponentSheet.tsx +187 -0
- package/src/panels/storyboard/ComponentStage.tsx +235 -0
- package/src/panels/storyboard/MiniSketch.tsx +173 -0
- package/src/panels/storyboard/PartPicker.tsx +64 -0
- package/src/panels/storyboard/PlanPanel.tsx +617 -0
- package/src/panels/storyboard/ReferencePreview.tsx +217 -0
- package/src/panels/storyboard/ShotBrief.tsx +360 -0
- package/src/panels/storyboard/ShotCard.tsx +251 -0
- package/src/panels/storyboard/StagePreview.tsx +348 -0
- package/src/panels/storyboard/StillThumbs.tsx +162 -0
- package/src/panels/storyboard/StoryboardView.tsx +79 -0
- package/src/panels/storyboard/board.css +1065 -0
- package/src/panels/storyboard/board.ts +12 -0
- package/src/panels/storyboard/boardClipboard.ts +111 -0
- package/src/panels/storyboard/boardOrder.ts +68 -0
- package/src/panels/storyboard/boardRows.tsx +425 -0
- package/src/panels/storyboard/liveCap.ts +90 -0
- package/src/panels/storyboard/plan.css +295 -0
- package/src/panels/storyboard/posterCache.ts +133 -0
- package/src/panels/storyboard/shotboard/ComponentPicker.tsx +373 -0
- package/src/panels/storyboard/shotboard/ImagePicker.tsx +145 -0
- package/src/panels/storyboard/shotboard/ShotBoard.tsx +292 -0
- package/src/panels/storyboard/shotboard/SketchCanvas.tsx +443 -0
- package/src/panels/storyboard/shotboard/SketchInspector.tsx +471 -0
- package/src/panels/storyboard/shotboard/SketchItem.tsx +240 -0
- package/src/panels/storyboard/shotboard/SketchLayers.tsx +130 -0
- package/src/panels/storyboard/shotboard/SketchPlay.tsx +108 -0
- package/src/panels/storyboard/shotboard/SketchStrip.tsx +178 -0
- package/src/panels/storyboard/shotboard/SketchToolFooter.tsx +99 -0
- package/src/panels/storyboard/shotboard/sketch.css +1392 -0
- package/src/panels/storyboard/shotboard/sketchModel.ts +219 -0
- package/src/panels/storyboard/storyboardDrop.ts +164 -0
- package/src/panels/studio/ComponentLibraryRail.tsx +346 -0
- package/src/panels/studio/ComponentSidePanel.tsx +355 -0
- package/src/panels/studio/ComponentStudio.tsx +243 -0
- package/src/panels/studio/ComponentsHome.tsx +318 -0
- package/src/panels/studio/ComponentsPreview.tsx +179 -0
- package/src/panels/studio/EveryUse.tsx +244 -0
- package/src/panels/studio/ThisUsePanel.tsx +679 -0
- package/src/panels/studio/componentParts.tsx +341 -0
- package/src/panels/studio/components.ts +6 -0
- package/src/panels/studio/newCodeComponent.ts +66 -0
- package/src/panels/timeline/AudioFxButton.tsx +290 -0
- package/src/panels/timeline/AudioLane.tsx +674 -85
- package/src/panels/timeline/BlockRow.tsx +154 -85
- package/src/panels/timeline/ChannelRow.tsx +378 -129
- package/src/panels/timeline/CurvePane.tsx +508 -0
- package/src/panels/timeline/Filmstrip.tsx +361 -0
- package/src/panels/timeline/GenerateDrawer.tsx +407 -0
- package/src/panels/timeline/KeyStretch.tsx +115 -0
- package/src/panels/timeline/LifespanRow.tsx +730 -47
- package/src/panels/timeline/MarkerLane.tsx +46 -8
- package/src/panels/timeline/PlayButton.tsx +91 -0
- package/src/panels/timeline/PropertyPicker.tsx +254 -0
- package/src/panels/timeline/ShotRow.tsx +400 -0
- package/src/panels/timeline/SoundMode.tsx +1406 -0
- package/src/panels/timeline/TimelineDock.tsx +2338 -272
- package/src/panels/timeline/TransportVolume.tsx +163 -0
- package/src/panels/timeline/beatRuler.ts +74 -0
- package/src/panels/timeline/curveModel.ts +500 -0
- package/src/panels/timeline/duckUnderVoice.ts +68 -0
- package/src/panels/timeline/keyframeMenu.ts +138 -0
- package/src/panels/timeline/labelWidth.ts +49 -0
- package/src/panels/timeline/marquee.ts +155 -0
- package/src/panels/timeline/model.ts +1860 -199
- package/src/panels/timeline/snap.ts +125 -43
- package/src/panels/timeline/staggerPreview.tsx +92 -0
- package/src/panels/timeline/takeMeasure.ts +72 -0
- package/src/panels/timeline/useLive.ts +48 -0
- package/src/panels/timeline/viewport.ts +234 -0
- package/src/panels/toolbar/BackChip.tsx +116 -0
- package/src/panels/toolbar/CameraViewBar.tsx +118 -49
- package/src/panels/toolbar/CanvasBar.tsx +117 -0
- package/src/panels/toolbar/InsertButton.tsx +38 -0
- package/src/panels/toolbar/IsolationTrail.tsx +156 -0
- package/src/panels/toolbar/PanelToggles.tsx +86 -0
- package/src/panels/toolbar/ShadingBar.tsx +119 -26
- package/src/panels/toolbar/ToolDockBar.tsx +329 -80
- package/src/panels/toolbar/ToolFooter.tsx +102 -0
- package/src/panels/toolbar/ViewModeBar.tsx +247 -38
- package/src/panels/toolbar/WorkPlaneBar.tsx +94 -0
- package/src/panels/toolbar/useAddRows.tsx +326 -0
- package/src/panels/toolbar/useDismiss.ts +122 -0
- package/src/panels/versions/VersionHistoryPanel.tsx +274 -0
- package/src/panels/versions/versionModel.ts +103 -0
- package/src/panels/virtualWindow.ts +271 -0
- package/src/shotTokens.css +151 -60
- package/src/stage/FrustumGizmo.tsx +504 -84
- package/src/stage/GridPlane.tsx +225 -16
- package/src/stage/NodePreviews.tsx +628 -0
- package/src/stage/PerfHud.tsx +437 -47
- package/src/stage/SplitRenderer.tsx +816 -169
- package/src/stage/StageApp.tsx +4274 -486
- package/src/stage/StageRootBoundary.tsx +114 -0
- package/src/stage/StageTools.tsx +651 -151
- package/src/stage/TransformGizmo.tsx +696 -0
- package/src/stage/adaptivePresentation.ts +145 -0
- package/src/stage/bridgeClient.ts +2522 -41
- package/src/stage/exportWorker.ts +9 -0
- package/src/stage/feed.ts +305 -14
- package/src/stage/fontPreview.ts +176 -0
- package/src/stage/frustumGeometry.ts +319 -1
- package/src/stage/furnitureTokens.ts +33 -0
- package/src/stage/gizmoMath.ts +508 -16
- package/src/stage/gpuTimer.ts +276 -0
- package/src/stage/instanceModules.ts +194 -33
- package/src/stage/interactions/move.ts +24 -5
- package/src/stage/isolation.ts +291 -33
- package/src/stage/jsSelfProfiler.ts +325 -0
- package/src/stage/main.tsx +116 -16
- package/src/stage/modalState.ts +222 -23
- package/src/stage/moduleEpoch.ts +60 -0
- package/src/stage/motionPathStage.ts +279 -0
- package/src/stage/motionPreview.ts +74 -0
- package/src/stage/overlays/Overlays.tsx +1112 -159
- package/src/stage/overlays/Rulers.tsx +495 -0
- package/src/stage/panes.ts +159 -10
- package/src/stage/project.ts +68 -3
- package/src/stage/renderScaleController.ts +730 -0
- package/src/stage/rulers.ts +129 -0
- package/src/stage/sceneExtent.ts +75 -0
- package/src/stage/shading.ts +20 -0
- package/src/stage/splineStage.ts +632 -0
- package/src/stage/stagePerformanceTelemetry.ts +717 -0
- package/src/stage/stageTheme.ts +36 -0
- package/src/stage/stageWarmup.ts +11 -0
- package/src/stage/textAutoSize.ts +124 -0
- package/src/stage/tier1Export.ts +641 -0
- package/src/stage/tokenColor.ts +14 -9
- package/src/stage/view.ts +56 -9
- package/src/stage/workingView.ts +277 -33
- package/src/state/accountPrefs.ts +261 -0
- package/src/state/agentActions.ts +173 -15
- package/src/state/agentActivity.ts +198 -0
- package/src/state/agentQuestion.ts +239 -0
- package/src/state/bootOpen.ts +42 -0
- package/src/state/cameraVerbs.ts +139 -0
- package/src/state/clientId.ts +6 -1
- package/src/state/comments.ts +1099 -0
- package/src/state/context.tsx +19 -1
- package/src/state/editorPrefs.ts +220 -0
- package/src/state/errorReports.ts +121 -0
- package/src/state/fieldWrite.ts +161 -0
- package/src/state/fontRecents.ts +70 -0
- package/src/state/fonts.ts +656 -0
- package/src/state/graphClipboard.ts +414 -0
- package/src/state/imageThumbs.ts +216 -0
- package/src/state/insert.ts +444 -67
- package/src/state/isolationTrail.ts +92 -0
- package/src/state/keyMoves.ts +134 -0
- package/src/state/keyframeClipboard.ts +177 -0
- package/src/state/keymap.ts +1153 -117
- package/src/state/layoutPrefs.ts +272 -0
- package/src/state/layouts.ts +205 -0
- package/src/state/measureMedia.ts +167 -0
- package/src/state/menu.ts +2341 -28
- package/src/state/motionStamp.ts +7 -0
- package/src/state/panelSize.ts +375 -5
- package/src/state/pendingChanges.ts +119 -0
- package/src/state/playHold.ts +78 -0
- package/src/state/playbackPreparation.ts +562 -0
- package/src/state/posterCapture.ts +242 -0
- package/src/state/presence.ts +254 -0
- package/src/state/projectComponents.ts +160 -0
- package/src/state/renderEvents.ts +298 -18
- package/src/state/runtimeErrors.ts +46 -0
- package/src/state/selection.ts +12 -0
- package/src/state/shortcuts.ts +1606 -0
- package/src/state/sketchGuide.ts +51 -0
- package/src/state/splineRefs.ts +87 -0
- package/src/state/stageHealth.ts +259 -0
- package/src/state/stageWatchdog.ts +47 -0
- package/src/state/stillStage.ts +330 -0
- package/src/state/stillThumbs.ts +474 -0
- package/src/state/store.ts +23591 -2982
- package/src/state/storyboardModel.ts +528 -0
- package/src/state/sync.ts +1257 -0
- package/src/state/syncCache.ts +159 -0
- package/src/state/triangles.ts +13 -0
- package/src/state/types.ts +1698 -55
- package/src/state/unsavedGuard.ts +49 -0
- package/src/state/viewMode.ts +200 -0
- package/src/state/webmcp.ts +1128 -0
- package/src/state/workspace.ts +1147 -0
- package/src/styles/assets-tab.css +304 -0
- package/src/styles/canvas.css +545 -0
- package/src/styles/comments.css +1435 -0
- package/src/styles/controls.css +162 -0
- package/src/styles/dialogs.css +390 -0
- package/src/styles/insert-drawer.css +586 -0
- package/src/styles/inspector-board.css +207 -0
- package/src/styles/inspector-object.css +486 -0
- package/src/styles/inspector-shot.css +252 -0
- package/src/styles/inspector.css +360 -0
- package/src/styles/left-column.css +1628 -0
- package/src/styles/library-preview.css +575 -0
- package/src/styles/library.css +512 -0
- package/src/styles/modes/code.css +569 -0
- package/src/styles/modes/component.css +1561 -0
- package/src/styles/modes/material.css +1201 -0
- package/src/styles/modes/storyboard.css +518 -0
- package/src/styles/share-component.css +49 -0
- package/src/styles/shell.css +653 -0
- package/src/styles/shot-brief.css +360 -0
- package/src/styles/states.css +76 -0
- package/src/styles/sync.css +380 -0
- package/src/styles/timeline-graph.css +384 -0
- package/src/styles/timeline-meters.css +89 -0
- package/src/styles/timeline-rows.css +1959 -0
- package/src/styles/timeline-sound.css +1003 -0
- package/src/styles/timeline.css +754 -0
- package/src/styles/tool-footer.css +525 -0
- package/src/styles/topbar.css +886 -0
- package/src/styles/versions.css +262 -0
- package/src/styles.css +72 -2921
- package/src/tools.ts +108 -23
- package/dist/assets/index-B7notge7.css +0 -1
- package/dist/assets/index-BBE6Ta9L.js +0 -52
- package/src/panels/files/icons.tsx +0 -118
- package/src/panels/header/DocSwitcher.tsx +0 -85
- package/src/panels/header/TransportBar.tsx +0 -86
- package/src/panels/inspector/animate/BlockTiming.tsx +0 -341
- package/src/panels/inspector/animate/DuringBlocks.tsx +0 -85
- package/src/panels/inspector/animate/InOutPresets.tsx +0 -57
- package/src/panels/inspector/animate/ResolvedChannels.tsx +0 -150
- package/src/panels/inspector/animate/useBlocks.ts +0 -43
- package/src/panels/material/MaterialPicker.tsx +0 -172
- package/src/panels/timeline/SceneStrip.tsx +0 -145
- package/src/panels/toolbar/AddMenu.tsx +0 -230
- package/src/stage/MoveGizmo.tsx +0 -411
|
@@ -6,39 +6,66 @@
|
|
|
6
6
|
// ponytail: uniform radius only; add the per-corner expander when a template
|
|
7
7
|
// needs one.
|
|
8
8
|
import { InspectorRow, InspectorSection, NumberField } from "@dailies-studio/ui";
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
9
|
+
import { KeyframeDot } from "../KeyframeDot.js";
|
|
10
|
+
import type { CornerRadius, Layer3D, LayerPaint } from "@dailies-studio/shot/doc";
|
|
11
|
+
import { useSelectedLayers, useSelectionScrub, useSelectionValue, useSelectionWrite } from "../useDocWrite.js";
|
|
12
|
+
|
|
13
|
+
/** The four corners this section's one field writes, in the schema's own key
|
|
14
|
+
* order — which is also the order codegen prints them in. */
|
|
15
|
+
const RADIUS_PATHS = ["paint.radius.tl", "paint.radius.tr", "paint.radius.br", "paint.radius.bl"] as const;
|
|
16
|
+
/** The same four, as the diamond's tooltip names what it keys together. */
|
|
17
|
+
const RADIUS_PARTS = ["Top left", "top right", "bottom right", "bottom left"] as const;
|
|
11
18
|
|
|
12
19
|
export function CornerSection() {
|
|
13
20
|
const write = useSelectionWrite();
|
|
14
21
|
const radius = useSelectionValue((layer) => uniformOf(layer.paint.radius));
|
|
22
|
+
// Mixed INSIDE one layer too: an edit writes one value to all four corners,
|
|
23
|
+
// so a layer with per-corner radii reads Mixed before that flattens it.
|
|
24
|
+
const cornersDiffer = useSelectedLayers().some((layer) => !isUniform(layer.paint.radius));
|
|
25
|
+
// ONE builder for the typed value and the drag, because a capture is handed a
|
|
26
|
+
// layer out of the gesture's BASE document: a drag that re-derived the corner
|
|
27
|
+
// from what the panel last rendered would compound its own moves.
|
|
28
|
+
const scrub = useSelectionScrub((layer, raw) => withRadius(layer, raw as number));
|
|
15
29
|
|
|
16
30
|
return (
|
|
17
|
-
<InspectorSection title="Corner" persistKey="shot:corner">
|
|
31
|
+
<InspectorSection className="insp-object" title="Corner" persistKey="shot:corner">
|
|
32
|
+
{/* ONE diamond for FOUR paths: the control writes all four corners, so it
|
|
33
|
+
has one value and one keyframe gesture, and no expose pin (a pin
|
|
34
|
+
publishes one target, and one corner is not what this row edits).
|
|
35
|
+
See KeyframeDot. */}
|
|
18
36
|
<InspectorRow>
|
|
19
37
|
<NumberField
|
|
20
38
|
value={radius.value ?? 0}
|
|
21
|
-
mixed={radius.mixed}
|
|
39
|
+
mixed={radius.mixed || cornersDiffer}
|
|
22
40
|
label="Radius"
|
|
23
41
|
ariaLabel="Corner radius"
|
|
24
42
|
unit="px"
|
|
25
43
|
min={0}
|
|
44
|
+
// No upper limit: a big enough radius is a pill shape.
|
|
26
45
|
step={1}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
? withoutRadius(layer.paint)
|
|
33
|
-
: { ...layer.paint, radius: { tl: next, tr: next, br: next, bl: next } },
|
|
34
|
-
}))
|
|
35
|
-
}
|
|
46
|
+
trailing={<KeyframeDot path={RADIUS_PATHS} label="Radius" parts={RADIUS_PARTS} />}
|
|
47
|
+
onCommit={(next) => write((layer) => withRadius(layer, next))}
|
|
48
|
+
onScrubStart={scrub.start}
|
|
49
|
+
onScrub={scrub.move}
|
|
50
|
+
onScrubEnd={scrub.end}
|
|
36
51
|
/>
|
|
37
52
|
</InspectorRow>
|
|
38
53
|
</InspectorSection>
|
|
39
54
|
);
|
|
40
55
|
}
|
|
41
56
|
|
|
57
|
+
/** 0 or less DELETES the key rather than storing a zero radius: absent already
|
|
58
|
+
* means square corners, and codegen prints the block by key order. */
|
|
59
|
+
function withRadius(layer: Layer3D, next: number): Layer3D {
|
|
60
|
+
return {
|
|
61
|
+
...layer,
|
|
62
|
+
paint:
|
|
63
|
+
next <= 0
|
|
64
|
+
? withoutRadius(layer.paint)
|
|
65
|
+
: { ...layer.paint, radius: { tl: next, tr: next, br: next, bl: next } },
|
|
66
|
+
} as Layer3D;
|
|
67
|
+
}
|
|
68
|
+
|
|
42
69
|
/** The largest corner, so a document with mixed corners reads as the shape the
|
|
43
70
|
* author sees rather than as zero. */
|
|
44
71
|
function uniformOf(radius: CornerRadius | undefined): number {
|
|
@@ -46,7 +73,11 @@ function uniformOf(radius: CornerRadius | undefined): number {
|
|
|
46
73
|
return Math.max(radius.tl, radius.tr, radius.br, radius.bl);
|
|
47
74
|
}
|
|
48
75
|
|
|
49
|
-
function
|
|
76
|
+
function isUniform(radius: CornerRadius | undefined): boolean {
|
|
77
|
+
return radius === undefined || (radius.tl === radius.tr && radius.tr === radius.br && radius.br === radius.bl);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function withoutRadius(paint: LayerPaint): LayerPaint {
|
|
50
81
|
const { radius: _drop, ...rest } = paint;
|
|
51
82
|
return rest;
|
|
52
83
|
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
// THE PROPS PLAYGROUND: a definition's published surface, LIVE.
|
|
2
|
+
//
|
|
3
|
+
// The ledger this replaces listed the props and let you rename or retire them,
|
|
4
|
+
// which meant the one panel naming a component's controls was the one place
|
|
5
|
+
// they could not be turned. An author had to place an instance to find out what
|
|
6
|
+
// their own component's Colour prop did.
|
|
7
|
+
//
|
|
8
|
+
// So every row is now the control itself, and it is deliberately the SAME row
|
|
9
|
+
// as the instance panel's: one `PropRow` over the control the prop's target
|
|
10
|
+
// describes (`exposedRowOf`: a published 0..1 opacity is a bounded field, a
|
|
11
|
+
// published enum keeps its options, a published text keeps its line breaks),
|
|
12
|
+
// with one drag bracket per row. What differs is only the subject: there the
|
|
13
|
+
// value belongs to a placement, here it belongs to the definition.
|
|
14
|
+
//
|
|
15
|
+
// ── WHAT A ROW READS, AND WHY IT IS NOT `prop.default` ──────────────────
|
|
16
|
+
//
|
|
17
|
+
// The interior layer is the RUNTIME truth: `applyOverrides` skips a prop no
|
|
18
|
+
// instance overrides, so an un-overridden placement renders the layer's own
|
|
19
|
+
// stored value. `prop.default` is a mirror, kept in step by `setExposedValue`
|
|
20
|
+
// writing both halves in one transaction, and it drifts the moment the
|
|
21
|
+
// published field is edited anywhere else (the layer's own section, a stage
|
|
22
|
+
// drag, an agent's `update_layer`). This panel reads the layer, else what the
|
|
23
|
+
// definition draws there (`exposedMasterValue`), so it can never show a number
|
|
24
|
+
// the stage disagrees with.
|
|
25
|
+
//
|
|
26
|
+
// ── TRY FIRST, SAVE ON PURPOSE ──────────────────────────────────────────
|
|
27
|
+
//
|
|
28
|
+
// With "Apply to all instances" off (the default) a turn is only TRIED:
|
|
29
|
+
// `playComponentProp` holds it and the stage draws it the way a placement's
|
|
30
|
+
// overrides are drawn. The document is untouched until the box is ticked,
|
|
31
|
+
// which saves what was tried in one undo step (`setComponentApplyAll`).
|
|
32
|
+
//
|
|
33
|
+
// THE HEAD'S RESET DROPS WHAT IS TRIED, and nothing else, so it is drawn
|
|
34
|
+
// only while Apply is off. With Apply on, a turn writes the master itself:
|
|
35
|
+
// nothing is ever tried, no row differs from the master, and undo takes a
|
|
36
|
+
// turn back, so a Reset there could never be pressed. One there once put
|
|
37
|
+
// each prop back to its published `default`, and that only ever did anything
|
|
38
|
+
// where the default had drifted: it wrote the stale value back over the
|
|
39
|
+
// author's later edit.
|
|
40
|
+
//
|
|
41
|
+
// ── ONE IMPLEMENTATION, TWO FACES ───────────────────────────────────────
|
|
42
|
+
//
|
|
43
|
+
// The inspector renders this for a definition on both faces (the Studio face
|
|
44
|
+
// and the Layers face with nothing selected). A second copy would be two
|
|
45
|
+
// widget vocabularies over one document field.
|
|
46
|
+
import { IconClose, IconDots, InspectorSection, PropRow, useContextMenu, useLocked, usePrompt } from "@dailies-studio/ui";
|
|
47
|
+
import type { PromptRequest, PropControlAsset } from "@dailies-studio/ui";
|
|
48
|
+
import { controlLabel } from "@dailies-studio/contract";
|
|
49
|
+
import { exposedMasterValue, readAtPath, setExposedValue } from "@dailies-studio/shot/doc";
|
|
50
|
+
import type { ComponentDef3D, ExposedProp3D } from "@dailies-studio/shot/doc";
|
|
51
|
+
import type { Value } from "@dailies-studio/engine";
|
|
52
|
+
import { useMemo, useRef } from "react";
|
|
53
|
+
import { useShotEditor, useStore } from "../../../state/context.js";
|
|
54
|
+
import { ApplyAllToggle } from "../../studio/componentParts.js";
|
|
55
|
+
import { coercePropValue, exposedRowOf, masterRowValue, projectAssetsOf, propEditOf, shownPropValue } from "../propValue.js";
|
|
56
|
+
import { useScrub } from "../useDocWrite.js";
|
|
57
|
+
|
|
58
|
+
export function DefinitionProps({ def }: { def: ComponentDef3D }) {
|
|
59
|
+
// ONE dialog for the whole section, not one per row: `usePrompt` mounts a
|
|
60
|
+
// `PromptDialog`, and a definition with a dozen props would otherwise mount a
|
|
61
|
+
// dozen of them to show at most one.
|
|
62
|
+
const { prompt, dialog } = usePrompt();
|
|
63
|
+
const store = useStore();
|
|
64
|
+
const viewer = useShotEditor((s) => s.readOnly);
|
|
65
|
+
const saving = useShotEditor((s) => s.componentApplyAll) && !viewer;
|
|
66
|
+
const tried = useShotEditor((s) => Object.keys(s.componentPlay).length);
|
|
67
|
+
const assetTable = useShotEditor((s) => s.doc?.assets);
|
|
68
|
+
const assets = useMemo(() => projectAssetsOf(assetTable), [assetTable]);
|
|
69
|
+
// RESET: drop every tried value. Only while Apply is off (see the header).
|
|
70
|
+
const reset = saving ? null : (
|
|
71
|
+
<button
|
|
72
|
+
type="button"
|
|
73
|
+
className="props-head-reset"
|
|
74
|
+
data-testid="definition-props-reset"
|
|
75
|
+
disabled={tried === 0}
|
|
76
|
+
title={tried === 0 ? "Nothing tried" : "Drop every tried value"}
|
|
77
|
+
onClick={(e) => {
|
|
78
|
+
e.stopPropagation();
|
|
79
|
+
store.resetComponentPlay();
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
Reset
|
|
83
|
+
</button>
|
|
84
|
+
);
|
|
85
|
+
return (
|
|
86
|
+
<InspectorSection className="insp-object" title="Properties" persistKey="shot:definition-exposed" action={reset}>
|
|
87
|
+
{dialog}
|
|
88
|
+
{def.exposed.length === 0 ? null : <ApplyAllToggle disabled={viewer} disabledReason="View only" />}
|
|
89
|
+
{def.exposed.length === 0 ? (
|
|
90
|
+
// NAMES THE ONE WAY IN. An empty panel that only says it is empty is a
|
|
91
|
+
// dead end, and the affordance it points at is not on this face: the
|
|
92
|
+
// pin sits beside the keyframe diamond, inside a field box of the layer
|
|
93
|
+
// that owns the field, on the Layers face.
|
|
94
|
+
<p className="insp-empty">
|
|
95
|
+
Nothing published yet. Open the <strong>Edit</strong> tab, select a layer, and press the pin
|
|
96
|
+
inside any property's field to publish it. Every instance can then override it.
|
|
97
|
+
</p>
|
|
98
|
+
) : (
|
|
99
|
+
def.exposed.map((prop) => (
|
|
100
|
+
<ExposedPropRow key={prop.key} def={def} prop={prop} prompt={prompt} saving={saving} assets={assets} />
|
|
101
|
+
))
|
|
102
|
+
)}
|
|
103
|
+
</InspectorSection>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* One published property: turn it, relabel it, retire it.
|
|
109
|
+
*
|
|
110
|
+
* A component and not inline JSX because the drag bracket is a HOOK and there
|
|
111
|
+
* is one gesture per prop. A colour picker's SV square, its hue bar, its alpha
|
|
112
|
+
* bar and a range field's slider route a drag ENTIRELY through `scrub.move`
|
|
113
|
+
* and never call `commit` while the pointer is down, so a row wired to the
|
|
114
|
+
* typed half alone has a control whose thumb moves and whose document does not.
|
|
115
|
+
*/
|
|
116
|
+
function ExposedPropRow({
|
|
117
|
+
def,
|
|
118
|
+
prop,
|
|
119
|
+
prompt,
|
|
120
|
+
saving,
|
|
121
|
+
assets,
|
|
122
|
+
}: {
|
|
123
|
+
def: ComponentDef3D;
|
|
124
|
+
prop: ExposedProp3D;
|
|
125
|
+
prompt: (req: PromptRequest) => Promise<string | null>;
|
|
126
|
+
/** "Apply to all instances" is on: turns write the definition. Off = tried. */
|
|
127
|
+
saving: boolean;
|
|
128
|
+
assets: readonly PropControlAsset[];
|
|
129
|
+
}) {
|
|
130
|
+
const store = useStore();
|
|
131
|
+
const materials = useShotEditor((s) => s.doc?.materials);
|
|
132
|
+
const contracts = useShotEditor((s) => s.contracts);
|
|
133
|
+
const tried = useShotEditor((s) => s.componentPlay[prop.key]);
|
|
134
|
+
// The row's verbs are plain buttons in its label column (PropRow's
|
|
135
|
+
// `actions`), so they take the panel's lock here: a read-only row's control
|
|
136
|
+
// is locked by the row itself, and its retire must stay live (it is how an
|
|
137
|
+
// orphan or an undescribed prop is fixed).
|
|
138
|
+
const locked = useLocked();
|
|
139
|
+
const menu = useContextMenu();
|
|
140
|
+
const defId = def.id;
|
|
141
|
+
const row = exposedRowOf(prop, def, materials, contracts);
|
|
142
|
+
const { spec } = row;
|
|
143
|
+
const label = controlLabel(spec);
|
|
144
|
+
const layer = def.layersById[prop.target.layer];
|
|
145
|
+
// What the row shows untried: the layer's own value (what an un-overridden
|
|
146
|
+
// placement renders, shown as it is stored, malformed or not), else what
|
|
147
|
+
// the definition draws there (`exposedMasterValue`: a derived value, a
|
|
148
|
+
// graph parameter's or a contract prop's default), never the published
|
|
149
|
+
// `default`, which drifts from the layer.
|
|
150
|
+
const live = layer === undefined ? undefined : (readAtPath(layer, prop.target.path) as Value | undefined);
|
|
151
|
+
const fallback = live ?? masterRowValue(spec, exposedMasterValue(def, prop, { materials, contracts }));
|
|
152
|
+
|
|
153
|
+
// Re-read from the document it is HANDED, never from a value closed over at
|
|
154
|
+
// render: every capture re-derives from the gesture's base, so a builder that
|
|
155
|
+
// remembered would re-apply the whole drag on top of itself per pointer event.
|
|
156
|
+
// A value the target cannot hold writes nothing.
|
|
157
|
+
const saveScrub = useScrub((next, raw) => {
|
|
158
|
+
const value = coercePropValue(spec, raw);
|
|
159
|
+
return value === null ? next : setExposedValue(next, defId, prop.key, value);
|
|
160
|
+
});
|
|
161
|
+
// TRYING: every move IS the edit, so a cancelled gesture puts back the
|
|
162
|
+
// value it started from.
|
|
163
|
+
const before = useRef<Value | undefined>(undefined);
|
|
164
|
+
const scrub = saving
|
|
165
|
+
? saveScrub
|
|
166
|
+
: {
|
|
167
|
+
start: () => {
|
|
168
|
+
before.current = tried;
|
|
169
|
+
},
|
|
170
|
+
move: (raw: unknown) => {
|
|
171
|
+
const value = coercePropValue(spec, raw);
|
|
172
|
+
if (value !== null) store.playComponentProp(prop.key, value);
|
|
173
|
+
},
|
|
174
|
+
end: (commit: boolean) => {
|
|
175
|
+
if (!commit) store.playComponentProp(prop.key, before.current ?? null);
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
const commit = (raw: unknown): void => {
|
|
179
|
+
const edit = propEditOf(spec, raw, fallback);
|
|
180
|
+
if (edit.kind === "refused") {
|
|
181
|
+
store.reportError(edit.reason);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// "No asset" over a value that is already none: drop what is tried, and
|
|
185
|
+
// the saved value (none) shows again.
|
|
186
|
+
if (edit.kind === "clear") {
|
|
187
|
+
if (!saving) store.playComponentProp(prop.key, null);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (saving) store.setExposedPropValue(defId, prop.key, edit.value);
|
|
191
|
+
else store.playComponentProp(prop.key, edit.value);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// THE ROW'S VERBS LIVE IN ITS LABEL COLUMN (PropRow's `actions`), as ONE
|
|
195
|
+
// "More" that opens Rename… and Stop publishing. A verb never changes the
|
|
196
|
+
// control's width, and it is drawn once per row: as a box's accessory it
|
|
197
|
+
// was drawn in every box of a vector, and two of them took a third-width
|
|
198
|
+
// box's prefix and unit at the default width and spilled past its edge at
|
|
199
|
+
// the 264px floor. In the label column a vector's three boxes keep their
|
|
200
|
+
// whole width for the value. Rename is a PROMPT rather than an inline field
|
|
201
|
+
// for the same reason the component's own name is: it is a rare edit, and a
|
|
202
|
+
// permanently mounted input costs a row its readability every time it is
|
|
203
|
+
// not being used.
|
|
204
|
+
const retire = (): void => store.deleteExposedProp(defId, prop.key);
|
|
205
|
+
const rename = (): void => {
|
|
206
|
+
void prompt({
|
|
207
|
+
title: "Rename property",
|
|
208
|
+
label: "Name",
|
|
209
|
+
initialValue: prop.label,
|
|
210
|
+
confirmLabel: "Rename",
|
|
211
|
+
}).then((next) => {
|
|
212
|
+
if (next !== null && next !== "") store.renameExposedProp(defId, prop.key, next);
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
const more = (
|
|
216
|
+
<button
|
|
217
|
+
type="button"
|
|
218
|
+
className="insp-key"
|
|
219
|
+
aria-label={`More for ${label}`}
|
|
220
|
+
aria-haspopup="menu"
|
|
221
|
+
aria-expanded={menu.menu !== null}
|
|
222
|
+
title="Rename or stop publishing"
|
|
223
|
+
disabled={locked}
|
|
224
|
+
onClick={(e) => {
|
|
225
|
+
const at = e.currentTarget.getBoundingClientRect();
|
|
226
|
+
menu.open({ x: at.left, y: at.bottom }, [
|
|
227
|
+
{
|
|
228
|
+
kind: "action",
|
|
229
|
+
id: "rename",
|
|
230
|
+
label: "Rename…",
|
|
231
|
+
title: "The key instances override by does not change",
|
|
232
|
+
onSelect: rename,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
kind: "action",
|
|
236
|
+
id: "retire",
|
|
237
|
+
label: "Stop publishing",
|
|
238
|
+
danger: true,
|
|
239
|
+
title: "Instance overrides stay stored",
|
|
240
|
+
onSelect: retire,
|
|
241
|
+
},
|
|
242
|
+
]);
|
|
243
|
+
}}
|
|
244
|
+
>
|
|
245
|
+
<IconDots />
|
|
246
|
+
</button>
|
|
247
|
+
);
|
|
248
|
+
// An orphan's one verb, pressed directly: there is nothing else to choose.
|
|
249
|
+
const remove = (
|
|
250
|
+
<button
|
|
251
|
+
type="button"
|
|
252
|
+
className="insp-key is-danger"
|
|
253
|
+
aria-label={`Stop publishing ${label}`}
|
|
254
|
+
title="Stop publishing: instance overrides stay stored"
|
|
255
|
+
disabled={locked}
|
|
256
|
+
onClick={retire}
|
|
257
|
+
>
|
|
258
|
+
<IconClose />
|
|
259
|
+
</button>
|
|
260
|
+
);
|
|
261
|
+
// The key is override identity, not a caption, so it rides the label's
|
|
262
|
+
// tooltip beside the target it writes rather than taking the line the
|
|
263
|
+
// author reads.
|
|
264
|
+
const where = `Key ${prop.key} · ${layer?.label ?? prop.target.layer} · ${prop.target.path}`;
|
|
265
|
+
|
|
266
|
+
if (layer === undefined) {
|
|
267
|
+
// AN ORPHAN, said plainly. `setExposedValue` and `applyOverrides` both skip
|
|
268
|
+
// a prop whose target is gone, so a live control here would be a widget
|
|
269
|
+
// that writes nothing, and the save gate names this prop anyway. The value
|
|
270
|
+
// it last held stays on screen, read-only, and retire is the only verb
|
|
271
|
+
// left, so it is the only one offered. Nothing can be tried on it, so
|
|
272
|
+
// its dot lane stays empty, but it is reserved: without it the label
|
|
273
|
+
// started 10px left of every live row's above and below it.
|
|
274
|
+
return (
|
|
275
|
+
<PropRow
|
|
276
|
+
spec={spec}
|
|
277
|
+
value={shownPropValue(spec, prop.default)}
|
|
278
|
+
commit={() => {}}
|
|
279
|
+
scrub={saveScrub}
|
|
280
|
+
readOnly
|
|
281
|
+
changed={false}
|
|
282
|
+
actions={remove}
|
|
283
|
+
description={where}
|
|
284
|
+
error="Its layer is gone, so nothing drives this any more."
|
|
285
|
+
assets={assets}
|
|
286
|
+
rowProps={{ "data-definition-prop": prop.key }}
|
|
287
|
+
/>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<>
|
|
293
|
+
<PropRow
|
|
294
|
+
spec={spec}
|
|
295
|
+
value={shownPropValue(spec, tried ?? fallback)}
|
|
296
|
+
commit={commit}
|
|
297
|
+
scrub={scrub}
|
|
298
|
+
// THE BLUE DOT: a value tried here, not saved.
|
|
299
|
+
changed={tried !== undefined}
|
|
300
|
+
changedLabel="Tried, not saved"
|
|
301
|
+
dotProps={{ "data-tried": prop.key }}
|
|
302
|
+
{...(row.undescribed ? { readOnly: true } : {})}
|
|
303
|
+
{...(row.opaqueColor ? { opaqueColor: true } : {})}
|
|
304
|
+
actions={more}
|
|
305
|
+
description={where}
|
|
306
|
+
assets={assets}
|
|
307
|
+
// A hook for the row, not a style: nothing restyles a published
|
|
308
|
+
// prop's row, which is the house PropRow.
|
|
309
|
+
rowProps={{ "data-definition-prop": prop.key }}
|
|
310
|
+
/>
|
|
311
|
+
{/* The menu the row's More opens, once per row, beside it. */}
|
|
312
|
+
{menu.menu}
|
|
313
|
+
</>
|
|
314
|
+
);
|
|
315
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// The open DEFINITION itself — the component context's control panel when
|
|
2
|
+
// nothing inside it is selected (unify P2), and the Component Studio's whole
|
|
3
|
+
// right rail. The def-level twin of SceneSection: what it publishes and how
|
|
4
|
+
// big it is. The mo1 read: this is the module's own
|
|
5
|
+
// property sheet.
|
|
6
|
+
//
|
|
7
|
+
// ── THE ORDER IS THE QUESTION AN AUTHOR ASKS ────────────────────────────
|
|
8
|
+
//
|
|
9
|
+
// Properties first, then the canvas. It used to run the other
|
|
10
|
+
// way, which put the definition's WIDTH above the surface every instance of it
|
|
11
|
+
// is driven through — right while the panel was a ledger nobody could turn, and
|
|
12
|
+
// wrong the moment the props became live controls (`DefinitionProps`). The two
|
|
13
|
+
// faces share this component, so the order is one decision rather than two.
|
|
14
|
+
//
|
|
15
|
+
// EXPOSED PROPS are created by the agent's `expose_prop` and by the chrome's
|
|
16
|
+
// own pin (`inspector/ExposeDot.tsx`, inside a row's field box beside the
|
|
17
|
+
// keyframe diamond, on the layers face). Everything after that is
|
|
18
|
+
// `DefinitionProps`: the value, the label and the retire, all respecting the
|
|
19
|
+
// key-is-identity rule (a rename never touches the key, a delete leaves stored
|
|
20
|
+
// overrides quarantined in place).
|
|
21
|
+
import { InspectorRow, InspectorSection, NumberField, TextField } from "@dailies-studio/ui";
|
|
22
|
+
import type { ScrubHandlers } from "@dailies-studio/ui";
|
|
23
|
+
import {
|
|
24
|
+
componentDefsOf,
|
|
25
|
+
defDurationFrames,
|
|
26
|
+
instancesOf,
|
|
27
|
+
setComponentDuration,
|
|
28
|
+
setComponentSize,
|
|
29
|
+
} from "@dailies-studio/shot/doc";
|
|
30
|
+
import type { Doc3D } from "@dailies-studio/shot/doc";
|
|
31
|
+
import { useShotEditor, useStore } from "../../../state/context.js";
|
|
32
|
+
import { useScrub } from "../useDocWrite.js";
|
|
33
|
+
import { DefinitionProps } from "./DefinitionProps.js";
|
|
34
|
+
|
|
35
|
+
/** A whole, positive number of pixels or frames, the floor these fields keep. */
|
|
36
|
+
const whole = (n: number): number => Math.max(1, Math.round(n));
|
|
37
|
+
|
|
38
|
+
/** One canvas side, written into the definition the drag is HANDED (a scrub
|
|
39
|
+
* re-derives every move from its base), the other side kept as it is there. */
|
|
40
|
+
function sizeWrite(defId: string, axis: 0 | 1): (doc: Doc3D, raw: unknown) => Doc3D {
|
|
41
|
+
return (doc, raw) => {
|
|
42
|
+
const def = componentDefsOf(doc)[defId];
|
|
43
|
+
if (def === undefined || typeof raw !== "number" || !Number.isFinite(raw)) return doc;
|
|
44
|
+
const size: [number, number] = [def.size[0], def.size[1]];
|
|
45
|
+
size[axis] = whole(raw);
|
|
46
|
+
return setComponentSize(doc, defId, size);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** A NumberField's drag half, from the store's scrub trio. */
|
|
51
|
+
function dragOf(scrub: ScrubHandlers): {
|
|
52
|
+
onScrubStart: () => void;
|
|
53
|
+
onScrub: (value: number) => void;
|
|
54
|
+
onScrubEnd: (commit: boolean) => void;
|
|
55
|
+
} {
|
|
56
|
+
return { onScrubStart: scrub.start, onScrub: scrub.move, onScrubEnd: scrub.end };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function DefinitionSection() {
|
|
60
|
+
const store = useStore();
|
|
61
|
+
const doc = useShotEditor((s) => s.doc);
|
|
62
|
+
const editingDef = useShotEditor((s) => s.editingDef);
|
|
63
|
+
const def = editingDef === null ? undefined : doc?.components?.[editingDef];
|
|
64
|
+
const defId = def?.id ?? "";
|
|
65
|
+
// THE DRAG HALVES: a drag on W, H or Frames moves the definition while the
|
|
66
|
+
// pointer is down, one undo entry, instead of waiting for the release.
|
|
67
|
+
const width = useScrub(sizeWrite(defId, 0));
|
|
68
|
+
const height = useScrub(sizeWrite(defId, 1));
|
|
69
|
+
const frames = useScrub((next, raw) =>
|
|
70
|
+
typeof raw === "number" && Number.isFinite(raw) ? setComponentDuration(next, defId, whole(raw)) : next,
|
|
71
|
+
);
|
|
72
|
+
if (doc === null || def === undefined) return null;
|
|
73
|
+
|
|
74
|
+
const placed = instancesOf(doc, def.id).length;
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
<DefinitionProps key={def.id} def={def} />
|
|
79
|
+
|
|
80
|
+
<InspectorSection className="insp-object" title="Component" persistKey="shot:definition" collapsible={false}>
|
|
81
|
+
<InspectorRow label="Name">
|
|
82
|
+
<TextField
|
|
83
|
+
value={def.name}
|
|
84
|
+
ariaLabel="Component name"
|
|
85
|
+
onCommit={(name) => store.renameComponent(def.id, name)}
|
|
86
|
+
/>
|
|
87
|
+
</InspectorRow>
|
|
88
|
+
{/* THE CANVAS, a W | H pair like the Transform section's: two field
|
|
89
|
+
boxes side by side, each named inside, rather than two fields
|
|
90
|
+
flattened into one labelled pill. */}
|
|
91
|
+
<InspectorRow>
|
|
92
|
+
<div className="insp-vec">
|
|
93
|
+
<NumberField
|
|
94
|
+
value={def.size[0]}
|
|
95
|
+
label="W"
|
|
96
|
+
ariaLabel="Component width"
|
|
97
|
+
unit="px"
|
|
98
|
+
min={1}
|
|
99
|
+
step={1}
|
|
100
|
+
onCommit={(w) => store.setComponentSize(def.id, [whole(w), def.size[1]])}
|
|
101
|
+
{...dragOf(width)}
|
|
102
|
+
/>
|
|
103
|
+
<NumberField
|
|
104
|
+
value={def.size[1]}
|
|
105
|
+
label="H"
|
|
106
|
+
ariaLabel="Component height"
|
|
107
|
+
unit="px"
|
|
108
|
+
min={1}
|
|
109
|
+
step={1}
|
|
110
|
+
onCommit={(h) => store.setComponentSize(def.id, [def.size[0], whole(h)])}
|
|
111
|
+
{...dragOf(height)}
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
</InspectorRow>
|
|
115
|
+
<InspectorRow>
|
|
116
|
+
<NumberField
|
|
117
|
+
value={defDurationFrames(def)}
|
|
118
|
+
label="Frames"
|
|
119
|
+
ariaLabel="Component duration"
|
|
120
|
+
min={1}
|
|
121
|
+
step={1}
|
|
122
|
+
onCommit={(f) => store.setComponentDuration(def.id, Math.round(f))}
|
|
123
|
+
{...dragOf(frames)}
|
|
124
|
+
/>
|
|
125
|
+
</InspectorRow>
|
|
126
|
+
<p className="insp-note">
|
|
127
|
+
{placed === 0
|
|
128
|
+
? "Not placed yet. Use it in a shot or add it to the storyboard."
|
|
129
|
+
: placed === 1
|
|
130
|
+
? "Placed once. Edits here reach it."
|
|
131
|
+
: `Placed ${placed} times. Edits here reach all of them.`}
|
|
132
|
+
</p>
|
|
133
|
+
</InspectorSection>
|
|
134
|
+
</>
|
|
135
|
+
);
|
|
136
|
+
}
|