From 80f3a3a2d27777136a0018caf79fa0c479ff844f Mon Sep 17 00:00:00 2001 From: Jared Moulton Date: Thu, 20 Jun 2024 01:29:16 -0600 Subject: [PATCH] Scroll top, middle, and bottom (#497) * Center editor * support scroll to center, top, bottom --- src/views/editor/mod.rs | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/views/editor/mod.rs b/src/views/editor/mod.rs index 4175bd75..4df01185 100644 --- a/src/views/editor/mod.rs +++ b/src/views/editor/mod.rs @@ -598,6 +598,52 @@ impl Editor { self.doc().run_command(self, &cmd, Some(lines), mods); } + pub fn center_window(&self) { + let viewport = self.viewport.get_untracked(); + // TODO: don't assume line height is constant + let line_height = f64::from(self.line_height(0)); + let offset = self.cursor.with_untracked(|cursor| cursor.offset()); + let (line, _col) = self.offset_to_line_col(offset); + + let viewport_center = viewport.height() / 2.0; + + let current_line_position = line as f64 * line_height; + + let desired_top = current_line_position - viewport_center + (line_height / 2.0); + + let scroll_delta = desired_top - viewport.y0; + + self.scroll_delta.set(Vec2::new(0.0, scroll_delta)); + } + + pub fn top_of_window(&self, scroll_off: usize) { + let viewport = self.viewport.get_untracked(); + // TODO: don't assume line height is constant + let line_height = f64::from(self.line_height(0)); + let offset = self.cursor.with_untracked(|cursor| cursor.offset()); + let (line, _col) = self.offset_to_line_col(offset); + + let desired_top = (line.saturating_sub(scroll_off)) as f64 * line_height; + + let scroll_delta = desired_top - viewport.y0; + + self.scroll_delta.set(Vec2::new(0.0, scroll_delta)); + } + + pub fn bottom_of_window(&self, scroll_off: usize) { + let viewport = self.viewport.get_untracked(); + // TODO: don't assume line height is constant + let line_height = f64::from(self.line_height(0)); + let offset = self.cursor.with_untracked(|cursor| cursor.offset()); + let (line, _col) = self.offset_to_line_col(offset); + + let desired_bottom = (line + scroll_off + 1) as f64 * line_height - viewport.height(); + + let scroll_delta = desired_bottom - viewport.y0; + + self.scroll_delta.set(Vec2::new(0.0, scroll_delta)); + } + pub fn scroll(&self, top_shift: f64, down: bool, count: usize, mods: Modifiers) { let viewport = self.viewport.get_untracked(); // TODO: don't assume line height is constant