bexa_ui_core/widgets/
label.rs1use 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}