Skip to main content

bexa_ui_core/widgets/
label.rs

1use glyphon::Metrics;
2use glyphon::cosmic_text::Align;
3use taffy::prelude::*;
4
5use crate::framework::{DrawContext, Widget};
6use crate::signal::{Signal, IntoSignal};
7
8pub struct Label {
9    text: Signal<String>,
10    metrics: Metrics,
11    color: [u8; 3],
12    align: Align,
13    padding: f32,
14    font_family: Option<String>,
15}
16
17impl Label {
18    pub fn new(text: impl IntoSignal<String>, metrics: Metrics, color: [u8; 3]) -> Self {
19        Self {
20            text: text.into_signal(),
21            metrics,
22            color,
23            align: Align::Left,
24            padding: 4.0,
25            font_family: None,
26        }
27    }
28
29    pub fn with_align(mut self, align: Align) -> Self {
30        self.align = align;
31        self
32    }
33
34    pub fn with_padding(mut self, padding: f32) -> Self {
35        self.padding = padding;
36        self
37    }
38
39    pub fn with_font_family(mut self, family: &str) -> Self {
40        self.font_family = Some(family.to_string());
41        self
42    }
43}
44
45impl Widget for Label {
46    fn style(&self) -> Style {
47        let height = self.metrics.line_height + self.padding * 2.0;
48        Style {
49            size: Size {
50                width: Dimension::Percent(1.0),
51                height: Dimension::Length(height),
52            },
53            ..Default::default()
54        }
55    }
56
57    fn draw(&self, ctx: &mut DrawContext) {
58        let layout = ctx.layout;
59        let left = layout.location.x + self.padding;
60        let top = layout.location.y + self.padding;
61        let bounds = (layout.size.width - self.padding * 2.0, layout.size.height - self.padding * 2.0);
62        self.text.with(|text| {
63            if let Some(ref family) = self.font_family {
64                ctx.renderer.draw_text_with_font(
65                    text,
66                    (left, top),
67                    self.color,
68                    bounds,
69                    self.metrics,
70                    self.align,
71                    family,
72                );
73            } else {
74                ctx.renderer.draw_text(
75                    text,
76                    (left, top),
77                    self.color,
78                    bounds,
79                    self.metrics,
80                    self.align,
81                );
82            }
83        });
84    }
85}