Skip to content

CommandBarFlyout

Header: winui/ui/menus/CommandBarFlyout.hpp. Spec: winui/ui/menus/CommandBarFlyout.hpp.

The mini-toolbar of an in-app object: a small row of icon-only commands in a flyout, with a menu of more commands under it behind a "More" button.

Like every FlyoutBase, it sits in the tree wrapping its anchor (set_anchor()) and shows its content as a popup. Primary commands (app-bar buttons) form a row of 40x40 icon buttons, and secondary commands form the menu. The show mode decides how it opens. Transient, for a click, starts with the menu collapsed and takes no focus. Standard, for a context menu, starts expanded and focuses the first command. Clicking a secondary command closes the flyout, and clicking a primary one collapses the menu. The menu always opens downward, and primary commands never move into it.

Example:

auto flyout = std::make_unique<ui::CommandBarFlyoutControl>();
flyout->set_placement(ui::PopupPlacement::Right);
flyout->set_show_mode(ui::FlyoutShowMode::Transient);
flyout->add_primary(std::make_unique<ui::AppBarButtonControl>("Share", ui::Symbol::Share));
flyout->add_primary(std::make_unique<ui::AppBarButtonControl>("Delete", ui::Symbol::Delete));
auto* resize = flyout->add_secondary(std::make_unique<ui::AppBarButtonControl>("Resize"));
resize->on_click([] { /* resize the photo */ });
flyout->set_anchor(std::make_unique<ui::ButtonControl>("Photo")); // a Button anchor toggles it
window.set_content(std::move(flyout));

// Declaratively; open it through `.control`:
ui::Control<ui::CommandBarFlyout> photo_menu;
window.set_content(ui::CommandBarFlyout{
    .placement = ui::PopupPlacement::Right,
    .show_mode = ui::FlyoutShowMode::Transient,
    .control   = photo_menu,
    .anchor    = ui::Button{.text = "Photo", .on_click = [&] { photo_menu->show(); }},
    .primary   = {ui::AppBarButton{.text = "Share", .icon = ui::Symbol::Share},
                  ui::AppBarButton{.text = "Delete", .icon = ui::Symbol::Delete}},
    .secondary = {ui::AppBarButton{.text = "Resize"}},
});

ui::CommandBarFlyout

A small bar of commands in a flyout, with a menu of more under it. Builds a ui::CommandBarFlyoutControl. To open it, call show() on its .control handle from the anchor's handlers. Use show_mode Transient for a click and Standard for a context menu.

Example:

ui::Control<ui::CommandBarFlyout> flyout;

window.set_content(ui::CommandBarFlyout{
    .placement = ui::PopupPlacement::Right,
    .show_mode = ui::FlyoutShowMode::Transient,
    .control   = flyout,
    .anchor    = ui::Button{ .text = "Photo", .on_click = [&] { flyout->show(); } },
    .primary   = { ui::AppBarButton{ .text = "Share", .icon = ui::Symbol::Share },
                   ui::AppBarButton{ .text = "Save", .icon = ui::Symbol::Save },
                   ui::AppBarButton{ .text = "Delete", .icon = ui::Symbol::Delete } },
    .secondary = { ui::AppBarButton{ .text = "Resize" } },
});

Every field, in the order a designated initializer names them:

ui::CommandBarFlyout{
    .is_open, .placement, .placement_alignment, .always_expanded, .show_mode, .light_dismiss,
    .style, .margin, .width, .height, .min_width, .min_height, .max_width, .max_height,
    .horizontal_alignment, .vertical_alignment, .visible, .tool_tip, .accessibility,
    .on_opened, .on_closing, .on_closed, .on_pointer_entered, .on_pointer_exited,
    .on_got_focus, .on_lost_focus, .on_key_down, .on_wheel, .control, .anchor, .primary,
    .secondary
}

Fields, in declaration order (designators must follow it):

Field Type Default
is_open ui::TwoWayField<bool> {false} Whether the flyout is showing. Two-way with ui::bind(): closing it writes false, and a false that on_closing cancels is put back to true.
placement ui::Binding<ui::PopupPlacement> {ui::PopupPlacement::Above} Which side of the anchor it opens on.
placement_alignment ui::Binding<ui::PopupPlacementAlignment> {ui::PopupPlacementAlignment::Center} How the flyout lines up with the anchor along that side.
always_expanded ui::Binding<bool> {false} The secondary menu shows whenever the flyout does.
show_mode ui::Binding<ui::FlyoutShowMode> {ui::FlyoutShowMode::Standard} Transient, for a click, opens with the menu collapsed and leaves focus alone. Standard, for a context menu, opens it expanded and takes focus.
light_dismiss ui::Binding<bool> {true} Whether an outside click or Escape closes it; true by default. Off, it stays open until is_open turns false, hide() runs or a command in it runs.
on_opened ui::Action The flyout is showing. A two-way is_open has been written by then.
on_closing ui::Callback<ui::Decision(const ui::PopupClosingArgs&)> Gets why it is about to close; return ui::Cancel to keep it open.
on_closed ui::Callback<void(ui::PopupCloseReason)> Gets why it closed, once the close fade has finished. A two-way is_open has been written by then.
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::CommandBarFlyout> Out: the handle that receives the built control, through which to show() it.
anchor ui::Spec The in-tree element the flyout hangs from.
primary ui::SpecList The icon row, as app-bar specs.
secondary ui::SpecList The menu under the row, 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, accessibility every spec carries (conventions).

