@weasel-js/core 1.9.3 → 1.9.4
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/CHANGELOG.md +356 -0
- package/README.md +2 -2
- package/dist/WeaselProvider.js +5 -5
- package/dist/affordances/composeAffordanceLayer.js +10 -20
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/cornerResize.js +25 -17
- package/dist/affordances/cornerResize.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +27 -20
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/rotationHandle.js +18 -18
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/behaviors/momentum.js +93 -55
- package/dist/animation/behaviors/momentum.js.map +1 -1
- package/dist/animation/loop.js +10 -12
- package/dist/animation/loop.js.map +1 -1
- package/dist/animation/reflow.js +8 -8
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/stagger.js +64 -56
- package/dist/animation/stagger.js.map +1 -1
- package/dist/animation/timeline/booking.js +62 -54
- package/dist/animation/timeline/booking.js.map +1 -1
- package/dist/animation/timeline/createTimeline.js +85 -76
- package/dist/animation/timeline/createTimeline.js.map +1 -1
- package/dist/animation/timeline/sampleTrack.js +13 -5
- package/dist/animation/timeline/sampleTrack.js.map +1 -1
- package/dist/animation/useAnimator.js +45 -35
- package/dist/animation/useAnimator.js.map +1 -1
- package/dist/animation/wrappers/animateLifecycle.js +31 -24
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
- package/dist/animation/wrappers/animateOnSetPose.js +28 -26
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
- package/dist/animation/wrappers/instantPose.js +13 -0
- package/dist/animation/wrappers/instantPose.js.map +1 -0
- package/dist/{poseDescriptor-D-OH-tu5.d.ts → autoPoseDescriptor-Ct7yqivU.d.ts} +28 -3
- package/dist/barrel/chrome.js +16 -0
- package/dist/barrel/input.js +19 -0
- package/dist/barrel/interactions.js +42 -0
- package/dist/barrel/paint.js +18 -0
- package/dist/barrel/paths.js +19 -0
- package/dist/barrel/renderer.js +20 -0
- package/dist/barrel/routing.js +51 -0
- package/dist/barrel/text.js +18 -0
- package/dist/barrel/viewport.js +52 -0
- package/dist/builtins-DPcdghtB.d.ts +1223 -0
- package/dist/canvas/Canvas.js +363 -448
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +164 -165
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +37 -32
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +49 -43
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/MinimapCanvas.js +26 -25
- package/dist/canvas/MinimapCanvas.js.map +1 -1
- package/dist/canvas/NodeShape.js +59 -377
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js +50 -47
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +167 -0
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +13 -13
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +67 -0
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +16 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/coordTrace.js +10 -0
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +112 -70
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +9 -8
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +1 -0
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/isDev.js +12 -0
- package/dist/canvas/SceneCanvas/isDev.js.map +1 -0
- package/dist/canvas/SceneCanvas/poseGeometry.js +29 -28
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/poseRegistrars.js +13 -0
- package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -0
- package/dist/canvas/SceneCanvas/props.js +38 -0
- package/dist/canvas/SceneCanvas/props.js.map +1 -0
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +21 -62
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +46 -48
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +33 -33
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +534 -788
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +45 -43
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +91 -0
- package/dist/canvas/buildSceneLayer.js.map +1 -0
- package/dist/canvas/buildSceneTree.js +16 -19
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/canvasRenderer.js +68 -52
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/deps/changes.js +13 -0
- package/dist/canvas/deps/changes.js.map +1 -0
- package/dist/canvas/deps/editAnchors.js +28 -28
- package/dist/canvas/deps/insert.js +119 -91
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/slice.js +46 -45
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +10 -9
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/derivedPath.js +46 -23
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +7 -7
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/hud.module.js +1 -1
- package/dist/canvas/hud.module.js.map +1 -1
- package/dist/canvas/kitRequirements.js +2 -2
- package/dist/canvas/kitRequirements.js.map +1 -1
- package/dist/canvas/layerOrder.js +13 -6
- package/dist/canvas/layerOrder.js.map +1 -1
- package/dist/canvas/minimapMath.js +12 -10
- package/dist/canvas/minimapMath.js.map +1 -1
- package/dist/canvas/nodeShapes/derivedPainter.js +34 -0
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/imagePainter.js +87 -0
- package/dist/canvas/nodeShapes/imagePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/memo.js +9 -0
- package/dist/canvas/nodeShapes/memo.js.map +1 -0
- package/dist/canvas/nodeShapes/nodePaint.js +57 -0
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -0
- package/dist/canvas/nodeShapes/pathPainter.js +38 -0
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/poseBox.js +20 -0
- package/dist/canvas/nodeShapes/poseBox.js.map +1 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +38 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/shapePainter.js +72 -0
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/textPainter.js +55 -0
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/paintCull.js +10 -11
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/canvas/pickWalk.js +52 -63
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/poseRotation.js +11 -23
- package/dist/canvas/poseRotation.js.map +1 -1
- package/dist/canvas/renderDebugSnapshot.js +5 -5
- package/dist/canvas/renderSceneToPixels.js +3 -1
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +66 -148
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +112 -0
- package/dist/canvas/sceneClipboard.js.map +1 -0
- package/dist/canvas/sceneSlotWiring.js +4 -4
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +39 -40
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/useCanvasRenderer.js +14 -6
- package/dist/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/canvas/useCanvasView.js +58 -0
- package/dist/canvas/useCanvasView.js.map +1 -0
- package/dist/canvas/useFrameLoop.js +35 -26
- package/dist/canvas/useFrameLoop.js.map +1 -1
- package/dist/canvas/useSceneLayerList.js +21 -0
- package/dist/canvas/useSceneLayerList.js.map +1 -0
- package/dist/clipboard.d.ts +10 -6
- package/dist/clone.d.ts +4 -3
- package/dist/core/adapters/arrayAdapter.js +48 -39
- package/dist/core/adapters/arrayAdapter.js.map +1 -1
- package/dist/core/device/index.js +5 -4
- package/dist/core/device/useDeviceProfile.js +38 -44
- package/dist/core/device/useDeviceProfile.js.map +1 -1
- package/dist/core/device/watchDevicePixelRatio.js +17 -0
- package/dist/core/device/watchDevicePixelRatio.js.map +1 -0
- package/dist/core/fillInPoseFrame.js.map +1 -1
- package/dist/core/geometry/poseDescriptor.js +21 -19
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/poseFrame.js +44 -0
- package/dist/core/geometry/poseFrame.js.map +1 -0
- package/dist/core/geometry/poseRotation.js.map +1 -1
- package/dist/core/geometry/regionHit.js +9 -10
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/unionBounds.js +31 -29
- package/dist/core/geometry/unionBounds.js.map +1 -1
- package/dist/core/isPlainObject.js +2 -11
- package/dist/core/ops/arrange.js +1 -0
- package/dist/core/ops/arrange.js.map +1 -1
- package/dist/core/ops/create.js +10 -5
- package/dist/core/ops/create.js.map +1 -1
- package/dist/core/ops/delete.js +12 -24
- package/dist/core/ops/delete.js.map +1 -1
- package/dist/core/ops/reorder/index.js +43 -40
- package/dist/core/ops/reorder/index.js.map +1 -1
- package/dist/core/ops/reorder/setChildOrder.js +34 -0
- package/dist/core/ops/reorder/setChildOrder.js.map +1 -0
- package/dist/core/paintKinds.js +5 -5
- package/dist/core/paintKinds.js.map +1 -1
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/appliedLog.js +37 -0
- package/dist/core/scene/appliedLog.js.map +1 -0
- package/dist/core/scene/arrivalWindow.js +101 -0
- package/dist/core/scene/arrivalWindow.js.map +1 -0
- package/dist/core/scene/derivedPath.js.map +1 -1
- package/dist/core/scene/historyFacade.js +84 -0
- package/dist/core/scene/historyFacade.js.map +1 -0
- package/dist/core/scene/kitOps.js +173 -0
- package/dist/core/scene/kitOps.js.map +1 -0
- package/dist/core/scene/layerStack.js +38 -0
- package/dist/core/scene/layerStack.js.map +1 -0
- package/dist/core/scene/lockGuard.js +37 -0
- package/dist/core/scene/lockGuard.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +5 -6
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js +45 -19
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +126 -0
- package/dist/core/scene/nodeStore.js.map +1 -0
- package/dist/core/scene/pickability.js +6 -0
- package/dist/core/scene/pickability.js.map +1 -0
- package/dist/core/scene/poseFeed.js +38 -38
- package/dist/core/scene/poseFeed.js.map +1 -1
- package/dist/core/scene/poseOverrides.js +34 -38
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/renderOrder.js +84 -0
- package/dist/core/scene/renderOrder.js.map +1 -0
- package/dist/core/scene/scene.js +289 -866
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/serialization.js +68 -0
- package/dist/core/scene/serialization.js.map +1 -0
- package/dist/core/scene/treeOrder.js +13 -0
- package/dist/core/scene/treeOrder.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/viewport/meanScale.js +1 -1
- package/dist/core/viewport/meanScale.js.map +1 -1
- package/dist/core/viewport/view.js +12 -12
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/zoomBounds.js +10 -8
- package/dist/core/viewport/zoomBounds.js.map +1 -1
- package/dist/{cornerHandles-BCrDp_mH.d.ts → cornerHandles-CtCb8a3G.d.ts} +1 -1
- package/dist/debug/createDebugOverlayLayer.js +14 -14
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/flag.js +2 -41
- package/dist/features/chrome-caps/useHoverTracking.js +22 -17
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/focus/gateLayer.js +3 -4
- package/dist/features/focus/gateLayer.js.map +1 -1
- package/dist/features/images/imageCache.js +19 -9
- package/dist/features/images/imageCache.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +14 -11
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/ingestion/index.js +1 -1
- package/dist/features/ingestion/registerKitHandlers.js +7 -7
- package/dist/features/ingestion/weaselJsonHandler.js +17 -14
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
- package/dist/features/meshPaint/lazyKind.js +201 -35
- package/dist/features/meshPaint/lazyKind.js.map +1 -1
- package/dist/features/meshPaint/meshPaint.js +82 -79
- package/dist/features/meshPaint/meshPaint.js.map +1 -1
- package/dist/features/minimap/createMinimapContribution.js +42 -42
- package/dist/features/minimap/layers.js +44 -62
- package/dist/features/minimap/layers.js.map +1 -1
- package/dist/features/parallax/createParallaxPlane.js +10 -14
- package/dist/features/parallax/createParallaxPlane.js.map +1 -1
- package/dist/features/paths/anchorEdits.js +19 -8
- package/dist/features/paths/anchorEdits.js.map +1 -1
- package/dist/features/paths/anchors.js +31 -26
- package/dist/features/paths/anchors.js.map +1 -1
- package/dist/features/paths/booleans.js +2 -2
- package/dist/features/paths/index.js +13 -11
- package/dist/features/paths/markerCommands.js +37 -36
- package/dist/features/paths/markerCommands.js.map +1 -1
- package/dist/features/paths/pathInWorld.js +19 -19
- package/dist/features/paths/pathInWorld.js.map +1 -1
- package/dist/features/paths/pathLayer.js.map +1 -1
- package/dist/features/paths/strokeToPath.js +40 -0
- package/dist/features/paths/strokeToPath.js.map +1 -0
- package/dist/features/paths/tessellate/stroke.js.map +1 -1
- package/dist/features/patterns/commandPaint.js +18 -0
- package/dist/features/patterns/commandPaint.js.map +1 -0
- package/dist/features/patterns/index.js +5 -17
- package/dist/features/patterns/index.js.map +1 -1
- package/dist/features/patterns/rasterizeTile.js +17 -0
- package/dist/features/patterns/rasterizeTile.js.map +1 -0
- package/dist/features/patterns/resolveSpec.js +52 -44
- package/dist/features/patterns/resolveSpec.js.map +1 -1
- package/dist/features/poseRun/usePoseRun.js +8 -3
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/selection/SelectionContext.js +5 -0
- package/dist/features/selection/SelectionContext.js.map +1 -1
- package/dist/features/selection/overlay.js +18 -18
- package/dist/features/selection/overlay.js.map +1 -1
- package/dist/features/text/domOffsets.js +82 -0
- package/dist/features/text/domOffsets.js.map +1 -0
- package/dist/features/text/domRuns.js +103 -131
- package/dist/features/text/domRuns.js.map +1 -1
- package/dist/features/text/hitTest.js +5 -2
- package/dist/features/text/hitTest.js.map +1 -1
- package/dist/features/text/isTextData.js +8 -0
- package/dist/features/text/isTextData.js.map +1 -0
- package/dist/features/text/overlayDirection.js +15 -0
- package/dist/features/text/overlayDirection.js.map +1 -0
- package/dist/features/text/runs/rangeStyle.js +32 -34
- package/dist/features/text/runs/rangeStyle.js.map +1 -1
- package/dist/features/text/textCommand.js +34 -33
- package/dist/features/text/textCommand.js.map +1 -1
- package/dist/features/text/textToPath.js +40 -40
- package/dist/features/text/textToPath.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +76 -82
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/text/useTextEdit.js +184 -160
- package/dist/features/text/useTextEdit.js.map +1 -1
- package/dist/features/tiling/createTiledLayer.js +24 -22
- package/dist/features/tiling/createTiledLayer.js.map +1 -1
- package/dist/index.d.ts +11033 -7749
- package/dist/index.js +316 -309
- package/dist/input/keyState.js +42 -43
- package/dist/input/keyState.js.map +1 -1
- package/dist/input/useKeyModifiers.js +11 -0
- package/dist/input/useKeyModifiers.js.map +1 -0
- package/dist/interactions/actions/align/align.js +8 -8
- package/dist/interactions/actions/clipboard/clipboardOps.js +34 -32
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/materializePaste.js +10 -7
- package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -1
- package/dist/interactions/actions/defaultCommitAdapter.js +20 -18
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
- package/dist/interactions/actions/defaults/align.js +9 -10
- package/dist/interactions/actions/defaults/align.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +59 -81
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/areaSelect.js +35 -38
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/clipboard.js +26 -10
- package/dist/interactions/actions/defaults/clipboard.js.map +1 -1
- package/dist/interactions/actions/defaults/clone.js +44 -60
- package/dist/interactions/actions/defaults/clone.js.map +1 -1
- package/dist/interactions/actions/defaults/copySubtree.js +40 -0
- package/dist/interactions/actions/defaults/copySubtree.js.map +1 -0
- package/dist/interactions/actions/defaults/distribute.js +14 -13
- package/dist/interactions/actions/defaults/distribute.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +17 -57
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/editAnchors.js +18 -18
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/flip.js +52 -46
- package/dist/interactions/actions/defaults/flip.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +43 -48
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +35 -33
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insert.js +50 -51
- package/dist/interactions/actions/defaults/insert.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -7
- package/dist/interactions/actions/defaults/lassoSelect.js +67 -70
- package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/move.js +267 -249
- package/dist/interactions/actions/defaults/move.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +40 -68
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/nudgeSteps.js +37 -0
- package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -0
- package/dist/interactions/actions/defaults/reorder.js +2 -0
- package/dist/interactions/actions/defaults/reorder.js.map +1 -1
- package/dist/interactions/actions/defaults/resize.js +104 -98
- package/dist/interactions/actions/defaults/resize.js.map +1 -1
- package/dist/interactions/actions/defaults/rotate.js +111 -110
- package/dist/interactions/actions/defaults/rotate.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +7 -7
- package/dist/interactions/actions/defaults/setFillOpacity.js +4 -4
- package/dist/interactions/actions/defaults/setStroke.js +12 -12
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +6 -6
- package/dist/interactions/actions/defaults/sliceOps.js +19 -19
- package/dist/interactions/actions/defaults/viewportDragPan.js +37 -26
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/geometry.js +28 -23
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
- package/dist/interactions/actions/flip/helpers.js +30 -17
- package/dist/interactions/actions/flip/helpers.js.map +1 -1
- package/dist/interactions/actions/hitSelection.js +8 -0
- package/dist/interactions/actions/hitSelection.js.map +1 -0
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +14 -18
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +5 -5
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +32 -21
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/gestureAdapter.js +32 -15
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +33 -0
- package/dist/interactions/actions/move/landedDescendants.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +18 -18
- package/dist/interactions/actions/poseDescriptorDep.js +16 -4
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +11 -6
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/previewOverrides.js +5 -5
- package/dist/interactions/actions/previewOverrides.js.map +1 -1
- package/dist/interactions/actions/selectionSubtree.js +69 -0
- package/dist/interactions/actions/selectionSubtree.js.map +1 -0
- package/dist/interactions/actions/useStandardActions.js +66 -62
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragGesture.js +4 -7
- package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragPointOf.js +23 -0
- package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -0
- package/dist/interactions/gestures/handleDrag/handleDrag.js +21 -26
- package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +8 -6
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +8 -4
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
- package/dist/{math-Drrw4ewZ.d.ts → math-J-ACHyEg.d.ts} +1 -2
- package/dist/math.d.ts +2 -3
- package/dist/move.d.ts +12 -11
- package/dist/{originProjection-DEklpDc_.d.ts → originProjection-gHnOup4e.d.ts} +1 -1
- package/dist/{registerProgram-BMZRDgrh.d.ts → registerProgram-T9S_PfAX.d.ts} +18 -7
- package/dist/renderer/DrawCommand.js.map +1 -1
- package/dist/renderer/WeaselRenderer.js +75 -73
- package/dist/renderer/WeaselRenderer.js.map +1 -1
- package/dist/renderer/cache/GLImageCache.js +15 -5
- package/dist/renderer/cache/GLImageCache.js.map +1 -1
- package/dist/renderer/cache/GLMeshCache.js +23 -23
- package/dist/renderer/cache/GLMeshCache.js.map +1 -1
- package/dist/renderer/cache/GLTextureCache.js +18 -1
- package/dist/renderer/cache/GLTextureCache.js.map +1 -1
- package/dist/renderer/cache/cache.js.map +1 -1
- package/dist/renderer/cache/markerCommandCache.js.map +1 -1
- package/dist/renderer/cache/strokeMeshCache.js.map +1 -1
- package/dist/renderer/cullDrawCommands.js +11 -11
- package/dist/renderer/draw/batch.js +133 -0
- package/dist/renderer/draw/batch.js.map +1 -0
- package/dist/renderer/draw/clip.js +89 -0
- package/dist/renderer/draw/clip.js.map +1 -0
- package/dist/renderer/draw/customShader.js +230 -0
- package/dist/renderer/draw/customShader.js.map +1 -0
- package/dist/renderer/draw/drawTriangles.js +8 -0
- package/dist/renderer/draw/drawTriangles.js.map +1 -0
- package/dist/renderer/draw/effects.js +28 -0
- package/dist/renderer/draw/effects.js.map +1 -0
- package/dist/renderer/draw/flushBatch.js +35 -0
- package/dist/renderer/draw/flushBatch.js.map +1 -0
- package/dist/renderer/draw/gradient.js +90 -0
- package/dist/renderer/draw/gradient.js.map +1 -0
- package/dist/renderer/draw/image.js +38 -0
- package/dist/renderer/draw/image.js.map +1 -0
- package/dist/renderer/draw/mesh.js +16 -0
- package/dist/renderer/draw/mesh.js.map +1 -0
- package/dist/renderer/draw/paintBind.js +70 -0
- package/dist/renderer/draw/paintBind.js.map +1 -0
- package/dist/renderer/draw/pathPaint.js +142 -0
- package/dist/renderer/draw/pathPaint.js.map +1 -0
- package/dist/renderer/draw/scratchPass.js +83 -0
- package/dist/renderer/draw/scratchPass.js.map +1 -0
- package/dist/renderer/draw/stencil.js +28 -0
- package/dist/renderer/draw/stencil.js.map +1 -0
- package/dist/renderer/draw/text.js +167 -0
- package/dist/renderer/draw/text.js.map +1 -0
- package/dist/renderer/draw/uniforms.js +77 -0
- package/dist/renderer/draw/uniforms.js.map +1 -0
- package/dist/renderer/draw.js +60 -1116
- package/dist/renderer/draw.js.map +1 -1
- package/dist/renderer/effects/EffectTargets.js +3 -0
- package/dist/renderer/effects/EffectTargets.js.map +1 -1
- package/dist/renderer/effects/composite.js +7 -5
- package/dist/renderer/effects/composite.js.map +1 -1
- package/dist/renderer/index.js +18 -17
- package/dist/renderer/math/color.js +63 -83
- package/dist/renderer/math/color.js.map +1 -1
- package/dist/renderer/math/mat3.js +15 -11
- package/dist/renderer/math/mat3.js.map +1 -1
- package/dist/renderer/math/viewToMat3.js +1 -1
- package/dist/renderer/math/viewToMat3.js.map +1 -1
- package/dist/renderer/shaders/ShaderProgram.js +13 -13
- package/dist/renderer/shaders/ShaderProgram.js.map +1 -1
- package/dist/renderer/shaders/glyphPaint.js +3 -3
- package/dist/renderer/shaders/glyphPaint.js.map +1 -1
- package/dist/renderer/shaders/gradFill.js +2 -1
- package/dist/renderer/shaders/gradFill.js.map +1 -1
- package/dist/renderer/shaders/pathFill.js +2 -1
- package/dist/renderer/shaders/pathFill.js.map +1 -1
- package/dist/renderer/shaders/patternFill.js +2 -1
- package/dist/renderer/shaders/patternFill.js.map +1 -1
- package/dist/renderer/shaders/registerProgram.js.map +1 -1
- package/dist/renderer/strokeLengths.js.map +1 -1
- package/dist/renderer/textures/registerTexture.js +25 -5
- package/dist/renderer/textures/registerTexture.js.map +1 -1
- package/dist/renderer.d.ts +16 -15
- package/dist/renderer.js +17 -16
- package/dist/resize.d.ts +5 -6
- package/dist/resize.js +5 -5
- package/dist/style.css +1 -1
- package/dist/test-hook/install.js +12 -6
- package/dist/test-hook/install.js.map +1 -1
- package/dist/{test-seams-CuIxe0xY.d.ts → test-seams-DM2B87-g.d.ts} +4 -4
- package/dist/test-seams.d.ts +2 -2
- package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js +1 -0
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js +11 -11
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js +1 -0
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +153 -103
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js +13 -8
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js +1 -0
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/selectionContributions.js +24 -23
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +51 -48
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/shared/pointerFollower.js +17 -0
- package/dist/tools/builtin/shared/pointerFollower.js.map +1 -0
- package/dist/tools/builtin/slice/useSliceTool.js +49 -54
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +22 -16
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +1 -0
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/useKeybindings.js +14 -30
- package/dist/tools/useKeybindings.js.map +1 -1
- package/dist/{types-B_9g6hMM.d.ts → types-B4iJRHC3.d.ts} +5 -1
- package/dist/{types-A37hYkeR.d.ts → types-k-5Oqh-U.d.ts} +31 -7
- package/dist/util/color.js +3 -3
- package/dist/util/color.js.map +1 -1
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +20 -18
- package/dist/autoPoseDescriptor-vCdt55xm.d.ts +0 -27
- package/dist/builtins-C-VgUlWI.d.ts +0 -4514
- package/dist/core/isPlainObject.js.map +0 -1
- package/dist/debug/flag.js.map +0 -1
- package/dist/interactions/actions/defaults/freshNodeId.js +0 -10
- package/dist/interactions/actions/defaults/freshNodeId.js.map +0 -1
- package/dist/renderer/shaders/imageFill.js +0 -14
- package/dist/renderer/shaders/imageFill.js.map +0 -1
- package/dist/tools/prefs.js +0 -62
- package/dist/tools/prefs.js.map +0 -1
|
@@ -2,13 +2,15 @@ import { defaultCommitAdapter as e } from "../defaultCommitAdapter.js";
|
|
|
2
2
|
import { CopyIcon as t, CutIcon as n, PasteIcon as r } from "./icons/editIcons.js";
|
|
3
3
|
import { requiresSelection as i } from "./requiresSelection.js";
|
|
4
4
|
import { buildDeleteOps as a } from "./delete.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { kitWeaselJsonHandler as o } from "../../../features/ingestion/weaselJsonHandler.js";
|
|
6
|
+
import { ANY_INGEST_MODS as s, INGEST_REQUIRES as c, ingestFromEvent as l } from "./ingest.js";
|
|
7
|
+
import { createElement as u } from "react";
|
|
8
|
+
import { ActionDisabledReason as d } from "@weasel-js/routing";
|
|
7
9
|
//#region src/interactions/actions/defaults/clipboard.ts
|
|
8
|
-
var
|
|
10
|
+
var f = {
|
|
9
11
|
id: "clipboard.copy",
|
|
10
12
|
label: "Copy",
|
|
11
|
-
icon:
|
|
13
|
+
icon: u(t),
|
|
12
14
|
group: "clipboard",
|
|
13
15
|
defaultBinding: {
|
|
14
16
|
kind: "key",
|
|
@@ -24,10 +26,10 @@ var c = {
|
|
|
24
26
|
}
|
|
25
27
|
},
|
|
26
28
|
enabled: i
|
|
27
|
-
},
|
|
29
|
+
}, p = {
|
|
28
30
|
id: "clipboard.cut",
|
|
29
31
|
label: "Cut",
|
|
30
|
-
icon:
|
|
32
|
+
icon: u(n),
|
|
31
33
|
group: "clipboard",
|
|
32
34
|
defaultBinding: {
|
|
33
35
|
kind: "key",
|
|
@@ -54,10 +56,10 @@ var c = {
|
|
|
54
56
|
}
|
|
55
57
|
},
|
|
56
58
|
enabled: i
|
|
57
|
-
},
|
|
59
|
+
}, m = {
|
|
58
60
|
id: "clipboard.paste",
|
|
59
61
|
label: "Paste",
|
|
60
|
-
icon:
|
|
62
|
+
icon: u(r),
|
|
61
63
|
group: "clipboard",
|
|
62
64
|
eligible: { capability: "edits-page" },
|
|
63
65
|
requires: ["clipboard"],
|
|
@@ -69,10 +71,24 @@ var c = {
|
|
|
69
71
|
},
|
|
70
72
|
enabled: (e) => {
|
|
71
73
|
let t = e?.clipboard;
|
|
72
|
-
return t && !t.isEmpty() ? !0 :
|
|
74
|
+
return t && !t.isEmpty() ? !0 : d.NotApplicable;
|
|
73
75
|
}
|
|
76
|
+
}, h = [o], g = {
|
|
77
|
+
id: "clipboard.pasteEvent",
|
|
78
|
+
label: "Paste copied nodes",
|
|
79
|
+
defaultBinding: {
|
|
80
|
+
kind: "paste",
|
|
81
|
+
types: ["text/plain"],
|
|
82
|
+
mods: s
|
|
83
|
+
},
|
|
84
|
+
requires: [...c],
|
|
85
|
+
invoker: {
|
|
86
|
+
timing: "immediate",
|
|
87
|
+
run: (e, t) => l(e, t, { handlers: h })
|
|
88
|
+
},
|
|
89
|
+
enabled: () => !0
|
|
74
90
|
};
|
|
75
91
|
//#endregion
|
|
76
|
-
export {
|
|
92
|
+
export { f as clipboardCopyAction, p as clipboardCutAction, m as clipboardPasteAction, g as clipboardPasteEventAction };
|
|
77
93
|
|
|
78
94
|
//# sourceMappingURL=clipboard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clipboard.js","names":["clipboardCopyAction","createElement","CopyIcon","requiresSelection","clipboardCutAction","CutIcon","clipboard","deps","selection","scene","applyOps","ids","ops","buildDeleteOps","defaultCommitAdapter","clipboardPasteAction","PasteIcon","ActionDisabledReason"],"sources":["../../../../src/interactions/actions/defaults/clipboard.ts"],"sourcesContent":["import { createElement } from 'react';\nimport { CopyIcon, CutIcon, PasteIcon } from './icons/editIcons';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { ActionDisabledReason, type Action } from '@weasel-js/routing';\nimport { buildDeleteOps } from './delete';\nimport { requiresSelection } from './requiresSelection';\n\n/**\n * @experimental\n * Static descriptor for the `clipboard.copy` Action (Cmd/Ctrl+C).\n */\nexport const clipboardCopyAction: Action & { requires: string[] } = {\n id: 'clipboard.copy',\n label: 'Copy',\n icon: createElement(CopyIcon),\n group: 'clipboard',\n defaultBinding: { kind: 'key', key: 'c', mods: { mod: true } },\n // Same gate as `duplicate`: a mode that can neither edit the page nor own a\n // selection has nothing to copy. Notably excludes `text-edit`, where Cmd+C\n // must stay the browser's own copy of the caret range.\n eligible: { capability: ['edits-page', 'creates-selection'] },\n // `selection` is read by the `enabled` gate, not the invoker — the\n // dispatcher builds deps for both, and an undeclared read is undefined.\n requires: ['clipboard', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n deps.clipboard?.copy();\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * @experimental\n * Static descriptor for the `clipboard.cut` Action (Cmd/Ctrl+X) — copy, then\n * the same batched delete `deleteAction` performs, as one undo entry.\n */\nexport const clipboardCutAction: Action & { requires: string[] } = {\n id: 'clipboard.cut',\n label: 'Cut',\n icon: createElement(CutIcon),\n group: 'clipboard',\n defaultBinding: { kind: 'key', key: 'x', mods: { mod: true } },\n eligible: { capability: 'edits-page' },\n requires: ['clipboard', 'scene', 'selection', 'applyOps'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const clipboard = deps.clipboard;\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!clipboard || !selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n // Snapshot before removal — `snapshotSelection` reads live nodes.\n clipboard.copy();\n\n const ops = buildDeleteOps(scene, ids, 'Cut');\n if (ops.length > 0) {\n if (applyOps) applyOps(ops, 'Cut');\n else scene.applyBatch(ops, 'Cut', defaultCommitAdapter(scene, selection.adapterMethods));\n }\n selection.set([]);\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * @experimental\n * Static descriptor for the `clipboard.paste` Action — what a Paste button or\n * menu item triggers. It has no key binding: Cmd/Ctrl+V already arrives as a
|
|
1
|
+
{"version":3,"file":"clipboard.js","names":["clipboardCopyAction","createElement","CopyIcon","requiresSelection","clipboardCutAction","CutIcon","clipboard","deps","selection","scene","applyOps","ids","ops","buildDeleteOps","defaultCommitAdapter","clipboardPasteAction","PasteIcon","ActionDisabledReason","PASTE_EVENT_HANDLERS","kitWeaselJsonHandler","clipboardPasteEventAction","ANY_INGEST_MODS","INGEST_REQUIRES","ingestFromEvent","params"],"sources":["../../../../src/interactions/actions/defaults/clipboard.ts"],"sourcesContent":["import { createElement } from 'react';\nimport { CopyIcon, CutIcon, PasteIcon } from './icons/editIcons';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { ActionDisabledReason, type Action } from '@weasel-js/routing';\nimport { buildDeleteOps } from './delete';\nimport { requiresSelection } from './requiresSelection';\nimport { kitWeaselJsonHandler } from 'features/ingestion/weaselJsonHandler';\nimport { ANY_INGEST_MODS, INGEST_REQUIRES, ingestFromEvent } from './ingest';\n\n/**\n * @experimental\n * Static descriptor for the `clipboard.copy` Action (Cmd/Ctrl+C).\n */\nexport const clipboardCopyAction: Action & { requires: string[] } = {\n id: 'clipboard.copy',\n label: 'Copy',\n icon: createElement(CopyIcon),\n group: 'clipboard',\n defaultBinding: { kind: 'key', key: 'c', mods: { mod: true } },\n // Same gate as `duplicate`: a mode that can neither edit the page nor own a\n // selection has nothing to copy. Notably excludes `text-edit`, where Cmd+C\n // must stay the browser's own copy of the caret range.\n eligible: { capability: ['edits-page', 'creates-selection'] },\n // `selection` is read by the `enabled` gate, not the invoker — the\n // dispatcher builds deps for both, and an undeclared read is undefined.\n requires: ['clipboard', 'selection'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n deps.clipboard?.copy();\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * @experimental\n * Static descriptor for the `clipboard.cut` Action (Cmd/Ctrl+X) — copy, then\n * the same batched delete `deleteAction` performs, as one undo entry.\n */\nexport const clipboardCutAction: Action & { requires: string[] } = {\n id: 'clipboard.cut',\n label: 'Cut',\n icon: createElement(CutIcon),\n group: 'clipboard',\n defaultBinding: { kind: 'key', key: 'x', mods: { mod: true } },\n eligible: { capability: 'edits-page' },\n requires: ['clipboard', 'scene', 'selection', 'applyOps'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const clipboard = deps.clipboard;\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!clipboard || !selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n // Snapshot before removal — `snapshotSelection` reads live nodes.\n clipboard.copy();\n\n const ops = buildDeleteOps(scene, ids, 'Cut');\n if (ops.length > 0) {\n if (applyOps) applyOps(ops, 'Cut');\n else scene.applyBatch(ops, 'Cut', defaultCommitAdapter(scene, selection.adapterMethods));\n }\n selection.set([]);\n },\n },\n enabled: requiresSelection,\n};\n\n/**\n * @experimental\n * Static descriptor for the `clipboard.paste` Action — what a Paste button or\n * menu item triggers, pasting the last copy this canvas made. It has no key\n * binding: Cmd/Ctrl+V already arrives as a DOM `paste` event, which the\n * dispatcher routes to `clipboard.pasteEvent` or `ingest`, and a binding here\n * would fire alongside it and paste twice.\n */\nexport const clipboardPasteAction: Action & { requires: string[] } = {\n id: 'clipboard.paste',\n label: 'Paste',\n icon: createElement(PasteIcon),\n group: 'clipboard',\n eligible: { capability: 'edits-page' },\n requires: ['clipboard'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n deps.clipboard?.paste();\n },\n },\n enabled: (deps) => {\n const clipboard = deps?.clipboard;\n return clipboard && !clipboard.isEmpty() ? true : ActionDisabledReason.NotApplicable;\n },\n};\n\nconst PASTE_EVENT_HANDLERS = [kitWeaselJsonHandler];\n\n/**\n * @experimental\n * Static descriptor for the `clipboard.pasteEvent` Action — Cmd/Ctrl+V on a\n * canvas that edits and does not ingest. It answers the DOM `paste` event by\n * pasting nodes a kit canvas copied to the OS clipboard, in this tab or\n * another, and nothing else: an image, SVG, or file on the clipboard, and\n * every consumer content handler, need `ingest`. `ingest` binds the same\n * event and takes this payload among the rest, so `useStandardActions`\n * leaves this one unregistered wherever `ingest` is registered.\n *\n * Bound to `text/plain` because that is the only flavor of a copy a paste\n * event carries; a paste without text stays the page's.\n */\nexport const clipboardPasteEventAction: Action & { requires: string[] } = {\n id: 'clipboard.pasteEvent',\n label: 'Paste copied nodes',\n defaultBinding: { kind: 'paste', types: ['text/plain'], mods: ANY_INGEST_MODS },\n requires: [...INGEST_REQUIRES],\n invoker: {\n timing: 'immediate',\n run: (deps, params) => ingestFromEvent(deps, params, { handlers: PASTE_EVENT_HANDLERS }),\n },\n enabled: () => true,\n};\n"],"mappings":";;;;;;;;;AAaA,IAAaA,IAAuD;CAClE,IAAI;CACJ,OAAO;CACP,MAAMC,EAAcC,CAAQ;CAC5B,OAAO;CACP,gBAAgB;EAAE,MAAM;EAAO,KAAK;EAAK,MAAM,EAAE,KAAK,GAAK;CAAE;CAI7D,UAAU,EAAE,YAAY,CAAC,cAAc,mBAAmB,EAAE;CAG5D,UAAU,CAAC,aAAa,WAAW;CACnC,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,EAAK,WAAW,KAAK;EACvB;CACF;CACA,SAASC;AACX,GAOaC,IAAsD;CACjE,IAAI;CACJ,OAAO;CACP,MAAMH,EAAcI,CAAO;CAC3B,OAAO;CACP,gBAAgB;EAAE,MAAM;EAAO,KAAK;EAAK,MAAM,EAAE,KAAK,GAAK;CAAE;CAC7D,UAAU,EAAE,YAAY,aAAa;CACrC,UAAU;EAAC;EAAa;EAAS;EAAa;CAAU;CACxD,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAYC,EAAK,WACjBC,IAAYD,EAAK,WACjBE,IAAQF,EAAK,OACbG,IAAWH,EAAK;GACtB,IAAI,CAACD,KAAa,CAACE,KAAa,CAACC,GAAO;GACxC,IAAME,IAAMH,EAAU,IAAI;GAC1B,IAAIG,EAAI,WAAW,GAAG;GAGtB,EAAU,KAAK;GAEf,IAAMC,IAAMC,EAAeJ,GAAOE,GAAK,KAAK;GAK5C,AAJIC,EAAI,SAAS,MACXF,IAAUA,EAASE,GAAK,KAAK,IAC5BH,EAAM,WAAWG,GAAK,OAAOE,EAAqBL,GAAOD,EAAU,cAAc,CAAC,IAEzFA,EAAU,IAAI,CAAC,CAAC;EAClB;CACF;CACA,SAASL;AACX,GAUaY,IAAwD;CACnE,IAAI;CACJ,OAAO;CACP,MAAMd,EAAce,CAAS;CAC7B,OAAO;CACP,UAAU,EAAE,YAAY,aAAa;CACrC,UAAU,CAAC,WAAW;CACtB,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,EAAK,WAAW,MAAM;EACxB;CACF;CACA,UAAU,MAAS;EACjB,IAAMV,IAAYC,GAAM;EACxB,OAAOD,KAAa,CAACA,EAAU,QAAQ,IAAI,KAAOW,EAAqB;CACzE;AACF,GAEMC,IAAuB,CAACC,CAAoB,GAerCC,IAA6D;CACxE,IAAI;CACJ,OAAO;CACP,gBAAgB;EAAE,MAAM;EAAS,OAAO,CAAC,YAAY;EAAG,MAAMC;CAAgB;CAC9E,UAAU,CAAC,GAAGC,CAAe;CAC7B,SAAS;EACP,QAAQ;EACR,MAAM,GAAM,MAAWC,EAAgBhB,GAAMiB,GAAQ,EAAE,UAAUN,EAAqB,CAAC;CACzF;CACA,eAAe;AACjB"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { translatePoseViaDescriptor as e } from "../../../core/geometry/poseDescriptor.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { selectedRoots as t, translateTargets as n } from "../selectionSubtree.js";
|
|
3
|
+
import { nodeDescriptors as r, poseDescriptorOf as i } from "../poseDescriptorDep.js";
|
|
4
|
+
import { carryPose as a, inPlane as o, invertPlane as s, planeOf as c, selectionLayer as l } from "../planeInput.js";
|
|
5
|
+
import { defaultCommitAdapter as u } from "../defaultCommitAdapter.js";
|
|
6
|
+
import { scenePoseFrame as d } from "../poseFrame.js";
|
|
7
|
+
import { copySelection as f } from "./copySubtree.js";
|
|
8
8
|
//#region src/interactions/actions/defaults/clone.ts
|
|
9
|
-
var
|
|
9
|
+
var p = o({
|
|
10
10
|
id: "clone",
|
|
11
11
|
label: "Clone",
|
|
12
12
|
cursor: "copy",
|
|
@@ -21,87 +21,71 @@ var d = r({
|
|
|
21
21
|
],
|
|
22
22
|
invoker: {
|
|
23
23
|
timing: "ongoing",
|
|
24
|
-
start(
|
|
25
|
-
let
|
|
26
|
-
if (!
|
|
27
|
-
let
|
|
28
|
-
if (
|
|
29
|
-
let
|
|
30
|
-
for (let e of m) {
|
|
31
|
-
let t =
|
|
24
|
+
start(o, l) {
|
|
25
|
+
let p = o.deps.selection, m = o.deps.scene, h = o.deps.applyOps;
|
|
26
|
+
if (!p || !m) return {};
|
|
27
|
+
let g = p.get();
|
|
28
|
+
if (g.length === 0) return {};
|
|
29
|
+
let _ = d(m, o.deps.poseComposition), v = /* @__PURE__ */ new Map(), y = r(m, i(o.deps.poseDescriptor));
|
|
30
|
+
for (let e of n(m, _, g)) {
|
|
31
|
+
let t = m.get(e);
|
|
32
32
|
if (t === void 0) continue;
|
|
33
|
-
let
|
|
34
|
-
|
|
33
|
+
let n = s(c(o.deps.view, t.layer));
|
|
34
|
+
v.set(e, a(y(e), _.world(e), n));
|
|
35
35
|
}
|
|
36
|
-
if (
|
|
37
|
-
let
|
|
38
|
-
ids: m,
|
|
39
|
-
scene:
|
|
40
|
-
|
|
41
|
-
frame:
|
|
42
|
-
originPoses:
|
|
43
|
-
view:
|
|
36
|
+
if (v.size === 0) return {};
|
|
37
|
+
let b = {
|
|
38
|
+
ids: t(m, g),
|
|
39
|
+
scene: m,
|
|
40
|
+
descriptorOf: y,
|
|
41
|
+
frame: _,
|
|
42
|
+
originPoses: v,
|
|
43
|
+
view: o.deps.view,
|
|
44
44
|
currentDelta: {
|
|
45
45
|
dx: 0,
|
|
46
46
|
dy: 0
|
|
47
47
|
},
|
|
48
48
|
previews: /* @__PURE__ */ new Map(),
|
|
49
|
-
applyOps:
|
|
50
|
-
},
|
|
51
|
-
let
|
|
52
|
-
if (
|
|
53
|
-
let
|
|
54
|
-
return
|
|
49
|
+
applyOps: h
|
|
50
|
+
}, x = (t, n, r) => {
|
|
51
|
+
let i = b.originPoses.get(t), o = b.scene.get(t);
|
|
52
|
+
if (i === void 0 || !o) return;
|
|
53
|
+
let s = b.descriptorOf(t), l = e(i, n, r, s);
|
|
54
|
+
return b.frame.local(t, a(s, l, c(b.view, o.layer)));
|
|
55
55
|
};
|
|
56
56
|
return {
|
|
57
57
|
kind: "clone",
|
|
58
58
|
previewHidesSource: !1,
|
|
59
59
|
onMove(e) {
|
|
60
60
|
if (!e.drag) return;
|
|
61
|
-
|
|
61
|
+
b.currentDelta = {
|
|
62
62
|
dx: e.drag.delta.x,
|
|
63
63
|
dy: e.drag.delta.y
|
|
64
|
-
},
|
|
65
|
-
let { dx: t, dy: n } =
|
|
66
|
-
if (t !== 0 || n !== 0) for (let e of
|
|
64
|
+
}, b.previews.clear();
|
|
65
|
+
let { dx: t, dy: n } = b.currentDelta;
|
|
66
|
+
if (t !== 0 || n !== 0) for (let e of b.originPoses.keys()) b.previews.set(e, x(e, t, n));
|
|
67
67
|
},
|
|
68
68
|
onEnd(e, t) {
|
|
69
69
|
if (t === "cancel") {
|
|
70
|
-
|
|
70
|
+
b.previews.clear();
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
-
let { dx: n, dy: r } =
|
|
73
|
+
let { dx: n, dy: r } = b.currentDelta;
|
|
74
74
|
if (n === 0 && r === 0) {
|
|
75
|
-
|
|
75
|
+
b.previews.clear();
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
|
-
let i =
|
|
79
|
-
|
|
80
|
-
let t = v.scene.get(e), a = y(e, n, r);
|
|
81
|
-
if (a === void 0 || !t) continue;
|
|
82
|
-
let o = {
|
|
83
|
-
id: u(),
|
|
84
|
-
kind: t.kind,
|
|
85
|
-
layer: t.layer,
|
|
86
|
-
pose: a,
|
|
87
|
-
data: t.data,
|
|
88
|
-
parent: t.parent ?? null
|
|
89
|
-
};
|
|
90
|
-
i.push(l({
|
|
91
|
-
node: o,
|
|
92
|
-
label: "Clone"
|
|
93
|
-
}));
|
|
94
|
-
}
|
|
95
|
-
i.length > 0 && (v.applyOps ? v.applyOps(i, "Clone") : v.scene.applyBatch(i, "Clone", s(v.scene, d.adapterMethods))), v.previews.clear();
|
|
78
|
+
let { ops: i, copies: a } = f(b.scene, b.ids, (e, t) => b.originPoses.has(e) ? x(e, n, r) : t.pose, "Clone");
|
|
79
|
+
i.length > 0 && (b.applyOps ? b.applyOps(i, "Clone") : b.scene.applyBatch(i, "Clone", u(b.scene, p.adapterMethods)), p.set(a)), b.previews.clear();
|
|
96
80
|
},
|
|
97
|
-
previewIds: () =>
|
|
98
|
-
previewPose: (e) =>
|
|
81
|
+
previewIds: () => b.previews.keys(),
|
|
82
|
+
previewPose: (e) => b.previews.get(e) ?? null
|
|
99
83
|
};
|
|
100
84
|
}
|
|
101
85
|
},
|
|
102
86
|
enabled: () => !0
|
|
103
|
-
},
|
|
87
|
+
}, l);
|
|
104
88
|
//#endregion
|
|
105
|
-
export {
|
|
89
|
+
export { p as cloneAction };
|
|
106
90
|
|
|
107
91
|
//# sourceMappingURL=clone.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone.js","names":["cloneAction","inPlane","selection","ctx","scene","applyOps","ids","frame","scenePoseFrame","originPoses","descriptor","poseDescriptorOf","id","node","toEdited","invertPlane","planeOf","carryPose","scratch","landed","origin","moved","translatePoseViaDescriptor","dx","dy","moveCtx","reason","ops","originNode","newPose","freshNodeId","createInsertOp","defaultCommitAdapter","selectionLayer"],"sources":["../../../../src/interactions/actions/defaults/clone.ts"],"sourcesContent":["/**\n * `cloneAction` — ongoing Action descriptor for alt-drag clone.\n *\n * ## Status: REAL (scene-direct, no overlay)\n *\n * Implements the core clone-by-drag logic via insert ops committed through\n * `scene.applyBatch`:\n * - `start`: validates selection + scene; captures origin poses for all\n * selected nodes. The alt-modifier check that activates cloning in\n * `useClone` (via `CloneBehavior.activates`) is intentionally NOT applied\n * here — the descriptor fires when the dispatcher routes to it; modifier\n * discrimination is a dispatcher concern (Phase 12 TODO for alt-gating).\n * - `onMove`: tracks current drag delta in scratch (no scene writes).\n * - `onEnd('commit')`: emits one insert op per selected node (translated\n * pose) and commits them as a single batch — via the consumer `applyOps`\n * hook when present, else `scene.applyBatch(ops, 'Clone', ...)`. One\n * undo entry for the whole batch.\n * - `onEnd('cancel')`: no-op (scene never mutated during drag).\n *\n * ## What this does NOT wire (vs `useClone`)\n *\n * - Modifier gate: `useClone` only activates when `CloneBehavior.activates(mods)`\n * returns true (typically alt-held). The descriptor lacks that gate — it runs\n * whenever the dispatcher routes `clone`. Proper alt-gating requires a modifier-\n * discriminant in the dispatcher (Phase 12 TODO).\n * - Overlay: `useClone` renders a ghost via `setOverlay / clearOverlay`. The\n * descriptor has no overlay surface (deferred to Phase 7 overlay system).\n * - `expandIds`: group expansion is omitted; only leaf poses are cloned.\n * - Custom `CloneBehavior.onEnd` ops (e.g. `cloneByAltDrag`): the descriptor\n * uses a simpler `scene.add` path that does not delegate to behavior `onEnd`.\n * Behavior-pipeline cloning waits for a later phase.\n *\n * ## Pose generics\n *\n * Poses are translated through the `poseDescriptor` dep, as `moveAction` does.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle } from '@weasel-js/routing';\nimport type { Node, Scene, NodeId } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createInsertOp } from 'core/ops/create';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { freshNodeId } from './freshNodeId';\nimport { poseDescriptorOf } from '../poseDescriptorDep';\nimport { translatePoseViaDescriptor, type PoseDescriptor } from '../resize/geometry';\nimport { scenePoseFrame, type PoseFrame } from '../poseFrame';\nimport { carryPose, invertPlane, inPlane, planeOf, selectionLayer } from '../planeInput';\n\n// ---------------------------------------------------------------------------\n// Internal scratch\n// ---------------------------------------------------------------------------\n\ninterface CloneScratch {\n ids: NodeId[];\n scene: Scene<unknown, string, unknown>;\n descriptor: PoseDescriptor<unknown>;\n /** World reads and local writes over the scene's composition strategy. */\n frame: PoseFrame<unknown>;\n /** Origin poses captured at drag start, in world — the frame the drag\n * delta is expressed in, and the plane the edit is measured in. The copy\n * keeps its source's parent and layer, so each translated result is\n * carried back to that layer's plane and stored in that same frame. */\n originPoses: Map<NodeId, unknown>;\n /** The view the invocation started with, read for `planeOf`. */\n view: unknown;\n /** Running drag delta — updated each onMove, applied once at commit. */\n currentDelta: { dx: number; dy: number };\n /** Preview poses keyed by ORIGINAL node id (the clone targets don't have\n * scene ids yet; the preview-ghost layer paints the originals' silhouette\n * at the translated pose — original stays visible at its committed home,\n * ghost appears at the drag target). */\n previews: Map<NodeId, unknown>;\n /** Optional consumer commit hook captured at gesture start. When present,\n * the insert ops route through it (consumer history) instead of\n * `scene.applyBatch`. Undefined → fall back to `scene.applyBatch`. */\n applyOps?: (ops: Op[], label: string) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `clone` Action.\n *\n * Requires dep-schema entries: `selection`, `scene`.\n *\n * Clones selected nodes into new scene nodes translated by the drag delta.\n * Commits insert ops via `scene.applyBatch(ops, 'Clone', ...)` (or the\n * consumer `applyOps` hook) for a single undo entry.\n *\n * @see useClone — the React hook this descriptor partially mirrors.\n */\nexport const cloneAction: Action & { requires: string[] } = inPlane({\n id: 'clone',\n label: 'Clone',\n // No default binding: a bare `{ kind: 'drag' }` would clone a non-empty\n // selection on any drag no tool claimed. Alt-drag on a body binds it\n // (`selectionMoveBindings`, the `move` preset).\n // The platform's duplicate cursor, and the whole reason this field is\n // modifier-aware: the select tool binds clone behind `mods: { alt: true }`,\n // so the pump predicts it — and shows this — only while Alt is down.\n cursor: 'copy',\n activeCursor: 'copy',\n eligible: { capability: ['edits-page', 'creates-selection'] },\n requires: ['selection', 'scene', 'applyOps', 'poseDescriptor', 'poseComposition'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, _opts): OngoingHandle {\n const selection = ctx.deps.selection;\n const scene = ctx.deps.scene;\n const applyOps = ctx.deps.applyOps;\n\n if (!selection || !scene) return {};\n\n const ids = selection.get() as NodeId[];\n if (ids.length === 0) return {};\n\n // Capture origin poses once at drag start.\n const frame = scenePoseFrame(scene, ctx.deps.poseComposition);\n const originPoses = new Map<NodeId, unknown>();\n const descriptor = poseDescriptorOf(ctx.deps.poseDescriptor);\n for (const id of ids) {\n const node = scene.get(id);\n if (node === undefined) continue;\n const toEdited = invertPlane(planeOf(ctx.deps.view, node.layer));\n originPoses.set(id, carryPose(descriptor, frame.world(id), toEdited));\n }\n\n if (originPoses.size === 0) return {};\n\n const scratch: CloneScratch = {\n ids,\n scene,\n descriptor,\n frame,\n originPoses,\n view: ctx.deps.view,\n currentDelta: { dx: 0, dy: 0 },\n previews: new Map<NodeId, unknown>(),\n applyOps,\n };\n\n /** Where the copy of `id` lands for a drag of `(dx, dy)`, as stored. */\n const landed = (id: NodeId, dx: number, dy: number): unknown => {\n const origin = scratch.originPoses.get(id);\n const node = scratch.scene.get(id);\n if (origin === undefined || !node) return undefined;\n const moved = translatePoseViaDescriptor(origin, dx, dy, scratch.descriptor);\n return scratch.frame.local(id, carryPose(scratch.descriptor, moved, planeOf(scratch.view, node.layer)));\n };\n\n return {\n kind: 'clone',\n // Clone: source stays visible at its committed pose; the ghost\n // (rendered via previewIds/previewPose below) appears at the\n // drag target. Opt out of the default \"hide source\" behavior\n // move/resize/rotate use.\n previewHidesSource: false,\n onMove(moveCtx: InvocationCtx): void {\n if (!moveCtx.drag) return;\n scratch.currentDelta = {\n dx: moveCtx.drag.delta.x,\n dy: moveCtx.drag.delta.y,\n };\n // Preview: paint each original's silhouette at the translated pose.\n // The original stays at its committed location (we don't hide it);\n // the ghost overlay shows where the new copy will land on commit.\n scratch.previews.clear();\n const { dx, dy } = scratch.currentDelta;\n if (dx === 0 && dy === 0) return;\n for (const id of scratch.originPoses.keys()) scratch.previews.set(id, landed(id, dx, dy)!);\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n if (reason === 'cancel') {\n scratch.previews.clear();\n return;\n }\n const { dx, dy } = scratch.currentDelta;\n // Zero-delta drag — no clone.\n if (dx === 0 && dy === 0) {\n scratch.previews.clear();\n return;\n }\n\n // Build one insert op per clone target — same nodes/values the old\n // direct `scene.add` loop produced (kind/layer/data/parent preserved,\n // pose translated by the drag delta), then route the batch through the\n // consumer `applyOps` hook when present (so an app with its own history\n // captures the clone as a single undo entry); otherwise commit straight\n // to the scene's own history. One applyOps / applyBatch call =\n // one undo entry, matching the prior single `scene.batch('Clone', …)`.\n const ops: Op[] = [];\n for (const id of scratch.ids) {\n const originNode = scratch.scene.get(id);\n const newPose = landed(id, dx, dy);\n if (newPose === undefined || !originNode) continue;\n // The old `scene.add` (no explicit id) minted a random id; we\n // pre-generate one so the insert op carries a full node. Id value\n // was never observable, so behavior is preserved.\n const node = {\n id: freshNodeId(),\n kind: originNode.kind,\n layer: originNode.layer,\n pose: newPose,\n data: originNode.data,\n parent: originNode.parent ?? null,\n } as Node<unknown, string, unknown>;\n ops.push(createInsertOp<Node<unknown, string, unknown>>({ node, label: 'Clone' }));\n }\n if (ops.length > 0) {\n if (scratch.applyOps) scratch.applyOps(ops, 'Clone');\n else scratch.scene.applyBatch(ops, 'Clone', defaultCommitAdapter(scratch.scene, selection.adapterMethods));\n }\n scratch.previews.clear();\n },\n previewIds: () => scratch.previews.keys(),\n previewPose: (id: string) => scratch.previews.get(id as NodeId) ?? null,\n };\n },\n },\n enabled: () => true,\n}, selectionLayer);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"clone.js","names":["cloneAction","inPlane","selection","ctx","scene","applyOps","ids","frame","scenePoseFrame","originPoses","descriptorOf","nodeDescriptors","poseDescriptorOf","id","translateTargets","node","toEdited","invertPlane","planeOf","carryPose","scratch","selectedRoots","landed","origin","d","moved","translatePoseViaDescriptor","dx","dy","moveCtx","reason","copySelection","ops","defaultCommitAdapter","copies","selectionLayer"],"sources":["../../../../src/interactions/actions/defaults/clone.ts"],"sourcesContent":["/**\n * `cloneAction` — ongoing Action descriptor for alt-drag clone.\n *\n * `start` captures the world pose of every node the copy will hold, `onMove`\n * tracks the drag delta and previews the copies, and `onEnd('commit')` inserts\n * them as one batch — through the consumer `applyOps` hook when present, else\n * `scene.applyBatch`. Nothing is written before the commit, so a cancel only\n * clears the preview.\n *\n * The action does not gate on a modifier: it runs whenever the dispatcher\n * routes to it, and the binding that names it carries the `alt` requirement.\n */\n\nimport type { Action } from '@weasel-js/routing';\nimport type { InvocationCtx, OngoingHandle } from '@weasel-js/routing';\nimport type { Scene, NodeId } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { copySelection } from './copySubtree';\nimport { selectedRoots, translateTargets } from '../selectionSubtree';\nimport { nodeDescriptors, poseDescriptorOf } from '../poseDescriptorDep';\nimport { translatePoseViaDescriptor, type PoseDescriptor } from '../resize/geometry';\nimport { scenePoseFrame, type PoseFrame } from '../poseFrame';\nimport { carryPose, invertPlane, inPlane, planeOf, selectionLayer } from '../planeInput';\n\n// ---------------------------------------------------------------------------\n// Internal scratch\n// ---------------------------------------------------------------------------\n\ninterface CloneScratch {\n /** The selected ids a copy starts from; each brings its subtree. */\n ids: NodeId[];\n scene: Scene<unknown, string, unknown>;\n descriptorOf: (id: NodeId) => PoseDescriptor<unknown>;\n /** World reads and local writes over the scene's composition strategy. */\n frame: PoseFrame<unknown>;\n /** Origin poses captured at drag start, in world — the frame the drag\n * delta is expressed in, and the plane the edit is measured in. The copy\n * keeps its source's parent and layer, so each translated result is\n * carried back to that layer's plane and stored in that same frame.\n * Holds every node the copy moves itself: a node stored in a copied frame\n * is absent, because the copy of that frame carries it. */\n originPoses: Map<NodeId, unknown>;\n /** The view the invocation started with, read for `planeOf`. */\n view: unknown;\n /** Running drag delta — updated each onMove, applied once at commit. */\n currentDelta: { dx: number; dy: number };\n /** Preview poses keyed by the original's id: the copies have no ids yet. */\n previews: Map<NodeId, unknown>;\n /** Optional consumer commit hook captured at gesture start. When present,\n * the insert ops route through it (consumer history) instead of\n * `scene.applyBatch`. Undefined → fall back to `scene.applyBatch`. */\n applyOps?: (ops: Op[], label: string) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Descriptor\n// ---------------------------------------------------------------------------\n\n/**\n * @experimental\n * Static descriptor for the `clone` Action.\n *\n * Requires dep-schema entries: `selection`, `scene`.\n *\n * Copies each selected node, with its subtree, to where the drag left it.\n * One undo entry.\n */\nexport const cloneAction: Action & { requires: string[] } = inPlane({\n id: 'clone',\n label: 'Clone',\n // No default binding: a bare `{ kind: 'drag' }` would clone a non-empty\n // selection on any drag no tool claimed. Alt-drag on a body binds it\n // (`selectionMoveBindings`, the `move` preset).\n // The platform's duplicate cursor, and the whole reason this field is\n // modifier-aware: the select tool binds clone behind `mods: { alt: true }`,\n // so the pump predicts it — and shows this — only while Alt is down.\n cursor: 'copy',\n activeCursor: 'copy',\n eligible: { capability: ['edits-page', 'creates-selection'] },\n requires: ['selection', 'scene', 'applyOps', 'poseDescriptor', 'poseComposition'],\n invoker: {\n timing: 'ongoing',\n start(ctx: InvocationCtx, _opts): OngoingHandle {\n const selection = ctx.deps.selection;\n const scene = ctx.deps.scene;\n const applyOps = ctx.deps.applyOps;\n\n if (!selection || !scene) return {};\n\n const ids = selection.get() as NodeId[];\n if (ids.length === 0) return {};\n\n // Capture origin poses once at drag start.\n const frame = scenePoseFrame(scene, ctx.deps.poseComposition);\n const originPoses = new Map<NodeId, unknown>();\n const descriptorOf = nodeDescriptors(scene, poseDescriptorOf(ctx.deps.poseDescriptor));\n for (const id of translateTargets(scene, frame, ids)) {\n const node = scene.get(id);\n if (node === undefined) continue;\n const toEdited = invertPlane(planeOf(ctx.deps.view, node.layer));\n originPoses.set(id, carryPose(descriptorOf(id), frame.world(id), toEdited));\n }\n\n if (originPoses.size === 0) return {};\n\n const scratch: CloneScratch = {\n ids: selectedRoots(scene, ids),\n scene,\n descriptorOf,\n frame,\n originPoses,\n view: ctx.deps.view,\n currentDelta: { dx: 0, dy: 0 },\n previews: new Map<NodeId, unknown>(),\n applyOps,\n };\n\n /** Where the copy of `id` lands for a drag of `(dx, dy)`, as stored. */\n const landed = (id: NodeId, dx: number, dy: number): unknown => {\n const origin = scratch.originPoses.get(id);\n const node = scratch.scene.get(id);\n if (origin === undefined || !node) return undefined;\n const d = scratch.descriptorOf(id);\n const moved = translatePoseViaDescriptor(origin, dx, dy, d);\n return scratch.frame.local(id, carryPose(d, moved, planeOf(scratch.view, node.layer)));\n };\n\n return {\n kind: 'clone',\n // Clone: source stays visible at its committed pose; the ghost\n // (rendered via previewIds/previewPose below) appears at the\n // drag target. Opt out of the default \"hide source\" behavior\n // move/resize/rotate use.\n previewHidesSource: false,\n onMove(moveCtx: InvocationCtx): void {\n if (!moveCtx.drag) return;\n scratch.currentDelta = {\n dx: moveCtx.drag.delta.x,\n dy: moveCtx.drag.delta.y,\n };\n // Preview: paint each original's silhouette at the translated pose.\n // The original stays at its committed location (we don't hide it);\n // the ghost overlay shows where the new copy will land on commit.\n scratch.previews.clear();\n const { dx, dy } = scratch.currentDelta;\n if (dx === 0 && dy === 0) return;\n for (const id of scratch.originPoses.keys()) scratch.previews.set(id, landed(id, dx, dy)!);\n },\n onEnd(_endCtx: InvocationCtx, reason: 'commit' | 'cancel'): void {\n if (reason === 'cancel') {\n scratch.previews.clear();\n return;\n }\n const { dx, dy } = scratch.currentDelta;\n // Zero-delta drag — no clone.\n if (dx === 0 && dy === 0) {\n scratch.previews.clear();\n return;\n }\n\n const { ops, copies } = copySelection(\n scratch.scene,\n scratch.ids,\n (id, node) => (scratch.originPoses.has(id) ? landed(id, dx, dy) : node.pose),\n 'Clone',\n );\n if (ops.length > 0) {\n if (scratch.applyOps) scratch.applyOps(ops, 'Clone');\n else scratch.scene.applyBatch(ops, 'Clone', defaultCommitAdapter(scratch.scene, selection.adapterMethods));\n selection.set(copies);\n }\n scratch.previews.clear();\n },\n previewIds: () => scratch.previews.keys(),\n previewPose: (id: string) => scratch.previews.get(id as NodeId) ?? null,\n };\n },\n },\n enabled: () => true,\n}, selectionLayer);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { selectedRoots as e } from "../selectionSubtree.js";
|
|
2
|
+
import { createInsertOp as t } from "../../../core/ops/create.js";
|
|
3
|
+
//#region src/interactions/actions/defaults/copySubtree.ts
|
|
4
|
+
function n(e, r, i, a, o, s, c, l) {
|
|
5
|
+
let u = e.get(r);
|
|
6
|
+
if (!u) return null;
|
|
7
|
+
let d = e.mintId();
|
|
8
|
+
l.set(r, d);
|
|
9
|
+
let f = {
|
|
10
|
+
...u,
|
|
11
|
+
id: d,
|
|
12
|
+
pose: o(r, u, a),
|
|
13
|
+
parent: i
|
|
14
|
+
};
|
|
15
|
+
c.push(t({
|
|
16
|
+
node: f,
|
|
17
|
+
label: s
|
|
18
|
+
}));
|
|
19
|
+
for (let t of e.childrenOf(r)) n(e, t, d, !1, o, s, c, l);
|
|
20
|
+
return d;
|
|
21
|
+
}
|
|
22
|
+
function r(t, r, i, a) {
|
|
23
|
+
let o = [], s = [], c = /* @__PURE__ */ new Map();
|
|
24
|
+
for (let l of e(t, r)) {
|
|
25
|
+
let e = n(t, l, t.get(l)?.parent ?? null, !0, i, a, o, c);
|
|
26
|
+
e && s.push(e);
|
|
27
|
+
}
|
|
28
|
+
for (let e of o) {
|
|
29
|
+
let t = e.args.node, n = t.dependsOn;
|
|
30
|
+
Array.isArray(n) && n.every((e) => c.has(e)) && (t.dependsOn = n.map((e) => c.get(e)));
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
ops: o,
|
|
34
|
+
copies: s
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { r as copySelection };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=copySubtree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copySubtree.js","names":["copySubtree","node","scene","id","newId","copy","poseOf","isRoot","createInsertOp","child","label","ops","copyOf","copySelection","copies","selectedRoots","ids","op","deps","dep"],"sources":["../../../../src/interactions/actions/defaults/copySubtree.ts"],"sourcesContent":["import type { Node, NodeId, Scene } from 'core/scene/types';\nimport type { Op } from 'core/ops/types';\nimport { createInsertOp } from 'core/ops/create';\nimport { selectedRoots } from '../selectionSubtree';\n\ntype AnyScene = Scene<unknown, string, unknown>;\ntype AnyNode = Node<unknown, string, unknown>;\n\n/** The pose a copy of `node` is stored with. `isRoot` is true for a selected\n * node and false for one copied because an ancestor was. */\nexport type CopyPose = (id: NodeId, node: AnyNode, isRoot: boolean) => unknown;\n\nfunction copySubtree(\n scene: AnyScene,\n id: NodeId,\n parent: NodeId | null,\n isRoot: boolean,\n poseOf: CopyPose,\n label: string,\n ops: Op[],\n copyOf: Map<NodeId, NodeId>,\n): NodeId | null {\n const node = scene.get(id);\n if (!node) return null;\n const newId = scene.mintId();\n copyOf.set(id, newId);\n const copy = { ...node, id: newId, pose: poseOf(id, node, isRoot), parent } as AnyNode;\n ops.push(createInsertOp<AnyNode>({ node: copy, label }));\n for (const child of scene.childrenOf(id)) {\n copySubtree(scene, child, newId, false, poseOf, label, ops, copyOf);\n }\n return newId;\n}\n\n/**\n * Insert ops copying each of `ids` with its whole subtree, so copying a group\n * produces a populated group. Ops are in pre-order: a parent is inserted\n * before its children. A copied root keeps its source's parent.\n *\n * A copy that derives from an id list follows the copies when every node in\n * the list was copied with it, and keeps the original list otherwise.\n */\nexport function copySelection(\n scene: AnyScene,\n ids: readonly string[],\n poseOf: CopyPose,\n label: string,\n): { ops: Op[]; copies: NodeId[] } {\n const ops: Op[] = [];\n const copies: NodeId[] = [];\n const copyOf = new Map<NodeId, NodeId>();\n for (const id of selectedRoots(scene, ids)) {\n const newId = copySubtree(scene, id, scene.get(id)?.parent ?? null, true, poseOf, label, ops, copyOf);\n if (newId) copies.push(newId);\n }\n for (const op of ops) {\n const node = (op.args as { node: AnyNode }).node;\n const deps = node.dependsOn;\n if (!Array.isArray(deps) || !deps.every((dep) => copyOf.has(dep))) continue;\n (node as { dependsOn?: readonly NodeId[] }).dependsOn = deps.map((dep) => copyOf.get(dep)!);\n }\n return { ops, copies };\n}\n"],"mappings":";;;AAYA,SAASA,EACP,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACe;CACf,IAAMC,IAAOC,EAAM,IAAIC,CAAE;CACzB,IAAI,CAACF,GAAM,OAAO;CAClB,IAAMG,IAAQF,EAAM,OAAO;CAC3B,EAAO,IAAIC,GAAIC,CAAK;CACpB,IAAMC,IAAO;EAAE,GAAGJ;EAAM,IAAIG;EAAO,MAAME,EAAOH,GAAIF,GAAMM,CAAM;EAAG;CAAO;CAC1E,EAAI,KAAKC,EAAwB;EAAE,MAAMH;EAAM;CAAM,CAAC,CAAC;CACvD,KAAK,IAAMI,KAASP,EAAM,WAAWC,CAAE,GACrC,EAAYD,GAAOO,GAAOL,GAAO,IAAOE,GAAQI,GAAOC,GAAKC,CAAM;CAEpE,OAAOR;AACT;AAUA,SAAgBS,EACd,GACA,GACA,GACA,GACiC;CACjC,IAAMF,IAAY,CAAC,GACbG,IAAmB,CAAC,GACpBF,oBAAS,IAAI,IAAoB;CACvC,KAAK,IAAMT,KAAMY,EAAcb,GAAOc,CAAG,GAAG;EAC1C,IAAMZ,IAAQJ,EAAYE,GAAOC,GAAID,EAAM,IAAIC,CAAE,CAAC,EAAE,UAAU,MAAM,IAAMG,GAAQI,GAAOC,GAAKC,CAAM;EACpG,AAAIR,KAAOU,EAAO,KAAKV,CAAK;CAC9B;CACA,KAAK,IAAMa,KAAMN,GAAK;EACpB,IAAMV,IAAQgB,EAAG,KAA2B,MACtCC,IAAOjB,EAAK;EAClB,AAAK,MAAM,QAAQiB,CAAI,KAAMA,EAAK,OAAO,MAAQN,EAAO,IAAIO,CAAG,CAAC,MAChE,EAA4C,YAAYD,EAAK,KAAK,MAAQN,EAAO,IAAIO,CAAG,CAAE;CAC5F;CACA,OAAO;EAAE;EAAK;CAAO;AACvB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { visualBoundsViaDescriptor as e } from "../../../core/geometry/poseDescriptor.js";
|
|
2
|
+
import { translateEach as t } from "../selectionSubtree.js";
|
|
2
3
|
import { poseDescriptorOf as n } from "../poseDescriptorDep.js";
|
|
3
4
|
import { scenePoseFrame as r } from "../poseFrame.js";
|
|
4
5
|
import { planDistribute as i } from "../distribute/plan.js";
|
|
@@ -19,22 +20,22 @@ var l = {
|
|
|
19
20
|
function f(n, a, o, s, c, l) {
|
|
20
21
|
let u = n.get();
|
|
21
22
|
if (u.length < 3) return;
|
|
22
|
-
let d = r(a, l), f = u.map((
|
|
23
|
-
let n = d.world(
|
|
23
|
+
let d = r(a, l), f = u.map((t) => {
|
|
24
|
+
let n = d.world(t);
|
|
24
25
|
return {
|
|
25
|
-
id:
|
|
26
|
+
id: t,
|
|
26
27
|
pose: n,
|
|
27
|
-
b:
|
|
28
|
+
b: e(n, c)
|
|
29
|
+
};
|
|
30
|
+
}), p = i(f.map((e) => e.b), o, s), m = f.map((e, t) => {
|
|
31
|
+
let n = p[t] - (o === "x" ? e.b.x : e.b.y);
|
|
32
|
+
return {
|
|
33
|
+
id: e.id,
|
|
34
|
+
dx: o === "x" ? n : 0,
|
|
35
|
+
dy: o === "y" ? n : 0
|
|
28
36
|
};
|
|
29
|
-
}), p = i(f.map((e) => e.b), o, s);
|
|
30
|
-
a.batch("Distribute", () => {
|
|
31
|
-
for (let t = 0; t < f.length; t++) {
|
|
32
|
-
let n = f[t], r = p[t] - (o === "x" ? n.b.x : n.b.y);
|
|
33
|
-
if (r === 0) continue;
|
|
34
|
-
let i = o === "x" ? r : 0, s = o === "y" ? r : 0, l = e(n.pose, i, s, c);
|
|
35
|
-
a.setPose(n.id, d.local(n.id, l));
|
|
36
|
-
}
|
|
37
37
|
});
|
|
38
|
+
a.batch("Distribute", () => t(a, d, c, m));
|
|
38
39
|
}
|
|
39
40
|
function p(e) {
|
|
40
41
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distribute.js","names":["ID_FOR","LABEL_FOR","ICON_FOR","DistributeHorizontalIcon","DistributeVerticalIcon","distributeSelection","ids","selection","frame","scenePoseFrame","scene","poseComposition","items","pose","id","visualBoundsViaDescriptor","geom","targets","planDistribute","it","axis","mode","
|
|
1
|
+
{"version":3,"file":"distribute.js","names":["ID_FOR","LABEL_FOR","ICON_FOR","DistributeHorizontalIcon","DistributeVerticalIcon","distributeSelection","ids","selection","frame","scenePoseFrame","scene","poseComposition","items","pose","id","visualBoundsViaDescriptor","geom","targets","planDistribute","it","axis","mode","moves","delta","i","translateEach","makeDistributeAction","deps","params","poseDescriptorOf","ActionDisabledReason","distributeHorizontalAction","distributeVerticalAction"],"sources":["../../../../src/interactions/actions/defaults/distribute.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { Scene } from 'core/scene/types';\nimport type { PoseDescriptor } from '../resize/geometry';\nimport { poseDescriptorOf } from '../poseDescriptorDep';\nimport { visualBoundsViaDescriptor } from '../align/align';\nimport type { DistributeAxis, DistributeMode } from '../distribute/distribute';\nimport { planDistribute } from '../distribute/plan';\nimport { scenePoseFrame } from '../poseFrame';\nimport { translateEach } from '../selectionSubtree';\nimport type { Action } from '@weasel-js/routing';\nimport { ActionDisabledReason } from '@weasel-js/routing';\nimport type { SelectionApi } from 'core/selection/useSelection';\nimport type { ImmediateInvoker } from '@weasel-js/routing';\nimport { DistributeHorizontalIcon, DistributeVerticalIcon } from './icons/distributeIcons';\n\nconst ID_FOR: Record<DistributeAxis, string> = { x: 'distribute.horizontal', y: 'distribute.vertical' };\nconst LABEL_FOR: Record<DistributeAxis, string> = { x: 'Distribute Horizontally', y: 'Distribute Vertically' };\nconst ICON_FOR: Record<DistributeAxis, ReactNode> = {\n x: <DistributeHorizontalIcon />,\n y: <DistributeVerticalIcon />,\n};\n\n// ---------------------------------------------------------------------------\n// Shared helper for descriptor invokers\n// ---------------------------------------------------------------------------\n\n/**\n * Apply a distribute operation to the current selection via the Scene API.\n * Reads poses through the `poseDescriptor` dep; `mode` comes from the\n * binding's `params.mode`.\n *\n * The span being divided is a world span, so the bounds are read and\n * translated in world and each result is stored back in its own parent's\n * frame.\n */\nfunction distributeSelection(\n selection: SelectionApi,\n scene: Scene<unknown, string, unknown>,\n axis: DistributeAxis,\n mode: DistributeMode,\n geom: PoseDescriptor<unknown>,\n poseComposition: unknown,\n): void {\n const ids = selection.get();\n if (ids.length < 3) return;\n const frame = scenePoseFrame(scene, poseComposition);\n\n const items = ids.map((id) => {\n const pose = frame.world(id);\n return { id, pose, b: visualBoundsViaDescriptor(pose, geom) };\n });\n const targets = planDistribute(items.map((it) => it.b), axis, mode);\n\n const moves = items.map((it, i) => {\n const delta = targets[i] - (axis === 'x' ? it.b.x : it.b.y);\n return { id: it.id, dx: axis === 'x' ? delta : 0, dy: axis === 'y' ? delta : 0 };\n });\n scene.batch('Distribute', () => translateEach(scene, frame, geom, moves));\n}\n\n// ---------------------------------------------------------------------------\n// Static descriptors\n// ---------------------------------------------------------------------------\n\nfunction makeDistributeAction(axis: DistributeAxis): Action {\n return {\n id: ID_FOR[axis],\n label: LABEL_FOR[axis],\n icon: ICON_FOR[axis],\n group: 'distribute',\n eligible: { capability: 'transforms-selection' },\n requires: ['selection', 'scene', 'poseDescriptor', 'poseComposition'],\n // No default keybindings. Wire bindings explicitly via the actions registry.\n invoker: {\n timing: 'immediate',\n run: (deps, params) => {\n const selection = deps.selection;\n const scene = deps.scene;\n if (!selection || !scene) return;\n const mode = (params?.mode as DistributeMode | undefined) ?? 'centers';\n distributeSelection(selection, scene, axis, mode, poseDescriptorOf(deps.poseDescriptor), deps.poseComposition);\n },\n } satisfies ImmediateInvoker,\n // Deps-aware, matching `distributeSelection`'s own `ids.length < 3` guard:\n // a constant disabled reason greys the entry out forever (see\n // `requiresSelection`).\n enabled: (deps) => {\n const selection = deps?.selection;\n const count = selection?.get().length ?? 0;\n return count >= 3 ? true : ActionDisabledReason.SelectionRequired;\n },\n };\n}\n\n/** @experimental Static descriptor for distribute-horizontal. */\nexport const distributeHorizontalAction = makeDistributeAction('x');\n/** @experimental Static descriptor for distribute-vertical. */\nexport const distributeVerticalAction = makeDistributeAction('y');\n\n"],"mappings":";;;;;;;;;AAeA,IAAMA,IAAyC;CAAE,GAAG;CAAyB,GAAG;AAAsB,GAChGC,IAA4C;CAAE,GAAG;CAA2B,GAAG;AAAwB,GACvGC,IAA8C;CAClD,GAAG,kBAACC,GAAD,CAA2B,CAAA;CAC9B,GAAG,kBAACC,GAAD,CAAyB,CAAA;AAC9B;AAeA,SAASC,EACP,GACA,GACA,GACA,GACA,GACA,GACM;CACN,IAAMC,IAAMC,EAAU,IAAI;CAC1B,IAAID,EAAI,SAAS,GAAG;CACpB,IAAME,IAAQC,EAAeC,GAAOC,CAAe,GAE7CC,IAAQN,EAAI,KAAK,MAAO;EAC5B,IAAMO,IAAOL,EAAM,MAAMM,CAAE;EAC3B,OAAO;GAAE;GAAI;GAAM,GAAGC,EAA0BF,GAAMG,CAAI;EAAE;CAC9D,CAAC,GACKC,IAAUC,EAAeN,EAAM,KAAK,MAAOO,EAAG,CAAC,GAAGC,GAAMC,CAAI,GAE5DC,IAAQV,EAAM,KAAK,GAAI,MAAM;EACjC,IAAMW,IAAQN,EAAQO,MAAMJ,MAAS,MAAMD,EAAG,EAAE,IAAIA,EAAG,EAAE;EACzD,OAAO;GAAE,IAAIA,EAAG;GAAI,IAAIC,MAAS,MAAMG,IAAQ;GAAG,IAAIH,MAAS,MAAMG,IAAQ;EAAE;CACjF,CAAC;CACD,EAAM,MAAM,oBAAoBE,EAAcf,GAAOF,GAAOQ,GAAMM,CAAK,CAAC;AAC1E;AAMA,SAASI,EAAqB,GAA8B;CAC1D,OAAO;EACL,IAAI1B,EAAOoB;EACX,OAAOnB,EAAUmB;EACjB,MAAMlB,EAASkB;EACf,OAAO;EACP,UAAU,EAAE,YAAY,uBAAuB;EAC/C,UAAU;GAAC;GAAa;GAAS;GAAkB;EAAiB;EAEpE,SAAS;GACP,QAAQ;GACR,MAAM,GAAM,MAAW;IACrB,IAAMb,IAAYoB,EAAK,WACjBjB,IAAQiB,EAAK;IACnB,AAAKpB,KAAcG,KAEnBL,EAAoBE,GAAWG,GAAOU,GADxBQ,GAAQ,QAAuC,WACXC,EAAiBF,EAAK,cAAc,GAAGA,EAAK,eAAe;GAC/G;EACF;EAIA,UAAU,QACUA,GAAM,UAAA,EACC,IAAI,CAAC,CAAC,UAAU,MACzB,KAAWG,EAAqB;CAEpD;AACF;AAGA,IAAaC,IAA6BL,EAAqB,GAAG,GAErDM,IAA6BN,EAAqB,GAAG"}
|
|
@@ -1,46 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { poseDescriptorOf as n } from "../poseDescriptorDep.js";
|
|
1
|
+
import { translatePoseViaDescriptor as e } from "../../../core/geometry/poseDescriptor.js";
|
|
2
|
+
import { nodeDescriptors as t, poseDescriptorOf as n } from "../poseDescriptorDep.js";
|
|
4
3
|
import { defaultCommitAdapter as r } from "../defaultCommitAdapter.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { createElement as c } from "react";
|
|
4
|
+
import { copySelection as i } from "./copySubtree.js";
|
|
5
|
+
import { DuplicateIcon as a } from "./icons/editIcons.js";
|
|
6
|
+
import { requiresSelection as o } from "./requiresSelection.js";
|
|
7
|
+
import { createElement as s } from "react";
|
|
10
8
|
//#region src/interactions/actions/defaults/duplicate.ts
|
|
11
|
-
var l =
|
|
12
|
-
function u(e, t, n) {
|
|
13
|
-
let r = e.get(t)?.parent ?? null;
|
|
14
|
-
for (; r != null;) {
|
|
15
|
-
if (n.has(r)) return !0;
|
|
16
|
-
r = e.get(r)?.parent ?? null;
|
|
17
|
-
}
|
|
18
|
-
return !1;
|
|
19
|
-
}
|
|
20
|
-
function d(e, n, r, o, s, c, l) {
|
|
21
|
-
let u = e.get(n);
|
|
22
|
-
if (!u) return null;
|
|
23
|
-
let f = a(), p = {
|
|
24
|
-
...u,
|
|
25
|
-
id: f,
|
|
26
|
-
pose: t(u.pose, o.dx, o.dy, l),
|
|
27
|
-
parent: r
|
|
28
|
-
};
|
|
29
|
-
c.push(i({
|
|
30
|
-
node: p,
|
|
31
|
-
label: "Duplicate"
|
|
32
|
-
}));
|
|
33
|
-
let m = s ? o : {
|
|
34
|
-
dx: 0,
|
|
35
|
-
dy: 0
|
|
36
|
-
};
|
|
37
|
-
for (let t of e.childrenOf(n)) d(e, t, f, m, s, c, l);
|
|
38
|
-
return f;
|
|
39
|
-
}
|
|
40
|
-
var f = {
|
|
9
|
+
var c = 12, l = {
|
|
41
10
|
id: "duplicate",
|
|
42
11
|
label: "Duplicate",
|
|
43
|
-
icon:
|
|
12
|
+
icon: s(a),
|
|
44
13
|
group: "edit",
|
|
45
14
|
defaultBinding: {
|
|
46
15
|
kind: "key",
|
|
@@ -57,27 +26,18 @@ var f = {
|
|
|
57
26
|
],
|
|
58
27
|
invoker: {
|
|
59
28
|
timing: "immediate",
|
|
60
|
-
run: (
|
|
61
|
-
let
|
|
62
|
-
if (!
|
|
63
|
-
let
|
|
64
|
-
if (
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
dy: l
|
|
68
|
-
}, m = [], h = [];
|
|
69
|
-
for (let n of s) {
|
|
70
|
-
let r = e(n), i = a.get(r);
|
|
71
|
-
if (!i || u(a, r, c)) continue;
|
|
72
|
-
let o = d(a, r, i.parent ?? null, p, t.poseComposition === void 0, m, f);
|
|
73
|
-
o && h.push(o);
|
|
74
|
-
}
|
|
75
|
-
m.length !== 0 && (o ? o(m, "Duplicate") : a.applyBatch(m, "Duplicate", r(a, i.adapterMethods)), i.set(h));
|
|
29
|
+
run: (a) => {
|
|
30
|
+
let o = a.selection, s = a.scene, l = a.applyOps;
|
|
31
|
+
if (!o || !s) return;
|
|
32
|
+
let u = o.get();
|
|
33
|
+
if (u.length === 0) return;
|
|
34
|
+
let d = t(s, n(a.poseDescriptor)), f = a.poseComposition === void 0, { ops: p, copies: m } = i(s, u, (t, n, r) => r || f ? e(n.pose, c, c, d(t)) : n.pose, "Duplicate");
|
|
35
|
+
p.length !== 0 && (l ? l(p, "Duplicate") : s.applyBatch(p, "Duplicate", r(s, o.adapterMethods)), o.set(m));
|
|
76
36
|
}
|
|
77
37
|
},
|
|
78
|
-
enabled:
|
|
38
|
+
enabled: o
|
|
79
39
|
};
|
|
80
40
|
//#endregion
|
|
81
|
-
export {
|
|
41
|
+
export { l as duplicateAction };
|
|
82
42
|
|
|
83
43
|
//# sourceMappingURL=duplicate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicate.js","names":["DUPLICATE_OFFSET","
|
|
1
|
+
{"version":3,"file":"duplicate.js","names":["DUPLICATE_OFFSET","duplicateAction","createElement","DuplicateIcon","selection","deps","scene","applyOps","ids","descriptorOf","nodeDescriptors","poseDescriptorOf","offsetDescendants","newIds","copySelection","isRoot","translatePoseViaDescriptor","node","id","ops","defaultCommitAdapter","requiresSelection"],"sources":["../../../../src/interactions/actions/defaults/duplicate.ts"],"sourcesContent":["import type { Action } from '@weasel-js/routing';\nimport { createElement } from 'react';\nimport { DuplicateIcon } from './icons/editIcons';\nimport { defaultCommitAdapter } from '../defaultCommitAdapter';\nimport { copySelection } from './copySubtree';\nimport { requiresSelection } from './requiresSelection';\nimport { nodeDescriptors, poseDescriptorOf } from '../poseDescriptorDep';\nimport { translatePoseViaDescriptor } from '../resize/geometry';\n\n/** Same nudge `sceneToAdapter.getPasteOffset` gives a paste, so duplicate and\n * paste land in the same place rather than disagreeing by a few units. */\nconst DUPLICATE_OFFSET = 12;\n\n/**\n * @experimental\n * Static descriptor for the `duplicate` Action. Copies each selected node —\n * with its subtree, so duplicating a group produces a populated group — offset\n * by a small nudge, as one undoable batch, then selects the copies.\n */\nexport const duplicateAction: Action & { requires: string[] } = {\n id: 'duplicate',\n label: 'Duplicate',\n icon: createElement(DuplicateIcon),\n group: 'edit',\n defaultBinding: { kind: 'key', key: 'd', mods: { mod: true } },\n eligible: { capability: ['edits-page', 'creates-selection'] },\n // `selection` is read by the `enabled` gate as well as the invoker. An\n // undeclared read throws inside the dev-build deps Proxy before the gate can\n // answer, which is how this action spent a while doing nothing at all.\n requires: ['scene', 'selection', 'applyOps', 'poseComposition', 'poseDescriptor'],\n invoker: {\n timing: 'immediate',\n run: (deps) => {\n const selection = deps.selection;\n const scene = deps.scene;\n const applyOps = deps.applyOps;\n if (!selection || !scene) return;\n const ids = selection.get();\n if (ids.length === 0) return;\n\n const descriptorOf = nodeDescriptors(scene, poseDescriptorOf(deps.poseDescriptor));\n // With a `poseComposition` a child's pose is relative, so offsetting the\n // root carries the subtree and offsetting a child again would double it.\n const offsetDescendants = deps.poseComposition === undefined;\n const { ops, copies: newIds } = copySelection(\n scene,\n ids,\n (id, node, isRoot) => (isRoot || offsetDescendants\n ? translatePoseViaDescriptor(node.pose, DUPLICATE_OFFSET, DUPLICATE_OFFSET, descriptorOf(id))\n : node.pose),\n 'Duplicate',\n );\n\n if (ops.length === 0) return;\n if (applyOps) applyOps(ops, 'Duplicate');\n else scene.applyBatch(ops, 'Duplicate', defaultCommitAdapter(scene, selection.adapterMethods));\n selection.set(newIds);\n },\n },\n enabled: requiresSelection,\n};\n"],"mappings":";;;;;;;;AAWA,IAAMA,IAAmB,IAQZC,IAAmD;CAC9D,IAAI;CACJ,OAAO;CACP,MAAMC,EAAcC,CAAa;CACjC,OAAO;CACP,gBAAgB;EAAE,MAAM;EAAO,KAAK;EAAK,MAAM,EAAE,KAAK,GAAK;CAAE;CAC7D,UAAU,EAAE,YAAY,CAAC,cAAc,mBAAmB,EAAE;CAI5D,UAAU;EAAC;EAAS;EAAa;EAAY;EAAmB;CAAgB;CAChF,SAAS;EACP,QAAQ;EACR,MAAM,MAAS;GACb,IAAMC,IAAYC,EAAK,WACjBC,IAAQD,EAAK,OACbE,IAAWF,EAAK;GACtB,IAAI,CAACD,KAAa,CAACE,GAAO;GAC1B,IAAME,IAAMJ,EAAU,IAAI;GAC1B,IAAII,EAAI,WAAW,GAAG;GAEtB,IAAMC,IAAeC,EAAgBJ,GAAOK,EAAiBN,EAAK,cAAc,CAAC,GAG3EO,IAAoBP,EAAK,oBAAoB,KAAA,GAC7C,EAAE,QAAK,QAAQQ,MAAWC,EAC9BR,GACAE,IACC,GAAI,GAAM,MAAYO,KAAUH,IAC7BI,EAA2BC,EAAK,MAAMjB,GAAkBA,GAAkBS,EAAaS,CAAE,CAAC,IAC1FD,EAAK,MACT,WACF;GAEA,AAAIE,EAAI,WAAW,MACfZ,IAAUA,EAASY,GAAK,WAAW,IAClCb,EAAM,WAAWa,GAAK,aAAaC,EAAqBd,GAAOF,EAAU,cAAc,CAAC,GAC7FA,EAAU,IAAIS,CAAM;EACtB;CACF;CACA,SAASQ;AACX"}
|