import { masterRoutingProblems } from '../../core/music/projectRouting'; import { ROUTING_ID } from '../../core/model/Project'; import { Button, Label, Spacer, VStack } from '../../ui'; import { GraphCanvas } from '../graph/GraphCanvas'; import { GRAPH_SNAPS_AT_FIRST, SnapToggle } from '../graph/SnapToggle'; import type { EditorState } from '../state'; import { TabHeader } from '../TabHeader'; const INFO_WIDTH = 220; /** * The Master routing tab (#351), one per project: a node per sound, instrument, pattern, song, video * with sound, composition and bus and the master, the links between them where each one goes. * Edited as the routing of a song is (#350); a click on a node shows its asset in the inspector, a * double click opens it. */ export class RoutingEditor extends VStack { readonly canvas: GraphCanvas; readonly fitButton: Button; readonly snap: SnapToggle; private readonly info = new Label('', { style: 'small', align: 'right' }); constructor(private readonly state: EditorState) { super(); this.canvas = new GraphCanvas(state, 'routing'); this.snap = new SnapToggle(() => this.canvas, GRAPH_SNAPS_AT_FIRST); this.fitButton = new Button('Fit', { onClick: () => this.canvas.fit() }); this.info.minWidth = INFO_WIDTH; const header = new TabHeader(); for (const widget of this.snap.widgets) header.add(widget); header.add(this.fitButton); header.add(new Spacer(), 1); header.add(this.info); this.add(header); this.add(this.canvas, 1); state.on('project', () => this.refresh()); state.on('load', () => this.close()); } /** Shows the routing of the project; framed the first time, as it was left after that. */ open(): void { this.canvas.show(ROUTING_ID); this.refresh(); } /** The tab is closed: opened again, the routing starts from a fitted view. */ close(): void { this.canvas.show(''); this.refresh(); } /** The readout: how many links, and how many nodes go nowhere and are never heard. */ get shownInfo(): string { return this.info.text; } private refresh(): void { if (this.canvas.currentAssetId !== ROUTING_ID) return this.info.setText(''); const graph = this.state.project.routing; const silent = Object.keys(masterRoutingProblems(graph)).length; const links = `${graph.edges.length} link${graph.edges.length === 1 ? '' : 's'}`; this.info.setText(silent > 0 ? `${links} ยท ${silent} going nowhere` : links); } }