Search guides and the APICtrl K
  1. API reference
  2. Native GUI

gfx/containers.h

A list, a set of tabs, and a progress bar.

#include <sonore/gfx/containers.h>
On this page

Design notes

Why these three

A ListBox is what a preset browser IS -- also a sample list, a modulation slot list, a device list. A synth with an oscillator page, a filter page and an envelope page is the ordinary shape of an instrument editor, and that is a TabbedComponent. And loading a sample library is the one thing a plugin does that takes long enough to need a progress bar.

The list is virtual

ListBox draws rows on demand from a model rather than owning a component per row. A preset browser with four thousand presets would otherwise build four thousand components, each with bounds and a paint method, to show twelve of them. Everything below the fold costs nothing here.

Types 3

class ListBox : public Widget

A scrolling list of rows, drawn on demand.

The model is two callbacks rather than a subclass to implement: how many rows there are, and how to draw one. A plugin's list is usually a vector it already has, and making it inherit from something to show that vector is ceremony with no payoff.

class TabbedComponent : public Widget

Pages behind a row of tabs.

The pages are NOT owned, for the same reason nothing else here owns its content: a plugin builds its panels as members and a container that took them over would decide a lifetime the plugin already decided.

class ProgressBar : public Widget

A bar that fills.

Reads its value through a pointer rather than being told, because the thing making progress is usually on another thread -- a sample library loading -- and a bar that had to be pushed at would need that thread to know about the UI. A value another thread writes is a std::atomic<double>; a plain double is for one written on the message thread, which is the thread that reads it.

↑↓ to move↵ to openEvery public name in the headers, and every guide