feat(terminal): add a read-only view of the terminal state after the draw call

pull/452/head
Florian Dehau 3 years ago
parent 67e996c5f4
commit 853f3d9200

@ -60,6 +60,12 @@ impl TestBackend {
&self.buffer
}
pub fn resize(&mut self, width: u16, height: u16) {
self.buffer.resize(Rect::new(0, 0, width, height));
self.width = width;
self.height = height;
}
pub fn assert_buffer(&self, expected: &Buffer) {
assert_eq!(expected.area, self.buffer.area);
let diff = expected.diff(&self.buffer);

@ -94,7 +94,8 @@
//! .title("Block")
//! .borders(Borders::ALL);
//! f.render_widget(block, size);
//! })
//! })?;
//! Ok(())
//! }
//! ```
//!
@ -136,7 +137,8 @@
//! .title("Block 2")
//! .borders(Borders::ALL);
//! f.render_widget(block, chunks[1]);
//! })
//! })?;
//! Ok(())
//! }
//! ```
//!

@ -148,6 +148,14 @@ where
}
}
/// CompletedFrame represents the state of the terminal after all changes performed in the last
/// [`Terminal::draw`] call have been applied. Therefore, it is only valid until the next call to
/// [`Terminal::draw`].
pub struct CompletedFrame<'a> {
pub buffer: &'a Buffer,
pub area: Rect,
}
impl<B> Drop for Terminal<B>
where
B: Backend,
@ -247,7 +255,7 @@ where
/// Synchronizes terminal size, calls the rendering closure, flushes the current internal state
/// and prepares for the next draw call.
pub fn draw<F>(&mut self, f: F) -> io::Result<()>
pub fn draw<F>(&mut self, f: F) -> io::Result<CompletedFrame>
where
F: FnOnce(&mut Frame<B>),
{
@ -279,7 +287,10 @@ where
// Flush
self.backend.flush()?;
Ok(())
Ok(CompletedFrame {
buffer: &self.buffers[1 - self.current],
area: self.viewport.area,
})
}
pub fn hide_cursor(&mut self) -> io::Result<()> {

@ -1,5 +1,8 @@
use std::error::Error;
use tui::{
backend::{Backend, TestBackend},
layout::Rect,
widgets::Paragraph,
Terminal,
};
@ -11,3 +14,23 @@ fn terminal_buffer_size_should_be_limited() {
assert_eq!(size.width, 255);
assert_eq!(size.height, 255);
}
#[test]
fn terminal_draw_returns_the_completed_frame() -> Result<(), Box<dyn Error>> {
let backend = TestBackend::new(10, 10);
let mut terminal = Terminal::new(backend)?;
let frame = terminal.draw(|f| {
let paragrah = Paragraph::new("Test");
f.render_widget(paragrah, f.size());
})?;
assert_eq!(frame.buffer.get(0, 0).symbol, "T");
assert_eq!(frame.area, Rect::new(0, 0, 10, 10));
terminal.backend_mut().resize(8, 8);
let frame = terminal.draw(|f| {
let paragrah = Paragraph::new("test");
f.render_widget(paragrah, f.size());
})?;
assert_eq!(frame.buffer.get(0, 0).symbol, "t");
assert_eq!(frame.area, Rect::new(0, 0, 8, 8));
Ok(())
}

Loading…
Cancel
Save