UIModule Enhancements: - Add ui:set_text topic handler to update widget text dynamically (UILabel support) - Add example: slider value updates linked label via game module coordination - Add timestamp logging for IIO latency measurement (T0-T3 tracking) Documentation Restructure: - Split UIModule README.md (600+ lines) into focused docs: * docs/UI_WIDGETS.md - Widget properties and JSON configuration * docs/UI_TOPICS.md - IIO topics reference and usage patterns * docs/UI_ARCHITECTURE.md - Threading model, limitations, design principles - Update CLAUDE.md with clear references to UIModule docs - Add warning: "READ BEFORE WORKING ON UI" for essential docs Asset Path Fixes: - Change test_ui_showcase texture paths from ../../assets to assets/ - Tests now run from project root (./build/tests/test_ui_showcase) - Add texture loading success/failure logs to TextureLoader and ResourceCache IIO Performance: - Re-enable batch flush thread in IntraIOManager (was disabled for debugging) - Document message latency: ~16ms in single-threaded tests, <1ms with threading - Clarify intentional architecture: no direct data binding, all via IIO topics Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6.9 KiB
6.9 KiB
UIModule - Widget Reference
Complete reference for all available widgets and their properties.
Widget Overview
| Widget | Purpose | Events |
|---|---|---|
| UIButton | Clickable button | ui:click, ui:action |
| UILabel | Static/dynamic text | - |
| UIPanel | Container widget | - |
| UICheckbox | Toggle checkbox | ui:value_changed |
| UISlider | Value slider | ui:value_changed |
| UITextInput | Text entry field | ui:value_changed, ui:text_submitted |
| UIProgressBar | Progress indicator | - |
| UIImage | Sprite/texture display | - |
| UIScrollPanel | Scrollable container | ui:scroll |
| UITooltip | Hover tooltip | - |
Common Properties
All widgets support these base properties:
{
"type": "WidgetType",
"id": "unique_id",
"x": 0,
"y": 0,
"width": 100,
"height": 100,
"visible": true,
"tooltip": "Optional tooltip text"
}
UIButton
Clickable button with hover/press states.
{
"type": "button",
"id": "my_button",
"x": 100,
"y": 100,
"width": 200,
"height": 50,
"text": "Click Me",
"onClick": "button_action",
"style": {
"normal": {
"bgColor": "0x0984e3FF",
"textColor": "0xFFFFFFFF",
"textureId": 0
},
"hover": {
"bgColor": "0x74b9ffFF",
"textColor": "0xFFFFFFFF"
},
"pressed": {
"bgColor": "0x0652a1FF",
"textColor": "0xFFFFFFFF"
}
}
}
Properties:
text- Button label textonClick- Action name published toui:actionstyle- Visual states (normal, hover, pressed)bgColor- Background color (hex RGBA)textColor- Text color (hex RGBA)textureId- Sprite texture ID (0 = solid color)
Events:
ui:click-{widgetId, x, y}ui:action-{widgetId, action}where action = onClick value
UILabel
Static or dynamic text display.
{
"type": "label",
"id": "my_label",
"x": 100,
"y": 100,
"width": 300,
"height": 50,
"text": "Hello World",
"style": {
"fontSize": 24,
"color": "0xFFFFFFFF"
}
}
Properties:
text- Label text (can be updated viaui:set_text)style.fontSize- Font size in pixelsstyle.color- Text color (hex RGBA)
Dynamic Updates:
auto msg = std::make_unique<JsonDataNode>("set_text");
msg->setString("id", "my_label");
msg->setString("text", "New Text");
m_io->publish("ui:set_text", std::move(msg));
UIPanel
Container widget with background color.
{
"type": "panel",
"id": "my_panel",
"x": 0,
"y": 0,
"width": 400,
"height": 300,
"style": {
"bgColor": "0x2d3436FF"
}
}
Properties:
style.bgColor- Background color (hex RGBA, use0x00000000for transparent)
UICheckbox
Toggle checkbox with check state.
{
"type": "checkbox",
"id": "enable_vsync",
"x": 100,
"y": 100,
"width": 24,
"height": 24,
"checked": true,
"text": "Enable VSync"
}
Properties:
checked- Initial checked statetext- Optional label text next to checkbox
Events:
ui:value_changed-{widgetId, checked}
UISlider
Horizontal or vertical value slider.
{
"type": "slider",
"id": "volume_slider",
"x": 100,
"y": 100,
"width": 300,
"height": 24,
"min": 0.0,
"max": 100.0,
"value": 50.0,
"orientation": "horizontal"
}
Properties:
min- Minimum valuemax- Maximum valuevalue- Current valueorientation- "horizontal" or "vertical"
Events:
ui:value_changed-{widgetId, value, min, max}
UITextInput
Text entry field with cursor and focus state.
{
"type": "textinput",
"id": "player_name",
"x": 100,
"y": 100,
"width": 300,
"height": 40,
"text": "",
"placeholder": "Enter name...",
"maxLength": 32,
"style": {
"fontSize": 20,
"textColor": "0xFFFFFFFF",
"bgColor": "0x34495eFF",
"borderColor": "0x666666FF"
}
}
Properties:
text- Initial textplaceholder- Placeholder text when emptymaxLength- Maximum character limitstyle.fontSize- Font sizestyle.textColor- Text colorstyle.bgColor- Background colorstyle.borderColor- Border color (changes to blue when focused)
Events:
ui:value_changed-{widgetId, text}- on each character changeui:text_submitted-{widgetId, text}- on Enter key
UIProgressBar
Progress indicator (0.0 to 1.0).
{
"type": "progressbar",
"id": "loading_bar",
"x": 100,
"y": 100,
"width": 400,
"height": 30,
"value": 0.65,
"style": {
"bgColor": "0x34495eFF",
"fillColor": "0x2ecc71FF"
}
}
Properties:
value- Progress value (0.0 = empty, 1.0 = full)style.bgColor- Background colorstyle.fillColor- Fill color
Dynamic Updates:
auto msg = std::make_unique<JsonDataNode>("set_value");
msg->setString("id", "loading_bar");
msg->setDouble("value", 0.75); // 75%
m_io->publish("ui:set_value", std::move(msg));
UIImage
Display a sprite/texture.
{
"type": "image",
"id": "logo",
"x": 100,
"y": 100,
"width": 200,
"height": 200,
"textureId": 5
}
Properties:
textureId- Texture ID from BgfxRenderer
UIScrollPanel
Scrollable container with vertical scrollbar.
{
"type": "scrollpanel",
"id": "inventory_panel",
"x": 100,
"y": 100,
"width": 400,
"height": 600,
"contentHeight": 1200,
"scrollY": 0.0,
"scrollbarWidth": 20,
"style": {
"bgColor": "0x2d3436FF"
}
}
Properties:
contentHeight- Total height of scrollable contentscrollY- Initial scroll position (0.0 = top)scrollbarWidth- Width of scrollbar in pixelsstyle.bgColor- Background color
Events:
ui:scroll-{widgetId, scrollY}
UITooltip
Hover tooltip (managed automatically by UIModule).
{
"type": "tooltip",
"id": "help_tooltip",
"x": 100,
"y": 100,
"width": 200,
"height": 60,
"text": "This is a helpful tooltip",
"visible": false,
"style": {
"fontSize": 14,
"bgColor": "0x2c3e50FF",
"textColor": "0xFFFFFFFF"
}
}
Note: Tooltips are automatically shown when tooltip property is set on any widget:
{
"type": "button",
"id": "save_button",
"tooltip": "Save your progress",
...
}
Creating Custom Widgets
- Create
Widgets/MyWidget.h/.cpp - Inherit from
UIWidget - Implement required methods:
class MyWidget : public UIWidget {
public:
void update(UIContext& ctx, float deltaTime) override;
void render(UIRenderer& renderer) override;
std::string getType() const override { return "mywidget"; }
// Event handlers
bool onMouseButton(int button, bool pressed, float x, float y) override;
void onMouseMove(float x, float y) override;
};
- Register in
UITree::createWidget():
if (type == "mywidget") {
auto widget = std::make_unique<MyWidget>();
// ... configure from JSON
return widget;
}
- Use in JSON layouts:
{
"type": "mywidget",
"id": "custom1",
...
}