From 4dde87d805306ad83b4980ce32ab25312e68b7eb Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 25 Sep 2022 19:31:01 +0200 Subject: [PATCH] Fix list cursor when item moves off-screen When a list scrolls or changes in such a way that the cursor item moves off-screen, the cursor would jump to the closest visible item. It makes more sense for the cursor to remain on its selected item and for the list to scroll instead. That way, it is less likely for the user to perform an action on the wrong list item if they press a key while the list is changing. --- CHANGELOG.md | 1 + src/ui/widgets/list.rs | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cffe55..5f6df89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Procedure when bumping the version number: ### Fixed - Cursor being visible through popups +- Cursor in lists when highlighted item moves off-screen ## v0.4.0 - 2022-09-01 diff --git a/src/ui/widgets/list.rs b/src/ui/widgets/list.rs index 6a586a1..8df110c 100644 --- a/src/ui/widgets/list.rs +++ b/src/ui/widgets/list.rs @@ -1,5 +1,3 @@ -// TODO Fix scrolling by focusing on the cursor like in chat::tree - use std::sync::Arc; use async_trait::async_trait; @@ -36,7 +34,10 @@ impl Cursor { #[derive(Debug)] struct InnerListState { rows: Vec>, + + /// Offset of the first line visible on the screen. offset: usize, + cursor: Option>, make_cursor_visible: bool, } @@ -47,7 +48,7 @@ impl InnerListState { rows: vec![], offset: 0, cursor: None, - make_cursor_visible: false, + make_cursor_visible: true, } } } @@ -172,7 +173,7 @@ impl InnerListState { self.clamp_scrolling(height); self.move_cursor_to_make_it_visible(height); } - self.make_cursor_visible = false; + self.make_cursor_visible = true; } } @@ -190,11 +191,13 @@ impl ListState { pub fn scroll_up(&mut self, amount: usize) { let mut guard = self.0.lock(); guard.offset = guard.offset.saturating_sub(amount); + guard.make_cursor_visible = false; } pub fn scroll_down(&mut self, amount: usize) { let mut guard = self.0.lock(); guard.offset = guard.offset.saturating_add(amount); + guard.make_cursor_visible = false; } }