use evdev::{ Device, KeyCode, EventSummary };
pub struct Joystick {
device: Device,
x: usize,
y: usize,
mode: MovementMode,
}
pub enum MovementMode {
Wrap, Clamp, }
pub enum JoystickEvent {
Move,
Enter, }
impl Joystick {
pub fn open(dev_path: &str, mode: MovementMode) -> Option<Self> {
Device::open(dev_path).ok().map(|dev| Self { device: dev, x: 0, y: 0, mode })
}
pub fn position(&self) -> (usize, usize) {
(self.x, self.y)
}
pub fn run<F>(&mut self, mut callback: F)
where
F: FnMut(usize, usize, JoystickEvent), {
loop {
for ev in self.device.fetch_events().unwrap() {
match ev.destructure() {
EventSummary::Key(_, keycode, value) => {
if value == 1 {
let mut moved: bool = false;
let mut event = None;
match keycode {
KeyCode::KEY_DOWN => {
match self.mode {
MovementMode::Wrap => { self.y = if self.y < 7 { self.y + 1 } else { 0 }; }
MovementMode::Clamp => { if self.y < 7 { self.y += 1; } }
}
moved = true;
}
KeyCode::KEY_UP => {
match self.mode {
MovementMode::Wrap => { self.y = if self.y > 0 { self.y - 1 } else { 7 }; }
MovementMode::Clamp => { if self.y > 0 { self.y -= 1; } }
}
moved = true;
}
KeyCode::KEY_RIGHT => {
match self.mode {
MovementMode::Wrap => { self.x = if self.x < 7 { self.x + 1 } else { 0 }; }
MovementMode::Clamp => { if self.x < 7 { self.x += 1; } }
}
moved = true;
}
KeyCode::KEY_LEFT => {
match self.mode {
MovementMode::Wrap => { self.x = if self.x > 0 { self.x - 1} else { 7 }; }
MovementMode::Clamp => { if self.x > 0 { self.x -= 1; } }
}
moved = true;
}
KeyCode::KEY_ENTER => {
event = Some(JoystickEvent::Enter);
}
_ => {}
}
if moved {
callback(self.x, self.y, JoystickEvent::Move);
} else if let Some(evt) = event {
callback(self.x, self.y, evt);
}
}
}
_ => {}
}
}
}
}
}