Scroll¶
Headers: winui/ui/scrolling/Scroll.hpp, winui/ui/scrolling/ScrollBarOverlay.hpp. Spec: winui/ui/scrolling/Scroll.hpp.
A viewport that scrolls and zooms one child, with overlay scroll bars.
The child is measured without a limit along the scrolling axes (content_orientation()) and drawn clipped and offset. Offsets are in zoomed DIPs, from 0 to scrollable_width() and scrollable_height(). The wheel scrolls, Ctrl+wheel zooms while zoom_mode() allows it, the bars drag and step, and with set_focusable() the keys scroll too. scroll_to(), scroll_by(), zoom_to(), zoom_by() and add_scroll_velocity() move it from code, animated by default. Each returns a correlation id that its completed event reports. The declarative form is ui::Scroll.
Example:
auto view = std::make_unique<ui::ScrollControl>();
view->set_height(300.0f);
view->set_zoom_mode(ui::ScrollZoomMode::Enabled);
auto* list = view->set_child(std::make_unique<ui::StackControl>(ui::Orientation::Vertical));
for (int i = 0; i < 100; ++i)
{
list->add(std::make_unique<ui::TextControl>(std::format("Row {}", i)));
}
view->on_view_changed([v = view.get()] { std::println("at {}", v->vertical_offset()); });
view->on_scroll_completed([](int id) { std::println("scroll {} done", id); });
ui::ScrollControl* observer = view.get();
window.set_content(std::move(view));
observer->scroll_to(0.0f, 500.0f); // animated; lands after the first layout if called before it
ui::Scroll¶
A scrollable, zoomable viewport around one child. Builds a ui::ScrollControl. The modes and bar visibilities can be bound.
Give it a bounded size, such as a height, a star grid row or a window, or it grows to its content and has nothing to scroll. horizontal_offset, vertical_offset and zoom_factor bind two-way: the user's scrolling writes them, and writing them moves the view at once. Animated scrolling goes through .control: scroll_to(), scroll_by(), zoom_to().
Example:
const std::string long_text = "A text much taller than the window...";
ui::Property<float> position{0.0f};
ui::Control<ui::Scroll> scroller;
window.set_content(ui::VerticalStack{.content = {
ui::Button{.text = "Back to top", .on_click = [&] { scroller->scroll_to(0.0f, 0.0f); }},
ui::Text{.text = ui::bind(position, [](float y) { return std::format("{:.0f} DIPs down", y); })},
ui::Scroll{
.vertical_offset = position, // follows the user's scrolling; writing it jumps
.zoom_mode = ui::ScrollZoomMode::Enabled,
.height = 400.0f,
.control = scroller,
.content = ui::Text{.text = long_text, .wrapping = ui::TextWrapping::Wrap},
},
}});
Every field, in the order a designated initializer names them:
ui::Scroll{
.horizontal_offset, .vertical_offset, .zoom_factor, .min_zoom_factor, .max_zoom_factor,
.content_orientation, .horizontal_scroll_mode, .vertical_scroll_mode, .zoom_mode,
.horizontal_scroll_bar_visibility, .vertical_scroll_bar_visibility, .focusable,
.horizontal_scroll_chain_mode, .vertical_scroll_chain_mode, .background, .pan_on_drag,
.style, .margin, .width, .height, .min_width, .min_height, .max_width, .max_height,
.horizontal_alignment, .vertical_alignment, .visible, .tool_tip, .enabled, .accessibility,
.on_view_changed, .on_scroll_completed, .on_zoom_completed, .on_scroll_animation_starting,
.on_pointer_entered, .on_pointer_exited, .on_got_focus, .on_lost_focus, .on_key_down,
.on_wheel, .control, .content
}
Fields, in declaration order (designators must follow it):
| Field | Type | Default | |
|---|---|---|---|
horizontal_offset |
ui::TwoWayField<float> |
{0.0f} |
How far the view is scrolled right, in zoomed DIPs. Two-way: the user's scrolling writes it, and a write moves the view at once, where scroll_to() animates. Clamped to the scrollable range, and the clamped value is written back. A write before the first layout lands once the content has a size. |
vertical_offset |
ui::TwoWayField<float> |
{0.0f} |
How far the view is scrolled down, in zoomed DIPs. Two-way, as horizontal_offset. |
zoom_factor |
ui::TwoWayField<float> |
{1.0f} |
The zoom factor. Two-way, as horizontal_offset. A write zooms at once about the viewport's center, clamped to the zoom range below, where zoom_to() animates. |
min_zoom_factor |
ui::Binding<float> |
{ui::ScrollControl::DefaultMinZoomFactor} |
The smallest zoom the user can reach. |
max_zoom_factor |
ui::Binding<float> |
{ui::ScrollControl::DefaultMaxZoomFactor} |
The largest zoom the user can reach. |
content_orientation |
ui::Binding<ui::ScrollContentOrientation> |
{ui::ScrollContentOrientation::Vertical} |
The axis the content is free to grow along (Vertical, Horizontal, Both or None). The other axis is measured at the viewport's size. |
horizontal_scroll_mode |
ui::Binding<ui::ScrollMode> |
{ui::ScrollMode::Auto} |
Whether user input may scroll this axis. |
vertical_scroll_mode |
ui::Binding<ui::ScrollMode> |
{ui::ScrollMode::Auto} |
Whether user input may scroll this axis. |
zoom_mode |
ui::Binding<ui::ScrollZoomMode> |
{ui::ScrollZoomMode::Disabled} |
Enabled lets Ctrl+wheel zoom, 10 % a notch, between the zoom factors. |
horizontal_scroll_bar_visibility |
ui::Binding<ui::ScrollBarVisibility> |
{ui::ScrollBarVisibility::Auto} |
Auto shows the bar only when there is something to scroll. |
vertical_scroll_bar_visibility |
ui::Binding<ui::ScrollBarVisibility> |
{ui::ScrollBarVisibility::Auto} |
Auto shows the bar only when there is something to scroll. |
focusable |
bool |
false |
The viewport itself takes focus, for keyboard scrolling of content with nothing focusable in it. Off by default. |
horizontal_scroll_chain_mode |
ui::Binding<ui::ScrollChainMode> |
{ui::ScrollChainMode::Auto} |
Whether a wheel turn goes on to the scroller around it (ui::ScrollChainMode). Auto passes on a turn this view is at the end of, and Never keeps it. |
vertical_scroll_chain_mode |
ui::Binding<ui::ScrollChainMode> |
{ui::ScrollChainMode::Auto} |
As above. |
background |
ui::Binding<ui::Paint> |
Background behind the content: a Color, or a ThemeColor read from the theme. Empty, the default, draws none. | |
pan_on_drag |
ui::Binding<bool> |
{false} |
Dragging the content with the left button moves the view (ScrollControl::pan_on_drag()). Off by default. |
on_view_changed |
ui::Callback<void()> |
An offset or the zoom factor changed. | |
on_scroll_completed |
ui::Callback<void(int)> |
A scroll finished, with the correlation id scroll_to()/scroll_by() returned. | |
on_zoom_completed |
ui::Callback<void(int)> |
A zoom finished, with the correlation id zoom_to()/zoom_by() returned. | |
on_scroll_animation_starting |
ui::Callback<void(ui::ScrollAnimationStarting&)> |
Edit the args' animation to change its duration or path. | |
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::Scroll> |
Out: the handle that receives the built control. | |
content |
ui::Spec |
The scrolled content. |
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::ScrollControl; the caller owns it.
ui::ScrollControl¶
Derives from ui::Element, ui::ScrollProvider.
A viewport that scrolls and zooms one child, with overlay scroll bars.
The child is measured without a limit along the scrolling axes (content_orientation()) and drawn clipped and offset. Offsets are in zoomed DIPs, from 0 to scrollable_width() and scrollable_height(). The wheel scrolls, Ctrl+wheel zooms while zoom_mode() allows it, the bars drag and step, and with set_focusable() the keys scroll too. scroll_to(), scroll_by(), zoom_to(), zoom_by() and add_scroll_velocity() move it from code, animated by default. Each returns a correlation id that its completed event reports. The declarative form is ui::Scroll.
Example:
auto view = std::make_unique<ui::ScrollControl>();
view->set_height(300.0f);
view->set_zoom_mode(ui::ScrollZoomMode::Enabled);
auto* list = view->set_child(std::make_unique<ui::StackControl>(ui::Orientation::Vertical));
for (int i = 0; i < 100; ++i)
{
list->add(std::make_unique<ui::TextControl>(std::format("Row {}", i)));
}
view->on_view_changed([v = view.get()] { std::println("at {}", v->vertical_offset()); });
view->on_scroll_completed([](int id) { std::println("scroll {} done", id); });
ui::ScrollControl* observer = view.get();
window.set_content(std::move(view));
observer->scroll_to(0.0f, 500.0f); // animated; lands after the first layout if called before it
DefaultMinZoomFactor¶
The default min_zoom_factor().
DefaultMaxZoomFactor¶
The default max_zoom_factor().
ScrollControl¶
An empty view: vertical content orientation, Auto modes and bars, zoom disabled.
set_child¶
Takes ownership of the scrollable content and returns a non-owning pointer to it, as StackControl::add does. Replaces any previous child.
child¶
The content (non-owning), or nullptr before set_child().
content_orientation¶
Which axes the child is free to grow along. Vertical by default.
set_content_orientation¶
Lays the view out again.
horizontal_scroll_mode¶
Whether user input scrolls horizontally. Auto by default.
set_horizontal_scroll_mode¶
Takes effect on the next input. Scrolling from code ignores it.
vertical_scroll_mode¶
Whether user input scrolls vertically. Auto by default.
set_vertical_scroll_mode¶
Takes effect on the next input. Scrolling from code ignores it.
computed_horizontal_scroll_mode¶
The horizontal scroll mode with Auto resolved, so never Auto.
computed_vertical_scroll_mode¶
The vertical counterpart of computed_horizontal_scroll_mode().
zoom_mode¶
Whether Ctrl+wheel zooms. Disabled by default.
set_zoom_mode¶
Also changes what the Auto scroll modes resolve to.
pan_on_drag¶
Whether dragging the content with the left button moves the view, as a hand tool does. A pen or a finger counts as the left button. Off by default. Only a press that nothing inside handles starts a pan, so the content's buttons and boxes keep their clicks, and only the axes the user may scroll (computed_horizontal_scroll_mode(), computed_vertical_scroll_mode()) move. While there is something to pan, the pointer shows the move cursor over the content.
set_pan_on_drag¶
Takes effect on the next press. Turning it off during a drag lets the drag finish.
cursor_at¶
The move cursor over the content while pan_on_drag() has something to pan.
horizontal_scroll_chain_mode¶
Whether a wheel turn this view can't use goes on to the scroller around it, per axis (ScrollChainMode). Auto by default: a list scrolled to its bottom passes the wheel on to the page it sits in.
set_horizontal_scroll_chain_mode¶
Takes effect on the next wheel turn.
vertical_scroll_chain_mode¶
The vertical axis's chain mode; see horizontal_scroll_chain_mode().
set_vertical_scroll_chain_mode¶
Takes effect on the next wheel turn.
horizontal_scroll_bar_visibility¶
When the horizontal bar shows. Auto by default.
set_horizontal_scroll_bar_visibility¶
Redraws. The bars lie over the content, so the layout stays the same.
vertical_scroll_bar_visibility¶
When the vertical bar shows. Auto by default.
set_vertical_scroll_bar_visibility¶
Redraws. The bars lie over the content, so the layout stays the same.
computed_horizontal_scroll_bar_visible¶
Whether the horizontal bar shows right now, with Auto resolved against whether the axis can scroll and its scroll mode.
computed_vertical_scroll_bar_visible¶
Whether the vertical bar shows right now, as computed_horizontal_scroll_bar_visible().
min_zoom_factor¶
The smallest zoom factor. DefaultMinZoomFactor (0.1) by default.
set_min_zoom_factor¶
Clamps the current zoom factor into the new range.
max_zoom_factor¶
The largest zoom factor. DefaultMaxZoomFactor (10) by default.
set_max_zoom_factor¶
Clamps the current zoom factor into the new range.
background¶
The fixed color painted behind the content across the viewport. nullopt, the default, paints nothing.
background_resource¶
The theme resource the background is drawn from, or null.
set_background¶
A fixed background. Replaces any theme resource and redraws.
set_background¶
A background read from the theme each time it is drawn. Replaces any fixed color.
set_focusable¶
Whether the Scroll itself takes focus, ahead of its content in the tab order, and scrolls with the keyboard. False by default. focusable() reads it and is false while disabled. Lays the view out again, since the focus ring needs room.
horizontal_offset¶
How far the view is scrolled right, in zoomed DIPs, in [0, scrollable_width()].
vertical_offset¶
How far the view is scrolled down, in zoomed DIPs, in [0, scrollable_height()].
zoom_factor¶
The zoom factor, within [min_zoom_factor(), max_zoom_factor()]. 1 by default.
extent_width¶
The content's arranged width, unzoomed.
extent_height¶
The content's arranged height, unzoomed.
viewport_width¶
The view's own arranged width in DIPs, less the room an era's permanent vertical scroll bar takes while it shows, as Aero's does. The overlay bar takes none.
viewport_height¶
The view's own arranged height in DIPs, less the room an era's horizontal bar takes.
scrollable_width¶
max(0, extent_width() * zoom_factor() - viewport_width()), the largest horizontal_offset().
scrollable_height¶
The largest vertical_offset(), as scrollable_width().
scroll_info¶
Element::scroll_info(), whose content can be pulled a whole viewport past either end.
state¶
What is moving the view: nothing, a thumb drag, inertia or an animation.
scroll_to¶
Moves the view to the given offsets, in zoomed DIPs clamped to the scrollable range, animated unless options say otherwise. Stops any running animation or inertia and completes its request.
Each of these calls returns the request's correlation id, which the matching completed event reports. A request made before the first layout waits until then, so a view set up right after it is built lands against the real viewport.
scroll_by¶
scroll_to() the current offsets plus the deltas.
add_scroll_velocity¶
int add_scroll_velocity(Point offsets_velocity, std::optional<Point> inertia_decay_rate = std::nullopt)
Starts an inertial coast at offsets_velocity DIPs per second, or adds to the velocity of one already coasting. inertia_decay_rate is per axis, in [0, 1]. nullopt is 0.95, and 0 keeps a constant speed.
zoom_to¶
int zoom_to(float zoom_factor, std::optional<Point> center_point = std::nullopt, ScrollZoomOptions options = {})
Changes the zoom factor, clamped to the zoom range, about center_point, which is relative to the viewport. nullopt is the viewport's center.
zoom_by¶
int zoom_by(float zoom_factor_delta, std::optional<Point> center_point = std::nullopt, ScrollZoomOptions options = {})
zoom_to() the current factor plus zoom_factor_delta.
show_scrollbar¶
Whether this Scroll draws its own vertical scroll bar and lets it take input. True by default. AnnotatedScrollBarControl::set_target() sets it to false while attached, since that bar replaces the built-in one.
set_show_scrollbar¶
Redraws when it changes.
on_view_changed¶
An offset or the zoom factor changed.
on_extent_changed¶
The content's arranged size changed.
on_state_changed¶
state() changed; read it in the handler.
on_scroll_completed¶
A scroll_to() or scroll_by() finished, with the request's correlation id. A request replaced by a later one completes when it is replaced.
on_zoom_completed¶
A zoom_to() or zoom_by() finished or was replaced, with its correlation id.
on_scroll_animation_starting¶
Edit args.animation before an animated scroll plays, to change the duration or the path.
on_zoom_animation_starting¶
Edit args.animation before an animated zoom plays.
parallel_measure_safe¶
True: measuring touches only the content, the view's own sizes and its scroll bars' sizes.
focusable¶
Only after set_focusable(true), and while enabled.
focused¶
Whether the view itself (not its content) holds keyboard focus.
for_each_child¶
Visits the content, if any. The scroll bars are drawn by the view and are not children. Tab reaches the view itself first when it is a tab stop, then what is focusable in the content.
reveal_child¶
Scrolls a newly focused descendant into the viewport (Element::bring_into_view), so Tab never moves focus to a part of the content that is scrolled out of view.
automation_role¶
Reports the Pane role to accessibility tools.
measure_override¶
Measures the child without a limit along the axes content_orientation() leaves free. The view itself takes all it is offered, and the child's size only on an axis offered 0.
arrange_override¶
Derives the extent, clamps the offsets, arranges the child at them and runs any request held for the first layout.
render_override¶
The background, the child clipped to the viewport and zoomed, then the scroll bars.
pointer_override¶
Scroll bar drags and steps first; everything else goes to the child, mapped through the offsets and the zoom.
wheel_override¶
Scrolls at once, or zooms with Ctrl. Returns false when there was nothing to scroll that way, so a scroller around it may take the turn, depending on the chain mode.
map_to_children¶
A point in this element's layout coordinates, mapped into its children's: a control that scrolls, zooms or scales its content maps it the way the content is drawn. Default: the point unchanged.
children_hit_clip¶
Where the children can be hit, in this element's layout coordinates, or nullopt for anywhere (the default): a scrolling control returns its viewport, so content scrolled out of view is not hit.
covers_children_at¶
Whether a part of this element drawn over its children is at p (a scroll bar over the content), so the element is hit there instead of a child. Default: false.
tick_override¶
Advances the scroll bars' fades, any scroll or zoom animation and any inertia, then ticks the content.
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.
key_override¶
While focused, the arrow keys scroll 15 % of the viewport, Page Up and Page Down a whole viewport, and Home and End go to either end.
focus_changed¶
Called by Window as focus moves; redraws.
class ScrollBarOverlay¶
The overlay scroll bar a scrolling Element paints over its own viewport. It is a part of its owner, not an Element itself.
It holds only interaction and animation state. The owner passes the viewport, the content length and the current offset into every call, and applies the offset handle_pointer() hands back. At rest it is a thin thumb flush with the edge. Hovered or dragged, it widens and shows a track and two step buttons. After 2 s without activity it fades away. Scroll and VirtualList use it, and a custom scroller uses it the same way.
Example:
class Scroller final : public ui::Element
{
public:
ui::Size measure_override(ui::Size available, const ui::MeasureContext&) const override
{
return available;
}
bool pointer_override(const ui::PointerEvent& e) override
{
float offset = offset_;
if (bar_.handle_pointer(e, bounds(), content_height_, offset))
{
offset_ = offset; // clamp and re-arrange here
mark_dirty(ui::DirtyFlags::Visual);
return true; // claimed: do not forward to the content
}
return false; // ... or forward to the content ...
}
void tick_override(ui::Duration delta) override
{
if (bar_.update(delta))
{
mark_dirty(ui::DirtyFlags::Visual);
}
if (const std::optional<ui::Duration> wait = bar_.fade_wait())
{
request_tick_in(*wait); // wake once for the fade
}
}
void render_override(ui::Renderer& renderer, const ui::RenderContext& context) const override
{
// ... render the clipped content first ...
bar_.render(renderer, theme, bounds(), content_height_, offset_);
}
private:
ui::ScrollBarOverlay bar_{ui::Orientation::Vertical};
float offset_ = 0.0f;
float content_height_ = 1000.0f;
};
ScrollBarOverlay¶
A bar for one axis, collapsed and idle.
orientation¶
The axis given at construction.
scrollable¶
Whether content_length (DIPs along this bar's axis) exceeds the viewport along it.
always_visible¶
ScrollBarVisibility::Visible: draw the bar even with nothing to scroll. Its thumb then fills the track, and it takes no input. Off by default, which is Auto.
set_always_visible¶
The owner redraws. This class marks nothing dirty.
apply_theme¶
Takes the theme's kind of bar: this overlay, or an era's permanent bar such as Aero's, which takes room of its own at full thickness, never fades and draws the era's look. The owner calls it in measure, where it has the theme, before it lays its content out.
gutter¶
The room the bar takes from its scroller's viewport while it shows, in DIPs: the era bar's thickness, or 0 for the overlay, which draws over the content.
band_bounds¶
The area that takes the bar's input: the rightmost, full-height, 12-DIP slice of the viewport, whether the bar is expanded or not. A click or hover must land in it to reach the bar. It spans the step buttons and the thumb and track between them. For a horizontal bar, it is the bottom row.
up_button_bounds¶
The up (top) step button, or the left one for a horizontal bar: a 12-DIP square at that end of the band, which scrolls back a small step. Both step buttons always take their space, however far the expand animation is, and the thumb's track stops short of them. Only their drawing fades with the animation.
down_button_bounds¶
The down (bottom) step button, or the right one for a horizontal bar; see up_button_bounds().
thumb_bounds¶
Where the thumb is drawn for offset, the DIPs scrolled into content_length. Its length is the viewport's share of the track between the step buttons, at least 30 DIPs, at the thickness the animation has reached.
expanded¶
True while hovered or dragging: the expanded look (thicker thumb, visible track) instead of the collapsed one (thin thumb, no track).
dragging¶
True while the thumb is being dragged.
handle_pointer¶
bool handle_pointer(const PointerEvent& e, const Rect& viewport, float content_length, float& offset)
The owner passes every pointer event except wheel turns here first. Returns true if the bar took the event, and the owner must then not forward it to its content. When it returns true and offset differs from what the owner passed in, the owner applies it the way it applies a wheel turn, through its own offset setter, which clamps and arranges again.
update¶
Advances the expand and collapse animation by delta. Call it once per frame from the owner's tick_override(). Returns true while an animation is still running. The owner then marks itself visually dirty so render() is called again.
fade_wait¶
How long until the bar starts to fade by itself. Set while it shows and waits out its 2 s without activity, and empty while hovered, dragged, fading or faded. The owner passes it to Element::request_tick_in() from tick_override(), so an otherwise idle window wakes once for the fade.
notify_activity¶
Restarts the 2 s idle clock after which the bar fades, for activity handle_pointer() can't see, such as a wheel turn the owner scrolled with, whether or not the pointer is over the band. Scroll and VirtualList call it from their wheel handling. Hovering and dragging keep the clock reset by themselves.
render¶
void render(Renderer& renderer, const Theme& theme, const Rect& viewport, float content_length, float offset) const
Draws nothing when !is_scrollable(viewport, content_length). Call it after the owner has drawn its clipped content. The bar draws on top, unclipped.
is_scrollable¶
Whether there is anything to scroll at all, which decides whether the bar draws and takes input. This static form checks the vertical axis, and scrollable() below checks this bar's own axis.
struct ScrollOptions¶
How ScrollControl::scroll_to() and scroll_by() move. Snap points are not supported.
Example:
ui::Control<ui::Scroll> view; // a Scroll's .control
// Back to the top at once, no animation.
view->scroll_to(0.0f, 0.0f, {.animation_mode = ui::ScrollAnimationMode::Disabled});
| Field | Type | Default | |
|---|---|---|---|
animation_mode |
ScrollAnimationMode |
ScrollAnimationMode::Auto |
Whether the scroll animates. Auto animates. |
struct ScrollZoomOptions¶
How ScrollControl::zoom_to() and zoom_by() change the zoom.
| Field | Type | Default | |
|---|---|---|---|
animation_mode |
ScrollAnimationMode |
ScrollAnimationMode::Auto |
Whether the zoom animates. Auto animates. |
struct KeyFrameEasing¶
How a key frame eases in from the one before it: a cubic Bézier curve, or a step easing when steps is positive. A step easing jumps in steps equal steps, the last of them at the key frame itself.
curve¶
The curve, used while steps is 0. Fluent's fast-out-slow-in by default.
steps¶
A positive count makes this a step easing instead of curve.
evaluate¶
The eased progress (0..1) at linear progress x (0..1) between the two key frames.
struct ScrollKeyFrame¶
One key frame of a scroll animation: at progress, 0 to 1 of the duration, the view is at offsets. The offsets are horizontal and vertical, in zoomed DIPs, and are clamped to the scrollable range as the animation plays.
| Field | Type | Default | |
|---|---|---|---|
progress |
float |
1.0f |
Where in the animation the frame sits, 0..1 of the duration. |
offsets |
Point |
The (horizontal, vertical) offsets the view reaches at progress. |
|
easing |
KeyFrameEasing |
How the view eases in from the previous key frame. |
struct ScrollAnimation¶
The key-frame animation a Scroll builds for an animated scroll. By default it is one key frame at 1.0 on the target, over a duration that depends on the distance. The start at progress 0 is implicit. Key frames play in progress order.
| Field | Type | Default | |
|---|---|---|---|
duration |
Duration |
The whole animation's length. | |
key_frames |
std::vector<ScrollKeyFrame> |
The frames after the implicit start. |
struct ScrollAnimationStarting¶
The arguments of ScrollControl::on_scroll_animation_starting(). The handler may edit or replace animation. start_position and end_position are the offsets the view moves between.
Example:
ui::Control<ui::Scroll> view; // a Scroll's .control
view->on_scroll_animation_starting([](ui::ScrollAnimationStarting& args) {
args.animation.duration = 600ms; // slower than the distance-based default
args.animation.key_frames = {
{.progress = 0.5f, .offsets = args.start_position}, // hold, then
{.progress = 1.0f, .offsets = args.end_position}, // move
};
});
| Field | Type | Default | |
|---|---|---|---|
animation |
ScrollAnimation |
The animation about to play. The handler may change it. | |
start_position |
Point |
The offsets the view starts from. | |
end_position |
Point |
The offsets the request targets. | |
correlation_id |
int |
0 |
The id scroll_to()/scroll_by() returned for this request. |
struct ZoomKeyFrame¶
One key frame of a zoom animation. It carries a zoom factor, applied about the animation's center_point.
| Field | Type | Default | |
|---|---|---|---|
progress |
float |
1.0f |
Where in the animation the frame sits, 0..1 of the duration. |
zoom_factor |
float |
1.0f |
The zoom factor reached at progress. |
easing |
KeyFrameEasing |
How the zoom eases in from the previous key frame. |
struct ZoomAnimation¶
The key-frame animation a Scroll builds for an animated zoom. By default it is one key frame at 1.0 on the target factor, over 250 ms per whole zoom step, kept within 50 to 1000 ms.
| Field | Type | Default | |
|---|---|---|---|
duration |
Duration |
The whole animation's length. | |
key_frames |
std::vector<ZoomKeyFrame> |
The frames after the implicit start, in progress order. |
struct ZoomAnimationStarting¶
The arguments of ScrollControl::on_zoom_animation_starting(). The handler may edit or replace animation, as in ScrollAnimationStarting.
| Field | Type | Default | |
|---|---|---|---|
animation |
ZoomAnimation |
The animation about to play. The handler may change it. | |
start_zoom_factor |
float |
1.0f |
The zoom factor the view starts from. |
end_zoom_factor |
float |
1.0f |
The zoom factor the request targets. |
center_point |
Point |
The point kept still while zooming, in DIPs relative to the viewport. | |
correlation_id |
int |
0 |
The id zoom_to()/zoom_by() returned for this request. |
Enumerations¶
ScrollContentOrientation¶
Which axes a Scroll's content is free to grow along.
| Value | |
|---|---|
Vertical |
Width fixed to the viewport, height free (the default). |
Horizontal |
Height fixed to the viewport, width free. |
None |
Both fixed: the content fits the viewport, and zooming shows more. |
Both |
Both free. |
ScrollMode¶
Whether the user can scroll along an axis.
| Value | |
|---|---|
Enabled |
The wheel, the scroll bar and the keys scroll this axis. |
Disabled |
User input leaves this axis alone. scroll_to() and the other calls still move it. |
Auto |
Enabled while the axis has something to scroll, or while zooming is enabled. |
ScrollZoomMode¶
Whether the user can zoom (Ctrl+wheel).
| Value | |
|---|---|
Enabled |
Ctrl+wheel zooms, 10 % a notch. |
Disabled |
The default. zoom_to() and zoom_by() still work. |
ScrollChainMode¶
Whether a wheel turn this view cannot use, because it is already at the end the turn points toward, goes on to the scroller around it. Auto and Always differ only for touch input, which the library does not handle, so both pass the turn on. Never keeps the turn, and the page behind does not move.
| Value | |
|---|---|
Auto |
Pass the turn on (the default). |
Always |
Pass the turn on, the same as Auto without touch. |
Never |
Keep the turn. |
ScrollBarVisibility¶
When a scroll bar shows.
| Value | |
|---|---|
Auto |
Shown while its axis is scrollable and its scroll mode enabled. |
Visible |
Always shown. |
Hidden |
Never shown. |
ScrollAnimationMode¶
Whether a programmatic view change animates.
| Value | |
|---|---|
Disabled |
Jump straight to the target. |
Enabled |
Animate over a duration that depends on the distance. |
Auto |
Always animates. The system animation setting is not checked. |
ScrollInteractionState¶
What is moving the view right now (ScrollControl::state()).
| Value | |
|---|---|
Idle |
Nothing. |
Interaction |
A scroll bar thumb is being dragged. |
Inertia |
An add_scroll_velocity() is coasting. |
Animating |
A scroll_to(), scroll_by(), zoom_to() or zoom_by() is animating. |
Tests¶
tests/test_scroll.cpp