diff options
| author | 2022-11-14 00:24:23 +0100 | |
|---|---|---|
| committer | 2022-11-14 00:24:23 +0100 | |
| commit | f5c9f63329ec420757c81ef73ab76e7a8cb2cd2e (patch) | |
| tree | 06cd44cdc5abfca94c1acfa10ab0281ae21c4b0c /native/src/widget | |
| parent | 5f08b8d41ae2d749bd11068f103a0f8ce3abd7bf (diff) | |
| parent | a7a4a92466a4447f8d2e9b5ae2fc715ba6262de0 (diff) | |
| download | iced-f5c9f63329ec420757c81ef73ab76e7a8cb2cd2e.tar.gz iced-f5c9f63329ec420757c81ef73ab76e7a8cb2cd2e.tar.bz2 iced-f5c9f63329ec420757c81ef73ab76e7a8cb2cd2e.zip  | |
Merge pull request #1529 from tarkah/feat/text-input-operations
Add text input operations
Diffstat (limited to '')
| -rw-r--r-- | native/src/widget/action.rs | 8 | ||||
| -rw-r--r-- | native/src/widget/operation.rs | 5 | ||||
| -rw-r--r-- | native/src/widget/operation/text_input.rs | 131 | ||||
| -rw-r--r-- | native/src/widget/text_input.rs | 45 | 
4 files changed, 189 insertions, 0 deletions
diff --git a/native/src/widget/action.rs b/native/src/widget/action.rs index 0345fe2b..593d6f63 100644 --- a/native/src/widget/action.rs +++ b/native/src/widget/action.rs @@ -93,4 +93,12 @@ where      ) {          self.operation.scrollable(state, id);      } + +    fn text_input( +        &mut self, +        state: &mut dyn operation::TextInput, +        id: Option<&Id>, +    ) { +        self.operation.text_input(state, id); +    }  } diff --git a/native/src/widget/operation.rs b/native/src/widget/operation.rs index 2b1179f1..a0aa4117 100644 --- a/native/src/widget/operation.rs +++ b/native/src/widget/operation.rs @@ -1,9 +1,11 @@  //! 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; @@ -28,6 +30,9 @@ pub trait Operation<T> {      /// 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>) {} +      /// Finishes the [`Operation`] and returns its [`Outcome`].      fn finish(&self) -> Outcome<T> {          Outcome::None diff --git a/native/src/widget/operation/text_input.rs b/native/src/widget/operation/text_input.rs new file mode 100644 index 00000000..4c773e99 --- /dev/null +++ b/native/src/widget/operation/text_input.rs @@ -0,0 +1,131 @@ +//! Operate on widgets that have text input. +use crate::widget::operation::Operation; +use crate::widget::Id; + +/// The internal state of a widget that has text input. +pub trait TextInput { +    /// Moves the cursor of the text input to the front of the input text. +    fn move_cursor_to_front(&mut self); +    /// Moves the cursor of the text input to the end of the input text. +    fn move_cursor_to_end(&mut self); +    /// Moves the cursor of the text input to an arbitrary location. +    fn move_cursor_to(&mut self, position: usize); +    /// Selects all the content of the text input. +    fn select_all(&mut self); +} + +/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the +/// front. +pub fn move_cursor_to_front<T>(target: Id) -> impl Operation<T> { +    struct MoveCursor { +        target: Id, +    } + +    impl<T> Operation<T> for MoveCursor { +        fn text_input(&mut self, state: &mut dyn TextInput, id: Option<&Id>) { +            match id { +                Some(id) if id == &self.target => { +                    state.move_cursor_to_front(); +                } +                _ => {} +            } +        } + +        fn container( +            &mut self, +            _id: Option<&Id>, +            operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>), +        ) { +            operate_on_children(self) +        } +    } + +    MoveCursor { target } +} + +/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the +/// end. +pub fn move_cursor_to_end<T>(target: Id) -> impl Operation<T> { +    struct MoveCursor { +        target: Id, +    } + +    impl<T> Operation<T> for MoveCursor { +        fn text_input(&mut self, state: &mut dyn TextInput, id: Option<&Id>) { +            match id { +                Some(id) if id == &self.target => { +                    state.move_cursor_to_end(); +                } +                _ => {} +            } +        } + +        fn container( +            &mut self, +            _id: Option<&Id>, +            operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>), +        ) { +            operate_on_children(self) +        } +    } + +    MoveCursor { target } +} + +/// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the +/// provided position. +pub fn move_cursor_to<T>(target: Id, position: usize) -> impl Operation<T> { +    struct MoveCursor { +        target: Id, +        position: usize, +    } + +    impl<T> Operation<T> for MoveCursor { +        fn text_input(&mut self, state: &mut dyn TextInput, id: Option<&Id>) { +            match id { +                Some(id) if id == &self.target => { +                    state.move_cursor_to(self.position); +                } +                _ => {} +            } +        } + +        fn container( +            &mut self, +            _id: Option<&Id>, +            operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>), +        ) { +            operate_on_children(self) +        } +    } + +    MoveCursor { target, position } +} + +/// Produces an [`Operation`] that selects all the content of the widget with the given [`Id`]. +pub fn select_all<T>(target: Id) -> impl Operation<T> { +    struct MoveCursor { +        target: Id, +    } + +    impl<T> Operation<T> for MoveCursor { +        fn text_input(&mut self, state: &mut dyn TextInput, id: Option<&Id>) { +            match id { +                Some(id) if id == &self.target => { +                    state.select_all(); +                } +                _ => {} +            } +        } + +        fn container( +            &mut self, +            _id: Option<&Id>, +            operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>), +        ) { +            operate_on_children(self) +        } +    } + +    MoveCursor { target } +} diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 2315b05a..e2886181 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -233,6 +233,7 @@ where          let state = tree.state.downcast_mut::<State>();          operation.focusable(state, self.id.as_ref().map(|id| &id.0)); +        operation.text_input(state, self.id.as_ref().map(|id| &id.0));      }      fn on_event( @@ -337,6 +338,32 @@ pub fn focus<Message: 'static>(id: Id) -> Command<Message> {      Command::widget(operation::focusable::focus(id.0))  } +/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the +/// end. +pub fn move_cursor_to_end<Message: 'static>(id: Id) -> Command<Message> { +    Command::widget(operation::text_input::move_cursor_to_end(id.0)) +} + +/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the +/// front. +pub fn move_cursor_to_front<Message: 'static>(id: Id) -> Command<Message> { +    Command::widget(operation::text_input::move_cursor_to_front(id.0)) +} + +/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the +/// provided position. +pub fn move_cursor_to<Message: 'static>( +    id: Id, +    position: usize, +) -> Command<Message> { +    Command::widget(operation::text_input::move_cursor_to(id.0, position)) +} + +/// Produces a [`Command`] that selects all the content of the [`TextInput`] with the given [`Id`]. +pub fn select_all<Message: 'static>(id: Id) -> Command<Message> { +    Command::widget(operation::text_input::select_all(id.0)) +} +  /// Computes the layout of a [`TextInput`].  pub fn layout<Renderer>(      renderer: &Renderer, @@ -1001,6 +1028,24 @@ impl operation::Focusable for State {      }  } +impl operation::TextInput for State { +    fn move_cursor_to_front(&mut self) { +        State::move_cursor_to_front(self) +    } + +    fn move_cursor_to_end(&mut self) { +        State::move_cursor_to_end(self) +    } + +    fn move_cursor_to(&mut self, position: usize) { +        State::move_cursor_to(self, position) +    } + +    fn select_all(&mut self) { +        State::select_all(self) +    } +} +  mod platform {      use crate::keyboard;  | 
