diff options
Diffstat (limited to 'widget/src/text_input.rs')
-rw-r--r-- | widget/src/text_input.rs | 96 |
1 files changed, 70 insertions, 26 deletions
diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 2ac6f4ba..d5ede524 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -129,11 +129,23 @@ where /// 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)); + pub fn on_input( + mut self, + on_input: impl Fn(String) -> Message + 'a, + ) -> Self { + self.on_input = Some(Box::new(on_input)); + self + } + + /// Sets the message that should be produced when some text is typed into + /// the [`TextInput`], if `Some`. + /// + /// If `None`, the [`TextInput`] will be disabled. + pub fn on_input_maybe( + mut self, + on_input: Option<impl Fn(String) -> Message + 'a>, + ) -> Self { + self.on_input = on_input.map(|f| Box::new(f) as _); self } @@ -144,6 +156,13 @@ where self } + /// Sets the message that should be produced when the [`TextInput`] is + /// focused and the enter key is pressed, if `Some`. + pub fn on_submit_maybe(mut self, on_submit: Option<Message>) -> Self { + self.on_submit = on_submit; + self + } + /// Sets the message that should be produced when some text is pasted into /// the [`TextInput`]. pub fn on_paste( @@ -154,6 +173,16 @@ where self } + /// Sets the message that should be produced when some text is pasted into + /// the [`TextInput`], if `Some`. + pub fn on_paste_maybe( + mut self, + on_paste: Option<impl Fn(String) -> Message + 'a>, + ) -> Self { + self.on_paste = on_paste.map(|f| Box::new(f) as _); + self + } + /// Sets the [`Font`] of the [`TextInput`]. /// /// [`Font`]: text::Renderer::Font @@ -251,6 +280,7 @@ where horizontal_alignment: alignment::Horizontal::Left, vertical_alignment: alignment::Vertical::Center, shaping: text::Shaping::Advanced, + wrapping: text::Wrapping::default(), }; state.placeholder.update(placeholder_text); @@ -275,6 +305,7 @@ where horizontal_alignment: alignment::Horizontal::Center, vertical_alignment: alignment::Vertical::Center, shaping: text::Shaping::Advanced, + wrapping: text::Wrapping::default(), }; state.icon.update(icon_text); @@ -395,11 +426,11 @@ where position, ); - let is_cursor_visible = ((focus.now - focus.updated_at) - .as_millis() - / CURSOR_BLINK_INTERVAL_MILLIS) - % 2 - == 0; + let is_cursor_visible = !is_disabled + && ((focus.now - focus.updated_at).as_millis() + / CURSOR_BLINK_INTERVAL_MILLIS) + % 2 + == 0; let cursor = if is_cursor_visible { Some(( @@ -531,12 +562,9 @@ where fn diff(&self, tree: &mut Tree) { let state = tree.state.downcast_mut::<State<Renderer::Paragraph>>(); - // Unfocus text input if it becomes disabled + // Stop pasting if input becomes disabled if self.on_input.is_none() { - state.last_click = None; - state.is_focused = None; state.is_pasting = None; - state.is_dragging = false; } } @@ -597,11 +625,7 @@ where | Event::Touch(touch::Event::FingerPressed { .. }) => { let state = state::<Renderer>(tree); - let click_position = if self.on_input.is_some() { - cursor.position_over(layout.bounds()) - } else { - None - }; + let click_position = cursor.position_over(layout.bounds()); state.is_focused = if click_position.is_some() { state.is_focused.or_else(|| { @@ -632,8 +656,11 @@ where cursor_position.x - text_bounds.x - alignment_offset }; - let click = - mouse::Click::new(cursor_position, state.last_click); + let click = mouse::Click::new( + cursor_position, + mouse::Button::Left, + state.last_click, + ); match click.kind() { click::Kind::Single => { @@ -747,10 +774,6 @@ where let state = state::<Renderer>(tree); if let Some(focus) = &mut state.is_focused { - let Some(on_input) = &self.on_input else { - return event::Status::Ignored; - }; - let modifiers = state.keyboard_modifiers; focus.updated_at = Instant::now(); @@ -774,6 +797,10 @@ where if state.keyboard_modifiers.command() && !self.is_secure => { + let Some(on_input) = &self.on_input else { + return event::Status::Ignored; + }; + if let Some((start, end)) = state.cursor.selection(&self.value) { @@ -798,6 +825,10 @@ where if state.keyboard_modifiers.command() && !state.keyboard_modifiers.alt() => { + let Some(on_input) = &self.on_input else { + return event::Status::Ignored; + }; + let content = match state.is_pasting.take() { Some(content) => content, None => { @@ -841,6 +872,10 @@ where } if let Some(text) = text { + let Some(on_input) = &self.on_input else { + return event::Status::Ignored; + }; + state.is_pasting = None; if let Some(c) = @@ -869,6 +904,10 @@ where } } keyboard::Key::Named(key::Named::Backspace) => { + let Some(on_input) = &self.on_input else { + return event::Status::Ignored; + }; + if modifiers.jump() && state.cursor.selection(&self.value).is_none() { @@ -893,6 +932,10 @@ where update_cache(state, &self.value); } keyboard::Key::Named(key::Named::Delete) => { + let Some(on_input) = &self.on_input else { + return event::Status::Ignored; + }; + if modifiers.jump() && state.cursor.selection(&self.value).is_none() { @@ -1111,7 +1154,7 @@ where ) -> mouse::Interaction { if cursor.is_over(layout.bounds()) { if self.on_input.is_none() { - mouse::Interaction::NotAllowed + mouse::Interaction::Idle } else { mouse::Interaction::Text } @@ -1423,6 +1466,7 @@ fn replace_paragraph<Renderer>( horizontal_alignment: alignment::Horizontal::Left, vertical_alignment: alignment::Vertical::Top, shaping: text::Shaping::Advanced, + wrapping: text::Wrapping::default(), }); } |