use ustreamer_proto::input::InputEvent;
#[derive(Debug, Clone)]
pub enum AppAction {
Rotate { dx: f32, dy: f32 },
Zoom { delta: f32 },
Pan { dx: f32, dy: f32 },
ScrollStep { delta: i32 },
DragAdjust { dx: f32, dy: f32 },
PointerUpdate { x: f32, y: f32 },
}
pub struct InputMapper {
mode: InteractionMode,
last_x: f32,
last_y: f32,
buttons: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InteractionMode {
Rotate,
Pan,
Zoom,
Scroll,
DragAdjust,
}
impl Default for InputMapper {
fn default() -> Self {
Self {
mode: InteractionMode::Rotate,
last_x: 0.0,
last_y: 0.0,
buttons: 0,
}
}
}
impl InputMapper {
pub fn set_mode(&mut self, mode: InteractionMode) {
self.mode = mode;
}
pub fn process(&mut self, event: &InputEvent) -> Vec<AppAction> {
match event {
InputEvent::PointerMove { x, y, buttons, .. } => {
let dx = x - self.last_x;
let dy = y - self.last_y;
self.last_x = *x;
self.last_y = *y;
self.buttons = *buttons;
let mut actions = vec![AppAction::PointerUpdate { x: *x, y: *y }];
if *buttons & 1 != 0 {
match self.mode {
InteractionMode::Rotate => {
actions.push(AppAction::Rotate { dx, dy });
}
InteractionMode::Pan => {
actions.push(AppAction::Pan { dx, dy });
}
InteractionMode::Zoom => {
actions.push(AppAction::Zoom { delta: dy });
}
InteractionMode::DragAdjust => {
actions.push(AppAction::DragAdjust { dx, dy });
}
InteractionMode::Scroll => {}
}
}
actions
}
InputEvent::Scroll { delta_y, .. } => {
vec![AppAction::ScrollStep {
delta: if *delta_y > 0.0 { 1 } else { -1 },
}]
}
InputEvent::PointerDown { x, y, .. } => {
self.last_x = *x;
self.last_y = *y;
vec![]
}
_ => vec![],
}
}
}