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.
This commit is contained in:
Joscha 2022-09-25 19:31:01 +02:00
parent 9aac9f6fdd
commit 4dde87d805
2 changed files with 8 additions and 4 deletions

View file

@ -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

View file

@ -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<Id> Cursor<Id> {
#[derive(Debug)]
struct InnerListState<Id> {
rows: Vec<Option<Id>>,
/// Offset of the first line visible on the screen.
offset: usize,
cursor: Option<Cursor<Id>>,
make_cursor_visible: bool,
}
@ -47,7 +48,7 @@ impl<Id> InnerListState<Id> {
rows: vec![],
offset: 0,
cursor: None,
make_cursor_visible: false,
make_cursor_visible: true,
}
}
}
@ -172,7 +173,7 @@ impl<Id: Clone + Eq> InnerListState<Id> {
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<Id> ListState<Id> {
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;
}
}