diff --git a/src/tui/component.rs b/src/tui/component.rs new file mode 100644 index 0000000..ca3f659 --- /dev/null +++ b/src/tui/component.rs @@ -0,0 +1,12 @@ +use ratatui::{layout::Rect, Frame}; + +pub trait Component { + /// The enum that represents what can happen in THIS component + type Msg; + + /// Update the state based on a message + fn update(&mut self, msg: Self::Msg); + + /// Render the component to the screen + fn view(&self, frame: &mut Frame); +} diff --git a/src/tui/dashboard.rs b/src/tui/dashboard.rs new file mode 100644 index 0000000..af6288f --- /dev/null +++ b/src/tui/dashboard.rs @@ -0,0 +1,21 @@ +use crate::component::Component; +use crossterm::event::Event; +use ratatui::{layout::Rect, text::Text, Frame}; + +#[derive(Debug)] +pub enum MenuMsg { + MoveUp, + MoveDown, + Select, +} + +#[derive(Default, Debug)] +pub struct Menu; +impl Component for Menu { + type Msg = MenuMsg; + fn update(&mut self, msg: MenuMsg) {} + fn view(&self, f: &mut Frame) { + let text = Text::raw("meow"); + f.render_widget(text, f.area()); + } +} diff --git a/src/tui/main.rs b/src/tui/main.rs index ddf7de8..ab06112 100644 --- a/src/tui/main.rs +++ b/src/tui/main.rs @@ -5,92 +5,52 @@ use data::{ArchivedData, Data}; use ratatui::{ layout::{self, Constraint, Flex, Layout, Rect}, prelude::Stylize, + style::Style, text::Text, - widgets::{Block, BorderType, Borders}, + widgets::{Block, BorderType, Borders, Paragraph}, Frame, }; use rkyv::{deserialize, rancor}; -mod data_graph; + +use crate::{ + component::Component, + dashboard::{Menu, MenuMsg}, +}; + +mod component; +mod dashboard; + +// -- GLOBAL APP MESSAGE -- +enum AppMsg { + Menu(MenuMsg), // Wraps the Menu's specific enum + GlobalQuit, +} #[derive(Default, Debug)] -struct Root { - counter: i32, - running_state: RunningState, +struct App { + menu: Menu, + should_quit: bool, } -#[derive(Default, Debug, PartialEq)] -enum RunningState { - #[default] - Running, - Done, -} +impl App { + // The "Update" part of TEA + fn update(&mut self, msg: AppMsg) { + match msg { + AppMsg::Menu(child_msg) => self.menu.update(child_msg), + AppMsg::GlobalQuit => self.should_quit = true, + } + } -#[derive(PartialEq)] -enum Message { - Increment, - Decrement, - Reset, - Quit, -} - -impl Root { + // The "View" part of TEA fn view(&self, f: &mut Frame) { - let text = Text::raw("Meow"); - let block = Block::new().borders(Borders::ALL).title("Meow"); - let vertical_layout = Layout::vertical([Constraint::Max(50)]) - .flex(Flex::Center) - .split(f.area()); - - let area = Layout::horizontal([Constraint::Max(50)]) - .flex(Flex::Center) - .split(vertical_layout[0])[0]; - f.render_widget(block, area); - } - fn handle_events() -> Result, Box> { - if event::poll(Duration::from_millis(250))? { - if let Ok(Event::Key(key)) = event::read() { - return Ok(Self::handle_key(key)); - } - return Ok(None); - } - return Ok(None); - } - fn handle_key(key: event::KeyEvent) -> Option { - match key.code { - KeyCode::Up => Some(Message::Increment), - KeyCode::Down => Some(Message::Decrement), - KeyCode::Esc => Some(Message::Quit), - _ => None, - } - } - fn update(&mut self) -> Result<(), Box> { - if let Ok(msg) = Self::handle_events() { - if let Some(msg) = msg { - match msg { - Message::Increment => self.counter += 1, - Message::Decrement => self.counter -= 1, - Message::Reset => unimplemented!(), - Message::Quit => self.running_state = RunningState::Done, - } - return Ok(()); - } else { - return Ok(()); - } - } else { - panic!("Failed to process event"); - } + // Centering logic we discussed earlier! + self.menu.view(f); } } -fn main() -> Result<(), Box> { - let mut app = Root::default(); - ratatui::run(|terminal| { - while app.running_state == RunningState::Running { - terminal.draw(|frame| { - app.view(frame); - })?; - app.update()?; - } - Ok(()) - }) +fn main() { + let app: App = App::default(); + ratatui::run(|terminal| loop { + terminal.draw(|f| app.view(f)); + }); }