diff options
Diffstat (limited to 'native/src/widget/text.rs')
-rw-r--r-- | native/src/widget/text.rs | 162 |
1 files changed, 146 insertions, 16 deletions
diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs index 10d892a3..f949b607 100644 --- a/native/src/widget/text.rs +++ b/native/src/widget/text.rs @@ -1,9 +1,113 @@ //! Write some text for your users to read. -use crate::{layout, Element, Hasher, Layout, Length, Point, Widget}; +use crate::{ + layout, Color, Element, Font, Hasher, HorizontalAlignment, Layout, Length, + Point, Rectangle, Size, VerticalAlignment, Widget, +}; use std::hash::Hash; -pub use iced_core::text::*; +/// A paragraph of text. +/// +/// # Example +/// +/// ``` +/// # use iced_native::Text; +/// +/// Text::new("I <3 iced!") +/// .size(40); +/// ``` +#[derive(Debug, Clone)] +pub struct Text { + content: String, + size: Option<u16>, + color: Option<Color>, + font: Font, + width: Length, + height: Length, + horizontal_alignment: HorizontalAlignment, + vertical_alignment: VerticalAlignment, +} + +impl Text { + /// Create a new fragment of [`Text`] with the given contents. + /// + /// [`Text`]: struct.Text.html + pub fn new(label: &str) -> Self { + Text { + content: String::from(label), + size: None, + color: None, + font: Font::Default, + width: Length::Fill, + height: Length::Shrink, + horizontal_alignment: HorizontalAlignment::Left, + vertical_alignment: VerticalAlignment::Top, + } + } + + /// Sets the size of the [`Text`]. + /// + /// [`Text`]: struct.Text.html + pub fn size(mut self, size: u16) -> Self { + self.size = Some(size); + self + } + + /// Sets the [`Color`] of the [`Text`]. + /// + /// [`Text`]: struct.Text.html + /// [`Color`]: ../../struct.Color.html + pub fn color<C: Into<Color>>(mut self, color: C) -> Self { + self.color = Some(color.into()); + self + } + + /// Sets the [`Font`] of the [`Text`]. + /// + /// [`Text`]: struct.Text.html + /// [`Font`]: ../../struct.Font.html + pub fn font(mut self, font: Font) -> Self { + self.font = font; + self + } + + /// Sets the width of the [`Text`] boundaries. + /// + /// [`Text`]: struct.Text.html + pub fn width(mut self, width: Length) -> Self { + self.width = width; + self + } + + /// Sets the height of the [`Text`] boundaries. + /// + /// [`Text`]: struct.Text.html + pub fn height(mut self, height: Length) -> Self { + self.height = height; + self + } + + /// Sets the [`HorizontalAlignment`] of the [`Text`]. + /// + /// [`Text`]: struct.Text.html + /// [`HorizontalAlignment`]: enum.HorizontalAlignment.html + pub fn horizontal_alignment( + mut self, + alignment: HorizontalAlignment, + ) -> Self { + self.horizontal_alignment = alignment; + self + } + + /// Sets the [`VerticalAlignment`] of the [`Text`]. + /// + /// [`Text`]: struct.Text.html + /// [`VerticalAlignment`]: enum.VerticalAlignment.html + pub fn vertical_alignment(mut self, alignment: VerticalAlignment) -> Self { + self.vertical_alignment = alignment; + self + } +} impl<Message, Renderer> Widget<Message, Renderer> for Text where @@ -18,7 +122,18 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - renderer.layout(&self, limits) + let limits = limits.width(self.width).height(self.height); + + let size = self.size.unwrap_or(renderer.default_size()); + + let bounds = limits.max(); + + let (width, height) = + renderer.measure(&self.content, size, self.font, bounds); + + let size = limits.resolve(Size::new(width, height)); + + layout::Node::new(size) } fn draw( @@ -27,7 +142,15 @@ where layout: Layout<'_>, _cursor_position: Point, ) -> Renderer::Output { - renderer.draw(&self, layout) + renderer.draw( + layout.bounds(), + &self.content, + self.size.unwrap_or(renderer.default_size()), + self.font, + self.color, + self.horizontal_alignment, + self.vertical_alignment, + ) } fn hash_layout(&self, state: &mut Hasher) { @@ -47,17 +170,15 @@ where /// [renderer]: ../../renderer/index.html /// [`UserInterface`]: ../../struct.UserInterface.html pub trait Renderer: crate::Renderer { - /// Creates a [`Node`] with the given [`Style`] for the provided [`Text`] - /// contents and size. - /// - /// You should probably use [`Node::with_measure`] to allow [`Text`] to - /// adapt to the dimensions of its container. - /// - /// [`Node`]: ../../struct.Node.html - /// [`Style`]: ../../struct.Style.html - /// [`Text`]: struct.Text.html - /// [`Node::with_measure`]: ../../struct.Node.html#method.with_measure - fn layout(&self, text: &Text, limits: &layout::Limits) -> layout::Node; + fn default_size(&self) -> u16; + + fn measure( + &self, + content: &str, + size: u16, + font: Font, + bounds: Size, + ) -> (f32, f32); /// Draws a [`Text`] fragment. /// @@ -72,7 +193,16 @@ pub trait Renderer: crate::Renderer { /// [`Text`]: struct.Text.html /// [`HorizontalAlignment`]: enum.HorizontalAlignment.html /// [`VerticalAlignment`]: enum.VerticalAlignment.html - fn draw(&mut self, text: &Text, layout: Layout<'_>) -> Self::Output; + fn draw( + &mut self, + bounds: Rectangle, + content: &str, + size: u16, + font: Font, + color: Option<Color>, + horizontal_alignment: HorizontalAlignment, + vertical_alignment: VerticalAlignment, + ) -> Self::Output; } impl<'a, Message, Renderer> From<Text> for Element<'a, Message, Renderer> |