summaryrefslogtreecommitdiff
path: root/src/components/mail/listing/plain.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/mail/listing/plain.rs')
-rw-r--r--src/components/mail/listing/plain.rs231
1 files changed, 87 insertions, 144 deletions
diff --git a/src/components/mail/listing/plain.rs b/src/components/mail/listing/plain.rs
index c4296a4c..c54294c3 100644
--- a/src/components/mail/listing/plain.rs
+++ b/src/components/mail/listing/plain.rs
@@ -130,7 +130,7 @@ pub struct PlainListing {
subsort: (SortField, SortOrder),
rows: RowsState<(ThreadHash, EnvelopeHash)>,
/// Cache current view.
- data_columns: DataColumns,
+ data_columns: DataColumns<4>,
#[allow(clippy::type_complexity)]
search_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
@@ -167,9 +167,9 @@ impl MailListingTrait for PlainListing {
.values()
.cloned()
.any(std::convert::identity);
- dbg!(is_selection_empty);
if is_selection_empty {
- return dbg!(self.get_env_under_cursor(self.cursor_pos.2))
+ return self
+ .get_env_under_cursor(self.cursor_pos.2)
.into_iter()
.collect::<_>();
}
@@ -205,8 +205,6 @@ impl MailListingTrait for PlainListing {
odd_highlighted: crate::conf::value(context, "mail.listing.plain.odd_highlighted"),
even_selected: crate::conf::value(context, "mail.listing.plain.even_selected"),
odd_selected: crate::conf::value(context, "mail.listing.plain.odd_selected"),
- attachment_flag: crate::conf::value(context, "mail.listing.attachment_flag"),
- thread_snooze_flag: crate::conf::value(context, "mail.listing.thread_snooze_flag"),
tag_default: crate::conf::value(context, "mail.listing.tag_default"),
theme_default: crate::conf::value(context, "theme_default"),
..self.color_cache
@@ -448,15 +446,19 @@ impl ListingTrait for PlainListing {
if self.cursor_pos.2 != self.new_cursor_pos.2 && prev_page_no == page_no {
let old_cursor_pos = self.cursor_pos;
self.cursor_pos = self.new_cursor_pos;
- for idx in &[old_cursor_pos.2, self.new_cursor_pos.2] {
- if *idx >= self.length {
+ for &(idx, highlight) in &[(old_cursor_pos.2, false), (self.new_cursor_pos.2, true)] {
+ if idx >= self.length {
continue; //bounds check
}
- let new_area = (
- set_y(upper_left, get_y(upper_left) + (*idx % rows)),
- set_y(bottom_right, get_y(upper_left) + (*idx % rows)),
- );
- self.highlight_line(grid, new_area, *idx, context);
+ let new_area = nth_row_area(area, idx % rows);
+ self.data_columns
+ .draw(grid, idx, self.cursor_pos.2, grid.bounds_iter(new_area));
+ if highlight {
+ let row_attr = row_attr!(self.color_cache, idx % 2 == 0, false, true, false);
+ change_colors(grid, new_area, row_attr.fg, row_attr.bg);
+ } else if let Some(row_attr) = self.rows.row_attr_cache.get(&idx) {
+ change_colors(grid, new_area, row_attr.fg, row_attr.bg);
+ }
context.dirty_areas.push_back(new_area);
}
return;
@@ -468,107 +470,37 @@ impl ListingTrait for PlainListing {
self.cursor_pos.2 = self.new_cursor_pos.2;
}
- let width = width!(area);
- self.data_columns.widths = Default::default();
- self.data_columns.widths[0] = self.data_columns.columns[0].size().0;
- self.data_columns.widths[1] = self.data_columns.columns[1].size().0; /* date*/
- self.data_columns.widths[2] = self.data_columns.columns[2].size().0; /* from */
- self.data_columns.widths[3] = self.data_columns.columns[3].size().0; /* subject */
-
- let min_col_width = std::cmp::min(
- 15,
- std::cmp::min(self.data_columns.widths[3], self.data_columns.widths[2]),
- );
- if self.data_columns.widths[0] + self.data_columns.widths[1] + 2 * min_col_width + 4 > width
- {
- let remainder = width
- .saturating_sub(self.data_columns.widths[0])
- .saturating_sub(self.data_columns.widths[1])
- .saturating_sub(2 * 2);
- self.data_columns.widths[2] = remainder / 6;
- } else {
- let remainder = width
- .saturating_sub(self.data_columns.widths[0])
- .saturating_sub(self.data_columns.widths[1])
- .saturating_sub(3 * 2);
- if min_col_width + self.data_columns.widths[3] > remainder {
- self.data_columns.widths[2] = min_col_width;
- }
- }
- clear_area(grid, area, self.color_cache.theme_default);
/* Page_no has changed, so draw new page */
- let mut x = get_x(upper_left);
- let mut flag_x = 0;
- for i in 0..4 {
- let column_width = self.data_columns.widths[i];
- if i == 3 {
- flag_x = x;
- }
- if column_width == 0 {
- continue;
- }
- copy_area(
- grid,
- &self.data_columns.columns[i],
- (set_x(upper_left, x), bottom_right),
- (
- (0, top_idx),
- (column_width.saturating_sub(1), self.length - 1),
- ),
- );
- x += column_width + 2; // + SEPARATOR
- if x > get_x(bottom_right) {
- break;
- }
- }
- for r in 0..cmp::min(self.length - top_idx, rows) {
- let (fg_color, bg_color) = {
- let c = &self.data_columns.columns[0][(0, r + top_idx)];
- (c.fg(), c.bg())
- };
- change_colors(
- grid,
- (
- pos_inc(upper_left, (0, r)),
- (flag_x.saturating_sub(1), get_y(upper_left) + r),
- ),
- fg_color,
- bg_color,
- );
- for c in grid.row_iter(
- flag_x
- ..std::cmp::min(
- get_x(bottom_right),
- flag_x + 2 + self.data_columns.widths[3],
- ),
- get_y(upper_left) + r,
- ) {
- grid[c].set_bg(bg_color);
+ _ = self
+ .data_columns
+ .recalc_widths((width!(area), height!(area)), top_idx);
+ clear_area(grid, area, self.color_cache.theme_default);
+ /* copy table columns */
+ self.data_columns
+ .draw(grid, top_idx, self.cursor_pos.2, grid.bounds_iter(area));
+ /* apply each row colors separately */
+ for i in top_idx..(top_idx + height!(area)) {
+ if let Some(row_attr) = self.rows.row_attr_cache.get(&i) {
+ change_colors(grid, nth_row_area(area, i % rows), row_attr.fg, row_attr.bg);
}
- change_colors(
- grid,
- (
- (
- flag_x + 2 + self.data_columns.widths[3],
- get_y(upper_left) + r,
- ),
- (get_x(bottom_right), get_y(upper_left) + r),
- ),
- fg_color,
- bg_color,
- );
}
- self.highlight_line(
+ /* highlight cursor */
+ let row_attr = row_attr!(
+ self.color_cache,
+ self.cursor_pos.2 % 2 == 0,
+ false,
+ true,
+ false
+ );
+ change_colors(
grid,
- (
- set_y(upper_left, get_y(upper_left) + (self.cursor_pos.2 % rows)),
- set_y(bottom_right, get_y(upper_left) + (self.cursor_pos.2 % rows)),
- ),
- self.cursor_pos.2,
- context,
+ nth_row_area(area, self.cursor_pos.2 % rows),
+ row_attr.fg,
+ row_attr.bg,
);
+ /* clear gap if available height is more than count of entries */
if top_idx + rows > self.length {
clear_area(
grid,
@@ -845,6 +777,14 @@ impl PlainListing {
continue;
}
}
+ let row_attr = row_attr!(
+ self.color_cache,
+ self.length % 2 == 0,
+ !envelope.is_seen(),
+ false,
+ false
+ );
+ self.rows.row_attr_cache.insert(self.length, row_attr);
let entry_strings = self.make_entry_string(&envelope, context);
min_width.1 = cmp::max(min_width.1, entry_strings.date.grapheme_width()); /* date */
@@ -868,6 +808,21 @@ impl PlainListing {
min_width.0 = self.length.saturating_sub(1).to_string().len();
+ self.data_columns.elasticities[0].set_rigid();
+ self.data_columns.elasticities[1].set_rigid();
+ self.data_columns.elasticities[2].set_grow(5, Some(35));
+ self.data_columns.elasticities[3].set_rigid();
+ self.data_columns
+ .cursor_config
+ .set_handle(true)
+ .set_even_odd_theme(
+ self.color_cache.even_highlighted,
+ self.color_cache.odd_highlighted,
+ );
+ self.data_columns
+ .theme_config
+ .set_even_odd_theme(self.color_cache.even, self.color_cache.odd);
+
/* index column */
self.data_columns.columns[0] =
CellBuffer::new_with_context(min_width.0, self.rows.len(), None, context);
@@ -903,14 +858,7 @@ impl PlainListing {
panic!();
}
- let envelope: EnvelopeRef = context.accounts[&self.cursor_pos.0].collection.get_env(i);
- let row_attr = row_attr!(
- self.color_cache,
- idx % 2 == 0,
- !envelope.is_seen(),
- false,
- false
- );
+ let row_attr = self.rows.row_attr_cache[&idx];
let (x, _) = write_string_to_grid(
&idx.to_string(),
@@ -998,17 +946,6 @@ impl PlainListing {
for c in columns[3].row_iter(x..min_width.3, idx) {
columns[3][c].set_bg(row_attr.bg).set_attrs(row_attr.attrs);
}
- /* Set fg color for flags */
- let mut x = 0;
- if self.rows.selection.get(&i).cloned().unwrap_or(false) {
- x += 1;
- }
- if !envelope.is_seen() {
- x += 1;
- }
- if envelope.has_attachments() {
- columns[3][(x, idx)].set_fg(self.color_cache.attachment_flag.fg);
- }
}
if self.length == 0 && self.filter_term.is_empty() {
let message: String = account[&self.cursor_pos.1].status();
@@ -1091,19 +1028,34 @@ impl Component for PlainListing {
if !self.rows.row_updates.is_empty() {
let (upper_left, bottom_right) = area;
- while let Some(row) = self.rows.row_updates.pop() {
- let row: usize = self.rows.env_order[&row];
+ while let Some(env_hash) = self.rows.row_updates.pop() {
+ let row: usize = self.rows.env_order[&env_hash];
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
let top_idx = page_no * rows;
if row >= top_idx && row <= top_idx + rows {
- let area = (
- set_y(upper_left, get_y(upper_left) + (row % rows)),
- set_y(bottom_right, get_y(upper_left) + (row % rows)),
+ let new_area = nth_row_area(area, row % rows);
+ self.data_columns.draw(
+ grid,
+ row,
+ self.cursor_pos.2,
+ grid.bounds_iter(new_area),
);
- self.highlight_line(grid, area, row, context);
- context.dirty_areas.push_back(area);
+ let envelope: EnvelopeRef = context.accounts[&self.cursor_pos.0]
+ .collection
+ .get_env(env_hash);
+ let row_attr = row_attr!(
+ self.color_cache,
+ row % 2 == 0,
+ !envelope.is_seen(),
+ false,
+ self.rows.selection[&env_hash]
+ );
+ self.rows.row_attr_cache.insert(row, row_attr);
+
+ change_colors(grid, new_area, row_attr.fg, row_attr.bg);
+ context.dirty_areas.push_back(new_area);
}
}
if self.force_draw {
@@ -1196,10 +1148,8 @@ impl Component for PlainListing {
{
if self.modifier_active && self.modifier_command.is_none() {
self.modifier_command = Some(Modifier::default());
- } else {
- if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
- self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
- }
+ } else if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
+ self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
}
return true;
}
@@ -1243,11 +1193,6 @@ impl Component for PlainListing {
),
even_selected: crate::conf::value(context, "mail.listing.plain.even_selected"),
odd_selected: crate::conf::value(context, "mail.listing.plain.odd_selected"),
- attachment_flag: crate::conf::value(context, "mail.listing.attachment_flag"),
- thread_snooze_flag: crate::conf::value(
- context,
- "mail.listing.thread_snooze_flag",
- ),
tag_default: crate::conf::value(context, "mail.listing.tag_default"),
theme_default: crate::conf::value(context, "theme_default"),
..self.color_cache
@@ -1332,9 +1277,7 @@ impl Component for PlainListing {
.cloned()
.any(std::convert::identity) =>
{
- for v in self.rows.selection.values_mut() {
- *v = false;
- }
+ self.rows.clear_selection();
self.dirty = true;
return true;
}