Notes on Selection

Selection in GUI

Selecting a View that represents a Stripable in the editor does two things:

  1. the View is added to the GUI side selection model for that component (Editor/Mixer)
  2. the underlying Stripable (if any) has its PresentationInfo marked as selected
When the View is added to the GUI side selection model, it will have its ::set_selected() method called on it. This will eventually invoke AxisView::set_selected() (since all views are ultimately AxisViews). If the View represents a Stripable, then the Stripable will have its PresentationInfo member marked as selected. This will in turn cause the emission of PresentationInfo::PropertyChange for the affected Stripable, with the what_changed argument indicating a selection change. Individual views (GUI or control surface "strips") that want to track selection status for the Stripable that they represent will have registered a handler for this signal. The handler (or any other code) can check the selected status via the Stripable's PresentationInfo state.

After this, the View is actually added to the GUI side selection model. This process may add additional Views representing Stripables that share selection (e.g. via a RouteGroup) with the one initially being added. Note that ::set_selected() is not called on these Views, which would cause a recursive (and potentially expensive to halt) re-entrant loop. In all other ways, these Stripables' state will be modified as if ::set_selected() had been called.

Once adding all relevant Views is complete, Selection::TracksChanged is emitted. This signal will be handled by both the Editor and the Mixer component of the UI, to ensure that ::set_selected has been invoked all appropriate View objects in both components. This ensures that the Editor, Mixer and PresentationInfo models of selected state remain consistent.

Next ControlProtocol::StripableSelectionChanged will be emitted. All control surfaces that care about overall selection status have a handler for this signal. This handler will note the new set of selected Stripables and ensure that the surface's version of that (which might potentially only involve a single Stripable) is synchronized with it. A surface may opt not to use this signal but instead use the PresentationInfo::PropertyChange signal and other logic to maintain the surface support code's selection model.

Finally, the Editor will call ControlProtocol::set_first_selected_stripable() to ensure that any control surfaces can determine the first selected stripable. This matters for surfaces with only a single fader, for example.

If the selection process took place in the Mixer, the steps taken are more or identical with what is described above, except that AxisViewSelection::RoutesChanged is emitted and handled by the Editor to keep the two selection models in sync.

Note that the Editor's selection model contains many more object types than the Mixer's. The former may contain automation data, control points, track views, regions and more; the latter contains only axis views and processors.

Selection from a Control Surface

The code that supports a given surface/protocol should emit one of the following signals: ControlProtocol::{Add,Set,Toggle}StripableSelection. This signal will be handled by the Editor GUI component, which will then carry out a selection modification as if it were driven from Editor itself.

Note that surfaces should not set a Stripable's PresentationInfo selected status directly.

Object Deletion

The View object representing a Stripable is responsible for handling a DropReferences signal from the Stripable (indicating that it is about to be deleted). It needs to do this for many reasons, but one of them is so that it can remove itself from any Selection model that it may be a part of. So, for example, a RouteTimeAxisView representing a Stripable that has just sent DropReferences must ensure the the Editor's selection model no longer includes the RouteTimeAxisView. The same process applies to MixerStrips.

Control surface elements require similar handling of DropReferences, and are thus also responsible for ensuring the consistency of any local selection state in the control surface code for a given device/protocol.