From d2265d98e79714dfba37c72d8234d694127bfb73 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 4 Feb 2024 14:09:41 +0000 Subject: [PATCH] Move terminal output into a sub-struct. The sub-struct is held in an Rc by Tui, which will allow me to make other copies of the Rc and use them to give preliminary display updates. --- src/tui.rs | 57 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/tui.rs b/src/tui.rs index 2ad2545..e427d4e 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -178,7 +178,7 @@ pub enum PhysicalAction { } pub struct Tui { - terminal: Terminal>, + output: Rc>, subthread_sender: std::sync::mpsc::SyncSender, subthread_receiver: std::sync::mpsc::Receiver, state: TuiLogicalState, @@ -333,8 +333,10 @@ impl Tui { let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; terminal.clear()?; + let output = Rc::new(RefCell::new(TuiOutput::new(terminal))); + let mut tui = Tui { - terminal, + output, subthread_sender: sender, subthread_receiver: receiver, state, @@ -478,19 +480,7 @@ impl Tui { fn main_loop(&mut self) -> Result<(), TuiError> { 'outer: loop { - { - let state = &mut self.state; - - self.terminal.draw(|frame| { - let area = frame.size(); - let buf = frame.buffer_mut(); - if let Some((x, y)) = state.draw_frame(area, buf) { - if let (Ok(x), Ok(y)) = (x.try_into(), y.try_into()) { - frame.set_cursor(x, y); - } - } - })?; - } + self.output.borrow_mut().draw(&mut self.state)?; // One physical keypress can break down into multiple // things we treat as logical keypresses. So we must do an @@ -556,7 +546,9 @@ impl Tui { match physact { PhysicalAction::Beep => Self::beep()?, PhysicalAction::Exit => break 'outer Ok(()), - PhysicalAction::Refresh => self.terminal.clear()?, + PhysicalAction::Refresh => { + self.output.borrow_mut().clear()? + } PhysicalAction::Error(err) => break 'outer Err(err), PhysicalAction::MainSessionSetup => { self.main_session_setup()? @@ -575,6 +567,39 @@ impl Tui { } } +struct TuiOutput { + terminal: Terminal>, +} + +impl TuiOutput { + fn new(terminal: Terminal>) -> Self { + TuiOutput { + terminal, + } + } + + fn draw( + &mut self, + state: &mut TuiLogicalState, + ) -> Result<(), std::io::Error> { + self.terminal.draw(|frame| { + let area = frame.size(); + let buf = frame.buffer_mut(); + if let Some((x, y)) = state.draw_frame(area, buf) { + if let (Ok(x), Ok(y)) = (x.try_into(), y.try_into()) { + frame.set_cursor(x, y); + } + } + })?; + + Ok(()) + } + + fn clear(&mut self) -> Result<(), std::io::Error> { + self.terminal.clear() + } +} + #[derive(Debug)] pub enum CursorPosition { None, // cursor is hidden -- 2.30.2