pub struct ScrollController {
pub bounds: State<Option<(Size2D, Size2D)>>,
/* private fields */
}Expand description
Handle to drive a scrollview programmatically.
By default a scrollview owns its scroll position and only the user can move it, through the
wheel, the scrollbar, arrow keys or dragging. A ScrollController lets your own code read and
change that position instead. Create one with use_scroll_controller and hand it to a
scrollview through its new_controlled constructor.
Some cases where a controller is needed:
- Jumping to the top or bottom in response to an action, for example scrolling a chat to the newest message after sending one.
- Keeping several scrollviews in sync, like a diff view with two panes that move together.
- Reading the current scroll position to drive something else, such as a “scroll to top” button that only appears once the user has scrolled down.
§Scrolling from code
scroll_to jumps to the start or end of an axis, with the end
resolved against the content on the next layout. This is the common way to snap a list to its
top or bottom.
fn app() -> impl IntoElement {
let mut scroll_controller = use_scroll_controller(ScrollConfig::default);
rect()
.child(
Button::new()
.on_press(move |_| {
scroll_controller.scroll_to(ScrollPosition::End, Direction::Vertical);
})
.child("Scroll to bottom"),
)
.child(
ScrollView::new_controlled(scroll_controller)
.children((0..100).map(|i| label().key(i).text(format!("Item {i}")))),
)
}For an exact pixel offset use scroll_to_y or
scroll_to_x. The current position is available by converting
the controller into a (i32, i32) tuple of (x, y) pixels, or calling
position.
§Animated scrolling
Scrolling to a position is instant by default. To animate, call
animate_from with the current position before setting
the target offset.
fn app() -> impl IntoElement {
let mut scroll_controller = use_scroll_controller(ScrollConfig::default);
rect()
.child(
Button::new()
.on_press(move |_| {
let current = scroll_controller.position();
scroll_controller.animate_from(current);
scroll_controller.scroll_to_y(-500);
})
.child("Animate scroll"),
)
.child(
ScrollView::new_controlled(scroll_controller)
.children((0..100).map(|i| label().key(i).text(format!("Item {i}")))),
)
}§Keeping scrollviews in sync
Pass the same ScrollController to several scrollviews to share a single scroll position.
Moving any of them moves the rest.
fn app() -> impl IntoElement {
let scroll_controller = use_scroll_controller(ScrollConfig::default);
rect()
.horizontal()
.spacing(6.)
.child(
ScrollView::new_controlled(scroll_controller)
.width(Size::flex(1.))
.children((0..30).map(|i| label().key(i).text(format!("Left {i}")))),
)
.child(
ScrollView::new_controlled(scroll_controller)
.width(Size::flex(1.))
.children((0..30).map(|i| label().key(i).text(format!("Right {i}")))),
)
}§Starting position
The ScrollConfig passed to use_scroll_controller also decides where each axis starts.
Set default_vertical_position to
ScrollPosition::End to open a list already scrolled to the bottom.
fn app() -> impl IntoElement {
let scroll_controller = use_scroll_controller(|| ScrollConfig {
default_vertical_position: ScrollPosition::End,
..Default::default()
});
ScrollView::new_controlled(scroll_controller)
.children((0..100).map(|i| label().key(i).text(format!("Item {i}"))))
}Fields§
§bounds: State<Option<(Size2D, Size2D)>>Implementations§
Source§impl ScrollController
impl ScrollController
Sourcepub fn new(x: i32, y: i32) -> Self
pub fn new(x: i32, y: i32) -> Self
Creates a controller starting at the scroll position (x, y).
Sourcepub fn apply_layout(&mut self, content_size: Size2D, viewport_size: Size2D)
pub fn apply_layout(&mut self, content_size: Size2D, viewport_size: Size2D)
Updates the content and viewport bounds used to clamp scroll positions.
Sourcepub fn scroll_to_x(&mut self, to: i32) -> bool
pub fn scroll_to_x(&mut self, to: i32) -> bool
Scrolls the horizontal axis to to pixels. Returns whether the position actually changed.
Sourcepub fn scroll_to_y(&mut self, to: i32) -> bool
pub fn scroll_to_y(&mut self, to: i32) -> bool
Scrolls the vertical axis to to pixels. Returns whether the position actually changed.
Sourcepub fn scroll_to(
&mut self,
scroll_position: ScrollPosition,
scroll_direction: Direction,
)
pub fn scroll_to( &mut self, scroll_position: ScrollPosition, scroll_direction: Direction, )
Scrolls scroll_direction to scroll_position.
Source§impl ScrollController
Follows the target held by a ScrollController.
impl ScrollController
Follows the target held by a ScrollController.
Sourcepub fn animated_position(&self, target: Point2D) -> Point2D
pub fn animated_position(&self, target: Point2D) -> Point2D
Position to render, the animated one while a scroll animation is running.
Sourcepub fn animate_from(&mut self, current: Point2D)
pub fn animate_from(&mut self, current: Point2D)
Chases the controller position from current, keeping the current velocity.
Sourcepub fn begin_drag(&mut self)
pub fn begin_drag(&mut self)
Freezes the animation and starts a drag from the momentum it caught.
Sourcepub fn release_drag(&mut self, from: Point2D, content: Size2D, viewport: Size2D)
pub fn release_drag(&mut self, from: Point2D, content: Size2D, viewport: Size2D)
Ends a drag, flinging when it was fast enough to be a flick.
Trait Implementations§
Source§impl Clone for ScrollController
impl Clone for ScrollController
impl Copy for ScrollController
Source§impl From<ScrollController> for (i32, i32)
impl From<ScrollController> for (i32, i32)
Source§fn from(val: ScrollController) -> Self
fn from(val: ScrollController) -> Self
Reads the current (x, y) scroll position in pixels.
Source§impl PartialEq for ScrollController
impl PartialEq for ScrollController
impl StructuralPartialEq for ScrollController
Auto Trait Implementations§
impl !RefUnwindSafe for ScrollController
impl !Send for ScrollController
impl !Sync for ScrollController
impl !UnwindSafe for ScrollController
impl Freeze for ScrollController
impl Unpin for ScrollController
impl UnsafeUnpin for ScrollController
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> ComponentProps for T
impl<T> ComponentProps for T
fn changed(&self, other: &(dyn ComponentProps + 'static)) -> bool
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more