ui: add scrollbar widget in view/thread.rs
parent
dad7c09158
commit
d231865f88
|
@ -360,7 +360,7 @@ impl ThreadView {
|
|||
|
||||
/// draw the list
|
||||
fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
||||
let upper_left = upper_left!(area);
|
||||
let mut upper_left = pos_inc(upper_left!(area), (1, 0));
|
||||
let bottom_right = bottom_right!(area);
|
||||
let (width, height) = self.content.size();
|
||||
if height == 0 {
|
||||
|
@ -373,7 +373,9 @@ impl ThreadView {
|
|||
let page_no = (self.new_cursor_pos).wrapping_div(rows);
|
||||
|
||||
let top_idx = page_no * rows;
|
||||
|
||||
if (rows >= height!(self.content.area())) {
|
||||
upper_left = pos_dec(upper_left!(area), (1, 0));
|
||||
}
|
||||
/* This closure (written for code clarity, should be inlined by the compiler) returns the
|
||||
* **line** of an entry in the ThreadView grid. */
|
||||
let get_entry_area = |idx: usize, entries: &[ThreadEntry]| {
|
||||
|
@ -454,6 +456,18 @@ impl ThreadView {
|
|||
);
|
||||
|
||||
self.highlight_line(grid, dest_area, src_area, idx);
|
||||
if (rows < height!(self.content.area())) {
|
||||
ScrollBar::draw(
|
||||
grid,
|
||||
(
|
||||
upper_left!(area),
|
||||
set_x(bottom_right, get_x(upper_left!(area)) + 1),
|
||||
),
|
||||
self.cursor_pos,
|
||||
rows,
|
||||
visibles.len(),
|
||||
);
|
||||
}
|
||||
self.dirty = false;
|
||||
context.dirty_areas.push_back(area);
|
||||
} else {
|
||||
|
@ -491,6 +505,22 @@ impl ThreadView {
|
|||
);
|
||||
|
||||
self.highlight_line(grid, dest_area, src_area, entry_idx);
|
||||
if (rows < height!(self.content.area())) {
|
||||
ScrollBar::draw(
|
||||
grid,
|
||||
(
|
||||
upper_left!(area),
|
||||
set_x(bottom_right, get_x(upper_left!(area)) + 1),
|
||||
),
|
||||
self.cursor_pos,
|
||||
rows,
|
||||
visibles.len(),
|
||||
);
|
||||
context.dirty_areas.push_back((
|
||||
upper_left!(area),
|
||||
set_x(bottom_right, get_x(upper_left!(area)) + 1),
|
||||
));
|
||||
}
|
||||
|
||||
let (upper_left, bottom_right) = dest_area;
|
||||
context
|
||||
|
|
|
@ -226,7 +226,8 @@ impl FormWidget {
|
|||
buttons: ButtonWidget::new((action, true)),
|
||||
focus: FormFocus::Fields,
|
||||
hide_buttons: false,
|
||||
id: ComponentId::new_v4(), ..Default::default()
|
||||
id: ComponentId::new_v4(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -694,3 +695,37 @@ impl AutoComplete {
|
|||
Some(ret)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScrollBar();
|
||||
|
||||
impl ScrollBar {
|
||||
pub fn draw(grid: &mut CellBuffer, area: Area, pos: usize, visible_rows: usize, length: usize) {
|
||||
if length == 0 {
|
||||
return;
|
||||
}
|
||||
let height = height!(area);
|
||||
if height < 3 {
|
||||
return;
|
||||
}
|
||||
let visible_ratio: f32 = (std::cmp::min(visible_rows, length) as f32) / (length as f32);
|
||||
let scrollbar_height = std::cmp::max((visible_ratio * (length as f32)) as usize, 1);
|
||||
let scrollbar_offset = (visible_ratio * (pos as f32)) as usize + 1;
|
||||
|
||||
let (upper_left, bottom_right) = area;
|
||||
|
||||
grid[upper_left].set_ch('▴');
|
||||
for y in get_y(upper_left) + 1..(get_y(upper_left) + scrollbar_offset) {
|
||||
grid[set_y(upper_left, y)].set_ch(' ');
|
||||
}
|
||||
for y in (get_y(upper_left) + scrollbar_offset)
|
||||
..(get_y(upper_left) + scrollbar_offset + scrollbar_height)
|
||||
{
|
||||
grid[set_y(upper_left, y)].set_ch('█');
|
||||
}
|
||||
for y in (get_y(upper_left) + scrollbar_offset + scrollbar_height)..get_y(bottom_right) - 1
|
||||
{
|
||||
grid[set_y(upper_left, y)].set_ch(' ');
|
||||
}
|
||||
grid[set_x(bottom_right, get_x(upper_left))].set_ch('▾');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue