CommandBar¶
Header: winui/ui/menus/CommandBar.hpp. Spec: winui/ui/menus/CommandBar.hpp.
A toolbar of app-bar buttons with an overflow menu behind a More ("...") button.
Primary commands (AppBarButton, AppBarToggleButton, AppBarSeparator, or any Element) sit in a row against the bar's right edge, with optional content on the left. Secondary commands are in the overflow menu. Opening the bar with the More button or set_open() shows the overflow menu and the text of commands whose text goes at the Bottom. The open bar is drawn over whatever lies below it, or above it when it opens upward, and never moves other elements. A click on a command closes the bar, and so does a click outside or Escape unless is_sticky(). With dynamic overflow on (the default), primary commands that do not fit move into the overflow and come back when there is room. The shortcuts of secondary commands fire app-wide while the bar is in the window.
Example:
auto bar = std::make_unique<ui::CommandBarControl>();
auto* add = bar->add_primary(std::make_unique<ui::AppBarButtonControl>("Add", ui::Symbol::Add));
bar->add_primary(std::make_unique<ui::AppBarSeparatorControl>());
bar->add_primary(std::make_unique<ui::AppBarToggleButtonControl>("Shuffle", ui::Symbol::Shuffle));
auto* settings = bar->add_secondary(std::make_unique<ui::AppBarButtonControl>("Settings", ui::Symbol::Setting));
bar->set_content(std::make_unique<ui::TextControl>("Now playing"));
bar->set_default_text_position(ui::CommandBarDefaultTextPosition::Right);
add->on_click([] { /* add an item */ });
settings->on_click([] { /* open settings */ });
window.set_content(std::move(bar));
// Declaratively:
window.set_content(ui::CommandBar{
.default_text_position = ui::CommandBarDefaultTextPosition::Right,
.content = ui::Text{.text = "Now playing", .vertical_alignment = ui::Alignment::Center},
.primary = {ui::AppBarButton{.text = "Add", .icon = ui::Symbol::Add},
ui::AppBarSeparator{},
ui::AppBarToggleButton{.text = "Shuffle", .icon = ui::Symbol::Shuffle}},
.secondary = {ui::AppBarButton{.text = "Settings", .icon = ui::Symbol::Setting}},
});
ui::CommandBar¶
A toolbar of app-bar buttons with an overflow menu. Builds a ui::CommandBarControl.
Primary commands sit in the bar, and secondary commands are in the overflow menu behind the More ("...") button. With dynamic overflow on, primary commands that do not fit move into the overflow too. Opening the bar with the More button shows the text and the overflow.
Example:
ui::Property<std::string> status;
window.set_content(ui::CommandBar{
.default_text_position = ui::CommandBarDefaultTextPosition::Right,
.on_closed = [&](ui::PopupCloseReason) { status = "closed"; },
.content = ui::Text{ .text = "Now playing", .vertical_alignment = ui::Alignment::Center },
.primary = { ui::AppBarButton{ .text = "Add", .icon = ui::Symbol::Add, .on_click = [&] { status = "new"; } },
ui::AppBarSeparator{},
ui::AppBarToggleButton{ .text = "Shuffle", .icon = ui::Symbol::Shuffle } },
.secondary = { ui::AppBarButton{ .text = "Settings", .icon = ui::Symbol::Setting } },
});
Every field, in the order a designated initializer names them:
ui::CommandBar{
.is_open, .sticky, .default_text_position, .overflow_button_visibility,
.dynamic_overflow_enabled, .closed_display_mode, .background, .style, .margin, .width,
.height, .min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
.vertical_alignment, .visible, .tool_tip, .enabled, .accessibility, .on_opening,
.on_opened, .on_closing, .on_closed, .on_pointer_entered, .on_pointer_exited,
.on_got_focus, .on_lost_focus, .on_key_down, .on_wheel, .control, .content, .primary,
.secondary
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
is_open |
ui::TwoWayField<bool> |
{false} |
Whether the bar is open, with the text and the overflow menu showing. |
sticky |
ui::Binding<bool> |
{false} |
No light dismiss: an outside click or Escape leaves the open bar open. |
default_text_position |
ui::Binding<ui::CommandBarDefaultTextPosition> |
{ui::CommandBarDefaultTextPosition::Bottom} |
Text under the icons, to their right, or none. |
overflow_button_visibility |
ui::Binding<ui::AutoVisibility> |
{ui::AutoVisibility::Auto} |
Auto shows the More button only when there is something to reveal. |
dynamic_overflow_enabled |
ui::Binding<bool> |
{true} |
Primary commands that do not fit move into the overflow menu. |
closed_display_mode |
ui::Binding<ui::AppBarClosedDisplayMode> |
{ui::AppBarClosedDisplayMode::Compact} |
Compact (48 DIPs tall), Minimal (24 DIPs, the More button only) or Hidden (0). |
background |
ui::Binding<ui::Paint> |
The fill behind the bar: a fixed color or a theme resource. Unset is transparent. In Compact mode the open bar draws its own acrylic. | |
on_opening |
ui::Action |
The bar is about to open. | |
on_opened |
ui::Action |
The bar has opened. | |
on_closing |
ui::Callback<ui::Decision(const ui::PopupClosingArgs&)> |
The bar is about to close. Gets the reason: a light dismiss, a command click, the More button, or is_open set to false. Return ui::Cancel to keep it open. |
|
on_closed |
ui::Callback<void(ui::PopupCloseReason)> |
The bar has closed, with the reason. This is where a bound is_open learns about it. |
|
on_pointer_entered |
ui::Action |
The pointer moved onto the control. | |
on_pointer_exited |
ui::Action |
The pointer left the control. | |
on_got_focus |
ui::Action |
Keyboard focus arrived on the control, or on anything inside it, from outside it. A control with nothing focusable in it never gets focus, and never raises this. | |
on_lost_focus |
ui::Action |
Keyboard focus left the control and everything inside it. | |
on_key_down |
ui::Callback<ui::Handling(const ui::KeyEvent&)> |
A key pressed while focus is on the control or inside it, before the control's own handling; ui::Handled stops it there (Element::on_key_down()). | |
on_wheel |
ui::Callback<ui::Handling(const ui::PointerEvent&)> |
A wheel turn over the control, before the control scrolls; ui::Handled stops it there (Element::on_wheel()). | |
control |
ui::ControlOut<ui::CommandBar> |
Out: the handle that receives the built control. | |
content |
ui::Spec |
Shown at the bar's left. | |
primary |
ui::SpecList |
The commands in the bar: ui::AppBarButton, ui::AppBarToggleButton and ui::AppBarSeparator specs. | |
secondary |
ui::SpecList |
The overflow menu's entries, as app-bar specs. |
Plus the common fields style, margin, width, height, min_width, min_height, max_width, max_height, horizontal_alignment, vertical_alignment, visible, tool_tip, enabled, accessibility every spec carries (conventions).
build¶
Consumes the spec and returns the built ui::CommandBarControl; the caller owns it.
ui::CommandBarControl¶
Derives from ui::Element, ui::AppBarCommandHost.
A toolbar of app-bar buttons with an overflow menu behind a More ("...") button.
Primary commands (AppBarButton, AppBarToggleButton, AppBarSeparator, or any Element) sit in a row against the bar's right edge, with optional content on the left. Secondary commands are in the overflow menu. Opening the bar with the More button or set_open() shows the overflow menu and the text of commands whose text goes at the Bottom. The open bar is drawn over whatever lies below it, or above it when it opens upward, and never moves other elements. A click on a command closes the bar, and so does a click outside or Escape unless is_sticky(). With dynamic overflow on (the default), primary commands that do not fit move into the overflow and come back when there is room. The shortcuts of secondary commands fire app-wide while the bar is in the window.
Example:
auto bar = std::make_unique<ui::CommandBarControl>();
auto* add = bar->add_primary(std::make_unique<ui::AppBarButtonControl>("Add", ui::Symbol::Add));
bar->add_primary(std::make_unique<ui::AppBarSeparatorControl>());
bar->add_primary(std::make_unique<ui::AppBarToggleButtonControl>("Shuffle", ui::Symbol::Shuffle));
auto* settings = bar->add_secondary(std::make_unique<ui::AppBarButtonControl>("Settings", ui::Symbol::Setting));
bar->set_content(std::make_unique<ui::TextControl>("Now playing"));
bar->set_default_text_position(ui::CommandBarDefaultTextPosition::Right);
add->on_click([] { /* add an item */ });
settings->on_click([] { /* open settings */ });
window.set_content(std::move(bar));
// Declaratively:
window.set_content(ui::CommandBar{
.default_text_position = ui::CommandBarDefaultTextPosition::Right,
.content = ui::Text{.text = "Now playing", .vertical_alignment = ui::Alignment::Center},
.primary = {ui::AppBarButton{.text = "Add", .icon = ui::Symbol::Add},
ui::AppBarSeparator{},
ui::AppBarToggleButton{.text = "Shuffle", .icon = ui::Symbol::Shuffle}},
.secondary = {ui::AppBarButton{.text = "Settings", .icon = ui::Symbol::Setting}},
});
CommandBarControl¶
An empty, closed, Compact bar with the More button on Auto.
~CommandBarControl¶
Destroys every command, the content and the overflow.
add_primary¶
Appends command to the row. Takes ownership and hands back a non-owning observer (the same convention as StackControl::add()). Updates the layout.
add_secondary¶
Appends command to the overflow menu. Takes ownership and hands back a non-owning observer. Updates the layout.
insert_primary_element¶
Inserts a primary command before index (clamped to the end), taking ownership. command must not be null. Updates the layout.
insert_secondary_element¶
Inserts a secondary command before index (clamped to the end), taking ownership. command must not be null. Updates the layout.
remove_primary¶
Destroys the primary command at index; out of range is ignored. Updates the layout.
remove_secondary¶
Destroys the secondary command at index; out of range is ignored. Updates the layout.
primary_count¶
The number of primary commands, including any moved into the overflow.
secondary_count¶
The number of secondary commands.
primary¶
The primary command at index as a non-owning observer, or nullptr when out of range.
secondary¶
The secondary command at index as a non-owning observer, or nullptr when out of range.
set_content¶
Shows content at the bar's left, replacing any previous content; null clears it. Takes ownership and hands back a non-owning observer. Hidden while closed in Minimal/Hidden.
content¶
The content as a non-owning observer, or nullptr.
default_text_position¶
Where every command puts its text. Bottom (the default) shows the text only while the bar is open, Right always beside the icon, Collapsed never.
set_default_text_position¶
Sets where every command puts its text, and lays out every command again.
is_open¶
Whether the bar is lifted over its surroundings, with the text and the overflow showing. False by default.
set_open¶
Opens or closes the bar. Fires on_opening()/on_closing() at once and on_opened()/ on_closed() once the transition has run; no-op when unchanged.
closed_display_mode¶
What the closed bar shows; Compact by default.
set_closed_display_mode¶
Sets what the closed bar shows and updates the layout. The closed height is 48, 24 or 0 DIPs.
set_background¶
The fill behind the bar, closed and open: a fixed color or a theme resource. Empty, the default, is transparent. In Compact mode the open bar draws its acrylic over this fill.
open_rect¶
Where the open bar is drawn: over the closed bar and whatever lies below it, or above it when it opens upward. It takes no room in the layout, and the bar's bounds() stay those of the closed bar.
opens_up¶
Whether the open bar went up because there was not enough room below for it and its overflow.
is_sticky¶
Whether light dismiss is off, so an outside click or Escape leaves the bar open.
set_sticky¶
False by default. A click on a command still closes a sticky bar.
overflow_button_visibility¶
When the More button shows. Auto, the default, shows it only when there is something to reveal: overflow entries or hidden text. With Collapsed, the pointer cannot reach the secondary commands.
set_overflow_button_visibility¶
Updates the layout.
is_dynamic_overflow_enabled¶
Whether dynamic overflow is on; true by default. When the bar is narrower than its commands, primary commands move into the overflow and move back when there is room. The group with the lowest dynamic_overflow_order() moves first, then the rest from the right.
set_dynamic_overflow_enabled¶
Updates the layout.
is_primary_in_overflow¶
Whether the primary command at index has been moved into the overflow by dynamic overflow.
more_button_visible¶
Whether the More button shows, resolving overflow_button_visibility()'s Auto against the current commands, closed mode and text position.
on_opening¶
Fired as is_open() turns true, before the transition. Replaces any previous handler.
on_opened¶
Fired once the opening transition has run.
on_closing¶
Fired before is_open() turns false, with why: Programmatic for set_open(false), LightDismiss for a click outside or Escape, Invoked for a command click, CloseButton for the More button. Return ui::Cancel to keep the bar open.
on_closed¶
Fired once the closing transition has run, with the reason on_closing() saw. This is where a bound is_open learns about a light dismiss.
command_invoked¶
A command in the bar was clicked, so the bar closes.
toggle_from_more_button¶
The More button was clicked, or Down/Up pressed on it: toggles the bar, and an opening moves keyboard focus into the overflow.
for_each_child¶
Lists the shown row in drawing order (the content, the primaries left in the bar, the More button), which is what Tab and automation walk. A closed bar in Minimal or Hidden mode leaves out the content and the primaries, and Hidden leaves out the More button too.
sync_native¶
Passes native-control hosting on to the content only.
handle_global_shortcut¶
The shortcuts of the overflow's commands, which fire whether or not the overflow is open.
automation_role¶
Always AutomationRole::ToolBar.
measure_override¶
The closed bar's size, with a height of 48, 24 or 0 DIPs. Also decides which primary commands move into the overflow at the available width.
arrange_override¶
Places the content, the primaries left in the bar and the More button.
render_override¶
Draws the closed bar; the open bar is drawn over the tree by the window's popup layer.
hit_test_children¶
The commands, while the bar is closed.
clear_dirty_override¶
Clears flags on this node and every owned child, shown or not: the secondaries, the separator, the open-bar layer and the overflow too.
tick_override¶
Ticks the content and every command, shown or not, and the More button, then runs the open/close transition.
enabled_changed¶
is_enabled() flipped, through set_enabled() here or on an ancestor, or a move to another parent. Drop any press or hover state. The element is redrawn either way. No-op by default.
Enumerations¶
AppBarClosedDisplayMode¶
What a closed CommandBar shows.
| Value | |
|---|---|
Compact |
the icons, 48 tall |
Minimal |
the More button only, 24 tall |
Hidden |
nothing, 0 tall |
Tests¶
tests/test_command_bar.cpp