235 lines
7.7 KiB
Rust
235 lines
7.7 KiB
Rust
use galaxy_core::ui::appearance::Appearance;
|
|
use galaxyui::platform::WindowStyle;
|
|
use galaxyui::{App, TypedActionView};
|
|
|
|
use super::{Menu, MenuAction, MenuItem, MenuItemFields, SelectAction, SubMenu};
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
enum TestAction {
|
|
Root,
|
|
ChildOne,
|
|
ChildTwo,
|
|
}
|
|
|
|
fn test_submenu_items() -> Vec<MenuItem<TestAction>> {
|
|
vec![
|
|
MenuItem::Submenu {
|
|
fields: MenuItemFields::new_submenu("submenu"),
|
|
menu: SubMenu::new(vec![
|
|
MenuItemFields::new("child one")
|
|
.with_on_select_action(TestAction::ChildOne)
|
|
.into_item(),
|
|
MenuItemFields::new("child two")
|
|
.with_on_select_action(TestAction::ChildTwo)
|
|
.into_item(),
|
|
]),
|
|
},
|
|
MenuItemFields::new("root")
|
|
.with_on_select_action(TestAction::Root)
|
|
.into_item(),
|
|
]
|
|
}
|
|
|
|
#[test]
|
|
fn test_menu_item_selectable() {
|
|
assert!(MenuItemFields::<()>::new("normal").into_item().selectable());
|
|
assert!(!MenuItemFields::<()>::new("disabled")
|
|
.with_disabled(true)
|
|
.into_item()
|
|
.selectable());
|
|
assert!(!MenuItem::<()>::Separator.selectable());
|
|
}
|
|
|
|
#[test]
|
|
fn test_next_and_previous_indexes() {
|
|
App::test((), |mut app| async move {
|
|
app.add_singleton_model(|_| Appearance::mock());
|
|
|
|
let items = vec![
|
|
MenuItemFields::<()>::new("item1")
|
|
.with_disabled(true)
|
|
.into_item(),
|
|
MenuItemFields::<()>::new("item2").into_item(),
|
|
MenuItemFields::<()>::new("item3")
|
|
.with_disabled(true)
|
|
.into_item(),
|
|
MenuItemFields::<()>::new("item4").into_item(),
|
|
MenuItemFields::<()>::new("item5").into_item(),
|
|
];
|
|
|
|
let (_, menu) = app.add_window(WindowStyle::NotStealFocus, |ctx| {
|
|
let mut menu = Menu::<()>::new();
|
|
menu.set_items(items, ctx);
|
|
menu
|
|
});
|
|
|
|
menu.update(&mut app, |menu, _ctx| {
|
|
assert!(menu.selected_item().is_none());
|
|
|
|
menu.menu
|
|
.select_internal(SelectAction::Index { row: 1, item: 0 });
|
|
assert!(menu.selected_item().is_some());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"item2"
|
|
);
|
|
|
|
// Make sure we skip the disabled menu items
|
|
menu.menu.select_internal(SelectAction::Next);
|
|
assert!(menu.selected_item().is_some());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"item4"
|
|
);
|
|
|
|
menu.menu.select_internal(SelectAction::Next);
|
|
assert!(menu.selected_item().is_some());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"item5"
|
|
);
|
|
|
|
// Make sure we go around
|
|
menu.menu.select_internal(SelectAction::Next);
|
|
assert!(menu.selected_item().is_some());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"item2"
|
|
);
|
|
|
|
// Makre sure we go around with Prev action too
|
|
menu.menu.select_internal(SelectAction::Previous);
|
|
assert!(menu.selected_item().is_some());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"item5"
|
|
);
|
|
|
|
menu.menu.select_internal(SelectAction::Previous);
|
|
assert!(menu.selected_item().is_some());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"item4"
|
|
);
|
|
|
|
// Makre sure we skip the disabled ones for previous as well
|
|
menu.menu.select_internal(SelectAction::Previous);
|
|
assert!(menu.selected_item().is_some());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"item2"
|
|
);
|
|
});
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_right_opens_selected_submenu_and_selects_first_child() {
|
|
App::test((), |mut app| async move {
|
|
app.add_singleton_model(|_| Appearance::mock());
|
|
|
|
let (_, menu) = app.add_window(WindowStyle::NotStealFocus, |ctx| {
|
|
let mut menu = Menu::<TestAction>::new();
|
|
menu.set_items(test_submenu_items(), ctx);
|
|
menu
|
|
});
|
|
|
|
menu.update(&mut app, |menu, ctx| {
|
|
menu.set_selected_by_index(0, ctx);
|
|
menu.handle_action(&MenuAction::OpenSubmenu, ctx);
|
|
|
|
assert_eq!(menu.selected_index(), Some(0));
|
|
let submenu = menu.menu.selected_submenu().unwrap();
|
|
assert_eq!(submenu.selected_index(), Some(0));
|
|
assert_eq!(
|
|
submenu.selected_item().unwrap().fields().unwrap().label(),
|
|
"child one"
|
|
);
|
|
});
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_up_and_down_navigate_the_active_submenu() {
|
|
App::test((), |mut app| async move {
|
|
app.add_singleton_model(|_| Appearance::mock());
|
|
|
|
let (_, menu) = app.add_window(WindowStyle::NotStealFocus, |ctx| {
|
|
let mut menu = Menu::<TestAction>::new();
|
|
menu.set_items(test_submenu_items(), ctx);
|
|
menu
|
|
});
|
|
|
|
menu.update(&mut app, |menu, ctx| {
|
|
menu.set_selected_by_index(0, ctx);
|
|
menu.handle_action(&MenuAction::OpenSubmenu, ctx);
|
|
menu.handle_action(&MenuAction::Select(SelectAction::Next), ctx);
|
|
|
|
let submenu = menu.menu.selected_submenu().unwrap();
|
|
assert_eq!(submenu.selected_index(), Some(1));
|
|
assert_eq!(
|
|
submenu.selected_item().unwrap().fields().unwrap().label(),
|
|
"child two"
|
|
);
|
|
|
|
menu.handle_action(&MenuAction::Select(SelectAction::Previous), ctx);
|
|
|
|
let submenu = menu.menu.selected_submenu().unwrap();
|
|
assert_eq!(submenu.selected_index(), Some(0));
|
|
assert_eq!(
|
|
submenu.selected_item().unwrap().fields().unwrap().label(),
|
|
"child one"
|
|
);
|
|
});
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_enter_uses_the_active_submenu_selection() {
|
|
App::test((), |mut app| async move {
|
|
app.add_singleton_model(|_| Appearance::mock());
|
|
|
|
let (_, menu) = app.add_window(WindowStyle::NotStealFocus, |ctx| {
|
|
let mut menu = Menu::<TestAction>::new();
|
|
menu.set_items(test_submenu_items(), ctx);
|
|
menu
|
|
});
|
|
|
|
let mut selected_action = None;
|
|
menu.update(&mut app, |menu, ctx| {
|
|
menu.set_selected_by_index(0, ctx);
|
|
menu.handle_action(&MenuAction::OpenSubmenu, ctx);
|
|
menu.handle_action(&MenuAction::Select(SelectAction::Next), ctx);
|
|
|
|
selected_action = menu.menu.selected_action_for_enter(ctx);
|
|
});
|
|
|
|
assert_eq!(selected_action, Some(TestAction::ChildTwo));
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_right_is_a_noop_for_leaf_items() {
|
|
App::test((), |mut app| async move {
|
|
app.add_singleton_model(|_| Appearance::mock());
|
|
|
|
let (_, menu) = app.add_window(WindowStyle::NotStealFocus, |ctx| {
|
|
let mut menu = Menu::<TestAction>::new();
|
|
menu.set_items(test_submenu_items(), ctx);
|
|
menu
|
|
});
|
|
|
|
menu.update(&mut app, |menu, ctx| {
|
|
menu.set_selected_by_index(1, ctx);
|
|
menu.handle_action(&MenuAction::OpenSubmenu, ctx);
|
|
|
|
assert_eq!(menu.selected_index(), Some(1));
|
|
assert!(menu.menu.selected_submenu().is_none());
|
|
assert_eq!(
|
|
menu.selected_item().unwrap().fields().unwrap().label(),
|
|
"root"
|
|
);
|
|
});
|
|
})
|
|
}
|