From cb2fc22c5a57a686029e8f0b8efc0238ed541413 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 31 Jul 2022 23:09:39 +0200 Subject: [PATCH] Scroll with ctrl+e and ctrl+d --- src/ui/chat/tree.rs | 11 +++++++---- src/ui/chat/tree/cursor.rs | 17 +++++++++++++++++ src/ui/chat/tree/layout.rs | 5 ++++- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/ui/chat/tree.rs b/src/ui/chat/tree.rs index aed3381..52c34cf 100644 --- a/src/ui/chat/tree.rs +++ b/src/ui/chat/tree.rs @@ -34,6 +34,10 @@ struct InnerTreeViewState> { /// to a different message such that it remains visible. make_cursor_visible: bool, + /// Scroll the view on the next render. Positive values scroll up and + /// negative values scroll down. + scroll: i32, + editor: EditorState, } @@ -45,6 +49,7 @@ impl> InnerTreeViewState { last_cursor_line: 0, cursor: Cursor::Bottom, make_cursor_visible: false, + scroll: 0, editor: EditorState::new(), } } @@ -56,11 +61,9 @@ impl> InnerTreeViewState { KeyCode::Char('g') | KeyCode::Home => self.move_cursor_to_top().await, KeyCode::Char('G') | KeyCode::End => self.move_cursor_to_bottom().await, KeyCode::Char('y') if event.modifiers == KeyModifiers::CONTROL => { - self.last_cursor_line += 1; - } - KeyCode::Char('e') if event.modifiers == KeyModifiers::CONTROL => { - self.last_cursor_line -= 1; + self.scroll_up(1).await } + KeyCode::Char('e') if event.modifiers == KeyModifiers::CONTROL => self.scroll_down(1), _ => return false, } true diff --git a/src/ui/chat/tree/cursor.rs b/src/ui/chat/tree/cursor.rs index 1b9b7f0..25c5aff 100644 --- a/src/ui/chat/tree/cursor.rs +++ b/src/ui/chat/tree/cursor.rs @@ -223,6 +223,23 @@ impl> InnerTreeViewState { // Not really necessary; only here for consistency with other methods self.make_cursor_visible = true; } + + pub async fn scroll_up(&mut self, amount: i32) { + self.scroll += amount; + + if let Cursor::Bottom = self.cursor { + // Move cursor to bottommost message, if it exists + if let Some(mut id) = self.store.last_tree_id().await { + let tree = self.store.tree(&id).await; + while Self::find_last_child(&tree, &mut id) {} + self.cursor = Cursor::Msg(id); + } + } + } + + pub fn scroll_down(&mut self, amount: i32) { + self.scroll -= amount; + } } /* diff --git a/src/ui/chat/tree/layout.rs b/src/ui/chat/tree/layout.rs index e716985..ce35c57 100644 --- a/src/ui/chat/tree/layout.rs +++ b/src/ui/chat/tree/layout.rs @@ -285,7 +285,8 @@ impl> InnerTreeViewState { // The basic idea is this: // // First, layout a full screen of blocks around self.last_cursor, using - // self.last_cursor_line for offset positioning. + // self.last_cursor_line for offset positioning. At this point, any + // outstanding scrolling is performed as well. // // Then, check if self.cursor is somewhere in these blocks. If it is, we // now know the position of our own cursor. If it is not, it has jumped @@ -305,6 +306,7 @@ impl> InnerTreeViewState { let mut blocks = self .layout_initial_seed(frame, &last_cursor_path, &cursor_path) .await; + blocks.blocks_mut().offset(self.scroll); self.fill_screen_and_clamp_scrolling(frame, &mut blocks) .await; @@ -329,6 +331,7 @@ impl> InnerTreeViewState { self.last_cursor = self.cursor.clone(); self.last_cursor_line = self.cursor_line(&blocks); self.make_cursor_visible = false; + self.scroll = 0; blocks }