diff --git a/src/app/keybindings/keybindings.rs b/src/app/keybindings/keybindings.rs index f0b607d..fbf334a 100644 --- a/src/app/keybindings/keybindings.rs +++ b/src/app/keybindings/keybindings.rs @@ -7,6 +7,12 @@ pub enum Action { Quit2, Up, Down, + Left, + Right, + ScrollUp, + ScrollDown, + ScrollLeft, + ScrollRight, Space, Enter, Esc, @@ -17,6 +23,7 @@ pub enum Action { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)] pub enum Group { Movement, + Scroll, Select, Input, Quit, @@ -70,6 +77,60 @@ pub static KEYBINDINGS: &[KeyBinding] = &[ symbol: "↓", description: "Down", }, + KeyBinding { + action: Action::Left, + code: KeyCode::Left, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::NONE, + group: Group::Movement, + symbol: "←", + description: "Left", + }, + KeyBinding { + action: Action::Right, + code: KeyCode::Right, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::NONE, + group: Group::Movement, + symbol: "→", + description: "Right", + }, + KeyBinding { + action: Action::ScrollUp, + code: KeyCode::Up, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::CONTROL, + group: Group::Movement, + symbol: "Ctrl + ↑", + description: "Scroll Up ", + }, + KeyBinding { + action: Action::ScrollDown, + code: KeyCode::Down, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::CONTROL, + group: Group::Movement, + symbol: "Ctrl + ↓", + description: "Scroll Down", + }, + KeyBinding { + action: Action::ScrollLeft, + code: KeyCode::Left, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::CONTROL, + group: Group::Movement, + symbol: "Ctrl + ←", + description: "Scroll Left", + }, + KeyBinding { + action: Action::ScrollRight, + code: KeyCode::Right, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::CONTROL, + group: Group::Movement, + symbol: "Ctrl + →", + description: "Scroll Right", + }, KeyBinding { action: Action::Space, code: KeyCode::Char(' '), diff --git a/src/app/keybindings/skirmish.rs b/src/app/keybindings/skirmish.rs index 7ac9b39..96b0527 100644 --- a/src/app/keybindings/skirmish.rs +++ b/src/app/keybindings/skirmish.rs @@ -7,6 +7,10 @@ use ratatui::crossterm::event::KeyEvent; pub fn skirmish_keybindings(app: &mut App, key_event: &KeyEvent) { if let Some(action) = event_to_action(&key_event) { match action { + Action::ScrollUp => app.states.skirmish.vertical_scrollbar.prev(), + Action::ScrollDown => app.states.skirmish.vertical_scrollbar.next(), + Action::ScrollLeft => app.states.skirmish.horizontal_scrollbar.prev(), + Action::ScrollRight => app.states.skirmish.horizontal_scrollbar.next(), Action::Quit => app.exit = true, Action::Quit2 => app.exit = true, Action::Esc => app.view = View::MainMenu, diff --git a/src/app/state.rs b/src/app/state.rs index a8a5779..35b571b 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -1,3 +1,5 @@ +use ratatui::widgets::ScrollbarState; + use crate::{ app::states::{MainMenuState, PerkDecksState, SettingsState, SkillsConfigState, SkirmishState}, cli::Cli, @@ -23,6 +25,8 @@ impl GameStates { skirmish: SkirmishState { id: 1, name: "Skirmish", + vertical_scrollbar: ScrollbarState::new(0), + horizontal_scrollbar: ScrollbarState::new(0), }, perk_decks: PerkDecksState { id: 2, diff --git a/src/app/states/skirmish.rs b/src/app/states/skirmish.rs index c63905a..1330307 100644 --- a/src/app/states/skirmish.rs +++ b/src/app/states/skirmish.rs @@ -1,9 +1,12 @@ use clap::ValueEnum; +use ratatui::widgets::ScrollbarState; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SkirmishState { pub id: usize, pub name: &'static str, + pub vertical_scrollbar: ScrollbarState, + pub horizontal_scrollbar: ScrollbarState, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)] diff --git a/src/app/views/skirmish.rs b/src/app/views/skirmish.rs index d15aeaa..c7cfff9 100644 --- a/src/app/views/skirmish.rs +++ b/src/app/views/skirmish.rs @@ -1,4 +1,8 @@ -use crate::app::{App, keybindings::Action, widgets::KeybindingsWidget}; +use crate::app::{ + App, + keybindings::Action, + widgets::{BoardWidget, KeybindingsWidget}, +}; use ratatui::{ buffer::Buffer, layout::{Alignment, Constraint, Layout, Margin, Rect}, @@ -11,7 +15,7 @@ pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) { let vertical_layout: Layout = Layout::vertical([ Constraint::Length(4), Constraint::Fill(1), - Constraint::Length(4), + Constraint::Length(6), ]); let [title_area, main_area, keybindings_area] = vertical_layout.areas(area); @@ -65,24 +69,24 @@ pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) { let board_area: Rect = board_block.inner(main_area); board_block.render(main_area, buf); - let inner_board_area: Rect = board_area.inner(Margin { + let cells_area: Rect = board_area.inner(Margin { horizontal: 1, vertical: 1, }); - let map_width: u16 = inner_board_area.width / (app.states.settings.map_width as u16); - let map_height: u16 = inner_board_area.height / (app.states.settings.map_height as u16); - - Paragraph::new(format!( - "x = {}, y = {}, mw = {}, mh = {}", - inner_board_area.width, inner_board_area.height, map_width, map_height - )) - .block(Block::default()) - .render(inner_board_area, buf); + BoardWidget::new(app, cells_area.width, cells_area.height).render(cells_area, buf); } { - let actions: Vec = vec![Action::Quit, Action::Quit2, Action::Esc]; + let actions: Vec = vec![ + Action::ScrollUp, + Action::ScrollDown, + Action::ScrollLeft, + Action::ScrollRight, + Action::Quit, + Action::Quit2, + Action::Esc, + ]; KeybindingsWidget::new(actions).render(keybindings_area, buf); } diff --git a/src/app/widgets/board.rs b/src/app/widgets/board.rs new file mode 100644 index 0000000..4b323d9 --- /dev/null +++ b/src/app/widgets/board.rs @@ -0,0 +1,75 @@ +use crate::app::{App, widgets::CellWidget}; +use ratatui::{ + buffer::Buffer, + layout::{Constraint, Layout, Rect}, + widgets::Widget, +}; +use std::rc::Rc; + +pub struct BoardWidget { + cell_width: u16, + cell_height: u16, + cols: u16, + rows: u16, + h_offset: usize, + v_offset: usize, +} + +impl BoardWidget { + pub fn new(app: &App, area_width: u16, area_height: u16) -> Self { + let cell_width: u16 = 7; + let cell_height: u16 = 4; + + let cols: u16 = area_width / cell_width; + let rows: u16 = area_height / cell_height; + + let h_max_offset: u16 = if app.states.settings.map_height as u16 > rows { + app.states.settings.map_height as u16 - rows + } else { + 0 + }; + + let v_max_offset: u16 = if app.states.settings.map_width as u16 > cols { + app.states.settings.map_width as u16 - cols + } else { + 0 + }; + + // let h_offset: usize = (cell_height * rows as u16 / area_height) as usize; + // let v_offset: usize = (cell_width * cols as u16 / area_width) as usize; + + Self { + cell_width, + cell_height, + cols, + rows, + h_offset: h_max_offset as usize, + v_offset: v_max_offset as usize, + } + } +} + +impl Widget for BoardWidget { + fn render(self, area: Rect, buf: &mut Buffer) { + let horizontal: Rc<[Rect]> = Layout::horizontal(vec![ + Constraint::Length(self.cell_width); + self.cols as usize + ]) + .split(area); + + for (col_idx, col_area) in horizontal.iter().enumerate() { + let vertical: Rc<[Rect]> = Layout::vertical(vec![ + Constraint::Length(self.cell_height); + self.rows as usize + ]) + .split(*col_area); + + for (row_idx, cell_area) in vertical.iter().enumerate() { + let cell: CellWidget = + CellWidget::new(row_idx + self.v_offset, col_idx + self.h_offset); + + cell.render(*cell_area, buf); + } + } + } +} diff --git a/src/app/widgets/cell.rs b/src/app/widgets/cell.rs new file mode 100644 index 0000000..c2d8822 --- /dev/null +++ b/src/app/widgets/cell.rs @@ -0,0 +1,35 @@ +use ratatui::{ + buffer::Buffer, + layout::{Alignment, Rect}, + style::Stylize, + widgets::{Block, Borders, Paragraph, Widget}, +}; + +// pub enum CellTags { +// Player, +// Enemy, +// Dirt, +// Tunnel, +// Base, +// } + +pub struct CellWidget { + pub row: usize, + pub col: usize, + // pub tags: Vec, +} + +impl CellWidget { + pub fn new(row: usize, col: usize) -> Self { + Self { row, col } + } +} + +impl Widget for CellWidget { + fn render(self, area: Rect, buf: &mut Buffer) { + Paragraph::new(format!("{}/{}", self.row, self.col)) + .alignment(Alignment::Center) + .block(Block::default().borders(Borders::ALL).white()) + .render(area, buf); + } +} diff --git a/src/app/widgets/mod.rs b/src/app/widgets/mod.rs index 008492d..b325419 100644 --- a/src/app/widgets/mod.rs +++ b/src/app/widgets/mod.rs @@ -1,3 +1,7 @@ +pub mod board; +pub mod cell; pub mod keybindings; +pub use board::BoardWidget; +pub use cell::CellWidget; pub use keybindings::KeybindingsWidget; diff --git a/src/cli.rs b/src/cli.rs index ff47306..0e4676d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -37,7 +37,7 @@ pub struct Cli { long, help = "Map width", value_name = "Positive integer [20; 100]", - default_value = "50" + default_value = "27" )] pub map_width: u8, @@ -45,7 +45,7 @@ pub struct Cli { long, help = "Map height", value_name = "Positive integer [11; 50]", - default_value = "21" + default_value = "11" )] pub map_height: u8,