build

std::unique_ptr<Element> build()&&

Consumes the spec and returns the built ui::CommandBarFlyoutControl; the caller owns it.

ui::CommandBarFlyoutControl

Derives from ui::FlyoutBase, ui::AppBarCommandHost.

The mini-toolbar of an in-app object: a small row of icon-only commands in a flyout, with a menu of more commands under it behind a "More" button.

Like every FlyoutBase, it sits in the tree wrapping its anchor (set_anchor()) and shows its content as a popup. Primary commands (app-bar buttons) form a row of 40x40 icon buttons, and secondary commands form the menu. The show mode decides how it opens. Transient, for a click, starts with the menu collapsed and takes no focus. Standard, for a context menu, starts expanded and focuses the first command. Clicking a secondary command closes the flyout, and clicking a primary one collapses the menu. The menu always opens downward, and primary commands never move into it.

Example:

auto flyout = std::make_unique<ui::CommandBarFlyoutControl>();
flyout->set_placement(ui::PopupPlacement::Right);
flyout->set_show_mode(ui::FlyoutShowMode::Transient);
flyout->add_primary(std::make_unique<ui::AppBarButtonControl>("Share", ui::Symbol::Share));
flyout->add_primary(std::make_unique<ui::AppBarButtonControl>("Delete", ui::Symbol::Delete));
auto* resize = flyout->add_secondary(std::make_unique<ui::AppBarButtonControl>("Resize"));
resize->on_click([] { /* resize the photo */ });
flyout->set_anchor(std::make_unique<ui::ButtonControl>("Photo")); // a Button anchor toggles it
window.set_content(std::move(flyout));

// Declaratively; open it through `.control`:
ui::Control<ui::CommandBarFlyout> photo_menu;
window.set_content(ui::CommandBarFlyout{
    .placement = ui::PopupPlacement::Right,
    .show_mode = ui::FlyoutShowMode::Transient,
    .control   = photo_menu,
    .anchor    = ui::Button{.text = "Photo", .on_click = [&] { photo_menu->show(); }},
    .primary   = {ui::AppBarButton{.text = "Share", .icon = ui::Symbol::Share},
                  ui::AppBarButton{.text = "Delete", .icon = ui::Symbol::Delete}},
    .secondary = {ui::AppBarButton{.text = "Resize"}},
});

CommandBarFlyoutControl

CommandBarFlyoutControl()

An empty flyout with no anchor.

~CommandBarFlyoutControl

~CommandBarFlyoutControl() override

Destroys every command and the presenter.

add_primary

template <typename T>
T* add_primary(std::unique_ptr<T> command)

Appends command to the icon row. Takes ownership and hands back a non-owning observer (the same convention as StackControl::add()).

add_secondary

template <typename T>
T* add_secondary(std::unique_ptr<T> command)

Appends command to the menu. Takes ownership and hands back a non-owning observer.

primary_count

std::size_t primary_count() const

The number of primary commands.

secondary_count

std::size_t secondary_count() const

The number of secondary commands.

primary

Element* primary(std::size_t index) const

The primary command at index as a non-owning observer, or nullptr when out of range.

secondary

Element* secondary(std::size_t index) const

The secondary command at index as a non-owning observer, or nullptr when out of range.

always_expanded

bool always_expanded() const

Whether the menu of secondary commands stays open, with no More button. False by default.

set_always_expanded

void set_always_expanded(bool always_expanded)

Takes effect the next time the flyout opens.

is_expanded

bool is_expanded() const

Whether the secondary menu shows. Every open resets it from the show mode: expanded for Standard when there are secondary commands, collapsed for Transient.

set_expanded

void set_expanded(bool expanded)

Expands or collapses the menu with a slide, as the More button does. Ignored while always_expanded(), so the menu stays expanded.

command_invoked

void command_invoked(CommandBarElement& command) override

Called when a command is clicked. A secondary command hides the flyout, and a primary one collapses the menu.

handle_global_shortcut

bool handle_global_shortcut(const KeyEvent& e) override

The shortcuts of the secondary commands and of the anchor fire app-wide.

tick_override

void tick_override(Duration delta) override

Runs the open/close fade and the menu's slide.

Tests

  • tests/test_command_bar.cpp