mirror of https://github.com/sgoudham/neovide.git
integrate new keyboard api (#736)
* use new keyboard api using my fork of in progress winit keyboard pr branches * attempt fix for modifiers stuck bugmacos-click-through
parent
113a3f421c
commit
76237c6d47
@ -1,26 +0,0 @@
|
||||
use crate::settings::{FromValue, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum KeyboardLayout {
|
||||
Qwerty,
|
||||
}
|
||||
|
||||
impl FromValue for KeyboardLayout {
|
||||
fn from_value(&mut self, value: Value) {
|
||||
match value.as_str() {
|
||||
Some("qwerty") => *self = KeyboardLayout::Qwerty,
|
||||
_ => log::error!(
|
||||
"keyboard_layout setting expected a known keyboard layout name, but received: {}",
|
||||
value
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeyboardLayout> for Value {
|
||||
fn from(layout: KeyboardLayout) -> Self {
|
||||
match layout {
|
||||
KeyboardLayout::Qwerty => "qwerty".into(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
mod layout;
|
||||
mod modifiers;
|
||||
mod settings;
|
||||
mod token;
|
||||
|
||||
use crate::settings::SETTINGS;
|
||||
|
||||
pub use self::{
|
||||
layout::KeyboardLayout, modifiers::Modifiers, settings::KeyboardSettings, token::Token,
|
||||
};
|
||||
|
||||
type KeycodeToTokenFn<T> = fn(T, bool) -> Option<Token<'static>>;
|
||||
|
||||
pub fn neovim_keybinding_string<T, U>(
|
||||
keycode: Option<U>,
|
||||
keytext: Option<String>,
|
||||
modifiers: T,
|
||||
keycode_to_token: KeycodeToTokenFn<U>,
|
||||
) -> Option<String>
|
||||
where
|
||||
T: Into<Modifiers>,
|
||||
{
|
||||
let modifiers: Modifiers = modifiers.into();
|
||||
if let Some(text) = keytext {
|
||||
Some(
|
||||
if text == "<" {
|
||||
Token::new("lt", true, true)
|
||||
} else {
|
||||
Token::new(&text, false, false)
|
||||
}
|
||||
.into_string(modifiers),
|
||||
)
|
||||
} else if let Some(keycode) = keycode {
|
||||
match SETTINGS.get::<KeyboardSettings>().layout {
|
||||
KeyboardLayout::Qwerty => keycode_to_token(keycode, modifiers.shift),
|
||||
}
|
||||
.map(|e| e.into_string(modifiers))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unsupported_key<T, R>(keycode: T) -> Option<R>
|
||||
where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
log::trace!("Unsupported key: {:?}", keycode);
|
||||
None
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
/// The keyboard modifiers associated with a keystroke
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Modifiers {
|
||||
/// Shift key
|
||||
pub shift: bool,
|
||||
|
||||
/// Control key
|
||||
pub control: bool,
|
||||
|
||||
/// Alt on Windows, option on Mac
|
||||
pub meta: bool,
|
||||
|
||||
/// Windows key on PC, command key on Mac
|
||||
pub logo: bool,
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
use super::KeyboardLayout;
|
||||
use crate::settings::FromValue;
|
||||
|
||||
#[derive(SettingGroup)]
|
||||
#[setting_prefix = "keyboard"]
|
||||
#[derive(Clone)]
|
||||
pub struct KeyboardSettings {
|
||||
pub layout: KeyboardLayout,
|
||||
}
|
||||
|
||||
impl Default for KeyboardSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
layout: KeyboardLayout::Qwerty,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
use super::Modifiers;
|
||||
|
||||
/// Information about how to translate keyboard into Vim input
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Token<'a> {
|
||||
/// The name of the key in Vimscript.
|
||||
/// See `:help key-notation` for more details.
|
||||
key_name: &'a str,
|
||||
|
||||
/// Whether the token should be enclosed in brackets, such as <Esc> or <BS>
|
||||
special: bool,
|
||||
|
||||
/// Whether the shift key should be considered for inclusion in the token.
|
||||
use_shift: bool,
|
||||
}
|
||||
|
||||
impl<'a> Token<'a> {
|
||||
pub const fn new(key_name: &'a str, special: bool, use_shift: bool) -> Self {
|
||||
Self {
|
||||
key_name,
|
||||
special,
|
||||
use_shift,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the keypress to a Neovim input
|
||||
pub fn into_string(self, mods: Modifiers) -> String {
|
||||
let shift = self.use_shift && mods.shift;
|
||||
let special = self.special || shift || mods.control || mods.meta || use_logo(mods.logo);
|
||||
let open = if special { "<" } else { "" };
|
||||
let command = if use_logo(mods.logo) { "D-" } else { "" };
|
||||
let shift = if shift { "S-" } else { "" };
|
||||
let control = if mods.control { "C-" } else { "" };
|
||||
let meta = if mods.meta { "M-" } else { "" };
|
||||
let close = if special { ">" } else { "" };
|
||||
format!(
|
||||
"{}{}{}{}{}{}{}",
|
||||
open, command, shift, control, meta, self.key_name, close
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn use_logo(logo: bool) -> bool {
|
||||
logo
|
||||
}
|
||||
|
||||
// The Windows key is used for OS-level shortcuts,
|
||||
// so we want to ignore the logo key on this platform.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn use_logo(_: bool) -> bool {
|
||||
false
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
use glutin::event::{ElementState, Event, WindowEvent};
|
||||
use glutin::keyboard::Key;
|
||||
|
||||
use crate::bridge::UiCommand;
|
||||
use crate::channel_utils::LoggingTx;
|
||||
|
||||
pub struct KeyboardManager {
|
||||
command_sender: LoggingTx<UiCommand>,
|
||||
shift: bool,
|
||||
ctrl: bool,
|
||||
alt: bool,
|
||||
logo: bool,
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn use_logo(logo: bool) -> bool {
|
||||
logo
|
||||
}
|
||||
|
||||
// The Windows key is used for OS-level shortcuts,
|
||||
// so we want to ignore the logo key on this platform.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn use_logo(_: bool) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn or_empty(condition: bool, text: &str) -> &str {
|
||||
if condition {
|
||||
text
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
fn get_key_text(key: Key<'static>) -> Option<(&str, bool)> {
|
||||
match key {
|
||||
Key::Character(character_text) => match character_text {
|
||||
" " => Some(("Space", true)),
|
||||
"<" => Some(("lt", true)),
|
||||
"\\" => Some(("Bslash", true)),
|
||||
"|" => Some(("Bar", true)),
|
||||
" " => Some(("Tab", true)),
|
||||
"\n" => Some(("CR", true)),
|
||||
_ => Some((character_text, false)),
|
||||
},
|
||||
Key::Backspace => Some(("BS", true)),
|
||||
Key::Tab => Some(("Tab", true)),
|
||||
Key::Enter => Some(("CR", true)),
|
||||
Key::Escape => Some(("Esc", true)),
|
||||
Key::Space => Some(("Space", true)),
|
||||
Key::Delete => Some(("Del", true)),
|
||||
Key::ArrowUp => Some(("Up", true)),
|
||||
Key::ArrowDown => Some(("Down", true)),
|
||||
Key::ArrowLeft => Some(("Left", true)),
|
||||
Key::ArrowRight => Some(("Right", true)),
|
||||
Key::F1 => Some(("F1", true)),
|
||||
Key::F2 => Some(("F2", true)),
|
||||
Key::F3 => Some(("F3", true)),
|
||||
Key::F4 => Some(("F4", true)),
|
||||
Key::F5 => Some(("F5", true)),
|
||||
Key::F6 => Some(("F6", true)),
|
||||
Key::F7 => Some(("F7", true)),
|
||||
Key::F8 => Some(("F8", true)),
|
||||
Key::F9 => Some(("F9", true)),
|
||||
Key::F10 => Some(("F10", true)),
|
||||
Key::F11 => Some(("F11", true)),
|
||||
Key::F12 => Some(("F12", true)),
|
||||
Key::Insert => Some(("Insert", true)),
|
||||
Key::Home => Some(("Home", true)),
|
||||
Key::End => Some(("End", true)),
|
||||
Key::PageUp => Some(("PageUp", true)),
|
||||
Key::PageDown => Some(("PageDown", true)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardManager {
|
||||
pub fn new(command_sender: LoggingTx<UiCommand>) -> KeyboardManager {
|
||||
KeyboardManager {
|
||||
command_sender,
|
||||
shift: false,
|
||||
ctrl: false,
|
||||
alt: false,
|
||||
logo: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn format_keybinding_string(&self, special: bool, text: &str) -> String {
|
||||
let special = special || self.shift || self.ctrl || self.alt || self.logo;
|
||||
|
||||
let open = or_empty(special, "<");
|
||||
let shift = or_empty(self.shift, "S-");
|
||||
let ctrl = or_empty(self.ctrl, "C-");
|
||||
let alt = or_empty(self.alt, "M-");
|
||||
let logo = or_empty(use_logo(self.logo), "D-");
|
||||
let close = or_empty(special, ">");
|
||||
|
||||
format!("{}{}{}{}{}{}{}", open, shift, ctrl, alt, logo, text, close)
|
||||
}
|
||||
|
||||
pub fn handle_event(&mut self, event: &Event<()>) {
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::KeyboardInput {
|
||||
event: key_event, ..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
if key_event.state == ElementState::Pressed {
|
||||
if let Some((key_text, special)) = get_key_text(key_event.logical_key) {
|
||||
let keybinding_string = self.format_keybinding_string(special, key_text);
|
||||
|
||||
self.command_sender
|
||||
.send(UiCommand::Keyboard(keybinding_string))
|
||||
.expect("Could not send keyboard ui command");
|
||||
}
|
||||
}
|
||||
},
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::ModifiersChanged(modifiers),
|
||||
..
|
||||
} => {
|
||||
self.shift = modifiers.shift_key();
|
||||
self.ctrl = modifiers.control_key();
|
||||
self.alt = modifiers.alt_key();
|
||||
self.logo = modifiers.super_key();
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
mod qwerty;
|
||||
|
||||
use crate::window::keyboard::Modifiers;
|
||||
use glutin::event::ModifiersState;
|
||||
|
||||
pub use qwerty::handle_qwerty_layout;
|
||||
|
||||
impl From<Option<ModifiersState>> for Modifiers {
|
||||
fn from(state: Option<ModifiersState>) -> Modifiers {
|
||||
if let Some(modifiers) = state {
|
||||
Modifiers {
|
||||
shift: modifiers.shift(),
|
||||
control: modifiers.ctrl(),
|
||||
meta: modifiers.alt(),
|
||||
logo: modifiers.logo(),
|
||||
}
|
||||
} else {
|
||||
Modifiers {
|
||||
shift: false,
|
||||
control: false,
|
||||
meta: false,
|
||||
logo: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
use crate::window::keyboard::{unsupported_key, Token};
|
||||
use glutin::event::VirtualKeyCode::{self, *};
|
||||
|
||||
/// Maps winit keyboard events to Vim tokens
|
||||
pub fn handle_qwerty_layout(keycode: VirtualKeyCode, shift: bool) -> Option<Token<'static>> {
|
||||
let special = |text| Some(Token::new(text, true, true));
|
||||
let normal = |text| Some(Token::new(text, false, true));
|
||||
let partial = |text| Some(Token::new(text, false, false));
|
||||
match (keycode, shift) {
|
||||
(Back, _) => special("BS"),
|
||||
(Tab, _) => special("Tab"),
|
||||
(Return, _) => special("Enter"),
|
||||
(Escape, _) => special("Esc"),
|
||||
(Space, _) => normal(" "),
|
||||
(Apostrophe, false) => partial("'"),
|
||||
(Apostrophe, true) => partial("\""),
|
||||
(Comma, false) => normal(","),
|
||||
(Comma, true) => special("lt"),
|
||||
(Minus, false) => partial("-"),
|
||||
(Minus, true) => partial("_"),
|
||||
(Period, false) => partial("."),
|
||||
(Period, true) => partial(">"),
|
||||
(Slash, false) => partial("/"),
|
||||
(Slash, true) => partial("?"),
|
||||
(Key0, false) => normal("0"),
|
||||
(Key0, true) => partial(")"),
|
||||
(Key1, false) => normal("1"),
|
||||
(Key1, true) => partial("!"),
|
||||
(Key2, false) => partial("2"),
|
||||
(Key2, true) => partial("@"),
|
||||
(Key3, false) => partial("3"),
|
||||
(Key3, true) => partial("#"),
|
||||
(Key4, false) => partial("4"),
|
||||
(Key4, true) => partial("$"),
|
||||
(Key5, false) => partial("5"),
|
||||
(Key5, true) => partial("%"),
|
||||
(Key6, false) => partial("6"),
|
||||
(Key6, true) => partial("^"),
|
||||
(Key7, false) => partial("7"),
|
||||
(Key7, true) => partial("&"),
|
||||
(Key8, false) => partial("8"),
|
||||
(Key8, true) => partial("*"),
|
||||
(Key9, false) => partial("9"),
|
||||
(Key9, true) => partial("("),
|
||||
(Colon, _) => normal(":"),
|
||||
(Semicolon, false) => partial(";"),
|
||||
(Semicolon, true) => partial(":"),
|
||||
(Equals, false) => partial("="),
|
||||
(Equals, true) => partial("+"),
|
||||
(At, _) => normal("@"),
|
||||
(LBracket, false) => partial("["),
|
||||
(LBracket, true) => partial("{"),
|
||||
(Backslash, false) => partial("\\"),
|
||||
(Backslash, true) => partial("|"),
|
||||
(RBracket, false) => partial("]"),
|
||||
(RBracket, true) => partial("}"),
|
||||
(Caret, _) => normal("^"),
|
||||
(Grave, false) => partial("`"),
|
||||
(Grave, true) => partial("~"),
|
||||
(A, _) => normal("a"),
|
||||
(B, _) => normal("b"),
|
||||
(C, _) => normal("c"),
|
||||
(D, _) => normal("d"),
|
||||
(E, _) => normal("e"),
|
||||
(F, _) => normal("f"),
|
||||
(G, _) => normal("g"),
|
||||
(H, _) => normal("h"),
|
||||
(I, _) => normal("i"),
|
||||
(J, _) => normal("j"),
|
||||
(K, _) => normal("k"),
|
||||
(L, _) => normal("l"),
|
||||
(M, _) => normal("m"),
|
||||
(N, _) => normal("n"),
|
||||
(O, _) => normal("o"),
|
||||
(P, _) => normal("p"),
|
||||
(Q, _) => normal("q"),
|
||||
(R, _) => normal("r"),
|
||||
(S, _) => normal("s"),
|
||||
(T, _) => normal("t"),
|
||||
(U, _) => normal("u"),
|
||||
(V, _) => normal("v"),
|
||||
(W, _) => normal("w"),
|
||||
(X, _) => normal("x"),
|
||||
(Y, _) => normal("y"),
|
||||
(Z, _) => normal("z"),
|
||||
(Delete, _) => special("Delete"),
|
||||
(F1, _) => special("F1"),
|
||||
(F2, _) => special("F2"),
|
||||
(F3, _) => special("F3"),
|
||||
(F4, _) => special("F4"),
|
||||
(F5, _) => special("F5"),
|
||||
(F6, _) => special("F6"),
|
||||
(F7, _) => special("F7"),
|
||||
(F8, _) => special("F8"),
|
||||
(F9, _) => special("F9"),
|
||||
(F10, _) => special("F10"),
|
||||
(F11, _) => special("F11"),
|
||||
(F12, _) => special("F12"),
|
||||
(Insert, _) => special("Insert"),
|
||||
(Home, _) => special("Home"),
|
||||
(PageUp, _) => special("PageUp"),
|
||||
(End, _) => special("End"),
|
||||
(PageDown, _) => special("PageDown"),
|
||||
(Right, _) => special("Right"),
|
||||
(Left, _) => special("Left"),
|
||||
(Down, _) => special("Down"),
|
||||
(Up, _) => special("Up"),
|
||||
(Numpad0, _) => normal("0"),
|
||||
(Numpad1, _) => normal("1"),
|
||||
(Numpad2, _) => normal("2"),
|
||||
(Numpad3, _) => normal("3"),
|
||||
(Numpad4, _) => normal("4"),
|
||||
(Numpad5, _) => normal("5"),
|
||||
(Numpad6, _) => normal("6"),
|
||||
(Numpad7, _) => normal("7"),
|
||||
(Numpad8, _) => normal("8"),
|
||||
(Numpad9, _) => normal("9"),
|
||||
(F13, _) => special("F13"),
|
||||
(F14, _) => special("F14"),
|
||||
(F15, _) => special("F15"),
|
||||
(F16, _) => special("F16"),
|
||||
(F17, _) => special("F17"),
|
||||
(F18, _) => special("F18"),
|
||||
(F19, _) => special("F19"),
|
||||
(F20, _) => special("F20"),
|
||||
(F21, _) => special("F21"),
|
||||
(F22, _) => special("F22"),
|
||||
(F23, _) => special("F23"),
|
||||
(F24, _) => special("F24"),
|
||||
(LControl, _) => None,
|
||||
(LShift, _) => None,
|
||||
(LAlt, _) => None,
|
||||
(RControl, _) => None,
|
||||
(RShift, _) => None,
|
||||
(RAlt, _) => None,
|
||||
(keycode, _) => unsupported_key(keycode),
|
||||
}
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
use glutin::{
|
||||
self,
|
||||
WindowedContext,
|
||||
dpi::{
|
||||
LogicalPosition,
|
||||
LogicalSize,
|
||||
PhysicalSize
|
||||
},
|
||||
event::{
|
||||
ElementState,
|
||||
Event,
|
||||
MouseButton,
|
||||
MouseScrollDelta,
|
||||
WindowEvent,
|
||||
},
|
||||
PossiblyCurrent
|
||||
};
|
||||
|
||||
use crate::channel_utils::LoggingTx;
|
||||
use crate::bridge::UiCommand;
|
||||
use crate::renderer::Renderer;
|
||||
|
||||
pub struct MouseManager {
|
||||
command_sender: LoggingTx<UiCommand>,
|
||||
button_down: bool,
|
||||
position: LogicalPosition<u32>,
|
||||
grid_id_under_mouse: u64,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl MouseManager {
|
||||
pub fn new(command_sender: LoggingTx<UiCommand>) -> MouseManager {
|
||||
MouseManager {
|
||||
command_sender,
|
||||
button_down: false,
|
||||
position: LogicalPosition::new(0, 0),
|
||||
grid_id_under_mouse: 0,
|
||||
enabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_pointer_motion(&mut self, x: i32, y: i32, renderer: &Renderer, windowed_context: &WindowedContext<PossiblyCurrent>) {
|
||||
let size = windowed_context.window().inner_size();
|
||||
if x < 0 || x as u32 >= size.width || y < 0 || y as u32 >= size.height {
|
||||
return;
|
||||
}
|
||||
|
||||
let previous_position = self.position;
|
||||
|
||||
let logical_position: LogicalSize<u32> = PhysicalSize::new(x as u32, y as u32)
|
||||
.to_logical(windowed_context.window().scale_factor());
|
||||
|
||||
let mut top_window_position = (0.0, 0.0);
|
||||
let mut top_grid_position = None;
|
||||
|
||||
for details in renderer.window_regions.iter() {
|
||||
if logical_position.width >= details.region.left as u32
|
||||
&& logical_position.width < details.region.right as u32
|
||||
&& logical_position.height >= details.region.top as u32
|
||||
&& logical_position.height < details.region.bottom as u32
|
||||
{
|
||||
top_window_position = (details.region.left, details.region.top);
|
||||
top_grid_position = Some((
|
||||
details.id,
|
||||
LogicalSize::<u32>::new(
|
||||
logical_position.width - details.region.left as u32,
|
||||
logical_position.height - details.region.top as u32,
|
||||
),
|
||||
details.floating_order.is_some(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((grid_id, grid_position, grid_floating)) = top_grid_position {
|
||||
self.grid_id_under_mouse = grid_id;
|
||||
self.position = LogicalPosition::new(
|
||||
(grid_position.width as u64 / renderer.font_width) as u32,
|
||||
(grid_position.height as u64 / renderer.font_height) as u32,
|
||||
);
|
||||
|
||||
if self.enabled && self.button_down && previous_position != self.position {
|
||||
let (window_left, window_top) = top_window_position;
|
||||
|
||||
// Until https://github.com/neovim/neovim/pull/12667 is merged, we have to special
|
||||
// case non floating windows. Floating windows correctly transform mouse positions
|
||||
// into grid coordinates, but non floating windows do not.
|
||||
let position = if grid_floating {
|
||||
(self.position.x, self.position.y)
|
||||
} else {
|
||||
let adjusted_drag_left = self.position.x
|
||||
+ (window_left / renderer.font_width as f32) as u32;
|
||||
let adjusted_drag_top = self.position.y
|
||||
+ (window_top / renderer.font_height as f32) as u32;
|
||||
(adjusted_drag_left, adjusted_drag_top)
|
||||
};
|
||||
|
||||
self.command_sender
|
||||
.send(UiCommand::Drag {
|
||||
grid_id: self.grid_id_under_mouse,
|
||||
position,
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_pointer_down(&mut self) {
|
||||
if self.enabled {
|
||||
self.command_sender
|
||||
.send(UiCommand::MouseButton {
|
||||
action: String::from("press"),
|
||||
grid_id: self.grid_id_under_mouse,
|
||||
position: (self.position.x, self.position.y),
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
self.button_down = true;
|
||||
}
|
||||
|
||||
fn handle_pointer_up(&mut self) {
|
||||
if self.enabled {
|
||||
self.command_sender
|
||||
.send(UiCommand::MouseButton {
|
||||
action: String::from("release"),
|
||||
grid_id: self.grid_id_under_mouse,
|
||||
position: (self.position.x, self.position.y),
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
self.button_down = false;
|
||||
}
|
||||
|
||||
fn handle_mouse_wheel(&mut self, x: f32, y: f32) {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let vertical_input_type = match y {
|
||||
_ if y > 1.8 => Some("up"),
|
||||
_ if y < -1.8 => Some("down"),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(input_type) = vertical_input_type {
|
||||
self.command_sender
|
||||
.send(UiCommand::Scroll {
|
||||
direction: input_type.to_string(),
|
||||
grid_id: self.grid_id_under_mouse,
|
||||
position: (self.position.x, self.position.y),
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
let horizontal_input_type = match x {
|
||||
_ if x > 1.8 => Some("right"),
|
||||
_ if x < -1.8 => Some("left"),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(input_type) = horizontal_input_type {
|
||||
self.command_sender
|
||||
.send(UiCommand::Scroll {
|
||||
direction: input_type.to_string(),
|
||||
grid_id: self.grid_id_under_mouse,
|
||||
position: (self.position.x, self.position.y),
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_event(&mut self, event: &Event<()>, renderer: &Renderer, windowed_context: &WindowedContext<PossiblyCurrent>) {
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CursorMoved { position, .. },
|
||||
..
|
||||
} => self.handle_pointer_motion(
|
||||
position.x as i32, position.y as i32,
|
||||
renderer, windowed_context),
|
||||
Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::MouseWheel {
|
||||
delta: MouseScrollDelta::LineDelta(x, y),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => self.handle_mouse_wheel(*x as f32, *y as f32),
|
||||
Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::MouseWheel {
|
||||
delta: MouseScrollDelta::PixelDelta(logical_position),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => self.handle_mouse_wheel(logical_position.x as f32, logical_position.y as f32),
|
||||
Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::MouseInput {
|
||||
button: MouseButton::Left,
|
||||
state,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
if state == &ElementState::Pressed {
|
||||
self.handle_pointer_down();
|
||||
} else {
|
||||
self.handle_pointer_up();
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue