Add function to Terminal to mark back buffer dirty and allow forcing full redraws

pull/706/head
Karcsesz 1 year ago
parent fafad6c961
commit 1da684f2b3

@ -65,6 +65,11 @@ impl Cell {
self.bg = Color::Reset;
self.modifier = Modifier::empty();
}
/// Marks cell dirty so it has to be redrawn
pub fn mark_dirty(&mut self) {
self.reset();
self.symbol.clear();
}
}
impl Default for Cell {
@ -362,6 +367,12 @@ impl Buffer {
}
self.area = area;
}
/// Marks entire buffer dirty
pub fn mark_dirty(&mut self) {
for c in &mut self.content {
c.mark_dirty();
}
}
/// Reset all cells in the buffer
pub fn reset(&mut self) {

@ -317,6 +317,12 @@ where
Ok(())
}
/// Mark the underlying buffer dirty, forcing a full redraw on the next draw call.
pub fn mark_dirty(&mut self) {
// Mark all cells in the back buffer dirty
self.buffers[1 - self.current].mark_dirty();
}
/// Queries the real size of the backend.
pub fn size(&self) -> io::Result<Rect> {
self.backend.size()

@ -1,9 +1,11 @@
use std::error::Error;
use tui::buffer::Cell;
use tui::style::{Color, Modifier};
use tui::{
backend::{Backend, TestBackend},
layout::Rect,
widgets::Paragraph,
Terminal,
Frame, Terminal,
};
#[test]
@ -34,3 +36,73 @@ fn terminal_draw_returns_the_completed_frame() -> Result<(), Box<dyn Error>> {
assert_eq!(frame.area, Rect::new(0, 0, 8, 8));
Ok(())
}
#[test]
fn terminal_clear_wipes_terminal_and_does_full_redraw() -> Result<(), Box<dyn Error>> {
let backend = TestBackend::new(5, 5);
let mut terminal = Terminal::new(backend)?;
let draw_fun = |f: &mut Frame<TestBackend>| {
let paragrah = Paragraph::new("Tests\n".repeat(5));
f.render_widget(paragrah, f.size());
};
terminal.draw(draw_fun)?;
terminal.clear()?;
assert!(terminal
.backend()
.buffer()
.content
.iter()
.find(|cell| cell.symbol.ne(" "))
.is_none());
terminal.draw(draw_fun)?;
assert_eq!(
terminal
.backend()
.buffer()
.content
.iter()
.map(|cell| cell.symbol.clone())
.collect::<Vec<_>>()
.join(""),
"Tests".repeat(5)
);
Ok(())
}
#[test]
fn terminal_mark_dirty_does_full_redraw() -> Result<(), Box<dyn Error>> {
let backend = TestBackend::new(5, 5);
let mut terminal = Terminal::new(backend)?;
let draw_fun = |f: &mut Frame<TestBackend>| {
let paragrah = Paragraph::new("Tests\n".repeat(5));
f.render_widget(paragrah, f.size());
};
terminal.draw(draw_fun)?;
terminal.mark_dirty();
let mut fill_cell = Cell {
symbol: "#".to_string(),
fg: Color::Gray,
bg: Color::Gray,
modifier: Modifier::all(),
};
for row in 0..5 {
for col in 0..5 {
terminal
.backend_mut()
.draw(std::iter::once((row, col, &fill_cell)))?;
}
}
terminal.draw(draw_fun)?;
assert_eq!(
terminal
.backend()
.buffer()
.content
.iter()
.map(|cell| cell.symbol.clone())
.collect::<Vec<_>>()
.join(""),
"Tests".repeat(5)
);
Ok(())
}

Loading…
Cancel
Save