Skip to content
ModernUI A DaneTrades developer library

Event Bus

The ModernUI event bus is the recommended way to handle normal EA UI actions.

Instead of writing one handler class for every button, checkbox, spin edit, table, tab, dialog, or drawer, you:

  1. make your panel class inherit MuiEventSink
  2. connect it with m_ui.SetEventSink(...)
  3. assign .Id(...) to interactive controls
  4. handle events in one typed OnMuiEvent(...) method

Basic Pattern

Reference excerpt
class CMyPanel : public MuiEventSink
  {
private:
   MuiRoot          m_ui;
   MuiButtonAction *m_bSave;

public:
   virtual void OnMuiEvent(MuiRoot &root,const MuiEventData &event);
  };

Connect the sink after root initialisation:

Reference excerpt
if(!m_ui.Init(ChartID(),0,"MyPanel_",512,16))
   return INIT_FAILED;

m_ui.SetEventSink((MuiEventSink*)GetPointer(this));

Create controls and assign IDs:

UI build fragment
m_bSave=Mui::ButtonPrimary(parent,"Save");
m_bSave.Id(APP_ACTION_SAVE);

Route events centrally:

Reference excerpt
void CMyPanel::OnMuiEvent(MuiRoot &root,const MuiEventData &event)
  {
   if(event.EventId()==MUI_EVENT_CLICK && event.ControlId()==APP_ACTION_SAVE)
      Save(root);
  }

Control IDs

A control only emits app-level events when it has a non-negative ID.

UI build fragment
m_bBuy.Id(TP_ACTION_BUY);
m_seRisk.Id(TP_ACTION_INPUT_CHANGED);
m_cbConfirm.Id(TP_ACTION_CONFIRM_TRADES);
m_tvPositions.Id(TP_ACTION_POSITIONS_TABLE);

Use enums instead of raw numbers.

Reference excerpt
enum TRADE_PANEL_ACTION
  {
   TP_ACTION_BUY,
   TP_ACTION_SELL,
   TP_ACTION_INPUT_CHANGED,
   TP_ACTION_CONFIRM_TRADES,
   TP_ACTION_POSITIONS_TABLE
  };

MuiEventData Fields

MuiEventData is the typed payload received by OnMuiEvent(...).

Field Meaning
event.EventId() Which event happened, such as MUI_EVENT_CLICK.
event.Sender() The control that emitted the event. Use when you need control-specific data.
event.Is(control) Convenience check for event.Sender()==control.
event.ControlId() The ID assigned with .Id(...). This is usually your main routing key.
event.Value() Numeric payload. Kept for compatibility and simple numeric controls.
event.Text() Text payload, such as button text, selected item text, column name, or result ID.
event.Index() New selected index, clicked item index, tab index, table column index, or action index.
event.OldIndex() Previous selected index for controls that track it.
event.Row() Table row or selected row.
event.Col() Table column.
event.Checked() Checkbox, toggle, or confirm boolean.
event.Expanded() Drawer or accordion expanded/open state.
event.Date() Selected date from a date picker.
event.Argb() Selected ARGB color or first button ARGB payload.
event.CommandId() Toolbar command ID.

Standard UI Events

These are the app-level events EA authors normally handle.

