Skip to content

Commit fb37cec

Browse files
author
Stephan Dilly
committed
fix branchlist scrollbr
1 parent 89211f2 commit fb37cec

File tree

5 files changed

+42
-38
lines changed

5 files changed

+42
-38
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ anyhow = "1.0"
4141
unicode-width = "0.1"
4242
textwrap = "0.13"
4343
unicode-truncate = "0.2.0"
44+
easy-cast = "0.4"
4445

4546
[target.'cfg(all(target_family="unix",not(target_os="macos")))'.dependencies]
4647
which = "4.1"

src/components/branchlist.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ impl BranchListComponent {
505505
r: Rect,
506506
) -> Result<()> {
507507
let height_in_lines = r.height as usize;
508+
self.current_height.set(height_in_lines.try_into()?);
508509

509510
self.scroll_top.set(calc_scroll_top(
510511
self.scroll_top.get(),
@@ -524,17 +525,17 @@ impl BranchListComponent {
524525

525526
let mut r = r;
526527
r.width += 1;
528+
r.height += 2;
529+
r.y = r.y.saturating_sub(1);
527530

528531
ui::draw_scrollbar(
529532
f,
530533
r,
531534
&self.theme,
532-
self.branches.len(),
535+
self.branches.len().saturating_sub(height_in_lines),
533536
self.scroll_top.get(),
534537
);
535538

536-
self.current_height.set(height_in_lines.try_into()?);
537-
538539
Ok(())
539540
}
540541
}

src/components/diff.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -237,16 +237,12 @@ impl DiffComponent {
237237
}
238238

239239
fn lines_count(&self) -> usize {
240-
self.diff
241-
.as_ref()
242-
.map_or(0, |diff| diff.lines.saturating_sub(1))
240+
self.diff.as_ref().map_or(0, |diff| diff.lines)
243241
}
244242

245243
fn modify_selection(&mut self, direction: Direction) {
246-
if let Some(diff) = &self.diff {
247-
let max = diff.lines.saturating_sub(1);
248-
249-
self.selection.modify(direction, max);
244+
if self.diff.is_some() {
245+
self.selection.modify(direction, self.lines_count());
250246
}
251247
}
252248

@@ -610,9 +606,11 @@ impl DrawableComponent for DiffComponent {
610606
r.height.saturating_sub(2),
611607
));
612608

609+
let current_height = self.current_size.get().1;
610+
613611
self.scroll_top.set(calc_scroll_top(
614612
self.scroll_top.get(),
615-
self.current_size.get().1 as usize,
613+
current_height as usize,
616614
self.selection.get_end(),
617615
));
618616

@@ -628,7 +626,7 @@ impl DrawableComponent for DiffComponent {
628626
self.theme.text(false, false),
629627
)])]
630628
} else {
631-
self.get_text(r.width, self.current_size.get().1)
629+
self.get_text(r.width, current_height)
632630
};
633631

634632
f.render_widget(
@@ -648,7 +646,8 @@ impl DrawableComponent for DiffComponent {
648646
f,
649647
r,
650648
&self.theme,
651-
self.lines_count(),
649+
self.lines_count()
650+
.saturating_sub(usize::from(current_height)),
652651
self.scroll_top.get(),
653652
);
654653
}

src/ui/scrollbar.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::style::SharedTheme;
2+
use easy_cast::CastFloat;
23
use std::convert::TryFrom;
34
use tui::{
45
backend::Backend,
@@ -12,16 +13,16 @@ use tui::{
1213

1314
///
1415
struct Scrollbar {
15-
lines: u16,
16+
max: u16,
1617
pos: u16,
1718
style_bar: Style,
1819
style_pos: Style,
1920
}
2021

2122
impl Scrollbar {
22-
fn new(lines: usize, pos: usize) -> Self {
23+
fn new(max: usize, pos: usize) -> Self {
2324
Self {
24-
lines: u16::try_from(lines).unwrap_or_default(),
25+
max: u16::try_from(max).unwrap_or_default(),
2526
pos: u16::try_from(pos).unwrap_or_default(),
2627
style_pos: Style::default(),
2728
style_bar: Style::default(),
@@ -31,50 +32,51 @@ impl Scrollbar {
3132

3233
impl Widget for Scrollbar {
3334
fn render(self, area: Rect, buf: &mut Buffer) {
34-
let right = area.right().saturating_sub(1);
35-
if right <= area.left() {
35+
if area.height <= 2 {
3636
return;
37-
};
38-
39-
let area = area.inner(&Margin {
40-
horizontal: 0,
41-
vertical: 1,
42-
});
37+
}
4338

44-
if area.height == 0 {
39+
if self.max == 0 {
4540
return;
4641
}
4742

48-
if area.height >= self.lines {
43+
let right = area.right().saturating_sub(1);
44+
if right <= area.left() {
4945
return;
50-
}
46+
};
47+
48+
let (bar_top, bar_height) = {
49+
let scrollbar_area = area.inner(&Margin {
50+
horizontal: 0,
51+
vertical: 1,
52+
});
53+
54+
(scrollbar_area.top(), scrollbar_area.height)
55+
};
5156

52-
for y in area.top()..area.bottom() {
57+
for y in bar_top..(bar_top + bar_height) {
5358
buf.set_string(right, y, DOUBLE_VERTICAL, self.style_bar);
5459
}
5560

56-
let max_pos = self.lines.saturating_sub(area.height);
57-
let progress = f32::from(self.pos) / f32::from(max_pos);
61+
let progress = f32::from(self.pos) / f32::from(self.max);
5862
let progress = if progress > 1.0 { 1.0 } else { progress };
59-
let pos = f32::from(area.height) * progress;
63+
let pos = f32::from(bar_height) * progress;
6064

61-
//TODO: any better way for this?
62-
#[allow(clippy::cast_sign_loss)]
63-
#[allow(clippy::cast_possible_truncation)]
64-
let pos = (pos as u16).saturating_sub(1);
65+
let pos: u16 = pos.cast_nearest();
66+
let pos = pos.saturating_sub(1);
6567

66-
buf.set_string(right, area.top() + pos, FULL, self.style_pos);
68+
buf.set_string(right, bar_top + pos, FULL, self.style_pos);
6769
}
6870
}
6971

7072
pub fn draw_scrollbar<B: Backend>(
7173
f: &mut Frame<B>,
7274
r: Rect,
7375
theme: &SharedTheme,
74-
lines: usize,
76+
max: usize,
7577
pos: usize,
7678
) {
77-
let mut widget = Scrollbar::new(lines, pos);
79+
let mut widget = Scrollbar::new(max, pos);
7880
widget.style_pos = theme.scroll_bar_pos();
7981
f.render_widget(widget, r)
8082
}

0 commit comments

Comments
 (0)