PipsPager¶
Header: winui/ui/navigation/PipsPager.hpp. Spec: winui/ui/navigation/PipsPager.hpp.
A strip of small dots, one per page, for paging through a large item set such as a Carousel's pictures.
The selected page's dot is drawn larger, in the same color. Optional previous/next buttons flank the strip and hide at their own end of the range unless PipsPagerWrapMode::Wrap. At most max_visible_pips() dots are shown, and the shown range follows the selection. With number_of_pages() unset (the default) the page count is open-ended, and the list grows by one whenever the selection reaches its last pip. The whole strip is a single tab stop. The arrow keys along its axis step the selection, and Home/End jump to the ends. Hover never changes its measured size. ui::PipsPager is the declarative form.
Example:
ui::Property<std::size_t> page{0};
window.set_content(ui::VerticalStack{
.spacing = 12,
.content = {
ui::Text{.text = ui::bind(page, [](std::size_t p) { return std::format("Page {}", p + 1); })},
ui::PipsPager{
.selected_index = page,
.number_of_pages = 8,
.previous_button_visibility = ui::PipsPagerButtonVisibility::VisibleOnPointerOver,
.next_button_visibility = ui::PipsPagerButtonVisibility::VisibleOnPointerOver,
},
},
});
// Imperatively:
auto pager = std::make_unique<ui::PipsPagerControl>(/*number_of_pages=*/10);
pager->set_orientation(ui::Orientation::Vertical);
pager->set_wrap_mode(ui::PipsPagerWrapMode::Wrap);
pager->on_selection_changed([](std::size_t index) { /* show page `index` */ });
ui::PipsPager¶
A row of page dots. Builds a ui::PipsPagerControl.
Example:
ui::Property<std::size_t> picture{0};
window.set_content(ui::PipsPager{
.selected_index = picture,
.number_of_pages = 8,
.previous_button_visibility = ui::PipsPagerButtonVisibility::VisibleOnPointerOver,
.next_button_visibility = ui::PipsPagerButtonVisibility::VisibleOnPointerOver,
.horizontal_alignment = ui::Alignment::Center,
});
Every field, in the order a designated initializer names them:
ui::PipsPager{
.selected_index, .number_of_pages, .max_visible_pips, .orientation,
.previous_button_visibility, .next_button_visibility, .wrap_mode, .style, .margin, .width,
.height, .min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
.vertical_alignment, .visible, .tool_tip, .enabled, .accessibility, .on_selection_changed,
.on_pointer_entered, .on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down,
.on_wheel, .control
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
selected_index |
ui::TwoWayField<std::size_t> |
{0} |
The current page, 0-based. |
number_of_pages |
ui::Binding<std::optional<std::size_t>> |
The page count; nullopt (the default) is open-ended. | |
max_visible_pips |
ui::Binding<std::size_t> |
{5} |
How many pips show at once; the window of pips follows the selection. |
orientation |
ui::Binding<ui::Orientation> |
{ui::Orientation::Horizontal} |
Horizontal (the default) or Vertical. |
previous_button_visibility |
ui::Binding<ui::PipsPagerButtonVisibility> |
{ui::PipsPagerButtonVisibility::Collapsed} |
How the previous button shows: Collapsed (the default), Visible, or only on pointer-over. |
next_button_visibility |
ui::Binding<ui::PipsPagerButtonVisibility> |
{ui::PipsPagerButtonVisibility::Collapsed} |
How the next button shows, as previous_button_visibility. |
wrap_mode |
ui::Binding<ui::PipsPagerWrapMode> |
{ui::PipsPagerWrapMode::None} |
What happens at the ends: Wrap lets Next go from the last page to the first and Previous back around. |
on_selection_changed |
ui::Callback<void(std::size_t)> |
Called with the new page index, from a pip, a button, a key or a bound value. | |
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::PipsPager> |
Out: the handle that receives the built control. |
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::PipsPagerControl; the caller owns it.
ui::PipsPagerControl¶
Derives from ui::Element, ui::RangeValueProvider.
A strip of small dots, one per page, for paging through a large item set such as a Carousel's pictures.
The selected page's dot is drawn larger, in the same color. Optional previous/next buttons flank the strip and hide at their own end of the range unless PipsPagerWrapMode::Wrap. At most max_visible_pips() dots are shown, and the shown range follows the selection. With number_of_pages() unset (the default) the page count is open-ended, and the list grows by one whenever the selection reaches its last pip. The whole strip is a single tab stop. The arrow keys along its axis step the selection, and Home/End jump to the ends. Hover never changes its measured size. ui::PipsPager is the declarative form.
Example:
ui::Property<std::size_t> page{0};
window.set_content(ui::VerticalStack{
.spacing = 12,
.content = {
ui::Text{.text = ui::bind(page, [](std::size_t p) { return std::format("Page {}", p + 1); })},
ui::PipsPager{
.selected_index = page,
.number_of_pages = 8,
.previous_button_visibility = ui::PipsPagerButtonVisibility::VisibleOnPointerOver,
.next_button_visibility = ui::PipsPagerButtonVisibility::VisibleOnPointerOver,
},
},
});
// Imperatively:
auto pager = std::make_unique<ui::PipsPagerControl>(/*number_of_pages=*/10);
pager->set_orientation(ui::Orientation::Vertical);
pager->set_wrap_mode(ui::PipsPagerWrapMode::Wrap);
pager->on_selection_changed([](std::size_t index) { /* show page `index` */ });
PipsPagerControl¶
PipsPagerControl(std::optional<std::size_t> number_of_pages = std::nullopt, std::size_t selected_index = 0)
number_of_pages nullopt (the default) is an unknown, open-ended count.
PipsPagerControl¶
template <std::signed_integral I>
PipsPagerControl(I number_of_pages, std::size_t selected_index = 0)
As above, with a count given as a signed number, which must not be negative.
number_of_pages¶
The page count; nullopt for an open-ended count (see infinite()).
set_number_of_pages¶
Sets the page count; nullopt is an open-ended count (see infinite()). Clamps selected_index() into the new range, firing on_selection_changed() if that moves it.
set_number_of_pages¶
A count given as a signed number, which must not be negative. Pass std::nullopt for an open-ended count.
infinite¶
Whether the page count is open-ended: Next never hides and the pip list grows as the selection advances.
selected_index¶
The current page, 0-based; 0 by default and with no pages.
set_selected_index¶
Selects page index, clamped to [0, number_of_pages()-1], or to 0 with no pages. With an open-ended count there is no upper limit. Does nothing, and fires nothing, if the page is already selected.
max_visible_pips¶
The most pips shown at once; 5 by default.
set_max_visible_pips¶
Sets how many pips are shown at once. The shown range of pages keeps the selection roughly centered and stops at the ends, with no smooth scrolling. Changes the control's measured size.
orientation¶
Horizontal by default.
set_orientation¶
Swaps the strip's axes; updates the layout and redraws.
previous_button_visibility¶
How the previous button shows; Collapsed by default.
set_previous_button_visibility¶
Updates the layout. Only Collapsed gives up the reserved 24x24 DIP slot.
next_button_visibility¶
How the next button shows; Collapsed by default.
set_next_button_visibility¶
Updates the layout. Only Collapsed gives up the reserved 24x24 DIP slot.
wrap_mode¶
What happens at the ends; None by default.
set_wrap_mode¶
Sets what happens at the ends and redraws, since the edge buttons may appear or hide.
previous_button_visible¶
Whether the previous button is drawn and can be clicked right now. It must not be Collapsed or hidden at its edge, and with VisibleOnPointerOver the pointer must be over the pager or focus in it.
next_button_visible¶
The Next button's counterpart of previous_button_visible().
on_selection_changed¶
Fired whenever selected_index() changes: by a pip click, a button click, an arrow key, Home/End, or set_selected_index().
focused¶
Whether the strip has keyboard focus.
focusable¶
Not a tab stop while there is nothing to switch between.
automation_role¶
Exposed to accessibility tools as a spin button whose range value is the page index.
previous_button_visual_state¶
The Previous button's hover/pressed/disabled state as drawn; pips have no ButtonState.
next_button_visual_state¶
The Next button's hover/pressed/disabled state as drawn.
measure_override¶
A fixed-size strip: min(max_visible_pips, number_of_pages) pip slots, each 12 DIPs along the main axis by 24 across it, plus a 24x24 DIP square for each button that is not Collapsed, in either orientation. Hover never changes it, only the properties above do.
pointer_override¶
A click on a pip selects its page. A click on a button steps as PipsPagerWrapMode allows.
render_override¶
Draws the visible dots (the selected one larger), the button glyphs and the focus ring.
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.
focus_changed¶
Focus also reveals VisibleOnPointerOver buttons.
key_override¶
Arrow keys along the axis step the selection, following PipsPagerWrapMode. Home/End jump to the first/last page. End does nothing with an open-ended count.
Enumerations¶
PipsPagerButtonVisibility¶
How a PipsPager shows its previous or next button.
| Value | |
|---|---|
Visible |
Shown whenever it has somewhere to go. |
VisibleOnPointerOver |
Shown only while the pointer is over the pager or it has focus; its slot is reserved either way. |
Collapsed |
Not shown and takes no space (the default). |
PipsPagerWrapMode¶
What a PipsPager's previous/next buttons and arrow keys do at the ends.
| Value | |
|---|---|
None |
Stop at the first/last page; the button at that edge hides (the default). |
Wrap |
Next from the last page goes to the first, Previous from the first to the last. |
Tests¶
tests/test_pips_pager.cpp