diff --git a/card_stuffs/src/main.rs b/card_stuffs/src/main.rs index bd6e50a..aebb9b7 100644 --- a/card_stuffs/src/main.rs +++ b/card_stuffs/src/main.rs @@ -6,7 +6,7 @@ use ratatui::{ layout::{Constraint, Layout, Rect, Flex}, style::{Style, Stylize, Color}, text::Line, - widgets::{Block, BorderType, Borders, Paragraph}, + widgets::{Block, BorderType, Borders, Paragraph, Clear, Wrap}, DefaultTerminal, Frame, }; @@ -18,6 +18,7 @@ pub struct App { // I should think about making this a Vec so I can highlight a whole stack which is about to move selected_card: Option, exit: bool, + show_help: bool, } const CARD_HEIGHT: u16 = 11; @@ -69,26 +70,6 @@ fn draw_waste(cards_in_waste: &Vec, area: Rect, frame: &mut F } -fn deck_widget(cards_in_deck: &Vec) -> Paragraph<'static> { - let card_image = format!( - "#############\n\ - #############\n\ - ### Cards ###\n\ - ### Left ###\n\ - #############\n\ - #### {:02} #####\n\ - #############\n\ - #############\n\ - #############", cards_in_deck.len() - ); - - Paragraph::new(card_image) - .block(Block::new() - .borders(Borders::ALL) - .border_type(BorderType::Rounded)) -} - - fn card_widget<'a>(card: &'a card_stuffs::Card, top: bool, highlight: bool, select: bool) -> Paragraph<'a> { if !card.visible { return facedown_card(top); @@ -121,80 +102,6 @@ fn card_widget<'a>(card: &'a card_stuffs::Card, top: bool, highlight: bool, sele .border_type(BorderType::Rounded)) } -fn partially_covered_card(card: &card_stuffs::Card) -> Paragraph { - let card_image = format!( - "{value}{suit}", value=card.value, suit=card.suit - ); - let card_style = match card.suit.colour() { - card_stuffs::Colour::Black => Style::new().black().bg(Color::White), - card_stuffs::Colour::Red => Style::new().red().bg(Color::White), - }; - let borders = Borders::TOP | Borders::LEFT | Borders::BOTTOM; - let border_style = Style::new().white().on_black(); - Paragraph::new(card_image) - .style(card_style) - .block(Block::new() - .style(border_style) - .borders(borders) - .border_type(BorderType::Rounded)) -} - -/* -struct CardWidget { - card: card_stuffs::Card, - // put display stuff in here? -} - -impl Widget for CardWidget { - fn render(self, area: Rect, buf: &mut Buffer) { - let mut border_style = Style::default(); - - } -} -*/ - -fn facedown_card(top: bool) -> Paragraph<'static> { - let hidden_card = format!( - "#############\n\ - #############\n\ - #############\n\ - #############\n\ - #############\n\ - #############\n\ - #############\n\ - #############\n\ - #############" - ); - - let mut borders = Borders::TOP | Borders::LEFT | Borders::RIGHT; - if top { - borders |= Borders::BOTTOM; - } - - Paragraph::new(hidden_card) - .block(Block::new() - .borders(borders) - .border_type(BorderType::Rounded)) -} - -fn empty_pile() -> Paragraph<'static> { - // made using https://www.asciiart.eu/ - let hidden_card = format!( -" - XX XX - XX XX - - X X - X X - X X - XXXXXXX" - ); - - Paragraph::new(hidden_card) - .block(Block::new() - .borders(Borders::ALL) - .border_type(BorderType::Rounded)) -} impl App { /// runs the application's main loop until the user quits @@ -207,12 +114,13 @@ impl App { } fn draw(&self, frame: &mut Frame) { + let area = frame.area(); let vertical = Layout::vertical([ Constraint::Length(1), Constraint::Min(0), Constraint::Length(1), ]); - let [title_bar, main_area, status_bar] = vertical.areas(frame.area()); + let [title_bar, main_area, status_bar] = vertical.areas(area); frame.render_widget( Block::new() @@ -222,7 +130,7 @@ impl App { title_bar ); - let status_bar_info = format!("Cards Per-Draw: {} ---- Times Through Deck: {} ", self.cards.num_cards_turned, self.cards.current_num_passes_through_deck); + let status_bar_info = format!("Cards Per-Draw: {} ---- Times Through Deck: {} ---- Press 'h' for Help ", self.cards.num_cards_turned, self.cards.current_num_passes_through_deck); frame.render_widget( Block::new().borders(Borders::TOP).title(status_bar_info), status_bar @@ -313,6 +221,23 @@ impl App { } } } + + if self.show_help { + let block = Block::bordered().title("Help"); + let text = +"You are playing \"Legends of Soltar\" - a Klondike thingy +Press 'q' to Quit +Press '1' or '3' to change the number of cards you draw from the deck +Press 'd' to draw from your deck +Press 'w' to put the waste pile back into the deck (you can only do this when the waste is empty)"; + let p = Paragraph::new(text).wrap(Wrap { trim: true }); + let vertical = Layout::vertical([Constraint::Max(10)]).flex(Flex::Center); + let horizontal = Layout::horizontal([Constraint::Percentage(70)]).flex(Flex::Center); + let [area] = vertical.areas(area); + let [area] = horizontal.areas(area); + frame.render_widget(Clear, area); + frame.render_widget(p.block(block), area); + } } fn handle_events(&mut self) -> io::Result<()> { @@ -334,6 +259,7 @@ impl App { KeyCode::Char('w') => self.cards.waste_to_deck(), KeyCode::Char('1') => self.cards.num_cards_turned = 1, KeyCode::Char('3') => self.cards.num_cards_turned = 3, + KeyCode::Char('h') => self.show_help = !self.show_help, // toggle _ => {} } } @@ -351,6 +277,86 @@ fn main() -> io::Result<()> { } +fn deck_widget(cards_in_deck: &Vec) -> Paragraph<'static> { + let card_image = format!( + "#############\n\ + #############\n\ + ### Cards ###\n\ + ### Left ###\n\ + #############\n\ + #### {:02} #####\n\ + #############\n\ + #############\n\ + #############", cards_in_deck.len() + ); + + Paragraph::new(card_image) + .block(Block::new() + .borders(Borders::ALL) + .border_type(BorderType::Rounded)) +} + +fn partially_covered_card(card: &card_stuffs::Card) -> Paragraph { + let card_image = format!( + "{value}{suit}", value=card.value, suit=card.suit + ); + let card_style = match card.suit.colour() { + card_stuffs::Colour::Black => Style::new().black().bg(Color::White), + card_stuffs::Colour::Red => Style::new().red().bg(Color::White), + }; + let borders = Borders::TOP | Borders::LEFT | Borders::BOTTOM; + let border_style = Style::new().white().on_black(); + Paragraph::new(card_image) + .style(card_style) + .block(Block::new() + .style(border_style) + .borders(borders) + .border_type(BorderType::Rounded)) +} + +fn facedown_card(top: bool) -> Paragraph<'static> { + let hidden_card = format!( + "#############\n\ + #############\n\ + #############\n\ + #############\n\ + #############\n\ + #############\n\ + #############\n\ + #############\n\ + #############" + ); + + let mut borders = Borders::TOP | Borders::LEFT | Borders::RIGHT; + if top { + borders |= Borders::BOTTOM; + } + + Paragraph::new(hidden_card) + .block(Block::new() + .borders(borders) + .border_type(BorderType::Rounded)) +} + +fn empty_pile() -> Paragraph<'static> { + // made using https://www.asciiart.eu/ + let hidden_card = format!( +" + XX XX + XX XX + + X X + X X + X X + XXXXXXX" + ); + + Paragraph::new(hidden_card) + .block(Block::new() + .borders(Borders::ALL) + .border_type(BorderType::Rounded)) +} + fn card_paragraph(c: &card_stuffs::Card) -> String { match c.value {