Make room list behave more like chat
Accomplished by adding the same cursor movement and scrolling key bindings, as well as moving the cursor so it is visible when scrolling.
This commit is contained in:
parent
2c3586df7c
commit
f3b804347d
2 changed files with 66 additions and 15 deletions
|
|
@ -58,6 +58,14 @@ impl<Id: Clone> InnerListState<Id> {
|
|||
.find_map(|(i, r)| r.as_ref().map(|c| Cursor::new(c.clone(), i)))
|
||||
}
|
||||
|
||||
fn last_selectable(&self) -> Option<Cursor<Id>> {
|
||||
self.rows
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find_map(|(i, r)| r.as_ref().map(|c| Cursor::new(c.clone(), i)))
|
||||
}
|
||||
|
||||
fn selectable_at_or_before_index(&self, i: usize) -> Option<Cursor<Id>> {
|
||||
self.rows
|
||||
.iter()
|
||||
|
|
@ -92,7 +100,7 @@ impl<Id: Clone> InnerListState<Id> {
|
|||
.find_map(|(i, r)| r.as_ref().map(|c| Cursor::new(c.clone(), i)))
|
||||
}
|
||||
|
||||
fn make_cursor_visible(&mut self, height: usize) {
|
||||
fn scroll_so_cursor_is_visible(&mut self, height: usize) {
|
||||
if height == 0 {
|
||||
// Cursor can't be visible because nothing is visible
|
||||
return;
|
||||
|
|
@ -106,6 +114,25 @@ impl<Id: Clone> InnerListState<Id> {
|
|||
}
|
||||
}
|
||||
|
||||
fn move_cursor_to_make_it_visible(&mut self, height: usize) {
|
||||
if let Some(cursor) = &self.cursor {
|
||||
let min_idx = self.offset;
|
||||
let max_idx = self.offset.saturating_add(height).saturating_sub(1);
|
||||
|
||||
let new_cursor = if cursor.idx < min_idx {
|
||||
self.selectable_at_or_after_index(min_idx)
|
||||
} else if cursor.idx > max_idx {
|
||||
self.selectable_at_or_before_index(max_idx)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(new_cursor) = new_cursor {
|
||||
self.cursor = Some(new_cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn clamp_scrolling(&mut self, height: usize) {
|
||||
let min = 0;
|
||||
let max = self.rows.len().saturating_sub(height);
|
||||
|
|
@ -137,11 +164,13 @@ impl<Id: Clone + Eq> InnerListState<Id> {
|
|||
|
||||
self.fix_cursor();
|
||||
if self.make_cursor_visible {
|
||||
self.make_cursor_visible(height);
|
||||
self.make_cursor_visible = false;
|
||||
self.scroll_so_cursor_is_visible(height);
|
||||
self.clamp_scrolling(height);
|
||||
} else {
|
||||
self.clamp_scrolling(height);
|
||||
self.move_cursor_to_make_it_visible(height);
|
||||
}
|
||||
|
||||
self.clamp_scrolling(height);
|
||||
self.make_cursor_visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,14 +185,14 @@ impl<Id> ListState<Id> {
|
|||
List::new(self.0.clone())
|
||||
}
|
||||
|
||||
pub fn scroll_up(&mut self) {
|
||||
pub fn scroll_up(&mut self, amount: usize) {
|
||||
let mut guard = self.0.lock();
|
||||
guard.offset = guard.offset.saturating_sub(1);
|
||||
guard.offset = guard.offset.saturating_sub(amount);
|
||||
}
|
||||
|
||||
pub fn scroll_down(&mut self) {
|
||||
pub fn scroll_down(&mut self, amount: usize) {
|
||||
let mut guard = self.0.lock();
|
||||
guard.offset = guard.offset.saturating_add(1);
|
||||
guard.offset = guard.offset.saturating_add(amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -177,9 +206,9 @@ impl<Id: Clone> ListState<Id> {
|
|||
if let Some(cursor) = &guard.cursor {
|
||||
if let Some(new_cursor) = guard.selectable_before_index(cursor.idx) {
|
||||
guard.cursor = Some(new_cursor);
|
||||
guard.make_cursor_visible = true;
|
||||
}
|
||||
}
|
||||
guard.make_cursor_visible = true;
|
||||
}
|
||||
|
||||
pub fn move_cursor_down(&mut self) {
|
||||
|
|
@ -187,9 +216,25 @@ impl<Id: Clone> ListState<Id> {
|
|||
if let Some(cursor) = &guard.cursor {
|
||||
if let Some(new_cursor) = guard.selectable_after_index(cursor.idx) {
|
||||
guard.cursor = Some(new_cursor);
|
||||
guard.make_cursor_visible = true;
|
||||
}
|
||||
}
|
||||
guard.make_cursor_visible = true;
|
||||
}
|
||||
|
||||
pub fn move_cursor_to_top(&mut self) {
|
||||
let mut guard = self.0.lock();
|
||||
if let Some(new_cursor) = guard.first_selectable() {
|
||||
guard.cursor = Some(new_cursor);
|
||||
}
|
||||
guard.make_cursor_visible = true;
|
||||
}
|
||||
|
||||
pub fn move_cursor_to_bottom(&mut self) {
|
||||
let mut guard = self.0.lock();
|
||||
if let Some(new_cursor) = guard.last_selectable() {
|
||||
guard.cursor = Some(new_cursor);
|
||||
}
|
||||
guard.make_cursor_visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue