Graph: optionales Grid-Snapping beim Ziehen von Nodes

Ein Toggle in der Graph-Kopfzeile lässt gezogene Nodes auf dem 24er-Raster
einrasten – derselben Größe, die den Hintergrund zeichnet. Einschalten bewegt
nichts; die Regel greift erst beim nächsten Zug. Bei Mehrfachauswahl richtet
sich jeder Node für sich aus, statt einem gemeinsamen Versatz zu folgen, der
die alten krummen Abstände mitschleppen würde.

Die Entscheidung liegt als reine Funktion in framing.ts, wo die übrige
Graph-Geometrie schon wohnt, und ist dort wie im Browser gepinnt.
This commit is contained in:
root committed 2026-09-10 17:14:37 +02:00
1 parent 10d030376a
commit 4b47741fac
9 files changed
+187 -14

No files matched your search

+7 -3
View File
@@ -1,5 +1,5 @@
import type { Asset, BehaviorAsset } from '../../core/model/Asset';
import { Button } from '../../ui';
import { Button, Checkbox, Label } from '../../ui';
import { AssetTabEditor } from '../AssetTabEditor';
import type { EditorState } from '../state';
import { GraphCanvas } from './GraphCanvas';
@@ -9,11 +9,13 @@ const INFO_WIDTH = 150;
export class GraphEditor extends AssetTabEditor<BehaviorAsset, GraphCanvas> {
private readonly addButton: Button;
private readonly snapBox = new Checkbox();
constructor(state: EditorState) {
super(state, { noun: 'Behavior', infoWidth: INFO_WIDTH });
this.addButton = new Button('Add node…', { onClick: () => this.canvas.addNodeFrom(this.addButton) });
this.mount(new GraphCanvas(state), [this.addButton]);
this.snapBox.onChange = (on) => this.canvas.setSnapping(on);
this.mount(new GraphCanvas(state), [this.addButton, new Label('Snap', { style: 'muted' }), this.snapBox]);
// Adding nodes is an edit, and edits made while playing would be thrown away with the run.
state.on('mode', () => this.refresh());
}
@@ -33,6 +35,8 @@ export class GraphEditor extends AssetTabEditor<BehaviorAsset, GraphCanvas> {
}
protected override syncExtras(asset: BehaviorAsset | null): void {
this.addButton.setEnabled(Boolean(asset) && this.state.mode === 'edit');
const editable = Boolean(asset) && this.state.mode === 'edit';
this.addButton.setEnabled(editable);
this.snapBox.setEnabled(editable);
}
}