rosace_widgets/tree/
badge.rs1use rosace_core::types::{Point, Size};
2use rosace_render::Color;
3use super::{Widget, LayoutCtx, PaintCtx};
4use super::container::draw_rounded_rect_pub;
5
6pub struct Badge {
8 pub label: String,
9 pub dot: bool,
10 pub color: Color,
11 pub text_color: Color,
12 pub font_size: Option<f32>,
16}
17
18impl Badge {
19 pub fn new(text: impl Into<String>) -> Self {
21 Self::label(text)
22 }
23
24 pub fn count(n: u32) -> Self {
25 Self::label(n.to_string())
26 }
27
28 pub fn label(text: impl Into<String>) -> Self {
29 Self {
30 label: text.into(),
31 dot: false,
32 color: Color::rgb(110, 75, 210),
33 text_color: Color::rgb(230, 232, 245),
34 font_size: None,
35 }
36 }
37
38 pub fn dot() -> Self {
39 Self { dot: true, label: String::new(), color: Color::rgb(235, 75, 75),
40 text_color: Color::rgb(255,255,255), font_size: None }
41 }
42
43 pub fn color(mut self, c: Color) -> Self { self.color = c; self }
44 pub fn text_color(mut self, c: Color) -> Self { self.text_color = c; self }
45
46 fn resolved_font_size(&self, theme: &rosace_theme::ThemeData) -> f32 {
47 self.font_size.unwrap_or(theme.typography.label_small.size)
48 }
49}
50
51impl Widget for Badge {
52 fn layout(&self, ctx: &LayoutCtx) -> Size {
53 if self.dot {
54 return Size { width: 8.0, height: 8.0 };
55 }
56 let font_size = self.resolved_font_size(ctx.theme);
57 let w = self.label.len() as f32 * font_size * 0.6 + 12.0;
58 Size { width: w.max(16.0), height: 16.0 }
59 }
60
61 fn paint(&self, ctx: &mut PaintCtx) {
62 if self.dot {
63 let cx = ctx.rect.origin.x + 4.0;
65 let cy = ctx.rect.origin.y + 4.0;
66 ctx.fill_circle(Point { x: cx, y: cy }, 4.0, self.color);
67 return;
68 }
69 ctx.semantics(super::Semantics::new(rosace_core::Role::Text).label(&self.label));
70 let font_size = self.resolved_font_size(&ctx.theme);
71 let r = ctx.rect;
72 draw_rounded_rect_pub(ctx, r, self.color, r.size.height / 2.0);
73 let text_w = ctx.font.measure_text(&self.label, font_size);
74 let tx = ((r.size.width - text_w) / 2.0).max(0.0);
75 let line_h = ctx.font.line_height(font_size);
76 let ty = ((r.size.height - line_h) / 2.0).max(0.0);
77 ctx.text(&self.label, tx, ty, self.text_color, font_size);
78 }
79}