A box drawn around a part of the graph is part of it, so a fit frames it and a band catches it (#95)
game-maker / suite (push) Successful in 6m22s

Fit measured the nodes alone: a group drawn around them was cut off, and a graph holding nothing
but a comment framed the empty origin. It now frames both sorts together.

The rubber band ignored boxes entirely. It catches them now, into the *same* selection as the
nodes — `nodeIds` and `annotationIds` side by side — so one drag moves all of it, one Delete
removes all of it, and one undo takes it back. A box counts only when the band holds all of it,
where a node counts on touching: a group wraps the nodes it holds and therefore overlaps every
band drawn over any of them, and since it drags those nodes along, catching it by accident would
be felt at once.

A node inside a selected group is moved once, not twice — `travellers()` collects everything one
gesture carries and lets each thing appear in it a single time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5 committed 2026-09-16 14:23:56 +02:00
1 parent be8f2331de
commit 36ccc7626f
9 files changed
+554 -46

No files matched your search

+9 -3
View File
@@ -4,7 +4,7 @@ import { CollapseNodesCommand, DisconnectCommand, FoldEdgeCommand } from '../../
import { annotationNoun } from '../../core/commands/annotationCommands';
import type { AnnotationKind, GraphEdge, GraphNode } from '../../core/graph';
import { Menu, type MenuItem } from '../../ui';
import { removeAnnotation, removeNodes } from '../actions';
import { removeGraphSelection, removeNodes } from '../actions';
import type { EditorState } from '../state';
/** For the selected nodes; a selection mixing both states offers both directions. */
@@ -49,11 +49,17 @@ export function openAnnotationMenu(
x: number,
y: number,
): void {
// Right-clicking a box keeps whatever else is selected, so the entry speaks about all of it –
// a menu that silently deleted one of five marked boxes would be the worse surprise.
const held = state.selectedAnnotationIds.includes(id);
const boxes = held ? state.selectedAnnotationIds : [id];
const nodes = held ? state.selectedNodeIds : [];
const count = boxes.length + nodes.length;
new Menu([
{
label: `Delete ${annotationNoun(kind)}`,
label: count > 1 ? `Delete ${count} items` : `Delete ${annotationNoun(kind)}`,
danger: true,
onSelect: () => removeAnnotation(state, assetId, id),
onSelect: () => removeGraphSelection(state, assetId, nodes, boxes),
},
]).open(x, y);
}