Skip to content
ModernUI A DaneTrades developer library

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:

Pseudo-code
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

UI build fragment
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

UI build fragment
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

UI build fragment
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

UI build fragment
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).

UI build fragment
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

UI build fragment
MuiSection s = Mui::Section(parent, title, subtitle="", fullWidth=true);

Returns: MuiSectionpanel, 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

UI build fragment
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

UI build fragment
MuiLabeledField f = Mui::LabeledField(parent, label, control, hint="");

Compose a control created with parent == NULL:

UI build fragment
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

UI build fragment
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: controlMuiSpinEditHost*. Events: MUI_EVENT_VALUE_CHANGED with .Id on control.

Mui::ActionLabeledSpinEdit — same args plus MuiActionSink* + action id (legacy).

Mui::LabeledCombo

UI build fragment
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

UI build fragment
MuiButtonRow row = Mui::ButtonRow(parent, labels[], buttonWidth=0.0, buttonHeight=0.0, fullWidth=true);
Argument Purpose
labels[] One button per label.
buttonWidth 0.0MuiFastWrapDefaultButtonWidth().
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.

Reference excerpt
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

UI build fragment
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 want MUI_EVENT_CLICK (internal pick handler runs first).
  • Read state: grp.Selected() or grp.model.selected after 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

UI build fragment
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

UI build fragment
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

UI build fragment
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

UI build fragment
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 MuiToastServiceno 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.
UI build fragment
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

UI build fragment
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);
Reference excerpt
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