ui: add scrollbar widget in view/thread.rs
parent
dad7c09158
commit
d231865f88
|
@ -360,7 +360,7 @@ impl ThreadView {
|
||||||
|
|
||||||
/// draw the list
|
/// draw the list
|
||||||
fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
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 bottom_right = bottom_right!(area);
|
||||||
let (width, height) = self.content.size();
|
let (width, height) = self.content.size();
|
||||||
if height == 0 {
|
if height == 0 {
|
||||||
|
@ -373,7 +373,9 @@ impl ThreadView {
|
||||||
let page_no = (self.new_cursor_pos).wrapping_div(rows);
|
let page_no = (self.new_cursor_pos).wrapping_div(rows);
|
||||||
|
|
||||||
let top_idx = page_no * 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
|
/* This closure (written for code clarity, should be inlined by the compiler) returns the
|
||||||
* **line** of an entry in the ThreadView grid. */
|
* **line** of an entry in the ThreadView grid. */
|
||||||
let get_entry_area = |idx: usize, entries: &[ThreadEntry]| {
|
let get_entry_area = |idx: usize, entries: &[ThreadEntry]| {
|
||||||
|
@ -454,6 +456,18 @@ impl ThreadView {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.highlight_line(grid, dest_area, src_area, idx);
|
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;
|
self.dirty = false;
|
||||||
context.dirty_areas.push_back(area);
|
context.dirty_areas.push_back(area);
|
||||||
} else {
|
} else {
|
||||||
|
@ -491,6 +505,22 @@ impl ThreadView {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.highlight_line(grid, dest_area, src_area, entry_idx);
|
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;
|
let (upper_left, bottom_right) = dest_area;
|
||||||
context
|
context
|
||||||
|
|
|
@ -226,7 +226,8 @@ impl FormWidget {
|
||||||
buttons: ButtonWidget::new((action, true)),
|
buttons: ButtonWidget::new((action, true)),
|
||||||
focus: FormFocus::Fields,
|
focus: FormFocus::Fields,
|
||||||
hide_buttons: false,
|
hide_buttons: false,
|
||||||
id: ComponentId::new_v4(), ..Default::default()
|
id: ComponentId::new_v4(),
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,3 +695,37 @@ impl AutoComplete {
|
||||||
Some(ret)
|
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