diff options
author | 2024-08-24 02:44:55 +0200 | |
---|---|---|
committer | 2024-08-24 02:44:55 +0200 | |
commit | 043f0302142e46bf1d7ba2015f83261813280fec (patch) | |
tree | 1b3ba467f823562d60c61faf6c6888c8427966df /widget | |
parent | 84e766fd0022783f36f02c99b150a79753e74791 (diff) | |
parent | 6c741923c64c54841bc4f3a8a1b694975ee2eed7 (diff) | |
download | iced-043f0302142e46bf1d7ba2015f83261813280fec.tar.gz iced-043f0302142e46bf1d7ba2015f83261813280fec.tar.bz2 iced-043f0302142e46bf1d7ba2015f83261813280fec.zip |
Merge pull request #2535 from bungoboingo/text-input-alignment
Implement `align_x` for `TextInput`
Diffstat (limited to 'widget')
-rw-r--r-- | widget/src/text_input.rs | 79 |
1 files changed, 69 insertions, 10 deletions
diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 173de136..2ac6f4ba 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -19,7 +19,7 @@ use crate::core::keyboard::key; use crate::core::layout; use crate::core::mouse::{self, click}; use crate::core::renderer; -use crate::core::text::paragraph; +use crate::core::text::paragraph::{self, Paragraph as _}; use crate::core::text::{self, Text}; use crate::core::time::{Duration, Instant}; use crate::core::touch; @@ -74,6 +74,7 @@ pub struct TextInput< padding: Padding, size: Option<Pixels>, line_height: text::LineHeight, + alignment: alignment::Horizontal, on_input: Option<Box<dyn Fn(String) -> Message + 'a>>, on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>, on_submit: Option<Message>, @@ -103,6 +104,7 @@ where padding: DEFAULT_PADDING, size: None, line_height: text::LineHeight::default(), + alignment: alignment::Horizontal::Left, on_input: None, on_paste: None, on_submit: None, @@ -193,6 +195,15 @@ where self } + /// Sets the horizontal alignment of the [`TextInput`]. + pub fn align_x( + mut self, + alignment: impl Into<alignment::Horizontal>, + ) -> Self { + self.alignment = alignment.into(); + self + } + /// Sets the style of the [`TextInput`]. #[must_use] pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self @@ -457,9 +468,21 @@ where }; let draw = |renderer: &mut Renderer, viewport| { + let paragraph = if text.is_empty() { + state.placeholder.raw() + } else { + state.value.raw() + }; + + let alignment_offset = alignment_offset( + text_bounds.width, + paragraph.min_width(), + self.alignment, + ); + if let Some((cursor, color)) = cursor { renderer.with_translation( - Vector::new(-offset, 0.0), + Vector::new(alignment_offset - offset, 0.0), |renderer| { renderer.fill_quad(cursor, color); }, @@ -469,13 +492,9 @@ where } renderer.fill_paragraph( - if text.is_empty() { - state.placeholder.raw() - } else { - state.value.raw() - }, + paragraph, Point::new(text_bounds.x, text_bounds.center_y()) - - Vector::new(offset, 0.0), + + Vector::new(alignment_offset - offset, 0.0), if text.is_empty() { style.placeholder } else { @@ -600,7 +619,18 @@ where if let Some(cursor_position) = click_position { let text_layout = layout.children().next().unwrap(); - let target = cursor_position.x - text_layout.bounds().x; + + let target = { + let text_bounds = text_layout.bounds(); + + let alignment_offset = alignment_offset( + text_bounds.width, + state.value.raw().min_width(), + self.alignment, + ); + + cursor_position.x - text_bounds.x - alignment_offset + }; let click = mouse::Click::new(cursor_position, state.last_click); @@ -677,7 +707,18 @@ where if state.is_dragging { let text_layout = layout.children().next().unwrap(); - let target = position.x - text_layout.bounds().x; + + let target = { + let text_bounds = text_layout.bounds(); + + let alignment_offset = alignment_offset( + text_bounds.width, + state.value.raw().min_width(), + self.alignment, + ); + + position.x - text_bounds.x - alignment_offset + }; let value = if self.is_secure { self.value.secure() @@ -1486,3 +1527,21 @@ pub fn default(theme: &Theme, status: Status) -> Style { }, } } + +fn alignment_offset( + text_bounds_width: f32, + text_min_width: f32, + alignment: alignment::Horizontal, +) -> f32 { + if text_min_width > text_bounds_width { + 0.0 + } else { + match alignment { + alignment::Horizontal::Left => 0.0, + alignment::Horizontal::Center => { + (text_bounds_width - text_min_width) / 2.0 + } + alignment::Horizontal::Right => text_bounds_width - text_min_width, + } + } +} |