mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-26 14:40:30 +00:00
feat: crossterm backend can use alternate screen
This commit is contained in:
parent
7290086fe9
commit
b30cae0473
1 changed files with 43 additions and 11 deletions
|
@ -8,12 +8,20 @@ use crossterm::error::ErrorKind;
|
|||
|
||||
pub struct CrosstermBackend {
|
||||
screen: crossterm::Screen,
|
||||
crossterm: crossterm::Crossterm,
|
||||
// Need to keep the AlternateScreen around even when not using it directly,
|
||||
// see https://github.com/TimonPost/crossterm/issues/88
|
||||
alternate_screen: Option<crossterm::AlternateScreen>,
|
||||
}
|
||||
|
||||
impl Default for CrosstermBackend {
|
||||
fn default() -> CrosstermBackend {
|
||||
let screen = crossterm::Screen::default();
|
||||
let crossterm = crossterm::Crossterm::from_screen(&screen);
|
||||
CrosstermBackend {
|
||||
screen: crossterm::Screen::default(),
|
||||
screen,
|
||||
crossterm,
|
||||
alternate_screen: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,12 +32,38 @@ impl CrosstermBackend {
|
|||
}
|
||||
|
||||
pub fn with_screen(screen: crossterm::Screen) -> CrosstermBackend {
|
||||
CrosstermBackend { screen: screen }
|
||||
let crossterm = crossterm::Crossterm::from_screen(&screen);
|
||||
CrosstermBackend {
|
||||
screen,
|
||||
crossterm,
|
||||
alternate_screen: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_alternate_screen(screen: crossterm::Screen, raw_mode: bool) -> Result<CrosstermBackend, io::Error> {
|
||||
let alternate_screen = screen.enable_alternate_modes(raw_mode)?;
|
||||
let crossterm = crossterm::Crossterm::from_screen(&alternate_screen.screen);
|
||||
Ok(CrosstermBackend {
|
||||
screen,
|
||||
crossterm,
|
||||
alternate_screen: Some(alternate_screen),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn screen(&self) -> &crossterm::Screen {
|
||||
&self.screen
|
||||
}
|
||||
|
||||
pub fn alternate_screen(&self) -> Option<&crossterm::AlternateScreen> {
|
||||
match &self.alternate_screen {
|
||||
Some(alt_screen) => Some(&alt_screen),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn crossterm(&self) -> &crossterm::Crossterm {
|
||||
&self.crossterm
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: consider associated Error type on Backend to allow custom error types
|
||||
|
@ -50,7 +84,7 @@ fn convert_error(error: ErrorKind) -> io::Error {
|
|||
|
||||
impl Backend for CrosstermBackend {
|
||||
fn clear(&mut self) -> io::Result<()> {
|
||||
let terminal = crossterm::terminal();
|
||||
let terminal = self.crossterm.terminal();
|
||||
terminal
|
||||
.clear(crossterm::ClearType::All)
|
||||
.map_err(convert_error)?;
|
||||
|
@ -58,13 +92,13 @@ impl Backend for CrosstermBackend {
|
|||
}
|
||||
|
||||
fn hide_cursor(&mut self) -> io::Result<()> {
|
||||
let cursor = crossterm::cursor();
|
||||
let cursor = self.crossterm.cursor();
|
||||
cursor.hide().map_err(convert_error)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn show_cursor(&mut self) -> io::Result<()> {
|
||||
let cursor = crossterm::cursor();
|
||||
let cursor = self.crossterm.cursor();
|
||||
cursor.show().map_err(convert_error)?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -80,7 +114,7 @@ impl Backend for CrosstermBackend {
|
|||
}
|
||||
|
||||
fn size(&self) -> io::Result<Rect> {
|
||||
let terminal = crossterm::terminal();
|
||||
let terminal = self.crossterm.terminal();
|
||||
let (width, height) = terminal.terminal_size();
|
||||
Ok(Rect::new(0, 0, width, height))
|
||||
}
|
||||
|
@ -93,8 +127,7 @@ impl Backend for CrosstermBackend {
|
|||
where
|
||||
I: Iterator<Item = (u16, u16, &'a Cell)>,
|
||||
{
|
||||
let cursor = crossterm::cursor();
|
||||
let crossterm = crossterm::Crossterm::from_screen(&self.screen);
|
||||
let cursor = self.crossterm.cursor();
|
||||
let mut last_y = 0;
|
||||
let mut last_x = 0;
|
||||
let mut first = true;
|
||||
|
@ -105,8 +138,7 @@ impl Backend for CrosstermBackend {
|
|||
}
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
|
||||
let mut s = crossterm::style(&cell.symbol);
|
||||
let mut s = self.crossterm.style(&cell.symbol);
|
||||
if let Some(color) = cell.style.fg.into() {
|
||||
s = s.with(color)
|
||||
}
|
||||
|
@ -116,7 +148,7 @@ impl Backend for CrosstermBackend {
|
|||
if let Some(attr) = cell.style.modifier.into() {
|
||||
s = s.attr(attr)
|
||||
}
|
||||
crossterm.paint(s).map_err(convert_error)?;
|
||||
self.crossterm.paint(s).map_err(convert_error)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue