use super::{Menu, MenuBar, MenuItem};
impl MenuBar {
pub fn has_open_menu(&self) -> bool {
self.opened_menu.is_some()
}
pub fn opened_menu(&self) -> Option<&Menu> {
self.opened_menu.and_then(|index| self.menus.get(index))
}
pub fn opened_menu_mut(&mut self) -> Option<&mut Menu> {
self.opened_menu.and_then(|index| self.menus.get_mut(index))
}
pub fn open_menu(&mut self, index: usize) {
if index < self.menus.len() {
if let Some(current_index) = self.opened_menu {
if let Some(menu) = self.menus.get_mut(current_index) {
menu.focused_item = None;
menu.close_all_submenus();
}
}
self.opened_menu = Some(index);
if let Some(menu) = self.menus.get_mut(index) {
menu.focused_item = None; }
}
}
pub fn close_menu(&mut self) {
if let Some(index) = self.opened_menu {
if let Some(menu) = self.menus.get_mut(index) {
menu.focused_item = None;
menu.close_all_submenus();
}
}
self.opened_menu = None;
}
pub fn open_next_menu(&mut self) {
if self.menus.is_empty() {
return;
}
let next_index = if let Some(current) = self.opened_menu {
(current + 1) % self.menus.len()
} else {
0
};
self.open_menu(next_index);
}
pub fn open_previous_menu(&mut self) {
if self.menus.is_empty() {
return;
}
let prev_index = if let Some(current) = self.opened_menu {
if current == 0 {
self.menus.len() - 1
} else {
current - 1
}
} else {
self.menus.len() - 1
};
self.open_menu(prev_index);
}
}
impl Menu {
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled = enabled;
}
pub fn focus_next_item(&mut self) {
let next = if let Some(current) = self.focused_item {
self.find_next_selectable_item(current)
} else {
self.find_first_selectable_item()
};
self.focused_item = next;
}
pub fn focus_previous_item(&mut self) {
let previous = if let Some(current) = self.focused_item {
self.find_previous_selectable_item(current)
} else {
self.find_last_selectable_item()
};
self.focused_item = previous;
}
pub fn get_focused_item(&self) -> Option<&MenuItem> {
self.focused_item.and_then(|index| self.items.get(index))
}
pub fn close_all_submenus(&mut self) {
for item in &mut self.items {
if let MenuItem::SubMenu(submenu) = item {
submenu.is_open = false;
submenu.focused_item = None;
Self::close_submenus_recursive(&mut submenu.items);
}
}
}
fn close_submenus_recursive(items: &mut [MenuItem]) {
for item in items {
if let MenuItem::SubMenu(submenu) = item {
submenu.is_open = false;
submenu.focused_item = None;
Self::close_submenus_recursive(&mut submenu.items);
}
}
}
pub fn find_first_selectable_item(&self) -> Option<usize> {
self.items
.iter()
.position(|item| matches!(item, MenuItem::Action(_) | MenuItem::SubMenu(_)))
}
pub fn find_last_selectable_item(&self) -> Option<usize> {
self.items
.iter()
.rposition(|item| matches!(item, MenuItem::Action(_) | MenuItem::SubMenu(_)))
}
pub fn find_next_selectable_item(&self, current: usize) -> Option<usize> {
self.items
.iter()
.skip(current + 1)
.position(|item| matches!(item, MenuItem::Action(_) | MenuItem::SubMenu(_)))
.map(|pos| pos + current + 1)
.or_else(|| self.find_first_selectable_item())
}
pub fn find_previous_selectable_item(&self, current: usize) -> Option<usize> {
self.items
.iter()
.take(current)
.rposition(|item| matches!(item, MenuItem::Action(_) | MenuItem::SubMenu(_)))
.or_else(|| self.find_last_selectable_item())
}
}