Measure automatically in Terminal::present
This commit is contained in:
parent
e3365fdc02
commit
ed14ea9023
5 changed files with 41 additions and 59 deletions
|
|
@ -12,19 +12,13 @@ fn draw(f: &mut Frame) {
|
|||
}
|
||||
|
||||
fn render_frame(term: &mut Terminal) {
|
||||
loop {
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
term.autoresize().unwrap();
|
||||
draw(term.frame());
|
||||
while term.present().unwrap() {
|
||||
term.autoresize().unwrap();
|
||||
|
||||
draw(term.frame());
|
||||
term.present().unwrap();
|
||||
|
||||
if term.measuring_required() {
|
||||
term.measure_widths().unwrap();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use std::convert::Infallible;
|
||||
use std::io;
|
||||
|
||||
use crossterm::event::Event;
|
||||
use crossterm::style::Stylize;
|
||||
use toss::widgets::{BorderLook, Text};
|
||||
use toss::{Style, Styled, Terminal, Widget, WidgetExt};
|
||||
|
||||
fn widget() -> impl Widget<Infallible> {
|
||||
fn widget() -> impl Widget<io::Error> {
|
||||
let styled = Styled::new("Hello world!", Style::new().dark_green())
|
||||
.then_plain("\n")
|
||||
.then("Press any key to exit", Style::new().on_dark_blue());
|
||||
|
|
@ -22,19 +22,13 @@ fn widget() -> impl Widget<Infallible> {
|
|||
}
|
||||
|
||||
fn render_frame(term: &mut Terminal) {
|
||||
loop {
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
term.autoresize().unwrap();
|
||||
widget().draw(term.frame()).unwrap();
|
||||
while term.present().unwrap() {
|
||||
term.autoresize().unwrap();
|
||||
|
||||
widget().draw(term.frame()).unwrap();
|
||||
term.present().unwrap();
|
||||
|
||||
if term.measuring_required() {
|
||||
term.measure_widths().unwrap();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,19 +49,13 @@ fn draw(f: &mut Frame) {
|
|||
}
|
||||
|
||||
fn render_frame(term: &mut Terminal) {
|
||||
loop {
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
term.autoresize().unwrap();
|
||||
draw(term.frame());
|
||||
while term.present().unwrap() {
|
||||
term.autoresize().unwrap();
|
||||
|
||||
draw(term.frame());
|
||||
term.present().unwrap();
|
||||
|
||||
if term.measuring_required() {
|
||||
term.measure_widths().unwrap();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,19 +38,13 @@ fn draw(f: &mut Frame) {
|
|||
}
|
||||
|
||||
fn render_frame(term: &mut Terminal) {
|
||||
loop {
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
// Must be called before rendering, otherwise the terminal has out-of-date
|
||||
// size information and will present garbage.
|
||||
term.autoresize().unwrap();
|
||||
draw(term.frame());
|
||||
while term.present().unwrap() {
|
||||
term.autoresize().unwrap();
|
||||
|
||||
draw(term.frame());
|
||||
term.present().unwrap();
|
||||
|
||||
if term.measuring_required() {
|
||||
term.measure_widths().unwrap();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,16 +91,6 @@ impl Terminal {
|
|||
self.frame.widthdb.active
|
||||
}
|
||||
|
||||
pub fn measuring_required(&self) -> bool {
|
||||
self.frame.widthdb.measuring_required()
|
||||
}
|
||||
|
||||
pub fn measure_widths(&mut self) -> io::Result<()> {
|
||||
self.frame.widthdb.measure_widths(&mut self.out)?;
|
||||
self.full_redraw = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Resize the frame and other internal buffers if the terminal size has
|
||||
/// changed.
|
||||
pub fn autoresize(&mut self) -> io::Result<()> {
|
||||
|
|
@ -124,11 +114,27 @@ impl Terminal {
|
|||
}
|
||||
|
||||
/// Display the current frame on the screen and prepare the next frame.
|
||||
/// Returns `true` if an immediate redraw is required.
|
||||
///
|
||||
/// Before drawing and presenting a frame, [`Self::autoresize`] should be
|
||||
/// called. [`Self::present`] does **not** call it automatically.
|
||||
///
|
||||
/// If width measurements are turned on, any new graphemes encountered since
|
||||
/// the last [`Self::present`] call will be measured. This can lead to the
|
||||
/// screen flickering or being mostly blank until measurements complete.
|
||||
///
|
||||
/// Returns `true` if any new graphemes were measured. Since their widths
|
||||
/// may have changed because of the measurements, the application using this
|
||||
/// [`Terminal`] should re-draw and re-present the current frame.
|
||||
///
|
||||
/// After calling this function, the frame returned by [`Self::frame`] will
|
||||
/// be empty again and have no cursor position.
|
||||
pub fn present(&mut self) -> io::Result<()> {
|
||||
pub fn present(&mut self) -> io::Result<bool> {
|
||||
let measure = self.frame.widthdb.measuring_required();
|
||||
if measure {
|
||||
self.frame.widthdb.measure_widths(&mut self.out)?;
|
||||
self.full_redraw = true;
|
||||
}
|
||||
|
||||
if self.full_redraw {
|
||||
io::stdout().queue(Clear(ClearType::All))?;
|
||||
self.prev_frame_buffer.reset(); // Because the screen is now empty
|
||||
|
|
@ -142,7 +148,7 @@ impl Terminal {
|
|||
mem::swap(&mut self.prev_frame_buffer, &mut self.frame.buffer);
|
||||
self.frame.reset();
|
||||
|
||||
Ok(())
|
||||
Ok(measure)
|
||||
}
|
||||
|
||||
fn draw_differences(&mut self) -> io::Result<()> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue