use core_graphics::geometry::CGPoint;
use gpui::{
px, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
PlatformInput, Point, ScrollDelta, ScrollWheelEvent, TouchPhase,
};
use objc::{msg_send, runtime::Object, sel, sel_impl};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(i64)]
pub enum UITouchPhase {
Began = 0,
Moved = 1,
Stationary = 2,
Ended = 3,
Cancelled = 4,
}
impl From<i64> for UITouchPhase {
fn from(value: i64) -> Self {
match value {
0 => UITouchPhase::Began,
1 => UITouchPhase::Moved,
2 => UITouchPhase::Stationary,
3 => UITouchPhase::Ended,
4 => UITouchPhase::Cancelled,
_ => UITouchPhase::Cancelled,
}
}
}
impl From<UITouchPhase> for TouchPhase {
fn from(phase: UITouchPhase) -> Self {
match phase {
UITouchPhase::Began => TouchPhase::Started,
UITouchPhase::Moved => TouchPhase::Moved,
UITouchPhase::Stationary => TouchPhase::Moved,
UITouchPhase::Ended => TouchPhase::Ended,
UITouchPhase::Cancelled => TouchPhase::Ended,
}
}
}
pub fn touch_location_in_view(touch: *mut Object, view: *mut Object) -> Point<Pixels> {
unsafe {
let location: CGPoint = msg_send![touch, locationInView: view];
Point::new(px(location.x as f32), px(location.y as f32))
}
}
pub fn touch_phase(touch: *mut Object) -> UITouchPhase {
unsafe {
let phase: i64 = msg_send![touch, phase];
UITouchPhase::from(phase)
}
}
pub fn touch_tap_count(touch: *mut Object) -> u32 {
unsafe {
let count: i64 = msg_send![touch, tapCount];
count as u32
}
}
pub fn touch_began_to_mouse_down(
position: Point<Pixels>,
tap_count: u32,
modifiers: Modifiers,
) -> PlatformInput {
PlatformInput::MouseDown(MouseDownEvent {
button: MouseButton::Left,
position,
modifiers,
click_count: tap_count as usize,
first_mouse: false,
})
}
pub fn touch_ended_to_mouse_up(
position: Point<Pixels>,
tap_count: u32,
modifiers: Modifiers,
) -> PlatformInput {
PlatformInput::MouseUp(MouseUpEvent {
button: MouseButton::Left,
position,
modifiers,
click_count: tap_count as usize,
})
}
pub fn touch_moved_to_mouse_move(
position: Point<Pixels>,
modifiers: Modifiers,
pressed_button: Option<MouseButton>,
) -> PlatformInput {
PlatformInput::MouseMove(MouseMoveEvent {
position,
modifiers,
pressed_button,
})
}
pub fn pan_gesture_to_scroll(
position: Point<Pixels>,
delta: Point<Pixels>,
modifiers: Modifiers,
touch_phase: TouchPhase,
) -> PlatformInput {
PlatformInput::ScrollWheel(ScrollWheelEvent {
position,
delta: ScrollDelta::Pixels(delta),
modifiers,
touch_phase,
})
}
pub fn get_current_modifiers() -> Modifiers {
Modifiers::default()
}
pub fn is_long_press_for_context_menu(touch: *mut Object) -> bool {
unsafe {
let force: f64 = msg_send![touch, force];
let max_force: f64 = msg_send![touch, maximumPossibleForce];
if max_force > 0.0 && force / max_force > 0.5 {
return true;
}
false
}
}
pub fn force_touch_to_right_click(position: Point<Pixels>, modifiers: Modifiers) -> PlatformInput {
PlatformInput::MouseDown(MouseDownEvent {
button: MouseButton::Right,
position,
modifiers,
click_count: 1,
first_mouse: false,
})
}