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.rs133
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;
///
/// ![Text drawn by `iced_wgpu`](https://github.com/hecrj/iced/blob/7760618fb112074bc40b148944521f312152012a/docs/images/text.png?raw=true)
#[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(),