Event Emitted by Main fields
MUI_EVENT_CLICK Buttons and icon buttons ControlId(), Value(), Text(), Argb(), Sender()
MUI_EVENT_VALUE_CHANGED Spin edits and sliders ControlId(), Value(), Text()
MUI_EVENT_CHECK_CHANGED Checkboxes and toggles ControlId(), Checked(), Value(), Text()
MUI_EVENT_DIALOG_RESULT Dialog result buttons, close button, scrim dismiss when enabled ControlId(), Text()
MUI_EVENT_CONFIRM Confirm dialogs ControlId(), Checked(), Value()
MUI_EVENT_DRAWER_STATE Drawers ControlId(), Expanded(), Value()
MUI_EVENT_SELECTION_CHANGED List views, combo boxes, dropdown menus, radio groups, table selection, tree selection ControlId(), Index(), OldIndex(), Row(), Text()
MUI_EVENT_ITEM_CLICK Table rows and tree items ControlId(), Index(), Row(), Text()
MUI_EVENT_ITEM_DOUBLE_CLICK Tree items ControlId(), Index(), Text()
MUI_EVENT_TABLE_CELL_CLICK Table cells ControlId(), Row(), Col(), Text()
MUI_EVENT_TABLE_CELL_DOUBLE_CLICK Table cells ControlId(), Row(), Col(), Text()
MUI_EVENT_TABLE_HEADER_CLICK Table headers ControlId(), Index(), Col(), Text()
MUI_EVENT_EXPANDED_CHANGED Accordions and tree expand/collapse ControlId(), Index(), Expanded(), Text()
MUI_EVENT_TAB_CHANGED Tabs ControlId(), Index(), OldIndex(), Text()
MUI_EVENT_DATE_CHANGED Date picker ControlId(), Date(), Value(), Text()
MUI_EVENT_COLOR_CHANGED Color picker committed value ControlId(), Argb(), Value()
MUI_EVENT_COLOR_PREVIEW_CHANGED Color picker preview while editing ControlId(), Argb(), Value()
MUI_EVENT_TOOLBAR_COMMAND Toolbar buttons ControlId(), CommandId(), Value(), Text()
MUI_EVENT_MENU_ITEM Context menu item picks ControlId(), Index(), Text()
MUI_EVENT_ALERT_ACTION Alert banner action button ControlId(), Text()
MUI_EVENT_ALERT_DISMISSED Alert banner dismiss button ControlId(), Text()
MUI_EVENT_CARD_ACTION Card header action icons ControlId(), Index(), Text(), Argb()

Controls reference by event

Event Detailed control docs
MUI_EVENT_CLICK Buttons
MUI_EVENT_VALUE_CHANGED Spin edit, Slider
MUI_EVENT_CHECK_CHANGED Checkbox, Toggle
MUI_EVENT_SELECTION_CHANGED Combo, Radio, List, Table, Tree, Dropdown
MUI_EVENT_ITEM_CLICK / ITEM_DOUBLE_CLICK Table, Tree
MUI_EVENT_TABLE_* Table view
MUI_EVENT_TAB_CHANGED Tabs
MUI_EVENT_EXPANDED_CHANGED Accordion, Tree
MUI_EVENT_DIALOG_RESULT / CONFIRM Dialog, Modal
MUI_EVENT_DRAWER_STATE Drawer
MUI_EVENT_DATE_CHANGED / COLOR_* Date picker, Color picker
MUI_EVENT_TOOLBAR_COMMAND Toolbar
MUI_EVENT_MENU_ITEM Menu, Context menu
MUI_EVENT_ALERT_* Alert banner
MUI_EVENT_CARD_ACTION Card

Low-level pointer and keyboard events such as MUI_EVENT_MOUSE_MOVE, MUI_EVENT_MOUSE_DOWN, MUI_EVENT_KEY_DOWN, and MUI_EVENT_WHEEL are internal router events. Normal EAs should usually handle the app-level events above instead.

Common Routing Examples

Button clicks:

Reference excerpt
if(event.EventId()==MUI_EVENT_CLICK)
  {
   if(event.ControlId()==TP_ACTION_BUY)
      OnBuy(root);
   else if(event.ControlId()==TP_ACTION_SELL)
      OnSell(root);
   return;
  }

Spin edits and sliders:

Reference excerpt
if(event.EventId()==MUI_EVENT_VALUE_CHANGED && event.ControlId()==TP_ACTION_RISK)
  {
   m_riskPct=event.Value();
   Recalculate();
   root.RefreshAll();
   return;
  }

Checkboxes and toggles:

