use slog;
use slog_scope;
use std::collections::HashMap;
use wlc::{Callback, Key, KeyState, Modifier, Modifiers, View};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KeyPattern {
#[serde(default = "::handlers::keyboard::default_state")]
pub state: KeyState,
pub modifiers: Modifier::Flags,
pub key: Key,
}
fn default_state() -> KeyState {
KeyState::Pressed
}
impl KeyPattern {
pub fn new(state: KeyState, modifiers: Modifier::Flags, key: Key) -> KeyPattern {
KeyPattern {
state: state,
modifiers: modifiers,
key: key,
}
}
}
pub trait KeyHandler {
fn handle_key(&mut self, time: u32, view: Option<&View>);
}
impl<F> KeyHandler for F
where F: FnMut(u32, Option<&View>)
{
fn handle_key(&mut self, time: u32, view: Option<&View>) {
self(time, view)
}
}
pub struct KeyboardHandler {
global: HashMap<KeyPattern, Box<KeyHandler>>,
logger: slog::Logger,
}
impl Default for KeyboardHandler {
fn default() -> KeyboardHandler {
KeyboardHandler::new()
}
}
impl KeyboardHandler {
pub fn new() -> KeyboardHandler {
KeyboardHandler {
global: HashMap::new(),
logger: slog_scope::logger().new(o!("instance" => "KeyboardHandler")),
}
}
pub fn register<H: KeyHandler + 'static>(&mut self, pattern: KeyPattern, handler: H) {
let contains = self.global.contains_key(&pattern);
if contains {
error!(self.logger,
"KeyPattern ({:?}) is already registered. Not registering",
pattern);
} else {
self.global.insert(pattern, Box::new(handler));
}
}
}
impl Callback for KeyboardHandler {
fn keyboard_key(&mut self, view: Option<&View>, time: u32, modifiers: Modifiers, key: Key,
state: KeyState)
-> bool {
let pattern = KeyPattern::new(state, modifiers.mods, key);
if let Some(handler) = self.global.get_mut(&pattern) {
debug!(self.logger, "Matching KeyPattern ({:?})", pattern);
handler.handle_key(time, view);
true
} else {
false
}
}
}