Ember
Loading...
Searching...
No Matches
UI Components

Overview

EmberForge's user interface is built on a flexible panel and tab system that allows users to customize their workspace. This document explains the component hierarchy and how the pieces fit together.

Component Hierarchy

App (wxApp)
└── MainFrame (wxFrame)
├── wxAuiManager (docking system)
│ ├── LeftSidePanel
│ │ └── wxAuiNotebook
│ │ ├── FileExplorerTab
│ │ └── SceneHierarchyTab
│ ├── MainPanel (center)
│ │ └── SceneContainer
│ │ └── BehaviorTreeScene
│ │ └── TreeVisualization
│ ├── RightSidePanel
│ │ └── wxAuiNotebook
│ │ └── PropertiesTab
│ └── BottomPanel
│ └── wxAuiNotebook
│ └── LogTab
└── Menu/Toolbar

Panel System

IPanel Interface

All panels implement the IPanel interface:

class IPanel {
public:
virtual wxWindow* GetWindow() = 0;
virtual wxString GetTitle() const = 0;
virtual wxString GetPanelType() const = 0;
virtual void Refresh() = 0;
virtual void OnActivated() = 0;
virtual void OnDeactivated() = 0;
};
Interface for panel-based UI components in the application.
Definition IPanel.h:7
virtual wxString GetPanelType() const =0
Returns the panel type identifier.
virtual void Refresh()
Refreshes the panel content.
Definition IPanel.h:21
virtual void OnActivated()
Called when the panel becomes active.
Definition IPanel.h:23
virtual void OnDeactivated()
Called when the panel becomes inactive.
Definition IPanel.h:25
virtual wxString GetTitle() const =0
Returns the display title of the panel.

Panel Base Class

The Panel base class provides common functionality:

Method Purpose
CreateLayout() Set up panel UI (virtual)
ApplyTheme() Apply color theme
Refresh() Refresh panel content
Save() / Load() Serialize/deserialize state

SidePanel

SidePanel extends Panel for side dock panels with tab support:

class SidePanel : public Panel {
public:
int AddTab(ITabPtr tab);
void RemoveTab(int index);
ITabPtr GetTab(int index);
int GetActiveTabIndex();
void SetActiveTab(int index);
protected:
virtual void CreateToolbar();
virtual void CreateNotebook();
virtual bool ShouldShowToolbar() const;
};
std::unique_ptr< ITab > ITabPtr
Definition ITab.h:54
Panel(wxWindow *parent, const wxString &name="Panel", long style=wxTAB_TRAVERSAL)
Constructs the panel with optional name and style.
ITab * GetTab(int index) const
Returns the tab at the given index, or nullptr.
Definition SidePanel.cpp:96
bool SetActiveTab(int index) override
Sets the active tab by index; returns true on success.
void CreateNotebook() override
Hook: creates the notebook control. Override to customize.
Definition SidePanel.cpp:81
int AddTab(ITabPtr tab) override
Adds a tab and returns its index.
ITabPtr RemoveTab(int index) override
Removes the tab at the given index; returns the removed tab.

Concrete Panels

Panel Location Purpose
MainPanel Center Contains scene visualizations
LeftSidePanel Left dock File explorer, hierarchy
RightSidePanel Right dock Properties editor
BottomPanel Bottom dock Logs, output

Tab System

ITab Interface

Tabs are content components within panels:

class ITab {
public:
virtual wxWindow* GetWidget() = 0;
virtual wxString GetTitle() const = 0;
virtual wxString GetTabType() const = 0;
virtual wxBitmap GetIcon() const = 0;
virtual void Initialize() = 0;
virtual void Refresh() = 0;
virtual void OnActivated() = 0;
virtual void OnDeactivated() = 0;
virtual void OnClosed() = 0;
virtual bool IsValid() const = 0;
virtual bool CanClose() const = 0;
virtual bool CanMove() const = 0;
};
Interface for tab-based UI components in the application.
Definition ITab.h:7
virtual void OnDeactivated()
Called when the tab becomes inactive.
Definition ITab.h:27
virtual bool CanMove() const
Returns true if the tab can be moved/reordered.
Definition ITab.h:36
virtual bool CanClose() const
Returns true if the tab can be closed.
Definition ITab.h:34
virtual wxBitmap GetIcon() const
Returns the tab icon bitmap; defaults to null.
Definition ITab.h:18
virtual wxString GetTitle() const =0
Returns the display title of the tab.
virtual wxWindow * GetWidget()=0
Returns the wxWidgets window used as the tab content.
virtual void OnActivated()
Called when the tab becomes active.
Definition ITab.h:25
virtual void OnClosed()
Called when the tab is closed.
Definition ITab.h:29
virtual wxString GetTabType() const =0
Returns the tab type identifier.
virtual void Refresh()
Refreshes the tab content.
Definition ITab.h:23
virtual bool IsValid() const
Returns true if the tab is in a valid state.
Definition ITab.h:32
virtual void Initialize()
Called once when the tab is first created.
Definition ITab.h:21

Tab Implementations

Tab Purpose Features
FileExplorerTab Browse project files Tree/grid view, drag-drop, search
SceneHierarchyTab Navigate tree structure Node selection, expand/collapse
PropertiesTab Edit node properties Property grid, blackboard editing
LogTab Display log messages Filtering, search, virtual list
ToolTab Tool palette (Future: node creation tools)

TabFactory

Creates tabs by type name:

auto& factory = EmberForge::TabFactory::GetInstance();
// Create tab by type
auto tab = factory.CreateTab("FileExplorer", parentWindow);
// Get available types
auto types = factory.GetAvailableTabTypes();

TabContainer

Manages a collection of tabs:

