Accumulate mouse scrolls for smoother scrolling
This commit is contained in:
parent
222d3fb0a5
commit
1743730fd9
2 changed files with 62 additions and 27 deletions
|
|
@ -11,6 +11,8 @@ const SCROLL_SPEED: u32 = 3;
|
||||||
pub struct MouseReporter {
|
pub struct MouseReporter {
|
||||||
last_movment_x: Option<u32>,
|
last_movment_x: Option<u32>,
|
||||||
last_movment_y: Option<u32>,
|
last_movment_y: Option<u32>,
|
||||||
|
accumulated_scroll_x: f32,
|
||||||
|
accumulated_scroll_y: f32,
|
||||||
button: Option<Button>,
|
button: Option<Button>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,44 +169,71 @@ impl MouseReporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn report_sgr_mouse_wheel_scroll(
|
pub fn sgr_mouse_wheel_scroll(
|
||||||
terminal: &Terminal,
|
&mut self,
|
||||||
term_cell_width: f32,
|
term_cell_width: f32,
|
||||||
term_cell_height: f32,
|
term_cell_height: f32,
|
||||||
delta: ScrollDelta,
|
delta: ScrollDelta,
|
||||||
modifiers: &Modifiers,
|
modifiers: &Modifiers,
|
||||||
x: u32,
|
x: u32,
|
||||||
y: u32,
|
y: u32,
|
||||||
) {
|
) -> impl Iterator<Item = Vec<u8>> {
|
||||||
let (delta_x, delta_y) = match delta {
|
let (lines_x, lines_y) = match delta {
|
||||||
ScrollDelta::Lines { x, y } => (x, y),
|
ScrollDelta::Lines { x, y } => (x as i32, y as i32),
|
||||||
ScrollDelta::Pixels { x, y } => (x / term_cell_width, y / term_cell_height),
|
ScrollDelta::Pixels { x, y } => {
|
||||||
};
|
//Accumulate change
|
||||||
let (mut button_no, amount) = if delta_y > 0.0 {
|
self.accumulated_scroll_x += x / term_cell_width;
|
||||||
(64, delta_y.abs()) //Wheel UP
|
self.accumulated_scroll_y += y / term_cell_height;
|
||||||
} else if delta_y < 0.0 {
|
|
||||||
(65, delta_y.abs()) //Wheel Down
|
//Resolve lines crossed
|
||||||
} else if delta_x < 0.0 {
|
let lines_x = self.accumulated_scroll_x as i32;
|
||||||
(66, delta_x.abs()) //Wheel Left
|
let lines_y = self.accumulated_scroll_y as i32;
|
||||||
} else if delta_x > 0.0 {
|
|
||||||
(67, delta_x.abs()) //Wheel Right
|
//Subtract accounted lines from accumulators
|
||||||
} else {
|
self.accumulated_scroll_x -= lines_x as f32;
|
||||||
return;
|
self.accumulated_scroll_y -= lines_y as f32;
|
||||||
|
|
||||||
|
(lines_x, lines_y)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Resolve modifier flags
|
||||||
|
let mut modifier_flags = 0;
|
||||||
|
|
||||||
if modifiers.shift() {
|
if modifiers.shift() {
|
||||||
button_no += 4;
|
modifier_flags += 4;
|
||||||
}
|
}
|
||||||
if modifiers.alt() {
|
if modifiers.alt() {
|
||||||
button_no += 8;
|
modifier_flags += 8;
|
||||||
}
|
}
|
||||||
if modifiers.control() {
|
if modifiers.control() {
|
||||||
button_no += 16;
|
modifier_flags += 16;
|
||||||
}
|
};
|
||||||
let term_code = format!("\x1b[<{};{};{}M", button_no, x + 1, y + 1);
|
|
||||||
for _ in 0..amount as u32 {
|
//Resolve base inputs
|
||||||
terminal.input_no_scroll(term_code.as_bytes().to_vec());
|
let button_no_y = match lines_y.cmp(&0) {
|
||||||
}
|
std::cmp::Ordering::Less => 65, //Wheel Down
|
||||||
|
std::cmp::Ordering::Greater => 64, //Wheel Up
|
||||||
|
std::cmp::Ordering::Equal => 0, //Unused
|
||||||
|
};
|
||||||
|
|
||||||
|
let button_no_x = match lines_x.cmp(&0) {
|
||||||
|
std::cmp::Ordering::Less => 66, //Wheel Left
|
||||||
|
std::cmp::Ordering::Greater => 67, //Wheel Right
|
||||||
|
std::cmp::Ordering::Equal => 0, //Unused
|
||||||
|
};
|
||||||
|
|
||||||
|
//Generate term codes
|
||||||
|
let x_iter = std::iter::repeat_n(button_no_x, lines_x.unsigned_abs() as _);
|
||||||
|
let y_iter = std::iter::repeat_n(button_no_y, lines_y.unsigned_abs() as _);
|
||||||
|
|
||||||
|
x_iter
|
||||||
|
.chain(y_iter)
|
||||||
|
.map(move |button_no| button_no + modifier_flags)
|
||||||
|
.map(move |button_no| {
|
||||||
|
let term_code = format!("\x1b[<{};{};{}M", button_no, x + 1, y + 1);
|
||||||
|
term_code.as_bytes().to_vec()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//Emulate mouse wheel scroll with up/down arrows. Using mouse spec uses
|
//Emulate mouse wheel scroll with up/down arrows. Using mouse spec uses
|
||||||
|
|
|
||||||
|
|
@ -879,6 +879,7 @@ impl Terminal {
|
||||||
) {
|
) {
|
||||||
let term_lock = self.term.lock();
|
let term_lock = self.term.lock();
|
||||||
let mode = term_lock.mode();
|
let mode = term_lock.mode();
|
||||||
|
|
||||||
#[allow(clippy::collapsible_else_if)]
|
#[allow(clippy::collapsible_else_if)]
|
||||||
if mode.contains(TermMode::SGR_MOUSE) {
|
if mode.contains(TermMode::SGR_MOUSE) {
|
||||||
if let Some(code) = self.mouse_reporter.sgr_mouse_code(event, modifiers, x, y) {
|
if let Some(code) = self.mouse_reporter.sgr_mouse_code(event, modifiers, x, y) {
|
||||||
|
|
@ -896,6 +897,7 @@ impl Terminal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_mouse(
|
pub fn scroll_mouse(
|
||||||
&mut self,
|
&mut self,
|
||||||
delta: ScrollDelta,
|
delta: ScrollDelta,
|
||||||
|
|
@ -905,9 +907,9 @@ impl Terminal {
|
||||||
) {
|
) {
|
||||||
let term_lock = self.term.lock();
|
let term_lock = self.term.lock();
|
||||||
let mode = term_lock.mode();
|
let mode = term_lock.mode();
|
||||||
|
|
||||||
if mode.contains(TermMode::SGR_MOUSE) {
|
if mode.contains(TermMode::SGR_MOUSE) {
|
||||||
MouseReporter::report_sgr_mouse_wheel_scroll(
|
let codes = self.mouse_reporter.sgr_mouse_wheel_scroll(
|
||||||
self,
|
|
||||||
self.size().cell_width,
|
self.size().cell_width,
|
||||||
self.size().cell_height,
|
self.size().cell_height,
|
||||||
delta,
|
delta,
|
||||||
|
|
@ -915,6 +917,10 @@ impl Terminal {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for code in codes {
|
||||||
|
self.notifier.notify(code);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
MouseReporter::report_mouse_wheel_as_arrows(
|
MouseReporter::report_mouse_wheel_as_arrows(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue