@remotion/studio 4.0.476 → 4.0.478

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.
Files changed (74) hide show
  1. package/dist/components/Canvas.js +40 -1
  2. package/dist/components/CanvasIfSizeIsAvailable.js +2 -6
  3. package/dist/components/ControlButton.d.ts +1 -0
  4. package/dist/components/ControlButton.js +7 -2
  5. package/dist/components/EditorGuides/Guide.js +151 -21
  6. package/dist/components/EditorRuler/Ruler.js +20 -24
  7. package/dist/components/EditorRuler/index.js +26 -13
  8. package/dist/components/InlineAction.js +1 -0
  9. package/dist/components/MenuToolbar.d.ts +1 -0
  10. package/dist/components/MenuToolbar.js +4 -1
  11. package/dist/components/OutlineToggle.js +1 -1
  12. package/dist/components/SelectedOutlineElement.d.ts +17 -0
  13. package/dist/components/SelectedOutlineElement.js +1009 -0
  14. package/dist/components/SelectedOutlineOverlay.d.ts +4 -210
  15. package/dist/components/SelectedOutlineOverlay.js +68 -1637
  16. package/dist/components/SelectedOutlineUvControls.js +1 -1
  17. package/dist/components/ShowGuidesProvider.js +4 -4
  18. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -1
  19. package/dist/components/Timeline/SubscribeToNodePaths.js +2 -1
  20. package/dist/components/Timeline/Timeline.js +3 -1
  21. package/dist/components/Timeline/TimelineClipboardKeybindings.js +9 -10
  22. package/dist/components/Timeline/TimelineDeleteKeybindings.js +15 -4
  23. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +7 -11
  24. package/dist/components/Timeline/TimelineList.js +1 -1
  25. package/dist/components/Timeline/TimelineSelection.d.ts +27 -13
  26. package/dist/components/Timeline/TimelineSelection.js +47 -28
  27. package/dist/components/Timeline/TimelineSequence.js +156 -3
  28. package/dist/components/Timeline/TimelineSequenceFrame.d.ts +1 -0
  29. package/dist/components/Timeline/TimelineSequenceFrame.js +17 -6
  30. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  31. package/dist/components/Timeline/TimelineSequenceItem.js +90 -130
  32. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  33. package/dist/components/Timeline/TimelineVideoInfo.js +93 -8
  34. package/dist/components/Timeline/delete-selected-timeline-item.js +4 -0
  35. package/dist/components/Timeline/duplicate-selected-timeline-item.d.ts +8 -2
  36. package/dist/components/Timeline/duplicate-selected-timeline-item.js +32 -3
  37. package/dist/components/Timeline/get-sequence-context-menu-items.d.ts +20 -0
  38. package/dist/components/Timeline/get-sequence-context-menu-items.js +160 -0
  39. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +2 -1
  40. package/dist/components/Timeline/sequence-props-subscription-store.js +11 -3
  41. package/dist/components/Timeline/should-clear-selection-on-pointer-down.d.ts +2 -0
  42. package/dist/components/Timeline/should-clear-selection-on-pointer-down.js +16 -2
  43. package/dist/components/Timeline/timeline-video-filmstrip-times.d.ts +17 -0
  44. package/dist/components/Timeline/timeline-video-filmstrip-times.js +22 -0
  45. package/dist/components/Timeline/update-selected-easing.d.ts +4 -6
  46. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +2 -1
  47. package/dist/components/Timeline/use-sequence-props-subscription.js +3 -1
  48. package/dist/components/Timeline/use-timeline-keyframe-drag.d.ts +37 -1
  49. package/dist/components/Timeline/use-timeline-keyframe-drag.js +282 -1
  50. package/dist/components/import-assets.d.ts +45 -8
  51. package/dist/components/import-assets.js +227 -12
  52. package/dist/components/selected-outline-drag.d.ts +140 -0
  53. package/dist/components/selected-outline-drag.js +475 -0
  54. package/dist/components/selected-outline-measurement.d.ts +67 -0
  55. package/dist/components/selected-outline-measurement.js +355 -0
  56. package/dist/components/selected-outline-types.d.ts +121 -0
  57. package/dist/components/selected-outline-types.js +15 -0
  58. package/dist/components/selected-outline-uv.d.ts +1 -0
  59. package/dist/components/selected-outline-uv.js +12 -0
  60. package/dist/error-overlay/remotion-overlay/Overlay.js +3 -0
  61. package/dist/esm/{chunk-0atarw3p.js → chunk-hrw9799x.js} +12812 -11386
  62. package/dist/esm/internals.mjs +12812 -11386
  63. package/dist/esm/previewEntry.mjs +21059 -19629
  64. package/dist/esm/renderEntry.mjs +1 -1
  65. package/dist/helpers/editor-guide-selection.d.ts +31 -0
  66. package/dist/helpers/editor-guide-selection.js +58 -0
  67. package/dist/helpers/editor-ruler.d.ts +3 -3
  68. package/dist/helpers/editor-ruler.js +16 -18
  69. package/dist/helpers/get-preview-file-type.js +1 -1
  70. package/dist/helpers/ruler-canvas-size.d.ts +5 -0
  71. package/dist/helpers/ruler-canvas-size.js +17 -0
  72. package/dist/state/editor-guides.d.ts +2 -2
  73. package/dist/state/editor-guides.js +2 -2
  74. package/package.json +11 -11
