Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use new scroll delta field in viewport event for smooth scrolling #1827

Merged
merged 2 commits into from
Apr 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 5 additions & 15 deletions src/bridge/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ pub enum RedrawEvent {
current_line: f64,
current_column: f64,
line_count: Option<f64>,
scroll_delta: Option<f64>,
},
CommandLineShow {
content: StyledContent,
Expand Down Expand Up @@ -642,20 +643,14 @@ fn parse_win_float_pos(win_float_pos_arguments: Vec<Value>) -> Result<RedrawEven
let ([grid, _window, anchor, anchor_grid, anchor_row, anchor_column, focusable], [sort_order]) =
extract_values_with_optional(win_float_pos_arguments)?;

let sort_order = if let Some(sort_order) = sort_order {
Some(parse_u64(sort_order)?)
} else {
None
};

Ok(RedrawEvent::WindowFloatPosition {
grid: parse_u64(grid)?,
anchor: parse_window_anchor(anchor)?,
anchor_grid: parse_u64(anchor_grid)?,
anchor_row: parse_f64(anchor_row)?,
anchor_column: parse_f64(anchor_column)?,
focusable: parse_bool(focusable)?,
sort_order,
sort_order: sort_order.map(parse_u64).transpose()?,
})
}

Expand Down Expand Up @@ -697,22 +692,17 @@ fn parse_msg_set_pos(msg_set_pos_arguments: Vec<Value>) -> Result<RedrawEvent> {
fn parse_win_viewport(win_viewport_arguments: Vec<Value>) -> Result<RedrawEvent> {
let (
[grid, _window, top_line, bottom_line, current_line, current_column],
[line_count, _scroll_delta],
[line_count, scroll_delta],
) = extract_values_with_optional(win_viewport_arguments)?;

let line_count = if let Some(line_count) = line_count {
Some(parse_f64(line_count)?)
} else {
None
};

Ok(RedrawEvent::WindowViewport {
grid: parse_u64(grid)?,
top_line: parse_f64(top_line)?,
bottom_line: parse_f64(bottom_line)?,
current_line: parse_f64(current_line)?,
current_column: parse_f64(current_column)?,
line_count,
line_count: line_count.map(parse_f64).transpose()?,
scroll_delta: scroll_delta.map(parse_f64).transpose()?,
})
}

Expand Down
10 changes: 5 additions & 5 deletions src/editor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,10 @@ impl Editor {
}
RedrawEvent::WindowViewport {
grid,
top_line,
bottom_line,
// Don't send viewport events if they don't have a scroll delta
scroll_delta: Some(scroll_delta),
..
} => self.send_updated_viewport(grid, top_line, bottom_line),
} => self.send_updated_viewport(grid, scroll_delta),
_ => {}
},
EditorCommand::RedrawScreen => self.redraw_screen(),
Expand Down Expand Up @@ -463,9 +463,9 @@ impl Editor {
}
}

