diff options
| author | 2022-11-11 08:43:36 -0800 | |
|---|---|---|
| committer | 2022-11-11 08:43:36 -0800 | |
| commit | c4bca3f2af7ae9b2c8dfc3af48ab73dad852ed34 (patch) | |
| tree | a9c75de888366ea4d0f82c821e6d90a7682ae380 | |
| parent | 23299a555f8b7e908a6a14915307792a7cf97b9a (diff) | |
| download | iced-c4bca3f2af7ae9b2c8dfc3af48ab73dad852ed34.tar.gz iced-c4bca3f2af7ae9b2c8dfc3af48ab73dad852ed34.tar.bz2 iced-c4bca3f2af7ae9b2c8dfc3af48ab73dad852ed34.zip  | |
Add text input operations
| -rw-r--r-- | lazy/src/component.rs | 8 | ||||
| -rw-r--r-- | native/src/element.rs | 8 | ||||
| -rw-r--r-- | native/src/overlay/element.rs | 8 | ||||
| -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 | ||||
| -rw-r--r-- | src/widget.rs | 3 | 
8 files changed, 215 insertions, 1 deletions
diff --git a/lazy/src/component.rs b/lazy/src/component.rs index 8987b993..4f1df650 100644 --- a/lazy/src/component.rs +++ b/lazy/src/component.rs @@ -260,6 +260,14 @@ where              ) {                  self.operation.focusable(state, id);              } + +            fn text_input( +                &mut self, +                state: &mut dyn widget::operation::TextInput, +                id: Option<&widget::Id>, +            ) { +                self.operation.text_input(state, id); +            }          }          self.with_element(|element| { diff --git a/native/src/element.rs b/native/src/element.rs index c82d8e96..f941a490 100644 --- a/native/src/element.rs +++ b/native/src/element.rs @@ -324,6 +324,14 @@ where              ) {                  self.operation.scrollable(state, id);              } + +            fn text_input( +                &mut self, +                state: &mut dyn widget::operation::TextInput, +                id: Option<&widget::Id>, +            ) { +                self.operation.text_input(state, id); +            }          }          self.widget diff --git a/native/src/overlay/element.rs b/native/src/overlay/element.rs index 2c558086..09eee86d 100644 --- a/native/src/overlay/element.rs +++ b/native/src/overlay/element.rs @@ -178,6 +178,14 @@ where              ) {                  self.operation.scrollable(state, id);              } + +            fn text_input( +                &mut self, +                state: &mut dyn widget::operation::TextInput, +                id: Option<&widget::Id>, +            ) { +                self.operation.text_input(state, id) +            }          }          self.content 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; diff --git a/src/widget.rs b/src/widget.rs index 8c8ea216..7c67a599 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -120,7 +120,8 @@ pub mod toggler {  pub mod text_input {      //! Display fields that can be filled with text.      pub use iced_native::widget::text_input::{ -        focus, Appearance, Id, StyleSheet, +        focus, move_cursor_to, move_cursor_to_end, move_cursor_to_front, +        select_all, Appearance, Id, StyleSheet,      };      /// A field that can be filled with text.  | 
