Consolidate duplicated editor code, trim comments, refresh README
Split GraphCanvas (1076 -> 831 lines) into EdgeLayer and graphMenus; the port and marker menus were the same list and are now one function. Value specs of the inspector and the list tab share valueSpecs.ts, and the remaining copies (compound commands, type glyphs, typed asset lookup, name rule, play/editor world setup, marquee) are merged. Four copies had already drifted apart; merging them fixes: - "Disconnect N links" in the port menu is one undo step, not N - "+ Add collider" is hidden on a placed container instance, as in the hierarchy menu, instead of always failing - a bool property coerced from the text "false" becomes false - a port command on an unknown node type reports instead of crashing Comment-only edits leave the bundle byte-identical. README corrected in 35 places (step limit, jump-run clock, suite duration, 409 body, ...). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9212e61c4c
commit
8f92a06c84
96 files changed
+999
-1261
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import type { Command } from '../../core/commands/Command';
|
||||
import { CompoundCommand } from '../../core/commands/CompoundCommand';
|
||||
import { oneStep } from '../../core/commands/CompoundCommand';
|
||||
import { UnpackContainerCommand } from '../../core/commands/containerCommands';
|
||||
import { ReorderObjectCommand, SetParentCommand } from '../../core/commands/sceneObjectCommands';
|
||||
import { hasColorSwatch } from '../../core/model/AssetTypes';
|
||||
@@ -9,22 +9,12 @@ import { findAsset, type ObjectHolder } from '../../core/model/Project';
|
||||
import { deviationMarks } from '../../core/properties/deviation';
|
||||
import { resolveSceneObjectProps } from '../../core/properties/resolve';
|
||||
import { type DropSpot, ListView, Menu, Panel, ScrollContainer } from '../../ui';
|
||||
import { addCollider, createContainer, removeObjects } from '../actions';
|
||||
import { addCollider, canAddCollider, createContainer, removeObjects } from '../actions';
|
||||
import { type EditorState, objectSelection } from '../state';
|
||||
|
||||
/**
|
||||
* Objects of the scene or container being edited, as a tree (children indented below their parent).
|
||||
* Click selects, Ctrl/Shift-click adds to or removes from the selection. Drag a row onto
|
||||
* another to parent it there, into the gap above or below a row to order it among that row's
|
||||
* siblings, or onto the empty space below the rows to move it to the top level. The object keeps
|
||||
* its world position every time.
|
||||
*
|
||||
* A row's name turns gold when the object deviates from what it follows – its container template
|
||||
* or its asset – or when anything below it does, so a folded subtree still shows it.
|
||||
*
|
||||
* Rows with children fold: the chevron (or ←/→, or a double-click on the row) toggles them.
|
||||
* Everything starts collapsed – which ids are open is view state kept here, never part of the
|
||||
* project, and selecting an object always unfolds the way down to it.
|
||||
* Objects of the scene or container being edited, as a tree; dragging re-parents or reorders and always
|
||||
* keeps world position. Fold state is view state kept here, never in the project.
|
||||
*/
|
||||
export class HierarchyPanel extends Panel {
|
||||
private readonly list = new ListView();
|
||||
@@ -72,12 +62,7 @@ export class HierarchyPanel extends Panel {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* A drop either puts the dragged row inside another one (parenting, which keeps the world
|
||||
* position) or into a gap, which orders it among the siblings there – and does both when the
|
||||
* gap belongs to a parent the object did not have. A move that would leave the order as it is
|
||||
* does nothing, so a drag that lands where it started costs no undo step.
|
||||
*/
|
||||
/** A move that leaves the order as it is does nothing, so a drag back to its start costs no undo step. */
|
||||
private drop(draggedId: string, spot: DropSpot): void {
|
||||
const holder = this.holder();
|
||||
const object = holder && findObject(holder, draggedId);
|
||||
@@ -108,7 +93,7 @@ export class HierarchyPanel extends Panel {
|
||||
if (object.parentId !== parentId) commands.push(new SetParentCommand(holder.id, draggedId, parentId));
|
||||
commands.push(new ReorderObjectCommand(holder.id, draggedId, beforeId));
|
||||
if (parentId) this.expanded.add(parentId);
|
||||
this.state.execute(commands.length === 1 ? commands[0]! : new CompoundCommand('Move object', commands));
|
||||
this.state.execute(oneStep('Move object', commands));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,7 +150,6 @@ export class HierarchyPanel extends Panel {
|
||||
if (!holder) return undefined;
|
||||
const inScene = holder.type === 'scene';
|
||||
const object = findObject(holder, id);
|
||||
const type = object && findAsset(state.project, object.assetId)?.type;
|
||||
// Content of a placed container belongs to its template: values can be changed here, the
|
||||
// structure cannot (see `model/instance.ts`).
|
||||
const source = this.source();
|
||||
@@ -181,7 +165,7 @@ export class HierarchyPanel extends Panel {
|
||||
},
|
||||
{
|
||||
label: 'Add collider',
|
||||
disabled: !type || type === 'collider' || many || fromTemplate || instance,
|
||||
disabled: !object || !source || many || !canAddCollider(state.project, source, object),
|
||||
onSelect: () => addCollider(state, holder.id, id),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@ import type { EditorState, SaveStatus } from '../state';
|
||||
export interface ToolbarActions {
|
||||
/** The "Project" dropdown: list, create and delete projects. `anchor` is the button to open the menu under. */
|
||||
openProjectMenu(anchor: Widget): void;
|
||||
/** The scene dropdown: switch the active scene. */
|
||||
openSceneMenu(anchor: Widget): void;
|
||||
/** Play in edit mode, Stop in play mode. */
|
||||
togglePlay(): void;
|
||||
|
||||
Reference in new issue
Block a user