fix branchlist scrollbr

This commit is contained in:
Stephan Dilly 2021-04-27 14:51:42 +02:00
parent 89211f245e
commit fb37cec2f0
5 changed files with 42 additions and 38 deletions

1
Cargo.lock generated
View file

@ -363,6 +363,7 @@ dependencies = [
"crossbeam-channel",
"crossterm 0.19.0",
"dirs-next",
"easy-cast",
"itertools",
"log",
"pprof",

View file

@ -41,6 +41,7 @@ anyhow = "1.0"
unicode-width = "0.1"
textwrap = "0.13"
unicode-truncate = "0.2.0"
easy-cast = "0.4"
[target.'cfg(all(target_family="unix",not(target_os="macos")))'.dependencies]
which = "4.1"

View file

@ -505,6 +505,7 @@ impl BranchListComponent {
r: Rect,
) -> Result<()> {
let height_in_lines = r.height as usize;
self.current_height.set(height_in_lines.try_into()?);
self.scroll_top.set(calc_scroll_top(
self.scroll_top.get(),
@ -524,17 +525,17 @@ impl BranchListComponent {
let mut r = r;
r.width += 1;
r.height += 2;
r.y = r.y.saturating_sub(1);
ui::draw_scrollbar(
f,
r,
&self.theme,
self.branches.len(),
self.branches.len().saturating_sub(height_in_lines),
self.scroll_top.get(),
);
self.current_height.set(height_in_lines.try_into()?);
Ok(())
}
}

View file

@ -237,16 +237,12 @@ impl DiffComponent {
}
fn lines_count(&self) -> usize {
self.diff
.as_ref()
.map_or(0, |diff| diff.lines.saturating_sub(1))
self.diff.as_ref().map_or(0, |diff| diff.lines)
}
fn modify_selection(&mut self, direction: Direction) {
if let Some(diff) = &self.diff {
let max = diff.lines.saturating_sub(1);
self.selection.modify(direction, max);
if self.diff.is_some() {
self.selection.modify(direction, self.lines_count());
}
}
@ -610,9 +606,11 @@ impl DrawableComponent for DiffComponent {
r.height.saturating_sub(2),
));
let current_height = self.current_size.get().1;
self.scroll_top.set(calc_scroll_top(
self.scroll_top.get(),
self.current_size.get().1 as usize,
current_height as usize,
self.selection.get_end(),
));
@ -628,7 +626,7 @@ impl DrawableComponent for DiffComponent {
self.theme.text(false, false),
)])]
} else {
self.get_text(r.width, self.current_size.get().1)
self.get_text(r.width, current_height)
};
f.render_widget(
@ -648,7 +646,8 @@ impl DrawableComponent for DiffComponent {
f,
r,
&self.theme,
self.lines_count(),
self.lines_count()
.saturating_sub(usize::from(current_height)),
self.scroll_top.get(),
);
}

View file

@ -1,4 +1,5 @@
use super::style::SharedTheme;
use easy_cast::CastFloat;
use std::convert::TryFrom;
use tui::{
backend::Backend,
@ -12,16 +13,16 @@ use tui::{
///
struct Scrollbar {
lines: u16,
max: u16,
pos: u16,
style_bar: Style,
style_pos: Style,
}
impl Scrollbar {
fn new(lines: usize, pos: usize) -> Self {
fn new(max: usize, pos: usize) -> Self {
Self {
lines: u16::try_from(lines).unwrap_or_default(),
max: u16::try_from(max).unwrap_or_default(),
pos: u16::try_from(pos).unwrap_or_default(),
style_pos: Style::default(),
style_bar: Style::default(),
@ -31,39 +32,40 @@ impl Scrollbar {
impl Widget for Scrollbar {
fn render(self, area: Rect, buf: &mut Buffer) {
if area.height <= 2 {
return;
}
if self.max == 0 {
return;
}
let right = area.right().saturating_sub(1);
if right <= area.left() {
return;
};
let area = area.inner(&Margin {
horizontal: 0,
vertical: 1,
});
let (bar_top, bar_height) = {
let scrollbar_area = area.inner(&Margin {
horizontal: 0,
vertical: 1,
});
if area.height == 0 {
return;
}
(scrollbar_area.top(), scrollbar_area.height)
};
if area.height >= self.lines {
return;
}
for y in area.top()..area.bottom() {
for y in bar_top..(bar_top + bar_height) {
buf.set_string(right, y, DOUBLE_VERTICAL, self.style_bar);
}
let max_pos = self.lines.saturating_sub(area.height);
let progress = f32::from(self.pos) / f32::from(max_pos);
let progress = f32::from(self.pos) / f32::from(self.max);
let progress = if progress > 1.0 { 1.0 } else { progress };
let pos = f32::from(area.height) * progress;
let pos = f32::from(bar_height) * progress;
//TODO: any better way for this?
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_possible_truncation)]
let pos = (pos as u16).saturating_sub(1);
let pos: u16 = pos.cast_nearest();
let pos = pos.saturating_sub(1);
buf.set_string(right, area.top() + pos, FULL, self.style_pos);
buf.set_string(right, bar_top + pos, FULL, self.style_pos);
}
}
@ -71,10 +73,10 @@ pub fn draw_scrollbar<B: Backend>(
f: &mut Frame<B>,
r: Rect,
theme: &SharedTheme,
lines: usize,
max: usize,
pos: usize,
) {
let mut widget = Scrollbar::new(lines, pos);
let mut widget = Scrollbar::new(max, pos);
widget.style_pos = theme.scroll_bar_pos();
f.render_widget(widget, r)
}