1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Basic text label.
use alloc::string::String;
use rlvgl_core::draw::draw_widget_bg;
use rlvgl_core::event::Event;
use rlvgl_core::font::{FontMetrics, WidgetFont, shape_text_ltr};
use rlvgl_core::renderer::{ClipRenderer, Renderer};
use rlvgl_core::style::Style;
use rlvgl_core::widget::{Color, Rect, Widget};
/// Simple text element.
pub struct Label {
bounds: Rect,
text: String,
/// Visual style of the label background.
pub style: Style,
/// Color used to render the text.
#[deprecated(note = "use the resolved TextStyle text_color cascade when drawing labels")]
pub text_color: Color,
/// Font assignment for this label (FONT-00 §5); resolves to `FONT_6X10`
/// when unset.
font: WidgetFont,
}
impl Label {
/// Create a new label with the provided text and bounds.
#[allow(deprecated)]
pub fn new(text: impl Into<String>, bounds: Rect) -> Self {
Self {
bounds,
text: text.into(),
style: Style::default(),
text_color: Color(0, 0, 0, 255),
font: WidgetFont::new(),
}
}
/// Assign the font used to render this label (FONT-00 §5).
///
/// Pass any process-lifetime [`FontMetrics`] — e.g. a `PackedFont` for
/// anti-aliased text. With no assignment the label renders with the
/// built-in `FONT_6X10`.
pub fn set_font(&mut self, font: &'static dyn FontMetrics) {
self.font.set(font);
}
/// Resolve this label's font handle — the assigned font, or `FONT_6X10`.
///
/// Lets a containing widget (e.g. `ui::Input`/`Textarea`) draw extra text
/// with the same font this label resolves, without duplicating the slot.
pub fn resolved_font(&self) -> &'static dyn FontMetrics {
self.font.resolve()
}
/// Update the text displayed by the label.
pub fn set_text(&mut self, text: impl Into<String>) {
self.text = text.into();
}
/// Retrieve the current label text.
pub fn text(&self) -> &str {
&self.text
}
/// Update text color for this label.
///
/// Prefer migrated `TextStyle` plumbing for future callers; this method
/// is the compatibility path while upstream migration continues.
#[allow(deprecated)]
pub fn set_text_color(&mut self, color: Color) {
self.text_color = color;
}
/// Return text color blended by widget alpha.
///
/// Prefer `TextStyle` plumbing for long-lived callers; this helper keeps
/// existing widget implementations warning-free until migration completes.
#[allow(deprecated)]
pub fn text_color_with_alpha(&self, alpha: u8) -> Color {
self.text_color.with_alpha(alpha)
}
/// Draw this label using an explicit font metrics backend.
///
/// The shaped text path clips glyph coverage to the label bounds. The
/// `Widget::draw` impl calls this with the [`set_font`](Self::set_font)
/// assignment resolved via `WidgetFont` (FONT-00 §5); callers may also
/// invoke it directly with any `&dyn FontMetrics`.
#[allow(deprecated)]
pub fn draw_with_font(&self, renderer: &mut dyn Renderer, font: &dyn FontMetrics) {
draw_widget_bg(renderer, self.bounds, &self.style);
let metrics = font.line_metrics();
let baseline = self.bounds.y + metrics.ascent as i32;
let shaped = shape_text_ltr(font, &self.text, (self.bounds.x, baseline), 0);
let mut clipped = ClipRenderer::new(renderer, self.bounds);
clipped.draw_text_shaped(
&shaped,
(0, 0),
self.text_color.with_alpha(self.style.alpha),
);
}
}
impl Widget for Label {
fn bounds(&self) -> Rect {
self.bounds
}
fn widget_font_mut(&mut self) -> Option<&mut WidgetFont> {
Some(&mut self.font)
}
fn draw(&self, renderer: &mut dyn Renderer) {
self.draw_with_font(renderer, self.font.resolve());
}
fn handle_event(&mut self, _event: &Event) -> bool {
false
}
}