Factory helpers (reference)
Factory helpers live in Factory/Factory.mqh (included via ModernUI.mqh). Mui::... is the preferred surface for EA panels; MuiCreate::... is the lower-level surface when you need explicit x, y, w, h placement (especially on MuiAbsolutePanel).
Source of truth: Include/ModernUI/Factory/Factory.mqh.
Helper Groups
| Helper group | Use it for | Emits events |
|---|---|---|
MuiCreate::... |
Raw controls with explicit bounds; attaches when parent != NULL. |
Through returned controls after .Id(...) |
Mui::... |
Friendly creation, layout stacks, charts, overlays, toasts. | Through returned controls after .Id(...) |
| Fast wrapper structs | Multi-control bundles (MuiAppWindow, MuiSection, MuiLabeledSpinEdit, …). |
Through .control / contained widgets |
MuiActionSink / Action* helpers |
Legacy callback wiring. | Handler callbacks — prefer event bus for new panels |
Conventions
| Rule | Detail |
|---|---|
| Parent first | Most helpers take MuiContainer *parent first; parent == NULL creates detached controls (for LabeledField wrapping). |
Width / height 0.0 |
Usually means “use theme default” (button height, input height, table size). |
Handler NULL |
Pass NULL on button/slider/spin helpers when using the event bus with .Id(...). |
| Ownership | When parent != NULL, the helper calls parent.Add(child) — the parent owns the control. |
| Wrappers | Struct fields point at real controls; keep the struct (or source) alive while you edit data. |
Deeper conventions: Factory helpers guide. Struct field reference: Fast wrapper types.
Main Rule
Factory helpers build the UI; events still come from the underlying control after you assign .Id(...) ≥ 0 and handle OnMuiEvent(...). Non-interactive helpers (toasts, layout-only wrappers) do not add bus events by themselves.
MuiCreate (lower-level)
MuiCreate returns raw control pointers and applies bounds via ApplyBounds + Margin (for absolute canvases). Signature pattern:
Control(parent, x, y, w, h, …payload…)
| Helper | Returns | Notes |
|---|---|---|
Attach(parent, child) |
void |
Adds an existing element. |
ApplyBounds(el, x, y, w, h) |
void |
Sets margin-as-position + fixed size. |
AbsoluteCanvas(parent, w, h) |
MuiAbsolutePanel* |
Absolute layout host. |
Label, Badge, Icon, Swatch |
display types | Explicit rectangle. |
ProgressBar, Card, StatCard |
display types | Explicit rectangle. |
Button, IconButton |
MuiButton* |
Base button (use Mui::Button for MuiButtonAction). |
Checkbox, Toggle, RadioGroup, Slider |
input types | Bounds + state in helper args. |
TextBox, TextArea, SpinEdit, ComboBox |
host types | Native hosts. |
DatePicker, ColorPicker |
picker types | |
SimpleTableSource, AddTableRow |
data | In-memory table source helpers. |
Table, ListView, TreeView |
data views | Requires a source for list/tree/table. |
Tabs, Accordion, Toolbar |
navigation | |
StatusBar, Alert, LoadingSpinner |
feedback | |
Sparkline, LineChart, BarChart, DonutChart, HalfGaugeChart |
charts |
Use MuiCreate when you already use MuiCreate::AbsoluteCanvas or must place controls at pixel coordinates. For normal stacked panels, prefer Mui::....
Button helpers
All return MuiButtonAction* (creates MuiButtonAction, adds to parent when non-NULL). Variant helpers call Mui::Button then set Kind(...).
Mui::Button
MuiButtonAction *b = Mui::Button(parent, text, handler, width=160.0, height=0.0);
| Argument | Purpose |
|---|---|
parent |
Owner container (NULL = detached). |
text |
Button label. |
handler |
MuiClickHandler* or NULL for event bus. |
width |
Logical width (> 0 applies fixed width). |
height |
0.0 → theme ButtonHeight(). |
Creates: new MuiButtonAction, optional SetFixedSize, parent.Add.
Events: MUI_EVENT_CLICK when .Id(...) is set. See Buttons.
Mui::ButtonPrimary / ButtonGhost / ButtonDanger
Same signature as Button; sets Kind(MUI_BUTTON_PRIMARY | GHOST | DANGER).
Mui::ButtonIcon / ButtonIconAlign
Mui::ButtonIcon(parent, iconType, text, handler, width=170.0, height=0.0, iconArgb=0, iconSize=0);
Mui::ButtonIconAlign(parent, iconType, text, handler, align, ...);
iconType is MuiIconKind (e.g. MUI_ICON_SAVE). align: 0 = icon left, 1 = icon right.
Mui::IconButton
Mui::IconButton(parent, iconType, handler, size=0.0, iconArgb=0, iconSize=0);
Square icon-only button. size <= 0 → theme IconButtonSize().
Legacy Mui::ActionButton*
ActionButton, ActionButtonPrimary, etc. wire MuiActionClickHandler to a MuiActionSink. Prefer Button(..., NULL) + .Id(...) for new code.
Mui::AppWindow
MuiAppWindow app = Mui::AppWindow(root, title, x, y, width, height, scrollable=true);
| Argument | Purpose |
|---|---|
root |
MuiRoot — calls root.SetRoot(win). |
title |
Window title bar text. |
x, y, width, height |
Logical rect; min size clamped to 200×120. |
scrollable |
Maps to MuiWindow::OverflowScroll. |
Returns: MuiAppWindow with window (MuiWindow*) and content (MuiContainer* — same as win.Content()).
Creates: chart-hosted MuiWindow as application root.
Use when: starting a full panel EA (replaces manual SetRoot + body setup).
MuiAppWindow app = Mui::AppWindow(g_ui, "Trade panel", 20, 40, 720, 480, true);
MuiSection sec = Mui::Section(app.content, "Orders", "");
Events: none on the wrapper; children use normal control events.
Mui::Section and Mui::DrawerSection
Mui::Section
MuiSection s = Mui::Section(parent, title, subtitle="", fullWidth=true);
Returns: MuiSection — panel, title, subtitle (or NULL), body (column stack, spacing 10).
Creates: MuiPanel + heading labels + Mui::Divider + Mui::Column body.
Add form controls to s.body. parent == NULL → all-null struct (safe no-op).
Mui::DrawerSection
MuiSection s = Mui::DrawerSection(drawerBody, title, subtitle="");
Same as Section with tighter panel pad (10) and body spacing (8). Pass an existing drawer/column container — does not open a drawer.
Labeled field helpers
Mui::LabeledField
MuiLabeledField f = Mui::LabeledField(parent, label, control, hint="");
Compose a control created with parent == NULL:
MuiSpinEditHost *sp = Mui::SpinEdit(NULL, 0.1, 10.0, 1.0, 0.1, 2, NULL, 220.0, 0.0);
MuiLabeledField row = Mui::LabeledField(section.body, "Risk %", sp, "0.1 – 10.0");
sp.Id(APP_RISK);
Returns: root, label, control, hint.
Mui::LabeledSpinEdit
MuiLabeledSpinEdit row = Mui::LabeledSpinEdit(
parent, label,
minValue, maxValue, step, value,
digits=2,
width=0.0, height=0.0, hint="",
stepperFilled=true);
Creates: caption column + Mui::SpinEdit (handler NULL). Default width from MuiFastWrapDefaultSpinSliderWidth() when width <= 0.
Returns: control → MuiSpinEditHost*. Events: MUI_EVENT_VALUE_CHANGED with .Id on control.
Mui::ActionLabeledSpinEdit — same args plus MuiActionSink* + action id (legacy).
Mui::LabeledCombo
MuiLabeledCombo row = Mui::LabeledCombo(parent, label, items[], selected=0, width=0.0, height=0.0, hint="");
Creates: caption + Mui::ComboBox. Clamps selected to item count.
Events: MUI_EVENT_SELECTION_CHANGED on control.
Other Mui::Labeled* helpers
Same column pattern (caption + control + optional hint):
| Helper | control type |
|---|---|
LabeledTextBox |
MuiTextBoxHost* |
LabeledCheckbox |
MuiCheckbox* |
LabeledSlider |
MuiSlider* |
LabeledTextArea |
MuiTextAreaHost* |
LabeledDatePicker |
MuiDatePicker* |
LabeledColorPicker |
MuiColorPicker* |
See Inputs for per-control events.
Mui::ButtonRow
MuiButtonRow row = Mui::ButtonRow(parent, labels[], buttonWidth=0.0, buttonHeight=0.0, fullWidth=true);
| Argument | Purpose |
|---|---|
labels[] |
One button per label. |
buttonWidth |
0.0 → MuiFastWrapDefaultButtonWidth(). |
buttonHeight |
0.0 → theme button height. |
Creates: horizontal Mui::Row of Mui::Button(..., NULL, …) instances.
Returns: root, buttons[], Count(), Button(index).
Events: assign .Id(...) on each row.buttons[i] (or row.Button(i)) for MUI_EVENT_CLICK.
MuiButtonRow actions = Mui::ButtonRow(body, labels);
for(int i = 0; i < actions.Count(); i++)
{
MuiButtonAction *b = actions.Button(i);
if(b != NULL)
b.Id(PANEL_ACTION_ROW0 + i);
}
Mui::ButtonGroup
MuiButtonGroup grp = Mui::ButtonGroup(parent, labels[], selected=0, buttonWidth=0.0, buttonHeight=0.0, fullWidth=true);
Creates: segmented row; each button owns a MuiButtonGroupPickHandler that updates shared MuiButtonGroupModel (primary vs default Kind).
Returns: root, buttons[], model, Selected() / Selected(idx).
Events:
- Event bus: still assign
.Id(...)per button if you wantMUI_EVENT_CLICK(internal pick handler runs first). - Read state:
grp.Selected()orgrp.model.selectedafter a click.
Note: model is heap-allocated (new MuiButtonGroupModel); not destroyed with the row — delete manually only if you need strict teardown symmetry (see source comment).
Data wrappers
Mui::SimpleTable
MuiSimpleTable t = Mui::SimpleTable(parent, headers[], rows, width=0.0, height=0.0, scrollable=true, selectable=true);
Creates: MuiSimpleTableSource (columns from headers[], rows blank rows), Mui::TableView bound to source.
Returns: table, source, SetCell, Cell, SetRow, Clear, Refresh.
Ownership: view does not own source — keep t or t.source while editing. See Data views.
Mui::ListBox
MuiListBox lb = Mui::ListBox(parent, items[], selected=-1, width=0.0, height=0.0);
Creates: MuiStringArrayItemSource + MuiListView. selected == -1 clears selection.
Returns: list, source, SetItem, Item, Refresh.
Mui::TabsFromNames
MuiTabsBundle tabs = Mui::TabsFromNames(parent, names[], selected=0);
Creates: MuiTabs with one MuiPanel body per name. Returns: tabs, bodies[], Body(i), Selected() / Selected(root, index).
Events: MUI_EVENT_TAB_CHANGED on tabs.tabs with .Id(...).
Mui::StatusRow
MuiStatusRow r = Mui::StatusRow(parent, label, value, variant="neutral");
Creates: caption label (flex 1) + value MuiBadge. Variant strings: neutral, success, warning, danger, error (→ danger), info, primary.
Returns: root, label, badge. Events: none.
Toast helpers
All route through MuiToastService — no control pointer, no bus events.
| Helper | Purpose |
|---|---|
Toast(root, message, durationMs=2200, corner, marginLogical) |
Plain toast; default corner bottom-right. |
ToastSuccess / ToastWarning / ToastError |
Semantic tone; default 2500 ms. |
ToastTL / ToastTR / ToastBL / ToastBR |
Corner shortcuts. |
ToastMargin(logicalPx) |
Global margin for anchored toasts. |
Mui::ToastSuccess(g_ui, "Settings saved.");
See Overlays for modal/dialog helpers (Confirm, ModalAlert, Drawer, …).
Config structs (advanced creation)
Used with config-based MuiCreate / Mui overloads where present:
| Struct | Fields (high level) |
|---|---|
MuiSpinEditConfig |
x, y, w, h, minValue, maxValue, step, value, digits |
MuiSliderConfig |
x, y, w, h, minValue, maxValue, value, vertical |
MuiTableConfig |
x, y, w, h, scrollable, showGrid, rowHeight, headerHeight |
Prefer typed Mui::LabeledSpinEdit / Mui::Slider helpers unless you are generating absolute layouts.
Other Mui:: helpers (index)
Grouped by category page — signatures follow parent → content → size unless noted.
| Group | Examples | Reference |
|---|---|---|
| Layout | Row, Column, WrapRow, Grid, Panel, Scroll, Window, FormRow, Splitter, Spacer, Divider, AlignBox, AbsoluteCanvas |
Layout |
| Display | Label, CaptionLabel, Badge, Icon, Progress, Card, StatCard, StatusRow, HoverRow |
Display |
| Inputs | TextBox, TextArea, SpinEdit, ComboBox, Checkbox, Toggle, Slider, RadioGroup, DatePicker, ColorPicker |
Inputs |
| Navigation | Tabs, TabsWithSegmentDividers, Accordion, Dropdown |
Navigation |
| Data | ListView, TableView, TreeView, ListBox, SimpleTable |
Data views |
| Charts | Sparkline, LineChart, BarChart, Donut, HalfGauge, *Grid |
Charts |
| Window chrome | PinHeaderToWindowTop, PinStatusBarToWindowBottom, WindowFrameRadiusCap |
Layout |
| Theme | SetDense(root) |
Themes and tokens |
Example: panel shell + labeled input + button row
MuiAppWindow app = Mui::AppWindow(g_ui, "Risk panel", 24, 48, 420, 360, true);
MuiSection sec = Mui::Section(app.content, "Sizing", "Per-trade limits");
MuiLabeledSpinEdit risk = Mui::LabeledSpinEdit(sec.body, "Risk %", 0.1, 5.0, 0.1, 1.0);
if(risk.control != NULL)
risk.control.Id(APP_RISK);
string actions[] = {"Apply", "Reset"};
MuiButtonRow row = Mui::ButtonRow(sec.body, actions);
if(row.Button(0) != NULL)
row.Button(0).Id(APP_APPLY);
if(row.Button(1) != NULL)
row.Button(1).Id(APP_RESET);
void OnMuiEvent(MuiRoot &root, const MuiEventData &event)
{
if(event.EventId() == MUI_EVENT_VALUE_CHANGED && event.ControlId() == APP_RISK)
{
// read spin via your stored pointer or lookup
}
if(event.EventId() == MUI_EVENT_CLICK && event.ControlId() == APP_APPLY)
Mui::ToastSuccess(root, "Applied.");
}
Related Pages
- Factory helpers guide — conventions and mistakes
- Fast wrapper types — struct fields in one place
- Event Bus
- Controls reference
- Buttons