summaryrefslogtreecommitdiffstats
path: root/native/src/widget/text.rs
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/widget/text.rs')
-rw-r--r--native/src/widget/text.rs162
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>