iced_core/text/
paragraph.rs1use crate::alignment;
3use crate::text::{Difference, Hit, Span, Text};
4use crate::{Point, Rectangle, Size};
5
6pub trait Paragraph: Sized + Default {
8 type Font: Copy + PartialEq;
10
11 fn with_text(text: Text<&str, Self::Font>) -> Self;
13
14 fn with_spans<Link>(
16 text: Text<&[Span<'_, Link, Self::Font>], Self::Font>,
17 ) -> Self;
18
19 fn resize(&mut self, new_bounds: Size);
21
22 fn compare(&self, text: Text<(), Self::Font>) -> Difference;
25
26 fn horizontal_alignment(&self) -> alignment::Horizontal;
28
29 fn vertical_alignment(&self) -> alignment::Vertical;
31
32 fn min_bounds(&self) -> Size;
35
36 fn hit_test(&self, point: Point) -> Option<Hit>;
39
40 fn hit_span(&self, point: Point) -> Option<usize>;
44
45 fn span_bounds(&self, index: usize) -> Vec<Rectangle>;
48
49 fn grapheme_position(&self, line: usize, index: usize) -> Option<Point>;
51
52 fn min_width(&self) -> f32 {
54 self.min_bounds().width
55 }
56
57 fn min_height(&self) -> f32 {
59 self.min_bounds().height
60 }
61}
62
63#[derive(Debug, Clone, Default)]
65pub struct Plain<P: Paragraph> {
66 raw: P,
67 content: String,
68}
69
70impl<P: Paragraph> Plain<P> {
71 pub fn new(text: Text<&str, P::Font>) -> Self {
73 let content = text.content.to_owned();
74
75 Self {
76 raw: P::with_text(text),
77 content,
78 }
79 }
80
81 pub fn update(&mut self, text: Text<&str, P::Font>) {
83 if self.content != text.content {
84 text.content.clone_into(&mut self.content);
85 self.raw = P::with_text(text);
86 return;
87 }
88
89 match self.raw.compare(Text {
90 content: (),
91 bounds: text.bounds,
92 size: text.size,
93 line_height: text.line_height,
94 font: text.font,
95 horizontal_alignment: text.horizontal_alignment,
96 vertical_alignment: text.vertical_alignment,
97 shaping: text.shaping,
98 wrapping: text.wrapping,
99 }) {
100 Difference::None => {}
101 Difference::Bounds => {
102 self.raw.resize(text.bounds);
103 }
104 Difference::Shape => {
105 self.raw = P::with_text(text);
106 }
107 }
108 }
109
110 pub fn horizontal_alignment(&self) -> alignment::Horizontal {
112 self.raw.horizontal_alignment()
113 }
114
115 pub fn vertical_alignment(&self) -> alignment::Vertical {
117 self.raw.vertical_alignment()
118 }
119
120 pub fn min_bounds(&self) -> Size {
123 self.raw.min_bounds()
124 }
125
126 pub fn min_width(&self) -> f32 {
129 self.raw.min_width()
130 }
131
132 pub fn raw(&self) -> &P {
134 &self.raw
135 }
136}