Reference excerpt
if(event.EventId()==MUI_EVENT_CHECK_CHANGED && event.ControlId()==TP_ACTION_CONFIRM_TRADES)
  {
   m_confirmBeforeTrade=event.Checked();
   return;
  }

List, combo, dropdown, and radio selection:

Reference excerpt
if(event.EventId()==MUI_EVENT_SELECTION_CHANGED && event.ControlId()==APP_ACTION_PROFILE)
  {
   m_profileIndex=event.Index();
   m_profileName=event.Text();
   root.RefreshAll();
   return;
  }

Table interaction:

Reference excerpt
if(event.EventId()==MUI_EVENT_TABLE_CELL_CLICK && event.ControlId()==APP_ACTION_POSITIONS)
  {
   int row=event.Row();
   int col=event.Col();
   string cellText=event.Text();
   InspectCell(row,col,cellText);
   return;
  }

Tabs:

Reference excerpt
if(event.EventId()==MUI_EVENT_TAB_CHANGED && event.ControlId()==APP_ACTION_MAIN_TABS)
  {
   m_activeTab=event.Index();
   AddLog("Tab: "+event.Text());
   return;
  }

Dialogs and confirms:

Reference excerpt
if(event.EventId()==MUI_EVENT_DIALOG_RESULT && event.ControlId()==APP_ACTION_CONFIRM_CLOSE)
   AddLog("Dialog result: "+event.Text());

if(event.EventId()==MUI_EVENT_CONFIRM && event.ControlId()==APP_ACTION_CONFIRM_CLOSE)
  {
   if(event.Checked())
      ClosePosition();
   return;
  }

Drawers and accordions:

Reference excerpt
if(event.EventId()==MUI_EVENT_DRAWER_STATE && event.ControlId()==APP_ACTION_SETTINGS_DRAWER)
   AddLog(event.Expanded() ? "Settings opened" : "Settings closed");

if(event.EventId()==MUI_EVENT_EXPANDED_CHANGED && event.ControlId()==APP_ACTION_FILTERS)
   AddLog(event.Text()+" expanded="+(event.Expanded() ? "true" : "false"));

Color picker:

Reference excerpt
if(event.EventId()==MUI_EVENT_COLOR_CHANGED && event.ControlId()==APP_ACTION_ACCENT)
  {
   ApplyAccent(event.Argb());
   root.RefreshAll();
   return;
  }

Toolbar commands:

Reference excerpt
if(event.EventId()==MUI_EVENT_TOOLBAR_COMMAND)
  {
   if(event.CommandId()=="refresh")
      RefreshData(root);
   else if(event.CommandId()=="export")
      ExportSnapshot(root);
   return;
  }

Button Payloads

Buttons can carry a numeric payload with UserValue(...).

UI build fragment
MuiButtonAction *bRisk1=Mui::Button(parent,"1%");
bRisk1.Id(TP_ACTION_RISK_PRESET);
bRisk1.UserValue(1.0);

Read it with event.Value():

Reference excerpt
if(event.EventId()==MUI_EVENT_CLICK && event.ControlId()==TP_ACTION_RISK_PRESET)
   SetRisk(event.Value());

Buttons can also carry two ARGB values with UserArgb(...).

UI build fragment
MuiButtonAction *bBlue=Mui::Button(parent,"Blue");
bBlue.Id(TP_ACTION_ACCENT);
bBlue.UserArgb(0xFF2F6FED,0xFF3AA0FF);

event.Argb() contains the first ARGB value. Use event.Sender() when you need both:

Reference excerpt
if(event.EventId()==MUI_EVENT_CLICK && event.ControlId()==TP_ACTION_ACCENT)
  {
   MuiElement *sender=event.Sender();
   if(sender!=NULL)
      ApplyAccent(sender.UserArgb1(),sender.UserArgb2());
  }

Event Bus vs Low-Level Handlers

Use the event bus for normal EA code.

Low-level handlers still exist for advanced library work, custom reusable controls, and compatibility with older examples. They are no longer the recommended first pattern for application-level EA panels.

Related Pages