Copy MailListing content from cache

embed
Manos Pitsidianakis 2018-07-15 15:35:57 +03:00
parent 16e0960cd5
commit 13fe255459
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 137 additions and 109 deletions

View File

@ -28,93 +28,41 @@ pub struct MailListing {
impl MailListing {
pub fn new(mailbox: Mailbox) -> Self {
let length = mailbox.len();
MailListing {
let mut content = CellBuffer::new(0, 0, Cell::with_char(' '));
let mut retval = MailListing {
cursor_pos: 0,
new_cursor_pos: 0,
length: length,
content: CellBuffer::new(MAX_COLS, length+1, Cell::with_char(' ')),
length: 0,
content: content,
dirty: true,
unfocused: false,
mailbox: mailbox,
pager: None,
}
};
retval.refresh_mailbox();
retval
}
}
impl MailListing {
/// Draw only the list of `Envelope`s.
fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area);
fn refresh_mailbox(&mut self) {
self.dirty = true;
self.cursor_pos = 0;
self.new_cursor_pos = 0;
self.length = self.mailbox.len();
let mut content = CellBuffer::new(MAX_COLS, self.length+1, Cell::with_char(' '));
if self.length == 0 {
clear_area(grid, area);
let new_area = (upper_left, set_x(upper_left, get_x(bottom_right)));
write_string_to_grid(&format!("Folder `{}` is empty.",
self.mailbox.folder.get_name()),
grid,
&mut content,
Color::Default,
Color::Default,
new_area);
context.dirty_areas.push_back(area);
((0, 0), (MAX_COLS-1, 0)));
self.content = content;
return;
}
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
let prev_page_no = (self.cursor_pos).wrapping_div(rows);
let page_no = (self.new_cursor_pos).wrapping_div(rows);
/* If cursor position has changed, remove the highlight from the previous position and
* apply it in the new one. */
if self.cursor_pos != self.new_cursor_pos && prev_page_no == page_no {
for idx in [self.cursor_pos, self.new_cursor_pos].iter() {
if *idx >= self.length {
continue; //bounds check
}
let envelope: &Envelope = &self.mailbox.collection[*idx];
let fg_color = if !envelope.is_seen() {
Color::Byte(0)
} else {
Color::Default
};
let bg_color = if self.cursor_pos == *idx {
if !envelope.is_seen() {
Color::Byte(252)
} else if *idx % 2 == 0 {
Color::Byte(236)
} else {
Color::Default
}
} else {
Color::Byte(246)
};
let new_area = (set_y(upper_left, get_y(upper_left)+(*idx % rows)), bottom_right);
let x = write_string_to_grid(&make_entry_string(envelope, *idx),
grid,
fg_color,
bg_color,
new_area);
for x in x..=get_x(bottom_right) {
grid[(x,get_y(upper_left)+(*idx % rows))].set_ch(' ');
grid[(x,get_y(upper_left)+(*idx % rows))].set_bg(bg_color);
}
context.dirty_areas.push_back(new_area);
}
self.cursor_pos = self.new_cursor_pos;
return;
} else if self.cursor_pos != self.new_cursor_pos {
self.cursor_pos = self.new_cursor_pos;
}
context.dirty_areas.push_back(area);
let mut idx = page_no*rows;
for y in get_y(upper_left)..=get_y(bottom_right) {
let mut idx = 0;
for y in 0..=self.length {
if idx >= self.length {
clear_area(grid,
(set_y(upper_left, y), bottom_right));
clear_area(&mut content,
((0, y), (MAX_COLS-1, self.length)));
break;
}
/* Write an entire line for each envelope entry. */
@ -125,30 +73,89 @@ impl MailListing {
} else {
Color::Default
};
let bg_color = if self.cursor_pos == idx {
Color::Byte(246)
let bg_color = if !envelope.is_seen() {
Color::Byte(251)
} else if idx % 2 == 0 {
Color::Byte(236)
} else {
if !envelope.is_seen() {
Color::Byte(251)
} else if idx % 2 == 0 {
Color::Byte(236)
} else {
Color::Default
}
Color::Default
};
let x = write_string_to_grid(&make_entry_string(envelope, idx),
grid,
fg_color,
bg_color,
(set_y(upper_left, y), bottom_right));
&mut content,
fg_color,
bg_color,
((0, y) , (MAX_COLS-1, y)));
for x in x..=get_x(bottom_right) {
grid[(x,y)].set_ch(' ');
grid[(x,y)].set_bg(bg_color);
for x in x..MAX_COLS {
content[(x,y)].set_ch(' ');
content[(x,y)].set_bg(bg_color);
}
idx+=1;
}
self.content = content;
}
fn highlight_line(&self, grid: &mut CellBuffer, area: Area, idx: usize) {
let envelope: &Envelope = &self.mailbox.collection[idx];
let fg_color = if !envelope.is_seen() {
Color::Byte(0)
} else {
Color::Default
};
let bg_color = if self.cursor_pos != idx {
if !envelope.is_seen() {
Color::Byte(252)
} else if idx % 2 == 0 {
Color::Byte(236)
} else {
Color::Default
}
} else {
Color::Byte(246)
};
change_colors(grid, area, fg_color, bg_color);
}
/// Draw only the list of `Envelope`s.
fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area);
if self.length == 0 {
clear_area(grid, area);
copy_area(grid, &self.content, area, ((0, 0), (MAX_COLS-1, 0)));
context.dirty_areas.push_back(area);
return;
}
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
let prev_page_no = (self.cursor_pos).wrapping_div(rows);
let page_no = (self.new_cursor_pos).wrapping_div(rows);
let idx = page_no*rows;
/* If cursor position has changed, remove the highlight from the previous position and
* apply it in the new one. */
if self.cursor_pos != self.new_cursor_pos && 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, self.new_cursor_pos].iter() {
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.dirty_areas.push_back(new_area);
}
return;
} else if self.cursor_pos != self.new_cursor_pos {
self.cursor_pos = self.new_cursor_pos;
}
copy_area(grid, &self.content, area, ((0, idx), (MAX_COLS - 1, self.length)));
self.highlight_line(grid, (set_y(upper_left, get_y(upper_left)+(idx % rows)), set_y(bottom_right, get_y(upper_left) + (idx % rows))), self.cursor_pos);
context.dirty_areas.push_back(area);
}
/// Create a pager for the `Envelope` currently under the cursor.
@ -316,10 +323,8 @@ impl Component for MailListing {
},
UIEventType::RefreshMailbox(ref m) => {
self.cursor_pos = 0;
self.new_cursor_pos = 0;
self.mailbox = m.clone();
self.length = m.collection.len();
self.refresh_mailbox();
self.dirty = true;
self.pager = None;
},

