use std::sync::atomic::{AtomicUsize, Ordering};
use bitflags::bitflags;
use keyboard_types::{Code, CompositionEvent, Key, KeyState, Location, Modifiers};
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize};
use crate::WebViewPoint;
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct InputEventId(usize);
static INPUT_EVENT_ID: AtomicUsize = AtomicUsize::new(0);
impl InputEventId {
fn new() -> Self {
Self(INPUT_EVENT_ID.fetch_add(1, Ordering::Relaxed))
}
}
bitflags! {
#[derive(Clone, Copy, Default, Deserialize, PartialEq, Serialize)]
pub struct InputEventResult: u8 {
const DefaultPrevented = 1 << 0;
const Consumed = 1 << 1;
const DispatchFailed = 1 << 2;
}
}
#[derive(Deserialize, Serialize)]
pub struct InputEventOutcome {
pub id: InputEventId,
pub result: InputEventResult,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum InputEvent {
EditingAction(EditingActionEvent),
#[cfg(feature = "gamepad")]
Gamepad(GamepadEvent),
Ime(ImeEvent),
Keyboard(KeyboardEvent),
MouseButton(MouseButtonEvent),
MouseLeftViewport(MouseLeftViewportEvent),
MouseMove(MouseMoveEvent),
Touch(TouchEvent),
Wheel(WheelEvent),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InputEventAndId {
pub event: InputEvent,
pub id: InputEventId,
}
impl From<InputEvent> for InputEventAndId {
fn from(event: InputEvent) -> Self {
Self {
event,
id: InputEventId::new(),
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum EditingActionEvent {
Copy,
Cut,
Paste,
}
impl InputEvent {
pub fn point(&self) -> Option<WebViewPoint> {
match self {
InputEvent::EditingAction(..) => None,
#[cfg(feature = "gamepad")]
InputEvent::Gamepad(..) => None,
InputEvent::Ime(..) => None,
InputEvent::Keyboard(..) => None,
InputEvent::MouseButton(event) => Some(event.point),
InputEvent::MouseMove(event) => Some(event.point),
InputEvent::MouseLeftViewport(_) => None,
InputEvent::Touch(event) => Some(event.point),
InputEvent::Wheel(event) => Some(event.point),
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct KeyboardEvent {
pub event: ::keyboard_types::KeyboardEvent,
}
impl KeyboardEvent {
pub fn new(keyboard_event: ::keyboard_types::KeyboardEvent) -> Self {
Self {
event: keyboard_event,
}
}
pub fn new_without_event(
state: KeyState,
key: Key,
code: Code,
location: Location,
modifiers: Modifiers,
repeat: bool,
is_composing: bool,
) -> Self {
Self::new(::keyboard_types::KeyboardEvent {
state,
key,
code,
location,
modifiers,
repeat,
is_composing,
})
}
pub fn from_state_and_key(state: KeyState, key: Key) -> Self {
Self::new(::keyboard_types::KeyboardEvent {
state,
key,
..::keyboard_types::KeyboardEvent::default()
})
}
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct MouseButtonEvent {
pub action: MouseButtonAction,
pub button: MouseButton,
pub point: WebViewPoint,
}
impl MouseButtonEvent {
pub fn new(action: MouseButtonAction, button: MouseButton, point: WebViewPoint) -> Self {
Self {
action,
button,
point,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum MouseButton {
Left,
Middle,
Right,
Back,
Forward,
Other(u16),
}
impl<T: Into<u64>> From<T> for MouseButton {
fn from(value: T) -> Self {
let value = value.into();
match value {
0 => MouseButton::Left,
1 => MouseButton::Middle,
2 => MouseButton::Right,
3 => MouseButton::Back,
4 => MouseButton::Forward,
_ => MouseButton::Other(value as u16),
}
}
}
impl From<MouseButton> for i16 {
fn from(value: MouseButton) -> Self {
match value {
MouseButton::Left => 0,
MouseButton::Middle => 1,
MouseButton::Right => 2,
MouseButton::Back => 3,
MouseButton::Forward => 4,
MouseButton::Other(value) => value as i16,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum MouseButtonAction {
Down,
Up,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct MouseMoveEvent {
pub point: WebViewPoint,
#[doc(hidden)]
pub is_compatibility_event_for_touch: bool,
}
impl MouseMoveEvent {
pub fn new(point: WebViewPoint) -> Self {
Self {
point,
is_compatibility_event_for_touch: false,
}
}
#[doc(hidden)]
pub fn new_compatibility_for_touch(point: WebViewPoint) -> Self {
Self {
point,
is_compatibility_event_for_touch: true,
}
}
}
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
pub struct MouseLeftViewportEvent {
pub focus_moving_to_another_iframe: bool,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum TouchEventType {
Down,
Move,
Up,
Cancel,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct TouchId(pub i32);
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct TouchEvent {
pub event_type: TouchEventType,
pub touch_id: TouchId,
pub point: WebViewPoint,
cancelable: bool,
}
impl TouchEvent {
pub fn new(event_type: TouchEventType, touch_id: TouchId, point: WebViewPoint) -> Self {
TouchEvent {
event_type,
touch_id,
point,
cancelable: true,
}
}
#[doc(hidden)]
pub fn disable_cancelable(&mut self) {
self.cancelable = false;
}
#[doc(hidden)]
pub fn is_cancelable(&self) -> bool {
self.cancelable
}
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum WheelMode {
DeltaPixel = 0x00,
DeltaLine = 0x01,
DeltaPage = 0x02,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct WheelDelta {
pub x: f64,
pub y: f64,
pub z: f64,
pub mode: WheelMode,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct WheelEvent {
pub delta: WheelDelta,
pub point: WebViewPoint,
}
impl WheelEvent {
pub fn new(delta: WheelDelta, point: WebViewPoint) -> Self {
WheelEvent { delta, point }
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum ImeEvent {
Composition(CompositionEvent),
Dismissed,
}
#[cfg(feature = "gamepad")]
#[derive(
Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize,
)]
pub struct GamepadIndex(pub usize);
#[cfg(feature = "gamepad")]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GamepadInputBounds {
pub axis_bounds: (f64, f64),
pub button_bounds: (f64, f64),
}
#[cfg(feature = "gamepad")]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GamepadSupportedHapticEffects {
pub supports_dual_rumble: bool,
pub supports_trigger_rumble: bool,
}
#[cfg(feature = "gamepad")]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum GamepadEvent {
Connected(
GamepadIndex,
String,
GamepadInputBounds,
GamepadSupportedHapticEffects,
),
Disconnected(GamepadIndex),
Updated(GamepadIndex, GamepadUpdateType),
}
#[cfg(feature = "gamepad")]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum GamepadUpdateType {
Axis(usize, f64),
Button(usize, f64),
}