diff --git a/core/src/widget/operation/scrollable.rs b/core/src/widget/operation/scrollable.rs index 25a03434..1a1ea24f 100644 --- a/core/src/widget/operation/scrollable.rs +++ b/core/src/widget/operation/scrollable.rs @@ -5,10 +5,10 @@ use crate::{Rectangle, Vector}; /// The internal state of a widget that can be scrolled. pub trait Scrollable { /// Snaps the scroll of the widget to the given `percentage` along the horizontal & vertical axis. - fn snap_to(&mut self, offset: RelativeOffset); + fn snap_to(&mut self, offset: RelativeOffset>); /// Scroll the widget to the given [`AbsoluteOffset`] along the horizontal & vertical axis. - fn scroll_to(&mut self, offset: AbsoluteOffset); + fn scroll_to(&mut self, offset: AbsoluteOffset>); /// Scroll the widget by the given [`AbsoluteOffset`] along the horizontal & vertical axis. fn scroll_by( @@ -21,10 +21,13 @@ pub trait Scrollable { /// Produces an [`Operation`] that snaps the widget with the given [`Id`] to /// the provided `percentage`. -pub fn snap_to(target: Id, offset: RelativeOffset) -> impl Operation { +pub fn snap_to( + target: Id, + offset: RelativeOffset>, +) -> impl Operation { struct SnapTo { target: Id, - offset: RelativeOffset, + offset: RelativeOffset>, } impl Operation for SnapTo { @@ -51,10 +54,13 @@ pub fn snap_to(target: Id, offset: RelativeOffset) -> impl Operation { /// Produces an [`Operation`] that scrolls the widget with the given [`Id`] to /// the provided [`AbsoluteOffset`]. -pub fn scroll_to(target: Id, offset: AbsoluteOffset) -> impl Operation { +pub fn scroll_to( + target: Id, + offset: AbsoluteOffset>, +) -> impl Operation { struct ScrollTo { target: Id, - offset: AbsoluteOffset, + offset: AbsoluteOffset>, } impl Operation for ScrollTo { @@ -111,22 +117,31 @@ pub fn scroll_by(target: Id, offset: AbsoluteOffset) -> impl Operation { /// The amount of absolute offset in each direction of a [`Scrollable`]. #[derive(Debug, Clone, Copy, PartialEq, Default)] -pub struct AbsoluteOffset { +pub struct AbsoluteOffset { /// The amount of horizontal offset - pub x: f32, + pub x: T, /// The amount of vertical offset - pub y: f32, + pub y: T, +} + +impl From for AbsoluteOffset> { + fn from(offset: AbsoluteOffset) -> Self { + Self { + x: Some(offset.x), + y: Some(offset.y), + } + } } /// The amount of relative offset in each direction of a [`Scrollable`]. /// /// A value of `0.0` means start, while `1.0` means end. #[derive(Debug, Clone, Copy, PartialEq, Default)] -pub struct RelativeOffset { +pub struct RelativeOffset { /// The amount of horizontal offset - pub x: f32, + pub x: T, /// The amount of vertical offset - pub y: f32, + pub y: T, } impl RelativeOffset { @@ -136,3 +151,12 @@ impl RelativeOffset { /// A relative offset that points to the bottom-right of a [`Scrollable`]. pub const END: Self = Self { x: 1.0, y: 1.0 }; } + +impl From for RelativeOffset> { + fn from(offset: RelativeOffset) -> Self { + Self { + x: Some(offset.x), + y: Some(offset.y), + } + } +} diff --git a/runtime/src/widget/operation.rs b/runtime/src/widget/operation.rs index 8a1af55a..3aa1f9d4 100644 --- a/runtime/src/widget/operation.rs +++ b/runtime/src/widget/operation.rs @@ -9,10 +9,13 @@ pub use crate::core::widget::operation::scrollable::{ }; /// Snaps the scrollable with the given [`Id`] to the provided [`RelativeOffset`]. -pub fn snap_to(id: impl Into, offset: RelativeOffset) -> Task { +pub fn snap_to( + id: impl Into, + offset: impl Into>>, +) -> Task { task::effect(Action::widget(operation::scrollable::snap_to( id.into(), - offset, + offset.into(), ))) } @@ -20,15 +23,18 @@ pub fn snap_to(id: impl Into, offset: RelativeOffset) -> Task { pub fn snap_to_end(id: impl Into) -> Task { task::effect(Action::widget(operation::scrollable::snap_to( id.into(), - RelativeOffset::END, + RelativeOffset::END.into(), ))) } /// Scrolls the scrollable with the given [`Id`] to the provided [`AbsoluteOffset`]. -pub fn scroll_to(id: impl Into, offset: AbsoluteOffset) -> Task { +pub fn scroll_to( + id: impl Into, + offset: impl Into>>, +) -> Task { task::effect(Action::widget(operation::scrollable::scroll_to( id.into(), - offset, + offset.into(), ))) } diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index d12c33ca..1d760e32 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -1673,11 +1673,11 @@ impl Default for State { } impl operation::Scrollable for State { - fn snap_to(&mut self, offset: RelativeOffset) { + fn snap_to(&mut self, offset: RelativeOffset>) { State::snap_to(self, offset); } - fn scroll_to(&mut self, offset: AbsoluteOffset) { + fn scroll_to(&mut self, offset: AbsoluteOffset>) { State::scroll_to(self, offset); } @@ -1829,18 +1829,28 @@ impl State { self.unsnap(bounds, content_bounds); } - fn snap_to(&mut self, offset: RelativeOffset) { - self.offset_x = Offset::Relative(offset.x.clamp(0.0, 1.0)); - self.offset_y = Offset::Relative(offset.y.clamp(0.0, 1.0)); + fn snap_to(&mut self, offset: RelativeOffset>) { + if let Some(x) = offset.x { + self.offset_x = Offset::Relative(x.clamp(0.0, 1.0)); + } + + if let Some(y) = offset.y { + self.offset_y = Offset::Relative(y.clamp(0.0, 1.0)); + } } - fn scroll_to(&mut self, offset: AbsoluteOffset) { - self.offset_x = Offset::Absolute(offset.x.max(0.0)); - self.offset_y = Offset::Absolute(offset.y.max(0.0)); + fn scroll_to(&mut self, offset: AbsoluteOffset>) { + if let Some(x) = offset.x { + self.offset_x = Offset::Absolute(x.max(0.0)); + } + + if let Some(y) = offset.y { + self.offset_y = Offset::Absolute(y.max(0.0)); + } } /// Scroll by the provided [`AbsoluteOffset`]. - pub fn scroll_by( + fn scroll_by( &mut self, offset: AbsoluteOffset, bounds: Rectangle, @@ -1851,7 +1861,7 @@ impl State { /// Unsnaps the current scroll position, if snapped, given the bounds of the /// [`Scrollable`] and its contents. - pub fn unsnap(&mut self, bounds: Rectangle, content_bounds: Rectangle) { + fn unsnap(&mut self, bounds: Rectangle, content_bounds: Rectangle) { self.offset_x = Offset::Absolute( self.offset_x.absolute(bounds.width, content_bounds.width), );