Skip to content

Commit

Permalink
Merge pull request #2535 from bungoboingo/text-input-alignment
Browse files Browse the repository at this point in the history
Implement `align_x` for `TextInput`
  • Loading branch information
hecrj authored Aug 24, 2024
2 parents 84e766f + 6c74192 commit 043f030
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 11 deletions.
3 changes: 2 additions & 1 deletion examples/todos/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ impl Todos {
.on_input(Message::InputChanged)
.on_submit(Message::CreateTask)
.padding(15)
.size(30);
.size(30)
.align_x(Center);

let controls = view_controls(tasks, *filter);
let filtered_tasks =
Expand Down
79 changes: 69 additions & 10 deletions widget/src/text_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
},
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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,
}
}
}

0 comments on commit 043f030

Please sign in to comment.