launcher/widgets/
nav_button.rs1use eframe::egui;
2
3pub fn nav_button(
18 ui: &mut egui::Ui,
19 icon: &str,
20 label: &str,
21 is_selected: bool,
22 has_warning: bool,
23) -> egui::Response {
24 let palette = crate::theme::palette(ui.ctx());
25 let desired_size = egui::vec2(ui.available_width(), 44.0);
26 let (rect, response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
27
28 if ui.is_rect_visible(rect) {
29 let (bg_color, icon_bg_color, text_color) = if is_selected {
30 (
31 palette.accent,
32 egui::Color32::from_white_alpha(46),
33 palette.accent_ink,
34 )
35 } else if response.hovered() {
36 (palette.chip, palette.chip, palette.chip_ink)
37 } else {
38 (egui::Color32::TRANSPARENT, palette.chip, palette.text)
39 };
40
41 ui.painter()
43 .rect_filled(rect, 22.0, bg_color);
44
45 let icon_circle_radius = 15.0;
47 let icon_circle_center = egui::pos2(rect.left() + 23.0, rect.center().y);
48 ui.painter()
49 .circle_filled(icon_circle_center, icon_circle_radius, icon_bg_color);
50
51 let icon_galley = ui.painter().layout_no_wrap(
53 icon.to_string(),
54 egui::FontId::proportional(16.0),
55 text_color,
56 );
57 let icon_pos = egui::pos2(
58 icon_circle_center.x - icon_galley.size().x / 2.0,
59 icon_circle_center.y - icon_galley.size().y / 2.0,
60 );
61 ui.painter().galley(icon_pos, icon_galley, text_color);
62
63 if has_warning {
65 let badge_radius = 4.0;
66 let badge_center = egui::pos2(
67 icon_circle_center.x + icon_circle_radius * 0.7,
68 icon_circle_center.y - icon_circle_radius * 0.7,
69 );
70 ui.painter()
71 .circle_filled(badge_center, badge_radius, palette.err);
72 }
73
74 let text_galley = ui.painter().layout_no_wrap(
76 label.to_string(),
77 egui::FontId::proportional(14.0),
78 text_color,
79 );
80 let text_pos = egui::pos2(
81 rect.left() + 50.0,
82 rect.center().y - text_galley.size().y / 2.0,
83 );
84 ui.painter().galley(text_pos, text_galley, text_color);
85
86 if response.has_focus() {
88 ui.painter().rect_stroke(
89 rect,
90 22.0,
91 egui::Stroke::new(1.0, palette.accent),
92 egui::StrokeKind::Inside,
93 );
94 }
95 }
96
97 response
98}