CalendarView¶
Header: winui/ui/datetime/CalendarView.hpp. Spec: winui/ui/datetime/CalendarView.hpp.
A month calendar: the days of one month in a grid of weeks, with the month's name above them and buttons to page through months.
Clicking a day selects it, and clicking a selected day removes it from the selection. Clicking the heading zooms out to the months of the year and then to the years of the decade, and clicking a month or a year zooms back in. The days of the neighboring months fill the first and last weeks, in a dimmed color when out_of_scope_enabled is true.
The names of the months and the days and the first day of the week come from regional_date_format() unless the calendar sets its own.
Each theme era draws its own month calendar: - Fluent 2 is 300 by 350 DIPs with round cells, today a filled accent circle and a selected day an accent ring. - Fluent and MDL2 are 296 by 332 with Windows 10's square cells: today a filled accent square, a selected day a 2 DIP accent border. - Aero and Metro are 225 by 160, the Vista design: a light blue box around the selected day, a blue outline around today, and a "Today:" line under the grid that goes to today. - Windows 9x and Luna are comctl32's month calendar: a title band in the caption color with the scroll bar's arrow buttons, the selected day a filled ellipse, today circled in red, and the "Today:" line. Clicking the title opens a menu of the months, Ctrl+PageUp and Ctrl+PageDown move by a year, and there is no hover. - Windows 3.x and 1.x/2.x had no month calendar and draw the classic one from their own parts.
Keyboard: the arrow keys move between days, Home and End go to the first and the last day of the month, PageUp and PageDown move by a month, Ctrl+Up zooms out and Ctrl+Down zooms in, and Enter or Space select the focused day or zoom into the focused month or year. The heading, the two paging buttons and the grid are four tab stops.
ui::CalendarView is the declarative form.
Example:
ui::CalendarViewControl calendar;
calendar.set_selection_mode(ui::CalendarViewSelectionMode::Multiple);
calendar.on_selected_dates_changed([](const std::vector<std::chrono::year_month_day>& dates)
{ std::printf("%zu days picked\n", dates.size()); });
ui::CalendarView¶
The declarative form of CalendarViewControl: a month calendar.
Example:
ui::Property<std::vector<std::chrono::year_month_day>> picked;
window.set_content(ui::CalendarView{
.selected_dates = picked,
.group_label_visible = true,
.is_blackout = [](std::chrono::year_month_day date)
{
const std::chrono::weekday day{std::chrono::sys_days{date}};
return day == std::chrono::Saturday || day == std::chrono::Sunday; // weekdays only
},
});
Every field, in the order a designated initializer names them:
ui::CalendarView{
.selected_dates, .min_date, .max_date, .selection_mode, .display_mode, .display_date,
.first_day_of_week, .today_highlighted, .out_of_scope_enabled, .group_label_visible,
.style, .margin, .width, .height, .min_width, .min_height, .max_width, .max_height,
.horizontal_alignment, .vertical_alignment, .visible, .tool_tip, .enabled, .accessibility,
.on_selected_dates_changed, .on_display_mode_changed, .on_pointer_entered,
.on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down, .on_wheel, .control,
.is_blackout
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
selected_dates |
ui::TwoWayField<std::vector<std::chrono::year_month_day>> |
The selected dates (CalendarViewControl::set_selected_dates()). | |
min_date |
ui::Binding<std::optional<std::chrono::year_month_day>> |
The first date shown; unset is January 1, 100 years before today. | |
max_date |
ui::Binding<std::optional<std::chrono::year_month_day>> |
The last date shown; unset is December 31, 100 years after today. | |
selection_mode |
ui::Binding<ui::CalendarViewSelectionMode> |
{ui::CalendarViewSelectionMode::Single} |
How many dates can be selected. |
display_mode |
ui::TwoWayField<ui::CalendarViewDisplayMode> |
{ui::CalendarViewDisplayMode::Month} |
Month, Year or Decade. |
display_date |
ui::Binding<std::optional<std::chrono::year_month_day>> |
The month (or year, or decade) shown; unset is today's. | |
first_day_of_week |
ui::Binding<std::optional<std::chrono::weekday>> |
The day the weeks start on; unset follows regional_date_format(). | |
today_highlighted |
ui::Binding<bool> |
{true} |
Whether today is drawn as a filled circle. |
out_of_scope_enabled |
ui::Binding<bool> |
{true} |
Whether the days of the neighboring months are dimmed. |
group_label_visible |
ui::Binding<bool> |
{false} |
Whether the first day of each month carries the month's name. |
on_selected_dates_changed |
ui::Callback<void(const std::vector<std::chrono::year_month_day>&)> |
The new selection, from input or a bound value. | |
on_display_mode_changed |
ui::Callback<void(ui::CalendarViewDisplayMode)> |
The new display mode, from input 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, before the control pages; ui::Handled stops it there (Element::on_wheel()). | |
control |
ui::ControlOut<ui::CalendarView> |
Out: the handle that receives the built control. | |
is_blackout |
ui::Callback<bool(std::chrono::year_month_day)> |
Marks dates that can't be selected; unset blocks none. |
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::CalendarViewControl; the caller owns it.
ui::CalendarViewControl¶
Derives from ui::Element, ui::GridProvider, ui::TableProvider, ui::SelectionProvider, ui::ValueProvider.
A month calendar: the days of one month in a grid of weeks, with the month's name above them and buttons to page through months.
Clicking a day selects it, and clicking a selected day removes it from the selection. Clicking the heading zooms out to the months of the year and then to the years of the decade, and clicking a month or a year zooms back in. The days of the neighboring months fill the first and last weeks, in a dimmed color when out_of_scope_enabled is true.
The names of the months and the days and the first day of the week come from regional_date_format() unless the calendar sets its own.
Each theme era draws its own month calendar: - Fluent 2 is 300 by 350 DIPs with round cells, today a filled accent circle and a selected day an accent ring. - Fluent and MDL2 are 296 by 332 with Windows 10's square cells: today a filled accent square, a selected day a 2 DIP accent border. - Aero and Metro are 225 by 160, the Vista design: a light blue box around the selected day, a blue outline around today, and a "Today:" line under the grid that goes to today. - Windows 9x and Luna are comctl32's month calendar: a title band in the caption color with the scroll bar's arrow buttons, the selected day a filled ellipse, today circled in red, and the "Today:" line. Clicking the title opens a menu of the months, Ctrl+PageUp and Ctrl+PageDown move by a year, and there is no hover. - Windows 3.x and 1.x/2.x had no month calendar and draw the classic one from their own parts.
Keyboard: the arrow keys move between days, Home and End go to the first and the last day of the month, PageUp and PageDown move by a month, Ctrl+Up zooms out and Ctrl+Down zooms in, and Enter or Space select the focused day or zoom into the focused month or year. The heading, the two paging buttons and the grid are four tab stops.
ui::CalendarView is the declarative form.
Example:
ui::CalendarViewControl calendar;
calendar.set_selection_mode(ui::CalendarViewSelectionMode::Multiple);
calendar.on_selected_dates_changed([](const std::vector<std::chrono::year_month_day>& dates)
{ std::printf("%zu days picked\n", dates.size()); });
CalendarViewControl¶
A calendar on today's month, in single selection, with nothing selected.
~CalendarViewControl¶
Destroys the parts.
CalendarViewControl¶
operator=¶
selected_dates¶
The selected dates, in the order they were selected.
set_selected_dates¶
Replaces the selection. Dates outside [min_date(), max_date()], blackout dates and repeats are dropped, and single selection keeps the first. Raises the change callback when the selection differs.
on_selected_dates_changed¶
void on_selected_dates_changed(Callback<void(const std::vector<std::chrono::year_month_day>&)> handler)
Called after the selection changed, from input or a setter, with the new selection.
selection_mode¶
How many dates can be selected. Switching to None clears the selection and to Single keeps the first date.
set_selection_mode¶
See selection_mode().
min_date¶
The first date the calendar shows: unset is January 1, 100 years before today.
max_date¶
The last date the calendar shows: unset is December 31, 100 years after today.
set_date_range¶
void set_date_range(std::optional<std::chrono::year_month_day> min, std::optional<std::chrono::year_month_day> max)
Sets the range; unset follows today. A selected date outside it is dropped.
display_mode¶
Month, Year or Decade.
set_display_mode¶
Zooms to mode, animated where the theme animates.
on_display_mode_changed¶
Called after the display mode changed, from input or a setter.
display_date¶
A date in the month (or year, or decade) the calendar shows.
set_display_date¶
Shows the month, year or decade date is in, clamped to the range.
first_day_of_week¶
The day the weeks start on; unset follows regional_date_format().
set_first_day_of_week¶
See first_day_of_week().
today_highlighted¶
Whether today is drawn as a filled circle. True by default.
set_today_highlighted¶
See today_highlighted().
out_of_scope_enabled¶
Whether the days of the neighboring months are dimmed. True by default.
set_out_of_scope_enabled¶
group_label_visible¶
Whether the first day of each month carries the month's abbreviated name above its number (and January, in the year view, the year). False by default.
set_group_label_visible¶
set_blackout¶
Marks dates that can't be selected: they are drawn struck through and skipped by the selection. Unset blocks none.
is_blackout¶
Whether date is a blackout date.
set_today¶
The day drawn as today: unset (the default) is ui::today(). A test or a demo pins it.
today¶
The day drawn as today.
focused_date¶
The day the keyboard is on in the month view: the selected day, or today, until an arrow key moves it.
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.
focus_ring_rect¶
What the ring goes around, in window DIPs: bounds() by default. A control whose ring goes around one part of it (a slider's thumb, a list's current row) returns that part. theme is the one the element is drawn with, for a ring placed differently in each era.
focus_ring_corner_radius¶
The ring's corner radius: the theme's control radius by default.
focus_ring_inside¶
Whether the ring goes inside focus_ring_rect() in every era, its outer edge on the rect. False by default, which leaves it to the theme. An item inside a viewport (a list row, a tab, a menu item) returns true, as does a control in a tight spot, so a neighbor or the viewport edge never cuts its ring.
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¶
The heading, the two paging buttons, then the grid, as four tab stops.
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.
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.
Enumerations¶
CalendarViewSelectionMode¶
How many dates a CalendarView lets the user select.
| Value | |
|---|---|
None |
Days can't be selected; the calendar only shows dates. |
Single |
One date at a time: a click replaces the selection (the default). |
Multiple |
Any number of dates: a click adds or removes one. |
CalendarViewDisplayMode¶
What a CalendarView shows.
| Value | |
|---|---|
Month |
The days of one month, six weeks at a time (the default). |
Year |
The months of one year. |
Decade |
The years of one decade. |
Tests¶
tests/test_calendar_view.cpp