@@ -113,6 +113,27 @@ const getSfxDragUrl = (event) => {
113
113
  }
114
114
  return null;
115
115
  };
116
+ const getDropPosition = ({ clientX, clientY, contentDimensions, previewSize, size, }) => {
117
+ if (contentDimensions === null || contentDimensions === 'none') {
118
+ return null;
119
+ }
120
+ const scale = remotion_1.Internals.calculateScale({
121
+ canvasSize: size,
122
+ compositionHeight: contentDimensions.height,
123
+ compositionWidth: contentDimensions.width,
124
+ previewSize: previewSize.size,
125
+ });
126
+ const { centerX, centerY } = (0, get_effective_translation_1.getCenterPointWhileScrolling)({
127
+ size,
128
+ clientX,
129
+ clientY,
130
+ compositionWidth: contentDimensions.width,
131
+ compositionHeight: contentDimensions.height,
132
+ scale,
133
+ translation: previewSize.translation,
134
+ });
135
+ return { centerX, centerY };
136
+ };
116
137
  const isDragEventInsideCanvas = (event) => {
117
138
  const { current } = canvas_ref_1.canvasRef;
118
139
  if (!current) {
@@ -572,6 +593,13 @@ const Canvas = ({ canvasContent, size }) => {
572
593
  event.stopPropagation();
573
594
  setIsAddingAsset(true);
574
595
  try {
596
+ const dropPosition = getDropPosition({
597
+ clientX: event.clientX,
598
+ clientY: event.clientY,
599
+ contentDimensions,
600
+ previewSize,
601
+ size,
602
+ });
575
603
  if (isFileDragEvent(event)) {
576
604
  const files = Array.from((_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) !== null && _b !== void 0 ? _b : []);
577
605
  if (files.length === 0) {
@@ -581,6 +609,7 @@ const Canvas = ({ canvasContent, size }) => {
581
609
  files,
582
610
  compositionFile,
583
611
  compositionId: currentCompositionId,
612
+ dropPosition,
584
613
  });
585
614
  }
586
615
  else if (isAssetDragEvent(event)) {
@@ -592,6 +621,7 @@ const Canvas = ({ canvasContent, size }) => {
592
621
  assetPaths: [assetPath],
593
622
  compositionFile,
594
623
  compositionId: currentCompositionId,
624
+ dropPosition,
595
625
  });
596
626
  }
597
627
  else if (isSfxDragEvent(event)) {
@@ -612,6 +642,7 @@ const Canvas = ({ canvasContent, size }) => {
612
642
  component: componentDragData.component,
613
643
  compositionFile,
614
644
  compositionId: currentCompositionId,
645
+ dropPosition,
615
646
  });
616
647
  return;
617
648
  }
@@ -623,13 +654,21 @@ const Canvas = ({ canvasContent, size }) => {
623
654
  url,
624
655
  compositionFile,
625
656
  compositionId: currentCompositionId,
657
+ dropPosition,
626
658
  });
627
659
  }
628
660
  }
629
661
  finally {
630
662
  setIsAddingAsset(false);
631
663
  }
