diff options
Diffstat (limited to '')
| -rw-r--r-- | core/src/widget/operation/focusable.rs (renamed from native/src/widget/operation/focusable.rs) | 0 | ||||
| -rw-r--r-- | core/src/widget/operation/scrollable.rs (renamed from native/src/widget/operation/scrollable.rs) | 41 | ||||
| -rw-r--r-- | core/src/widget/operation/text_input.rs (renamed from native/src/widget/operation/text_input.rs) | 0 | ||||
| -rw-r--r-- | native/src/widget/operation.rs | 112 |
4 files changed, 40 insertions, 113 deletions
diff --git a/native/src/widget/operation/focusable.rs b/core/src/widget/operation/focusable.rs index 312e4894..312e4894 100644 --- a/native/src/widget/operation/focusable.rs +++ b/core/src/widget/operation/focusable.rs diff --git a/native/src/widget/operation/scrollable.rs b/core/src/widget/operation/scrollable.rs index 3b20631f..f947344d 100644 --- a/native/src/widget/operation/scrollable.rs +++ b/core/src/widget/operation/scrollable.rs @@ -5,6 +5,9 @@ use crate::widget::{Id, Operation}; 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); + + /// Scroll the widget to the given [`AbsoluteOffset`] along the horizontal & vertical axis. + fn scroll_to(&mut self, offset: AbsoluteOffset); } /// Produces an [`Operation`] that snaps the widget with the given [`Id`] to @@ -34,7 +37,43 @@ pub fn snap_to<T>(target: Id, offset: RelativeOffset) -> impl Operation<T> { SnapTo { target, offset } } -/// The amount of offset in each direction of a [`Scrollable`]. +/// Produces an [`Operation`] that scrolls the widget with the given [`Id`] to +/// the provided [`AbsoluteOffset`]. +pub fn scroll_to<T>(target: Id, offset: AbsoluteOffset) -> impl Operation<T> { + struct ScrollTo { + target: Id, + offset: AbsoluteOffset, + } + + impl<T> Operation<T> for ScrollTo { + fn container( + &mut self, + _id: Option<&Id>, + operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>), + ) { + operate_on_children(self) + } + + fn scrollable(&mut self, state: &mut dyn Scrollable, id: Option<&Id>) { + if Some(&self.target) == id { + state.scroll_to(self.offset); + } + } + } + + ScrollTo { target, offset } +} + +/// The amount of absolute offset in each direction of a [`Scrollable`]. +#[derive(Debug, Clone, Copy, PartialEq, Default)] +pub struct AbsoluteOffset { + /// The amount of horizontal offset + pub x: f32, + /// The amount of vertical offset + pub y: f32, +} + +/// 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)] diff --git a/native/src/widget/operation/text_input.rs b/core/src/widget/operation/text_input.rs index 4c773e99..4c773e99 100644 --- a/native/src/widget/operation/text_input.rs +++ b/core/src/widget/operation/text_input.rs diff --git a/native/src/widget/operation.rs b/native/src/widget/operation.rs deleted file mode 100644 index 53688a21..00000000 --- a/native/src/widget/operation.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! Query or update internal widget state. -pub mod focusable; -pub mod scrollable; -pub mod text_input; - -pub use focusable::Focusable; -pub use scrollable::Scrollable; -pub use text_input::TextInput; - -use crate::widget::Id; - -use std::any::Any; -use std::fmt; - -/// A piece of logic that can traverse the widget tree of an application in -/// order to query or update some widget state. -pub trait Operation<T> { - /// Operates on a widget that contains other widgets. - /// - /// The `operate_on_children` function can be called to return control to - /// the widget tree and keep traversing it. - fn container( - &mut self, - id: Option<&Id>, - operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>), - ); - - /// Operates on a widget that can be focused. - fn focusable(&mut self, _state: &mut dyn Focusable, _id: Option<&Id>) {} - - /// Operates on a widget that can be scrolled. - fn scrollable(&mut self, _state: &mut dyn Scrollable, _id: Option<&Id>) {} - - /// Operates on a widget that has text input. - fn text_input(&mut self, _state: &mut dyn TextInput, _id: Option<&Id>) {} - - /// Operates on a custom widget with some state. - fn custom(&mut self, _state: &mut dyn Any, _id: Option<&Id>) {} - - /// Finishes the [`Operation`] and returns its [`Outcome`]. - fn finish(&self) -> Outcome<T> { - Outcome::None - } -} - -/// The result of an [`Operation`]. -pub enum Outcome<T> { - /// The [`Operation`] produced no result. - None, - - /// The [`Operation`] produced some result. - Some(T), - - /// The [`Operation`] needs to be followed by another [`Operation`]. - Chain(Box<dyn Operation<T>>), -} - -impl<T> fmt::Debug for Outcome<T> -where - T: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::None => write!(f, "Outcome::None"), - Self::Some(output) => write!(f, "Outcome::Some({output:?})"), - Self::Chain(_) => write!(f, "Outcome::Chain(...)"), - } - } -} - -/// Produces an [`Operation`] that applies the given [`Operation`] to the -/// children of a container with the given [`Id`]. -pub fn scoped<T: 'static>( - target: Id, - operation: impl Operation<T> + 'static, -) -> impl Operation<T> { - struct ScopedOperation<Message> { - target: Id, - operation: Box<dyn Operation<Message>>, - } - - impl<Message: 'static> Operation<Message> for ScopedOperation<Message> { - fn container( - &mut self, - id: Option<&Id>, - operate_on_children: &mut dyn FnMut(&mut dyn Operation<Message>), - ) { - if id == Some(&self.target) { - operate_on_children(self.operation.as_mut()); - } else { - operate_on_children(self); - } - } - - fn finish(&self) -> Outcome<Message> { - match self.operation.finish() { - Outcome::Chain(next) => { - Outcome::Chain(Box::new(ScopedOperation { - target: self.target.clone(), - operation: next, - })) - } - outcome => outcome, - } - } - } - - ScopedOperation { - target, - operation: Box::new(operation), - } -} |