fn send_updated_viewport(&mut self, grid: u64, top_line: f64, bottom_line: f64) {
fn send_updated_viewport(&mut self, grid: u64, scroll_delta: f64) {
if let Some(window) = self.windows.get_mut(&grid) {
window.update_viewport(top_line, bottom_line);
window.update_viewport(scroll_delta);
} else {
trace!("viewport event received before window initialized");
}
Expand Down
7 changes: 2 additions & 5 deletions src/editor/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,8 @@ impl Window {
self.send_command(WindowDrawCommand::Close);
}

pub fn update_viewport(&self, top_line: f64, bottom_line: f64) {
self.send_command(WindowDrawCommand::Viewport {
top_line,
bottom_line,
});
pub fn update_viewport(&self, scroll_delta: f64) {
self.send_command(WindowDrawCommand::Viewport { scroll_delta });
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/cursor_renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ impl CursorRenderer {
if let Some(window) = windows.get(&self.cursor.parent_window_id) {
let grid_x = cursor_grid_x as f32 + window.grid_current_position.x;
let mut grid_y = cursor_grid_y as f32 + window.grid_current_position.y
- (window.current_scroll - window.current_surface.top_line as f32);
- (window.current_scroll - window.current_surface.vertical_position);

// Prevent the cursor from targeting a position outside its current window. Since only
// the vertical direction is effected by scrolling, we only have to clamp the vertical
Expand Down
34 changes: 18 additions & 16 deletions src/renderer/rendered_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ pub enum WindowDrawCommand {
Hide,
Close,
Viewport {
top_line: f64,
bottom_line: f64,
scroll_delta: f64,
},
}

Expand Down Expand Up @@ -100,31 +99,34 @@ fn build_window_surface_with_grid_size(

pub struct LocatedSnapshot {
image: Image,
top_line: u64,
vertical_position: f32,
}

pub struct LocatedSurface {
surface: Surface,
pub top_line: u64,
pub vertical_position: f32,
}

impl LocatedSurface {
fn new(
parent_canvas: &mut Canvas,
grid_renderer: &GridRenderer,
grid_size: Dimensions,
top_line: u64,
vertical_position: f32,
) -> LocatedSurface {
let surface = build_window_surface_with_grid_size(parent_canvas, grid_renderer, grid_size);

LocatedSurface { surface, top_line }
LocatedSurface {
surface,
vertical_position,
}
}

fn snapshot(&mut self) -> LocatedSnapshot {
let image = self.surface.image_snapshot();
LocatedSnapshot {
image,
top_line: self.top_line,
vertical_position: self.vertical_position,
}
}
}
Expand Down Expand Up @@ -168,7 +170,7 @@ impl RenderedWindow {
grid_size: Dimensions,
padding: WindowPadding,
) -> RenderedWindow {
let current_surface = LocatedSurface::new(parent_canvas, grid_renderer, grid_size, 0);
let current_surface = LocatedSurface::new(parent_canvas, grid_renderer, grid_size, 0.);

RenderedWindow {
snapshots: VecDeque::new(),
Expand Down Expand Up @@ -306,8 +308,8 @@ impl RenderedWindow {

// Draw scrolling snapshots.
for snapshot in self.snapshots.iter_mut().rev() {
let scroll_offset = (snapshot.top_line * font_height) as f32
- (self.current_scroll * font_height as f32);
let scroll_offset =
(snapshot.vertical_position - self.current_scroll) * font_height as f32;
let image = &mut snapshot.image;
root_canvas.draw_image_rect(
image,
Expand All @@ -318,8 +320,8 @@ impl RenderedWindow {
}

// Draw current surface.
let scroll_offset = (self.current_surface.top_line * font_height) as f32
- (self.current_scroll * font_height as f32);
let scroll_offset =
(self.current_surface.vertical_position - self.current_scroll) * font_height as f32;
let snapshot = self.current_surface.surface.image_snapshot();
root_canvas.draw_image_rect(
snapshot,
Expand Down Expand Up @@ -503,20 +505,20 @@ impl RenderedWindow {
}
}
WindowDrawCommand::Hide => self.hidden = true,
WindowDrawCommand::Viewport { top_line, .. } => {
if self.current_surface.top_line != top_line as u64 {
WindowDrawCommand::Viewport { scroll_delta, .. } => {
if scroll_delta.abs() > f64::EPSILON {
let new_snapshot = self.current_surface.snapshot();
self.snapshots.push_back(new_snapshot);

if self.snapshots.len() > 5 {
self.snapshots.pop_front();
}

self.current_surface.top_line = top_line as u64;
self.current_surface.vertical_position += scroll_delta as f32;

// Set new target viewport position and initialize animation timer.
self.start_scroll = self.current_scroll;
self.scroll_destination = top_line as f32;
self.scroll_destination = self.current_surface.vertical_position;
self.scroll_t = 0.0;
}
}
Expand Down