mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 00:48:35 +00:00
fix branchlist scrollbr
This commit is contained in:
parent
89211f245e
commit
fb37cec2f0
5 changed files with 42 additions and 38 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -363,6 +363,7 @@ dependencies = [
|
|||
"crossbeam-channel",
|
||||
"crossterm 0.19.0",
|
||||
"dirs-next",
|
||||
"easy-cast",
|
||||
"itertools",
|
||||
"log",
|
||||
"pprof",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue