From 132f9936991d1b681f1510ddd30f8f375eae2b49 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Sat, 7 Aug 2021 15:13:26 -0700 Subject: [PATCH] add better touch scrolling (#861) * add better touch scrolling * optionally send multiple scroll events * fix formatting Co-authored-by: Keith Simmons --- src/window/settings.rs | 2 - src/window/window_wrapper/mouse_manager.rs | 93 +++++++++++++--------- 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/window/settings.rs b/src/window/settings.rs index f3c3d42..52c5452 100644 --- a/src/window/settings.rs +++ b/src/window/settings.rs @@ -7,7 +7,6 @@ pub struct WindowSettings { pub transparency: f32, pub fullscreen: bool, pub iso_layout: bool, - pub scroll_dead_zone: f32, pub remember_window_size: bool, } @@ -22,7 +21,6 @@ impl Default for WindowSettings { .get::() .neovim_args .contains(&String::from("--noIdle")), - scroll_dead_zone: 0.0, remember_window_size: false, } } diff --git a/src/window/window_wrapper/mouse_manager.rs b/src/window/window_wrapper/mouse_manager.rs index 2d92d65..338aa09 100644 --- a/src/window/window_wrapper/mouse_manager.rs +++ b/src/window/window_wrapper/mouse_manager.rs @@ -1,3 +1,5 @@ +use std::cmp::Ordering; + use glutin::{ self, dpi::PhysicalPosition, @@ -9,8 +11,6 @@ use skia_safe::Rect; use crate::bridge::UiCommand; use crate::channel_utils::LoggingTx; use crate::renderer::{Renderer, WindowDrawDetails}; -use crate::settings::SETTINGS; -use crate::window::WindowSettings; fn clamp_position( position: PhysicalPosition, @@ -43,11 +43,16 @@ fn to_grid_coords( pub struct MouseManager { command_sender: LoggingTx, + dragging: bool, + drag_position: PhysicalPosition, + has_moved: bool, position: PhysicalPosition, relative_position: PhysicalPosition, - drag_position: PhysicalPosition, + + scroll_position: PhysicalPosition, + window_details_under_mouse: Option, pub enabled: bool, } @@ -61,6 +66,7 @@ impl MouseManager { position: PhysicalPosition::new(0, 0), relative_position: PhysicalPosition::new(0, 0), drag_position: PhysicalPosition::new(0, 0), + scroll_position: PhysicalPosition::new(0.0, 0.0), window_details_under_mouse: None, enabled: true, } @@ -192,54 +198,69 @@ impl MouseManager { } } - fn handle_mouse_wheel(&mut self, x: f32, y: f32) { + fn handle_line_scroll(&mut self, x: f32, y: f32) { if !self.enabled { return; } - let scroll_dead_zone = SETTINGS.get::().scroll_dead_zone; + let previous_y = self.scroll_position.y as i64; + self.scroll_position.y += y; + let new_y = self.scroll_position.y as i64; - let vertical_input_type = match y { - _ if y > scroll_dead_zone => Some("up"), - _ if y < -scroll_dead_zone => Some("down"), + let vertical_input_type = match new_y.partial_cmp(&previous_y) { + Some(Ordering::Greater) => Some("up"), + Some(Ordering::Less) => 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 - .window_details_under_mouse - .as_ref() - .map(|details| details.id) - .unwrap_or(0), - position: self.drag_position.into(), - }) - .ok(); + let scroll_command = UiCommand::Scroll { + direction: input_type.to_string(), + grid_id: self + .window_details_under_mouse + .as_ref() + .map(|details| details.id) + .unwrap_or(0), + position: self.drag_position.into(), + }; + for _ in 0..(new_y - previous_y).abs() { + self.command_sender.send(scroll_command.clone()).ok(); + } } - let horizontal_input_type = match x { - _ if x > scroll_dead_zone => Some("right"), - _ if x < -scroll_dead_zone => Some("left"), + let previous_x = self.scroll_position.x as i64; + self.scroll_position.x += x; + let new_x = self.scroll_position.x as i64; + + let horizontal_input_type = match new_x.partial_cmp(&previous_x) { + Some(Ordering::Greater) => Some("right"), + Some(Ordering::Less) => 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 - .window_details_under_mouse - .as_ref() - .map(|details| details.id) - .unwrap_or(0), - position: self.drag_position.into(), - }) - .ok(); + let scroll_command = UiCommand::Scroll { + direction: input_type.to_string(), + grid_id: self + .window_details_under_mouse + .as_ref() + .map(|details| details.id) + .unwrap_or(0), + position: self.drag_position.into(), + }; + for _ in 0..(new_x - previous_x).abs() { + self.command_sender.send(scroll_command.clone()).ok(); + } } } + fn handle_pixel_scroll(&mut self, renderer: &Renderer, pixel_x: f32, pixel_y: f32) { + self.handle_line_scroll( + pixel_x / renderer.font_width as f32, + pixel_y / renderer.font_height as f32, + ); + } + pub fn handle_event( &mut self, event: &Event<()>, @@ -263,15 +284,15 @@ impl MouseManager { .. }, .. - } => self.handle_mouse_wheel(*x as f32, *y as f32), + } => self.handle_line_scroll(*x, *y), Event::WindowEvent { event: WindowEvent::MouseWheel { - delta: MouseScrollDelta::PixelDelta(position), + delta: MouseScrollDelta::PixelDelta(delta), .. }, .. - } => self.handle_mouse_wheel(position.x as f32, position.y as f32), + } => self.handle_pixel_scroll(renderer, delta.x as f32, delta.y as f32), Event::WindowEvent { event: WindowEvent::MouseInput {