babylon.quarks-editor 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +6 -6
  2. package/dist/core/binding.d.ts +1 -1
  3. package/dist/core/colors.d.ts +1 -1
  4. package/dist/core/defaultEffect.d.ts +1 -1
  5. package/dist/core/effectTree.d.ts +1 -1
  6. package/dist/core/effectTree.js +18 -4
  7. package/dist/core/emitterShapeWireframe.d.ts +1 -1
  8. package/dist/core/emitterShapeWireframe.js +1 -1
  9. package/dist/core/galleryDropMarker.js +1 -1
  10. package/dist/core/galleryScene.d.ts +1 -1
  11. package/dist/core/galleryTree.js +4 -1
  12. package/dist/core/loadEffect.d.ts +2 -2
  13. package/dist/core/loadEffect.js +1 -1
  14. package/dist/core/loadEffectGallery.d.ts +2 -2
  15. package/dist/core/shapes.d.ts +1 -1
  16. package/dist/core/shapes.js +35 -8
  17. package/dist/core/systems.d.ts +1 -1
  18. package/dist/core/systems.js +3 -1
  19. package/dist/core/timeline.d.ts +1 -2
  20. package/dist/core/values.d.ts +1 -1
  21. package/dist/index.d.ts +11 -11
  22. package/dist/index.js +6 -6
  23. package/dist/react/CurveEditor.d.ts +1 -2
  24. package/dist/react/CurveEditor.js +14 -3
  25. package/dist/react/EffectEditor.d.ts +2 -2
  26. package/dist/react/EffectEditor.js +2 -2
  27. package/dist/react/EffectEditorHost.d.ts +1 -1
  28. package/dist/react/EffectEditorHost.js +123 -33
  29. package/dist/react/GalleryPanel.d.ts +1 -1
  30. package/dist/react/GalleryPanel.js +14 -7
  31. package/dist/react/GradientEditor.d.ts +1 -2
  32. package/dist/react/GradientEditor.js +8 -1
  33. package/dist/react/MessageDialog.js +7 -1
  34. package/dist/react/ModuleSection.js +10 -3
  35. package/dist/react/ObjectModule.d.ts +1 -2
  36. package/dist/react/ObjectModule.js +1 -1
  37. package/dist/react/SubEmittersModule.d.ts +1 -2
  38. package/dist/react/TimelinePanel.d.ts +3 -3
  39. package/dist/react/TimelinePanel.js +55 -9
  40. package/dist/react/TimelineTrackRow.d.ts +1 -1
  41. package/dist/react/TimelineTrackRow.js +20 -6
  42. package/dist/react/ValueField.d.ts +1 -2
  43. package/dist/react/behaviorModules.js +19 -5
  44. package/dist/react/index.d.ts +17 -17
  45. package/dist/react/index.js +11 -11
  46. package/dist/react/modules.js +55 -25
  47. package/package.json +68 -68
  48. package/src/core/binding.ts +2 -2
  49. package/src/core/colors.ts +1 -1
  50. package/src/core/defaultEffect.ts +1 -1
  51. package/src/core/effectTree.ts +22 -7
  52. package/src/core/emitterShapeWireframe.ts +8 -4
  53. package/src/core/galleryDropMarker.ts +6 -2
  54. package/src/core/galleryPlayback.ts +1 -1
  55. package/src/core/galleryScene.ts +3 -7
  56. package/src/core/gallerySelectionMarker.ts +5 -1
  57. package/src/core/galleryTree.ts +8 -5
  58. package/src/core/loadEffect.ts +3 -3
  59. package/src/core/loadEffectGallery.ts +7 -3
  60. package/src/core/pickGalleryFiles.ts +4 -1
  61. package/src/core/shapes.ts +48 -10
  62. package/src/core/systems.ts +9 -3
  63. package/src/core/timeline.ts +8 -8
  64. package/src/core/values.ts +1 -1
  65. package/src/core/viewportPicker.ts +1 -1
  66. package/src/index.ts +18 -18
  67. package/src/react/CurveEditor.tsx +40 -10
  68. package/src/react/EffectEditor.tsx +14 -13
  69. package/src/react/EffectEditorHost.tsx +239 -64
  70. package/src/react/GalleryPanel.tsx +56 -12
  71. package/src/react/GradientEditor.tsx +21 -4
  72. package/src/react/InspectorInfoIcon.tsx +6 -2
  73. package/src/react/MessageDialog.tsx +9 -1
  74. package/src/react/ModuleSection.tsx +12 -3
  75. package/src/react/ObjectModule.tsx +36 -15
  76. package/src/react/PromptDialog.tsx +5 -1
  77. package/src/react/SubEmittersModule.tsx +1 -2
  78. package/src/react/TimelinePanel.tsx +94 -21
  79. package/src/react/TimelineTrackRow.tsx +71 -18
  80. package/src/react/ValueField.tsx +0 -1
  81. package/src/react/behaviorModules.tsx +143 -29
  82. package/src/react/index.ts +33 -33
  83. package/src/react/modules.tsx +173 -57
