ui: add scrollbar widget in view/thread.rs

embed
Manos Pitsidianakis 2019-05-09 12:53:47 +03:00
parent dad7c09158
commit d231865f88
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 68 additions and 3 deletions

View File

@ -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

View File

@ -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('▾');
}
}