632
- }, [canDropAssets, compositionFile, currentCompositionId]);
664
+ }, [
665
+ canDropAssets,
666
+ compositionFile,
667
+ contentDimensions,
668
+ currentCompositionId,
669
+ previewSize,
670
+ size,
671
+ ]);
633
672
  (0, react_1.useEffect)(() => {
634
673
  if (!canDropAssets) {
635
674
  return;
@@ -4,7 +4,7 @@ exports.CanvasIfSizeIsAvailable = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
- const editor_rulers_1 = require("../state/editor-rulers");
7
+ const ruler_canvas_size_1 = require("../helpers/ruler-canvas-size");
8
8
  const CanvasOrLoading_1 = require("./CanvasOrLoading");
9
9
  const use_is_ruler_visible_1 = require("./EditorRuler/use-is-ruler-visible");
10
10
  const CanvasIfSizeIsAvailable = () => {
@@ -18,11 +18,7 @@ const CanvasIfSizeIsAvailable = () => {
18
18
  if (!size) {
19
19
  return null;
20
20
  }
21
- return {
22
- ...size,
23
- width: size.width - editor_rulers_1.RULER_WIDTH,
24
- height: size.height - editor_rulers_1.RULER_WIDTH,
25
- };
21
+ return (0, ruler_canvas_size_1.applyRulerInsetsToCanvasSize)({ rulersAreVisible, size });
26
22
  }, [context, rulersAreVisible]);
27
23
  if (!sizeWithRulersApplied) {
28
24
  return null;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  export declare const CONTROL_BUTTON_PADDING = 6;
3
+ export declare const CONTROL_BUTTON_SIZE = 30;
3
4
  export declare const ControlButton: (props: React.ClassAttributes<HTMLButtonElement> & React.ButtonHTMLAttributes<HTMLButtonElement> & {
4
5
  readonly title: string;
5
6
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,18 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ControlButton = exports.CONTROL_BUTTON_PADDING = void 0;
3
+ exports.ControlButton = exports.CONTROL_BUTTON_SIZE = exports.CONTROL_BUTTON_PADDING = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const z_index_1 = require("../state/z-index");
7
7
  exports.CONTROL_BUTTON_PADDING = 6;
8
+ exports.CONTROL_BUTTON_SIZE = 30;
8
9
  const ControlButton = (props) => {
9
10
  const style = (0, react_1.useMemo)(() => {
10
11
  return {
11
12
  opacity: props.disabled ? 0.5 : 1,
12
13
  display: 'inline-flex',
14
+ alignItems: 'center',
15
+ justifyContent: 'center',
16
+ width: exports.CONTROL_BUTTON_SIZE,
17
+ height: exports.CONTROL_BUTTON_SIZE,
13
18
  background: 'none',
14
19
  border: 'none',
15
- padding: exports.CONTROL_BUTTON_PADDING,
20
+ padding: 0,
16
21
  };
17
22
  }, [props.disabled]);
18
23
  const { tabIndex } = (0, z_index_1.useZIndex)();
@@ -3,14 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("react/jsx-runtime");
4
4
  const react_1 = require("react");
5
5
  const no_react_1 = require("remotion/no-react");
6
- const colors_1 = require("../../helpers/colors");
6
+ const editor_guide_selection_1 = require("../../helpers/editor-guide-selection");
7
7
  const editor_guides_1 = require("../../state/editor-guides");
8
8
  const editor_rulers_1 = require("../../state/editor-rulers");
9
9
  const ContextMenu_1 = require("../ContextMenu");
10
10
  const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
11
+ const should_clear_selection_on_pointer_down_1 = require("../Timeline/should-clear-selection-on-pointer-down");
12
+ const TimelineSelection_1 = require("../Timeline/TimelineSelection");
11
13
  const PADDING_FOR_EASY_DRAG = 4;
12
14
  const GuideComp = ({ guide, canvasDimensions, scale }) => {
13
- const { shouldCreateGuideRef, setGuidesList, setSelectedGuideId, selectedGuideId, setHoveredGuideId, hoveredGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
15
+ const { shouldCreateGuideRef, shouldDeleteGuideRef, setGuidesList, setDraggingGuideId, setHoveredGuideId, hoveredGuideId, draggingGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
16
+ const { clearSelection, onSelect, selected } = (0, TimelineSelection_1.useTimelineGuideSelection)(guide.id);
17
+ const pointerDownPositionRef = (0, react_1.useRef)(null);
18
+ const hasMovedGuideRef = (0, react_1.useRef)(false);
14
19
  const onPointerEnter = (0, react_1.useCallback)(() => {
15
20
  setHoveredGuideId(() => guide.id);
16
21
  }, [guide.id, setHoveredGuideId]);
@@ -43,20 +48,149 @@ const GuideComp = ({ guide, canvasDimensions, scale }) => {
43
48
  top: `${isVerticalGuide ? `-${editor_rulers_1.RULER_WIDTH}px` : '0px'}`,
44
49
  left: `${isVerticalGuide ? '0px' : `-${editor_rulers_1.RULER_WIDTH}px`}`,
45
50
  display: guide.show ? 'block' : 'none',
46
- backgroundColor: selectedGuideId === guide.id || hoveredGuideId === guide.id
47
- ? colors_1.SELECTED_GUIDE
48
- : colors_1.UNSELECTED_GUIDE,
51
+ backgroundColor: (0, editor_guide_selection_1.getEditorGuideColor)({
52
+ selected,
53
+ active: hoveredGuideId === guide.id || draggingGuideId === guide.id,
54
+ }),
49
55
  };
50
- }, [isVerticalGuide, guide.show, guide.id, selectedGuideId, hoveredGuideId]);
56
+ }, [
57
+ isVerticalGuide,
58
+ guide.show,
59
+ hoveredGuideId,
60
+ guide.id,
61
+ selected,
62
+ draggingGuideId,
63
+ ]);
64
+ const onPointerDown = (0, react_1.useCallback)((e) => {
65
+ if (e.button !== 0) {
66
+ return;
67
+ }
68
+ e.stopPropagation();
69
+ e.currentTarget.setPointerCapture(e.pointerId);
70
+ hasMovedGuideRef.current = false;
71
+ pointerDownPositionRef.current = {
72
+ guideId: guide.id,
73
+ clientX: e.clientX,
74
+ clientY: e.clientY,
75
+ };
76
+ shouldCreateGuideRef.current = false;
77
+ setDraggingGuideId(() => guide.id);
78
+ }, [guide.id, setDraggingGuideId, shouldCreateGuideRef]);
51
79
  const onMouseDown = (0, react_1.useCallback)((e) => {
80
+ if (e.button !== 0) {
81
+ return;
82
+ }
52
83
  e.preventDefault();
84
+ e.stopPropagation();
85
+ hasMovedGuideRef.current = false;
86
+ pointerDownPositionRef.current = {
87
+ guideId: guide.id,
88
+ clientX: e.clientX,
89
+ clientY: e.clientY,
90
+ };
91
+ shouldCreateGuideRef.current = false;
92
+ setDraggingGuideId(() => guide.id);
93
+ }, [guide.id, setDraggingGuideId, shouldCreateGuideRef]);
94
+ const updateHasMovedGuide = (0, react_1.useCallback)((clientX, clientY) => {
95
+ const pointerDownPosition = pointerDownPositionRef.current;
96
+ if (pointerDownPosition === null) {
97
+ return;
98
+ }
99
+ if (!(0, editor_guide_selection_1.isGuidePointerUpAClick)({
100
+ pointerDownPosition,
101
+ guideId: guide.id,
102
+ clientX,
103
+ clientY,
104
+ })) {
105
+ hasMovedGuideRef.current = true;
106
+ }
107
+ }, [guide.id]);
108
+ const onPointerMove = (0, react_1.useCallback)((e) => {
109
+ updateHasMovedGuide(e.clientX, e.clientY);
110
+ }, [updateHasMovedGuide]);
111
+ const onMouseMove = (0, react_1.useCallback)((e) => {
112
+ updateHasMovedGuide(e.clientX, e.clientY);
113
+ }, [updateHasMovedGuide]);
114
+ const finishGuideInteraction = (0, react_1.useCallback)(() => {
115
+ const shouldDeleteGuide = shouldDeleteGuideRef.current;
116
+ setGuidesList((prevState) => {
117
+ const newGuides = shouldDeleteGuide
118
+ ? prevState.filter((candidate) => candidate.id !== guide.id)
119
+ : prevState;
120
+ (0, editor_guides_1.persistGuidesList)(newGuides);
121
+ return newGuides;
122
+ });
123
+ if (shouldDeleteGuide && selected) {
124
+ clearSelection();
125
+ }
126
+ shouldDeleteGuideRef.current = false;
127
+ shouldCreateGuideRef.current = false;
128
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
129
+ setDraggingGuideId(() => null);
130
+ }, [
131
+ clearSelection,
132
+ guide.id,
133
+ selected,
134
+ setDraggingGuideId,
135
+ setGuidesList,
136
+ shouldCreateGuideRef,
137
+ shouldDeleteGuideRef,
138
+ ]);
139
+ const onPointerUp = (0, react_1.useCallback)((e) => {
140
+ if (e.currentTarget.hasPointerCapture(e.pointerId)) {
141
+ e.currentTarget.releasePointerCapture(e.pointerId);
142
+ }
143
+ const pointerDownPosition = pointerDownPositionRef.current;
144
+ pointerDownPositionRef.current = null;
145
+ const shouldDeleteGuide = shouldDeleteGuideRef.current;
146
+ finishGuideInteraction();
147
+ if (shouldDeleteGuide) {
148
+ return;
149
+ }
150
+ if ((0, editor_guide_selection_1.isGuidePointerUpAClick)({
151
+ pointerDownPosition,
152
+ guideId: guide.id,
153
+ clientX: e.clientX,
154
+ clientY: e.clientY,
155
+ })) {
156
+ onSelect();
157
+ }
158
+ }, [finishGuideInteraction, guide.id, onSelect, shouldDeleteGuideRef]);
159
+ const onMouseUp = (0, react_1.useCallback)((e) => {
160
+ const pointerDownPosition = pointerDownPositionRef.current;
161
+ pointerDownPositionRef.current = null;
162
+ const shouldDeleteGuide = shouldDeleteGuideRef.current;
163
+ finishGuideInteraction();
164
+ if (shouldDeleteGuide) {
165
+ return;
166
+ }
167
+ if ((0, editor_guide_selection_1.isGuidePointerUpAClick)({
168
+ pointerDownPosition,
169
+ guideId: guide.id,
170
+ clientX: e.clientX,
171
+ clientY: e.clientY,
172
+ })) {
173
+ onSelect();
174
+ }
175
+ }, [finishGuideInteraction, guide.id, onSelect, shouldDeleteGuideRef]);
176
+ const onClick = (0, react_1.useCallback)((e) => {
53
177
  if (e.button !== 0) {
54
178
  return;
55
179
  }
56
- shouldCreateGuideRef.current = true;
57
- (0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
58
- setSelectedGuideId(() => guide.id);
59
- }, [shouldCreateGuideRef, setSelectedGuideId, guide.id]);
180
+ e.preventDefault();
181
+ e.stopPropagation();
182
+ }, []);
183
+ const onPointerCancel = (0, react_1.useCallback)(() => {
184
+ pointerDownPositionRef.current = null;
185
+ finishGuideInteraction();
186
+ }, [finishGuideInteraction]);
187
+ const isActive = selected || hoveredGuideId === guide.id;
188
+ const activeClassName = isActive ? '__remotion_editor_guide_selected' : null;
189
+ const guideClassName = (0, react_1.useMemo)(() => {
190
+ return ['__remotion_editor_guide_content', activeClassName]
191
+ .filter(no_react_1.NoReactInternals.truthy)
192
+ .join(' ');
193
+ }, [activeClassName]);
60
194
  const values = (0, react_1.useMemo)(() => {
61
195
  return [
62
196
  {
@@ -66,12 +200,15 @@ const GuideComp = ({ guide, canvasDimensions, scale }) => {
66
200
  leftItem: null,
67
201
  onClick: () => {
68
202
  setGuidesList((prevState) => {
69
- const newGuides = prevState.filter((selected) => {
70
- return selected.id !== guide.id;
203
+ const newGuides = prevState.filter((candidate) => {
204
+ return candidate.id !== guide.id;
71
205
  });
72
206
  (0, editor_guides_1.persistGuidesList)(newGuides);
73
207
  return newGuides;
74
208
  });
209
+ if (selected) {
210
+ clearSelection();
211
+ }
75
212
  },
76
213
  quickSwitcherLabel: null,
77
214
  subMenu: null,
@@ -79,14 +216,7 @@ const GuideComp = ({ guide, canvasDimensions, scale }) => {
79
216
  value: 'remove',
80
217
  },
81
218
  ];
82
- }, [guide.id, setGuidesList]);
83
- return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: values, onOpen: null, children: jsx_runtime_1.jsx("div", { style: guideStyle, onMouseDown: onMouseDown, className: "__remotion_editor_guide", onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsx("div", { style: guideContentStyle, className: [
84
- '__remotion_editor_guide_content',
85
- selectedGuideId === guide.id || hoveredGuideId === guide.id
86
- ? '__remotion_editor_guide_selected'
87
- : null,
88
- ]
89
- .filter(no_react_1.NoReactInternals.truthy)
90
- .join(' ') }) }) }));
219
+ }, [clearSelection, guide.id, selected, setGuidesList]);
220
+ return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: values, onOpen: null, children: jsx_runtime_1.jsx("div", { style: guideStyle, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onPointerCancel: onPointerCancel, onMouseDown: onMouseDown, onMouseMove: onMouseMove, onMouseUp: onMouseUp, onClick: onClick, className: "__remotion_editor_guide", [should_clear_selection_on_pointer_down_1.PREVENT_CLEAR_SELECTION_ON_POINTER_DOWN_ATTR]: 'true', onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: jsx_runtime_1.jsx("div", { style: guideContentStyle, className: guideClassName }) }) }));
91
221
  };
