Control
Source:
Control.h
ControlDescriptor¶
src/core/Control.h:280Public Attributes¶
void * ptr = nullptr
const char * name = nullptr
uintptr_t aux = 0
ControlType type =
int32_t min = 0
int32_t max = 255
int32_t def = kNoDefault
bool hidden = false
bool persistLabel = false
bool readonly = false
bool advanced = false
bool numberField = false
bool fader = false
bool encoder = false
bool switchRow = false
bool displayStrip = false
bool live = false
const char * surfaceTarget = nullptr
bool(* validate = nullptr
Public Static Attributes¶
constexpr int32_t kNoDefault = INT32_MIN
ControlList¶
src/core/Control.h:397The set of controls a MoonModule exposes to the UI — a module's controls_.
Controls bind to a class variable by reference — the descriptor stores a pointer, hot-path code reads the variable directly (zero overhead, no getter/setter). The value lives in the class variable (1–4 bytes); the descriptor is just the metadata UI rendering and persistence need.
Memory footprint: the descriptor stays lean — a variable pointer, a flash name pointer, an aux word (Progress total / Select options), the type enum, the int32 min/max, two UI flag bytes, and an optional validate hook (~48 bytes on a 64-bit host, less on ESP32's 32-bit pointers). Descriptors live in a fixed-capacity per-module array — no per-control heap allocation. A module that overflows the default capacity is probably too complex.
Persistence and dynamic rebuild: control values persist via FilesystemModule, which overlays loaded values through each control's pointer during defineControls(). Calling defineControls() again at runtime (e.g. when a Select changes) clears and rebuilds the set, so only controls relevant to the current mode are shown — this is how conditional hidden flags re-evaluate.
The per-type storage/UI/DMX reference is on ControlType; each addX method below binds one type.
Prior art: MoonLight's addControl binds via reinterpret_cast<uintptr_t>(&variable) with UI types "slider"/"select"/"toggle"/"text"/"display" (https://github.com/ewowi/MoonLight/blob/main/src/MoonBase/Nodes.h#L80).
Public Methods¶
ControlList() = default
: Defaulted constructor.
ControlList(const ControlList &) = delete
: Deleted constructor.
ControlList(ControlList &&) = delete
: Deleted constructor.
inline void addControl(const char * name, uint8_t & var, uint8_t min = 0, uint8_t max = 255)
: Bind a member as a control.
inline void addControl(const char * name, uint16_t & var, uint16_t min = 0, uint16_t max = UINT16_MAX)
: Bind a uint16_t as a number input.
inline void addControl(const char * name, int16_t & var, int16_t min = INT16_MIN, int16_t max = INT16_MAX)
inline void addControl(const char * name, int32_t & var, int32_t min = INT32_MIN, int32_t max = INT32_MAX)
: Bind an int32_t where the value does not fit 16 bits.
void addControl(const char * name, int8_t & var, int16_t min = 0, int16_t max = 0) = delete
: An int8_t is NOT a control type here: it is either a GPIO (addPin, which PinsModule scans for to collect claimed pins) or telemetry (addReadOnlyInt, which needs a unit).
inline void addPin(const char * name, int8_t & var, int16_t min = -1, int16_t max = MM_MAX_GPIO)
inline void addControl(const char * name, bool & var)
: A toggle.
inline void addText(const char * name, char * var, uint16_t bufSize = 16, bool()(const char ) validate = nullptr)
inline void addTextArea(const char * name, char * var, uint16_t bufSize = 16, bool()(const char ) validate = nullptr)
inline void addFilePath(const char * name, char * var, uint16_t bufSize, const FilePathPick & pick, bool()(const char ) validate = nullptr)
inline void addFilePath(const char * name, char * var, uint16_t bufSize, bool()(const char ) validate = nullptr)
: A file-path control with no picker: an editor over one fixed path, so there is no directory to list and nothing to seed a new file with.
inline void addPassword(const char * name, char * var, uint8_t bufSize = 32)
inline void addReadOnly(const char * name, char * var, uint8_t bufSize = 32)
inline void addReadOnlyInt(const char * name, int8_t & var, const char * unit)
inline void addPalette(const char * name, uint8_t & var, PaletteOptionsFn optionsFn, uint8_t optionCount)
inline void addSelect(const char * name, uint8_t & var, const char *const * options, uint8_t optionCount)
inline void addProgress(const char * name, uint32_t & var, uint32_t total, bool bytes = true)
inline void addIPv4(const char * name, uint8_t * var)
inline void addList(const char * name, ListSource & source)
inline void addButton(const char * name)
inline void clear()
inline uint8_t count() const
inline const ControlDescriptor & operator[](uint8_t i) const
inline void setHidden(uint8_t i, bool hidden)
inline void setDefault(uint8_t i, int32_t def)
inline void setReadOnly(uint8_t i, bool readonly)
inline void setAdvanced(uint8_t i, bool advanced = true)
inline void setNumberField(uint8_t i, bool numberField = true)
inline void setPersistLabel(uint8_t i, bool persistLabel = true)
inline void setFader(uint8_t i, bool fader = true, const char * target = nullptr)
: Render this numeric control as a VERTICAL fader rather than a horizontal slider.
inline void setEncoder(uint8_t i, bool encoder = true, const char * target = nullptr)
: Render this numeric control as a ROTARY ENCODER: a knob, dragged vertically to turn.
inline void setSwitchRow(uint8_t i, bool switchRow = true, const char * target = nullptr)
: Render this boolean control in the horizontal SWITCH STRIP: a desk's channel buttons, sitting in the same columns as the encoders and faders below them.
inline void setDisplayStrip(uint8_t i, bool strip = true)
: Render this read-only text control as the surface's DISPLAY STRIP: a full-width alphanumeric readout, no label, in the segmented style the numeric readouts already use.
inline void setLive(uint8_t i, bool live = true)
: Declare a control as LIVE STATE rather than configuration: never persisted, never marks its module dirty.
ListSource¶
src/core/Control.h:181Public Methods¶
virtual uint8_t listRowCount() const
virtual void writeListRow(JsonSink & sink, uint8_t row) const
virtual inline void writeListRowDetail(JsonSink & sink, uint8_t row) const
virtual inline void writeListOptionSets(JsonSink &) const
virtual inline bool restoreList(const char , const char )
virtual inline bool persistsList() const
virtual inline bool isEditableList() const
virtual inline bool listAsPads() const
virtual inline uint8_t listGridCols() const
virtual inline uint8_t listGridRows() const
virtual inline bool addListRow(uint32_t &)
virtual inline bool deleteListRow(uint32_t)
virtual inline bool moveListRow(uint32_t, uint8_t)
virtual inline bool setListRowField(uint32_t, const char , const char )