1use crate::{
2 color::ColorU,
3 fonts::{FamilyId, Properties},
4 geometry::vector::{vec2f, Vector2F},
5 text_layout::Line,
6 AfterLayoutContext, AppContext, Element, Event, EventContext, LayoutContext, MutableAppContext,
7 PaintContext, SizeConstraint,
8};
9use std::{ops::Range, sync::Arc};
10
11pub struct Label {
12 text: String,
13 family_id: FamilyId,
14 font_properties: Properties,
15 font_size: f32,
16 highlights: Option<Highlights>,
17 layout_line: Option<Arc<Line>>,
18 colors: Option<Vec<(Range<usize>, ColorU)>>,
19 size: Option<Vector2F>,
20}
21
22pub struct Highlights {
23 color: ColorU,
24 indices: Vec<usize>,
25 font_properties: Properties,
26}
27
28impl Label {
29 pub fn new(text: String, family_id: FamilyId, font_size: f32) -> Self {
30 Self {
31 text,
32 family_id,
33 font_properties: Properties::new(),
34 font_size,
35 highlights: None,
36 layout_line: None,
37 colors: None,
38 size: None,
39 }
40 }
41
42 pub fn with_highlights(
43 mut self,
44 color: ColorU,
45 font_properties: Properties,
46 indices: Vec<usize>,
47 ) -> Self {
48 self.highlights = Some(Highlights {
49 color,
50 font_properties,
51 indices,
52 });
53 self
54 }
55}
56
57impl Element for Label {
58 fn layout(
59 &mut self,
60 constraint: SizeConstraint,
61 ctx: &mut LayoutContext,
62 _: &AppContext,
63 ) -> Vector2F {
64 let font_id = ctx
65 .font_cache
66 .select_font(self.family_id, &self.font_properties)
67 .unwrap();
68 let text_len = self.text.chars().count();
69 let mut styles;
70 let mut colors;
71 if let Some(highlights) = self.highlights.as_ref() {
72 styles = Vec::new();
73 colors = Vec::new();
74 let highlight_font_id = ctx
75 .font_cache
76 .select_font(self.family_id, &highlights.font_properties)
77 .unwrap_or(font_id);
78 let mut pending_highlight: Option<Range<usize>> = None;
79 for ix in &highlights.indices {
80 if let Some(pending_highlight) = pending_highlight.as_mut() {
81 if *ix == pending_highlight.end {
82 pending_highlight.end += 1;
83 } else {
84 styles.push((pending_highlight.clone(), highlight_font_id));
85 colors.push((pending_highlight.clone(), highlights.color));
86 styles.push((pending_highlight.end..*ix, font_id));
87 colors.push((pending_highlight.end..*ix, ColorU::black()));
88 *pending_highlight = *ix..*ix + 1;
89 }
90 } else {
91 styles.push((0..*ix, font_id));
92 colors.push((0..*ix, ColorU::black()));
93 pending_highlight = Some(*ix..*ix + 1);
94 }
95 }
96 if let Some(pending_highlight) = pending_highlight.as_mut() {
97 styles.push((pending_highlight.clone(), highlight_font_id));
98 colors.push((pending_highlight.clone(), highlights.color));
99 if text_len > pending_highlight.end {
100 styles.push((pending_highlight.end..text_len, font_id));
101 colors.push((pending_highlight.end..text_len, ColorU::black()));
102 }
103 } else {
104 styles.push((0..text_len, font_id));
105 colors.push((0..text_len, ColorU::black()));
106 }
107 } else {
108 styles = vec![(0..text_len, font_id)];
109 colors = vec![(0..text_len, ColorU::black())];
110 }
111
112 self.colors = Some(colors);
113
114 let layout_line = ctx.text_layout_cache.layout_str(
115 self.text.as_str(),
116 self.font_size,
117 styles.as_slice(),
118 ctx.font_cache,
119 );
120
121 let size = vec2f(
122 layout_line
123 .width
124 .max(constraint.min.x())
125 .min(constraint.max.x()),
126 ctx.font_cache.line_height(font_id, self.font_size).ceil(),
127 );
128
129 self.layout_line = Some(layout_line);
130 self.size = Some(size);
131
132 size
133 }
134
135 fn after_layout(&mut self, _: &mut AfterLayoutContext, _: &mut MutableAppContext) {}
136
137 fn paint(&mut self, origin: Vector2F, ctx: &mut PaintContext, _: &AppContext) {
138 // ctx.canvas.set_fill_style(FillStyle::Color(ColorU::black()));
139 // self.layout_line.as_ref().unwrap().paint(
140 // origin,
141 // RectF::new(origin, self.size.unwrap()),
142 // self.colors.as_ref().unwrap(),
143 // ctx.canvas,
144 // ctx.font_cache,
145 // );
146 }
147
148 fn size(&self) -> Option<Vector2F> {
149 self.size
150 }
151
152 fn dispatch_event(&self, _: &Event, _: &mut EventContext, _: &AppContext) -> bool {
153 false
154 }
155}