mirror of https://github.com/sgoudham/neovide.git
formatting fixes
parent
f5b65a6770
commit
407a7e24a9
@ -1,240 +1,288 @@
|
|||||||
use glutin::{
|
use glutin::{
|
||||||
self,
|
self,
|
||||||
WindowedContext,
|
dpi::{LogicalPosition, PhysicalPosition},
|
||||||
dpi::{
|
event::{ElementState, Event, MouseButton, MouseScrollDelta, WindowEvent},
|
||||||
LogicalPosition,
|
PossiblyCurrent, WindowedContext,
|
||||||
PhysicalPosition,
|
};
|
||||||
},
|
use skia_safe::Rect;
|
||||||
event::{
|
|
||||||
ElementState,
|
use crate::bridge::UiCommand;
|
||||||
Event,
|
use crate::channel_utils::LoggingTx;
|
||||||
MouseButton,
|
use crate::renderer::{Renderer, WindowDrawDetails};
|
||||||
MouseScrollDelta,
|
use crate::settings::SETTINGS;
|
||||||
WindowEvent,
|
use crate::window::WindowSettings;
|
||||||
},
|
|
||||||
PossiblyCurrent
|
fn clamp_position(
|
||||||
};
|
position: LogicalPosition<f32>,
|
||||||
use skia_safe::Rect;
|
region: Rect,
|
||||||
|
font_width: u64,
|
||||||
use crate::channel_utils::LoggingTx;
|
font_height: u64,
|
||||||
use crate::bridge::UiCommand;
|
) -> LogicalPosition<f32> {
|
||||||
use crate::renderer::{Renderer, WindowDrawDetails};
|
LogicalPosition::new(
|
||||||
use crate::settings::SETTINGS;
|
position
|
||||||
use crate::window::WindowSettings;
|
.x
|
||||||
|
.min(region.right - font_width as f32)
|
||||||
fn clamp_position(position: LogicalPosition<f32>, region: Rect, font_width: u64, font_height: u64) -> LogicalPosition<f32> {
|
.max(region.left),
|
||||||
LogicalPosition::new(
|
position
|
||||||
position.x.min(region.right - font_width as f32).max(region.left),
|
.y
|
||||||
position.y.min(region.bottom - font_height as f32).max(region.top))
|
.min(region.bottom - font_height as f32)
|
||||||
}
|
.max(region.top),
|
||||||
|
)
|
||||||
fn to_grid_coords(position: LogicalPosition<f32>, font_width: u64, font_height: u64) -> LogicalPosition<u32> {
|
}
|
||||||
LogicalPosition::new(
|
|
||||||
(position.x as u64 / font_width) as u32,
|
fn to_grid_coords(
|
||||||
(position.y as u64 / font_height) as u32)
|
position: LogicalPosition<f32>,
|
||||||
}
|
font_width: u64,
|
||||||
|
font_height: u64,
|
||||||
pub struct MouseManager {
|
) -> LogicalPosition<u32> {
|
||||||
command_sender: LoggingTx<UiCommand>,
|
LogicalPosition::new(
|
||||||
dragging: bool,
|
(position.x as u64 / font_width) as u32,
|
||||||
has_moved: bool,
|
(position.y as u64 / font_height) as u32,
|
||||||
position: LogicalPosition<u32>,
|
)
|
||||||
relative_position: LogicalPosition<u32>,
|
}
|
||||||
drag_position: LogicalPosition<u32>,
|
|
||||||
window_details_under_mouse: Option<WindowDrawDetails>,
|
pub struct MouseManager {
|
||||||
pub enabled: bool,
|
command_sender: LoggingTx<UiCommand>,
|
||||||
}
|
dragging: bool,
|
||||||
|
has_moved: bool,
|
||||||
impl MouseManager {
|
position: LogicalPosition<u32>,
|
||||||
pub fn new(command_sender: LoggingTx<UiCommand>) -> MouseManager {
|
relative_position: LogicalPosition<u32>,
|
||||||
MouseManager {
|
drag_position: LogicalPosition<u32>,
|
||||||
command_sender,
|
window_details_under_mouse: Option<WindowDrawDetails>,
|
||||||
dragging: false,
|
pub enabled: bool,
|
||||||
has_moved: false,
|
}
|
||||||
position: LogicalPosition::new(0, 0),
|
|
||||||
relative_position: LogicalPosition::new(0, 0),
|
impl MouseManager {
|
||||||
drag_position: LogicalPosition::new(0, 0),
|
pub fn new(command_sender: LoggingTx<UiCommand>) -> MouseManager {
|
||||||
window_details_under_mouse: None,
|
MouseManager {
|
||||||
enabled: true,
|
command_sender,
|
||||||
}
|
dragging: false,
|
||||||
}
|
has_moved: false,
|
||||||
|
position: LogicalPosition::new(0, 0),
|
||||||
fn handle_pointer_motion(&mut self, x: i32, y: i32, renderer: &Renderer, windowed_context: &WindowedContext<PossiblyCurrent>) {
|
relative_position: LogicalPosition::new(0, 0),
|
||||||
let size = windowed_context.window().inner_size();
|
drag_position: LogicalPosition::new(0, 0),
|
||||||
if x < 0 || x as u32 >= size.width || y < 0 || y as u32 >= size.height {
|
window_details_under_mouse: None,
|
||||||
return;
|
enabled: true,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let logical_position: LogicalPosition<f32> = PhysicalPosition::new(x as u32, y as u32)
|
|
||||||
.to_logical(windowed_context.window().scale_factor());
|
fn handle_pointer_motion(
|
||||||
|
&mut self,
|
||||||
// If dragging, the relevant window (the one which we send all commands to) is the one
|
x: i32,
|
||||||
// which the mouse drag started on. Otherwise its the top rendered window
|
y: i32,
|
||||||
let relevant_window_details = if self.dragging {
|
renderer: &Renderer,
|
||||||
renderer.window_regions.iter()
|
windowed_context: &WindowedContext<PossiblyCurrent>,
|
||||||
.find(|details| details.id == self.window_details_under_mouse.as_ref().expect("If dragging, there should be a window details recorded").id)
|
) {
|
||||||
} else {
|
let size = windowed_context.window().inner_size();
|
||||||
// the rendered window regions are sorted by draw order, so the earlier windows in the
|
if x < 0 || x as u32 >= size.width || y < 0 || y as u32 >= size.height {
|
||||||
// list are drawn under the later ones
|
return;
|
||||||
renderer.window_regions.iter().filter(|details| {
|
}
|
||||||
logical_position.x >= details.region.left &&
|
|
||||||
logical_position.x < details.region.right &&
|
let logical_position: LogicalPosition<f32> = PhysicalPosition::new(x as u32, y as u32)
|
||||||
logical_position.y >= details.region.top &&
|
.to_logical(windowed_context.window().scale_factor());
|
||||||
logical_position.y < details.region.bottom
|
|
||||||
}).last()
|
// If dragging, the relevant window (the one which we send all commands to) is the one
|
||||||
};
|
// which the mouse drag started on. Otherwise its the top rendered window
|
||||||
|
let relevant_window_details = if self.dragging {
|
||||||
let global_bounds = relevant_window_details.map(|details| details.region).unwrap_or(Rect::from_wh(size.width as f32, size.height as f32));
|
renderer.window_regions.iter().find(|details| {
|
||||||
let clamped_position = clamp_position(logical_position, global_bounds, renderer.font_width, renderer.font_height);
|
details.id
|
||||||
|
== self
|
||||||
self.position = to_grid_coords(clamped_position, renderer.font_width, renderer.font_height);
|
.window_details_under_mouse
|
||||||
|
.as_ref()
|
||||||
if let Some(relevant_window_details) = relevant_window_details {
|
.expect("If dragging, there should be a window details recorded")
|
||||||
let relative_position = LogicalPosition::new(
|
.id
|
||||||
clamped_position.x - relevant_window_details.region.left,
|
})
|
||||||
clamped_position.y - relevant_window_details.region.top);
|
} else {
|
||||||
self.relative_position = to_grid_coords(relative_position, renderer.font_width, renderer.font_height);
|
// the rendered window regions are sorted by draw order, so the earlier windows in the
|
||||||
|
// list are drawn under the later ones
|
||||||
let previous_position = self.drag_position;
|
renderer
|
||||||
// Until https://github.com/neovim/neovim/pull/12667 is merged, we have to special
|
.window_regions
|
||||||
// case non floating windows. Floating windows correctly transform mouse positions
|
.iter()
|
||||||
// into grid coordinates, but non floating windows do not.
|
.filter(|details| {
|
||||||
self.drag_position = if relevant_window_details.floating_order.is_some() {
|
logical_position.x >= details.region.left
|
||||||
// Floating windows handle relative grid coordinates just fine
|
&& logical_position.x < details.region.right
|
||||||
self.relative_position.clone()
|
&& logical_position.y >= details.region.top
|
||||||
} else {
|
&& logical_position.y < details.region.bottom
|
||||||
// Non floating windows need global coordinates
|
})
|
||||||
self.position.clone()
|
.last()
|
||||||
};
|
};
|
||||||
|
|
||||||
let has_moved = self.drag_position != previous_position;
|
let global_bounds = relevant_window_details
|
||||||
|
.map(|details| details.region)
|
||||||
// If dragging and we haven't already sent a position, send a drag command
|
.unwrap_or(Rect::from_wh(size.width as f32, size.height as f32));
|
||||||
if self.dragging && has_moved {
|
let clamped_position = clamp_position(
|
||||||
self.command_sender
|
logical_position,
|
||||||
.send(UiCommand::Drag {
|
global_bounds,
|
||||||
grid_id: relevant_window_details.id,
|
renderer.font_width,
|
||||||
position: self.drag_position.into(),
|
renderer.font_height,
|
||||||
})
|
);
|
||||||
.ok();
|
|
||||||
} else {
|
self.position = to_grid_coords(clamped_position, renderer.font_width, renderer.font_height);
|
||||||
// otherwise, update the window_id_under_mouse to match the one selected
|
|
||||||
self.window_details_under_mouse = Some(relevant_window_details.clone());
|
if let Some(relevant_window_details) = relevant_window_details {
|
||||||
}
|
let relative_position = LogicalPosition::new(
|
||||||
|
clamped_position.x - relevant_window_details.region.left,
|
||||||
self.has_moved = self.dragging && (self.has_moved || has_moved);
|
clamped_position.y - relevant_window_details.region.top,
|
||||||
}
|
);
|
||||||
}
|
self.relative_position =
|
||||||
|
to_grid_coords(relative_position, renderer.font_width, renderer.font_height);
|
||||||
fn handle_pointer_transition(&mut self, down: bool) {
|
|
||||||
// For some reason pointer down is handled differently from pointer up and drag.
|
let previous_position = self.drag_position;
|
||||||
// Floating windows: relative coordinates are great.
|
// Until https://github.com/neovim/neovim/pull/12667 is merged, we have to special
|
||||||
// Non floating windows: rather than global coordinates, relative are needed
|
// case non floating windows. Floating windows correctly transform mouse positions
|
||||||
if self.enabled {
|
// into grid coordinates, but non floating windows do not.
|
||||||
if let Some(details) = &self.window_details_under_mouse {
|
self.drag_position = if relevant_window_details.floating_order.is_some() {
|
||||||
let action = if down {
|
// Floating windows handle relative grid coordinates just fine
|
||||||
"press".to_owned()
|
self.relative_position.clone()
|
||||||
} else {
|
} else {
|
||||||
"release".to_owned()
|
// Non floating windows need global coordinates
|
||||||
};
|
self.position.clone()
|
||||||
|
};
|
||||||
let position = if !down && self.has_moved {
|
|
||||||
self.drag_position
|
let has_moved = self.drag_position != previous_position;
|
||||||
} else {
|
|
||||||
self.relative_position
|
// If dragging and we haven't already sent a position, send a drag command
|
||||||
};
|
if self.dragging && has_moved {
|
||||||
|
self.command_sender
|
||||||
self.command_sender
|
.send(UiCommand::Drag {
|
||||||
.send(UiCommand::MouseButton {
|
grid_id: relevant_window_details.id,
|
||||||
action,
|
position: self.drag_position.into(),
|
||||||
grid_id: details.id,
|
})
|
||||||
position: position.into(),
|
.ok();
|
||||||
})
|
} else {
|
||||||
.ok();
|
// otherwise, update the window_id_under_mouse to match the one selected
|
||||||
}
|
self.window_details_under_mouse = Some(relevant_window_details.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.dragging = down;
|
self.has_moved = self.dragging && (self.has_moved || has_moved);
|
||||||
|
}
|
||||||
if !self.dragging {
|
}
|
||||||
self.has_moved = false;
|
|
||||||
}
|
fn handle_pointer_transition(&mut self, down: bool) {
|
||||||
}
|
// For some reason pointer down is handled differently from pointer up and drag.
|
||||||
|
// Floating windows: relative coordinates are great.
|
||||||
fn handle_mouse_wheel(&mut self, x: f32, y: f32) {
|
// Non floating windows: rather than global coordinates, relative are needed
|
||||||
if !self.enabled {
|
if self.enabled {
|
||||||
return;
|
if let Some(details) = &self.window_details_under_mouse {
|
||||||
}
|
let action = if down {
|
||||||
|
"press".to_owned()
|
||||||
let scroll_dead_zone = SETTINGS.get::<WindowSettings>().scroll_dead_zone;
|
} else {
|
||||||
|
"release".to_owned()
|
||||||
let vertical_input_type = match y {
|
};
|
||||||
_ if y > scroll_dead_zone => Some("up"),
|
|
||||||
_ if y < -scroll_dead_zone => Some("down"),
|
let position = if !down && self.has_moved {
|
||||||
_ => None,
|
self.drag_position
|
||||||
};
|
} else {
|
||||||
|
self.relative_position
|
||||||
if let Some(input_type) = vertical_input_type {
|
};
|
||||||
self.command_sender
|
|
||||||
.send(UiCommand::Scroll {
|
self.command_sender
|
||||||
direction: input_type.to_string(),
|
.send(UiCommand::MouseButton {
|
||||||
grid_id: self.window_details_under_mouse.as_ref().map(|details| details.id).unwrap_or(0),
|
action,
|
||||||
position: self.drag_position.into(),
|
grid_id: details.id,
|
||||||
})
|
position: position.into(),
|
||||||
.ok();
|
})
|
||||||
}
|
.ok();
|
||||||
|
}
|
||||||
let horizontal_input_type = match x {
|
}
|
||||||
_ if x > scroll_dead_zone => Some("right"),
|
|
||||||
_ if x < -scroll_dead_zone => Some("left"),
|
self.dragging = down;
|
||||||
_ => None,
|
|
||||||
};
|
if !self.dragging {
|
||||||
|
self.has_moved = false;
|
||||||
if let Some(input_type) = horizontal_input_type {
|
}
|
||||||
self.command_sender
|
}
|
||||||
.send(UiCommand::Scroll {
|
|
||||||
direction: input_type.to_string(),
|
fn handle_mouse_wheel(&mut self, x: f32, y: f32) {
|
||||||
grid_id: self.window_details_under_mouse.as_ref().map(|details| details.id).unwrap_or(0),
|
if !self.enabled {
|
||||||
position: self.drag_position.into(),
|
return;
|
||||||
})
|
}
|
||||||
.ok();
|
|
||||||
}
|
let scroll_dead_zone = SETTINGS.get::<WindowSettings>().scroll_dead_zone;
|
||||||
}
|
|
||||||
|
let vertical_input_type = match y {
|
||||||
pub fn handle_event(&mut self, event: &Event<()>, renderer: &Renderer, windowed_context: &WindowedContext<PossiblyCurrent>) {
|
_ if y > scroll_dead_zone => Some("up"),
|
||||||
match event {
|
_ if y < -scroll_dead_zone => Some("down"),
|
||||||
Event::WindowEvent {
|
_ => None,
|
||||||
event: WindowEvent::CursorMoved { position, .. },
|
};
|
||||||
..
|
|
||||||
} => self.handle_pointer_motion(
|
if let Some(input_type) = vertical_input_type {
|
||||||
position.x as i32, position.y as i32,
|
self.command_sender
|
||||||
renderer, windowed_context),
|
.send(UiCommand::Scroll {
|
||||||
Event::WindowEvent {
|
direction: input_type.to_string(),
|
||||||
event:
|
grid_id: self
|
||||||
WindowEvent::MouseWheel {
|
.window_details_under_mouse
|
||||||
delta: MouseScrollDelta::LineDelta(x, y),
|
.as_ref()
|
||||||
..
|
.map(|details| details.id)
|
||||||
},
|
.unwrap_or(0),
|
||||||
..
|
position: self.drag_position.into(),
|
||||||
} => self.handle_mouse_wheel(*x as f32, *y as f32),
|
})
|
||||||
Event::WindowEvent {
|
.ok();
|
||||||
event:
|
}
|
||||||
WindowEvent::MouseWheel {
|
|
||||||
delta: MouseScrollDelta::PixelDelta(logical_position),
|
let horizontal_input_type = match x {
|
||||||
..
|
_ if x > scroll_dead_zone => Some("right"),
|
||||||
},
|
_ if x < -scroll_dead_zone => Some("left"),
|
||||||
..
|
_ => None,
|
||||||
} => self.handle_mouse_wheel(logical_position.x as f32, logical_position.y as f32),
|
};
|
||||||
Event::WindowEvent {
|
|
||||||
event:
|
if let Some(input_type) = horizontal_input_type {
|
||||||
WindowEvent::MouseInput {
|
self.command_sender
|
||||||
button: MouseButton::Left,
|
.send(UiCommand::Scroll {
|
||||||
state,
|
direction: input_type.to_string(),
|
||||||
..
|
grid_id: self
|
||||||
},
|
.window_details_under_mouse
|
||||||
..
|
.as_ref()
|
||||||
} => self.handle_pointer_transition(state == &ElementState::Pressed),
|
.map(|details| details.id)
|
||||||
_ => {}
|
.unwrap_or(0),
|
||||||
}
|
position: self.drag_position.into(),
|
||||||
}
|
})
|
||||||
}
|
.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,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => self.handle_pointer_transition(state == &ElementState::Pressed),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue