pittore 0.2.4

Simple toolkit for 2D visualization based on wgpu.
Documentation
use glam::{dvec2, DVec2, Vec2};
use rustc_hash::FxHashSet;
use winit::{
    event::{MouseButton, MouseScrollDelta, WindowEvent},
    keyboard::{KeyCode, PhysicalKey},
};

#[derive(Default)]
pub struct InputState {
    pub event_buffers: Vec<WindowEvent>,

    pub pressed_keys: FxHashSet<KeyCode>,
    pub just_pressed_keys: FxHashSet<KeyCode>,
    pub just_released_keys: FxHashSet<KeyCode>,

    pub cursor_position: Option<DVec2>,
    pub cursor_position_on_click: Option<DVec2>,
    pub pressed_mouse_buttons: FxHashSet<MouseButton>,
    pub clicked_mouse_buttons: FxHashSet<MouseButton>,
    pub mouse_wheel_delta: Option<Vec2>,
    pub mouse_drag_delta: Option<DVec2>,
}

impl InputState {
    pub fn push_event(&mut self, event: WindowEvent) {
        self.event_buffers.push(event);
    }

    pub fn update(&mut self) {
        self.just_pressed_keys.clear();
        self.just_released_keys.clear();
        self.clicked_mouse_buttons.clear();
        self.mouse_wheel_delta = None;
        self.mouse_drag_delta = None;

        for event in &self.event_buffers {
            match event {
                WindowEvent::KeyboardInput { event, .. } => {
                    if !event.repeat {
                        if let PhysicalKey::Code(keycode) = event.physical_key {
                            if event.state.is_pressed() {
                                self.pressed_keys.insert(keycode);
                                self.just_pressed_keys.insert(keycode);
                            } else {
                                self.pressed_keys.remove(&keycode);
                                self.just_released_keys.insert(keycode);
                            }
                        }
                    }
                }
                WindowEvent::CursorMoved { position, .. } => {
                    let previous_position = self.cursor_position;
                    let current_position = dvec2(position.x, position.y);

                    self.cursor_position = Some(current_position);
                    if let Some(previous_position) = previous_position {
                        if !self.pressed_mouse_buttons.is_empty() {
                            self.mouse_drag_delta = Some(current_position - previous_position);
                        }
                    }
                }
                WindowEvent::CursorLeft { .. } => {
                    self.cursor_position = None;
                }
                WindowEvent::MouseInput { state, button, .. } => {
                    if state.is_pressed() {
                        self.pressed_mouse_buttons.insert(*button);
                        self.cursor_position_on_click = self.cursor_position;
                    } else {
                        self.pressed_mouse_buttons.remove(button);
                        if self.cursor_position == self.cursor_position_on_click {
                            self.clicked_mouse_buttons.insert(*button);
                        }
                        self.cursor_position_on_click = None;
                    }
                }
                WindowEvent::MouseWheel { delta, .. } => match delta {
                    MouseScrollDelta::LineDelta(horizontal, vertical) => {
                        *self.mouse_wheel_delta.get_or_insert(Vec2::ZERO) +=
                            Vec2::new(*horizontal, *vertical);
                    }
                    _ => {}
                },
                _ => {}
            }
        }

        self.event_buffers.clear();
    }
}