import { statesOf } from '../../core/graph'; import type { Asset, StateMachineAsset } from '../../core/model/Asset'; import { AssetTabEditor } from '../AssetTabEditor'; import { GraphCanvas } from '../graph/GraphCanvas'; import { SnapToggle } from '../graph/SnapToggle'; import type { EditorState } from '../state'; /** Room kept for the "N states" readout. */ const INFO_WIDTH = 90; /** * The states of one state machine, on the graph canvas the Behavior tab uses: a state is a node and * a transition an edge, so placing (right-click), moving, snapping, renaming, connecting, deleting * and undo are all the graph's. */ export class StateMachineEditor extends AssetTabEditor { private readonly snap = new SnapToggle(() => this.canvas); constructor(state: EditorState) { super(state, { noun: 'State machine', infoWidth: INFO_WIDTH }); this.mount(new GraphCanvas(state, 'state machine'), this.snap.widgets); // Play swaps in the runtime copy of the project, and back. state.on('mode', () => this.refresh()); } protected override selectedId(): string { return this.state.selectedStateMachineId ?? ''; } protected override isMine(asset: Asset): asset is StateMachineAsset { return asset.type === 'statemachine'; } protected override infoText(asset: StateMachineAsset): string { const count = statesOf(asset.graph).length; return `${count} ${count === 1 ? 'state' : 'states'}`; } protected override syncExtras(asset: StateMachineAsset | null): void { this.snap.setEnabled(Boolean(asset)); } }