@tomorrowevening/theatre-studio 1.0.5 → 1.0.6
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/index.js +105 -56
- package/package.json +1 -1
- package/dist/IDBStorage.js +0 -19
- package/dist/PaneManager.js +0 -112
- package/dist/Scrub.js +0 -134
- package/dist/Studio.js +0 -405
- package/dist/StudioBundle.js +0 -21
- package/dist/StudioStore/StudioStore.js +0 -163
- package/dist/StudioStore/createTransactionPrivateApi.js +0 -204
- package/dist/StudioStore/generateDiskStateRevision.js +0 -4
- package/dist/StudioStore/persistStateOfStudio.js +0 -61
- package/dist/TheatreStudio.js +0 -154
- package/dist/UI/UI.js +0 -65
- package/dist/UI/UINonSSRBits.js +0 -60
- package/dist/UIRoot/PanelsRoot.js +0 -19
- package/dist/UIRoot/PointerCapturing.js +0 -96
- package/dist/UIRoot/ProvideTheme.js +0 -9
- package/dist/UIRoot/UIRoot.js +0 -79
- package/dist/UIRoot/useKeyboardShortcuts.js +0 -158
- package/dist/checkForUpdates.js +0 -86
- package/dist/css.js +0 -116
- package/dist/getStudio.js +0 -10
- package/dist/notify.js +0 -328
- package/dist/panels/BasePanel/BasePanel.js +0 -74
- package/dist/panels/BasePanel/ExtensionPaneWrapper.js +0 -138
- package/dist/panels/BasePanel/PanelDragZone.js +0 -88
- package/dist/panels/BasePanel/PanelResizeHandle.js +0 -184
- package/dist/panels/BasePanel/PanelResizers.js +0 -14
- package/dist/panels/BasePanel/PanelWrapper.js +0 -34
- package/dist/panels/BasePanel/common.js +0 -52
- package/dist/panels/DetailPanel/DetailPanel.js +0 -146
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/DetailCompoundPropEditor.js +0 -169
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/DetailSimplePropEditor.js +0 -22
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/SingleRowPropEditor.js +0 -89
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/getDetailRowHighlightBackground.js +0 -7
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/rowIndentationFormulaCSS.js +0 -1
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail.js +0 -28
- package/dist/panels/DetailPanel/EmptyState.js +0 -36
- package/dist/panels/DetailPanel/ObjectDetails.js +0 -52
- package/dist/panels/DetailPanel/ProjectDetails/StateConflictRow.js +0 -86
- package/dist/panels/DetailPanel/ProjectDetails.js +0 -98
- package/dist/panels/OutlinePanel/BaseItem.js +0 -136
- package/dist/panels/OutlinePanel/ObjectsList/ObjectItem.js +0 -14
- package/dist/panels/OutlinePanel/ObjectsList/ObjectsList.js +0 -85
- package/dist/panels/OutlinePanel/OutlinePanel.js +0 -73
- package/dist/panels/OutlinePanel/ProjectsList/ProjectListItem.js +0 -38
- package/dist/panels/OutlinePanel/ProjectsList/ProjectsList.js +0 -22
- package/dist/panels/OutlinePanel/SheetsList/SheetInstanceItem.js +0 -36
- package/dist/panels/OutlinePanel/SheetsList/SheetItem.js +0 -23
- package/dist/panels/OutlinePanel/SheetsList/SheetsList.js +0 -15
- package/dist/panels/OutlinePanel/outlinePanelUtils.js +0 -23
- package/dist/panels/SequenceEditorPanel/DopeSheet/DopeSheet.js +0 -21
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/AnyCompositeRow.js +0 -74
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/Left.js +0 -25
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/PrimitivePropRow.js +0 -97
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/PropWithChildrenRow.js +0 -15
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/SheetObjectRow.js +0 -19
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/SheetRow.js +0 -20
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/usePropHighlightMouseEnter.js +0 -33
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeConnector.js +0 -187
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeDot.js +0 -158
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeEditor.js +0 -32
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeVisualDot.js +0 -61
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/iif.js +0 -3
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/useAggregateKeyframeEditorUtils.js +0 -73
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregatedKeyframeTrack.js +0 -407
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/BasicKeyframedTrack.js +0 -108
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/BasicKeyframeConnector.js +0 -185
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/CurveEditorPopover.js +0 -397
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/CurveSegmentEditor.js +0 -136
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/EasingOption.js +0 -52
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/SVGCurveSegment.js +0 -43
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/colors.js +0 -3
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/shared.js +0 -84
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/useFreezableMemo.js +0 -16
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/useUIOptionGrid.js +0 -82
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/DeterminePropEditorForSingleKeyframe.js +0 -93
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeDot.js +0 -254
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeEditor.js +0 -22
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/useSingleKeyframeInlineEditorPopover.js +0 -11
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/useTempTransactionEditingTools.js +0 -43
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/DopeSheetBackground.js +0 -24
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/DopeSheetSelectionView.js +0 -272
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/FocusRangeCurtains.js +0 -88
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/HorizontallyScrollableArea.js +0 -215
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/KeyframeSnapTarget.js +0 -55
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthEditorPopover.js +0 -69
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthIndicator.js +0 -217
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/PrimitivePropRow.js +0 -25
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/PropWithChildrenRow.js +0 -18
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/Right.js +0 -30
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/Row.js +0 -50
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/SheetObjectRow.js +0 -14
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/SheetRow.js +0 -14
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/collectAggregateKeyframes.js +0 -92
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/keyframeRowUI/ConnectorLine.js +0 -62
- package/dist/panels/SequenceEditorPanel/DopeSheet/selections.js +0 -149
- package/dist/panels/SequenceEditorPanel/DopeSheet/setCollapsedSheetObjectOrCompoundProp.js +0 -10
- package/dist/panels/SequenceEditorPanel/FrameGrid/FrameGrid.js +0 -92
- package/dist/panels/SequenceEditorPanel/FrameGrid/StampsGrid.js +0 -99
- package/dist/panels/SequenceEditorPanel/FrameGrid/createGrid.js +0 -49
- package/dist/panels/SequenceEditorPanel/FrameStampPositionProvider.js +0 -189
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/BasicKeyframedTrack.js +0 -91
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/Curve.js +0 -87
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/CurveHandle.js +0 -186
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/GraphEditorDotNonScalar.js +0 -162
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/GraphEditorDotScalar.js +0 -209
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/GraphEditorNonScalarDash.js +0 -23
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/KeyframeEditor.js +0 -30
- package/dist/panels/SequenceEditorPanel/GraphEditor/GraphEditor.js +0 -73
- package/dist/panels/SequenceEditorPanel/GraphEditor/PrimitivePropGraph.js +0 -20
- package/dist/panels/SequenceEditorPanel/GraphEditorToggle.js +0 -59
- package/dist/panels/SequenceEditorPanel/RightOverlay/DopeSnap.js +0 -36
- package/dist/panels/SequenceEditorPanel/RightOverlay/DopeSnapHitZoneUI.js +0 -57
- package/dist/panels/SequenceEditorPanel/RightOverlay/FocusRangeZone/FocusRangeStrip.js +0 -233
- package/dist/panels/SequenceEditorPanel/RightOverlay/FocusRangeZone/FocusRangeThumb.js +0 -217
- package/dist/panels/SequenceEditorPanel/RightOverlay/FocusRangeZone/FocusRangeZone.js +0 -181
- package/dist/panels/SequenceEditorPanel/RightOverlay/FrameStamp.js +0 -65
- package/dist/panels/SequenceEditorPanel/RightOverlay/HorizontalScrollbar.js +0 -235
- package/dist/panels/SequenceEditorPanel/RightOverlay/Markers/MarkerDot.js +0 -184
- package/dist/panels/SequenceEditorPanel/RightOverlay/Markers/MarkerEditorPopover.js +0 -65
- package/dist/panels/SequenceEditorPanel/RightOverlay/Markers/Markers.js +0 -13
- package/dist/panels/SequenceEditorPanel/RightOverlay/Playhead.js +0 -265
- package/dist/panels/SequenceEditorPanel/RightOverlay/PlayheadPositionPopover.js +0 -64
- package/dist/panels/SequenceEditorPanel/RightOverlay/RightOverlay.js +0 -35
- package/dist/panels/SequenceEditorPanel/RightOverlay/TopStrip.js +0 -31
- package/dist/panels/SequenceEditorPanel/SequenceEditorPanel.js +0 -179
- package/dist/panels/SequenceEditorPanel/VerticalScrollContainer.js +0 -42
- package/dist/panels/SequenceEditorPanel/layout/layout.js +0 -166
- package/dist/panels/SequenceEditorPanel/layout/tree.js +0 -139
- package/dist/panels/SequenceEditorPanel/whatPropIsHighlighted.js +0 -58
- package/dist/propEditors/DefaultValueIndicator.js +0 -64
- package/dist/propEditors/NextPrevKeyframeCursors.js +0 -135
- package/dist/propEditors/getNearbyKeyframesOfTrack.js +0 -46
- package/dist/propEditors/simpleEditors/BooleanPropEditor.js +0 -17
- package/dist/propEditors/simpleEditors/FilePropEditor.js +0 -118
- package/dist/propEditors/simpleEditors/ISimplePropEditorReactProps.js +0 -1
- package/dist/propEditors/simpleEditors/ImagePropEditor.js +0 -126
- package/dist/propEditors/simpleEditors/NumberPropEditor.js +0 -9
- package/dist/propEditors/simpleEditors/RgbaPropEditor.js +0 -73
- package/dist/propEditors/simpleEditors/StringLiteralPropEditor.js +0 -10
- package/dist/propEditors/simpleEditors/StringPropEditor.js +0 -6
- package/dist/propEditors/simpleEditors/simplePropEditorByPropType.js +0 -16
- package/dist/propEditors/useEditingToolsForCompoundProp.js +0 -228
- package/dist/propEditors/useEditingToolsForSimpleProp.js +0 -229
- package/dist/propEditors/utils/IEditingTools.js +0 -1
- package/dist/propEditors/utils/PropConfigForType.js +0 -1
- package/dist/propEditors/utils/getPropTypeByPointer.js +0 -48
- package/dist/propEditors/utils/propNameTextCSS.js +0 -7
- package/dist/selectors.js +0 -63
- package/dist/store/index.js +0 -184
- package/dist/store/stateEditors.js +0 -774
- package/dist/store/types/ahistoric.js +0 -1
- package/dist/store/types/ephemeral.js +0 -1
- package/dist/store/types/historic.js +0 -1
- package/dist/store/types/index.js +0 -3
- package/dist/toolbars/ExtensionToolbar/ExtensionToolbar.js +0 -51
- package/dist/toolbars/ExtensionToolbar/Toolset.js +0 -27
- package/dist/toolbars/ExtensionToolbar/tools/ExtensionFlyoutMenu.js +0 -51
- package/dist/toolbars/ExtensionToolbar/tools/IconButton.js +0 -16
- package/dist/toolbars/ExtensionToolbar/tools/Switch.js +0 -20
- package/dist/toolbars/GlobalToolbar.js +0 -142
- package/dist/toolbars/MoreMenu/MoreMenu.js +0 -133
- package/dist/toolbars/PinButton.js +0 -26
- package/dist/uiComponents/DetailPanelButton.js +0 -21
- package/dist/uiComponents/PointerEventsHandler.js +0 -80
- package/dist/uiComponents/Popover/ArrowContext.js +0 -3
- package/dist/uiComponents/Popover/BasicPopover.js +0 -35
- package/dist/uiComponents/Popover/BasicTooltip.js +0 -10
- package/dist/uiComponents/Popover/ErrorTooltip.js +0 -9
- package/dist/uiComponents/Popover/MinimalTooltip.js +0 -6
- package/dist/uiComponents/Popover/PopoverArrow.js +0 -38
- package/dist/uiComponents/Popover/TooltipContext.js +0 -46
- package/dist/uiComponents/Popover/TooltipWrapper.js +0 -103
- package/dist/uiComponents/Popover/usePopover.js +0 -132
- package/dist/uiComponents/Popover/useTooltip.js +0 -33
- package/dist/uiComponents/RoomToClick.js +0 -10
- package/dist/uiComponents/SVGIcon.js +0 -19
- package/dist/uiComponents/ShowMousePosition.js +0 -30
- package/dist/uiComponents/colorPicker/components/EditingProvider.js +0 -15
- package/dist/uiComponents/colorPicker/components/RgbaColorPicker.js +0 -31
- package/dist/uiComponents/colorPicker/components/common/Alpha.js +0 -54
- package/dist/uiComponents/colorPicker/components/common/AlphaColorPicker.js +0 -28
- package/dist/uiComponents/colorPicker/components/common/Hue.js +0 -41
- package/dist/uiComponents/colorPicker/components/common/Interactive.js +0 -142
- package/dist/uiComponents/colorPicker/components/common/Pointer.js +0 -39
- package/dist/uiComponents/colorPicker/components/common/Saturation.js +0 -44
- package/dist/uiComponents/colorPicker/hooks/useColorManipulation.js +0 -77
- package/dist/uiComponents/colorPicker/hooks/useEventCallback.js +0 -10
- package/dist/uiComponents/colorPicker/hooks/useIsomorphicLayoutEffect.js +0 -5
- package/dist/uiComponents/colorPicker/index.js +0 -1
- package/dist/uiComponents/colorPicker/types.js +0 -1
- package/dist/uiComponents/colorPicker/utils/clamp.js +0 -6
- package/dist/uiComponents/colorPicker/utils/compare.js +0 -25
- package/dist/uiComponents/colorPicker/utils/convert.js +0 -165
- package/dist/uiComponents/colorPicker/utils/round.js +0 -3
- package/dist/uiComponents/colorPicker/utils/validate.js +0 -10
- package/dist/uiComponents/createCursorLock.js +0 -2
- package/dist/uiComponents/form/BasicCheckbox.js +0 -5
- package/dist/uiComponents/form/BasicNumberInput.js +0 -261
- package/dist/uiComponents/form/BasicSelect.js +0 -58
- package/dist/uiComponents/form/BasicStringInput.js +0 -151
- package/dist/uiComponents/form/BasicSwitch.js +0 -60
- package/dist/uiComponents/icons/AddImage.js +0 -6
- package/dist/uiComponents/icons/ArrowClockwise.js +0 -6
- package/dist/uiComponents/icons/ArrowsOutCardinal.js +0 -6
- package/dist/uiComponents/icons/Bell.js +0 -6
- package/dist/uiComponents/icons/Camera.js +0 -7
- package/dist/uiComponents/icons/ChevronDown.js +0 -6
- package/dist/uiComponents/icons/ChevronLeft.js +0 -6
- package/dist/uiComponents/icons/ChevronRight.js +0 -6
- package/dist/uiComponents/icons/Cube.js +0 -6
- package/dist/uiComponents/icons/CubeFull.js +0 -6
- package/dist/uiComponents/icons/CubeHalf.js +0 -6
- package/dist/uiComponents/icons/CubeRendered.js +0 -7
- package/dist/uiComponents/icons/Details.js +0 -6
- package/dist/uiComponents/icons/DoubleChevronLeft.js +0 -6
- package/dist/uiComponents/icons/DoubleChevronRight.js +0 -6
- package/dist/uiComponents/icons/Ellipsis.js +0 -6
- package/dist/uiComponents/icons/EllipsisFill.js +0 -6
- package/dist/uiComponents/icons/GlobeSimple.js +0 -6
- package/dist/uiComponents/icons/Outline.js +0 -6
- package/dist/uiComponents/icons/Package.js +0 -6
- package/dist/uiComponents/icons/Resize.js +0 -7
- package/dist/uiComponents/icons/Trash.js +0 -6
- package/dist/uiComponents/icons/index.js +0 -20
- package/dist/uiComponents/isSafari.js +0 -2
- package/dist/uiComponents/onPointerOutside.js +0 -19
- package/dist/uiComponents/selects/BasicSelect.js +0 -24
- package/dist/uiComponents/simpleContextMenu/ContextMenu/BaseMenu.js +0 -40
- package/dist/uiComponents/simpleContextMenu/ContextMenu/ContextMenu.js +0 -87
- package/dist/uiComponents/simpleContextMenu/ContextMenu/Item.js +0 -37
- package/dist/uiComponents/simpleContextMenu/useContextMenu.js +0 -20
- package/dist/uiComponents/simpleContextMenu/useRequestContextMenu.js +0 -22
- package/dist/uiComponents/toolbar/ToolbarDropdownSelect.js +0 -7
- package/dist/uiComponents/toolbar/ToolbarIconButton.js +0 -74
- package/dist/uiComponents/toolbar/ToolbarSwitchSelect.js +0 -12
- package/dist/uiComponents/toolbar/ToolbarSwitchSelectContainer.js +0 -9
- package/dist/uiComponents/useBoundingClientRect.js +0 -13
- package/dist/uiComponents/useDebugRefreshEvery.js +0 -19
- package/dist/uiComponents/useDrag.js +0 -199
- package/dist/uiComponents/useHotspot.js +0 -30
- package/dist/uiComponents/useHover.js +0 -23
- package/dist/uiComponents/useHoverWithoutDescendants.js +0 -33
- package/dist/uiComponents/useKeyDown.js +0 -9
- package/dist/uiComponents/useKeyDownCallback.js +0 -28
- package/dist/uiComponents/useLockSet.js +0 -17
- package/dist/uiComponents/useLogger.js +0 -16
- package/dist/uiComponents/useOnClickOutside.js +0 -25
- package/dist/uiComponents/useOnKeyDown.js +0 -12
- package/dist/uiComponents/usePresence.js +0 -156
- package/dist/uiComponents/useValToAtom.js +0 -11
- package/dist/utils/absoluteDims.js +0 -7
- package/dist/utils/contextualWebComponents.js +0 -44
- package/dist/utils/copyToClipboard.js +0 -28
- package/dist/utils/derive-utils.js +0 -61
- package/dist/utils/devStringify.js +0 -20
- package/dist/utils/invariant.js +0 -79
- package/dist/utils/isMac.js +0 -2
- package/dist/utils/keyboardUtils.js +0 -23
- package/dist/utils/mousePositionD.js +0 -18
- package/dist/utils/redux/actionCreator.js +0 -15
- package/dist/utils/redux/actionCreator.test.js +0 -35
- package/dist/utils/redux/actionReducersBundle.js +0 -18
- package/dist/utils/redux/atomFromReduxStore.js +0 -11
- package/dist/utils/redux/configureStore.js +0 -18
- package/dist/utils/redux/pointerFriendlySelector.js +0 -8
- package/dist/utils/redux/withHistory/withBatchActions.js +0 -13
- package/dist/utils/redux/withHistory/withHistory.js +0 -157
- package/dist/utils/renderInPortalInContext.js +0 -38
- package/dist/utils/selectClosestHTMLAncestor.js +0 -13
- package/dist/utils/tightJsonStringify.js +0 -27
- package/dist/utils/tightJsonStringify.test.js +0 -25
- package/dist/utils/useRefAndState.js +0 -32
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import React, { useMemo, useRef } from 'react';
|
|
2
|
-
import styled from 'styled-components';
|
|
3
|
-
import getStudio from '@tomorrowevening/theatre-studio/getStudio';
|
|
4
|
-
import useContextMenu from '@tomorrowevening/theatre-studio/uiComponents/simpleContextMenu/useContextMenu';
|
|
5
|
-
import useDrag from '@tomorrowevening/theatre-studio/uiComponents/useDrag';
|
|
6
|
-
import useRefAndState from '@tomorrowevening/theatre-studio/utils/useRefAndState';
|
|
7
|
-
import { val } from '@tomorrowevening/theatre-dataverse';
|
|
8
|
-
import { useLockFrameStampPosition } from '@tomorrowevening/theatre-studio/panels/SequenceEditorPanel/FrameStampPositionProvider';
|
|
9
|
-
import { useCssCursorLock } from '@tomorrowevening/theatre-studio/uiComponents/PointerEventsHandler';
|
|
10
|
-
import DopeSnap from '@tomorrowevening/theatre-studio/panels/SequenceEditorPanel/RightOverlay/DopeSnap';
|
|
11
|
-
import { absoluteDims } from '@tomorrowevening/theatre-studio/utils/absoluteDims';
|
|
12
|
-
import { useLogger } from '@tomorrowevening/theatre-studio/uiComponents/useLogger';
|
|
13
|
-
import { copyableKeyframesFromSelection } from '@tomorrowevening/theatre-studio/panels/SequenceEditorPanel/DopeSheet/selections';
|
|
14
|
-
import { pointerEventsAutoInNormalMode } from '@tomorrowevening/theatre-studio/css';
|
|
15
|
-
import { collectKeyframeSnapPositions, snapToNone, snapToSome, } from '@tomorrowevening/theatre-studio/panels/SequenceEditorPanel/DopeSheet/Right/KeyframeSnapTarget';
|
|
16
|
-
import { useKeyframeInlineEditorPopover } from './useSingleKeyframeInlineEditorPopover';
|
|
17
|
-
import usePresence, { PresenceFlag, } from '@tomorrowevening/theatre-studio/uiComponents/usePresence';
|
|
18
|
-
export const DOT_SIZE_PX = 6;
|
|
19
|
-
const DOT_HOVER_SIZE_PX = DOT_SIZE_PX + 2;
|
|
20
|
-
const dotTheme = {
|
|
21
|
-
normalColor: '#40AAA4',
|
|
22
|
-
selectedColor: '#F2C95C',
|
|
23
|
-
inlineEditorOpenColor: '#FCF3DC',
|
|
24
|
-
selectedAndInlineEditorOpenColor: '#CBEBEA',
|
|
25
|
-
};
|
|
26
|
-
const selectBackgroundForDiamond = ({ isSelected, isInlineEditorPopoverOpen, }) => {
|
|
27
|
-
if (isSelected && isInlineEditorPopoverOpen) {
|
|
28
|
-
return dotTheme.inlineEditorOpenColor;
|
|
29
|
-
}
|
|
30
|
-
else if (isSelected) {
|
|
31
|
-
return dotTheme.selectedColor;
|
|
32
|
-
}
|
|
33
|
-
else if (isInlineEditorPopoverOpen) {
|
|
34
|
-
return dotTheme.selectedAndInlineEditorOpenColor;
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
return dotTheme.normalColor;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
/** The keyframe diamond ◆ */
|
|
41
|
-
const Diamond = styled.div `
|
|
42
|
-
position: absolute;
|
|
43
|
-
${absoluteDims(DOT_SIZE_PX)}
|
|
44
|
-
|
|
45
|
-
background: ${(props) => selectBackgroundForDiamond(props)};
|
|
46
|
-
transform: rotateZ(45deg);
|
|
47
|
-
|
|
48
|
-
${(props) => props.flag === PresenceFlag.Primary ? 'outline: 2px solid white;' : ''};
|
|
49
|
-
|
|
50
|
-
z-index: 1;
|
|
51
|
-
pointer-events: none;
|
|
52
|
-
`;
|
|
53
|
-
const Square = styled.div `
|
|
54
|
-
position: absolute;
|
|
55
|
-
${absoluteDims(DOT_SIZE_PX * 1.5)}
|
|
56
|
-
|
|
57
|
-
background: ${(props) => selectBackgroundForDiamond(props)};
|
|
58
|
-
|
|
59
|
-
${(props) => props.flag === PresenceFlag.Primary ? 'outline: 2px solid white;' : ''};
|
|
60
|
-
|
|
61
|
-
z-index: 1;
|
|
62
|
-
pointer-events: none;
|
|
63
|
-
`;
|
|
64
|
-
const HitZone = styled.div `
|
|
65
|
-
z-index: 1;
|
|
66
|
-
cursor: ew-resize;
|
|
67
|
-
|
|
68
|
-
position: absolute;
|
|
69
|
-
${absoluteDims(12)};
|
|
70
|
-
${pointerEventsAutoInNormalMode};
|
|
71
|
-
|
|
72
|
-
& + ${Diamond} {
|
|
73
|
-
${(props) => props.isInlineEditorPopoverOpen ? absoluteDims(DOT_HOVER_SIZE_PX) : ''}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
&:hover + ${Diamond} {
|
|
77
|
-
${absoluteDims(DOT_HOVER_SIZE_PX)}
|
|
78
|
-
}
|
|
79
|
-
`;
|
|
80
|
-
/** The ◆ you can grab onto in "keyframe editor" (aka "dope sheet" in other programs) */
|
|
81
|
-
const SingleKeyframeDot = (props) => {
|
|
82
|
-
const logger = useLogger('SingleKeyframeDot', props.keyframe.id);
|
|
83
|
-
const presence = usePresence(props.itemKey);
|
|
84
|
-
const [ref, node] = useRefAndState(null);
|
|
85
|
-
const [contextMenu] = useSingleKeyframeContextMenu(node, logger, props);
|
|
86
|
-
const { node: inlineEditorPopover, toggle: toggleEditor, isOpen: isInlineEditorPopoverOpen, } = useKeyframeInlineEditorPopover([
|
|
87
|
-
{
|
|
88
|
-
type: 'primitiveProp',
|
|
89
|
-
keyframe: props.keyframe,
|
|
90
|
-
pathToProp: props.leaf.pathToProp,
|
|
91
|
-
propConfig: props.leaf.propConf,
|
|
92
|
-
sheetObject: props.leaf.sheetObject,
|
|
93
|
-
trackId: props.leaf.trackId,
|
|
94
|
-
},
|
|
95
|
-
]);
|
|
96
|
-
const [isDragging] = useDragForSingleKeyframeDot(node, props, {
|
|
97
|
-
onClickFromDrag(dragStartEvent) {
|
|
98
|
-
toggleEditor(dragStartEvent, ref.current);
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
const showDiamond = !props.keyframe.type || props.keyframe.type === 'bezier';
|
|
102
|
-
return (React.createElement(React.Fragment, null,
|
|
103
|
-
React.createElement(HitZone, { ref: ref, isInlineEditorPopoverOpen: isInlineEditorPopoverOpen, ...presence.attrs }),
|
|
104
|
-
showDiamond ? (React.createElement(Diamond, { isSelected: !!props.selection, isInlineEditorPopoverOpen: isInlineEditorPopoverOpen, flag: presence.flag })) : (React.createElement(Square, { isSelected: !!props.selection, isInlineEditorPopoverOpen: isInlineEditorPopoverOpen, flag: presence.flag })),
|
|
105
|
-
inlineEditorPopover,
|
|
106
|
-
contextMenu));
|
|
107
|
-
};
|
|
108
|
-
export default SingleKeyframeDot;
|
|
109
|
-
function useSingleKeyframeContextMenu(target, logger, props) {
|
|
110
|
-
return useContextMenu(target, {
|
|
111
|
-
displayName: 'Keyframe',
|
|
112
|
-
menuItems: () => {
|
|
113
|
-
const copyableKeyframes = copyableKeyframesFromSelection(props.leaf.sheetObject.address.projectId, props.leaf.sheetObject.address.sheetId, props.selection);
|
|
114
|
-
return [
|
|
115
|
-
{
|
|
116
|
-
label: copyableKeyframes.length > 0 ? 'Copy (selection)' : 'Copy',
|
|
117
|
-
callback: () => {
|
|
118
|
-
if (copyableKeyframes.length > 0) {
|
|
119
|
-
getStudio().transaction((api) => {
|
|
120
|
-
api.stateEditors.studio.ahistoric.setClipboardKeyframes(copyableKeyframes);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
getStudio().transaction((api) => {
|
|
125
|
-
api.stateEditors.studio.ahistoric.setClipboardKeyframes([
|
|
126
|
-
{ keyframe: props.keyframe, pathToProp: props.leaf.pathToProp },
|
|
127
|
-
]);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
label: props.selection !== undefined ? 'Delete (selection)' : 'Delete',
|
|
134
|
-
callback: () => {
|
|
135
|
-
if (props.selection) {
|
|
136
|
-
props.selection.delete();
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
getStudio().transaction(({ stateEditors }) => {
|
|
140
|
-
stateEditors.coreByProject.historic.sheetsById.sequence.deleteKeyframes({
|
|
141
|
-
...props.leaf.sheetObject.address,
|
|
142
|
-
keyframeIds: [props.keyframe.id],
|
|
143
|
-
trackId: props.leaf.trackId,
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
];
|
|
150
|
-
},
|
|
151
|
-
onOpen() {
|
|
152
|
-
logger._debug('Show keyframe', props);
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
function useDragForSingleKeyframeDot(node, props, options) {
|
|
157
|
-
const propsRef = useRef(props);
|
|
158
|
-
propsRef.current = props;
|
|
159
|
-
const { onClickFromDrag } = options;
|
|
160
|
-
const useDragOpts = useMemo(() => {
|
|
161
|
-
return {
|
|
162
|
-
debugName: 'KeyframeDot/useDragKeyframe',
|
|
163
|
-
onDragStart(event) {
|
|
164
|
-
const props = propsRef.current;
|
|
165
|
-
const tracksByObject = val(getStudio().atomP.historic.coreByProject[props.leaf.sheetObject.address.projectId].sheetsById[props.leaf.sheetObject.address.sheetId].sequence
|
|
166
|
-
.tracksByObject);
|
|
167
|
-
const snapPositions = collectKeyframeSnapPositions(tracksByObject,
|
|
168
|
-
// Calculate all the valid snap positions in the sequence editor,
|
|
169
|
-
// excluding this keyframe, and any selection it is part of.
|
|
170
|
-
function shouldIncludeKeyfram(keyframe, { trackId, objectKey }) {
|
|
171
|
-
return (
|
|
172
|
-
// we exclude this keyframe from being a snap target
|
|
173
|
-
keyframe.id !== props.keyframe.id &&
|
|
174
|
-
!(
|
|
175
|
-
// if the current dragged keyframe is in the selection,
|
|
176
|
-
(props.selection &&
|
|
177
|
-
// then we exclude it and all other keyframes in the selection from being snap targets
|
|
178
|
-
props.selection.byObjectKey[objectKey]?.byTrackId[trackId]
|
|
179
|
-
?.byKeyframeId[keyframe.id])));
|
|
180
|
-
});
|
|
181
|
-
snapToSome(snapPositions);
|
|
182
|
-
if (props.selection) {
|
|
183
|
-
const { selection, leaf } = props;
|
|
184
|
-
const { sheetObject } = leaf;
|
|
185
|
-
const handlers = selection
|
|
186
|
-
.getDragHandlers({
|
|
187
|
-
...sheetObject.address,
|
|
188
|
-
domNode: node,
|
|
189
|
-
positionAtStartOfDrag: props.track.data.keyframes[props.index].position,
|
|
190
|
-
})
|
|
191
|
-
.onDragStart(event);
|
|
192
|
-
// this opens the regular inline keyframe editor on click.
|
|
193
|
-
// in the future, we may want to show an multi-editor, like in the
|
|
194
|
-
// single tween editor, so that selected keyframes' values can be changed
|
|
195
|
-
// together
|
|
196
|
-
return (handlers && {
|
|
197
|
-
...handlers,
|
|
198
|
-
onClick: onClickFromDrag,
|
|
199
|
-
onDragEnd: (...args) => {
|
|
200
|
-
handlers.onDragEnd?.(...args);
|
|
201
|
-
snapToNone();
|
|
202
|
-
},
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
const propsAtStartOfDrag = props;
|
|
206
|
-
const toUnitSpace = val(propsAtStartOfDrag.layoutP.scaledSpace.toUnitSpace);
|
|
207
|
-
let tempTransaction;
|
|
208
|
-
return {
|
|
209
|
-
onDrag(dx, dy, event) {
|
|
210
|
-
const original = propsAtStartOfDrag.track.data.keyframes[propsAtStartOfDrag.index];
|
|
211
|
-
const newPosition = Math.max(
|
|
212
|
-
// check if our event hoversover a [data-pos] element
|
|
213
|
-
DopeSnap.checkIfMouseEventSnapToPos(event, {
|
|
214
|
-
ignore: node,
|
|
215
|
-
}) ??
|
|
216
|
-
// if we don't find snapping target, check the distance dragged + original position
|
|
217
|
-
original.position + toUnitSpace(dx),
|
|
218
|
-
// sanitize to minimum of zero
|
|
219
|
-
0);
|
|
220
|
-
tempTransaction?.discard();
|
|
221
|
-
tempTransaction = undefined;
|
|
222
|
-
tempTransaction = getStudio().tempTransaction(({ stateEditors }) => {
|
|
223
|
-
stateEditors.coreByProject.historic.sheetsById.sequence.replaceKeyframes({
|
|
224
|
-
...propsAtStartOfDrag.leaf.sheetObject.address,
|
|
225
|
-
trackId: propsAtStartOfDrag.leaf.trackId,
|
|
226
|
-
keyframes: [{ ...original, position: newPosition }],
|
|
227
|
-
snappingFunction: val(propsAtStartOfDrag.layoutP.sheet).getSequence().closestGridPosition,
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
},
|
|
231
|
-
onDragEnd(dragHappened) {
|
|
232
|
-
if (dragHappened) {
|
|
233
|
-
tempTransaction?.commit();
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
tempTransaction?.discard();
|
|
237
|
-
}
|
|
238
|
-
snapToNone();
|
|
239
|
-
},
|
|
240
|
-
onClick(ev) {
|
|
241
|
-
onClickFromDrag(ev);
|
|
242
|
-
},
|
|
243
|
-
};
|
|
244
|
-
},
|
|
245
|
-
};
|
|
246
|
-
}, [onClickFromDrag]);
|
|
247
|
-
const [isDragging] = useDrag(node, useDragOpts);
|
|
248
|
-
// Lock frame stamp to the current position of the dragged keyframe instead of
|
|
249
|
-
// the mouse position, so that it appears centered above the keyframe even
|
|
250
|
-
// regardless of where in the hit zone of the keyframe the mouse is located.
|
|
251
|
-
useLockFrameStampPosition(isDragging, props.keyframe.position);
|
|
252
|
-
useCssCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize');
|
|
253
|
-
return [isDragging];
|
|
254
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { val } from '@tomorrowevening/theatre-dataverse';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import styled from 'styled-components';
|
|
4
|
-
import SingleKeyframeConnector from './BasicKeyframeConnector';
|
|
5
|
-
import SingleKeyframeDot from './SingleKeyframeDot';
|
|
6
|
-
const SingleKeyframeEditorContainer = styled.div `
|
|
7
|
-
position: absolute;
|
|
8
|
-
`;
|
|
9
|
-
const noConnector = React.createElement(React.Fragment, null);
|
|
10
|
-
const SingleKeyframeEditor = React.memo((props) => {
|
|
11
|
-
const { index, track: { data: trackData }, } = props;
|
|
12
|
-
const cur = trackData.keyframes[index];
|
|
13
|
-
const next = trackData.keyframes[index + 1];
|
|
14
|
-
const connected = cur.connectedRight && !!next;
|
|
15
|
-
return (React.createElement(SingleKeyframeEditorContainer, { style: {
|
|
16
|
-
top: `${props.leaf.nodeHeight / 2}px`,
|
|
17
|
-
left: `calc(${val(props.layoutP.scaledSpace.leftPadding)}px + calc(var(--unitSpaceToScaledSpaceMultiplier) * ${cur.position}px))`,
|
|
18
|
-
} },
|
|
19
|
-
React.createElement(SingleKeyframeDot, { ...props, itemKey: props.itemKey }),
|
|
20
|
-
connected ? React.createElement(SingleKeyframeConnector, { ...props }) : noConnector));
|
|
21
|
-
});
|
|
22
|
-
export default SingleKeyframeEditor;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import usePopover from '@tomorrowevening/theatre-studio/uiComponents/Popover/usePopover';
|
|
3
|
-
import BasicPopover from '@tomorrowevening/theatre-studio/uiComponents/Popover/BasicPopover';
|
|
4
|
-
import { DeterminePropEditorForKeyframeTree } from './DeterminePropEditorForSingleKeyframe';
|
|
5
|
-
/** The editor that pops up when directly clicking a Keyframe. */
|
|
6
|
-
export function useKeyframeInlineEditorPopover(props) {
|
|
7
|
-
return usePopover({ debugName: 'useKeyframeInlineEditorPopover' }, () => (React.createElement(BasicPopover, { showPopoverEdgeTriangle: true },
|
|
8
|
-
React.createElement("div", { style: { margin: '1px 2px 1px 10px' } }, !Array.isArray(props)
|
|
9
|
-
? undefined
|
|
10
|
-
: props.map((prop, i) => (React.createElement(DeterminePropEditorForKeyframeTree, { key: i, ...prop, autoFocusInput: i === 0, indent: 0 })))))));
|
|
11
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import getStudio from '@tomorrowevening/theatre-studio/getStudio';
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
|
-
/**
|
|
4
|
-
* This function takes a function `writeTx` that sets a value in the private Studio API and
|
|
5
|
-
* returns a memoized editingTools object which contains three functions:
|
|
6
|
-
* - `temporarilySetValue` - uses `writeTx` to set a value that can be discarded
|
|
7
|
-
* - `discardTemporaryValue` - if `temporarilySetValue` was called, discards the value it set
|
|
8
|
-
* - `permanentlySetValue` - uses `writeTx` to set a value
|
|
9
|
-
*
|
|
10
|
-
* @param writeTx - a function that uses a value to perform an action using the
|
|
11
|
-
* private Studio API.
|
|
12
|
-
* @returns an editingTools object that can be passed to `DeterminePropEditorForKeyframe` or
|
|
13
|
-
* `DetailDeterminePropEditor` and is used by the prop editors in `simplePropEditorByPropType`.
|
|
14
|
-
*/
|
|
15
|
-
export function useTempTransactionEditingTools(writeTx, obj) {
|
|
16
|
-
return useMemo(() => createTempTransactionEditingTools(writeTx, obj), []);
|
|
17
|
-
}
|
|
18
|
-
function createTempTransactionEditingTools(writeTx, obj) {
|
|
19
|
-
let currentTransaction = null;
|
|
20
|
-
const createTempTx = (value) => getStudio().tempTransaction((api) => writeTx(api, value));
|
|
21
|
-
function discardTemporaryValue() {
|
|
22
|
-
currentTransaction?.discard();
|
|
23
|
-
currentTransaction = null;
|
|
24
|
-
}
|
|
25
|
-
const editAssets = {
|
|
26
|
-
createAsset: obj.sheet.project.assetStorage.createAsset,
|
|
27
|
-
getAssetUrl: (asset) => asset.id
|
|
28
|
-
? obj.sheet.project.assetStorage.getAssetUrl(asset.id)
|
|
29
|
-
: undefined,
|
|
30
|
-
};
|
|
31
|
-
return {
|
|
32
|
-
temporarilySetValue(value) {
|
|
33
|
-
discardTemporaryValue();
|
|
34
|
-
currentTransaction = createTempTx(value);
|
|
35
|
-
},
|
|
36
|
-
discardTemporaryValue,
|
|
37
|
-
permanentlySetValue(value) {
|
|
38
|
-
discardTemporaryValue();
|
|
39
|
-
createTempTx(value).commit();
|
|
40
|
-
},
|
|
41
|
-
...editAssets,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { theme } from '@tomorrowevening/theatre-studio/css';
|
|
2
|
-
import { zIndexes } from '@tomorrowevening/theatre-studio/panels/SequenceEditorPanel/SequenceEditorPanel';
|
|
3
|
-
import { useVal } from '@tomorrowevening/theatre-react';
|
|
4
|
-
import { darken, transparentize } from 'polished';
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import styled from 'styled-components';
|
|
7
|
-
import FrameGrid from '@tomorrowevening/theatre-studio/panels/SequenceEditorPanel/FrameGrid/FrameGrid';
|
|
8
|
-
const Container = styled.div `
|
|
9
|
-
position: absolute;
|
|
10
|
-
top: 0;
|
|
11
|
-
right: 0;
|
|
12
|
-
bottom: 0;
|
|
13
|
-
z-index: ${() => zIndexes.rightBackground};
|
|
14
|
-
overflow: hidden;
|
|
15
|
-
background: ${transparentize(0.01, darken(1 * 0.03, theme.panel.bg))};
|
|
16
|
-
pointer-events: none;
|
|
17
|
-
`;
|
|
18
|
-
const DopeSheetBackground = ({ layoutP }) => {
|
|
19
|
-
const width = useVal(layoutP.rightDims.width);
|
|
20
|
-
const height = useVal(layoutP.panelDims.height);
|
|
21
|
-
return (React.createElement(Container, { style: { width: width + 'px' } },
|
|
22
|
-
React.createElement(FrameGrid, { width: width, height: height, layoutP: layoutP })));
|
|
23
|
-
};
|
|
24
|
-
export default DopeSheetBackground;
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
import getStudio from '@tomorrowevening/theatre-studio/getStudio';
|
|
2
|
-
import useDrag from '@tomorrowevening/theatre-studio/uiComponents/useDrag';
|
|
3
|
-
import useKeyDown from '@tomorrowevening/theatre-studio/uiComponents/useKeyDown';
|
|
4
|
-
import useValToAtom from '@tomorrowevening/theatre-studio/uiComponents/useValToAtom';
|
|
5
|
-
import mutableSetDeep from '@tomorrowevening/theatre-shared/utils/mutableSetDeep';
|
|
6
|
-
import useRefAndState from '@tomorrowevening/theatre-studio/utils/useRefAndState';
|
|
7
|
-
import { usePrism } from '@tomorrowevening/theatre-react';
|
|
8
|
-
import { val } from '@tomorrowevening/theatre-dataverse';
|
|
9
|
-
import React, { useMemo, useRef } from 'react';
|
|
10
|
-
import styled from 'styled-components';
|
|
11
|
-
import DopeSnap from '@tomorrowevening/theatre-studio/panels/SequenceEditorPanel/RightOverlay/DopeSnap';
|
|
12
|
-
import { collectAggregateKeyframesInPrism } from './collectAggregateKeyframes';
|
|
13
|
-
import { useLogger } from '@tomorrowevening/theatre-studio/uiComponents/useLogger';
|
|
14
|
-
const HITBOX_SIZE_PX = 5;
|
|
15
|
-
const Container = styled.div `
|
|
16
|
-
cursor: ${(props) => (props.isShiftDown ? 'cell' : 'default')};
|
|
17
|
-
`;
|
|
18
|
-
const DopeSheetSelectionView = ({ layoutP, children, height }) => {
|
|
19
|
-
const [containerRef, containerNode] = useRefAndState(null);
|
|
20
|
-
const isShiftDown = useKeyDown('Shift');
|
|
21
|
-
const selectionBounds = useCaptureSelection(layoutP, containerNode);
|
|
22
|
-
const selectionBoundsRef = useRef(selectionBounds);
|
|
23
|
-
selectionBoundsRef.current = selectionBounds;
|
|
24
|
-
return (React.createElement(Container, { style: { height: height + 'px' }, ref: containerRef, isShiftDown: isShiftDown, className: "selectionview" },
|
|
25
|
-
selectionBounds && (React.createElement(SelectionRectangle, { state: selectionBounds, layoutP: layoutP })),
|
|
26
|
-
children));
|
|
27
|
-
};
|
|
28
|
-
function useCaptureSelection(layoutP, containerNode) {
|
|
29
|
-
const [ref, state] = useRefAndState(null);
|
|
30
|
-
const logger = useLogger('useCaptureSelection');
|
|
31
|
-
useDrag(containerNode, useMemo(() => {
|
|
32
|
-
return {
|
|
33
|
-
debugName: 'DopeSheetSelectionView/useCaptureSelection',
|
|
34
|
-
dontBlockMouseDown: true,
|
|
35
|
-
lockCSSCursorTo: 'cell',
|
|
36
|
-
onDragStart(event) {
|
|
37
|
-
if (!event.shiftKey || event.target instanceof HTMLInputElement) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
const rect = containerNode.getBoundingClientRect();
|
|
41
|
-
// all the `val()` calls here are meant to be read cold
|
|
42
|
-
const posInScaledSpace = event.clientX -
|
|
43
|
-
rect.left -
|
|
44
|
-
// selection is happening in left padded space, convert it to normal space
|
|
45
|
-
val(layoutP.scaledSpace.leftPadding);
|
|
46
|
-
const posInUnitSpace = val(layoutP.scaledSpace.toUnitSpace)(posInScaledSpace);
|
|
47
|
-
ref.current = {
|
|
48
|
-
h: [posInUnitSpace, posInUnitSpace],
|
|
49
|
-
v: [event.clientY - rect.top, event.clientY - rect.top],
|
|
50
|
-
};
|
|
51
|
-
val(layoutP.selectionAtom).set({ current: undefined });
|
|
52
|
-
return {
|
|
53
|
-
onDrag(_dx, _dy, event) {
|
|
54
|
-
// const state = ref.current!
|
|
55
|
-
const rect = containerNode.getBoundingClientRect();
|
|
56
|
-
const posInScaledSpace = event.clientX -
|
|
57
|
-
rect.left -
|
|
58
|
-
// selection is happening in left padded space, convert it to normal space
|
|
59
|
-
val(layoutP.scaledSpace.leftPadding);
|
|
60
|
-
const posInUnitSpace = val(layoutP.scaledSpace.toUnitSpace)(posInScaledSpace);
|
|
61
|
-
ref.current = {
|
|
62
|
-
h: [ref.current.h[0], posInUnitSpace],
|
|
63
|
-
v: [ref.current.v[0], event.clientY - rect.top],
|
|
64
|
-
};
|
|
65
|
-
const selection = utils.boundsToSelection(logger, val(layoutP), ref.current);
|
|
66
|
-
val(layoutP.selectionAtom).set({ current: selection });
|
|
67
|
-
},
|
|
68
|
-
onDragEnd(_dragHappened) {
|
|
69
|
-
ref.current = null;
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
}, [layoutP, containerNode, ref]));
|
|
75
|
-
return state;
|
|
76
|
-
}
|
|
77
|
-
var utils;
|
|
78
|
-
(function (utils) {
|
|
79
|
-
const collectForAggregatedChildren = (logger, layout, leaf, bounds, selectionByObjectKey) => {
|
|
80
|
-
const aggregatedKeyframes = collectAggregateKeyframesInPrism(leaf);
|
|
81
|
-
if (leaf.top + leaf.nodeHeight / 2 + HITBOX_SIZE_PX > bounds.v[0] &&
|
|
82
|
-
leaf.top + leaf.nodeHeight / 2 - HITBOX_SIZE_PX < bounds.v[1]) {
|
|
83
|
-
for (const [position, keyframes] of aggregatedKeyframes.byPosition) {
|
|
84
|
-
const hitboxWidth = layout.scaledSpace.toUnitSpace(HITBOX_SIZE_PX);
|
|
85
|
-
const isHitboxOutsideSelection = position + hitboxWidth <= bounds.h[0] ||
|
|
86
|
-
position - hitboxWidth >= bounds.h[1];
|
|
87
|
-
if (isHitboxOutsideSelection)
|
|
88
|
-
continue;
|
|
89
|
-
for (const keyframeWithTrack of keyframes) {
|
|
90
|
-
mutableSetDeep(selectionByObjectKey, (selectionByObjectKeyP) =>
|
|
91
|
-
// convenience for accessing a deep path which might not actually exist
|
|
92
|
-
// through the use of pointer proxy (so we don't have to deal with undeifned )
|
|
93
|
-
selectionByObjectKeyP[keyframeWithTrack.track.sheetObject.address.objectKey].byTrackId[keyframeWithTrack.track.id].byKeyframeId[keyframeWithTrack.kf.id], true);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
collectChildren(logger, layout, leaf, bounds, selectionByObjectKey);
|
|
98
|
-
};
|
|
99
|
-
const collectorByLeafType = {
|
|
100
|
-
sheet(logger, layout, leaf, bounds, selectionByObjectKey) {
|
|
101
|
-
collectForAggregatedChildren(logger, layout, leaf, bounds, selectionByObjectKey);
|
|
102
|
-
},
|
|
103
|
-
propWithChildren(logger, layout, leaf, bounds, selectionByObjectKey) {
|
|
104
|
-
collectForAggregatedChildren(logger, layout, leaf, bounds, selectionByObjectKey);
|
|
105
|
-
},
|
|
106
|
-
sheetObject(logger, layout, leaf, bounds, selectionByObjectKey) {
|
|
107
|
-
collectForAggregatedChildren(logger, layout, leaf, bounds, selectionByObjectKey);
|
|
108
|
-
},
|
|
109
|
-
primitiveProp(logger, layout, leaf, bounds, selectionByObjectKey) {
|
|
110
|
-
const { sheetObject, trackId } = leaf;
|
|
111
|
-
const trackData = val(getStudio().atomP.historic.coreByProject[sheetObject.address.projectId]
|
|
112
|
-
.sheetsById[sheetObject.address.sheetId].sequence.tracksByObject[sheetObject.address.objectKey].trackData[trackId]);
|
|
113
|
-
if (bounds.v[0] >
|
|
114
|
-
leaf.top + leaf.heightIncludingChildren / 2 + HITBOX_SIZE_PX ||
|
|
115
|
-
leaf.top + leaf.heightIncludingChildren / 2 - HITBOX_SIZE_PX >
|
|
116
|
-
bounds.v[1]) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
for (const kf of trackData.keyframes) {
|
|
120
|
-
if (kf.position + layout.scaledSpace.toUnitSpace(HITBOX_SIZE_PX) <=
|
|
121
|
-
bounds.h[0])
|
|
122
|
-
continue;
|
|
123
|
-
if (kf.position - layout.scaledSpace.toUnitSpace(HITBOX_SIZE_PX) >=
|
|
124
|
-
bounds.h[1])
|
|
125
|
-
break;
|
|
126
|
-
mutableSetDeep(selectionByObjectKey, (selectionByObjectKeyP) =>
|
|
127
|
-
// convenience for accessing a deep path which might not actually exist
|
|
128
|
-
// through the use of pointer proxy (so we don't have to deal with undeifned )
|
|
129
|
-
selectionByObjectKeyP[sheetObject.address.objectKey].byTrackId[trackId].byKeyframeId[kf.id], true);
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
const collectChildren = (logger, layout, leaf, bounds, selectionByObjectKey) => {
|
|
134
|
-
if ('children' in leaf) {
|
|
135
|
-
for (const sub of leaf.children) {
|
|
136
|
-
collectFromAnyLeaf(logger, layout, sub, bounds, selectionByObjectKey);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
function collectFromAnyLeaf(logger, layout, leaf, bounds, selectionByObjectKey) {
|
|
141
|
-
// don't collect from non rendered
|
|
142
|
-
if (!leaf.shouldRender)
|
|
143
|
-
return;
|
|
144
|
-
if (bounds.v[0] > leaf.top + leaf.heightIncludingChildren ||
|
|
145
|
-
leaf.top > bounds.v[1]) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
const collector = collectorByLeafType[leaf.type];
|
|
149
|
-
if (collector) {
|
|
150
|
-
collector(logger, layout, leaf, bounds, selectionByObjectKey);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
collectChildren(logger, layout, leaf, bounds, selectionByObjectKey);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
function boundsToSelection(logger, layout, bounds) {
|
|
157
|
-
const selectionByObjectKey = {};
|
|
158
|
-
bounds = sortBounds(bounds);
|
|
159
|
-
const tree = layout.tree;
|
|
160
|
-
collectFromAnyLeaf(logger.utilFor.internal(), layout, tree, bounds, selectionByObjectKey);
|
|
161
|
-
const sheet = layout.tree.sheet;
|
|
162
|
-
return {
|
|
163
|
-
type: 'DopeSheetSelection',
|
|
164
|
-
byObjectKey: selectionByObjectKey,
|
|
165
|
-
getDragHandlers(origin) {
|
|
166
|
-
return {
|
|
167
|
-
debugName: 'DopeSheetSelectionView/boundsToSelection',
|
|
168
|
-
onDragStart() {
|
|
169
|
-
let tempTransaction;
|
|
170
|
-
const toUnitSpace = layout.scaledSpace.toUnitSpace;
|
|
171
|
-
return {
|
|
172
|
-
onDrag(dx, _, event) {
|
|
173
|
-
if (tempTransaction) {
|
|
174
|
-
tempTransaction.discard();
|
|
175
|
-
tempTransaction = undefined;
|
|
176
|
-
}
|
|
177
|
-
const snapPos = DopeSnap.checkIfMouseEventSnapToPos(event, {
|
|
178
|
-
ignore: origin.domNode,
|
|
179
|
-
});
|
|
180
|
-
const delta = snapPos != null
|
|
181
|
-
? snapPos - origin.positionAtStartOfDrag
|
|
182
|
-
: toUnitSpace(dx);
|
|
183
|
-
tempTransaction = getStudio().tempTransaction(({ stateEditors }) => {
|
|
184
|
-
const transformKeyframes = stateEditors.coreByProject.historic.sheetsById.sequence
|
|
185
|
-
.transformKeyframes;
|
|
186
|
-
for (const objectKey of Object.keys(selectionByObjectKey)) {
|
|
187
|
-
const { byTrackId } = selectionByObjectKey[objectKey];
|
|
188
|
-
for (const trackId of Object.keys(byTrackId)) {
|
|
189
|
-
const { byKeyframeId } = byTrackId[trackId];
|
|
190
|
-
transformKeyframes({
|
|
191
|
-
trackId,
|
|
192
|
-
keyframeIds: Object.keys(byKeyframeId),
|
|
193
|
-
translate: delta,
|
|
194
|
-
scale: 1,
|
|
195
|
-
origin: 0,
|
|
196
|
-
snappingFunction: sheet.getSequence().closestGridPosition,
|
|
197
|
-
objectKey,
|
|
198
|
-
projectId: origin.projectId,
|
|
199
|
-
sheetId: origin.sheetId,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
},
|
|
205
|
-
onDragEnd(dragHappened) {
|
|
206
|
-
if (dragHappened)
|
|
207
|
-
tempTransaction?.commit();
|
|
208
|
-
else
|
|
209
|
-
tempTransaction?.discard();
|
|
210
|
-
},
|
|
211
|
-
};
|
|
212
|
-
},
|
|
213
|
-
};
|
|
214
|
-
},
|
|
215
|
-
delete() {
|
|
216
|
-
getStudio().transaction(({ stateEditors }) => {
|
|
217
|
-
const deleteKeyframes = stateEditors.coreByProject.historic.sheetsById.sequence
|
|
218
|
-
.deleteKeyframes;
|
|
219
|
-
for (const objectKey of Object.keys(selectionByObjectKey)) {
|
|
220
|
-
const { byTrackId } = selectionByObjectKey[objectKey];
|
|
221
|
-
for (const trackId of Object.keys(byTrackId)) {
|
|
222
|
-
const { byKeyframeId } = byTrackId[trackId];
|
|
223
|
-
deleteKeyframes({
|
|
224
|
-
...sheet.address,
|
|
225
|
-
objectKey,
|
|
226
|
-
trackId,
|
|
227
|
-
keyframeIds: Object.keys(byKeyframeId),
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
},
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
utils.boundsToSelection = boundsToSelection;
|
|
236
|
-
})(utils || (utils = {}));
|
|
237
|
-
const SelectionRectangleDiv = styled.div `
|
|
238
|
-
position: absolute;
|
|
239
|
-
background: rgba(255, 255, 255, 0.1);
|
|
240
|
-
border: 1px dashed rgba(255, 255, 255, 0.4);
|
|
241
|
-
box-sizing: border-box;
|
|
242
|
-
`;
|
|
243
|
-
const sortBounds = (b) => {
|
|
244
|
-
return {
|
|
245
|
-
h: [...b.h].sort((a, b) => a - b),
|
|
246
|
-
v: [...b.v].sort((a, b) => a - b),
|
|
247
|
-
};
|
|
248
|
-
};
|
|
249
|
-
const SelectionRectangle = ({ state, layoutP }) => {
|
|
250
|
-
const atom = useValToAtom(state);
|
|
251
|
-
return usePrism(() => {
|
|
252
|
-
const state = val(atom.pointer);
|
|
253
|
-
const sorted = sortBounds(state);
|
|
254
|
-
const unitSpaceToScaledSpace = val(layoutP.scaledSpace.fromUnitSpace);
|
|
255
|
-
const leftPadding = val(layoutP.scaledSpace.leftPadding);
|
|
256
|
-
const positionsInScaledSpace = sorted.h
|
|
257
|
-
.map(unitSpaceToScaledSpace)
|
|
258
|
-
// bounds are in normal space, convert them left-padded space
|
|
259
|
-
.map((coord) => coord + leftPadding);
|
|
260
|
-
const top = sorted.v[0];
|
|
261
|
-
const height = sorted.v[1] - sorted.v[0];
|
|
262
|
-
const left = positionsInScaledSpace[0];
|
|
263
|
-
const width = positionsInScaledSpace[1] - positionsInScaledSpace[0];
|
|
264
|
-
return (React.createElement(SelectionRectangleDiv, { style: {
|
|
265
|
-
top: top + 'px',
|
|
266
|
-
height: height + 'px',
|
|
267
|
-
left: left + 'px',
|
|
268
|
-
width: width + 'px',
|
|
269
|
-
} }));
|
|
270
|
-
}, [layoutP, atom]);
|
|
271
|
-
};
|
|
272
|
-
export default DopeSheetSelectionView;
|