class TabContainer {
public:
int AddTab(ITabPtr tab);
void RemoveTab(int index);
void CloseTab(int index);
ITabPtr GetTab(int index);
ITabPtr GetActiveTab();
void SetTabTitle(int index, const wxString& title);
void SetTabState(int index, TabState state);
// Callbacks
void SetTabActivatedCallback(Callback cb);
void SetTabClosedCallback(Callback cb);
};

Scene System

IScene Interface

Scenes are visual content areas in the MainPanel:

class IScene {
public:
virtual wxPanel* GetPanel() = 0;
virtual wxString GetTitle() const = 0;
virtual wxString GetSceneType() const = 0;
virtual void OnActivated() = 0;
virtual void OnDeactivated() = 0;
virtual void Refresh() = 0;
virtual bool HasUnsavedChanges() const = 0;
virtual bool Save() = 0;
};
Interface for scene-based UI components (e.g., views or screens).
Definition IScene.h:7
virtual bool HasUnsavedChanges() const
Returns true if the scene has unsaved changes.
Definition IScene.h:26
virtual void OnActivated()
Called when the scene becomes active.
Definition IScene.h:19
virtual wxString GetSceneType() const =0
Returns the scene type identifier.
virtual void Refresh()
Refreshes the scene content.
Definition IScene.h:23
virtual wxString GetTitle() const =0
Returns the display title of the scene.
virtual wxPanel * GetPanel()=0
Returns the wxPanel used as the scene content.
virtual bool Save()
Saves the scene content; returns true on success.
Definition IScene.h:28
virtual void OnDeactivated()
Called when the scene becomes inactive.
Definition IScene.h:21

BehaviorTreeScene

The primary scene type for visualizing behavior trees:

class BehaviorTreeScene : public IScene {
public:
// Set tree data
void SetBehaviorTree(std::shared_ptr<Node> root);
void SetTreeStructure(std::shared_ptr<ITreeStructure> tree);
// Selection
// Tree selector dropdown
void UpdateTreeSelector(const std::vector<std::string>& names,
const std::string& current);
void SetTreeSelectionCallback(TreeSelectionCallback cb);
};
Scene implementation for behavior tree visualization.
void SetNodeSelectionCallback(NodeSelectionCallback callback)
Set callback for node selection events.
void SetBehaviorTree(std::shared_ptr< EmberCore::Node > root)
Set the behavior tree for this scene using legacy Node interface.
std::function< void(EmberCore::ITreeNode *)> NodeSelectionCallback

SceneContainer

Manages multiple scenes with tabs:

class SceneContainer {
public:
int AddScene(std::unique_ptr<IScene> scene);
void RemoveScene(int index);
IScene* GetActiveScene();
// Scene lifecycle
void SuspendInactiveScenes();
void ResumeAllScenes();
// Callbacks
void SetSceneActivatedCallback(Callback cb);
void SetSceneDeactivatedCallback(Callback cb);
};

TreeVisualization

Canvas component for rendering behavior trees:

class TreeVisualization : public wxPanel {
public:
void SetTreeStructure(std::shared_ptr<ITreeStructure> tree);
// View control
void SetZoom(float zoom);
void CenterView();
void FitToWindow();
// Selection
void SelectNode(ITreeNode* node);
void ClearSelection();
// Configuration
void SetConfig(const VisualizationConfig& config);
};

Dialogs

Common Dialogs

Dialog Purpose
PreferencesDialog Application settings
ParserConfigDialog Parser profile configuration
BehaviorTreeProjectDialog Multi-file project management
ProjectManagerDialog Open/create projects
LoadingDialog Progress indicator

Dialog Pattern

Dialogs typically follow this pattern:

PreferencesDialog dlg(parentWindow);
if (dlg.ShowModal() == wxID_OK) {
// User confirmed, settings already applied
}
// Dialog automatically destroyed
Preferences dialog for configuring EmberForge application settings.

Event Flow

Node Selection

User clicks node in TreeVisualization
TreeVisualization::OnMouseDown()
NodeSelectionCallback invoked
MainFrame::OnNodeSelected()
├─► SceneHierarchyTab::SelectNode()
└─► PropertiesTab::SetSelectedNode()

File Open

User selects File > Open
MainFrame::OnFileOpen()
wxFileDialog for file selection
LibXMLBehaviorTreeParser::ParseFile()
MainFrame::LoadBehaviorTree()
├─► Create DirectTreeAdapter
├─► BehaviorTreeScene::SetTreeStructure()
└─► Update hierarchy and properties

Layout Management

EmberForge uses wxAuiManager for dockable panels:

// In MainFrame initialization
m_auiManager.SetManagedWindow(this);
// Add panels
m_auiManager.AddPane(m_leftPanel, wxAuiPaneInfo()
.Left()
.Caption("Explorer")
.MinSize(200, -1)
.BestSize(250, -1));
m_auiManager.AddPane(m_mainPanel, wxAuiPaneInfo()
.CenterPane()
.Caption("Scene"));
m_auiManager.Update();

Saving/Restoring Layout

// Save perspective
wxString layout = m_auiManager.SavePerspective();
prefs.SetString("window/layout", layout);
// Restore perspective
wxString layout = prefs.GetString("window/layout", "");
if (!layout.empty()) {
m_auiManager.LoadPerspective(layout);
}

Theming

Panels and tabs support theming through AppPreferences:

void Panel::ApplyTheme() {
auto& prefs = AppPreferencesManager::GetInstance();
wxColour bg = prefs.GetPanelBackgroundColor();
wxColour fg = prefs.GetPanelForegroundColor();
SetBackgroundColour(bg);
SetForegroundColour(fg);
Refresh();
}

See Also