diff options
Diffstat (limited to 'native/src/widget/scrollable.rs')
-rw-r--r-- | native/src/widget/scrollable.rs | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index b40c3743..4ebb07a0 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -5,10 +5,12 @@ use crate::mouse; use crate::overlay; use crate::renderer; use crate::touch; +use crate::widget; +use crate::widget::operation::{self, Operation}; use crate::widget::tree::{self, Tree}; use crate::{ - Background, Clipboard, Color, Element, Layout, Length, Point, Rectangle, - Shell, Size, Vector, Widget, + Background, Clipboard, Color, Command, Element, Layout, Length, Point, + Rectangle, Shell, Size, Vector, Widget, }; use std::{f32, u32}; @@ -30,6 +32,7 @@ where Renderer: crate::Renderer, Renderer::Theme: StyleSheet, { + id: Option<Id>, height: Length, scrollbar_width: u16, scrollbar_margin: u16, @@ -47,6 +50,7 @@ where /// Creates a new [`Scrollable`]. pub fn new(content: impl Into<Element<'a, Message, Renderer>>) -> Self { Scrollable { + id: None, height: Length::Shrink, scrollbar_width: 10, scrollbar_margin: 0, @@ -57,6 +61,12 @@ where } } + /// Sets the [`Id`] of the [`Scrollable`]. + pub fn id(mut self, id: Id) -> Self { + self.id = Some(id); + self + } + /// Sets the height of the [`Scrollable`]. pub fn height(mut self, height: Length) -> Self { self.height = height; @@ -150,6 +160,25 @@ where ) } + fn operate( + &self, + tree: &mut Tree, + layout: Layout<'_>, + operation: &mut dyn Operation<Message>, + ) { + let state = tree.state.downcast_mut::<State>(); + + operation.scrollable(state, self.id.as_ref().map(|id| &id.0)); + + operation.container(None, &mut |operation| { + self.content.as_widget().operate( + &mut tree.children[0], + layout.children().next().unwrap(), + operation, + ); + }); + } + fn on_event( &mut self, tree: &mut Tree, @@ -287,6 +316,30 @@ where } } +/// The identifier of a [`Scrollable`]. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Id(widget::Id); + +impl Id { + /// Creates a custom [`Id`]. + pub fn new(id: impl Into<std::borrow::Cow<'static, str>>) -> Self { + Self(widget::Id::new(id)) + } + + /// Creates a unique [`Id`]. + /// + /// This function produces a different [`Id`] every time it is called. + pub fn unique() -> Self { + Self(widget::Id::unique()) + } +} + +/// Produces a [`Command`] that snaps the [`Scrollable`] with the given [`Id`] +/// to the provided `percentage`. +pub fn snap_to<Message: 'static>(id: Id, percentage: f32) -> Command<Message> { + Command::widget(operation::scrollable::snap_to(id.0, percentage)) +} + /// Computes the layout of a [`Scrollable`]. pub fn layout<Renderer>( renderer: &Renderer, @@ -774,6 +827,12 @@ impl Default for State { } } +impl operation::Scrollable for State { + fn snap_to(&mut self, percentage: f32) { + State::snap_to(self, percentage); + } +} + /// The local state of a [`Scrollable`]. #[derive(Debug, Clone, Copy)] enum Offset { |