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.
- package/README.md +6 -6
- package/dist/core/binding.d.ts +1 -1
- package/dist/core/colors.d.ts +1 -1
- package/dist/core/defaultEffect.d.ts +1 -1
- package/dist/core/effectTree.d.ts +1 -1
- package/dist/core/effectTree.js +18 -4
- package/dist/core/emitterShapeWireframe.d.ts +1 -1
- package/dist/core/emitterShapeWireframe.js +1 -1
- package/dist/core/galleryDropMarker.js +1 -1
- package/dist/core/galleryScene.d.ts +1 -1
- package/dist/core/galleryTree.js +4 -1
- package/dist/core/loadEffect.d.ts +2 -2
- package/dist/core/loadEffect.js +1 -1
- package/dist/core/loadEffectGallery.d.ts +2 -2
- package/dist/core/shapes.d.ts +1 -1
- package/dist/core/shapes.js +35 -8
- package/dist/core/systems.d.ts +1 -1
- package/dist/core/systems.js +3 -1
- package/dist/core/timeline.d.ts +1 -2
- package/dist/core/values.d.ts +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +6 -6
- package/dist/react/CurveEditor.d.ts +1 -2
- package/dist/react/CurveEditor.js +14 -3
- package/dist/react/EffectEditor.d.ts +2 -2
- package/dist/react/EffectEditor.js +2 -2
- package/dist/react/EffectEditorHost.d.ts +1 -1
- package/dist/react/EffectEditorHost.js +123 -33
- package/dist/react/GalleryPanel.d.ts +1 -1
- package/dist/react/GalleryPanel.js +14 -7
- package/dist/react/GradientEditor.d.ts +1 -2
- package/dist/react/GradientEditor.js +8 -1
- package/dist/react/MessageDialog.js +7 -1
- package/dist/react/ModuleSection.js +10 -3
- package/dist/react/ObjectModule.d.ts +1 -2
- package/dist/react/ObjectModule.js +1 -1
- package/dist/react/SubEmittersModule.d.ts +1 -2
- package/dist/react/TimelinePanel.d.ts +3 -3
- package/dist/react/TimelinePanel.js +55 -9
- package/dist/react/TimelineTrackRow.d.ts +1 -1
- package/dist/react/TimelineTrackRow.js +20 -6
- package/dist/react/ValueField.d.ts +1 -2
- package/dist/react/behaviorModules.js +19 -5
- package/dist/react/index.d.ts +17 -17
- package/dist/react/index.js +11 -11
- package/dist/react/modules.js +55 -25
- package/package.json +68 -68
- package/src/core/binding.ts +2 -2
- package/src/core/colors.ts +1 -1
- package/src/core/defaultEffect.ts +1 -1
- package/src/core/effectTree.ts +22 -7
- package/src/core/emitterShapeWireframe.ts +8 -4
- package/src/core/galleryDropMarker.ts +6 -2
- package/src/core/galleryPlayback.ts +1 -1
- package/src/core/galleryScene.ts +3 -7
- package/src/core/gallerySelectionMarker.ts +5 -1
- package/src/core/galleryTree.ts +8 -5
- package/src/core/loadEffect.ts +3 -3
- package/src/core/loadEffectGallery.ts +7 -3
- package/src/core/pickGalleryFiles.ts +4 -1
- package/src/core/shapes.ts +48 -10
- package/src/core/systems.ts +9 -3
- package/src/core/timeline.ts +8 -8
- package/src/core/values.ts +1 -1
- package/src/core/viewportPicker.ts +1 -1
- package/src/index.ts +18 -18
- package/src/react/CurveEditor.tsx +40 -10
- package/src/react/EffectEditor.tsx +14 -13
- package/src/react/EffectEditorHost.tsx +239 -64
- package/src/react/GalleryPanel.tsx +56 -12
- package/src/react/GradientEditor.tsx +21 -4
- package/src/react/InspectorInfoIcon.tsx +6 -2
- package/src/react/MessageDialog.tsx +9 -1
- package/src/react/ModuleSection.tsx +12 -3
- package/src/react/ObjectModule.tsx +36 -15
- package/src/react/PromptDialog.tsx +5 -1
- package/src/react/SubEmittersModule.tsx +1 -2
- package/src/react/TimelinePanel.tsx +94 -21
- package/src/react/TimelineTrackRow.tsx +71 -18
- package/src/react/ValueField.tsx +0 -1
- package/src/react/behaviorModules.tsx +143 -29
- package/src/react/index.ts +33 -33
- 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: {
|
|
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
|
|
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
|
|
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: {
|
|
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
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
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 {
|
|
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
|
-
}, [
|
|
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
|
|
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
|
|
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
|
|
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={{
|
|
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
|
|
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={
|
|
495
|
+
onToggleCollapse={
|
|
496
|
+
row.kind === 'group' ? () => toggleCollapse(row.node) : undefined
|
|
497
|
+
}
|
|
438
498
|
hidden={row.kind === 'track' && hiddenSystems.has(row.system)}
|
|
439
|
-
onToggleVisible={
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
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
|
|
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 ?
|
|
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
|
|
143
|
-
|
|
144
|
-
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
|
241
|
-
|
|
242
|
-
|
|
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}}
|
|
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>
|
package/src/react/ValueField.tsx
CHANGED