cadmus_core/view/reader/
results_label.rs1use crate::color::TEXT_NORMAL;
2use crate::context::Context;
3use crate::device::CURRENT_DEVICE;
4use crate::font::{font_from_style, Fonts, NORMAL_STYLE};
5use crate::framebuffer::{Framebuffer, UpdateMode};
6use crate::geom::Rectangle;
7use crate::view::{Bus, Event, Hub, Id, RenderData, RenderQueue, View, ID_FEEDER};
8
9pub struct ResultsLabel {
10 id: Id,
11 rect: Rectangle,
12 children: Vec<Box<dyn View>>,
13 count: usize,
14 completed: bool,
15}
16
17impl ResultsLabel {
18 pub fn new(rect: Rectangle, count: usize, completed: bool) -> ResultsLabel {
19 ResultsLabel {
20 id: ID_FEEDER.next(),
21 rect,
22 children: Vec::new(),
23 count,
24 completed,
25 }
26 }
27
28 pub fn update(&mut self, count: usize, rq: &mut RenderQueue) {
29 self.count = count;
30 rq.add(RenderData::new(self.id, self.rect, UpdateMode::Gui));
31 }
32
33 fn text(&self) -> String {
34 let qualifier = if self.count != 1 { "results" } else { "result" };
35
36 if self.count == 0 {
37 format!("No {}", qualifier)
38 } else {
39 format!("{} {}", self.count, qualifier)
40 }
41 }
42}
43
44impl View for ResultsLabel {
45 #[cfg_attr(feature = "otel", tracing::instrument(skip(self, _hub, _bus, rq, _context), fields(event = ?evt), ret(level=tracing::Level::TRACE)))]
46 fn handle_event(
47 &mut self,
48 evt: &Event,
49 _hub: &Hub,
50 _bus: &mut Bus,
51 rq: &mut RenderQueue,
52 _context: &mut Context,
53 ) -> bool {
54 match *evt {
55 Event::EndOfSearch => {
56 self.completed = true;
57 rq.add(RenderData::new(self.id, self.rect, UpdateMode::Gui));
58 false
59 }
60 _ => false,
61 }
62 }
63
64 #[cfg_attr(feature = "otel", tracing::instrument(skip(self, fb, fonts, _rect), fields(rect = ?_rect)))]
65 fn render(&self, fb: &mut dyn Framebuffer, _rect: Rectangle, fonts: &mut Fonts) {
66 let dpi = CURRENT_DEVICE.dpi;
67 let font = font_from_style(fonts, &NORMAL_STYLE, dpi);
68 let padding = font.em() as i32 / 2;
69 let max_width = self.rect.width().saturating_sub(2 * padding as u32) as i32;
70 let plan = font.plan(&self.text(), Some(max_width), None);
71 let dx = padding + (max_width - plan.width) / 2;
72 let dy = (self.rect.height() as i32 - font.x_heights.0 as i32) / 2;
73 let pt = pt!(self.rect.min.x + dx, self.rect.max.y - dy);
74 fb.draw_rectangle(&self.rect, TEXT_NORMAL[0]);
75 let color = if self.completed {
76 TEXT_NORMAL[1]
77 } else {
78 TEXT_NORMAL[2]
79 };
80 font.render(fb, color, &plan, pt);
81 }
82
83 fn rect(&self) -> &Rectangle {
84 &self.rect
85 }
86
87 fn rect_mut(&mut self) -> &mut Rectangle {
88 &mut self.rect
89 }
90
91 fn children(&self) -> &Vec<Box<dyn View>> {
92 &self.children
93 }
94
95 fn children_mut(&mut self) -> &mut Vec<Box<dyn View>> {
96 &mut self.children
97 }
98
99 fn id(&self) -> Id {
100 self.id
101 }
102}