diff --git a/card_stuffs/Cargo.lock b/card_stuffs/Cargo.lock deleted file mode 100644 index 3c2d1e7..0000000 --- a/card_stuffs/Cargo.lock +++ /dev/null @@ -1,105 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "anyhow" -version = "1.0.96" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" - -[[package]] -name = "card_stuffs" -version = "0.1.0" -dependencies = [ - "anyhow", - "strum", - "strum_macros", - "thiserror", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "proc-macro2" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rustversion" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" - -[[package]] -name = "strum" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" - -[[package]] -name = "strum_macros" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "unicode-ident" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" diff --git a/card_stuffs/Cargo.toml b/card_stuffs/Cargo.toml index 0b792d8..e7ba2db 100644 --- a/card_stuffs/Cargo.toml +++ b/card_stuffs/Cargo.toml @@ -5,6 +5,9 @@ edition = "2021" [dependencies] anyhow = "1.0.96" +rand = "0.9.0" +ratatui = { version = "0.29.0", features = ["all-widgets"] } +crossterm = "0.28.1" strum = "0.27.1" strum_macros = "0.27.1" thiserror = "2.0.11" diff --git a/card_stuffs/src/main.rs b/card_stuffs/src/main.rs new file mode 100644 index 0000000..8faae0c --- /dev/null +++ b/card_stuffs/src/main.rs @@ -0,0 +1,119 @@ +use std::io; +use card_stuffs; + +use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}; +use ratatui::{ + buffer::Buffer, + layout::{Constraint, Layout, Rect}, + style::Stylize, + symbols::border, + text::{Line, Text}, + widgets::{block::title, Block, BorderType, Borders, Paragraph, Widget, Padding}, + DefaultTerminal, Frame, +}; + +#[derive(Debug, Default)] +pub struct App { + cards: card_stuffs::Klondike, + exit: bool, +} + +const CARD_HEIGHT: u16 = 12; +const CARD_WIDTH: u16 = 10; + +impl App { + + /// runs the application's main loop until the user quits + pub fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> { + while !self.exit { + terminal.draw(|frame| self.draw(frame))?; + self.handle_events()?; + } + Ok(()) + } + + fn draw(&self, frame: &mut Frame) { + let vertical = Layout::vertical([ + Constraint::Length(1), + Constraint::Min(0), + Constraint::Length(1), + ]); + let [title_bar, main_area, status_bar] = vertical.areas(frame.area()); + + frame.render_widget( + Block::new() + .borders(Borders::TOP) + .border_type(BorderType::Thick) + .title(Line::from("Legends of Soltar").bold()), + title_bar + ); + + let vertical = Layout::vertical([ + Constraint::Length(CARD_HEIGHT + 2), // for padding + Constraint::Min(0) + ]); + let [dwf_area, piles_area] = vertical.areas(main_area); + + frame.render_widget( + Block::new().borders(Borders::ALL).title("dwf_area"), + dwf_area + ); + frame.render_widget( + Block::new().borders(Borders::ALL).title("piles_area"), + piles_area + ); + let horizontal = Layout::horizontal([ + Constraint::Length(CARD_WIDTH), + Constraint::Length(2), + Constraint::Length(CARD_WIDTH), + Constraint::Length(2), + Constraint::Length(CARD_WIDTH), + Constraint::Length(2), + Constraint::Length(CARD_WIDTH), + Constraint::Length(2), + Constraint::Length(CARD_WIDTH), + Constraint::Length(2), + Constraint::Length(CARD_WIDTH), + Constraint::Length(2), + Constraint::Length(CARD_WIDTH), + Constraint::Length(2), + ]); + let piles_and_spacers: [Rect; 14] = horizontal.areas(piles_area); + for pile in 0..card_stuffs::NUM_PILES_KLONDIKE { + frame.render_widget( + Block::new().borders(Borders::ALL).title(format!("pile {}", pile)), + piles_and_spacers[pile*2] + ) + } + } + + fn handle_events(&mut self) -> io::Result<()> { + match event::read()? { + // it's important to check that the event is a key press event as + // crossterm also emits key release and repeat events on Windows. + Event::Key(key_event) if key_event.kind == KeyEventKind::Press => { + self.handle_key_event(key_event) + } + _ => {} + }; + Ok(()) + } + + fn handle_key_event(&mut self, key_event: KeyEvent) { + match key_event.code { + KeyCode::Char('q') => self.exit(), + _ => {} + } + } + + fn exit(&mut self) { + self.exit = true; + } +} + +fn main() -> io::Result<()> { + let mut terminal = ratatui::init(); + let app_result = App::default().run(&mut terminal); + ratatui::restore(); + app_result +}