ProgressBar¶
Header: winui/ui/status/ProgressBar.hpp. Spec: winui/ui/status/ProgressBar.hpp.
A thin horizontal bar showing determinate progress, or an endless sweep while the duration is unknown.
Determinate, a pill-shaped accent indicator covers the fraction of [min(), max()] that value() has reached, over a 1 DIP track; it jumps to each new value without animating. Indeterminate, two bars sweep across in a 2-second loop. show_paused() / show_error() tint the indicator in the caution / critical color (error wins) and freeze an indeterminate sweep into one full-width bar. The bar is 3 DIPs tall and 200 DIPs wide unless its slot is narrower; it takes no input and has no disabled state.
Under Aero it is the era's bar instead: 15 DIPs tall, framed and glossy, with a glint that crosses the filled part at 200 DIPs a second and rests a second between passes. An indeterminate Aero bar runs the glint over the empty track.
Under Windows 9x it is 16 DIPs tall: a face-colored well with a 1 DIP sunken edge, filled with highlight-colored chunks two thirds as wide as they are tall, 2 DIPs apart. Under Windows 3.x and Windows 1.x it is one solid block inside a 1 DIP frame, black on white under Windows 1.x. Indeterminate, each sweeps a band across the well: five chunks under Windows 9x, a quarter of the bar under the other two. ui::ProgressBar is the declarative form.
Example:
ui::Property<double> progress{0.0};
window.set_content(ui::VerticalStack{
.spacing = 12,
.content = {
ui::ProgressBar{.value = progress, .width = 200.0f,
.accessibility = {.name = "Download progress"}},
ui::ProgressBar{.width = 200.0f},
ui::Button{.text = "Step", .on_click = [&] { progress += 10.0; }},
},
});
// Imperatively:
auto bar = std::make_unique<ui::ProgressBarControl>(/*value=*/0.0, /*min=*/0.0, /*max=*/1.0);
bar->on_value_changed([](double v) { /* v is already clamped to [0, 1] */ });
bar->set_value(0.25);
bar->set_show_paused(true); // amber indicator
ui::ProgressBar¶
A determinate or indeterminate horizontal progress bar. Builds a ui::ProgressBarControl.
Example:
ui::Property<double> progress{0.0};
window.set_content(ui::VerticalStack{
.spacing = 8,
.content = {
ui::ProgressBar{.value = progress, .width = 200.0f},
ui::ProgressBar{.width = 200.0f}, // no value: an indeterminate sweep
ui::Button{.text = "Step", .on_click = [&] { progress += 10.0; }},
},
});
Every field, in the order a designated initializer names them:
ui::ProgressBar{
.value, .min, .max, .show_paused, .show_error, .style, .margin, .width, .height,
.min_width, .min_height, .max_width, .max_height, .horizontal_alignment,
.vertical_alignment, .visible, .tool_tip, .accessibility, .on_value_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 | |
|---|---|---|---|
value |
ui::Binding<std::optional<double>> |
Value, clamped to [min, max]; the filled share of the bar. Unset (the default) is an endless sweep, for work whose length is unknown. |
|
min |
double |
0.0 |
The value of the empty bar. Fixed at build time. |
max |
double |
100.0 |
The value of the full bar. Fixed at build time. |
show_paused |
ui::Binding<bool> |
{false} |
The indicator in the caution color, and an indeterminate sweep frozen into a full bar. |
show_error |
ui::Binding<bool> |
{false} |
As show_paused, in the critical color. |
on_value_changed |
ui::Callback<void(double)> |
The new (clamped) value, whenever a bound value moves 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::ProgressBar> |
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, accessibility every spec carries (conventions).
build¶
Consumes the spec and returns the built ui::ProgressBarControl; the caller owns it.
ui::ProgressBarControl¶
Derives from ui::Element, ui::RangeValueProvider.
A thin horizontal bar showing determinate progress, or an endless sweep while the duration is unknown.
Determinate, a pill-shaped accent indicator covers the fraction of [min(), max()] that value() has reached, over a 1 DIP track; it jumps to each new value without animating. Indeterminate, two bars sweep across in a 2-second loop. show_paused() / show_error() tint the indicator in the caution / critical color (error wins) and freeze an indeterminate sweep into one full-width bar. The bar is 3 DIPs tall and 200 DIPs wide unless its slot is narrower; it takes no input and has no disabled state.
Under Aero it is the era's bar instead: 15 DIPs tall, framed and glossy, with a glint that crosses the filled part at 200 DIPs a second and rests a second between passes. An indeterminate Aero bar runs the glint over the empty track.
Under Windows 9x it is 16 DIPs tall: a face-colored well with a 1 DIP sunken edge, filled with highlight-colored chunks two thirds as wide as they are tall, 2 DIPs apart. Under Windows 3.x and Windows 1.x it is one solid block inside a 1 DIP frame, black on white under Windows 1.x. Indeterminate, each sweeps a band across the well: five chunks under Windows 9x, a quarter of the bar under the other two. ui::ProgressBar is the declarative form.
Example:
ui::Property<double> progress{0.0};
window.set_content(ui::VerticalStack{
.spacing = 12,
.content = {
ui::ProgressBar{.value = progress, .width = 200.0f,
.accessibility = {.name = "Download progress"}},
ui::ProgressBar{.width = 200.0f},
ui::Button{.text = "Step", .on_click = [&] { progress += 10.0; }},
},
});
// Imperatively:
auto bar = std::make_unique<ui::ProgressBarControl>(/*value=*/0.0, /*min=*/0.0, /*max=*/1.0);
bar->on_value_changed([](double v) { /* v is already clamped to [0, 1] */ });
bar->set_value(0.25);
bar->set_show_paused(true); // amber indicator
ProgressBarControl¶
A determinate bar; max below min is raised to min, and value is clamped into the range.
min¶
The value at which the bar is empty; 0 by default.
max¶
The value at which the bar is full; 100 by default.
set_range¶
Sets both ends (max below min becomes min) and re-clamps value(), firing on_value_changed() if that moves it. Always marks the bar for redraw.
value¶
The value, always within [min(), max()]; 0 by default. Ignored while indeterminate.
set_value¶
Clamps into the range (to min() for an empty range). Does nothing, and fires no callback, when the clamped value is unchanged. Otherwise redraws and fires on_value_changed().
is_indeterminate¶
Whether it shows an endless sweep instead of a filled share; false by default.
set_indeterminate¶
Redraws only. Turning the sweep on always restarts its phase from the beginning.
show_paused¶
The indicator in the caution color; false by default.
set_show_paused¶
Marks the bar for redraw.
show_error¶
The indicator in the critical color, winning over show_paused(); false by default.
set_show_error¶
Marks the bar for redraw.
on_value_changed¶
Fired with the new, clamped value whenever value() changes. Replaces any previous handler.
parallel_measure_safe¶
True: measuring reads nothing shared.
automation_role¶
ProgressBar, with a range value that UI Automation can read but not set, since the bar takes no input.
measure_override¶
200 x 3 DIPs (15 tall under Aero), the width capped at a bounded available width.
render_override¶
Draws the track, then the determinate indicator or the two clipped sweep bars.
tick_override¶
Advances the indeterminate sweep's phase clock while indeterminate and neither paused nor in error; a determinate bar ignores ticks, except under Aero, where the glint runs while there is progress to show.
Tests¶
tests/test_progress_bar.cpp