//! Mode 01: Direct view, actions with history use ::std::sync::{Arc, RwLock}; use ::crossterm::event::{Event::*, KeyEvent, KeyCode::*}; use ::ratatui::style::Color; use ::tengri::{*, lang::*}; use itertools::Itertools; tui_app!(State { /** Command history (undo/redo). */ history: Vec, /** User-controllable value. */ cursor: usize, }); tui_keys!(self: State, input { Ok(if let Key(KeyEvent { code, .. }) = input.0 { match code { Down | Right => Action::Next, Up | Left => Action::Prev, _ => { return Ok(()) } } .apply(self)? .map(|x|self.history.push(x)); }) }); tui_view!(self: State { let title = "Demo Mode 00"; let items = self.history.iter().take(10).map(|x|format!("{x:?}")).join("\n"); let history = format!("History: {}\n{items}", self.history.len()); let cursor = format!("Cursor: {}", self.cursor); north( east(title.align_sw(), ShowSize.align_se()), east(history.align_c(), cursor.align_c()), ) }); #[derive(Debug)] enum Action { /** Increment cursor */ Next, /** Decrement cursor */ Prev, } impl Action { fn apply (&self, state: &mut State) -> Perhaps { use Action::*; match self { Next => state.next(), Prev => state.prev(), } } } impl State { fn next (&mut self) -> Perhaps { self.cursor = (self.cursor + 1) % 10; Ok(Some(Action::Prev)) } fn prev (&mut self) -> Perhaps { self.cursor = if self.cursor > 0 { self.cursor - 1 } else { 10 - 1 }; Ok(Some(Action::Next)) } }