summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-05-09 12:53:47 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-06-10 19:40:48 +0300
commitd231865f885672e8d4f797e5344682890a90f0cc (patch)
treedd1cb5c74aff58bf43af19a5eeb585c2da9ba3aa /ui
parentdad7c09158b5a366206c559ebf64647db39aa86f (diff)
ui: add scrollbar widget in view/thread.rs
Diffstat (limited to 'ui')
-rw-r--r--ui/src/components/mail/view/thread.rs34
-rw-r--r--ui/src/components/utilities/widgets.rs37
2 files changed, 68 insertions, 3 deletions
diff --git a/ui/src/components/mail/view/thread.rs b/ui/src/components/mail/view/thread.rs
index 917ce64f..b8741491 100644
--- a/ui/src/components/mail/view/thread.rs
+++ b/ui/src/components/mail/view/thread.rs
@@ -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
diff --git a/ui/src/components/utilities/widgets.rs b/ui/src/components/utilities/widgets.rs
index 71894171..1da31f30 100644
--- a/ui/src/components/utilities/widgets.rs
+++ b/ui/src/components/utilities/widgets.rs
@@ -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('▾');
+ }
+}