diff options
| author | 2022-07-28 03:53:47 +0200 | |
|---|---|---|
| committer | 2022-07-28 03:53:47 +0200 | |
| commit | 52f84e51e90db1c324310565f2aff8b7e6987cba (patch) | |
| tree | 721ef64dd91e0aca0e490971c8e1ee44ca912957 /native/src/widget | |
| parent | 80688689aa4b15bc23824df899974a9094a77b07 (diff) | |
| download | iced-52f84e51e90db1c324310565f2aff8b7e6987cba.tar.gz iced-52f84e51e90db1c324310565f2aff8b7e6987cba.tar.bz2 iced-52f84e51e90db1c324310565f2aff8b7e6987cba.zip  | |
Implement `Widget::operate` for `TextInput`
Diffstat (limited to '')
| -rw-r--r-- | native/src/widget.rs | 1 | ||||
| -rw-r--r-- | native/src/widget/action.rs | 6 | ||||
| -rw-r--r-- | native/src/widget/button.rs | 16 | ||||
| -rw-r--r-- | native/src/widget/column.rs | 19 | ||||
| -rw-r--r-- | native/src/widget/container.rs | 17 | ||||
| -rw-r--r-- | native/src/widget/operation.rs | 18 | ||||
| -rw-r--r-- | native/src/widget/row.rs | 19 | ||||
| -rw-r--r-- | native/src/widget/scrollable.rs | 16 | ||||
| -rw-r--r-- | native/src/widget/text_input.rs | 39 | 
9 files changed, 133 insertions, 18 deletions
diff --git a/native/src/widget.rs b/native/src/widget.rs index 79f6ae3a..56ba28c8 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -171,6 +171,7 @@ where      /// Applies an [`Operation`] to the [`Widget`].      fn operate(          &self, +        _state: &mut Tree,          _layout: Layout<'_>,          _operation: &mut dyn Operation<Message>,      ) { diff --git a/native/src/widget/action.rs b/native/src/widget/action.rs index 23ea4269..69723358 100644 --- a/native/src/widget/action.rs +++ b/native/src/widget/action.rs @@ -42,7 +42,7 @@ where      fn container(          &mut self,          id: Option<&Id>, -        operate_on_children: &dyn Fn(&mut dyn Operation<B>), +        operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>),      ) {          struct MapRef<'a, A, B> {              operation: &'a mut dyn Operation<A>, @@ -53,11 +53,11 @@ where              fn container(                  &mut self,                  id: Option<&Id>, -                operate_on_children: &dyn Fn(&mut dyn Operation<B>), +                operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>),              ) {                  let Self { operation, f } = self; -                operation.container(id, &|operation| { +                operation.container(id, &mut |operation| {                      operate_on_children(&mut MapRef { operation, f });                  });              } diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 6eac6c1b..6c0b8f6e 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -8,6 +8,7 @@ use crate::overlay;  use crate::renderer;  use crate::touch;  use crate::widget::tree::{self, Tree}; +use crate::widget::Operation;  use crate::{      Background, Clipboard, Color, Element, Layout, Length, Padding, Point,      Rectangle, Shell, Vector, Widget, @@ -164,6 +165,21 @@ where          )      } +    fn operate( +        &self, +        tree: &mut Tree, +        layout: Layout<'_>, +        operation: &mut dyn Operation<Message>, +    ) { +        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, diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs index 834f9858..a8b0f183 100644 --- a/native/src/widget/column.rs +++ b/native/src/widget/column.rs @@ -4,7 +4,7 @@ use crate::layout;  use crate::mouse;  use crate::overlay;  use crate::renderer; -use crate::widget::Tree; +use crate::widget::{Operation, Tree};  use crate::{      Alignment, Clipboard, Element, Layout, Length, Padding, Point, Rectangle,      Shell, Widget, @@ -143,6 +143,23 @@ where          )      } +    fn operate( +        &self, +        tree: &mut Tree, +        layout: Layout<'_>, +        operation: &mut dyn Operation<Message>, +    ) { +        operation.container(None, &mut |operation| { +            self.children +                .iter() +                .zip(&mut tree.children) +                .zip(layout.children()) +                .for_each(|((child, state), layout)| { +                    child.as_widget().operate(state, layout, operation); +                }) +        }); +    } +      fn on_event(          &mut self,          tree: &mut Tree, diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index b0fa0315..2afad3f2 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -5,7 +5,7 @@ use crate::layout;  use crate::mouse;  use crate::overlay;  use crate::renderer; -use crate::widget::Tree; +use crate::widget::{Operation, Tree};  use crate::{      Background, Clipboard, Color, Element, Layout, Length, Padding, Point,      Rectangle, Shell, Widget, @@ -165,6 +165,21 @@ where          )      } +    fn operate( +        &self, +        tree: &mut Tree, +        layout: Layout<'_>, +        operation: &mut dyn Operation<Message>, +    ) { +        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, diff --git a/native/src/widget/operation.rs b/native/src/widget/operation.rs index b6c108e0..2cfba005 100644 --- a/native/src/widget/operation.rs +++ b/native/src/widget/operation.rs @@ -5,7 +5,7 @@ pub trait Operation<T> {      fn container(          &mut self,          id: Option<&Id>, -        operate_on_children: &dyn Fn(&mut dyn Operation<T>), +        operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),      );      fn focusable( @@ -37,14 +37,12 @@ pub fn focus<T>(target: Id) -> impl Operation<T> {              state: &mut dyn state::Focusable,              id: Option<&Id>,          ) { -            if state.is_focused() { -                match id { -                    Some(id) if id == &self.target => { -                        state.focus(); -                    } -                    _ => { -                        state.unfocus(); -                    } +            match id { +                Some(id) if id == &self.target => { +                    state.focus(); +                } +                _ => { +                    state.unfocus();                  }              }          } @@ -52,7 +50,7 @@ pub fn focus<T>(target: Id) -> impl Operation<T> {          fn container(              &mut self,              _id: Option<&Id>, -            operate_on_children: &dyn Fn(&mut dyn Operation<T>), +            operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),          ) {              operate_on_children(self)          } diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs index c342c277..eda7c2d3 100644 --- a/native/src/widget/row.rs +++ b/native/src/widget/row.rs @@ -4,7 +4,7 @@ use crate::layout::{self, Layout};  use crate::mouse;  use crate::overlay;  use crate::renderer; -use crate::widget::Tree; +use crate::widget::{Operation, Tree};  use crate::{      Alignment, Clipboard, Element, Length, Padding, Point, Rectangle, Shell,      Widget, @@ -130,6 +130,23 @@ where          )      } +    fn operate( +        &self, +        tree: &mut Tree, +        layout: Layout<'_>, +        operation: &mut dyn Operation<Message>, +    ) { +        operation.container(None, &mut |operation| { +            self.children +                .iter() +                .zip(&mut tree.children) +                .zip(layout.children()) +                .for_each(|((child, state), layout)| { +                    child.as_widget().operate(state, layout, operation); +                }) +        }); +    } +      fn on_event(          &mut self,          tree: &mut Tree, diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index b40c3743..91c13eb5 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -6,6 +6,7 @@ use crate::overlay;  use crate::renderer;  use crate::touch;  use crate::widget::tree::{self, Tree}; +use crate::widget::Operation;  use crate::{      Background, Clipboard, Color, Element, Layout, Length, Point, Rectangle,      Shell, Size, Vector, Widget, @@ -150,6 +151,21 @@ where          )      } +    fn operate( +        &self, +        tree: &mut Tree, +        layout: Layout<'_>, +        operation: &mut dyn Operation<Message>, +    ) { +        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, diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 1dbb8d6b..1ca5ccf2 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -19,11 +19,13 @@ use crate::mouse::{self, click};  use crate::renderer;  use crate::text::{self, Text};  use crate::touch; +use crate::widget; +use crate::widget::operation::{self, Operation};  use crate::widget::state;  use crate::widget::tree::{self, Tree};  use crate::{ -    Clipboard, Color, Element, Layout, Length, Padding, Point, Rectangle, -    Shell, Size, Vector, Widget, +    Clipboard, Color, Command, Element, Layout, Length, Padding, Point, +    Rectangle, Shell, Size, Vector, Widget,  };  pub use iced_style::text_input::{Appearance, StyleSheet}; @@ -54,6 +56,7 @@ where      Renderer: text::Renderer,      Renderer::Theme: StyleSheet,  { +    id: Option<Id>,      placeholder: String,      value: Value,      is_secure: bool, @@ -84,6 +87,7 @@ where          F: 'a + Fn(String) -> Message,      {          TextInput { +            id: None,              placeholder: String::from(placeholder),              value: Value::new(value),              is_secure: false, @@ -98,6 +102,12 @@ where          }      } +    /// Sets the [`Id`] of the [`TextInput`]. +    pub fn id(mut self, id: Id) -> Self { +        self.id = Some(id); +        self +    } +      /// Converts the [`TextInput`] into a secure password input.      pub fn password(mut self) -> Self {          self.is_secure = true; @@ -215,6 +225,17 @@ where          layout(renderer, limits, self.width, self.padding, self.size)      } +    fn operate( +        &self, +        tree: &mut Tree, +        _layout: Layout<'_>, +        operation: &mut dyn Operation<Message>, +    ) { +        let state = tree.state.downcast_mut::<State>(); + +        operation.focusable(state, self.id.as_ref().map(|id| &id.0)); +    } +      fn on_event(          &mut self,          tree: &mut Tree, @@ -294,6 +315,19 @@ where      }  } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Id(widget::Id); + +impl Id { +    pub fn new(id: impl Into<std::borrow::Cow<'static, str>>) -> Self { +        Self(widget::Id::new(id)) +    } +} + +pub fn focus<Message: 'static>(id: Id) -> Command<Message> { +    Command::widget(operation::focus(id.0)) +} +  /// Computes the layout of a [`TextInput`].  pub fn layout<Renderer>(      renderer: &Renderer, @@ -915,6 +949,7 @@ impl State {      /// Focuses the [`TextInput`].      pub fn focus(&mut self) {          self.is_focused = true; +        self.move_cursor_to_end();      }      /// Unfocuses the [`TextInput`].  | 
