mimick/library/
bottom_nav.rs1use std::rc::Rc;
2
3use gtk::prelude::*;
4
5use super::LibraryWindowUi;
6
7const ITEMS: [(&str, &str, &str); 4] = [
8 ("photos", "Photos", "image-x-generic-symbolic"),
9 ("explore", "Explore", "view-grid-symbolic"),
10 ("albums", "Albums", "folder-pictures-symbolic"),
11 ("people", "People", "avatar-default-symbolic"),
12];
13
14pub(super) struct BottomNav {
15 pub root: gtk::Box,
16 pub revealer: gtk::Revealer,
17 buttons: Vec<(String, gtk::ToggleButton)>,
18}
19
20pub(super) fn build_bottom_nav() -> BottomNav {
21 let row = gtk::Box::builder()
22 .homogeneous(true)
23 .spacing(4)
24 .margin_top(4)
25 .margin_bottom(4)
26 .margin_start(8)
27 .margin_end(8)
28 .build();
29 let buttons: Vec<(String, gtk::ToggleButton)> = ITEMS
30 .iter()
31 .map(|(key, label, icon)| (key.to_string(), nav_button(label, icon)))
32 .collect();
33 for (_, button) in &buttons {
34 row.append(button);
35 }
36 let revealer = gtk::Revealer::builder()
37 .transition_type(gtk::RevealerTransitionType::SlideUp)
38 .reveal_child(true)
39 .child(&row)
40 .build();
41 let root = gtk::Box::builder()
42 .orientation(gtk::Orientation::Vertical)
43 .visible(false)
44 .css_classes(["mimick-bottom-nav"])
45 .build();
46 root.append(>k::Separator::new(gtk::Orientation::Horizontal));
47 root.append(&revealer);
48 BottomNav {
49 root,
50 revealer,
51 buttons,
52 }
53}
54
55fn nav_button(label: &str, icon: &str) -> gtk::ToggleButton {
56 let content = gtk::Box::builder()
57 .orientation(gtk::Orientation::Vertical)
58 .spacing(2)
59 .build();
60 content.append(>k::Image::from_icon_name(icon));
61 content.append(
62 >k::Label::builder()
63 .label(label)
64 .ellipsize(gtk::pango::EllipsizeMode::End)
65 .css_classes(["caption"])
66 .build(),
67 );
68 gtk::ToggleButton::builder()
69 .child(&content)
70 .tooltip_text(label)
71 .css_classes(["flat"])
72 .build()
73}
74
75pub(super) fn connect_bottom_nav(ui: &Rc<LibraryWindowUi>) {
76 ui.bulk_bar
77 .bind_property("reveal-child", &ui.bottom_nav.revealer, "reveal-child")
78 .invert_boolean()
79 .sync_create()
80 .build();
81 for (key, button) in &ui.bottom_nav.buttons {
82 let (ui, key) = (ui.clone(), key.clone());
83 button.connect_clicked(move |_| {
84 if let Some(location) = super::navigation::location_for_key(&key) {
85 super::navigation::navigate(&ui, location);
86 }
87 });
88 }
89}
90
91pub(super) fn set_button_visible(nav: &BottomNav, key: &str, visible: bool) {
92 for (button_key, button) in &nav.buttons {
93 if button_key == key {
94 button.set_visible(visible);
95 }
96 }
97}
98
99pub(super) fn sync(nav: &BottomNav, active_key: &str) {
100 for (key, button) in &nav.buttons {
101 button.set_active(key == active_key);
102 }
103}