NodeView

The tracker's node editor: the signal-flow half, over a shared canvas.

Declared in src/libs/libbahn/bahn/tracker/ui/NodeView.hpp
Inherits QWidget
Group bahn

Detailed description

construct-project-space P13, §PSU-6. The interaction — drag, pan, zoom, lasso, selection, menus, shortcuts — moved to widgets::graph::GraphCanvas in libwidgets. What is left here is what is genuinely bahn's: the processor catalogue, the node and connection menus, the floating parameter windows, the scope, and the line solver.

Why this CONTAINS the canvas instead of being one

NodeView is a promoted custom widget in Bahn.ui (<widget class="NodeView" name="pageNodes">, with a <customwidget> header at :535-538), and Bahn.cpp connects to its navigate and updatePatterns signals. Composition keeps that class name, that header path and those signals exactly as they were, so neither .ui file nor Bahn.cpp changes at all.

The spec's task list said to move the widget and update Bahn.ui's promoted widget and header. Composition makes that unnecessary, which is a smaller and safer change than the one that was planned: a wrong <customwidget> header does not fail at the edit, it fails later as uic emitting an include for a file that is not there.

Ids, not pointers

The canvas speaks in IGraphHost::Id. mHost maps those to QSharedPointer<bahn::Node> and never reuses a value, so a stale id in a selection resolves to nothing rather than to whichever node was allocated at that address next.

Member function documentation

closeParameterViews

void NodeView::closeParameterViews()

Close every open node parameter window.

These are created parentless so they can float, which makes each one a top-level window, and Qt keeps the application alive while any top-level window is visible. Closing the main window therefore left them open and the process never exited.

This cannot live in closeEvent(): NodeView is a CHILD widget, and Qt delivers QCloseEvent only to top-level windows, so that handler never fired. The owner of the shell has to call this once the user has confirmed the close.

getsATrack

[static slot] bool NodeView::getsATrack(const media::graph::ProcessorCharacter &characteristics)

Does a node of this kind get a sequencer track when it is added?

Returns true when the processor that characteristics describes produces sound or outputs sound from the app, and false otherwise.

Two kinds do, in the owner's words (2026-10-02): a node that PRODUCES sound — a source, with no input — and a node that OUTPUTS sound from the app — an Output node, an intrinsic sink.

The rule used to be "gives output". That gave every effect a track, a Delay or a Filter, and gave the Output node none, because an Output node gives no output to another node. An effect still gets a column when a person asks for one with Add Track.

In this section