92
222
  exports.default = (0, react_1.memo)(GuideComp);
@@ -4,26 +4,32 @@ const jsx_runtime_1 = require("react/jsx-runtime");
4
4
  const react_1 = require("react");
5
5
  const remotion_1 = require("remotion");
6
6
  const colors_1 = require("../../helpers/colors");
7
+ const editor_guide_selection_1 = require("../../helpers/editor-guide-selection");
7
8
  const editor_ruler_1 = require("../../helpers/editor-ruler");
8
9
  const editor_guides_1 = require("../../state/editor-guides");
9
10
  const editor_rulers_1 = require("../../state/editor-rulers");
10
11
  const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
12
+ const should_clear_selection_on_pointer_down_1 = require("../Timeline/should-clear-selection-on-pointer-down");
13
+ const TimelineSelection_1 = require("../Timeline/TimelineSelection");
11
14
  const makeGuideId = () => {
12
15
  return Math.random().toString(36).substring(7);
13
16
  };
14
17
  const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, orientation, }) => {
15
18
  const rulerCanvasRef = (0, react_1.useRef)(null);
16
19
  const isVerticalRuler = orientation === 'vertical';
17
- const { shouldCreateGuideRef, setGuidesList, selectedGuideId, hoveredGuideId, setSelectedGuideId, guidesList, setEditorShowGuides, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
20
+ const { shouldCreateGuideRef, setGuidesList, draggingGuideId, hoveredGuideId, setDraggingGuideId, guidesList, setEditorShowGuides, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
21
+ const { selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
18
22
  const unsafeVideoConfig = remotion_1.Internals.useUnsafeVideoConfig();
19
23
  if (!unsafeVideoConfig) {
20
24
  throw new Error('Video config not set');
21
25
  }
22
- const [cursor, setCursor] = (0, react_1.useState)(isVerticalRuler ? 'ew-resize' : 'ns-resize');
23
- const selectedOrHoveredGuide = (0, react_1.useMemo)(() => {
24
- var _a, _b;
25
- return ((_b = (_a = guidesList.find((guide) => guide.id === selectedGuideId)) !== null && _a !== void 0 ? _a : guidesList.find((guide) => guide.id === hoveredGuideId)) !== null && _b !== void 0 ? _b : null);
26
- }, [guidesList, hoveredGuideId, selectedGuideId]);
26
+ const cursor = isVerticalRuler ? 'ew-resize' : 'ns-resize';
27
+ const guideHighlight = (0, react_1.useMemo)(() => (0, editor_guide_selection_1.getRulerGuideHighlight)({
28
+ guidesList,
29
+ selectedItems,
30
+ hoveredGuideId,
31
+ draggingGuideId,
32
+ }), [draggingGuideId, guidesList, hoveredGuideId, selectedItems]);
27
33
  const rulerWidth = isVerticalRuler ? editor_rulers_1.RULER_WIDTH : size.width - editor_rulers_1.RULER_WIDTH;
28
34
  const rulerHeight = isVerticalRuler ? size.height - editor_rulers_1.RULER_WIDTH : editor_rulers_1.RULER_WIDTH;
29
35
  (0, react_1.useEffect)(() => {
@@ -35,7 +41,7 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
35
41
  markingGaps,
36
42
  orientation,
37
43
  rulerCanvasRef,
38
- selectedGuide: selectedOrHoveredGuide,
44
+ guideHighlight,
39
45
  canvasHeight: rulerHeight * window.devicePixelRatio,
40
46
  canvasWidth: rulerWidth * window.devicePixelRatio,
41
47
  });
@@ -46,7 +52,7 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
46
52
  originOffset,
47
53
  markingGaps,
48
54
  orientation,
49
- selectedOrHoveredGuide,
55
+ guideHighlight,
50
56
  size,
51
57
  rulerHeight,
52
58
  rulerWidth,
@@ -62,7 +68,7 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
62
68
  borderRight: isVerticalRuler ? '1px solid ' + colors_1.RULER_COLOR : undefined,
63
69
  cursor,
64
70
  }), [rulerWidth, rulerHeight, cursor, isVerticalRuler]);
65
- const onMouseDown = (0, react_1.useCallback)((e) => {
71
+ const onPointerDown = (0, react_1.useCallback)((e) => {
66
72
  if (e.button !== 0) {
67
73
  return;
68
74
  }
@@ -70,10 +76,10 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
70
76
  // Prevent deselection of currently selected items
71
77
  e.stopPropagation();
72
78
  shouldCreateGuideRef.current = true;
73
- (0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
79
+ (0, ForceSpecificCursor_1.forceSpecificCursor)(cursor);
74
80
  const guideId = makeGuideId();
75
81
  setEditorShowGuides(() => true);
76
- setSelectedGuideId(() => guideId);
82
+ setDraggingGuideId(() => guideId);
77
83
  setGuidesList((prevState) => {
78
84
  return [
79
85
  ...prevState,
@@ -89,23 +95,13 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
89
95
  }, [
90
96
  shouldCreateGuideRef,
91
97
  setEditorShowGuides,
92
- setSelectedGuideId,
98
+ setDraggingGuideId,
93
99
  setGuidesList,
94
100
  orientation,
95
101
  originOffset,
96
102
  unsafeVideoConfig.id,
103
+ cursor,
97
104
  ]);
98
- const changeCursor = (0, react_1.useCallback)((e) => {
99
- e.preventDefault();
100
- if (selectedGuideId !== null) {
101
- setCursor('no-drop');
102
- }
103
- }, [setCursor, selectedGuideId]);
104
- (0, react_1.useEffect)(() => {
105
- if (selectedGuideId === null) {
106
- setCursor(isVerticalRuler ? 'ew-resize' : 'ns-resize');
107
- }
108
- }, [selectedGuideId, isVerticalRuler]);
109
- return (jsx_runtime_1.jsx("canvas", { ref: rulerCanvasRef, width: rulerWidth * window.devicePixelRatio, height: rulerHeight * window.devicePixelRatio, style: rulerStyle, onPointerDown: onMouseDown, onPointerEnter: changeCursor, onPointerLeave: changeCursor }));
105
+ return (jsx_runtime_1.jsx("canvas", { ref: rulerCanvasRef, width: rulerWidth * window.devicePixelRatio, height: rulerHeight * window.devicePixelRatio, style: rulerStyle, [should_clear_selection_on_pointer_down_1.PREVENT_CLEAR_SELECTION_ON_POINTER_DOWN_ATTR]: 'true', onPointerDown: onPointerDown }));
110
106
  };
111
107
  exports.default = Ruler;
@@ -12,6 +12,7 @@ const use_studio_canvas_dimensions_1 = require("../../helpers/use-studio-canvas-
12
12
  const editor_guides_1 = require("../../state/editor-guides");
13
13
  const editor_rulers_1 = require("../../state/editor-rulers");
14
14
  const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
15
+ const TimelineSelection_1 = require("../Timeline/TimelineSelection");
15
16
  const Ruler_1 = __importDefault(require("./Ruler"));
16
17
  const originBlockStyles = {
17
18
  position: 'absolute',
@@ -29,7 +30,8 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
29
30
  contentDimensions,
30
31
  assetMetadata,
31
32
  });
32
- const { shouldCreateGuideRef, shouldDeleteGuideRef, setGuidesList, selectedGuideId, setSelectedGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
33
+ const { shouldCreateGuideRef, shouldDeleteGuideRef, setGuidesList, draggingGuideId, setDraggingGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
34
+ const { clearSelection, selectedItems } = (0, TimelineSelection_1.useTimelineSelection)();
33
35
  const rulerMarkingGaps = (0, react_1.useMemo)(() => {
34
36
  const minimumGap = editor_rulers_1.MINIMUM_RULER_MARKING_GAP_PX;
35
37
  const predefinedGap = editor_rulers_1.PREDEFINED_RULER_SCALE_GAPS.find((gap) => gap * scale > minimumGap);
@@ -71,12 +73,13 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
71
73
  if (!shouldDeleteGuideRef.current) {
72
74
  shouldDeleteGuideRef.current = true;
73
75
  }
74
- (0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
75
76
  setGuidesList((prevState) => {
76
77
  const newGuides = prevState.map((guide) => {
77
- if (guide.id !== selectedGuideId) {
78
+ if (guide.id !== draggingGuideId) {
78
79
  return guide;
79
80
  }
81
+ const desiredCursor = guide.orientation === 'vertical' ? 'ew-resize' : 'ns-resize';
82
+ (0, ForceSpecificCursor_1.forceSpecificCursor)(desiredCursor);
80
83
  return {
81
84
  ...guide,
82
85
  show: false,
@@ -93,7 +96,7 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
93
96
  setGuidesList((prevState) => {
94
97
  // Intentionally no persist, only persist on mouse up
95
98
  return prevState.map((guide) => {
96
- if (guide.id !== selectedGuideId) {
99
+ if (guide.id !== draggingGuideId) {
97
100
  return guide;
98
101
  }
99
102
  const position = guide.orientation === 'vertical'
@@ -116,49 +119,59 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
116
119
  containerRef,
117
120
  shouldDeleteGuideRef,
118
121
  setGuidesList,
119
- selectedGuideId,
122
+ draggingGuideId,
120
123
  scale,
121
124
  canvasPosition.left,
122
125
  canvasPosition.top,
123
126
  ]);
124
127
  const onMouseUp = (0, react_1.useCallback)(() => {
128
+ const shouldDeleteGuide = shouldDeleteGuideRef.current;
125
129
  setGuidesList((prevState) => {
126
130
  const newGuides = prevState.filter((selected) => {
127
- if (!shouldDeleteGuideRef.current) {
131
+ if (!shouldDeleteGuide) {
128
132
  return true;
129
133
  }
130
- return selected.id !== selectedGuideId;
134
+ return selected.id !== draggingGuideId;
131
135
  });
132
136
  (0, editor_guides_1.persistGuidesList)(newGuides);
133
137
  return newGuides;
134
138
  });
139
+ const deletedGuideWasSelected = selectedItems.some((item) => item.type === 'guide' && item.guideId === draggingGuideId);
140
+ if (shouldDeleteGuide && deletedGuideWasSelected) {
141
+ clearSelection();
142
+ }
135
143
  shouldDeleteGuideRef.current = false;
136
144
  (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
137
145
  shouldCreateGuideRef.current = false;
138
- setSelectedGuideId(() => null);
146
+ setDraggingGuideId(() => null);
139
147
  document.removeEventListener('pointerup', onMouseUp);
148
+ document.removeEventListener('pointercancel', onMouseUp);
140
149
  document.removeEventListener('pointermove', onMouseMove);
141
150
  }, [
142
- selectedGuideId,
151
+ clearSelection,
152
+ draggingGuideId,
143
153
  shouldCreateGuideRef,
144
154
  shouldDeleteGuideRef,
145
- setSelectedGuideId,
155
+ setDraggingGuideId,
146
156
  setGuidesList,
147
157
  onMouseMove,
158
+ selectedItems,
148
159
  ]);
149
- (0, react_1.useEffect)(() => {
150
- if (selectedGuideId !== null) {
160
+ (0, react_1.useLayoutEffect)(() => {
161
+ if (draggingGuideId !== null) {
151
162
  document.addEventListener('pointermove', onMouseMove);
152
163
  document.addEventListener('pointerup', onMouseUp);
164
+ document.addEventListener('pointercancel', onMouseUp);
153
165
  }
154
166
  return () => {
155
167
  document.removeEventListener('pointermove', onMouseMove);
156
168
  document.removeEventListener('pointerup', onMouseUp);
169
+ document.removeEventListener('pointercancel', onMouseUp);
157
170
  if (requestAnimationFrameRef.current) {
158
171
  cancelAnimationFrame(requestAnimationFrameRef.current);
159
172
  }
160
173
  };
161
- }, [selectedGuideId, onMouseMove, onMouseUp]);
174
+ }, [draggingGuideId, onMouseMove, onMouseUp]);
162
175
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
163
176
  jsx_runtime_1.jsx("div", { style: originBlockStyles }), jsx_runtime_1.jsx(Ruler_1.default, { orientation: "horizontal", scale: scale, points: horizontalRulerPoints, startMarking: horizontalRulerStartMarking, markingGaps: rulerMarkingGaps, originOffset: canvasPosition.left, size: canvasSize }), jsx_runtime_1.jsx(Ruler_1.default, { orientation: "vertical", scale: scale, points: verticalRulerPoints, startMarking: verticalRulerStartMarking, markingGaps: rulerMarkingGaps, originOffset: canvasPosition.top, size: canvasSize })
164
177
  ] }));
@@ -22,6 +22,7 @@ const InlineAction = ({ renderAction, onClick, disabled, title, }) => {
22
22
  : (0, colors_1.getBackgroundFromHoverState)({ hovered, selected: false }),
23
23
  height: 24,
24
24
  width: 24,
25
+ padding: 0,
25
26
  display: 'inline-flex',
26
27
  justifyContent: 'center',
27
28
  alignItems: 'center',
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ export declare const MENU_TOOLBAR_HEIGHT = 30;
2
3
  export declare const MenuToolbar: React.FC<{
3
4
  readonly readOnlyStudio: boolean;
4
5
  }>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MenuToolbar = void 0;
3
+ exports.MenuToolbar = exports.MENU_TOOLBAR_HEIGHT = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const colors_1 = require("../helpers/colors");
@@ -12,13 +12,16 @@ const MenuBuildIndicator_1 = require("./MenuBuildIndicator");
12
12
  const SidebarCollapserControls_1 = require("./SidebarCollapserControls");
13
13
  const UndoRedoButtons_1 = require("./UndoRedoButtons");
14
14
  const UpdateCheck_1 = require("./UpdateCheck");
15
+ exports.MENU_TOOLBAR_HEIGHT = 30;
15
16
  const row = {
16
17
  alignItems: 'center',
17
18
  flexDirection: 'row',
18
19
  display: 'flex',
19
20
  color: 'white',
20
21
  borderBottom: '1px solid black',
22
+ boxSizing: 'border-box',
21
23
  fontSize: 13,
24
+ height: exports.MENU_TOOLBAR_HEIGHT,
22
25
  paddingLeft: 6,
23
26
  paddingRight: 10,
24
27
  backgroundColor: colors_1.BACKGROUND,
@@ -15,6 +15,6 @@ const OutlineToggle = () => {
15
15
  const accessibilityLabel = editorShowOutlines
16
16
  ? 'Hide outlines'
17
17
  : 'Show outlines';
18
- return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, onClick: onClick, children: jsx_runtime_1.jsx("svg", { style: { width: 16, height: 16 }, viewBox: "0 0 512 512", fill: color, "aria-hidden": "true", focusable: "false", children: jsx_runtime_1.jsx("path", { d: "M32 119.4C12.9 108.4 0 87.7 0 64 0 28.7 28.7 0 64 0 87.7 0 108.4 12.9 119.4 32l273.1 0c11.1-19.1 31.7-32 55.4-32 35.3 0 64 28.7 64 64 0 23.7-12.9 44.4-32 55.4l0 273.1c19.1 11.1 32 31.7 32 55.4 0 35.3-28.7 64-64 64-23.7 0-44.4-12.9-55.4-32l-273.1 0c-11.1 19.1-31.7 32-55.4 32-35.3 0-64-28.7-64-64 0-23.7 12.9-44.4 32-55.4l0-273.1zm64 0l0 273.1c9.7 5.6 17.8 13.7 23.4 23.4l273.1 0c5.6-9.7 13.7-17.8 23.4-23.4l0-273.1c-9.7-5.6-17.8-13.7-23.4-23.4L119.4 96c-5.6 9.7-13.7 17.8-23.4 23.4z" }) }) }));
18
+ return (jsx_runtime_1.jsx(ControlButton_1.ControlButton, { title: accessibilityLabel, "aria-label": accessibilityLabel, onClick: onClick, children: jsx_runtime_1.jsx("svg", { style: { width: 18, height: 18 }, viewBox: "0 0 512 512", fill: color, "aria-hidden": "true", focusable: "false", children: jsx_runtime_1.jsx("path", { d: "M32 119.4C12.9 108.4 0 87.7 0 64 0 28.7 28.7 0 64 0 87.7 0 108.4 12.9 119.4 32l273.1 0c11.1-19.1 31.7-32 55.4-32 35.3 0 64 28.7 64 64 0 23.7-12.9 44.4-32 55.4l0 273.1c19.1 11.1 32 31.7 32 55.4 0 35.3-28.7 64-64 64-23.7 0-44.4-12.9-55.4-32l-273.1 0c-11.1 19.1-31.7 32-55.4 32-35.3 0-64-28.7-64-64 0-23.7 12.9-44.4 32-55.4l0-273.1zm64 0l0 273.1c9.7 5.6 17.8 13.7 23.4 23.4l273.1 0c5.6-9.7 13.7-17.8 23.4-23.4l0-273.1c-9.7-5.6-17.8-13.7-23.4-23.4L119.4 96c-5.6 9.7-13.7 17.8-23.4 23.4z" }) }) }));
19
19
  };
20
20
  exports.OutlineToggle = OutlineToggle;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { SelectedOutline } from './selected-outline-geometry';
3
+ import { type SelectedOutlineDragTarget, type SelectedOutlineRotationDragTarget, type SelectedOutlineScaleDragTarget, type SelectedOutlineTarget } from './selected-outline-types';
4
+ import type { TimelineSelection, TimelineSelectionInteraction } from './Timeline/TimelineSelection';
5
+ export declare const SelectedOutlineElement: React.FC<{
6
+ readonly allDragTargets: readonly SelectedOutlineDragTarget[];
7
+ readonly allRotationDragTargets: readonly SelectedOutlineRotationDragTarget[];
8
+ readonly allScaleDragTargets: readonly SelectedOutlineScaleDragTarget[];
9
+ readonly dragging: boolean;
10
+ readonly hovered: boolean;
11
+ readonly outline: SelectedOutline;
12
+ readonly onDraggingChange: (dragging: boolean) => void;
13
+ readonly onHoverChange: (key: string | null) => void;
14
+ readonly onSelect: (item: TimelineSelection, interaction: TimelineSelectionInteraction) => void;
15
+ readonly scale: number;
16
+ readonly target: SelectedOutlineTarget | undefined;
17
+ }>;