Skip to main content

rlvgl_widgets/
label.rs

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