diff options
Diffstat (limited to 'native/src/widget')
| -rw-r--r-- | native/src/widget/helpers.rs | 3 | ||||
| -rw-r--r-- | native/src/widget/text_input.rs | 365 | 
2 files changed, 196 insertions, 172 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..65897a68 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_change(|_| 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_change: 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_change: None,              on_paste: None,              on_submit: None,              icon: None, @@ -175,6 +171,16 @@ where          self      } +    /// Sets the callback which is called when the text gets changed +    /// If not specified, the widget will be disabled +    pub fn on_change<F>(mut self, callback: F) -> Self +    where +        F: 'a + Fn(String) -> Message, +    { +        self.on_change = Some(Box::new(callback)); +        self +    } +      /// Draws the [`TextInput`] with the given [`Renderer`], overriding its      /// [`Value`] if provided.      /// @@ -201,6 +207,7 @@ where              self.is_secure,              self.icon.as_ref(),              &self.style, +            self.on_change.is_none(),          )      }  } @@ -277,7 +284,7 @@ where              self.size,              &self.font,              self.is_secure, -            self.on_change.as_ref(), +            self.on_change.as_deref(),              self.on_paste.as_deref(),              &self.on_submit,              || tree.state.downcast_mut::<State>(), @@ -307,6 +314,7 @@ where              self.is_secure,              self.icon.as_ref(),              &self.style, +            self.on_change.is_none(),          )      } @@ -492,7 +500,7 @@ pub fn update<'a, Message, Renderer>(      size: Option<f32>,      font: &Renderer::Font,      is_secure: bool, -    on_change: &dyn Fn(String) -> Message, +    on_change: Option<&dyn Fn(String) -> Message>,      on_paste: Option<&dyn Fn(String) -> Message>,      on_submit: &Option<Message>,      state: impl FnOnce() -> &'a mut State, @@ -501,11 +509,14 @@ where      Message: Clone,      Renderer: text::Renderer,  { +    let is_disabled = on_change.is_none(); +      match event {          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 = is_clicked && !is_disabled;              state.is_focused = if is_clicked {                  state.is_focused.or_else(|| { @@ -635,20 +646,22 @@ where              let state = state();              if let Some(focus) = &mut state.is_focused { -                if state.is_pasting.is_none() -                    && !state.keyboard_modifiers.command() -                    && !c.is_control() -                { -                    let mut editor = Editor::new(value, &mut state.cursor); +                if let Some(on_change) = on_change { +                    if state.is_pasting.is_none() +                        && !state.keyboard_modifiers.command() +                        && !c.is_control() +                    { +                        let mut editor = Editor::new(value, &mut state.cursor); -                    editor.insert(c); +                        editor.insert(c); -                    let message = (on_change)(editor.contents()); -                    shell.publish(message); +                        let message = (on_change)(editor.contents()); +                        shell.publish(message); -                    focus.updated_at = Instant::now(); +                        focus.updated_at = Instant::now(); -                    return event::Status::Captured; +                        return event::Status::Captured; +                    }                  }              }          } @@ -656,181 +669,188 @@ where              let state = state();              if let Some(focus) = &mut state.is_focused { -                let modifiers = state.keyboard_modifiers; -                focus.updated_at = Instant::now(); +                if let Some(on_change) = on_change { +                    let modifiers = state.keyboard_modifiers; +                    focus.updated_at = Instant::now(); -                match key_code { -                    keyboard::KeyCode::Enter -                    | keyboard::KeyCode::NumpadEnter => { -                        if let Some(on_submit) = on_submit.clone() { -                            shell.publish(on_submit); +                    match key_code { +                        keyboard::KeyCode::Enter +                        | keyboard::KeyCode::NumpadEnter => { +                            if let Some(on_submit) = on_submit.clone() { +                                shell.publish(on_submit); +                            }                          } -                    } -                    keyboard::KeyCode::Backspace => { -                        if platform::is_jump_modifier_pressed(modifiers) -                            && state.cursor.selection(value).is_none() -                        { -                            if is_secure { -                                let cursor_pos = state.cursor.end(value); -                                state.cursor.select_range(0, cursor_pos); -                            } else { -                                state.cursor.select_left_by_words(value); +                        keyboard::KeyCode::Backspace => { +                            if platform::is_jump_modifier_pressed(modifiers) +                                && state.cursor.selection(value).is_none() +                            { +                                if is_secure { +                                    let cursor_pos = state.cursor.end(value); +                                    state.cursor.select_range(0, cursor_pos); +                                } else { +                                    state.cursor.select_left_by_words(value); +                                }                              } + +                            let mut editor = +                                Editor::new(value, &mut state.cursor); +                            editor.backspace(); + +                            let message = (on_change)(editor.contents()); +                            shell.publish(message);                          } +                        keyboard::KeyCode::Delete => { +                            if platform::is_jump_modifier_pressed(modifiers) +                                && state.cursor.selection(value).is_none() +                            { +                                if is_secure { +                                    let cursor_pos = state.cursor.end(value); +                                    state +                                        .cursor +                                        .select_range(cursor_pos, value.len()); +                                } else { +                                    state.cursor.select_right_by_words(value); +                                } +                            } -                        let mut editor = Editor::new(value, &mut state.cursor); -                        editor.backspace(); +                            let mut editor = +                                Editor::new(value, &mut state.cursor); +                            editor.delete(); -                        let message = (on_change)(editor.contents()); -                        shell.publish(message); -                    } -                    keyboard::KeyCode::Delete => { -                        if platform::is_jump_modifier_pressed(modifiers) -                            && state.cursor.selection(value).is_none() -                        { -                            if is_secure { -                                let cursor_pos = state.cursor.end(value); -                                state -                                    .cursor -                                    .select_range(cursor_pos, value.len()); +                            let message = (on_change)(editor.contents()); +                            shell.publish(message); +                        } +                        keyboard::KeyCode::Left => { +                            if platform::is_jump_modifier_pressed(modifiers) +                                && !is_secure +                            { +                                if modifiers.shift() { +                                    state.cursor.select_left_by_words(value); +                                } else { +                                    state.cursor.move_left_by_words(value); +                                } +                            } else if modifiers.shift() { +                                state.cursor.select_left(value)                              } else { -                                state.cursor.select_right_by_words(value); +                                state.cursor.move_left(value);                              }                          } - -                        let mut editor = Editor::new(value, &mut state.cursor); -                        editor.delete(); - -                        let message = (on_change)(editor.contents()); -                        shell.publish(message); -                    } -                    keyboard::KeyCode::Left => { -                        if platform::is_jump_modifier_pressed(modifiers) -                            && !is_secure -                        { -                            if modifiers.shift() { -                                state.cursor.select_left_by_words(value); +                        keyboard::KeyCode::Right => { +                            if platform::is_jump_modifier_pressed(modifiers) +                                && !is_secure +                            { +                                if modifiers.shift() { +                                    state.cursor.select_right_by_words(value); +                                } else { +                                    state.cursor.move_right_by_words(value); +                                } +                            } else if modifiers.shift() { +                                state.cursor.select_right(value)                              } else { -                                state.cursor.move_left_by_words(value); +                                state.cursor.move_right(value);                              } -                        } else if modifiers.shift() { -                            state.cursor.select_left(value) -                        } else { -                            state.cursor.move_left(value);                          } -                    } -                    keyboard::KeyCode::Right => { -                        if platform::is_jump_modifier_pressed(modifiers) -                            && !is_secure -                        { +                        keyboard::KeyCode::Home => {                              if modifiers.shift() { -                                state.cursor.select_right_by_words(value); +                                state +                                    .cursor +                                    .select_range(state.cursor.start(value), 0);                              } else { -                                state.cursor.move_right_by_words(value); +                                state.cursor.move_to(0);                              } -                        } else if modifiers.shift() { -                            state.cursor.select_right(value) -                        } else { -                            state.cursor.move_right(value); -                        } -                    } -                    keyboard::KeyCode::Home => { -                        if modifiers.shift() { -                            state -                                .cursor -                                .select_range(state.cursor.start(value), 0); -                        } else { -                            state.cursor.move_to(0);                          } -                    } -                    keyboard::KeyCode::End => { -                        if modifiers.shift() { -                            state.cursor.select_range( -                                state.cursor.start(value), -                                value.len(), -                            ); -                        } else { -                            state.cursor.move_to(value.len()); +                        keyboard::KeyCode::End => { +                            if modifiers.shift() { +                                state.cursor.select_range( +                                    state.cursor.start(value), +                                    value.len(), +                                ); +                            } else { +                                state.cursor.move_to(value.len()); +                            }                          } -                    } -                    keyboard::KeyCode::C -                        if state.keyboard_modifiers.command() => -                    { -                        if let Some((start, end)) = -                            state.cursor.selection(value) +                        keyboard::KeyCode::C +                            if state.keyboard_modifiers.command() =>                          { -                            clipboard -                                .write(value.select(start, end).to_string()); +                            if let Some((start, end)) = +                                state.cursor.selection(value) +                            { +                                clipboard.write( +                                    value.select(start, end).to_string(), +                                ); +                            }                          } -                    } -                    keyboard::KeyCode::X -                        if state.keyboard_modifiers.command() => -                    { -                        if let Some((start, end)) = -                            state.cursor.selection(value) +                        keyboard::KeyCode::X +                            if state.keyboard_modifiers.command() =>                          { -                            clipboard -                                .write(value.select(start, end).to_string()); -                        } - -                        let mut editor = Editor::new(value, &mut state.cursor); -                        editor.delete(); - -                        let message = (on_change)(editor.contents()); -                        shell.publish(message); -                    } -                    keyboard::KeyCode::V => { -                        if state.keyboard_modifiers.command() { -                            let content = match state.is_pasting.take() { -                                Some(content) => content, -                                None => { -                                    let content: String = clipboard -                                        .read() -                                        .unwrap_or_default() -                                        .chars() -                                        .filter(|c| !c.is_control()) -                                        .collect(); - -                                    Value::new(&content) -                                } -                            }; +                            if let Some((start, end)) = +                                state.cursor.selection(value) +                            { +                                clipboard.write( +                                    value.select(start, end).to_string(), +                                ); +                            }                              let mut editor =                                  Editor::new(value, &mut state.cursor); +                            editor.delete(); -                            editor.paste(content.clone()); - -                            let message = if let Some(paste) = &on_paste { -                                (paste)(editor.contents()) -                            } else { -                                (on_change)(editor.contents()) -                            }; +                            let message = (on_change)(editor.contents());                              shell.publish(message); - -                            state.is_pasting = Some(content); -                        } else { -                            state.is_pasting = None;                          } -                    } -                    keyboard::KeyCode::A -                        if state.keyboard_modifiers.command() => -                    { -                        state.cursor.select_all(value); -                    } -                    keyboard::KeyCode::Escape => { -                        state.is_focused = None; -                        state.is_dragging = false; -                        state.is_pasting = None; +                        keyboard::KeyCode::V => { +                            if state.keyboard_modifiers.command() { +                                let content = match state.is_pasting.take() { +                                    Some(content) => content, +                                    None => { +                                        let content: String = clipboard +                                            .read() +                                            .unwrap_or_default() +                                            .chars() +                                            .filter(|c| !c.is_control()) +                                            .collect(); + +                                        Value::new(&content) +                                    } +                                }; + +                                let mut editor = +                                    Editor::new(value, &mut state.cursor); + +                                editor.paste(content.clone()); + +                                let message = if let Some(paste) = &on_paste { +                                    (paste)(editor.contents()) +                                } else { +                                    (on_change)(editor.contents()) +                                }; +                                shell.publish(message); + +                                state.is_pasting = Some(content); +                            } else { +                                state.is_pasting = None; +                            } +                        } +                        keyboard::KeyCode::A +                            if state.keyboard_modifiers.command() => +                        { +                            state.cursor.select_all(value); +                        } +                        keyboard::KeyCode::Escape => { +                            state.is_focused = None; +                            state.is_dragging = false; +                            state.is_pasting = None; -                        state.keyboard_modifiers = -                            keyboard::Modifiers::default(); -                    } -                    keyboard::KeyCode::Tab -                    | keyboard::KeyCode::Up -                    | keyboard::KeyCode::Down => { -                        return event::Status::Ignored; +                            state.keyboard_modifiers = +                                keyboard::Modifiers::default(); +                        } +                        keyboard::KeyCode::Tab +                        | keyboard::KeyCode::Up +                        | keyboard::KeyCode::Down => { +                            return event::Status::Ignored; +                        } +                        _ => {}                      } -                    _ => {}                  }                  return event::Status::Captured; @@ -900,6 +920,7 @@ pub fn draw<Renderer>(      is_secure: bool,      icon: Option<&Icon<Renderer::Font>>,      style: &<Renderer::Theme as StyleSheet>::Style, +    is_disabled: bool,  ) where      Renderer: text::Renderer,      Renderer::Theme: StyleSheet, @@ -914,7 +935,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) @@ -968,7 +991,7 @@ pub fn draw<Renderer>(                      % 2                      == 0; -                let cursor = if is_cursor_visible { +                let cursor = if is_cursor_visible && !is_disabled {                      Some((                          renderer::Quad {                              bounds: Rectangle { @@ -1057,6 +1080,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)              }, | 
