Replace scrollbar state with simple offset struct

Introduce Offset type to track scroll positions and replace
ScrollbarState fields in SkirmishState
Update keybindings, App::draw, Widget impl, and BoardWidget::new
to use mutable references and the new Offset struct.
Adjust imports accordingly.
This commit is contained in:
2026-03-26 21:50:39 +01:00
parent cc179cee03
commit 5a40760151
8 changed files with 59 additions and 32 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ impl App {
Ok(()) Ok(())
} }
fn draw(&self, frame: &mut Frame<'_>) { fn draw(&mut self, frame: &mut Frame<'_>) {
frame.render_widget(self, frame.area()); frame.render_widget(self, frame.area());
} }
+4 -4
View File
@@ -7,10 +7,10 @@ use ratatui::crossterm::event::KeyEvent;
pub fn skirmish_keybindings(app: &mut App, key_event: &KeyEvent) { pub fn skirmish_keybindings(app: &mut App, key_event: &KeyEvent) {
if let Some(action) = event_to_action(&key_event) { if let Some(action) = event_to_action(&key_event) {
match action { match action {
Action::ScrollUp => app.states.skirmish.vertical_scrollbar.prev(), Action::ScrollUp => app.states.skirmish.vertical_offset.prev(),
Action::ScrollDown => app.states.skirmish.vertical_scrollbar.next(), Action::ScrollDown => app.states.skirmish.vertical_offset.next(),
Action::ScrollLeft => app.states.skirmish.horizontal_scrollbar.prev(), Action::ScrollLeft => app.states.skirmish.horizontal_offset.prev(),
Action::ScrollRight => app.states.skirmish.horizontal_scrollbar.next(), Action::ScrollRight => app.states.skirmish.horizontal_offset.next(),
Action::Quit => app.exit = true, Action::Quit => app.exit = true,
Action::Quit2 => app.exit = true, Action::Quit2 => app.exit = true,
Action::Esc => app.view = View::MainMenu, Action::Esc => app.view = View::MainMenu,
+5 -5
View File
@@ -1,7 +1,7 @@
use ratatui::widgets::ScrollbarState;
use crate::{ use crate::{
app::states::{MainMenuState, PerkDecksState, SettingsState, SkillsConfigState, SkirmishState}, app::states::{
MainMenuState, Offset, PerkDecksState, SettingsState, SkillsConfigState, SkirmishState,
},
cli::Cli, cli::Cli,
}; };
@@ -25,8 +25,8 @@ impl GameStates {
skirmish: SkirmishState { skirmish: SkirmishState {
id: 1, id: 1,
name: "Skirmish", name: "Skirmish",
vertical_scrollbar: ScrollbarState::new(0), vertical_offset: Offset::new(),
horizontal_scrollbar: ScrollbarState::new(0), horizontal_offset: Offset::new(),
}, },
perk_decks: PerkDecksState { perk_decks: PerkDecksState {
id: 2, id: 2,
+1 -1
View File
@@ -8,4 +8,4 @@ pub use main_menu::MainMenuState;
pub use perk_decks::{PerkDecks, PerkDecksState}; pub use perk_decks::{PerkDecks, PerkDecksState};
pub use settings::SettingsState; pub use settings::SettingsState;
pub use skills_config::SkillsConfigState; pub use skills_config::SkillsConfigState;
pub use skirmish::{GameMode, SkirmishState}; pub use skirmish::{GameMode, Offset, SkirmishState};
+30 -3
View File
@@ -1,12 +1,39 @@
use clap::ValueEnum; use clap::ValueEnum;
use ratatui::widgets::ScrollbarState;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Offset {
value: usize,
max: usize,
}
impl Offset {
pub fn new() -> Self {
Self { value: 0, max: 0 }
}
pub fn get_value(&self) -> usize {
self.value
}
pub fn set_max(&mut self, max: usize) {
self.max = max;
}
pub fn next(&mut self) {
self.value = self.value.saturating_add(1).min(self.max);
}
pub fn prev(&mut self) {
self.value = self.value.saturating_sub(1).max(0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SkirmishState { pub struct SkirmishState {
pub id: usize, pub id: usize,
pub name: &'static str, pub name: &'static str,
pub vertical_scrollbar: ScrollbarState, pub vertical_offset: Offset,
pub horizontal_scrollbar: ScrollbarState, pub horizontal_offset: Offset,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)]
+1 -1
View File
@@ -13,7 +13,7 @@ pub enum View {
SkillsConfig, SkillsConfig,
} }
impl Widget for &App { impl Widget for &mut App {
fn render(self, area: Rect, buf: &mut Buffer) fn render(self, area: Rect, buf: &mut Buffer)
where where
Self: Sized, Self: Sized,
+2 -2
View File
@@ -11,7 +11,7 @@ use ratatui::{
widgets::{Block, Borders, Padding, Paragraph, Widget}, widgets::{Block, Borders, Padding, Paragraph, Widget},
}; };
pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) { pub fn skirmish_view(app: &mut App, area: Rect, buf: &mut Buffer) {
let vertical_layout: Layout = Layout::vertical([ let vertical_layout: Layout = Layout::vertical([
Constraint::Length(4), Constraint::Length(4),
Constraint::Fill(1), Constraint::Fill(1),
@@ -70,7 +70,7 @@ pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) {
board_block.render(main_area, buf); board_block.render(main_area, buf);
let cells_area: Rect = board_area.inner(Margin { let cells_area: Rect = board_area.inner(Margin {
horizontal: 1, horizontal: 3,
vertical: 1, vertical: 1,
}); });
+15 -15
View File
@@ -16,35 +16,35 @@ pub struct BoardWidget {
} }
impl BoardWidget { impl BoardWidget {
pub fn new(app: &App, area_width: u16, area_height: u16) -> Self { pub fn new(app: &mut App, area_width: u16, area_height: u16) -> Self {
let cell_width: u16 = 7; const CELL_HIGHT: u16 = 4;
let cell_height: u16 = 4; const CELL_WIDTH: u16 = 7;
let cols: u16 = area_width / cell_width; let rows: u16 = area_height / CELL_HIGHT;
let rows: u16 = area_height / cell_height; let cols: u16 = area_width / CELL_WIDTH;
let h_max_offset: u16 = if app.states.settings.map_height as u16 > rows { let h_max_offset: usize = if app.states.settings.map_height as u16 > rows {
app.states.settings.map_height as u16 - rows app.states.settings.map_height as u16 - rows
} else { } else {
0 0
}; } as usize;
let v_max_offset: u16 = if app.states.settings.map_width as u16 > cols { let v_max_offset: usize = if app.states.settings.map_width as u16 > cols {
app.states.settings.map_width as u16 - cols app.states.settings.map_width as u16 - cols
} else { } else {
0 0
}; } as usize;
// let h_offset: usize = (cell_height * rows as u16 / area_height) as usize; app.states.skirmish.horizontal_offset.set_max(h_max_offset);
// let v_offset: usize = (cell_width * cols as u16 / area_width) as usize; app.states.skirmish.vertical_offset.set_max(v_max_offset);
Self { Self {
cell_width, cell_width: CELL_WIDTH,
cell_height, cell_height: CELL_HIGHT,
cols, cols,
rows, rows,
h_offset: h_max_offset as usize, h_offset: app.states.skirmish.horizontal_offset.get_value(),
v_offset: v_max_offset as usize, v_offset: app.states.skirmish.vertical_offset.get_value(),
} }
} }
} }