1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
//! Event handling (mouse, keyboard, controller, touch screen, etc.)
//!
//! See [`Event`](enum.Event.html) for more information.

#[cfg(target_arch = "wasm32")]
compile_error!("This module should not be included when compiling to wasm");

use piston_window::{Button, ButtonArgs, ButtonState, Event as PistonEvent, Input, Motion};
pub use piston_window::{ControllerAxisArgs as ControllerAxis, ControllerButton, Key, MouseButton, TouchArgs as Touch};

use Point;

/// Possible events returned from [`Drawing::poll_event()`](../struct.Drawing.html#method.poll_event).
///
/// Events are used to make programs more interactive.
/// See that method's documentation for more information about how to use events.
///
/// This type is meant to provide a simplified model of `piston_window`'s `Event` type.
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum Event {
    /// Sent when a keyboard key is pressed
    KeyPressed(Key),
    /// Sent when a keyboard key is released
    KeyReleased(Key),
    /// Sent when a mouse button is pressed
    MouseButtonPressed(MouseButton),
    /// Sent when a mouse button is released
    MouseButtonReleased(MouseButton),
    /// Sent when a controller button is pressed
    ControllerButtonPressed(ControllerButton),
    /// Sent when a controller button is released
    ControllerButtonReleased(ControllerButton),
    /// Sent when a controller axis (usually a joystick) is changed
    ControllerAxisChange(ControllerAxis),

    /// Sent when the mouse is moving. Only sent when the mouse is over the window.
    /// `x` and `y` represent the new coordinates of where the mouse is currently.
    ///
    /// Coordinates are relative to the center of the window.
    MouseMove { x: f64, y: f64 },
    /// Sent when the mouse is scrolled. Only sent when the mouse is over the window.
    /// `x` and `y` are in scroll ticks.
    MouseScroll { x: f64, y: f64 },

    /// Sent when a user touches the screen
    Touch(Touch),

    /// Sent when the window gets resized
    WindowResized { width: u32, height: u32 },

    /// Sent when the window focus changes
    ///
    /// The boolean value is true if the window is in focus.
    WindowFocused(bool),
    /// Sent when the window gains or loses the cursor.
    ///
    /// The boolean value is true if the window gained the cursor.
    WindowCursor(bool),
    /// Sent when the window is closed
    WindowClosed,
}

/// Attempts to convert a piston Event to our event type
pub(crate) fn from_piston_event<F>(event: &PistonEvent, to_local_coords: F) -> Option<Event>
where
    F: FnOnce(Point) -> Point,
{
    use self::Event::*;

    let input_event = match *event {
        PistonEvent::Input(ref input_event) => input_event,
        _ => return None,
    };

    Some(match *input_event {
        Input::Button(ButtonArgs {
            state,
            button,
            ..
        }) => match state {
            ButtonState::Press => match button {
                Button::Keyboard(key) => KeyPressed(key),
                Button::Mouse(button) => MouseButtonPressed(button),
                Button::Controller(button) => ControllerButtonPressed(button),
            },
            ButtonState::Release => match button {
                Button::Keyboard(key) => KeyReleased(key),
                Button::Mouse(button) => MouseButtonReleased(button),
                Button::Controller(button) => ControllerButtonReleased(button),
            },
        },
        Input::Move(motion) => match motion {
            Motion::MouseCursor(x, y) => {
                let local = to_local_coords(Point { x, y });
                MouseMove { x: local.x, y: local.y }
            }
            // Ignored in favor of MouseCursor
            Motion::MouseRelative(..) => return None,
            Motion::MouseScroll(x, y) => MouseScroll { x, y },
            Motion::ControllerAxis(axis) => ControllerAxisChange(axis),
            Motion::Touch(touch) => Touch(touch),
        },
        // Ignored because this value doesn't produce text reliably for all keys
        // (especially when ctrl is pressed)
        Input::Text(_) => return None,
        Input::Resize(width, height) => WindowResized { width, height },
        Input::Focus(focused) => WindowFocused(focused),
        Input::Cursor(cursor) => WindowCursor(cursor),
        Input::Close(_) => WindowClosed,
    })
}