ui: refactor menu

embed
Manos Pitsidianakis 2019-08-18 15:46:01 +03:00
parent 1845b046fa
commit 734bc109b0
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
1 changed files with 115 additions and 68 deletions

View File

@ -470,8 +470,8 @@ impl Listing {
self.dirty = false; self.dirty = false;
let mut y = get_y(upper_left); let mut y = get_y(upper_left);
for a in &self.accounts { for a in &self.accounts {
y += 1;
y += self.print_account(grid, (set_y(upper_left, y), bottom_right), &a, context); y += self.print_account(grid, (set_y(upper_left, y), bottom_right), &a, context);
y += 3;
} }
context.dirty_areas.push_back(area); context.dirty_areas.push_back(area);
@ -505,26 +505,20 @@ impl Listing {
let upper_left = upper_left!(area); let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area); let bottom_right = bottom_right!(area);
let highlight = self.cursor_pos.0 == a.index; let must_highlight_account: bool = self.cursor_pos.0 == a.index;
let mut inc = 0; let mut inc = 0;
let mut depth = String::from(""); let mut depth = 0;
let mut s = format!("{}\n", a.name); let mut lines: Vec<(usize, usize, FolderHash, Option<usize>)> = Vec::new();
fn pop(depth: &mut String) {
depth.pop();
}
fn push(depth: &mut String, c: char) {
depth.push(c);
}
/* Gather the folder tree structure in `lines` recursively */
fn print( fn print(
folder_idx: FolderHash, folder_idx: FolderHash,
depth: &mut String, depth: &mut usize,
inc: &mut usize, inc: &mut usize,
entries: &FnvHashMap<FolderHash, Folder>, entries: &FnvHashMap<FolderHash, Folder>,
folders_order: &FnvHashMap<FolderHash, usize>, folders_order: &FnvHashMap<FolderHash, usize>,
s: &mut String, lines: &mut Vec<(usize, usize, FolderHash, Option<usize>)>,
index: usize, //account index index: usize, //account index
context: &mut Context, context: &mut Context,
) { ) {
@ -543,32 +537,33 @@ impl Listing {
} }
}) })
.count(); .count();
let len = s.len(); lines.push((*depth, *inc, folder_idx, Some(count)));
s.insert_str(
len,
&format!("{} {} {}\n ", *inc, &entries[&folder_idx].name(), count),
);
} }
Err(_) => { Err(_) => {
let len = s.len(); lines.push((*depth, *inc, folder_idx, None));
s.insert_str(
len,
&format!("{} {} ...\n ", *inc, &entries[&folder_idx].name()),
);
} }
} }
*inc += 1; *inc += 1;
let mut children: Vec<FolderHash> = entries[&folder_idx].children().to_vec(); let mut children: Vec<FolderHash> = entries[&folder_idx].children().to_vec();
children children
.sort_unstable_by(|a, b| folders_order[a].partial_cmp(&folders_order[b]).unwrap()); .sort_unstable_by(|a, b| folders_order[a].partial_cmp(&folders_order[b]).unwrap());
push(depth, ' '); *depth += 1;
for child in children { for child in children {
let len = s.len(); print(
s.insert_str(len, &format!("{} ", depth)); child,
print(child, depth, inc, entries, folders_order, s, index, context); depth,
inc,
entries,
folders_order,
lines,
index,
context,
);
} }
pop(depth); *depth -= 1;
} }
/* Start with roots */
for f in entries.keys() { for f in entries.keys() {
if entries[f].parent().is_none() { if entries[f].parent().is_none() {
print( print(
@ -577,26 +572,37 @@ impl Listing {
&mut inc, &mut inc,
&entries, &entries,
&folders_order, &folders_order,
&mut s, &mut lines,
a.index, a.index,
context, context,
); );
} }
} }
let lines: Vec<&str> = s.lines().collect(); /* Print account name first */
let lines_len = lines.len(); write_string_to_grid(
if lines_len < 2 { &a.name,
grid,
Color::Default,
Color::Default,
Attr::Bold,
area,
false,
);
if lines.is_empty() {
return 0; return 0;
} }
let lines_len = lines.len();
let mut idx = 0; let mut idx = 0;
for y in get_y(upper_left)..get_y(bottom_right) {
for y in get_y(upper_left) + 1..get_y(bottom_right) {
if idx == lines_len { if idx == lines_len {
break; break;
} }
let s = lines[idx].to_string(); let (fg_color, bg_color) = if must_highlight_account {
let (color_fg, color_bg) = if highlight { if self.cursor_pos.1 == idx {
if self.cursor_pos.1 + 1 == idx {
(Color::Byte(233), Color::Byte(15)) (Color::Byte(233), Color::Byte(15))
} else { } else {
(Color::Byte(15), Color::Byte(233)) (Color::Byte(15), Color::Byte(233))
@ -605,43 +611,84 @@ impl Listing {
(Color::Default, Color::Default) (Color::Default, Color::Default)
}; };
write_string_to_grid( let (depth, inc, folder_idx, count) = lines[idx];
&s, /* Calculate how many columns the folder index tags should occupy with right alignment,
* eg.
* 1
* 2
* ...
* 9
* 10
*/
let total_folder_no_digits = {
let mut len = lines_len;
let mut ctr = 1;
while len > 9 {
ctr += 1;
len /= 10;
}
ctr
};
let (x, _) = write_string_to_grid(
&format!("{:>width$}", inc, width = total_folder_no_digits),
grid, grid,
color_fg, Color::Byte(243),
color_bg, bg_color,
Attr::Default,
(set_y(upper_left, y), bottom_right), (set_y(upper_left, y), bottom_right),
false, false,
); );
{ let (x, _) = write_string_to_grid(
enum CellPos { &" ".repeat(depth + 1),
BeforeIndex, grid,
Index, fg_color,
//AfterIndex, bg_color,
Attr::Default,
((x, y), bottom_right),
false,
);
let (x, _) = write_string_to_grid(
entries[&folder_idx].name(),
grid,
fg_color,
bg_color,
Attr::Default,
((x, y), bottom_right),
false,
);
/* Unread message count */
let count_string = if let Some(c) = count {
if c > 0 {
format!(" {}", c)
} else {
String::new()
} }
let mut pos = CellPos::BeforeIndex; } else {
let mut x = get_x(upper_left); " ...".to_string()
while let Some(cell) = grid.get_mut(x, y) { };
if x == get_x(bottom_right) {
break; let (x, _) = write_string_to_grid(
} &count_string,
match (cell.ch(), &pos) { grid,
(c, CellPos::Index) | (c, CellPos::BeforeIndex) if c.is_numeric() => { fg_color,
pos = CellPos::Index; bg_color,
cell.set_fg(Color::Byte(243)); if count.unwrap_or(0) > 0 {
x += 1; Attr::Bold
continue; } else {
} Attr::Default
(c, CellPos::BeforeIndex) if c.is_whitespace() => { },
x += 1; (
continue; (
} /* Hide part of folder name if need be to fit the message count */
_ => { std::cmp::min(x, get_x(bottom_right).saturating_sub(count_string.len())),
break; y,
} ),
} bottom_right,
} ),
} false,
);
change_colors(grid, ((x, y), set_y(bottom_right, y)), fg_color, bg_color);
idx += 1; idx += 1;
} }
if idx == 0 { if idx == 0 {