Skip to content

Control

Source: Control.h

ControlDescriptor

struct ControlDescriptor
src/core/Control.h:280

Public 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

class ControlList
src/core/Control.h:397

The 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

struct ListSource
src/core/Control.h:181

Public 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 )