Let a graph node collapse to its title bar
A chevron in front of the title toggles it without touching the selection, and right-click offers Collapse node / Expand node for the whole selection as one undo step. A collapsed node draws its title bar alone; every link of one side meets at a single point on it, and hidden links there share one mark per side, since per-port marks would stack on the same pixels. It has no ports to grab, so a link dropped on it connects nothing. Like hiding a link this is drawing only: collapsed is saved on the node and an expanded node leaves no trace in the project file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
631cf54c72
commit
1e2285c545
12 files changed
+366
-14
No files matched your search
@@ -242,6 +242,36 @@ export class FoldEdgeCommand implements Command {
|
||||
}
|
||||
}
|
||||
|
||||
/** One undo step for the whole selection; every node is found before any of them changes. */
|
||||
export class CollapseNodesCommand implements Command {
|
||||
readonly label: string;
|
||||
private previous: boolean[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly assetId: string,
|
||||
private readonly nodeIds: readonly string[],
|
||||
private readonly collapsed: boolean,
|
||||
) {
|
||||
const noun = nodeIds.length === 1 ? 'node' : 'nodes';
|
||||
this.label = collapsed ? `Collapse ${noun}` : `Expand ${noun}`;
|
||||
}
|
||||
|
||||
execute(project: Project): void {
|
||||
const nodes = this.nodeIds.map((id) => requireNode(project, this.assetId, id));
|
||||
this.previous = nodes.map((n) => n.collapsed === true);
|
||||
for (const node of nodes) setCollapsed(node, this.collapsed);
|
||||
}
|
||||
|
||||
undo(project: Project): void {
|
||||
this.nodeIds.forEach((id, i) => setCollapsed(requireNode(project, this.assetId, id), this.previous[i]!));
|
||||
}
|
||||
}
|
||||
|
||||
function setCollapsed(node: GraphNode, collapsed: boolean): void {
|
||||
if (collapsed) node.collapsed = true;
|
||||
else delete node.collapsed;
|
||||
}
|
||||
|
||||
export class DisconnectCommand implements Command {
|
||||
readonly label = 'Disconnect';
|
||||
private removed: Removed<GraphEdge>[] = [];
|
||||
|
||||
@@ -24,6 +24,8 @@ export interface GraphNode {
|
||||
* behavior its signature; an Expand/Pack node is what gives a struct its fields.
|
||||
*/
|
||||
ports?: DeclaredPort[];
|
||||
/** Drawn as its title bar alone, every link meeting at one point per side. Purely visual. */
|
||||
collapsed?: boolean;
|
||||
}
|
||||
|
||||
/** A port a start/end node declares. `kind` maps to the PortType of the same name (`text` → string). */
|
||||
|
||||
@@ -244,6 +244,7 @@ function normalizeGraph(raw: unknown): Graph {
|
||||
const node: GraphNode = { id, type, x: toNumber(n.x), y: toNumber(n.y), params };
|
||||
const ports = normalizePorts(n.ports);
|
||||
if (ports.length > 0) node.ports = ports;
|
||||
if (n.collapsed === true) node.collapsed = true;
|
||||
graph.nodes.push(node);
|
||||
}
|
||||
const edgeIds = new Set<string>();
|
||||
|
||||
Reference in new issue
Block a user