diff options
| author | 2023-04-12 04:51:19 +0200 | |
|---|---|---|
| committer | 2023-04-12 04:51:19 +0200 | |
| commit | ce8e92ca7a4ed0f4fe284c9042f863f7c83ba03a (patch) | |
| tree | f9be0c6e0d8f9e2af6170f4370677918c4b43a2a /native/src/widget | |
| parent | ca828f03f5aab9efacc9d63d4149363333035a0c (diff) | |
| parent | 7e7e66586d990788ffd77b17e98357e74252f497 (diff) | |
| download | iced-ce8e92ca7a4ed0f4fe284c9042f863f7c83ba03a.tar.gz iced-ce8e92ca7a4ed0f4fe284c9042f863f7c83ba03a.tar.bz2 iced-ce8e92ca7a4ed0f4fe284c9042f863f7c83ba03a.zip | |
Merge pull request #1744 from JungleTryne/disable-text-input
Add functionality to make `TextInput` disabled 
Diffstat (limited to 'native/src/widget')
| -rw-r--r-- | native/src/widget/helpers.rs | 3 | ||||
| -rw-r--r-- | native/src/widget/text_input.rs | 91 | 
2 files changed, 65 insertions, 29 deletions
| diff --git a/native/src/widget/helpers.rs b/native/src/widget/helpers.rs index d13eca75..0363fc99 100644 --- a/native/src/widget/helpers.rs +++ b/native/src/widget/helpers.rs @@ -171,14 +171,13 @@ where  pub fn text_input<'a, Message, Renderer>(      placeholder: &str,      value: &str, -    on_change: impl Fn(String) -> Message + 'a,  ) -> widget::TextInput<'a, Message, Renderer>  where      Message: Clone,      Renderer: crate::text::Renderer,      Renderer::Theme: widget::text_input::StyleSheet,  { -    widget::TextInput::new(placeholder, value, on_change) +    widget::TextInput::new(placeholder, value)  }  /// Creates a new [`Slider`]. diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index fd61a849..8627aa98 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -46,8 +46,8 @@ pub use iced_style::text_input::{Appearance, StyleSheet};  /// let input = TextInput::new(  ///     "This is the placeholder...",  ///     value, -///     Message::TextInputChanged,  /// ) +/// .on_input(Message::TextInputChanged)  /// .padding(10);  /// ```  ///  @@ -65,7 +65,7 @@ where      width: Length,      padding: Padding,      size: Option<f32>, -    on_change: Box<dyn Fn(String) -> Message + 'a>, +    on_input: Option<Box<dyn Fn(String) -> Message + 'a>>,      on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,      on_submit: Option<Message>,      icon: Option<Icon<Renderer::Font>>, @@ -82,12 +82,8 @@ where      ///      /// It expects:      /// - a placeholder, -    /// - the current value, and -    /// - a function that produces a message when the [`TextInput`] changes. -    pub fn new<F>(placeholder: &str, value: &str, on_change: F) -> Self -    where -        F: 'a + Fn(String) -> Message, -    { +    /// - the current value +    pub fn new(placeholder: &str, value: &str) -> Self {          TextInput {              id: None,              placeholder: String::from(placeholder), @@ -97,7 +93,7 @@ where              width: Length::Fill,              padding: Padding::new(5.0),              size: None, -            on_change: Box::new(on_change), +            on_input: None,              on_paste: None,              on_submit: None,              icon: None, @@ -117,6 +113,25 @@ where          self      } +    /// Sets the message that should be produced when some text is typed into +    /// the [`TextInput`]. +    /// +    /// If this method is not called, the [`TextInput`] will be disabled. +    pub fn on_input<F>(mut self, callback: F) -> Self +    where +        F: 'a + Fn(String) -> Message, +    { +        self.on_input = Some(Box::new(callback)); +        self +    } + +    /// Sets the message that should be produced when the [`TextInput`] is +    /// focused and the enter key is pressed. +    pub fn on_submit(mut self, message: Message) -> Self { +        self.on_submit = Some(message); +        self +    } +      /// Sets the message that should be produced when some text is pasted into      /// the [`TextInput`].      pub fn on_paste( @@ -159,13 +174,6 @@ where          self      } -    /// Sets the message that should be produced when the [`TextInput`] is -    /// focused and the enter key is pressed. -    pub fn on_submit(mut self, message: Message) -> Self { -        self.on_submit = Some(message); -        self -    } -      /// Sets the style of the [`TextInput`].      pub fn style(          mut self, @@ -198,6 +206,7 @@ where              &self.placeholder,              self.size,              &self.font, +            self.on_input.is_none(),              self.is_secure,              self.icon.as_ref(),              &self.style, @@ -220,6 +229,18 @@ where          tree::State::new(State::new())      } +    fn diff(&self, tree: &mut Tree) { +        let state = tree.state.downcast_mut::<State>(); + +        // Unfocus text input if it becomes disabled +        if self.on_input.is_none() { +            state.last_click = None; +            state.is_focused = None; +            state.is_pasting = None; +            state.is_dragging = false; +        } +    } +      fn width(&self) -> Length {          self.width      } @@ -277,7 +298,7 @@ where              self.size,              &self.font,              self.is_secure, -            self.on_change.as_ref(), +            self.on_input.as_deref(),              self.on_paste.as_deref(),              &self.on_submit,              || tree.state.downcast_mut::<State>(), @@ -304,6 +325,7 @@ where              &self.placeholder,              self.size,              &self.font, +            self.on_input.is_none(),              self.is_secure,              self.icon.as_ref(),              &self.style, @@ -318,7 +340,7 @@ where          _viewport: &Rectangle,          _renderer: &Renderer,      ) -> mouse::Interaction { -        mouse_interaction(layout, cursor_position) +        mouse_interaction(layout, cursor_position, self.on_input.is_none())      }  } @@ -492,7 +514,7 @@ pub fn update<'a, Message, Renderer>(      size: Option<f32>,      font: &Renderer::Font,      is_secure: bool, -    on_change: &dyn Fn(String) -> Message, +    on_input: Option<&dyn Fn(String) -> Message>,      on_paste: Option<&dyn Fn(String) -> Message>,      on_submit: &Option<Message>,      state: impl FnOnce() -> &'a mut State, @@ -505,7 +527,8 @@ where          Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))          | Event::Touch(touch::Event::FingerPressed { .. }) => {              let state = state(); -            let is_clicked = layout.bounds().contains(cursor_position); +            let is_clicked = +                layout.bounds().contains(cursor_position) && on_input.is_some();              state.is_focused = if is_clicked {                  state.is_focused.or_else(|| { @@ -635,6 +658,8 @@ where              let state = state();              if let Some(focus) = &mut state.is_focused { +                let Some(on_input) = on_input else { return event::Status::Ignored }; +                  if state.is_pasting.is_none()                      && !state.keyboard_modifiers.command()                      && !c.is_control() @@ -643,7 +668,7 @@ where                      editor.insert(c); -                    let message = (on_change)(editor.contents()); +                    let message = (on_input)(editor.contents());                      shell.publish(message);                      focus.updated_at = Instant::now(); @@ -656,6 +681,8 @@ where              let state = state();              if let Some(focus) = &mut state.is_focused { +                let Some(on_input) = on_input else { return event::Status::Ignored }; +                  let modifiers = state.keyboard_modifiers;                  focus.updated_at = Instant::now(); @@ -681,7 +708,7 @@ where                          let mut editor = Editor::new(value, &mut state.cursor);                          editor.backspace(); -                        let message = (on_change)(editor.contents()); +                        let message = (on_input)(editor.contents());                          shell.publish(message);                      }                      keyboard::KeyCode::Delete => { @@ -701,7 +728,7 @@ where                          let mut editor = Editor::new(value, &mut state.cursor);                          editor.delete(); -                        let message = (on_change)(editor.contents()); +                        let message = (on_input)(editor.contents());                          shell.publish(message);                      }                      keyboard::KeyCode::Left => { @@ -776,7 +803,7 @@ where                          let mut editor = Editor::new(value, &mut state.cursor);                          editor.delete(); -                        let message = (on_change)(editor.contents()); +                        let message = (on_input)(editor.contents());                          shell.publish(message);                      }                      keyboard::KeyCode::V => { @@ -803,7 +830,7 @@ where                              let message = if let Some(paste) = &on_paste {                                  (paste)(editor.contents())                              } else { -                                (on_change)(editor.contents()) +                                (on_input)(editor.contents())                              };                              shell.publish(message); @@ -897,6 +924,7 @@ pub fn draw<Renderer>(      placeholder: &str,      size: Option<f32>,      font: &Renderer::Font, +    is_disabled: bool,      is_secure: bool,      icon: Option<&Icon<Renderer::Font>>,      style: &<Renderer::Theme as StyleSheet>::Style, @@ -914,7 +942,9 @@ pub fn draw<Renderer>(      let is_mouse_over = bounds.contains(cursor_position); -    let appearance = if state.is_focused() { +    let appearance = if is_disabled { +        theme.disabled(style) +    } else if state.is_focused() {          theme.focused(style)      } else if is_mouse_over {          theme.hovered(style) @@ -1057,6 +1087,8 @@ pub fn draw<Renderer>(              content: if text.is_empty() { placeholder } else { &text },              color: if text.is_empty() {                  theme.placeholder_color(style) +            } else if is_disabled { +                theme.disabled_color(style)              } else {                  theme.value_color(style)              }, @@ -1085,9 +1117,14 @@ pub fn draw<Renderer>(  pub fn mouse_interaction(      layout: Layout<'_>,      cursor_position: Point, +    is_disabled: bool,  ) -> mouse::Interaction {      if layout.bounds().contains(cursor_position) { -        mouse::Interaction::Text +        if is_disabled { +            mouse::Interaction::NotAllowed +        } else { +            mouse::Interaction::Text +        }      } else {          mouse::Interaction::default()      } | 
