Make key binds work with mouse events

Former-commit-id: 77421b44e92d7c60c39ebcb3f94a406ef7f027ff
This commit is contained in:
timokoesters 2019-05-25 16:39:27 +02:00
parent 075c0d9e11
commit 3c0121538b
4 changed files with 180 additions and 181 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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(),

View File

@ -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<u32>),
/// 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<f32>),
/// 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<glutin::VirtualKeyCode, Key>,
key_map: HashMap<KeyMouse, GameInput>,
supplement_events: Vec<Event>,
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<u32>),
/// 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<f32>),
/// 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,
}