use super::action::Action;
use super::binding::{KeyCode, Modifiers, MouseButton};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ModifiersMatch {
Exact(Modifiers),
Contains(Modifiers),
Any,
}
impl ModifiersMatch {
pub fn matches(&self, mods: Modifiers) -> bool {
match self {
ModifiersMatch::Exact(required) => mods == *required,
ModifiersMatch::Contains(required) => {
(!required.alt || mods.alt)
&& (!required.shift || mods.shift)
&& (!required.ctrl || mods.ctrl)
}
ModifiersMatch::Any => true,
}
}
}
#[derive(Debug, Clone)]
pub enum ViewportGesture {
Drag {
button: MouseButton,
modifiers: ModifiersMatch,
},
WheelY {
modifiers: ModifiersMatch,
},
WheelXY {
modifiers: ModifiersMatch,
},
KeyPress {
key: KeyCode,
modifiers: ModifiersMatch,
},
KeyHold {
key: KeyCode,
modifiers: ModifiersMatch,
},
}
#[derive(Debug, Clone)]
pub struct ViewportBinding {
pub action: Action,
pub gesture: ViewportGesture,
}
impl ViewportBinding {
pub fn new(action: Action, gesture: ViewportGesture) -> Self {
Self { action, gesture }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn exact_none_matches_no_modifiers() {
assert!(ModifiersMatch::Exact(Modifiers::NONE).matches(Modifiers::NONE));
}
#[test]
fn exact_none_rejects_alt() {
assert!(!ModifiersMatch::Exact(Modifiers::NONE).matches(Modifiers::ALT));
}
#[test]
fn exact_shift_matches_shift_only() {
assert!(ModifiersMatch::Exact(Modifiers::SHIFT).matches(Modifiers::SHIFT));
assert!(!ModifiersMatch::Exact(Modifiers::SHIFT).matches(Modifiers::NONE));
assert!(!ModifiersMatch::Exact(Modifiers::SHIFT).matches(Modifiers::CTRL_SHIFT));
}
#[test]
fn contains_shift_allows_extras() {
assert!(ModifiersMatch::Contains(Modifiers::SHIFT).matches(Modifiers::SHIFT));
assert!(ModifiersMatch::Contains(Modifiers::SHIFT).matches(Modifiers::CTRL_SHIFT));
assert!(!ModifiersMatch::Contains(Modifiers::SHIFT).matches(Modifiers::NONE));
assert!(!ModifiersMatch::Contains(Modifiers::SHIFT).matches(Modifiers::CTRL));
}
#[test]
fn contains_ctrl_shift_requires_both() {
assert!(ModifiersMatch::Contains(Modifiers::CTRL_SHIFT).matches(Modifiers::CTRL_SHIFT));
assert!(!ModifiersMatch::Contains(Modifiers::CTRL_SHIFT).matches(Modifiers::CTRL));
assert!(!ModifiersMatch::Contains(Modifiers::CTRL_SHIFT).matches(Modifiers::SHIFT));
}
#[test]
fn any_matches_everything() {
assert!(ModifiersMatch::Any.matches(Modifiers::NONE));
assert!(ModifiersMatch::Any.matches(Modifiers::ALT));
assert!(ModifiersMatch::Any.matches(Modifiers::CTRL_SHIFT));
}
}