Table of contents
1. Setting up the WindowManager
Create a WindowManager in your application entry point, passing only the RenderingWindow it draws into. The manager subscribes to the engine process and input events automatically, creates the default style, and uses a font embedded in the library:
int lysaMain() {
lysa::ContextConfiguration contextConfiguration { };
lysa::Lysa
lysa(contextConfiguration);
MainWindow window;
auto scene = std::make_unique<nodes::GameScene>(windowManager);
scene->attach(window);
lysa::ctx().events.subscribe(lysa::MainLoopEvent::PROCESS,
[&](const lysa::Event&) {
window.getRenderTarget().render();
});
return 0;
}
The defaults are read by every Window that does not set its own, and changing one refreshes all of them:
windowManager.setDefaultFontScale(0.25f);
auto font = std::make_shared<lysa::Font>(
"app://res/fonts/Signwood");
windowManager.setDefaultFont(
font);
windowManager.getDefaultStyle().setOption("color_text", "1.0,1.0,1.0,1.0");
2. Creating a UI Window
A Window is a virtual overlay panel managed by WindowManager. Create one with a rectangle and configure its style and root widget before adding child widgets:
const auto uiWindow = windowManager.create(lysa::RECT_FULLSCREEN);
const auto dialog = windowManager.create(lysa::Rect{100.0f, 100.0f, 400.0f, 300.0f});
dialog->setMinimumSize(200.0f, 150.0f);
Subclass Window to respond to lifecycle events:
public:
HUDWindow() : Window(
lysa::RECT_FULLSCREEN) {}
void onCreate() override {
}
}
};
const auto hud = windowManager.add(std::make_shared<HUDWindow>());
3. Creating and adding widgets
Use the create<T>() template on a Window or Widget to construct and add a child in one step. The first argument is a resource string (size or style hint), the second is the Alignment:
Widgets can also be constructed separately and added with add<T>():
auto label = std::make_shared<lysa::ui::Text>("Score: 0");
label->setTextColor(lysa::float4{1.0f, 1.0f, 0.0f, 1.0f});
Remove a specific child or clear the entire tree:
4. Alignment and layout
The Alignment enum controls how each child is stacked inside its parent's content area. Children are laid out in the order they are added.
for (const auto& label : {"OK", "Cancel"}) {
}
Use padding to add space between stacked children:
Use borders to add internal margins inside a widget:
panel->setHBorder(10.0f);
5. Handling events
All widget signals are dispatched through the engine's event system. Subscribe using the widget's id and a UIEvent constant. Events are queued and executed on the next frame and the parameters of the event are carried in a lysa::Event::payload and read with std::any_cast :
[](const lysa::Event&) {
lysa::Log::info("Button clicked!");
});
[](const lysa::Event& e) {
const auto& payload = std::any_cast<const lysa::ui::UIEventText&>(e.payload);
lysa::Log::info("New text: " + payload.text);
});
[](const lysa::Event& e) {
const auto& payload = std::any_cast<const lysa::ui::UIEventValue&>(e.payload);
lysa::Log::info("Value: " + std::to_string(payload.value));
});
subscribe() returns the identifier of the handler. Keep it in a variable to remove the handler with lysa::ctx().events.unsubscribe(handlerId) before the widget is destroyed.
6. Text widget
Text displays a single immutable line of text. Wrap it inside a Box or Button for a bordered appearance:
label->setFontScale(1.5f);
label->setText("Health: 75");
Query the natural size of a Text widget before sizing its container:
float w, h;
label->getSize(w, h);
container->setSize(w + 20.0f, h + 10.0f);
7. TextEdit widget
TextEdit provides a single-line editable text field with cursor and selection support:
edit->setText("Player One");
edit->setSelStart(0);
[edit](const lysa::Event&) {
lysa::Log::info("Input: " + edit->getText());
});
8. RichTextArea widget
RichTextArea displays a read-only block of word-wrapped text marked up with BBCode:
"width=400;height=200",
"[center][b]Release notes[/b][/center][br]"
"The [i]Lysa[/i] engine now supports [color=orange]rich text[/color].[br]"
"Read the [url=https://lysaengine.org]documentation[/url] or run [code]lysa --help[/code].");
Supported tags :
| Tag | Effect |
[b] [i] | Bold and italic; drawn with the faces given to setFonts() (bold is emulated when no bold face is given) |
[u] [s] | Underlined and struck-through text |
[code] | Monospaced text drawn with the code color |
[color=…] | Color of the text, as a name (red, orange, silver, …), #rgb / #rrggbb / #rrggbbaa, or r,g,b / r,g,b,a floats |
[size=n] | Size of the text relative to RichTextArea::SIZE_REFERENCE (100 = the size of the widget), clamped to [MIN_SIZE_FACTOR, MAX_SIZE_FACTOR] |
[url=target] | Clickable link; the payload of OnClick carries target or the link text when the tag has no value |
[left] [center] [right] | Horizontal placement of the line |
[br] | Line break |
An unknown or unterminated tag is displayed as-is.
Colors, fonts and scrolling:
area->setTextColor({0.9f, 0.9f, 0.9f, 1.0f});
area->setLinkColor({0.4f, 0.7f, 1.0f, 1.0f});
area->setCodeColor({0.8f, 0.8f, 0.5f, 1.0f});
area->setFonts(boldFont, italicFont, boldItalicFont, monoFont);
area->setColorConverter(
[](const lysa::float4& color) { return lysa::float4{color.rgb * 0.8f, color.a}; });
area->scrollToTop();
area->scrollToBottom();
Clicking a link:
[](
const lysa::Event&
event) {
const auto& link = std::any_cast<const lysa::ui::UIEventLink&>(event.payload);
lysa::Log::info("Link clicked: " + link.target);
});
9. Image widget
Image displays a lysa::Image resource. By default it auto-sizes to the image dimensions:
imgWidget->
setImage(
"app://res/ui/logo.png");
icon->setImage(
"app://res/ui/icon.png");
icon->setColor(lysa::float4{1.0f, 0.5f, 0.5f, 1.0f});
auto& logo = lysa::ctx().res.get<lysa::ImageManager>().load("app://res/ui/logo.png");
10. ScrollBar widget
ScrollBar (and its aliases HScrollBar / VScrollBar) lets the user select a value within a numeric range:
0.0f, 100.0f, 50.0f, 1.0f);
0.0f, 200.0f, 0.0f, 5.0f);
hBar->setMax(255.0f);
hBar->setValue(128.0f);
[hBar](const lysa::Event&) {
applyBrightness(hBar->getValue());
});
The two buttons scrolling by one step at the end of the bar are a SpinButtons widget, with the auto-repeat when a button is held down :
11. ToggleButton widget
ToggleButton is a two-state button (checked / unchecked). Query or change the state programmatically, or listen for UIEvent::OnStateChange:
[toggle](const lysa::Event&) {
const bool on = toggle->getState() == lysa::ui::CheckWidget::CHECK;
lysa::Log::info(std::string("Fullscreen: ") + (on ? "ON" : "OFF"));
});
12. TreeView widget
TreeView displays a hierarchical list of widgets with expand/collapse handles, a vertical scroll bar, a selection highlight and a highlight of the item below the mouse cursor :
std::make_shared<lysa::ui::Text>("Root A"));
const auto& rootB = tree->addItem(
std::make_shared<lysa::ui::Text>("Root B"));
const auto& childA1 = tree->addItem(rootA,
std::make_shared<lysa::ui::Text>("Child A.1"));
tree->addItem(rootA,
std::make_shared<lysa::ui::Text>("Child A.2"));
The resources of the background box, scroll bar, level indentation and the two highlights are assigned by the style (call setResources() to override them).
Expand and collapse items. expand() emits UIEvent::OnExpandItem, expandAll() does not :
tree->expand(rootA);
tree->expand(childA1, false);
tree->expand(someWidget);
tree->expandAll();
tree->expandAll(false);
Selection is single by default; SelectionMode::MULTI lets the user extend the selection with SHIFT (range) and CONTROL (individual items), SelectionMode::NONE disables it :
tree->setSelectionMode(lysa::ui::TreeView::SelectionMode::MULTI);
tree->select(childA1);
tree->select(childA1, false);
tree->unselectAll();
const auto item = tree->getSelectedItem();
const auto items = tree->getSelectedItems();
const auto hover = tree->getPointedItem();
const auto found = tree->getItem(someWidget);
Reacting to the user interaction with : UIEventItem::item :
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventItem>(e.payload);
if (payload.item != nullptr) { openInInspector(payload.item); }
});
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventItem>(e.payload);
activate(payload.item);
});
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventExpand>(e.payload);
lysa::Log::info(payload.expanded ? "expanded" : "collapsed");
});
tree->removeAllItems();
13. ListBox widget
ListBox displays a scrollable list of arbitrary widgets with keyboard navigation (Up/Down arrows) and a Selection highlight rectangle behind the selected item:
for (int i = 0; i < 10; ++i) {
auto label = std::make_shared<lysa::ui::Text>("Item " + std::to_string(i));
}
int idx =
list->getSelectedIndex();
auto item =
list->getSelectedItem();
[](const lysa::Event& e) {
const auto& payload = std::any_cast<const lysa::ui::UIEventItem&>(e.payload);
lysa::Log::info("Selected index: " + std::to_string(payload.index));
});
The inner box, the scroll bar and the selection highlight are styled by the active style; call setResources(resBox, resScroll, resSel) only to override them.
14. ProgressBar widget
ProgressBar (and its aliases HProgressBar / VProgressBar) fills proportionally to its current value within a [min, max] range. An optional text overlay can display the percentage or the raw value:
0.0f, 100.0f, 30.0f);
bar->setValue(75.0f);
0.0f, 100.0f, 50.0f);
15. ScrollBox widget
ScrollBox is a bordered container that automatically adds horizontal and vertical scroll bars when its content overflows. Add children via addContent() rather than create<T>():
const auto sbox =
panel->create<lysa::ui::ScrollBox>(
std::shared_ptr<lysa::ui::Widget> firstRow;
for (int i = 0; i < 20; ++i) {
const auto row = sbox->addContent(
std::make_shared<lysa::ui::Text>("Row " + std::to_string(i)),
"width=300;height=20");
if (i == 0) { firstRow = row; }
}
const auto inner = sbox->getInnerBox();
sbox->removeContent(firstRow);
sbox->removeAllContent();
The inner box and the two scroll bars are styled by the active style; call setResources(resBox, resVScroll, resHScroll) only to override them.
16. Popup widget
Popup is a Panel placed at fixed (x, y) coordinates relative to its parent and always drawn on top of all sibling widgets. Use it for context menus, tooltips, or floating overlays:
Tooltip is a Popup displaying a short help text in a Box :
const auto tip = uiWindow->add(
std::make_shared<lysa::ui::Tooltip>("Rotate the camera\nHold the right button", x, y),
tip->setText("Zoom in & out");
uiWindow->remove(tip);
17. CheckBox and RadioButton widgets
Both derive from CheckWidget.
CheckBox displays a CheckMark inside its box when checked :
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventState>(e.payload);
enableShadows(payload.state == lysa::ui::CheckWidget::CHECK);
});
RadioButton is exclusive : checking one unchecks every sibling radio button of the same parent sharing its group index (zero by default).
18. CheckMark, CrossMark and Arrow widgets
These three widgets draw a symbol inside their rectangle, with a transparent background.
TreeView uses an Arrow for its expand/collapse handles and CheckBox uses a CheckMark, both created internally.
19. Menu widget
Menu stacks text items vertically, each with an optional right-aligned keyboard shortcut and an optional leading widget (a CheckBox, a RadioButton, an Image, …).
const auto open =
menu->addItem(
"Open",
"Ctrl+O");
menu->addItem(
"Save",
"Ctrl+S");
const auto grid = std::make_shared<lysa::ui::CheckBox>();
const auto item =
menu->addItem(
"Show grid",
"",
"",
"",
grid);
menu->getItem(open)->setTextColor(lysa::float4{1.0f, 1.0f, 1.0f, 1.0f});
menu->getItemShortcut(open)->setTextColor(lysa::float4{0.6f, 0.6f, 0.6f, 1.0f});
A menu does not size itself : ask it for the room its items need, typically to size the Window or the Popup holding it :
holder->setSize(
menu->getContentWidth(),
menu->getContentHeight());
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventItem>(e.payload);
runCommand(payload.index);
});
20. TabBar widget
TabBar draws a horizontal row of tabs and tracks which one is selected. It does not manage what the tabs display : subscribe to UIEvent::OnSelectItem and manage the content yourself.
bar->addTab("Assets");
bar->addTab("Log", "", std::make_shared<lysa::ui::CrossMark>());
bar->setSize(0.0f, bar->getContentHeight());
bar->select(1);
const auto index = bar->getSelected();
bar->getTab(index)->setTextColor(lysa::float4{1.0f, 1.0f, 0.0f, 1.0f});
bar->removeTab(0);
bar->removeAllTabs();
The tabs open downwards by default. Pass TabPlacement::BOTTOM to the constructor for a bar sitting below its content, so the tabs open upwards :
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventItem>(e.payload);
showPage(payload.index);
});
21. TabContainer widget
TabContainer arranges widgets into a tabbed view : it creates a tab for each widget added and displays only the one of the selected tab and owns a TabBar.
const auto scene = tabs->
addTab(
"Scene", std::make_shared<lysa::ui::Panel>());
tabs->addTab("Log", std::make_shared<lysa::ui::ScrollBox>(), "", std::make_shared<lysa::ui::CheckMark>());
tabs->select(1);
const auto shown = tabs->getSelectedContent();
const auto index = tabs->getIndexOf(props);
tabs->getTab(index)->setText("Inspector");
tabs->removeTab(0);
tabs->removeAllTabs();
The bar of tabs adjusts its height to the tabs, set an explicit one to override it::
tabs->setTabBarHeight(24.0f);
tabs->getTabBar()->setTabPadding(10.0f);
tabs->getContentArea()->setPadding(4.0f);
Selecting a tab emits UIEvent::OnSelectItem on the container :
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventItem>(e.payload);
if (payload.item != nullptr) { refreshPage(payload.item); }
});
22. FoldableContainer widget
FoldableContainer groups widgets under a clickable title bar folding & unfolding them. It adjusts its own height to its title bar when folded & to its title bar plus its content when unfolded : stack several of them with Alignment::TOP to build a list of collapsible groups.
group->addContent(std::make_shared<lysa::ui::Text>("0.0, 0.0, 0.0"));
group->removeContent(row);
group->removeAllContent();
The heights of the title bar & of the content are computed from the title & from the widgets of the content, set explicit ones to override them :
group->setTitleBarHeight(24.0f);
group->setContentHeight(120.0f);
group->updateSize();
The state is read & changed from the code, & the internal widgets stay reachable :
group->setFolded();
group->toggle();
if (group->isFolded()) { }
group->getTitleWidget()->setTextColor({1.0f, 1.0f, 1.0f, 1.0f});
group->getTitleBar()->setPadding(2.0f);
group->getContent()->setPadding(2.0f);
Clicking the title bar emits UIEvent::OnExpandItem on the container :
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventExpand>(e.payload);
savePreference(payload.expanded);
});
23. Slider widget
Slider (and its aliases HSlider / VSlider) lets the user drag a grip along a track to select a value within a numeric range:
0.0f, 100.0f, 50.0f, 1.0f);
[
slider](
const lysa::Event&) {
setVolume(slider->getValue());
});
slider->getTrack()->setPadding(0.0f);
slider->getFill()->setDrawBackground(
false);
slider->setResources(
"style=LOWERED",
"style=FLAT;color=0.2,0.5,0.9,1.0",
"style=RAISED");
24. Knob widget
Knob selects a value by rotating a disc. A cursor drawn inside the disc points at the current value, and the values of the graduations can be drawn around it:
"width=" + std::to_string(80.0f /
panel->getAspectRatio()) +
";height=80",
0.0f, 100.0f, 50.0f, 1.0f);
[
knob](
const lysa::Event&) {
setGain(knob->getValue());
});
knob->setStartAngle(180.0f);
knob->setSweepAngle(180.0f);
The graduations are drawn outside of the disc, their values only on demand:
knob->setLabelsVisible();
knob->setTicksVisible(
false);
The disc is drawn RAISED by default, and the cursor, the graduations and the labels use the text color of the style :
knob->setTickLength(6.0f);
knob->setTickWidth(2.0f);
knob->setCursorWidth(3.0f);
knob->setCursorExtent(0.0f, 0.9f);
25. SpinBox widget
SpinBox displays a numeric value in an editable text field :
0.0f, 255.0f, 128.0f, 1.0f);
spin->setButtonsWidth(14.0f);
spin->setReadOnly();
[spin](const lysa::Event&) {
applyOpacity(spin->getValue());
});
spin->setRepeatDelay(400);
spin->setRepeatInterval(60);
spin->getTextEdit()->setReadOnly();
spin->getUpButton()->setPadding(0.0f);
spin->setResources("style=LOWERED");
The column of the two buttons is a SpinButtons widget also usable alone :
buttons->setRepeatInterval(60);
[](
const lysa::Event&
event) {
const auto& step = std::any_cast<const lysa::ui::UIEventStep&>(event.payload);
scroll(step.steps);
});
26. DropDownList widget
DropDownList displays the selected item of a list of strings & opens a popup list:
list->setItems({
"Debug",
"Release",
"RelWithDebInfo"},
"Release");
const auto index =
list->addItem(
"MinSizeRel");
[
list](
const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventItem>(e.payload);
selectConfiguration(payload.index, list->getSelectedItem());
});
The selection is read & changed by index or by label (NO_ITEM (-1) meaning no selection) :
list->setPlaceHolder(
"Select a configuration");
The popup list is opened & closed from the code :
list->setMaxDisplayedItems(6);
list->setArrowWidth(14.0f);
list->setResources(
"style=RAISED",
"",
"style=LOWERED");
27. IconImage and IconSVG widgets
Icon is the base of the widgets drawing a picture fitted into the widget rectangle, keeping the aspect ratio of the source : IconImage for a 2D image, IconSVG for a vector shape.
"app://res/icons/build.svg");
icon->setColor({0.9f, 0.9f, 0.9f, 1.0f});
The shape of an IconSVG is loaded from a URI :
icon->setSVG(
"app://res/icons/run.svg", 2.5f, 0.002f, lysa::SVGBounds::CONTENT);
An IconImage displays a GPU image :
bitmap->
setImage(
"app://res/icons/logo.png");
- Note
- The size of an icon is reset when it is added to a parent since the style applies the size of its resource string. Give the size in the resource string or call
setSize() after adding it.
28. ColorWheel and ColorSlider widgets
ColorWheel is a disc selecting the hue & the saturation of a color:
wheel->
setColor({1.0f, 0.5f, 0.0f, 1.0f});
wheel->setHueSaturation(210.0f, 0.75f);
wheel->setBrightness(0.8f);
wheel->setAlpha(0.5f);
[](const lysa::Event& e) {
const auto& payload = std::any_cast<lysa::ui::UIEventColor>(e.payload);
applyColor(payload.color);
});
The conversions used by the wheel are available as static helpers:
wheel->setSegments(360);
wheel->setRings(48);
wheel->setCursorRadius(4.0f);
ColorSlider (aliases HColorSlider / VColorSlider) is a Slider whose track is drawn with a gradient of colors & whose value is marked by an arrow :
0.0f, 255.0f, 128.0f, 1.0f);
ramp->
setColors({{0.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}});
ramp->setSteps(64);
const auto middle = ramp->colorAt(0.5f);
29. ColorPicker widget
ColorPicker assembles a preview box, a ColorWheel with its brightness slider & one row per component into a complete color selector :
lysa::float4{0.2f, 0.6f, 1.0f, 1.0f});
picker->
setColor({1.0f, 0.0f, 0.0f, 1.0f});
const auto& color = picker->getColor();
[](const lysa::Event& e) {
applyColor(std::any_cast<lysa::ui::UIEventColor>(e.payload).color);
});
The labels of the tabs can replaced for localization :
picker->setModeLabels({"RVB", "TSV", "Linéaire"});
picker->setTabHeight(24.0f);
The picker does not size itself : ask it for the height it needs to size the Window or the container holding it :
window->setHeight(picker->getAutoHeight());
picker->setPreviewHeight(32.0f);
picker->setWheelHeight(150.0f);
picker->setBrightnessWidth(16.0f);
picker->setRowHeight(28.0f);
picker->setLabelWidth(16.0f);
picker->setValueWidth(60.0f);
picker->setFooterHeight(24.0f);
picker->getWheel()->setCursorRadius(5.0f);
When the colors of the application are stored in the linear space give the picker a transform used for the preview & the gradients only :
picker->setPreviewTransform([](const lysa::float4& c) {
return lysa::float4{
c.a};
});
30. ColorPickerButton widget
ColorPickerButton is a button displaying a color swatch :
lysa::float4{1.0f, 1.0f, 1.0f, 1.0f}, "Ambient light");
[](const lysa::Event& e) {
setAmbientColor(std::any_cast<lysa::ui::UIEventColor>(e.payload).color);
});
The dialog is described by a ColorPickerButton::Dialog struct letting you localize its title, its buttons & adjust its geometry :
.title = "Ambient light",
.buttons = {"Select", "Cancel"},
.width = 170.0f,
.footerHeight = 0.0f,
},
});
button->setColor({0.5f, 0.5f, 0.5f, 1.0f});
button->setLabel(
"Fog color");
button->setSwatchWidth(48.0f);
31. Modal dialogs
ModalDialog is a Window : it displays a DialogBox centered on the screen, above its parent, and grabs the focus until it is closed. It needs a parent widget or window to find the WindowManager it must be attached to:
const auto dialog = std::make_shared<lysa::ui::ModalDialog>(
"Quit", std::vector<std::string>{"OK", "Cancel"}, 300.0f, 120.0f);
const auto button = std::any_cast<const lysa::ui::UIEventItem&>(
event.payload).index;
});
});
TextInputDialog asks the user for a single line of text. The validation callback is called when the action button is pressed and returns an empty string to accept the input or the message to display below the field to reject it:
const auto rename = std::make_shared<lysa::ui::TextInputDialog>(
"Rename",
std::vector<std::string>{"Rename", "Cancel"},
[](
const std::string&
text) -> std::string {
if (
text.empty()) {
return "The name can not be empty"; }
return "";
});
rename->setText("current name");
rename->show();
The dialog closes itself when the input is accepted, when it is unchanged, or when the cancel button (TextInputDialog::BUTTON_CANCEL) is pressed. getTextEdit() returns the TextEdit and getMessage() the Text displaying the validation message.
ColorModalDialog is the dialog opened by a ColorPickerButton it wraps aColorPicker` and calls back with the selected color.
32. Applying a style
The WindowManager creates a StyleClassic at construction and hands it to every Window that does not set its own. Reconfigure it through the manager to restyle the whole UI:
auto& style = windowManager.getDefaultStyle();
style.setOption("color_focus", "0.3,0.5,0.9,1.0");
style.setOption("color_highlight", "0.3,0.5,0.9,1.0");
style.setOption("color_foreground_up", "0.40,0.60,0.70,1.0");
style.setOption("color_foreground_down", "0.65,0.86,0.86,1.0");
style.setOption("color_shadow_dark", "0.1,0.1,0.1,1.0");
style.setOption("color_shadow_bright", "0.9,0.9,0.9,1.0");
style.setOption("color_tree_lines", "0.1,0.1,0.1,1.0");
style.setOption("color_text", "1.0,1.0,1.0,1.0");
color_text is the default color of the texts returned by Style::getTextColor() and applied to every Text and RichTextArea that was not given an explicit color.
Style also exposes the default size of the widgets the style sizes itself :
style.setOption("size_scroll_bar", "18");
style.setOption("size_check_box", "16");
style.setOption("size_radio_button", "16");
style.setOption("size_tree_indent", "12");
The other built-in look is StyleMaterial, inspired by Material Design : flat tonal surfaces,
auto& material = uiWindow->getStyle();
material.setOption("color_primary", "0.816,0.737,1.0,1.0");
material.setOption("color_surface", "0.078,0.071,0.094,1.0");
material.setOption("color_outline", "0.576,0.561,0.600,1.0");
material.setOption("size_corner_radius", "8");
uiWindow->setStyle(std::make_shared<MyStyle>());
uiWindow->setStyle(nullptr);
Widget resource strings are parsed by the active style. For the built-in styles, a resource string can encode the desired size and appearance:
33. Show, hide, and enable
Widgets are shown and hidden with setVisible(); a Window additionally offers the show() and hide() aliases, and its visibility changes take effect at the start of the next frame:
statusLabel->setVisible();
debugPanel->setVisible(false);
hud->show();
pauseMenu->hide();
pauseMenu->setVisible(!pauseMenu->isVisible());
Widget::isVisible() walks the whole parent chain and the owning Window.
Disabling a widget prevents it from responding to mouse and keyboard events but keeps it visible:
submitButton->setEnabled(false);
submitButton->setEnabled(true);
Force an "immediate" repaint of a widget and its children (widgets are drawn at the start of each frame):