Fixes for OS X machines.

Handles scroll wheel events in pixels (enabling the scroll wheel) and
sets rolling and wall leaping to use left shift by default on OS X
(instead of middle mouse click, which is absent by default on Apple
trackpads).  Also updates the controls UI to show the actual assigned
keys for those controls which are configurable.
This commit is contained in:
Joshua Yanovski 2020-01-20 05:08:04 +01:00
parent 595bc6c67a
commit 355a1b204a
4 changed files with 290 additions and 50 deletions

View File

@ -33,6 +33,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Controls pane in settings window now shows actual configured keys
- Fixed scroll wheel and roll keys on OS X
- Fixed near and far view planes - Fixed near and far view planes
- Improvements to armor names - Improvements to armor names
- Animation fixes to line up with true positions - Animation fixes to line up with true positions

View File

@ -1209,6 +1209,7 @@ impl<'a> Widget for SettingsWindow<'a> {
// Contents // Contents
if let SettingsTab::Controls = self.show.settings_tab { if let SettingsTab::Controls = self.show.settings_tab {
let controls = &self.global_state.settings.controls;
Text::new( Text::new(
"Free Cursor\n\ "Free Cursor\n\
Toggle Help Window\n\ Toggle Help Window\n\
@ -1288,65 +1289,65 @@ impl<'a> Widget for SettingsWindow<'a> {
.font_size(18) .font_size(18)
.set(state.ids.controls_text, ui); .set(state.ids.controls_text, ui);
// TODO: Replace with buttons that show actual keybinds and allow the user to change them. // TODO: Replace with buttons that show actual keybinds and allow the user to change them.
Text::new( Text::new(&format!(
"TAB\n\ "{}\n\
F1\n\ {}\n\
F2\n\ {}\n\
F3\n\ {}\n\
F4\n\ {}\n\
F6\n\ {}\n\
F11\n\ {}\n\
\n\ \n\
\n\ \n\
W\n\ {}\n\
A\n\ {}\n\
S\n\ {}\n\
D\n\ {}\n\
\n\ \n\
SPACE\n\ {}\n\
\n\ \n\
L-Shift\n\ {}\n\
\n\ \n\
??\n\ {}\n\
\n\ \n\
??\n\ {}\n\
\n\ \n\
??\n\ {}\n\
\n\ \n\
??\n\ {}\n\
\n\ \n\
??\n\ {}\n\
\n\ \n\
\n\ \n\
L-Click\n\ {}\n\
R-Click\n\ {}\n\
\n\ \n\
\n\ \n\
1\n\ {}\n\
2\n\ {}\n\
3\n\ {}\n\
4\n\ {}\n\
5\n\ {}\n\
6\n\ {}\n\
7\n\ {}\n\
8\n\ {}\n\
9\n\ {}\n\
0\n\ {}\n\
\n\ \n\
\n\ \n\
ESC\n\ {}\n\
N\n\ {}\n\
O\n\ {}\n\
M\n\ {}\n\
P\n\ {}\n\
C\n\ {}\n\
L\n\ {}\n\
B\n\ {}\n\
\n\ \n\
\n\ \n\
\n\ \n\
ENTER\n\ {}\n\
Mousewheel\n\ {}\n\
\n\ \n\
\n\ \n\
\n\ \n\
@ -1354,7 +1355,47 @@ impl<'a> Widget for SettingsWindow<'a> {
\n\ \n\
\n\ \n\
", ",
) controls.toggle_cursor,
controls.help,
controls.toggle_interface,
controls.toggle_debug,
controls.screenshot,
controls.toggle_ingame_ui,
controls.fullscreen,
controls.move_forward,
controls.move_left,
controls.move_back,
controls.move_right,
controls.jump,
controls.glide,
"??", // Dodge
"??", // Auto Walk
controls.toggle_wield,
"??", // Put on/Remove Helmet
controls.sit,
controls.primary,
controls.secondary,
"1", // Skillbar Slot 1
"2", // Skillbar Slot 2
"3", // Skillbar Slot 3
"4", // Skillbar Slot 4
"5", // Skillbar Slot 5
"6", // Skillbar Slot 6
"7", // Skillbar Slot 7
"8", // Skillbar Slot 8
"9", // Skillbar Slot 9
"0", // Skillbar Slot 10
controls.escape,
controls.settings,
controls.social,
controls.map,
controls.spellbook,
controls.character_window,
controls.quest_log,
controls.bag,
controls.enter,
"Mouse Wheel", // Scroll chat
))
.color(TEXT_COLOR) .color(TEXT_COLOR)
.right_from(state.ids.controls_text, 0.0) .right_from(state.ids.controls_text, 0.0)
.font_id(self.fonts.cyri) .font_id(self.fonts.cyri)

View File

@ -51,6 +51,15 @@ pub struct ControlSettings {
pub charge: KeyMouse, pub charge: KeyMouse,
} }
/// Since Macbook trackpads lack middle click, on OS X we default to LShift instead
/// It is an imperfect heuristic, but hopefully it will be a slightly better default, and the
/// two places we default to middle click currently (roll and wall jump) are both situations where
/// you cannot glide (the other default mapping for LShift).
#[cfg(target_os = "macos")]
const MIDDLE_CLICK_KEY: KeyMouse = KeyMouse::Key(VirtualKeyCode::LShift);
#[cfg(not(target_os = "macos"))]
const MIDDLE_CLICK_KEY: KeyMouse = KeyMouse::Mouse(MouseButton::Middle);
impl Default for ControlSettings { impl Default for ControlSettings {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -69,7 +78,7 @@ impl Default for ControlSettings {
glide: KeyMouse::Key(VirtualKeyCode::LShift), glide: KeyMouse::Key(VirtualKeyCode::LShift),
climb: KeyMouse::Key(VirtualKeyCode::Space), climb: KeyMouse::Key(VirtualKeyCode::Space),
climb_down: KeyMouse::Key(VirtualKeyCode::LControl), climb_down: KeyMouse::Key(VirtualKeyCode::LControl),
wall_leap: KeyMouse::Mouse(MouseButton::Middle), wall_leap: MIDDLE_CLICK_KEY,
mount: KeyMouse::Key(VirtualKeyCode::F), mount: KeyMouse::Key(VirtualKeyCode::F),
map: KeyMouse::Key(VirtualKeyCode::M), map: KeyMouse::Key(VirtualKeyCode::M),
bag: KeyMouse::Key(VirtualKeyCode::B), bag: KeyMouse::Key(VirtualKeyCode::B),
@ -84,7 +93,7 @@ impl Default for ControlSettings {
fullscreen: KeyMouse::Key(VirtualKeyCode::F11), fullscreen: KeyMouse::Key(VirtualKeyCode::F11),
screenshot: KeyMouse::Key(VirtualKeyCode::F4), screenshot: KeyMouse::Key(VirtualKeyCode::F4),
toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6), toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6),
roll: KeyMouse::Mouse(MouseButton::Middle), roll: MIDDLE_CLICK_KEY,
respawn: KeyMouse::Key(VirtualKeyCode::Space), respawn: KeyMouse::Key(VirtualKeyCode::Space),
interact: KeyMouse::Mouse(MouseButton::Right), interact: KeyMouse::Mouse(MouseButton::Right),
toggle_wield: KeyMouse::Key(VirtualKeyCode::T), toggle_wield: KeyMouse::Key(VirtualKeyCode::T),

View File

@ -6,6 +6,7 @@ use crate::{
use hashbrown::HashMap; use hashbrown::HashMap;
use log::{error, warn}; use log::{error, warn};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::fmt;
use vek::*; use vek::*;
/// Represents a key that the game recognises after keyboard mapping. /// Represents a key that the game recognises after keyboard mapping.
@ -86,6 +87,185 @@ pub enum KeyMouse {
Mouse(glutin::MouseButton), Mouse(glutin::MouseButton),
} }
impl fmt::Display for KeyMouse {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::KeyMouse::*;
use glutin::{MouseButton, VirtualKeyCode::*};
write!(
f,
"{}",
match self {
Key(Key1) => "1",
Key(Key2) => "2",
Key(Key3) => "3",
Key(Key4) => "4",
Key(Key5) => "5",
Key(Key6) => "6",
Key(Key7) => "7",
Key(Key8) => "8",
Key(Key9) => "9",
Key(Key0) => "0",
Key(A) => "A",
Key(B) => "B",
Key(C) => "C",
Key(D) => "D",
Key(E) => "E",
Key(F) => "F",
Key(G) => "G",
Key(H) => "H",
Key(I) => "I",
Key(J) => "J",
Key(K) => "K",
Key(L) => "L",
Key(M) => "M",
Key(N) => "N",
Key(O) => "O",
Key(P) => "P",
Key(Q) => "Q",
Key(R) => "R",
Key(S) => "S",
Key(T) => "T",
Key(U) => "U",
Key(V) => "V",
Key(W) => "W",
Key(X) => "X",
Key(Y) => "Y",
Key(Z) => "Z",
Key(Escape) => "ESC",
Key(F1) => "F1",
Key(F2) => "F2",
Key(F3) => "F3",
Key(F4) => "F4",
Key(F5) => "F5",
Key(F6) => "F6",
Key(F7) => "F7",
Key(F8) => "F8",
Key(F9) => "F9",
Key(F10) => "F10",
Key(F11) => "F11",
Key(F12) => "F12",
Key(F13) => "F13",
Key(F14) => "F14",
Key(F15) => "F15",
Key(F16) => "F16",
Key(F17) => "F17",
Key(F18) => "F18",
Key(F19) => "F19",
Key(F20) => "F20",
Key(F21) => "F21",
Key(F22) => "F22",
Key(F23) => "F23",
Key(F24) => "F24",
Key(Snapshot) => "Print Screen",
Key(Scroll) => "Scroll Lock",
Key(Pause) => "Pause/Break",
Key(Insert) => "Insert",
Key(Home) => "Home",
Key(Delete) => "Delete",
Key(End) => "End",
Key(PageDown) => "PageDown",
Key(PageUp) => "PageUp",
Key(Left) => "Left Arrow",
Key(Up) => "Up Arrow",
Key(Right) => "Right Arrow",
Key(Down) => "Down Arrow",
Key(Back) => "Backspace",
Key(Return) => "Enter",
Key(Space) => "Space",
Key(Compose) => "Compose",
Key(Caret) => "^",
Key(Numlock) => "Numlock",
Key(Numpad0) => "Numpad 0",
Key(Numpad1) => "Numpad 1",
Key(Numpad2) => "Numpad 2",
Key(Numpad3) => "Numpad 3",
Key(Numpad4) => "Numpad 4",
Key(Numpad5) => "Numpad 5",
Key(Numpad6) => "Numpad 6",
Key(Numpad7) => "Numpad 7",
Key(Numpad8) => "Numpad 8",
Key(Numpad9) => "Numpad 9",
Key(AbntC1) => "Abnt C1",
Key(AbntC2) => "Abnt C2",
Key(Add) => "Numpad +",
Key(Apostrophe) => "'",
Key(Apps) => "Context Menu",
Key(At) => "@",
Key(Ax) => "Ax",
Key(Backslash) => "\\",
Key(Calculator) => "Calculator",
Key(Capital) => "Caps Lock",
Key(Colon) => ":",
Key(Comma) => ",",
Key(Convert) => "Convert",
Key(Decimal) => "Numpad .",
Key(Divide) => "Numpad /",
Key(Equals) => "=",
Key(Grave) => "`",
Key(Kana) => "Kana",
Key(Kanji) => "Kanji",
Key(LAlt) => "LAlt",
Key(LBracket) => "[",
Key(LControl) => "LControl",
Key(LShift) => "LShift",
Key(LWin) => "LWin",
Key(Mail) => "Mail",
Key(MediaSelect) => "MediaSelect",
Key(MediaStop) => "MediaStop",
Key(Minus) => "-",
Key(Multiply) => "Numpad *",
Key(Mute) => "Mute",
Key(MyComputer) => "My Computer",
Key(NavigateForward) => "Navigate Forward",
Key(NavigateBackward) => "Navigate Backward",
Key(NextTrack) => "Next Track",
Key(NoConvert) => "Non Convert",
Key(NumpadComma) => "Numpad ,",
Key(NumpadEnter) => "Numpad Enter",
Key(NumpadEquals) => "Numpad =",
Key(OEM102) => "OEM 102",
Key(Period) => ".",
Key(PlayPause) => "Play / Pause",
Key(Power) => "Power",
Key(PrevTrack) => "Prev Track",
Key(RAlt) => "RAlt",
Key(RBracket) => "]",
Key(RControl) => "RControl",
Key(RShift) => "RShift",
Key(RWin) => "RWin",
Key(Semicolon) => ";",
Key(Slash) => "/",
Key(Sleep) => "Sleep",
Key(Stop) => "Media Stop",
Key(Subtract) => "Numpad -",
Key(Sysrq) => "Sysrq",
Key(Tab) => "Tab",
Key(Underline) => "_",
Key(Unlabeled) => "No Name",
Key(VolumeDown) => "Volume Down",
Key(VolumeUp) => "Volume Up",
Key(Wake) => "Wake",
Key(WebBack) => "Browser Back",
Key(WebFavorites) => "Browser Favorites",
Key(WebForward) => "Browser Forward",
Key(WebHome) => "Browser Home",
Key(WebRefresh) => "Browser Refresh",
Key(WebSearch) => "Browser Search",
Key(WebStop) => "Browser Stop",
Key(Yen) => "Yen",
Key(Copy) => "Copy",
Key(Paste) => "Paste",
Key(Cut) => "Cut",
Mouse(MouseButton::Left) => "Mouse L-Click",
Mouse(MouseButton::Right) => "Mouse R-Click",
Mouse(MouseButton::Middle) => "Mouse Middle-Click",
Mouse(MouseButton::Other(button)) =>
return write!(f, "Unknown Mouse Button: {:?}", button),
}
)
}
}
pub struct Window { pub struct Window {
events_loop: glutin::EventsLoop, events_loop: glutin::EventsLoop,
renderer: Renderer, renderer: Renderer,
@ -391,12 +571,20 @@ impl Window {
events.push(Event::CursorMove(delta)); events.push(Event::CursorMove(delta));
} }
} }
glutin::DeviceEvent::MouseWheel { glutin::DeviceEvent::MouseWheel { delta, .. } if cursor_grabbed && *focused => {
delta: glutin::MouseScrollDelta::LineDelta(_x, y), events.push(Event::Zoom({
.. let y = match delta {
} if cursor_grabbed && *focused => events.push(Event::Zoom( glutin::MouseScrollDelta::LineDelta(_x, y) => y,
y * (zoom_sensitivity as f32 / 100.0) * zoom_inversion, // TODO: Check to see if there is a better way to find the "line
)), // height" than just hardcoding 16.0 pixels. Alternately we could
// get rid of this and have the user set zoom sensitivity, since
// it's unlikely people would expect a configuration file to work
// across operating systems.
glutin::MouseScrollDelta::PixelDelta(pos) => (pos.y / 16.0) as f32,
};
y * (zoom_sensitivity as f32 / 100.0) * zoom_inversion
}))
}
_ => {} _ => {}
}, },
_ => {} _ => {}