summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--native/src/widget/checkbox.rs22
-rw-r--r--native/src/widget/text_input.rs111
2 files changed, 117 insertions, 16 deletions
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index 9b69e574..ad05a8e7 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -14,17 +14,6 @@ use crate::{
pub use iced_style::checkbox::{Appearance, StyleSheet};
-/// The icon in a [`Checkbox`].
-#[derive(Debug, Clone, PartialEq)]
-pub struct Icon<Font> {
- /// Font that will be used to display the `code_point`,
- pub font: Font,
- /// The unicode code point that will be used as the icon.
- pub code_point: char,
- /// Font size of the content.
- pub size: Option<f32>,
-}
-
/// A box that can be checked.
///
/// # Example
@@ -319,3 +308,14 @@ where
Element::new(checkbox)
}
}
+
+/// The icon in a [`Checkbox`].
+#[derive(Debug, Clone, PartialEq)]
+pub struct Icon<Font> {
+ /// Font that will be used to display the `code_point`,
+ pub font: Font,
+ /// The unicode code point that will be used as the icon.
+ pub code_point: char,
+ /// Font size of the content.
+ pub size: Option<f32>,
+}
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs
index ee0473ea..fd61a849 100644
--- a/native/src/widget/text_input.rs
+++ b/native/src/widget/text_input.rs
@@ -68,6 +68,7 @@ where
on_change: Box<dyn Fn(String) -> Message + 'a>,
on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,
on_submit: Option<Message>,
+ icon: Option<Icon<Renderer::Font>>,
style: <Renderer::Theme as StyleSheet>::Style,
}
@@ -99,6 +100,7 @@ where
on_change: Box::new(on_change),
on_paste: None,
on_submit: None,
+ icon: None,
style: Default::default(),
}
}
@@ -132,6 +134,13 @@ where
self.font = font;
self
}
+
+ /// Sets the [`Icon`] of the [`TextInput`].
+ pub fn icon(mut self, icon: Icon<Renderer::Font>) -> Self {
+ self.icon = Some(icon);
+ self
+ }
+
/// Sets the width of the [`TextInput`].
pub fn width(mut self, width: impl Into<Length>) -> Self {
self.width = width.into();
@@ -190,6 +199,7 @@ where
self.size,
&self.font,
self.is_secure,
+ self.icon.as_ref(),
&self.style,
)
}
@@ -223,7 +233,14 @@ where
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
- layout(renderer, limits, self.width, self.padding, self.size)
+ layout(
+ renderer,
+ limits,
+ self.width,
+ self.padding,
+ self.size,
+ self.icon.as_ref(),
+ )
}
fn operate(
@@ -288,6 +305,7 @@ where
self.size,
&self.font,
self.is_secure,
+ self.icon.as_ref(),
&self.style,
)
}
@@ -318,6 +336,30 @@ where
}
}
+/// The content of the [`Icon`].
+#[derive(Debug, Clone)]
+pub struct Icon<Font> {
+ /// The font that will be used to display the `code_point`.
+ pub font: Font,
+ /// The unicode code point that will be used as the icon.
+ pub code_point: char,
+ /// The font size of the content.
+ pub size: Option<f32>,
+ /// The spacing between the [`Icon`] and the text in a [`TextInput`].
+ pub spacing: f32,
+ /// The side of a [`TextInput`] where to display the [`Icon`].
+ pub side: Side,
+}
+
+/// The side of a [`TextInput`].
+#[derive(Debug, Clone)]
+pub enum Side {
+ /// The left side of a [`TextInput`].
+ Left,
+ /// The right side of a [`TextInput`].
+ Right,
+}
+
/// The identifier of a [`TextInput`].
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Id(widget::Id);
@@ -380,6 +422,7 @@ pub fn layout<Renderer>(
width: Length,
padding: Padding,
size: Option<f32>,
+ icon: Option<&Icon<Renderer::Font>>,
) -> layout::Node
where
Renderer: text::Renderer,
@@ -389,10 +432,51 @@ where
let padding = padding.fit(Size::ZERO, limits.max());
let limits = limits.width(width).pad(padding).height(text_size);
- let mut text = layout::Node::new(limits.resolve(Size::ZERO));
- text.move_to(Point::new(padding.left, padding.top));
+ let text_bounds = limits.resolve(Size::ZERO);
+
+ if let Some(icon) = icon {
+ let icon_width = renderer.measure_width(
+ &icon.code_point.to_string(),
+ icon.size.unwrap_or_else(|| renderer.default_size()),
+ icon.font.clone(),
+ );
+
+ let mut text_node = layout::Node::new(
+ text_bounds - Size::new(icon_width + icon.spacing, 0.0),
+ );
+
+ let mut icon_node =
+ layout::Node::new(Size::new(icon_width, text_bounds.height));
+
+ match icon.side {
+ Side::Left => {
+ text_node.move_to(Point::new(
+ padding.left + icon_width + icon.spacing,
+ padding.top,
+ ));
- layout::Node::with_children(text.size().pad(padding), vec![text])
+ icon_node.move_to(Point::new(padding.left, padding.top));
+ }
+ Side::Right => {
+ text_node.move_to(Point::new(padding.left, padding.top));
+
+ icon_node.move_to(Point::new(
+ padding.left + text_bounds.width - icon_width,
+ padding.top,
+ ));
+ }
+ };
+
+ layout::Node::with_children(
+ text_bounds.pad(padding),
+ vec![text_node, icon_node],
+ )
+ } else {
+ let mut text = layout::Node::new(text_bounds);
+ text.move_to(Point::new(padding.left, padding.top));
+
+ layout::Node::with_children(text_bounds.pad(padding), vec![text])
+ }
}
/// Processes an [`Event`] and updates the [`State`] of a [`TextInput`]
@@ -814,6 +898,7 @@ pub fn draw<Renderer>(
size: Option<f32>,
font: &Renderer::Font,
is_secure: bool,
+ icon: Option<&Icon<Renderer::Font>>,
style: &<Renderer::Theme as StyleSheet>::Style,
) where
Renderer: text::Renderer,
@@ -823,7 +908,9 @@ pub fn draw<Renderer>(
let value = secure_value.as_ref().unwrap_or(value);
let bounds = layout.bounds();
- let text_bounds = layout.children().next().unwrap().bounds();
+
+ let mut children_layout = layout.children();
+ let text_bounds = children_layout.next().unwrap().bounds();
let is_mouse_over = bounds.contains(cursor_position);
@@ -845,6 +932,20 @@ pub fn draw<Renderer>(
appearance.background,
);
+ if let Some(icon) = icon {
+ let icon_layout = children_layout.next().unwrap();
+
+ renderer.fill_text(Text {
+ content: &icon.code_point.to_string(),
+ size: icon.size.unwrap_or_else(|| renderer.default_size()),
+ font: icon.font.clone(),
+ color: appearance.icon_color,
+ bounds: icon_layout.bounds(),
+ horizontal_alignment: alignment::Horizontal::Left,
+ vertical_alignment: alignment::Vertical::Top,
+ });
+ }
+
let text = value.to_string();
let size = size.unwrap_or_else(|| renderer.default_size());