View File

@ -86,6 +86,45 @@ pub trait Component {
}
}
/// Copy Area src to dest
pub fn copy_area(grid_dest: &mut CellBuffer, grid_src: &CellBuffer, dest: Area, src: Area) {
if !is_valid_area!(dest) || !is_valid_area!(src) {
eprintln!("BUG: Invalid areas in copy_area:\n src: {:?}\n dest: {:?}", src, dest);
return;
}
let mut src_x = get_x(upper_left!(src));
let mut src_y = get_y(upper_left!(src));
for y in get_y(upper_left!(dest))..=get_y(bottom_right!(dest)) {
'for_x: for x in get_x(upper_left!(dest))..=get_x(bottom_right!(dest)) {
grid_dest[(x,y)] = grid_src[(src_x, src_y)];
if src_x == get_x(bottom_right!(src)) {
break 'for_x;
}
src_x += 1;
}
src_x = get_x(upper_left!(src));
if src_y == get_y(bottom_right!(src)) {
clear_area(grid_dest, ((get_x(upper_left!(dest)), y), bottom_right!(dest)));
break;
}
src_y += 1;
}
}
pub fn change_colors(grid: &mut CellBuffer, area: Area, fg_color: Color, bg_color: Color) {
if !is_valid_area!(area) {
eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area);
return;
}
for y in get_y(upper_left!(area))..=get_y(bottom_right!(area)) {
for x in get_x(upper_left!(area))..=get_x(bottom_right!(area)) {
grid[(x,y)].set_fg(fg_color);
grid[(x,y)].set_bg(bg_color);
}
}
}
fn write_string_to_grid(s: &str, grid: &mut CellBuffer, fg_color: Color, bg_color: Color, area: Area) -> usize {
let bounds = grid.size();

View File

@ -171,23 +171,7 @@ impl Component for Pager {
//let pager_stop: bool = context.settings.pager.pager_stop;
//let rows = get_y(bottom_right) - get_y(upper_left);
//let page_length = rows / self.height;
let mut inner_x = 0;
let mut inner_y = self.cursor_pos;
for y in get_y(upper_left)..=get_y(bottom_right) {
'for_x: for x in get_x(upper_left)..=get_x(bottom_right) {
if inner_x == self.width {
break 'for_x;
}
grid[(x,y)] = self.content[(inner_x, inner_y)];
inner_x += 1;
}
inner_y += 1;
inner_x = 0;
if inner_y == self.height {
break;
}
}
copy_area(grid, &self.content, area, ((0, self.cursor_pos), (self.width - 1, self.height - 1)));
context.dirty_areas.push_back(area);
}
fn process_event(&mut self, event: &UIEvent, _context: &mut Context) {

View File

@ -28,7 +28,7 @@ macro_rules! bottom_right { ($a:expr) => ( $a.1 ) }
macro_rules! is_valid_area { ($a:expr) => { {
let upper_left = upper_left!($a);
let bottom_right = bottom_right!($a);
if get_y(upper_left) >= get_y(bottom_right) || get_x(upper_left) > get_x(bottom_right) {
if get_y(upper_left) > get_y(bottom_right) || get_x(upper_left) > get_x(bottom_right) {
false
} else {
true