}
pub struct Tui {
- terminal: Terminal<CrosstermBackend<Stdout>>,
+ output: Rc<RefCell<TuiOutput>>,
subthread_sender: std::sync::mpsc::SyncSender<SubthreadEvent>,
subthread_receiver: std::sync::mpsc::Receiver<SubthreadEvent>,
state: TuiLogicalState,
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,
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
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()?
}
}
+struct TuiOutput {
+ terminal: Terminal<CrosstermBackend<Stdout>>,
+}
+
+impl TuiOutput {
+ fn new(terminal: Terminal<CrosstermBackend<Stdout>>) -> 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