diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index eb4bf1a951..4102a718fe 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -27,7 +27,7 @@ use crate::{ scene::camera::Camera, settings::{ControlSettings, Settings}, ui::{Ingame, Ingameable, ScaleMode, Ui}, - window::{Event as WinEvent, Key, Window}, + window::{Event as WinEvent, GameInput, Window}, GlobalState, }; use client::Client; @@ -624,20 +624,10 @@ impl Hud { } true } - WinEvent::KeyDown(Key::ToggleInterface) => { - self.show.toggle_ui(); - true - } - WinEvent::KeyDown(Key::ToggleCursor) => { - self.force_ungrab = !self.force_ungrab; - if self.force_ungrab { - global_state.window.grab_cursor(false); - } - true - } _ if !self.show.ui => false, WinEvent::Zoom(_) => !cursor_grabbed && !self.ui.no_widget_capturing_mouse(), - WinEvent::KeyDown(Key::Enter) => { + + WinEvent::InputUpdate(GameInput::Enter, true) => { self.ui.focus_widget(if self.typing() { None } else { @@ -645,7 +635,7 @@ impl Hud { }); true } - WinEvent::KeyDown(Key::Escape) => { + WinEvent::InputUpdate(GameInput::Escape, true) => { if self.typing() { self.ui.focus_widget(None); } else { @@ -654,40 +644,53 @@ impl Hud { } true } - WinEvent::KeyDown(key) if !self.typing() => match key { - Key::Map => { + + // Press key while not typing + WinEvent::InputUpdate(key, true) if !self.typing() => match key { + GameInput::ToggleInterface => { + self.show.toggle_ui(); + true + } + GameInput::ToggleCursor => { + self.force_ungrab = !self.force_ungrab; + if self.force_ungrab { + global_state.window.grab_cursor(false); + } + true + } + GameInput::Map => { self.show.toggle_map(); true } - Key::Bag => { + GameInput::Bag => { self.show.toggle_bag(); true } - Key::QuestLog => { + GameInput::QuestLog => { self.show.toggle_small(SmallWindowType::QuestLog); true } - Key::CharacterWindow => { + GameInput::CharacterWindow => { self.show.toggle_char_window(); true } - Key::Social => { + GameInput::Social => { self.show.toggle_small(SmallWindowType::Social); true } - Key::Spellbook => { + GameInput::Spellbook => { self.show.toggle_small(SmallWindowType::Spellbook); true } - Key::Settings => { + GameInput::Settings => { self.show.toggle_settings(); true } - Key::Help => { + GameInput::Help => { self.show.toggle_help(); true } - Key::ToggleDebug => { + GameInput::ToggleDebug => { self.show.debug = !self.show.debug; true } @@ -697,11 +700,10 @@ impl Hud { } _ => false, }, - WinEvent::KeyDown(key) | WinEvent::KeyUp(key) => match key { - Key::ToggleCursor => false, - _ => self.typing(), - }, + // Else the player is typing in chat + WinEvent::InputUpdate(key, _) => self.typing(), WinEvent::Char(_) => self.typing(), + _ => false, }; // Handle cursor grab. diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 9995625a26..dbaa93db75 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -4,7 +4,7 @@ use crate::{ render::Renderer, scene::Scene, settings::Settings, - window::{Event, Key, Window}, + window::{Event, GameInput, Window}, Direction, Error, GlobalState, PlayState, PlayStateResult, }; use client::{self, Client}; @@ -136,32 +136,23 @@ impl PlayState for SessionState { return PlayStateResult::Shutdown; } // Attack key pressed - Event::Click(MouseButton::Left, state) => match alive { - true => { - self.input_events.push(comp::InputEvent::Attack); - } - false => { - self.input_events.push(comp::InputEvent::RequestRespawn); - } - _ => unreachable!(), + Event::InputUpdate(GameInput::Attack, state) => { + self.input_events.push(comp::InputEvent::Attack); + //self.input_events.push(comp::InputEvent::RequestRespawn); }, - // Movement key pressed - Event::KeyDown(Key::MoveForward) if alive => self.key_state.up = true, - Event::KeyDown(Key::MoveBack) if alive => self.key_state.down = true, - Event::KeyDown(Key::MoveLeft) if alive => self.key_state.left = true, - Event::KeyDown(Key::MoveRight) if alive => self.key_state.right = true, - Event::KeyDown(Key::Jump) if alive => { + Event::InputUpdate(GameInput::MoveForward, state) => self.key_state.up = state, + Event::InputUpdate(GameInput::MoveBack, state) => self.key_state.down = state, + Event::InputUpdate(GameInput::MoveLeft, state) => self.key_state.left = state, + Event::InputUpdate(GameInput::MoveRight, state) => self.key_state.right = state, + Event::InputUpdate(GameInput::Glide, state) => self.key_state.glide = state, + Event::InputUpdate(GameInput::Jump, true) => { self.input_events.push(comp::InputEvent::Jump); self.key_state.jump = true; } - Event::KeyDown(Key::Glide) if alive => self.key_state.glide = true, - // Movement key released - Event::KeyUp(Key::MoveForward) if alive => self.key_state.up = false, - Event::KeyUp(Key::MoveBack) if alive => self.key_state.down = false, - Event::KeyUp(Key::MoveLeft) if alive => self.key_state.left = false, - Event::KeyUp(Key::MoveRight) if alive => self.key_state.right = false, - Event::KeyUp(Key::Jump) if alive => self.key_state.jump = false, - Event::KeyUp(Key::Glide) if alive => self.key_state.glide = false, + Event::InputUpdate(GameInput::Jump, false) => { + self.key_state.jump = false; + } + // Pass all other events to the scene event => { self.scene.handle_input_event(event); diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 3ba043737f..14d625601d 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -1,6 +1,7 @@ +use crate::window::KeyMouse; use config::{Config, ConfigError}; use directories::ProjectDirs; -use glutin::VirtualKeyCode; +use glutin::{MouseButton, VirtualKeyCode}; use serde_derive::{Deserialize, Serialize}; use std::{fs, io::prelude::*, path::PathBuf}; use toml; @@ -19,30 +20,31 @@ pub struct Settings { /// `ControlSettings` contains keybindings. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ControlSettings { - pub toggle_cursor: VirtualKeyCode, - pub escape: VirtualKeyCode, - pub enter: VirtualKeyCode, - pub move_forward: VirtualKeyCode, - pub move_left: VirtualKeyCode, - pub move_back: VirtualKeyCode, - pub move_right: VirtualKeyCode, - pub jump: VirtualKeyCode, - pub glide: VirtualKeyCode, - pub map: VirtualKeyCode, - pub bag: VirtualKeyCode, - pub quest_log: VirtualKeyCode, - pub character_window: VirtualKeyCode, - pub social: VirtualKeyCode, - pub spellbook: VirtualKeyCode, - pub settings: VirtualKeyCode, - pub help: VirtualKeyCode, - pub toggle_interface: VirtualKeyCode, - pub toggle_debug: VirtualKeyCode, - pub fullscreen: VirtualKeyCode, - pub screenshot: VirtualKeyCode, + pub toggle_cursor: KeyMouse, + pub escape: KeyMouse, + pub enter: KeyMouse, + pub move_forward: KeyMouse, + pub move_left: KeyMouse, + pub move_back: KeyMouse, + pub move_right: KeyMouse, + pub jump: KeyMouse, + pub glide: KeyMouse, + pub map: KeyMouse, + pub bag: KeyMouse, + pub quest_log: KeyMouse, + pub character_window: KeyMouse, + pub social: KeyMouse, + pub spellbook: KeyMouse, + pub settings: KeyMouse, + pub help: KeyMouse, + pub toggle_interface: KeyMouse, + pub toggle_debug: KeyMouse, + pub fullscreen: KeyMouse, + pub screenshot: KeyMouse, pub toggle_ingame_ui: VirtualKeyCode, pub pan_sensitivity: f32, pub zoom_sensitivity: f32, + pub attack: KeyMouse, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -77,30 +79,31 @@ impl Default for Settings { fn default() -> Self { Settings { controls: ControlSettings { - toggle_cursor: VirtualKeyCode::Tab, - escape: VirtualKeyCode::Escape, - enter: VirtualKeyCode::Return, - move_forward: VirtualKeyCode::W, - move_left: VirtualKeyCode::A, - move_back: VirtualKeyCode::S, - move_right: VirtualKeyCode::D, - jump: VirtualKeyCode::Space, - glide: VirtualKeyCode::LShift, - map: VirtualKeyCode::M, - bag: VirtualKeyCode::B, - quest_log: VirtualKeyCode::L, - character_window: VirtualKeyCode::C, - social: VirtualKeyCode::O, - spellbook: VirtualKeyCode::P, - settings: VirtualKeyCode::N, - help: VirtualKeyCode::F1, - toggle_interface: VirtualKeyCode::F2, - toggle_debug: VirtualKeyCode::F3, - fullscreen: VirtualKeyCode::F11, - screenshot: VirtualKeyCode::F4, + toggle_cursor: KeyMouse::Key(VirtualKeyCode::Tab), + escape: KeyMouse::Key(VirtualKeyCode::Escape), + enter: KeyMouse::Key(VirtualKeyCode::Return), + move_forward: KeyMouse::Key(VirtualKeyCode::W), + move_left: KeyMouse::Key(VirtualKeyCode::A), + move_back: KeyMouse::Key(VirtualKeyCode::S), + move_right: KeyMouse::Key(VirtualKeyCode::D), + jump: KeyMouse::Key(VirtualKeyCode::Space), + glide: KeyMouse::Key(VirtualKeyCode::LShift), + map: KeyMouse::Key(VirtualKeyCode::M), + bag: KeyMouse::Key(VirtualKeyCode::B), + quest_log: KeyMouse::Key(VirtualKeyCode::L), + character_window: KeyMouse::Key(VirtualKeyCode::C), + social: KeyMouse::Key(VirtualKeyCode::O), + spellbook: KeyMouse::Key(VirtualKeyCode::P), + settings: KeyMouse::Key(VirtualKeyCode::N), + help: KeyMouse::Key(VirtualKeyCode::F1), + toggle_interface: KeyMouse::Key(VirtualKeyCode::F2), + toggle_debug: KeyMouse::Key(VirtualKeyCode::F3), + fullscreen: KeyMouse::Key(VirtualKeyCode::F11), + screenshot: KeyMouse::Key(VirtualKeyCode::F4), toggle_ingame_ui: VirtualKeyCode::F6, pan_sensitivity: 1.0, zoom_sensitivity: 1.0, + attack: KeyMouse::Mouse(MouseButton::Left), }, networking: NetworkingSettings { username: "Username".to_string(), diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index f0dd30aafb..46ac859517 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -3,11 +3,67 @@ use crate::{ settings::Settings, ui, Error, }; +use serde_derive::{Deserialize, Serialize}; use std::collections::HashMap; use vek::*; -pub type MouseButton = glutin::MouseButton; -pub type ElementState = glutin::ElementState; +/// Represents a key that the game recognises after keyboard mapping. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub enum GameInput { + ToggleCursor, + MoveForward, + MoveBack, + MoveLeft, + MoveRight, + Jump, + Glide, + Enter, + Escape, + Map, + Bag, + QuestLog, + CharacterWindow, + Social, + Spellbook, + Settings, + ToggleInterface, + Help, + ToggleDebug, + Fullscreen, + Screenshot, + ToggleIngameUi, + Attack, + Respawn, +} + +/// Represents an incoming event from the window. +#[derive(Clone)] +pub enum Event { + /// The window has been requested to close. + Close, + /// The window has been resized. + Resize(Vec2), + /// A key has been typed that corresponds to a specific character. + Char(char), + /// The cursor has been panned across the screen while grabbed. + CursorPan(Vec2), + /// The camera has been requested to zoom. + Zoom(f32), + /// A key that the game recognises has been pressed or released. + InputUpdate(GameInput, bool), + /// Event that the ui uses. + Ui(ui::Event), + // The view distance has been changed + ViewDistanceChanged(u32), + /// Game settings have changed. + SettingsChanged, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub enum KeyMouse { + Key(glutin::VirtualKeyCode), + Mouse(glutin::MouseButton), +} pub struct Window { events_loop: glutin::EventsLoop, @@ -18,7 +74,7 @@ pub struct Window { pub zoom_sensitivity: f32, fullscreen: bool, needs_refresh_resize: bool, - key_map: HashMap, + key_map: HashMap, supplement_events: Vec, focused: bool, } @@ -45,28 +101,29 @@ impl Window { .map_err(|err| Error::BackendError(Box::new(err)))?; let mut key_map = HashMap::new(); - key_map.insert(settings.controls.toggle_cursor, Key::ToggleCursor); - key_map.insert(settings.controls.escape, Key::Escape); - key_map.insert(settings.controls.enter, Key::Enter); - key_map.insert(settings.controls.move_forward, Key::MoveForward); - key_map.insert(settings.controls.move_left, Key::MoveLeft); - key_map.insert(settings.controls.move_back, Key::MoveBack); - key_map.insert(settings.controls.move_right, Key::MoveRight); - key_map.insert(settings.controls.jump, Key::Jump); - key_map.insert(settings.controls.glide, Key::Glide); - key_map.insert(settings.controls.map, Key::Map); - key_map.insert(settings.controls.bag, Key::Bag); - key_map.insert(settings.controls.quest_log, Key::QuestLog); - key_map.insert(settings.controls.character_window, Key::CharacterWindow); - key_map.insert(settings.controls.social, Key::Social); - key_map.insert(settings.controls.spellbook, Key::Spellbook); - key_map.insert(settings.controls.settings, Key::Settings); - key_map.insert(settings.controls.help, Key::Help); - key_map.insert(settings.controls.toggle_interface, Key::ToggleInterface); - key_map.insert(settings.controls.toggle_debug, Key::ToggleDebug); - key_map.insert(settings.controls.fullscreen, Key::Fullscreen); - key_map.insert(settings.controls.screenshot, Key::Screenshot); - key_map.insert(settings.controls.toggle_ingame_ui, Key::ToggleIngameUi); + key_map.insert(settings.controls.toggle_cursor, GameInput::ToggleCursor); + key_map.insert(settings.controls.escape, GameInput::Escape); + key_map.insert(settings.controls.enter, GameInput::Enter); + key_map.insert(settings.controls.move_forward, GameInput::MoveForward); + key_map.insert(settings.controls.move_left, GameInput::MoveLeft); + key_map.insert(settings.controls.move_back, GameInput::MoveBack); + key_map.insert(settings.controls.move_right, GameInput::MoveRight); + key_map.insert(settings.controls.jump, GameInput::Jump); + key_map.insert(settings.controls.glide, GameInput::Glide); + key_map.insert(settings.controls.map, GameInput::Map); + key_map.insert(settings.controls.bag, GameInput::Bag); + key_map.insert(settings.controls.quest_log, GameInput::QuestLog); + key_map.insert(settings.controls.character_window, GameInput::CharacterWindow); + key_map.insert(settings.controls.social, GameInput::Social); + key_map.insert(settings.controls.spellbook, GameInput::Spellbook); + key_map.insert(settings.controls.settings, GameInput::Settings); + key_map.insert(settings.controls.help, GameInput::Help); + key_map.insert(settings.controls.toggle_interface, GameInput::ToggleInterface); + key_map.insert(settings.controls.toggle_debug, GameInput::ToggleDebug); + key_map.insert(settings.controls.fullscreen, GameInput::Fullscreen); + key_map.insert(settings.controls.screenshot, GameInput::Screenshot); + key_map.insert(settings.controls.toggle_ingame_ui, GameInput::ToggleIngameUi); + key_map.insert(settings.controls.attack, GameInput::Attack); Ok(Self { events_loop, @@ -128,27 +185,26 @@ impl Window { } glutin::WindowEvent::ReceivedCharacter(c) => events.push(Event::Char(c)), glutin::WindowEvent::MouseInput { button, state, .. } - if cursor_grabbed && state == glutin::ElementState::Pressed => + if cursor_grabbed => { - events.push(Event::Click(button, state)) + if let Some(&game_input) = key_map.get(&KeyMouse::Mouse(button)) { + events.push(Event::InputUpdate(game_input, state == glutin::ElementState::Pressed)) + } } glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode { - Some(keycode) => match key_map.get(&keycode) { - Some(Key::Fullscreen) => match input.state { + Some(key) => match key_map.get(&KeyMouse::Key(key)) { + Some(GameInput::Fullscreen) => match input.state { glutin::ElementState::Pressed => { toggle_fullscreen = !toggle_fullscreen } _ => (), }, - Some(Key::Screenshot) => match input.state { + Some(GameInput::Screenshot) => match input.state { glutin::ElementState::Pressed => take_screenshot = true, _ => {} }, - Some(&key) => events.push(match input.state { - glutin::ElementState::Pressed => Event::KeyDown(key), - glutin::ElementState::Released => Event::KeyUp(key), - }), + Some(&game_input) => events.push(Event::InputUpdate(game_input, input.state == glutin::ElementState::Pressed)), _ => {} }, _ => {} @@ -261,56 +317,3 @@ impl Window { } } } - -/// Represents a key that the game recognises after keyboard mapping. -#[derive(Clone, Copy)] -pub enum Key { - ToggleCursor, - MoveForward, - MoveBack, - MoveLeft, - MoveRight, - Jump, - Glide, - Enter, - Escape, - Map, - Bag, - QuestLog, - CharacterWindow, - Social, - Spellbook, - Settings, - ToggleInterface, - Help, - ToggleDebug, - Fullscreen, - Screenshot, - ToggleIngameUi, -} - -/// Represents an incoming event from the window. -#[derive(Clone)] -pub enum Event { - /// The window has been requested to close. - Close, - /// The window has been resized. - Resize(Vec2), - /// A key has been typed that corresponds to a specific character. - Char(char), - /// The cursor has been panned across the screen while grabbed. - Click(MouseButton, ElementState), - CursorPan(Vec2), - /// The camera has been requested to zoom. - Zoom(f32), - /// A key that the game recognises has been pressed down. - KeyDown(Key), - /// A key that the game recognises has been released down. - KeyUp(Key), - /// Event that the ui uses. - Ui(ui::Event), - // The view distance has been changed - ViewDistanceChanged(u32), - /// Game settings have changed. - SettingsChanged, -}