use super::types::GpmEvent;
pub fn gpm_to_crossterm(event: &GpmEvent) -> Option<crossterm::event::MouseEvent> {
use crossterm::event::{KeyModifiers, MouseButton, MouseEvent, MouseEventKind};
let mut modifiers = KeyModifiers::empty();
if event.modifiers.shift() {
modifiers |= KeyModifiers::SHIFT;
}
if event.modifiers.ctrl() {
modifiers |= KeyModifiers::CONTROL;
}
if event.modifiers.alt() {
modifiers |= KeyModifiers::ALT;
}
let button = if event.buttons.left() {
Some(MouseButton::Left)
} else if event.buttons.right() {
Some(MouseButton::Right)
} else if event.buttons.middle() {
Some(MouseButton::Middle)
} else {
None
};
let kind = if event.is_down() {
button.map(MouseEventKind::Down)?
} else if event.is_up() {
button.map(MouseEventKind::Up)?
} else if event.is_drag() {
button.map(MouseEventKind::Drag)?
} else if event.buttons.scroll_up() || event.wdy > 0 {
MouseEventKind::ScrollUp
} else if event.buttons.scroll_down() || event.wdy < 0 {
MouseEventKind::ScrollDown
} else if event.is_move() {
MouseEventKind::Moved
} else {
return None;
};
Some(MouseEvent {
kind,
column: event.x.max(0) as u16,
row: event.y.max(0) as u16,
modifiers,
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::services::gpm::types::{GpmButtons, GpmEventType, GpmModifiers};
use crossterm::event::{MouseButton, MouseEventKind};
#[test]
fn test_gpm_to_crossterm_left_click() {
let gpm_event = GpmEvent {
buttons: GpmButtons(GpmButtons::LEFT),
modifiers: GpmModifiers(0),
x: 5,
y: 10,
dx: 0,
dy: 0,
event_type: GpmEventType::Down as u32,
clicks: 1,
wdx: 0,
wdy: 0,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert!(matches!(
crossterm_event.kind,
MouseEventKind::Down(MouseButton::Left)
));
assert_eq!(crossterm_event.column, 5);
assert_eq!(crossterm_event.row, 10);
}
#[test]
fn test_gpm_to_crossterm_right_click() {
let gpm_event = GpmEvent {
buttons: GpmButtons(GpmButtons::RIGHT),
modifiers: GpmModifiers(0),
x: 3,
y: 7,
dx: 0,
dy: 0,
event_type: GpmEventType::Down as u32,
clicks: 1,
wdx: 0,
wdy: 0,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert!(matches!(
crossterm_event.kind,
MouseEventKind::Down(MouseButton::Right)
));
}
#[test]
fn test_gpm_to_crossterm_with_modifiers() {
use crossterm::event::KeyModifiers;
let gpm_event = GpmEvent {
buttons: GpmButtons(GpmButtons::LEFT),
modifiers: GpmModifiers(1 | 4), x: 0,
y: 0,
dx: 0,
dy: 0,
event_type: GpmEventType::Down as u32,
clicks: 1,
wdx: 0,
wdy: 0,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert!(crossterm_event.modifiers.contains(KeyModifiers::SHIFT));
assert!(crossterm_event.modifiers.contains(KeyModifiers::CONTROL));
assert!(!crossterm_event.modifiers.contains(KeyModifiers::ALT));
}
#[test]
fn test_gpm_to_crossterm_move() {
let gpm_event = GpmEvent {
buttons: GpmButtons(0),
modifiers: GpmModifiers(0),
x: 20,
y: 15,
dx: 1,
dy: 1,
event_type: GpmEventType::Move as u32,
clicks: 0,
wdx: 0,
wdy: 0,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert!(matches!(crossterm_event.kind, MouseEventKind::Moved));
assert_eq!(crossterm_event.column, 20);
assert_eq!(crossterm_event.row, 15);
}
#[test]
fn test_gpm_to_crossterm_drag() {
let gpm_event = GpmEvent {
buttons: GpmButtons(GpmButtons::LEFT),
modifiers: GpmModifiers(0),
x: 10,
y: 10,
dx: 2,
dy: 0,
event_type: GpmEventType::Drag as u32,
clicks: 0,
wdx: 0,
wdy: 0,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert!(matches!(
crossterm_event.kind,
MouseEventKind::Drag(MouseButton::Left)
));
}
#[test]
fn test_gpm_to_crossterm_scroll_up() {
let gpm_event = GpmEvent {
buttons: GpmButtons(GpmButtons::UP),
modifiers: GpmModifiers(0),
x: 5,
y: 5,
dx: 0,
dy: 0,
event_type: 0,
clicks: 0,
wdx: 0,
wdy: 1,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert!(matches!(crossterm_event.kind, MouseEventKind::ScrollUp));
}
#[test]
fn test_gpm_to_crossterm_scroll_down() {
let gpm_event = GpmEvent {
buttons: GpmButtons(GpmButtons::DOWN),
modifiers: GpmModifiers(0),
x: 5,
y: 5,
dx: 0,
dy: 0,
event_type: 0,
clicks: 0,
wdx: 0,
wdy: -1,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert!(matches!(crossterm_event.kind, MouseEventKind::ScrollDown));
}
#[test]
fn test_gpm_to_crossterm_negative_coords() {
let gpm_event = GpmEvent {
buttons: GpmButtons(GpmButtons::LEFT),
modifiers: GpmModifiers(0),
x: -1,
y: -5,
dx: 0,
dy: 0,
event_type: GpmEventType::Down as u32,
clicks: 1,
wdx: 0,
wdy: 0,
};
let crossterm_event = gpm_to_crossterm(&gpm_event).unwrap();
assert_eq!(crossterm_event.column, 0);
assert_eq!(crossterm_event.row, 0);
}
}