@@ -1,11 +1,15 @@
1
- import React from 'react';
2
1
  import {InformationCircleIcon} from '@heroicons/react/24/solid';
2
+ import React from 'react';
3
3
  import {iconStyle} from './icons';
4
4
  import {theme} from './theme';
5
5
  import {Tooltip} from './Tooltip';
6
6
 
7
7
  /** Small info icon with a themed inspector tooltip. */
8
- export function InspectorInfoIcon(props: {content: string; size?: number; onClick?: (e: React.MouseEvent) => void}): React.ReactElement {
8
+ export function InspectorInfoIcon(props: {
9
+ content: string;
10
+ size?: number;
11
+ onClick?: (e: React.MouseEvent) => void;
12
+ }): React.ReactElement {
9
13
  const size = props.size ?? 13;
10
14
  return (
11
15
  <Tooltip content={props.content}>
@@ -39,7 +39,15 @@ export function MessageDialog(props: MessageDialogProps): React.ReactElement {
39
39
  onClick={(e) => e.stopPropagation()}
40
40
  >
41
41
  <div style={{fontSize: 14, fontWeight: 600, color: theme.text, marginBottom: 8}}>{title}</div>
42
- <div style={{fontSize: 13, lineHeight: 1.5, color: theme.textDim, marginBottom: 14, whiteSpace: 'pre-wrap'}}>
42
+ <div
43
+ style={{
44
+ fontSize: 13,
45
+ lineHeight: 1.5,
46
+ color: theme.textDim,
47
+ marginBottom: 14,
48
+ whiteSpace: 'pre-wrap',
49
+ }}
50
+ >
43
51
  {message}
44
52
  </div>
45
53
  <div style={{display: 'flex', justifyContent: 'flex-end'}}>
@@ -1,9 +1,9 @@
1
- import React, {useState} from 'react';
2
1
  import {ChevronDownIcon, ChevronRightIcon} from '@heroicons/react/24/solid';
2
+ import React, {useState} from 'react';
3
+ import {iconStyle} from './icons';
3
4
  import {getInspectorHint} from './inspectorHints';
4
5
  import {InspectorInfoIcon} from './InspectorInfoIcon';
5
6
  import {theme} from './theme';
6
- import {iconStyle} from './icons';
7
7
 
8
8
  /** Unity-style module foldout with an optional enable checkbox. */
9
9
  export function ModuleSection(props: {
@@ -58,7 +58,16 @@ export function ModuleSection(props: {
58
58
  style={{width: 14, height: 14, accentColor: '#78a5ff', cursor: 'pointer'}}
59
59
  />
60
60
  )}
61
- <span style={{color: dimmed ? theme.textDim : theme.text, fontSize: 13, fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 5}}>
61
+ <span
62
+ style={{
63
+ color: dimmed ? theme.textDim : theme.text,
64
+ fontSize: 13,
65
+ fontWeight: 600,
66
+ display: 'inline-flex',
67
+ alignItems: 'center',
68
+ gap: 5,
69
+ }}
70
+ >
62
71
  {props.title}
63
72
  {tooltip ? <InspectorInfoIcon content={tooltip} onClick={(e) => e.stopPropagation()} /> : null}
64
73
  </span>
@@ -1,6 +1,6 @@
1
- import React, {useSyncExternalStore} from 'react';
2
- import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
3
1
  import {Quaternion} from '@babylonjs/core/Maths/math.vector';
2
+ import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
3
+ import {useSyncExternalStore} from 'react';
4
4
  import {getTransformRevision, notifyTransformChanged, subscribeTransform} from '../core/transformStore';
5
5
  import {ModuleSection} from './ModuleSection';
6
6
  import {NumberField, Row} from './fields';
@@ -23,7 +23,13 @@ function setEulerDegreeAxis(node: TransformNode, axis: 'x' | 'y' | 'z', degrees:
23
23
  }
24
24
  }
25
25
 
26
- function AxisRow(props: {label: string; hintKey?: string; values: {x: number; y: number; z: number}; step: number; onChange: (axis: 'x' | 'y' | 'z', value: number) => void}) {
26
+ function AxisRow(props: {
27
+ label: string;
28
+ hintKey?: string;
29
+ values: {x: number; y: number; z: number};
30
+ step: number;
31
+ onChange: (axis: 'x' | 'y' | 'z', value: number) => void;
32
+ }) {
27
33
  return (
28
34
  <Row label={props.label} hintKey={props.hintKey}>
29
35
  <div style={{display: 'flex', gap: 4}}>
@@ -41,18 +47,33 @@ export function ObjectModule(props: {node: TransformNode; label: string}) {
41
47
  const euler = getEulerDegrees(node);
42
48
  return (
43
49
  <ModuleSection title={`Object — ${props.label}`}>
44
- <AxisRow label="Position" values={{x: node.position.x, y: node.position.y, z: node.position.z}} step={0.1} onChange={(axis, v) => {
45
- node.position[axis] = v;
46
- notifyTransformChanged();
47
- }} />
48
- <AxisRow label="Rotation" values={euler} step={1} onChange={(axis, v) => {
49
- setEulerDegreeAxis(node, axis, v);
50
- notifyTransformChanged();
51
- }} />
52
- <AxisRow label="Scale" values={{x: node.scaling.x, y: node.scaling.y, z: node.scaling.z}} step={0.1} onChange={(axis, v) => {
53
- node.scaling[axis] = v;
54
- notifyTransformChanged();
55
- }} />
50
+ <AxisRow
51
+ label="Position"
52
+ values={{x: node.position.x, y: node.position.y, z: node.position.z}}
53
+ step={0.1}
54
+ onChange={(axis, v) => {
55
+ node.position[axis] = v;
56
+ notifyTransformChanged();
57
+ }}
58
+ />
59
+ <AxisRow
60
+ label="Rotation"
61
+ values={euler}
62
+ step={1}
63
+ onChange={(axis, v) => {
64
+ setEulerDegreeAxis(node, axis, v);
65
+ notifyTransformChanged();
66
+ }}
67
+ />
68
+ <AxisRow
69
+ label="Scale"
70
+ values={{x: node.scaling.x, y: node.scaling.y, z: node.scaling.z}}
71
+ step={0.1}
72
+ onChange={(axis, v) => {
73
+ node.scaling[axis] = v;
74
+ notifyTransformChanged();
75
+ }}
76
+ />
56
77
  </ModuleSection>
57
78
  );
58
79
  }
@@ -75,7 +75,11 @@ export function PromptDialog(props: PromptDialogProps): React.ReactElement {
75
75
  <button className="qe-hover" style={buttonStyle} onClick={onCancel}>
76
76
  Cancel
77
77
  </button>
78
- <button className="qe-hover" style={{...buttonStyle, background: theme.accent, color: '#0a1128', borderColor: theme.accent}} onClick={submit}>
78
+ <button
79
+ className="qe-hover"
80
+ style={{...buttonStyle, background: theme.accent, color: '#0a1128', borderColor: theme.accent}}
81
+ onClick={submit}
82
+ >
79
83
  {confirmLabel}
80
84
  </button>
81
85
  </div>
@@ -1,6 +1,5 @@
1
- import React from 'react';
2
- import {EmitSubParticleSystem, SubParticleEmitMode} from 'babylon.quarks';
3
1
  import type {ParticleEmitter, ParticleSystem} from 'babylon.quarks';
2
+ import {EmitSubParticleSystem, SubParticleEmitMode} from 'babylon.quarks';
4
3
  import {EffectBinding} from '../core/binding';
5
4
  import {findBehavior} from '../core/colors';
6
5
  import {createChildSystem} from '../core/systems';
@@ -1,15 +1,10 @@
1
- import React, {useMemo, useRef, useState} from 'react';
2
- import {
3
- ArrowPathIcon,
4
- ForwardIcon,
5
- PauseIcon,
6
- PlayIcon,
7
- RectangleGroupIcon,
8
- } from '@heroicons/react/24/solid';
9
- import type {ParticleSystem, BatchedRenderer} from 'babylon.quarks';
10
- import type {Scene} from '@babylonjs/core/scene';
11
1
  import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
2
+ import type {Scene} from '@babylonjs/core/scene';
3
+ import {ArrowPathIcon, ForwardIcon, PauseIcon, PlayIcon, RectangleGroupIcon} from '@heroicons/react/24/solid';
4
+ import type {BatchedRenderer, ParticleSystem} from 'babylon.quarks';
5
+ import React, {useMemo, useRef, useState} from 'react';
12
6
  import type {EffectBinding} from '../core/binding';
7
+ import {groupNodes} from '../core/groups';
13
8
  import {
14
9
  clearFocusFinished,
15
10
  getFocusElapsed,
@@ -18,7 +13,6 @@ import {
18
13
  setFocusElapsed,
19
14
  type PlaybackState,
20
15
  } from '../core/playback';
21
- import {groupNodes} from '../core/groups';
22
16
  import {pauseFocus, playFocus, scrubFocusTo, scrubFocusToSettled} from '../core/scrub';
23
17
  import {computeTimelineRows, computeTimelineSpan} from '../core/timeline';
24
18
  import {TimelineTrackRow} from './TimelineTrackRow';
@@ -64,7 +58,21 @@ function pickTickInterval(pxPerSecond: number): number {
64
58
  * apply only to the focused effect without stopping other previews.
65
59
  */
66
60
  export function TimelinePanel(props: TimelinePanelProps): React.ReactElement {
67
- const {binding, selectedNode, onSelectNode, scene, renderer, playbackRef, playheadRef, counterRef, stagePlaying, setStagePlaying, speed, setSpeed, playbackEnabled = true} = props;
61
+ const {
62
+ binding,
63
+ selectedNode,
64
+ onSelectNode,
65
+ scene,
66
+ renderer,
67
+ playbackRef,
68
+ playheadRef,
69
+ counterRef,
70
+ stagePlaying,
71
+ setStagePlaying,
72
+ speed,
73
+ setSpeed,
74
+ playbackEnabled = true,
75
+ } = props;
68
76
 
69
77
  const [bodyWidthPx, setBodyWidthPx] = useState(600);
70
78
  const [collapsedGroups, setCollapsedGroups] = useState<Set<TransformNode>>(() => new Set());
@@ -168,7 +176,18 @@ export function TimelinePanel(props: TimelinePanelProps): React.ReactElement {
168
176
  };
169
177
  raf = requestAnimationFrame(tick);
170
178
  return () => cancelAnimationFrame(raf);
171
- }, [pxPerSecond, timelineSpan, anyLooping, playbackRef, playheadRef, focusRootId, playbackEnabled, binding, scene, renderer]);
179
+ }, [
180
+ pxPerSecond,
181
+ timelineSpan,
182
+ anyLooping,
183
+ playbackRef,
184
+ playheadRef,
185
+ focusRootId,
186
+ playbackEnabled,
187
+ binding,
188
+ scene,
189
+ renderer,
190
+ ]);
172
191
 
173
192
  const visibleRows = useMemo(() => {
174
193
  let hideUntilDepth: number | null = null;
@@ -295,7 +314,15 @@ export function TimelinePanel(props: TimelinePanelProps): React.ReactElement {
295
314
  color: theme.text,
296
315
  }}
297
316
  >
298
- <div style={{display: 'flex', alignItems: 'center', gap: 6, padding: '6px 10px', borderBottom: `1px solid ${theme.border}`}}>
317
+ <div
318
+ style={{
319
+ display: 'flex',
320
+ alignItems: 'center',
321
+ gap: 6,
322
+ padding: '6px 10px',
323
+ borderBottom: `1px solid ${theme.border}`,
324
+ }}
325
+ >
299
326
  <button
300
327
  className="qe-hover"
301
328
  style={{...overlayButton, opacity: playbackEnabled ? 1 : 0.45}}
@@ -341,9 +368,23 @@ export function TimelinePanel(props: TimelinePanelProps): React.ReactElement {
341
368
  </option>
342
369
  ))}
343
370
  </select>
344
- <span ref={counterRef} style={{fontSize: 12, color: theme.textDim, fontVariantNumeric: 'tabular-nums', paddingLeft: 4, minWidth: 120}} />
371
+ <span
372
+ ref={counterRef}
373
+ style={{
374
+ fontSize: 12,
375
+ color: theme.textDim,
376
+ fontVariantNumeric: 'tabular-nums',
377
+ paddingLeft: 4,
378
+ minWidth: 120,
379
+ }}
380
+ />
345
381
  {groupSelection.size >= 2 && (
346
- <button className="qe-hover" style={overlayButton} title="Group the checked rows" onClick={groupSelectedNodes}>
382
+ <button
383
+ className="qe-hover"
384
+ style={overlayButton}
385
+ title="Group the checked rows"
386
+ onClick={groupSelectedNodes}
387
+ >
347
388
  <RectangleGroupIcon style={iconStyle(14)} />
348
389
  Group ({groupSelection.size})
349
390
  </button>
@@ -385,7 +426,12 @@ export function TimelinePanel(props: TimelinePanelProps): React.ReactElement {
385
426
  <div style={{height: RULER_HEIGHT}} />
386
427
  <div
387
428
  className="qe-hover-bg"
388
- style={{position: 'relative', height: RULER_HEIGHT, cursor: 'ew-resize', overflow: 'hidden'}}
429
+ style={{
430
+ position: 'relative',
431
+ height: RULER_HEIGHT,
432
+ cursor: 'ew-resize',
433
+ overflow: 'hidden',
434
+ }}
389
435
  onPointerDown={(e) => {
390
436
  playbackRef.current.scrubbing = true;
391
437
  (e.target as Element).setPointerCapture(e.pointerId);
@@ -400,7 +446,19 @@ export function TimelinePanel(props: TimelinePanelProps): React.ReactElement {
400
446
  }}
401
447
  >
402
448
  {ticks.map((t) => (
403
- <div key={t} style={{position: 'absolute', left: TIMELINE_INSET + t * pxPerSecond, top: 0, bottom: 0, borderLeft: `1px solid ${theme.border}`, fontSize: 10, color: theme.textDim, paddingLeft: 3}}>
449
+ <div
450
+ key={t}
451
+ style={{
452
+ position: 'absolute',
453
+ left: TIMELINE_INSET + t * pxPerSecond,
454
+ top: 0,
455
+ bottom: 0,
456
+ borderLeft: `1px solid ${theme.border}`,
457
+ fontSize: 10,
458
+ color: theme.textDim,
459
+ paddingLeft: 3,
460
+ }}
461
+ >
404
462
  {t}s
405
463
  </div>
406
464
  ))}
@@ -434,16 +492,31 @@ export function TimelinePanel(props: TimelinePanelProps): React.ReactElement {
434
492
  pxPerSecond={pxPerSecond}
435
493
  offsetPx={TIMELINE_INSET}
436
494
  collapsed={row.kind === 'group' && collapsedGroups.has(row.node)}
437
- onToggleCollapse={row.kind === 'group' ? () => toggleCollapse(row.node) : undefined}
495
+ onToggleCollapse={
496
+ row.kind === 'group' ? () => toggleCollapse(row.node) : undefined
497
+ }
438
498
  hidden={row.kind === 'track' && hiddenSystems.has(row.system)}
439
- onToggleVisible={row.kind === 'track' ? () => toggleVisible(row.system) : undefined}
499
+ onToggleVisible={
500
+ row.kind === 'track' ? () => toggleVisible(row.system) : undefined
501
+ }
440
502
  groupSelected={groupSelection.has(row.node)}
441
503
  onToggleGroupSelect={() => toggleGroupSelect(row.node)}
442
504
  />
443
505
  ))}
444
506
  </div>
445
507
  </div>
446
- <div style={{position: 'absolute', top: 0, bottom: 0, left: LABEL_WIDTH, width: 1, background: theme.border, pointerEvents: 'none', zIndex: 3}} />
508
+ <div
509
+ style={{
510
+ position: 'absolute',
511
+ top: 0,
512
+ bottom: 0,
513
+ left: LABEL_WIDTH,
514
+ width: 1,
515
+ background: theme.border,
516
+ pointerEvents: 'none',
517
+ zIndex: 3,
518
+ }}
519
+ />
447
520
  <div
448
521
  ref={playheadRef}
449
522
  style={{
@@ -1,4 +1,4 @@
1
- import React, {useState} from 'react';
1
+ import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
2
2
  import {
3
3
  CheckIcon,
4
4
  ChevronDownIcon,
@@ -12,11 +12,11 @@ import {
12
12
  XMarkIcon,
13
13
  } from '@heroicons/react/24/solid';
14
14
  import type {ParticleSystem} from 'babylon.quarks';
15
- import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
15
+ import React, {useState} from 'react';
16
16
  import type {EffectBinding} from '../core/binding';
17
17
  import {buildEffectTree, collectSystems} from '../core/effectTree';
18
- import {createChildSystem, removeSystems} from '../core/systems';
19
18
  import {ungroupNode} from '../core/groups';
19
+ import {createChildSystem, removeSystems} from '../core/systems';
20
20
  import type {TimelineRow} from '../core/timeline';
21
21
  import {PromptDialog} from './PromptDialog';
22
22
  import {iconStyle} from './icons';
@@ -56,7 +56,20 @@ const checkboxButton: React.CSSProperties = {...iconButton, width: 12, height: 1
56
56
 
57
57
  /** One row of the timeline: a label cell (name + actions) and, for tracks, a bar cell. */
58
58
  export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactElement {
59
- const {row, binding, selected, onSelectNode, pxPerSecond, offsetPx, collapsed, onToggleCollapse, hidden, onToggleVisible, groupSelected, onToggleGroupSelect} = props;
59
+ const {
60
+ row,
61
+ binding,
62
+ selected,
63
+ onSelectNode,
64
+ pxPerSecond,
65
+ offsetPx,
66
+ collapsed,
67
+ onToggleCollapse,
68
+ hidden,
69
+ onToggleVisible,
70
+ groupSelected,
71
+ onToggleGroupSelect,
72
+ } = props;
60
73
  const [renaming, setRenaming] = useState(false);
61
74
 
62
75
  const isRoot = row.node === binding.root;
@@ -100,7 +113,16 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
100
113
  {groupSelected ? (
101
114
  <CheckIcon style={iconStyle(12)} />
102
115
  ) : (
103
- <span style={{width: 10, height: 10, border: `1px solid currentColor`, borderRadius: 2, display: 'block', boxSizing: 'border-box'}} />
116
+ <span
117
+ style={{
118
+ width: 10,
119
+ height: 10,
120
+ border: `1px solid currentColor`,
121
+ borderRadius: 2,
122
+ display: 'block',
123
+ boxSizing: 'border-box',
124
+ }}
125
+ />
104
126
  )}
105
127
  </button>
106
128
  )}
@@ -113,7 +135,11 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
113
135
  onToggleCollapse?.();
114
136
  }}
115
137
  >
116
- {collapsed ? <ChevronRightIcon style={iconStyle(12)} /> : <ChevronDownIcon style={iconStyle(12)} />}
138
+ {collapsed ? (
139
+ <ChevronRightIcon style={iconStyle(12)} />
140
+ ) : (
141
+ <ChevronDownIcon style={iconStyle(12)} />
142
+ )}
117
143
  </span>
118
144
  <span style={{flex: 1, overflow: 'hidden', textOverflow: 'ellipsis'}}>{row.name}</span>
119
145
  <button
@@ -139,10 +165,15 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
139
165
  <PlusIcon style={iconStyle(13)} />
140
166
  </button>
141
167
  {!isRoot && (
142
- <button className="qe-hover" title="Rename" style={{...iconButton, color: theme.textDim}} onClick={(e) => {
143
- e.stopPropagation();
144
- setRenaming(true);
145
- }}>
168
+ <button
169
+ className="qe-hover"
170
+ title="Rename"
171
+ style={{...iconButton, color: theme.textDim}}
172
+ onClick={(e) => {
173
+ e.stopPropagation();
174
+ setRenaming(true);
175
+ }}
176
+ >
146
177
  <PencilSquareIcon style={iconStyle(12)} />
147
178
  </button>
148
179
  )}
@@ -166,7 +197,9 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
166
197
  style={{...iconButton, color: '#e08c8c'}}
167
198
  onClick={(e) => {
168
199
  e.stopPropagation();
169
- removeSystems(binding, collectSystems(buildEffectTree(row.node)), (s) => onSelectNode(s.emitter));
200
+ removeSystems(binding, collectSystems(buildEffectTree(row.node)), (s) =>
201
+ onSelectNode(s.emitter)
202
+ );
170
203
  binding.apply(() => row.node.dispose(true, false));
171
204
  }}
172
205
  >
@@ -174,7 +207,11 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
174
207
  </button>
175
208
  )}
176
209
  </div>
177
- <div className="qe-hover-bg" style={{height: ROW_HEIGHT, borderTop: `1px solid ${theme.border}`}} onClick={() => onSelectNode(row.node)} />
210
+ <div
211
+ className="qe-hover-bg"
212
+ style={{height: ROW_HEIGHT, borderTop: `1px solid ${theme.border}`}}
213
+ onClick={() => onSelectNode(row.node)}
214
+ />
178
215
  {renaming && (
179
216
  <PromptDialog
180
217
  title="Rename"
@@ -214,7 +251,16 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
214
251
  {groupSelected ? (
215
252
  <CheckIcon style={iconStyle(12)} />
216
253
  ) : (
217
- <span style={{width: 10, height: 10, border: `1px solid currentColor`, borderRadius: 2, display: 'block', boxSizing: 'border-box'}} />
254
+ <span
255
+ style={{
256
+ width: 10,
257
+ height: 10,
258
+ border: `1px solid currentColor`,
259
+ borderRadius: 2,
260
+ display: 'block',
261
+ boxSizing: 'border-box',
262
+ }}
263
+ />
218
264
  )}
219
265
  </button>
220
266
  )}
@@ -237,10 +283,15 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
237
283
  {system.onlyUsedByOther ? ' (sub)' : ''}
238
284
  </span>
239
285
  {!isRoot && (
240
- <button className="qe-hover" title="Rename" style={{...iconButton, color: theme.textDim}} onClick={(e) => {
241
- e.stopPropagation();
242
- setRenaming(true);
243
- }}>
286
+ <button
287
+ className="qe-hover"
288
+ title="Rename"
289
+ style={{...iconButton, color: theme.textDim}}
290
+ onClick={(e) => {
291
+ e.stopPropagation();
292
+ setRenaming(true);
293
+ }}
294
+ >
244
295
  <PencilSquareIcon style={iconStyle(12)} />
245
296
  </button>
246
297
  )}
@@ -306,7 +357,9 @@ export function TimelineTrackRow(props: TimelineTrackRowProps): React.ReactEleme
306
357
  }}
307
358
  >
308
359
  {row.looping && (
309
- <span style={{position: 'absolute', right: 4, top: -1, fontSize: 10, color: theme.text}}>⟳</span>
360
+ <span style={{position: 'absolute', right: 4, top: -1, fontSize: 10, color: theme.text}}>
361
+ ⟳
362
+ </span>
310
363
  )}
311
364
  </div>
312
365
  </div>
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import {ScalarGenerator, ScalarValueState, buildCurve, buildScalar, readPieces, readScalar} from '../core/values';
3
2
  import {CurveEditor} from './CurveEditor';
4
3
  import {NumberField, Row, SelectField} from './fields';