DatePicker¶
Header: winui/ui/datetime/DatePicker.hpp. Spec: winui/ui/datetime/DatePicker.hpp.
A field that shows a date in its parts (day, month and year, in the order the locale writes them) and opens a flyout of three spinning columns to pick one.
The flyout opens on the date, or on today while there is none. A click, Enter, Space or Alt+Down opens it. In the flyout the arrow keys, the wheel or a click on a row turn a column, Left and Right move between the columns, and Enter or the check mark button keeps the choice. Escape, a click outside or the cross drops it. Turning the month or the year keeps the day where it fits: January 31 becomes February 28.
Each theme era draws its own: Fluent's field and flyout, Windows 8.1's three drop-down lists under Metro, and comctl32's date picker under Aero, Luna and the classic eras, edited in place with the arrow keys and typed digits, with a drop-down button that opens the era's month calendar.
ui::DatePicker is the declarative form.
Example:
ui::DatePickerControl picker;
picker.set_header("Birthday");
picker.set_year_range(1900, 2026);
picker.on_selected_date_changed([](std::optional<std::chrono::year_month_day> date)
{ std::printf("%s\n", date ? "set" : "cleared"); });
ui::DatePicker¶
The declarative form of DatePickerControl: a date in its parts, picked from spinning columns.
Example:
ui::Property<std::optional<std::chrono::year_month_day>> birthday;
window.set_content(ui::DatePicker{
.header = "Birthday",
.selected_date = birthday,
.min_year = 1900,
});
Every field, in the order a designated initializer names them:
ui::DatePicker{
.header, .selected_date, .min_year, .max_year, .day_visible, .month_visible, .year_visible,
.style, .margin, .width, .height, .min_width, .min_height, .max_width, .max_height,
.horizontal_alignment, .vertical_alignment, .visible, .tool_tip, .enabled, .accessibility,
.on_selected_date_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 | |
|---|---|---|---|
header |
ui::Binding<std::string> |
The label above the field. Empty shows none. | |
selected_date |
ui::TwoWayField<std::optional<std::chrono::year_month_day>> |
The picked date; unset until one is picked. | |
min_year |
ui::Binding<std::optional<int>> |
The first year offered; unset is 100 years before today. | |
max_year |
ui::Binding<std::optional<int>> |
The last year offered; unset is 100 years after today. | |
day_visible |
ui::Binding<bool> |
{true} |
Whether the day shows. |
month_visible |
ui::Binding<bool> |
{true} |
Whether the month shows. |
year_visible |
ui::Binding<bool> |
{true} |
Whether the year shows. |
on_selected_date_changed |
ui::Callback<void(std::optional<std::chrono::year_month_day>)> |
The new date (unset when cleared), from the flyout 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. | |
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; ui::Handled stops it there (Element::on_wheel()). | |
control |
ui::ControlOut<ui::DatePicker> |
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::DatePickerControl; the caller owns it.
ui::DatePickerControl¶
Derives from ui::Element, ui::InvokeProvider, ui::ValueProvider.
A field that shows a date in its parts (day, month and year, in the order the locale writes them) and opens a flyout of three spinning columns to pick one.
The flyout opens on the date, or on today while there is none. A click, Enter, Space or Alt+Down opens it. In the flyout the arrow keys, the wheel or a click on a row turn a column, Left and Right move between the columns, and Enter or the check mark button keeps the choice. Escape, a click outside or the cross drops it. Turning the month or the year keeps the day where it fits: January 31 becomes February 28.
Each theme era draws its own: Fluent's field and flyout, Windows 8.1's three drop-down lists under Metro, and comctl32's date picker under Aero, Luna and the classic eras, edited in place with the arrow keys and typed digits, with a drop-down button that opens the era's month calendar.
ui::DatePicker is the declarative form.
Example:
ui::DatePickerControl picker;
picker.set_header("Birthday");
picker.set_year_range(1900, 2026);
picker.on_selected_date_changed([](std::optional<std::chrono::year_month_day> date)
{ std::printf("%s\n", date ? "set" : "cleared"); });
DatePickerControl¶
A picker with no date, its years 100 back and ahead of today.
~DatePickerControl¶
DatePickerControl¶
operator=¶
selected_date¶
The picked date; unset until one is picked.
set_selected_date¶
Sets the date, clamped to the years. Raises the change callback when it differs.
on_selected_date_changed¶
Called after the date changed, from the flyout or a setter, with the new date.
min_year¶
The first year offered; 100 years before today until set.
max_year¶
The last year offered; 100 years after today until set.
set_year_range¶
Sets the years offered; unset follows today. A date outside them is clamped.
set_parts_visible¶
Which parts the field and the flyout show; all three by default.
set_header¶
The label above the field. Empty shows none.
is_open¶
Whether the flyout is open.
set_open¶
Opens or closes the flyout (or, in the comctl32 eras, the calendar).
focusable¶
Whether this element can take keyboard focus (a leaf control opts in).
automation_role¶
What screen readers and other assistive tools see of this node: the role, name, help text and children here, and what a client can do with the node through the providers automation_providers() lists (ui/Automation.hpp).
automation_role() is the role this node reports; Group by default.
automation_name_fallback¶
automation_name()'s fallback when accessibility().name is empty. Default: no inherent name, correct for controls with no visible text of their own (Slider, ProgressBar), which need an explicit accessibility().name from the caller. A control with its own visible text (Button, CheckBox, TextControl, ...) overrides this to return it.
for_each_child¶
Call visit once for each child this element owns, in order (back to front where they overlap). The one override a container needs beyond measure, arrange and render. The default of every tree-wide walk recurses through it (collect_focusables(), the popup walk, clear_dirty(), build_visual_tree(), sync_composition(), sync_native(), tick() and automation_children()), so a custom container that lists its children here gets focus, popups, dirty clearing, ticks, composition, native controls and automation right without forwarding any of them. Default: no children, a leaf.
List the children the walks should reach, normally every one this element owns. A walk that must see a different set overrides that walk alone: a composite that is one tab stop and one automation node, a split view leaving its closed pane out of focus and popups. A control that parks parts (an unselected page, a hidden button) may leave them out here instead and clear them in clear_dirty_override() (and tick them in tick_override()), so a parked part never stays dirty.
Const so the const walks can use it, though it hands out mutable children: they are owned objects of their own, not part of this element's state. A tick can run a handler that adds or removes children, so a container that allows that walks its list by index.
Example:
class Row : public ui::Element
{
void for_each_child(ui::ChildVisitor visit) const override
{
for (const auto& child : children_)
{
visit(*child);
}
}
std::vector<std::unique_ptr<ui::Element>> children_;
};
collect_focusables¶
Append focusable elements in tab order, so the Window can build a flat focus ring over the whole tree. The default pushes this element when focusable(), then recurses into every child for_each_child() lists. Override it when the ring differs from the children: a composite that is one tab stop pushes only itself, a focus scope stops recursing (see collect_scope_focusables()), a pager leaves out its hidden pages.
automation_children¶
The children an automation client sees under this node, immediate children only. A client walks the tree one level at a time, and the parent comes from parent(). Defaults to every child for_each_child() lists. Override it only to show a client something else: the children in a different order, or without parts that are only decoration. A composite that is one automation node lists nothing.
measure_override¶
Implement these instead of measure() and arrange(). The base class has already applied margin, size limits and alignment by the time these run. measure_override() is pure (every concrete Element must size itself); arrange_override() defaults to a no-op since most leaves need nothing beyond having bounds() set, which the base already did.
arrange_override¶
Position children within the rect arrange() settled on (also in bounds(), window DIPs). Default: nothing, for a leaf.
render_override¶
What the control draws, in layout coordinates; render() has already applied the visual layer. A container draws its children through their render(), never their render_override().
pointer_override¶
A pointer event for this element: the element under the pointer, one inside it that did not handle the event, or the element holding the capture. The position is in layout coordinates (handle_pointer()). Return true when the event did something here, and it goes no further up; a handled press also captures the pointer until its release. A control that acts on a press (a click, a toggle, a caret placed, a drag started) returns true for the press and its release, so a list row or a card around it does not act on the same click. Default: false.
key_override¶
A key for this element: the focused one, or one inside it that did not handle it. Return true when the key did something here, and it goes no further; false lets it bubble on to the parent and then to the shortcuts, a dialog's default button and arrow-key focus moves. Default: false.
text_override¶
Typed text for this element, routed like key_override(). Default: false.
tick_override¶
This element's own part of tick(): a clock of its own (ToolTip's hover delay, an animation's phase, a caret blink). Runs after the visual layer has advanced and before the children are ticked, which tick() does by itself. Tick only parts that for_each_child() does not list here. Default: nothing.
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¶
Keyboard focus arrived (true) or left (false); is_focused() already says so. The element is redrawn either way. No-op by default.
Tests¶
tests/test_date_picker.cpp