cadmus_core/view/
labeled_icon.rs

1use crate::context::Context;
2use crate::font::Fonts;
3use crate::framebuffer::Framebuffer;
4use crate::geom::Rectangle;
5use crate::view::icon::Icon;
6use crate::view::label::Label;
7use crate::view::{Align, Bus, Event, Hub, Id, RenderQueue, View, ID_FEEDER};
8
9pub struct LabeledIcon {
10    id: Id,
11    rect: Rectangle,
12    children: Vec<Box<dyn View>>,
13    event: Event,
14}
15
16impl LabeledIcon {
17    pub fn new(name: &str, rect: Rectangle, event: Event, text: String) -> LabeledIcon {
18        let id = ID_FEEDER.next();
19        let mut children = Vec::new();
20        let side = rect.height() as i32;
21
22        let icon = Icon::new(
23            name,
24            rect![rect.min.x, rect.min.y, rect.min.x + side, rect.max.y],
25            Event::Validate,
26        );
27        children.push(Box::new(icon) as Box<dyn View>);
28
29        let label = Label::new(
30            rect![rect.min.x + side, rect.min.y, rect.max.x, rect.max.y],
31            text,
32            Align::Left(0),
33        )
34        .event(Some(Event::Validate));
35        children.push(Box::new(label) as Box<dyn View>);
36
37        LabeledIcon {
38            id,
39            rect,
40            children,
41            event,
42        }
43    }
44
45    pub fn update(&mut self, text: &str, rq: &mut RenderQueue) {
46        if let Some(label) = self.children[1].downcast_mut::<Label>() {
47            label.update(text, rq);
48        }
49    }
50}
51
52impl View for LabeledIcon {
53    #[cfg_attr(feature = "otel", tracing::instrument(skip(self, _hub, bus, _rq, _context), fields(event = ?evt), ret(level=tracing::Level::TRACE)))]
54    fn handle_event(
55        &mut self,
56        evt: &Event,
57        _hub: &Hub,
58        bus: &mut Bus,
59        _rq: &mut RenderQueue,
60        _context: &mut Context,
61    ) -> bool {
62        match *evt {
63            Event::Validate => {
64                if let Event::Show(view_id) = self.event {
65                    bus.push_back(Event::ToggleNear(view_id, self.rect));
66                } else {
67                    bus.push_back(self.event.clone());
68                }
69                true
70            }
71            _ => false,
72        }
73    }
74
75    #[cfg_attr(feature = "otel", tracing::instrument(skip(self, _fb, _fonts, _rect), fields(rect = ?_rect)))]
76    fn render(&self, _fb: &mut dyn Framebuffer, _rect: Rectangle, _fonts: &mut Fonts) {}
77
78    fn resize(&mut self, rect: Rectangle, hub: &Hub, rq: &mut RenderQueue, context: &mut Context) {
79        let side = rect.height() as i32;
80        self.children[0].resize(
81            rect![rect.min.x, rect.min.y, rect.min.x + side, rect.max.y],
82            hub,
83            rq,
84            context,
85        );
86        self.children[1].resize(
87            rect![rect.min.x + side, rect.min.y, rect.max.x, rect.max.y],
88            hub,
89            rq,
90            context,
91        );
92        if let Event::ToggleNear(_, ref mut event_rect) = self.event {
93            *event_rect = rect;
94        }
95        self.rect = rect;
96    }
97
98    fn rect(&self) -> &Rectangle {
99        &self.rect
100    }
101
102    fn rect_mut(&mut self) -> &mut Rectangle {
103        &mut self.rect
104    }
105
106    fn children(&self) -> &Vec<Box<dyn View>> {
107        &self.children
108    }
109
110    fn children_mut(&mut self) -> &mut Vec<Box<dyn View>> {
111        &mut self.children
112    }
113
114    fn id(&self) -> Id {
115        self.id
116    }
117}