Recount-TUI/src/app.rs

135 lines
3.3 KiB
Rust
Raw Normal View History

2023-05-28 22:18:30 -07:00
use crossterm::event::{Event, self, KeyCode};
use ratatui::widgets::ListState;
use crate::uis::history::HistoryState;
2023-05-31 22:27:26 -07:00
use crate::uis::new_transaction::NewTransactionTabState;
use crate::uis::navigation_frame::NavigationState;
2023-05-31 22:27:26 -07:00
2023-05-31 18:00:17 -07:00
pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
2023-05-28 22:18:30 -07:00
pub struct StatefulList<T> {
pub state: ListState,
pub items: Vec<T>,
}
impl<T> StatefulList<T> {
pub fn with_items(items: Vec<T>) -> StatefulList<T> {
StatefulList {
state: ListState::default(),
items,
}
}
pub fn next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(i));
}
pub fn previous(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
self.items.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.state.select(Some(i));
}
pub fn unselect(&mut self) {
self.state.select(None);
}
}
pub enum InputMode {
Insert,
Normal,
2023-05-31 22:27:26 -07:00
}
2023-05-28 22:18:30 -07:00
pub struct App<'a> {
pub running: bool,
2023-05-31 22:27:26 -07:00
pub states: States<'a>,
2023-05-31 22:27:26 -07:00
pub input_mode: InputMode,
2023-05-28 22:18:30 -07:00
}
impl<'a> App<'a> {
2023-05-31 18:00:17 -07:00
pub fn new() -> App<'a> {
App {
running: true,
states: States::new(),
input_mode: InputMode::Normal,
2023-05-31 18:00:17 -07:00
}
2023-05-28 22:18:30 -07:00
}
pub fn poll_events(&mut self) -> AppResult<()> {
if let Event::Key(key) = event::read()? {
// 'q' needs to be handled at the top level so it can't be
// accidentally handed to a dead end
if let KeyCode::Char('q') = key.code {
if let Some(_) = self.states.nav_state.message.clone() {
self.states.nav_state.message = None;
} else {
if let ActiveFrame::Navigation = self.states.active_frame {
self.running = false;
} else {
self.states.active_frame = ActiveFrame::Navigation;
}
}
}
match self.states.active_frame {
ActiveFrame::Navigation => {
NavigationState::handle_event(key, self);
}
ActiveFrame::History => {
HistoryState::handle_event(key, self);
}
ActiveFrame::NewTransaction => {
NewTransactionTabState::handle_event(key, self);
}
}
2023-05-28 22:18:30 -07:00
}
return Ok(())
2023-05-31 22:27:26 -07:00
}
}
2023-05-31 22:27:26 -07:00
pub enum ActiveFrame {
Navigation,
NewTransaction,
History,
}
pub struct States<'a> {
pub nav_state: NavigationState<'a>,
pub transactions: NewTransactionTabState<'a>,
pub history: HistoryState,
pub active_frame: ActiveFrame,
}
impl<'a> States<'a> {
pub fn new() -> States<'a> {
States {
nav_state: NavigationState::new(),
transactions: NewTransactionTabState::new(),
history: HistoryState::new(),
2023-05-31 22:27:26 -07:00
active_frame: ActiveFrame::Navigation,
}
2023-05-31 22:27:26 -07:00
}
}