state: cull redraws of floating notifications
Cull redraws by keeping track of whether the floating box has been initialised and whether its area has been drawn over by other dirty areas.jmap-eventsource
parent
4c1a9b2485
commit
393c5d0d53
68
src/state.rs
68
src/state.rs
|
@ -190,7 +190,10 @@ pub struct State {
|
|||
display_messages: SmallVec<[DisplayMessage; 8]>,
|
||||
display_messages_expiration_start: Option<UnixTimestamp>,
|
||||
display_messages_active: bool,
|
||||
display_messages_dirty: bool,
|
||||
display_messages_initialised: bool,
|
||||
display_messages_pos: usize,
|
||||
display_messages_area: Area,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -335,7 +338,9 @@ impl State {
|
|||
display_messages_expiration_start: None,
|
||||
display_messages_pos: 0,
|
||||
display_messages_active: false,
|
||||
|
||||
display_messages_dirty: false,
|
||||
display_messages_initialised: false,
|
||||
display_messages_area: ((0, 0), (0, 0)),
|
||||
context: Context {
|
||||
accounts,
|
||||
settings: settings.clone(),
|
||||
|
@ -522,6 +527,9 @@ impl State {
|
|||
.resize(self.cols, self.rows, Cell::with_char(' '));
|
||||
|
||||
self.rcv_event(UIEvent::Resize);
|
||||
self.display_messages_dirty = true;
|
||||
self.display_messages_initialised = false;
|
||||
self.display_messages_area = ((0, 0), (0, 0));
|
||||
|
||||
// Invalidate dirty areas.
|
||||
self.context.dirty_areas.clear();
|
||||
|
@ -546,6 +554,8 @@ impl State {
|
|||
.unwrap_or(false)
|
||||
{
|
||||
self.display_messages_active = false;
|
||||
self.display_messages_dirty = true;
|
||||
self.display_messages_initialised = false;
|
||||
self.display_messages_expiration_start = None;
|
||||
areas.push((
|
||||
(0, 0),
|
||||
|
@ -556,6 +566,18 @@ impl State {
|
|||
|
||||
/* Sort by x_start, ie upper_left corner's x coordinate */
|
||||
areas.sort_by(|a, b| (a.0).0.partial_cmp(&(b.0).0).unwrap());
|
||||
|
||||
if self.display_messages_active {
|
||||
/* Check if any dirty area intersects with the area occupied by floating notification
|
||||
* box */
|
||||
let (displ_top, displ_bot) = self.display_messages_area;
|
||||
for &((top_x, top_y), (bottom_x, bottom_y)) in &areas {
|
||||
self.display_messages_dirty |= !(bottom_y < displ_top.1
|
||||
|| displ_bot.1 < top_y
|
||||
|| bottom_x < displ_top.0
|
||||
|| displ_bot.0 < top_x);
|
||||
}
|
||||
}
|
||||
/* draw each dirty area */
|
||||
let rows = self.rows;
|
||||
for y in 0..rows {
|
||||
|
@ -613,13 +635,27 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
if self.display_messages_active {
|
||||
if self.display_messages_dirty && self.display_messages_active {
|
||||
if let Some(DisplayMessage {
|
||||
ref timestamp,
|
||||
ref msg,
|
||||
..
|
||||
}) = self.display_messages.get(self.display_messages_pos)
|
||||
{
|
||||
if !self.display_messages_initialised {
|
||||
{
|
||||
/* Clear area previously occupied by floating notification box */
|
||||
let displ_area = self.display_messages_area;
|
||||
for y in get_y(upper_left!(displ_area))..=get_y(bottom_right!(displ_area)) {
|
||||
(self.draw_horizontal_segment_fn)(
|
||||
&mut self.grid,
|
||||
self.stdout.as_mut().unwrap(),
|
||||
get_x(upper_left!(displ_area)),
|
||||
get_x(bottom_right!(displ_area)),
|
||||
y,
|
||||
);
|
||||
}
|
||||
}
|
||||
let noto_colors = crate::conf::value(&self.context, "status.notification");
|
||||
use crate::melib::text_processing::{Reflow, TextProcessing};
|
||||
|
||||
|
@ -684,16 +720,34 @@ impl State {
|
|||
Some(x),
|
||||
);
|
||||
}
|
||||
for y in get_y(upper_left!(displ_area))..=get_y(bottom_right!(displ_area)) {
|
||||
self.display_messages_area = displ_area;
|
||||
}
|
||||
for y in get_y(upper_left!(self.display_messages_area))
|
||||
..=get_y(bottom_right!(self.display_messages_area))
|
||||
{
|
||||
(self.draw_horizontal_segment_fn)(
|
||||
&mut self.overlay_grid,
|
||||
self.stdout.as_mut().unwrap(),
|
||||
get_x(upper_left!(self.display_messages_area)),
|
||||
get_x(bottom_right!(self.display_messages_area)),
|
||||
y,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.display_messages_dirty = false;
|
||||
} else if self.display_messages_dirty {
|
||||
/* Clear area previously occupied by floating notification box */
|
||||
let displ_area = self.display_messages_area;
|
||||
for y in get_y(upper_left!(displ_area))..=get_y(bottom_right!(displ_area)) {
|
||||
(self.draw_horizontal_segment_fn)(
|
||||
&mut self.grid,
|
||||
self.stdout.as_mut().unwrap(),
|
||||
get_x(upper_left!(displ_area)),
|
||||
get_x(bottom_right!(displ_area)),
|
||||
y,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.display_messages_dirty = false;
|
||||
}
|
||||
if !self.overlay.is_empty() {
|
||||
let area = center_area(
|
||||
|
@ -1092,12 +1146,16 @@ impl State {
|
|||
UIEvent::Input(Key::Alt('<')) => {
|
||||
self.display_messages_expiration_start = Some(melib::datetime::now());
|
||||
self.display_messages_active = true;
|
||||
self.display_messages_initialised = false;
|
||||
self.display_messages_dirty = true;
|
||||
self.display_messages_pos = self.display_messages_pos.saturating_sub(1);
|
||||
return;
|
||||
}
|
||||
UIEvent::Input(Key::Alt('>')) => {
|
||||
self.display_messages_expiration_start = Some(melib::datetime::now());
|
||||
self.display_messages_active = true;
|
||||
self.display_messages_initialised = false;
|
||||
self.display_messages_dirty = true;
|
||||
self.display_messages_pos = std::cmp::min(
|
||||
self.display_messages.len().saturating_sub(1),
|
||||
self.display_messages_pos + 1,
|
||||
|
@ -1110,6 +1168,8 @@ impl State {
|
|||
msg: msg.clone(),
|
||||
});
|
||||
self.display_messages_active = true;
|
||||
self.display_messages_initialised = false;
|
||||
self.display_messages_dirty = true;
|
||||
self.display_messages_expiration_start = None;
|
||||
self.display_messages_pos = self.display_messages.len() - 1;
|
||||
self.redraw();
|
||||
|
|
Loading…
Reference in New Issue