use iced::keyboard::{Key, Modifiers, key::Named};
use snora_core::focus::Cycle;
pub fn dismiss_on_escape<Message: Clone>(
has_modal: bool,
has_menu: bool,
on_close_modals: Option<Message>,
on_close_menus: Option<Message>,
key: Key,
) -> Option<Message> {
if key != Key::Named(Named::Escape) {
return None;
}
if has_modal {
return on_close_modals;
}
if has_menu {
return on_close_menus;
}
None
}
#[must_use]
pub fn cycle_zones(key: Key, modifiers: Modifiers) -> Option<Cycle> {
if key != Key::Named(Named::F6) {
return None;
}
if modifiers.shift() {
Some(Cycle::Backward)
} else {
Some(Cycle::Forward)
}
}
#[cfg(test)]
mod tests {
use super::*;
const ESC: Key = Key::Named(Named::Escape);
const ENTER: Key = Key::Named(Named::Enter);
#[test]
fn non_escape_key_returns_none() {
assert_eq!(
dismiss_on_escape(true, true, Some("close_modal"), Some("close_menu"), ENTER),
None,
);
}
#[test]
fn no_overlay_returns_none() {
assert_eq!(
dismiss_on_escape(false, false, Some("modal"), Some("menu"), ESC),
None,
);
}
#[test]
fn menu_only_returns_close_menus() {
assert_eq!(
dismiss_on_escape(false, true, Some("modal"), Some("menu"), ESC),
Some("menu"),
);
}
#[test]
fn modal_only_returns_close_modals() {
assert_eq!(
dismiss_on_escape(true, false, Some("modal"), Some("menu"), ESC),
Some("modal"),
);
}
#[test]
fn both_open_modal_takes_priority() {
assert_eq!(
dismiss_on_escape(true, true, Some("modal"), Some("menu"), ESC),
Some("modal"),
);
}
#[test]
fn modal_open_but_no_sink_returns_none() {
assert_eq!(
dismiss_on_escape(true, false, None::<&str>, Some("menu"), ESC),
None,
);
}
#[test]
fn menu_open_but_no_sink_returns_none() {
assert_eq!(
dismiss_on_escape(false, true, Some("modal"), None::<&str>, ESC),
None,
);
}
const F6: Key = Key::Named(Named::F6);
#[test]
fn f6_without_shift_cycles_forward() {
assert_eq!(cycle_zones(F6, Modifiers::empty()), Some(Cycle::Forward));
}
#[test]
fn shift_f6_cycles_backward() {
assert_eq!(cycle_zones(F6, Modifiers::SHIFT), Some(Cycle::Backward));
}
#[test]
fn non_f6_key_returns_none_even_with_shift() {
assert_eq!(cycle_zones(ESC, Modifiers::SHIFT), None);
assert_eq!(cycle_zones(ENTER, Modifiers::empty()), None);
}
#[test]
fn other_modifiers_alongside_f6_do_not_change_direction() {
assert_eq!(cycle_zones(F6, Modifiers::CTRL), Some(Cycle::Forward));
assert_eq!(
cycle_zones(F6, Modifiers::CTRL | Modifiers::SHIFT),
Some(Cycle::Backward)
);
}
}