1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
use super::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum ClientGlobalMenuAction {
Binding(crate::input::KeybindAction),
WhatsNew,
}
pub(super) fn global_menu_attention(snapshot: &ClientShellSnapshot) -> bool {
snapshot.update_available.is_some() || snapshot.integration_updates_available
}
pub(super) fn global_menu_item_has_badge(
snapshot: &ClientShellSnapshot,
action: ClientGlobalMenuAction,
) -> bool {
(action == ClientGlobalMenuAction::WhatsNew && snapshot.update_available.is_some())
|| (action == ClientGlobalMenuAction::Binding(crate::input::KeybindAction::Settings)
&& snapshot.integration_updates_available)
}
pub(super) fn global_menu_items(
snapshot: &ClientShellSnapshot,
) -> Vec<(&'static str, ClientGlobalMenuAction)> {
let mut items = vec![
(
"settings",
ClientGlobalMenuAction::Binding(crate::input::KeybindAction::Settings),
),
(
"keybinds",
ClientGlobalMenuAction::Binding(crate::input::KeybindAction::Help),
),
(
"reload config",
ClientGlobalMenuAction::Binding(crate::input::KeybindAction::ReloadConfig),
),
];
if snapshot.update_available.is_some() || snapshot.latest_release_notes_available {
items.push((
if snapshot.update_available.is_some() {
"update ready"
} else {
"what's new"
},
ClientGlobalMenuAction::WhatsNew,
));
}
items.push((
"detach",
ClientGlobalMenuAction::Binding(crate::input::KeybindAction::Detach),
));
items
}
impl ClientShellState {
pub(super) fn toggle_global_menu(&mut self) {
if matches!(self.overlay, Some(ClientShellOverlay::GlobalMenu(_))) {
self.overlay = None;
} else {
self.overlay = Some(ClientShellOverlay::GlobalMenu(ClientGlobalMenuOverlay {
highlighted: 0,
}));
}
}
pub(super) fn move_global_menu_selection(&mut self, delta: isize) {
let item_count = self
.snapshot
.as_deref()
.map(global_menu_items)
.map_or(0, |items| items.len());
let Some(ClientShellOverlay::GlobalMenu(menu)) = self.overlay.as_mut() else {
return;
};
menu.highlighted = (menu.highlighted as isize + delta)
.clamp(0, item_count.saturating_sub(1) as isize) as usize;
}
pub(super) fn activate_global_menu_item(
&mut self,
index: usize,
outcome: &mut ClientShellInput,
) {
let Some(action) = self.snapshot.as_deref().and_then(|snapshot| {
global_menu_items(snapshot)
.get(index)
.map(|(_, action)| *action)
}) else {
return;
};
if action == ClientGlobalMenuAction::WhatsNew
&& self
.snapshot
.as_deref()
.and_then(|snapshot| snapshot.release_notes.as_ref())
.is_none()
{
return;
}
self.overlay = None;
match action {
ClientGlobalMenuAction::Binding(binding) => {
self.record_binding(crate::input::KeybindMatch::Action(binding), outcome)
}
ClientGlobalMenuAction::WhatsNew => self.open_release_notes(),
}
outcome.repaint = true;
}
}
|