Add scrolloff
This commit is contained in:
parent
042f0ab78d
commit
4d1a42427a
1 changed files with 23 additions and 10 deletions
|
|
@ -8,6 +8,14 @@ use crate::ui::ChatMsg;
|
||||||
use super::tree_blocks::{BlockId, Root, TreeBlocks};
|
use super::tree_blocks::{BlockId, Root, TreeBlocks};
|
||||||
use super::{widgets, Correction, Cursor, InnerTreeViewState};
|
use super::{widgets, Correction, Cursor, InnerTreeViewState};
|
||||||
|
|
||||||
|
const SCROLLOFF: i32 = 2;
|
||||||
|
const MIN_CONTENT_HEIGHT: i32 = 10;
|
||||||
|
|
||||||
|
fn scrolloff(height: i32) -> i32 {
|
||||||
|
let scrolloff = (height - MIN_CONTENT_HEIGHT).max(0) / 2;
|
||||||
|
scrolloff.min(SCROLLOFF)
|
||||||
|
}
|
||||||
|
|
||||||
impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
async fn cursor_path(&self, cursor: &Cursor<M::Id>) -> Path<M::Id> {
|
async fn cursor_path(&self, cursor: &Cursor<M::Id>) -> Path<M::Id> {
|
||||||
match cursor {
|
match cursor {
|
||||||
|
|
@ -341,10 +349,11 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
.find(&BlockId::from_cursor(&self.cursor))
|
.find(&BlockId::from_cursor(&self.cursor))
|
||||||
.expect("no cursor found");
|
.expect("no cursor found");
|
||||||
|
|
||||||
let size = frame.size();
|
let height = frame.size().height as i32;
|
||||||
|
let scrolloff = scrolloff(height);
|
||||||
|
|
||||||
let min_line = -block.focus.start;
|
let min_line = -block.focus.start + scrolloff;
|
||||||
let max_line = size.height as i32 - block.focus.end;
|
let max_line = height - block.focus.end - scrolloff;
|
||||||
|
|
||||||
// If the message is higher than the available space, the top of the
|
// If the message is higher than the available space, the top of the
|
||||||
// message should always be visible. I'm not using top_line.clamp(...)
|
// message should always be visible. I'm not using top_line.clamp(...)
|
||||||
|
|
@ -364,8 +373,8 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visible(block: &Block<BlockId<M::Id>>, height: i32) -> bool {
|
fn visible(block: &Block<BlockId<M::Id>>, first_line: i32, last_line: i32) -> bool {
|
||||||
(1 - block.height..height).contains(&block.top_line)
|
(first_line + 1 - block.height..=last_line).contains(&block.top_line)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_so_it_is_visible(
|
fn move_cursor_so_it_is_visible(
|
||||||
|
|
@ -380,13 +389,17 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let height = frame.size().height as i32;
|
let height = frame.size().height as i32;
|
||||||
|
let scrolloff = scrolloff(height);
|
||||||
|
|
||||||
|
let first_line = scrolloff;
|
||||||
|
let last_line = height - 1 - scrolloff;
|
||||||
|
|
||||||
let new_cursor = if matches!(self.cursor, Cursor::Bottom) {
|
let new_cursor = if matches!(self.cursor, Cursor::Bottom) {
|
||||||
blocks
|
blocks
|
||||||
.blocks()
|
.blocks()
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.filter(|b| Self::visible(b, height))
|
.filter(|b| Self::visible(b, first_line, last_line))
|
||||||
.find_map(Self::msg_id)
|
.find_map(Self::msg_id)
|
||||||
} else {
|
} else {
|
||||||
let block = blocks
|
let block = blocks
|
||||||
|
|
@ -394,20 +407,20 @@ impl<M: Msg + ChatMsg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
.find(&BlockId::from_cursor(&self.cursor))
|
.find(&BlockId::from_cursor(&self.cursor))
|
||||||
.expect("no cursor found");
|
.expect("no cursor found");
|
||||||
|
|
||||||
if Self::visible(block, height) {
|
if Self::visible(block, first_line, last_line) {
|
||||||
return None;
|
return None;
|
||||||
} else if block.top_line < 0 {
|
} else if block.top_line < first_line {
|
||||||
blocks
|
blocks
|
||||||
.blocks()
|
.blocks()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|b| Self::visible(b, height))
|
.filter(|b| Self::visible(b, first_line, last_line))
|
||||||
.find_map(Self::msg_id)
|
.find_map(Self::msg_id)
|
||||||
} else {
|
} else {
|
||||||
blocks
|
blocks
|
||||||
.blocks()
|
.blocks()
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.filter(|b| Self::visible(b, height))
|
.filter(|b| Self::visible(b, first_line, last_line))
|
||||||
.find_map(Self::msg_id)
|
.find_map(Self::msg_id)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue