summaryrefslogtreecommitdiffstats
path: root/widget/src/text_input.rs
diff options
context:
space:
mode:
Diffstat (limited to 'widget/src/text_input.rs')
-rw-r--r--widget/src/text_input.rs96
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(),
});
}