diff options
Diffstat (limited to 'native/src/widget/text.rs')
-rw-r--r-- | native/src/widget/text.rs | 133 |
1 files changed, 60 insertions, 73 deletions
diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs index 168d49c2..4dbc4a65 100644 --- a/native/src/widget/text.rs +++ b/native/src/widget/text.rs @@ -1,12 +1,12 @@ //! Write some text for your users to read. use crate::alignment; use crate::layout; +use crate::renderer; +use crate::text; use crate::{ Color, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, }; -pub use iced_core::text::Hit; - use std::hash::Hash; /// A paragraph of text. @@ -14,7 +14,7 @@ use std::hash::Hash; /// # Example /// /// ``` -/// # type Text = iced_native::Text<iced_native::renderer::Null>; +/// # type Text = iced_native::widget::Text<iced_native::renderer::Null>; /// # /// Text::new("I <3 iced!") /// .color([0.0, 0.0, 1.0]) @@ -23,7 +23,7 @@ use std::hash::Hash; /// ///  #[derive(Debug)] -pub struct Text<Renderer: self::Renderer> { +pub struct Text<Renderer: text::Renderer> { content: String, size: Option<u16>, color: Option<Color>, @@ -34,7 +34,7 @@ pub struct Text<Renderer: self::Renderer> { vertical_alignment: alignment::Vertical, } -impl<Renderer: self::Renderer> Text<Renderer> { +impl<Renderer: text::Renderer> Text<Renderer> { /// Create a new fragment of [`Text`] with the given contents. pub fn new<T: Into<String>>(label: T) -> Self { Text { @@ -102,7 +102,7 @@ impl<Renderer: self::Renderer> Text<Renderer> { impl<Message, Renderer> Widget<Message, Renderer> for Text<Renderer> where - Renderer: self::Renderer, + Renderer: text::Renderer, { fn width(&self) -> Length { self.width @@ -134,21 +134,22 @@ where fn draw( &self, renderer: &mut Renderer, - defaults: &Renderer::Defaults, + style: &renderer::Style, layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, - ) -> Renderer::Output { - renderer.draw( - defaults, - layout.bounds(), + ) { + draw( + renderer, + style, + layout, &self.content, - self.size.unwrap_or(renderer.default_size()), self.font, + self.size, self.color, self.horizontal_alignment, self.vertical_alignment, - ) + ); } fn hash_layout(&self, state: &mut Hasher) { @@ -162,79 +163,65 @@ where } } -/// The renderer of a [`Text`] fragment. +/// Draws text using the same logic as the [`Text`] widget. /// -/// Your [renderer] will need to implement this trait before being -/// able to use [`Text`] in your user interface. +/// Specifically: /// -/// [renderer]: crate::Renderer -pub trait Renderer: crate::Renderer { - /// The font type used for [`Text`]. - type Font: Default + Copy; - - /// Returns the default size of [`Text`]. - fn default_size(&self) -> u16; - - /// Measures the [`Text`] in the given bounds and returns the minimum - /// boundaries that can fit the contents. - fn measure( - &self, - content: &str, - size: u16, - font: Self::Font, - bounds: Size, - ) -> (f32, f32); - - /// Tests whether the provided point is within the boundaries of [`Text`] - /// laid out with the given parameters, returning information about - /// the nearest character. - /// - /// If `nearest_only` is true, the hit test does not consider whether the - /// the point is interior to any glyph bounds, returning only the character - /// with the nearest centeroid. - fn hit_test( - &self, - contents: &str, - size: f32, - font: Self::Font, - bounds: Size, - point: Point, - nearest_only: bool, - ) -> Option<Hit>; - - /// Draws a [`Text`] fragment. - /// - /// It receives: - /// * the bounds of the [`Text`] - /// * the contents of the [`Text`] - /// * the size of the [`Text`] - /// * the color of the [`Text`] - /// * the [`HorizontalAlignment`] of the [`Text`] - /// * the [`VerticalAlignment`] of the [`Text`] - fn draw( - &mut self, - defaults: &Self::Defaults, - bounds: Rectangle, - content: &str, - size: u16, - font: Self::Font, - color: Option<Color>, - horizontal_alignment: alignment::Horizontal, - vertical_alignment: alignment::Vertical, - ) -> Self::Output; +/// * If no `size` is provided, the default text size of the `Renderer` will be +/// used. +/// * If no `color` is provided, the [`renderer::Style::text_color`] will be +/// used. +/// * The alignment attributes do not affect the position of the bounds of the +/// [`Layout`]. +pub fn draw<Renderer>( + renderer: &mut Renderer, + style: &renderer::Style, + layout: Layout<'_>, + content: &str, + font: Renderer::Font, + size: Option<u16>, + color: Option<Color>, + horizontal_alignment: alignment::Horizontal, + vertical_alignment: alignment::Vertical, +) where + Renderer: text::Renderer, +{ + let bounds = layout.bounds(); + + let x = match horizontal_alignment { + alignment::Horizontal::Left => bounds.x, + alignment::Horizontal::Center => bounds.center_x(), + alignment::Horizontal::Right => bounds.x + bounds.width, + }; + + let y = match vertical_alignment { + alignment::Vertical::Top => bounds.y, + alignment::Vertical::Center => bounds.center_y(), + alignment::Vertical::Bottom => bounds.y + bounds.height, + }; + + renderer.fill_text(crate::text::Text { + content, + size: f32::from(size.unwrap_or(renderer.default_size())), + bounds: Rectangle { x, y, ..bounds }, + color: color.unwrap_or(style.text_color), + font, + horizontal_alignment, + vertical_alignment, + }); } impl<'a, Message, Renderer> From<Text<Renderer>> for Element<'a, Message, Renderer> where - Renderer: self::Renderer + 'a, + Renderer: text::Renderer + 'a, { fn from(text: Text<Renderer>) -> Element<'a, Message, Renderer> { Element::new(text) } } -impl<Renderer: self::Renderer> Clone for Text<Renderer> { +impl<Renderer: text::Renderer> Clone for Text<Renderer> { fn clone(&self) -> Self { Self { content: self.content.clone(), |