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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use crate::event::{Event, Key, Modifiers};

use crate::EventLoop;
use winit::event::{DeviceEvent, ElementState, KeyboardInput, MouseButton, MouseScrollDelta, WindowEvent};
use winit::event_loop::{EventLoopClosed, EventLoopProxy};

/// Converts a winit event to a pixel-widgets event, if such a conversion is available.
/// Requires the "winit" feature.
pub fn convert_event<T>(ev: winit::event::Event<T>) -> Option<Event> {
    match ev {
        winit::event::Event::WindowEvent { event, .. } => match event {
            WindowEvent::Resized(size) => Some(Event::Resize(size.width as f32, size.height as f32)),
            WindowEvent::CloseRequested => Some(Event::Exit),
            WindowEvent::Focused(f) => Some(Event::Focus(f)),
            WindowEvent::ReceivedCharacter(c) => Some(Event::Text(c)),
            WindowEvent::KeyboardInput { input, .. } => match input {
                KeyboardInput {
                    state: ElementState::Pressed,
                    virtual_keycode: Some(key),
                    ..
                } => convert_key(key).map(|key| Event::Press(key)),
                KeyboardInput {
                    state: ElementState::Released,
                    virtual_keycode: Some(key),
                    ..
                } => convert_key(key).map(|key| Event::Release(key)),
                _ => None,
            },
            WindowEvent::ModifiersChanged(modifiers) => Some(Event::Modifiers(convert_mods(modifiers))),
            WindowEvent::MouseInput {
                state: ElementState::Pressed,
                button,
                ..
            } => match button {
                MouseButton::Left => Some(Event::Press(Key::LeftMouseButton)),
                MouseButton::Right => Some(Event::Press(Key::RightMouseButton)),
                MouseButton::Middle => Some(Event::Press(Key::MiddleMouseButton)),
                MouseButton::Other(_) => None,
            },
            WindowEvent::MouseInput {
                state: ElementState::Released,
                button,
                ..
            } => match button {
                MouseButton::Left => Some(Event::Release(Key::LeftMouseButton)),
                MouseButton::Right => Some(Event::Release(Key::RightMouseButton)),
                MouseButton::Middle => Some(Event::Release(Key::MiddleMouseButton)),
                MouseButton::Other(_) => None,
            },
            WindowEvent::CursorMoved { position, .. } => Some(Event::Cursor(position.x as f32, position.y as f32)),
            WindowEvent::MouseWheel { delta, .. } => match delta {
                MouseScrollDelta::LineDelta(dx, dy) => Some(Event::Scroll(dx * 20.0, dy * 20.0)),

                MouseScrollDelta::PixelDelta(delta) => Some(Event::Scroll(delta.x as f32, delta.y as f32)),
            },
            _ => None,
        },
        winit::event::Event::DeviceEvent { event, .. } => match event {
            DeviceEvent::MouseMotion { delta: (x, y) } => Some(Event::Motion(x as f32, y as f32)),
            _ => None,
        },
        _ => None,
    }
}

fn convert_mods(x: winit::event::ModifiersState) -> Modifiers {
    Modifiers {
        ctrl: x.ctrl(),
        alt: x.alt(),
        shift: x.shift(),
        logo: x.logo(),
    }
}

fn convert_key(key: winit::event::VirtualKeyCode) -> Option<Key> {
    use winit::event::VirtualKeyCode as Vk;

    match key {
        Vk::Key1 => Some(Key::Key1),
        Vk::Key2 => Some(Key::Key2),
        Vk::Key3 => Some(Key::Key3),
        Vk::Key4 => Some(Key::Key4),
        Vk::Key5 => Some(Key::Key5),
        Vk::Key6 => Some(Key::Key6),
        Vk::Key7 => Some(Key::Key7),
        Vk::Key8 => Some(Key::Key8),
        Vk::Key9 => Some(Key::Key9),
        Vk::Key0 => Some(Key::Key0),
        Vk::A => Some(Key::A),
        Vk::B => Some(Key::B),
        Vk::C => Some(Key::C),
        Vk::D => Some(Key::D),
        Vk::E => Some(Key::E),
        Vk::F => Some(Key::F),
        Vk::G => Some(Key::G),
        Vk::H => Some(Key::H),
        Vk::I => Some(Key::I),
        Vk::J => Some(Key::J),
        Vk::K => Some(Key::K),
        Vk::L => Some(Key::L),
        Vk::M => Some(Key::M),
        Vk::N => Some(Key::N),
        Vk::O => Some(Key::O),
        Vk::P => Some(Key::P),
        Vk::Q => Some(Key::Q),
        Vk::R => Some(Key::R),
        Vk::S => Some(Key::S),
        Vk::T => Some(Key::T),
        Vk::U => Some(Key::U),
        Vk::V => Some(Key::V),
        Vk::W => Some(Key::W),
        Vk::X => Some(Key::X),
        Vk::Y => Some(Key::Y),
        Vk::Z => Some(Key::Z),
        Vk::Tab => Some(Key::Tab),
        Vk::LShift => Some(Key::Shift),
        Vk::LControl => Some(Key::Ctrl),
        Vk::LAlt => Some(Key::Alt),
        Vk::Space => Some(Key::Space),
        Vk::Return => Some(Key::Enter),
        Vk::Back => Some(Key::Backspace),
        Vk::Escape => Some(Key::Escape),
        Vk::Left => Some(Key::Left),
        Vk::Right => Some(Key::Right),
        Vk::Up => Some(Key::Up),
        Vk::Down => Some(Key::Down),
        Vk::Home => Some(Key::Home),
        Vk::End => Some(Key::End),
        _ => None,
    }
}

impl<T: Send> EventLoop<T> for EventLoopProxy<T> {
    type Error = EventLoopClosed<T>;

    fn send_event(&self, event: T) -> Result<(), Self::Error> {
        EventLoopProxy::<T>::send_event(self, event)
    }
}