Skip to main content

rosace_widgets/tree/
avatar.rs

1use rosace_core::types::{Point, Size};
2use rosace_render::Color;
3use super::{Widget, LayoutCtx, PaintCtx};
4
5/// Circular avatar with initials or a colored fill.
6pub struct Avatar {
7    pub initials: String,
8    pub color: Color,
9    pub text_color: Color,
10    pub size: f32,
11    pub font_size: f32,
12}
13
14impl Avatar {
15    pub fn new(initials: impl Into<String>) -> Self {
16        let s = initials.into();
17        Self {
18            initials: s,
19            color: Color::rgb(110, 75, 210),
20            text_color: Color::rgb(230, 232, 245),
21            size: 32.0,
22            font_size: 12.0,
23        }
24    }
25    pub fn color(mut self, c: Color) -> Self { self.color = c; self }
26    pub fn text_color(mut self, c: Color) -> Self { self.text_color = c; self }
27    pub fn size(mut self, s: f32) -> Self { self.size = s; self.font_size = s * 0.38; self }
28}
29
30impl Widget for Avatar {
31    fn layout(&self, _ctx: &LayoutCtx) -> Size {
32        Size { width: self.size, height: self.size }
33    }
34
35    fn paint(&self, ctx: &mut PaintCtx) {
36        ctx.semantics(super::Semantics::new(rosace_core::Role::Image).label(&self.initials));
37        let cx = ctx.rect.origin.x + self.size / 2.0;
38        let cy = ctx.rect.origin.y + self.size / 2.0;
39        ctx.fill_circle(Point { x: cx, y: cy }, self.size / 2.0, self.color);
40
41        // Centered initials
42        let text_w = ctx.font.measure_text(&self.initials, self.font_size);
43        let line_h = ctx.font.line_height(self.font_size);
44        ctx.text(&self.initials,
45            (self.size - text_w) / 2.0,
46            (self.size - line_h) / 2.0,
47            self.text_color, self.font_size);
48    }
49}