cadmus_core/view/home/
address_bar.rs

1use crate::color::{SEPARATOR_NORMAL, TEXT_BUMP_SMALL};
2use crate::context::Context;
3use crate::device::CURRENT_DEVICE;
4use crate::font::Fonts;
5use crate::framebuffer::Framebuffer;
6use crate::geom::Rectangle;
7use crate::gesture::GestureEvent;
8use crate::input::DeviceEvent;
9use crate::unit::scale_by_dpi;
10use crate::view::filler::Filler;
11use crate::view::icon::Icon;
12use crate::view::input_field::InputField;
13use crate::view::{Bus, Event, Hub, Id, RenderQueue, View, ViewId, ID_FEEDER, THICKNESS_MEDIUM};
14
15pub struct AddressBar {
16    id: Id,
17    pub rect: Rectangle,
18    children: Vec<Box<dyn View>>,
19}
20
21impl AddressBar {
22    pub fn new<S: AsRef<str>>(rect: Rectangle, text: S, context: &mut Context) -> AddressBar {
23        let id = ID_FEEDER.next();
24        let mut children = Vec::new();
25        let dpi = CURRENT_DEVICE.dpi;
26        let thickness = scale_by_dpi(THICKNESS_MEDIUM, dpi) as i32;
27        let side = rect.height() as i32;
28
29        let home_rect = rect![rect.min, rect.min + side];
30        let home_icon = Icon::new(
31            "home",
32            home_rect,
33            Event::SelectDirectory(context.library.home.clone()),
34        )
35        .background(TEXT_BUMP_SMALL[0]);
36
37        children.push(Box::new(home_icon) as Box<dyn View>);
38
39        let separator = Filler::new(
40            rect![
41                pt!(rect.min.x + side, rect.min.y),
42                pt!(rect.min.x + side + thickness, rect.max.y)
43            ],
44            SEPARATOR_NORMAL,
45        );
46
47        children.push(Box::new(separator) as Box<dyn View>);
48
49        let input_field = InputField::new(
50            rect![
51                pt!(rect.min.x + side + thickness, rect.min.y),
52                pt!(rect.max.x - side - thickness, rect.max.y)
53            ],
54            ViewId::AddressBarInput,
55        )
56        .border(false)
57        .text(text.as_ref(), context);
58
59        children.push(Box::new(input_field) as Box<dyn View>);
60
61        let separator = Filler::new(
62            rect![
63                pt!(rect.max.x - side - thickness, rect.min.y),
64                pt!(rect.max.x - side, rect.max.y)
65            ],
66            SEPARATOR_NORMAL,
67        );
68
69        children.push(Box::new(separator) as Box<dyn View>);
70
71        let close_icon = Icon::new(
72            "close",
73            rect![
74                pt!(rect.max.x - side, rect.min.y),
75                pt!(rect.max.x, rect.max.y)
76            ],
77            Event::Close(ViewId::AddressBar),
78        )
79        .background(TEXT_BUMP_SMALL[0]);
80
81        children.push(Box::new(close_icon) as Box<dyn View>);
82
83        AddressBar { id, rect, children }
84    }
85
86    pub fn set_text<S: AsRef<str>>(
87        &mut self,
88        text: S,
89        rq: &mut RenderQueue,
90        context: &mut Context,
91    ) {
92        if let Some(input_field) = self.children[2].downcast_mut::<InputField>() {
93            input_field.set_text(text.as_ref(), true, rq, context);
94        }
95    }
96}
97
98impl View for AddressBar {
99    #[cfg_attr(feature = "otel", tracing::instrument(skip(self, _hub, _bus, _rq, _context), fields(event = ?evt), ret(level=tracing::Level::TRACE)))]
100    fn handle_event(
101        &mut self,
102        evt: &Event,
103        _hub: &Hub,
104        _bus: &mut Bus,
105        _rq: &mut RenderQueue,
106        _context: &mut Context,
107    ) -> bool {
108        match *evt {
109            Event::Gesture(GestureEvent::Tap(center))
110            | Event::Gesture(GestureEvent::HoldFingerShort(center, ..))
111                if self.rect.includes(center) =>
112            {
113                true
114            }
115            Event::Gesture(GestureEvent::Swipe { start, .. }) if self.rect.includes(start) => true,
116            Event::Device(DeviceEvent::Finger { position, .. }) if self.rect.includes(position) => {
117                true
118            }
119            _ => false,
120        }
121    }
122
123    #[cfg_attr(feature = "otel", tracing::instrument(skip(self, _fb, _fonts, _rect), fields(rect = ?_rect)))]
124    fn render(&self, _fb: &mut dyn Framebuffer, _rect: Rectangle, _fonts: &mut Fonts) {}
125
126    fn resize(&mut self, rect: Rectangle, hub: &Hub, rq: &mut RenderQueue, context: &mut Context) {
127        let dpi = CURRENT_DEVICE.dpi;
128        let thickness = scale_by_dpi(THICKNESS_MEDIUM, dpi) as i32;
129        let side = rect.height() as i32;
130        self.children[0].resize(rect![rect.min, rect.min + side], hub, rq, context);
131        self.children[1].resize(
132            rect![
133                pt!(rect.min.x + side, rect.min.y),
134                pt!(rect.min.x + side + thickness, rect.max.y)
135            ],
136            hub,
137            rq,
138            context,
139        );
140        self.children[2].resize(
141            rect![
142                pt!(rect.min.x + side + thickness, rect.min.y),
143                pt!(rect.max.x - side - thickness, rect.max.y)
144            ],
145            hub,
146            rq,
147            context,
148        );
149        self.children[3].resize(
150            rect![
151                pt!(rect.max.x - side - thickness, rect.min.y),
152                pt!(rect.max.x - side, rect.max.y)
153            ],
154            hub,
155            rq,
156            context,
157        );
158        self.children[4].resize(
159            rect![
160                pt!(rect.max.x - side, rect.min.y),
161                pt!(rect.max.x, rect.max.y)
162            ],
163            hub,
164            rq,
165            context,
166        );
167        self.rect = rect;
168    }
169
170    fn rect(&self) -> &Rectangle {
171        &self.rect
172    }
173
174    fn rect_mut(&mut self) -> &mut Rectangle {
175        &mut self.rect
176    }
177
178    fn children(&self) -> &Vec<Box<dyn View>> {
179        &self.children
180    }
181
182    fn children_mut(&mut self) -> &mut Vec<Box<dyn View>> {
183        &mut self.children
184    }
185
186    fn id(&self) -> Id {
187        self.id
188    }
189}