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(())
}
fn draw(&self, frame: &mut Frame<'_>) {
fn draw(&mut self, frame: &mut Frame<'_>) {
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) {
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::ScrollUp => app.states.skirmish.vertical_offset.prev(),
Action::ScrollDown => app.states.skirmish.vertical_offset.next(),
Action::ScrollLeft => app.states.skirmish.horizontal_offset.prev(),
Action::ScrollRight => app.states.skirmish.horizontal_offset.next(),
Action::Quit => app.exit = true,
Action::Quit2 => app.exit = true,
Action::Esc => app.view = View::MainMenu,
+5 -5
View File
@@ -1,7 +1,7 @@
use ratatui::widgets::ScrollbarState;
use crate::{
app::states::{MainMenuState, PerkDecksState, SettingsState, SkillsConfigState, SkirmishState},
app::states::{
MainMenuState, Offset, PerkDecksState, SettingsState, SkillsConfigState, SkirmishState,
},
cli::Cli,
};
@@ -25,8 +25,8 @@ impl GameStates {
skirmish: SkirmishState {
id: 1,
name: "Skirmish",
vertical_scrollbar: ScrollbarState::new(0),
horizontal_scrollbar: ScrollbarState::new(0),
vertical_offset: Offset::new(),
horizontal_offset: Offset::new(),
},
perk_decks: PerkDecksState {
id: 2,
+1 -1
View File
@@ -8,4 +8,4 @@ pub use main_menu::MainMenuState;
pub use perk_decks::{PerkDecks, PerkDecksState};
pub use settings::SettingsState;
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 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)]
pub struct SkirmishState {
pub id: usize,
pub name: &'static str,
pub vertical_scrollbar: ScrollbarState,
pub horizontal_scrollbar: ScrollbarState,
pub vertical_offset: Offset,
pub horizontal_offset: Offset,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)]
+1 -1
View File
@@ -13,7 +13,7 @@ pub enum View {
SkillsConfig,
}
impl Widget for &App {
impl Widget for &mut App {
fn render(self, area: Rect, buf: &mut Buffer)
where
Self: Sized,
+2 -2
View File
@@ -11,7 +11,7 @@ use ratatui::{
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([
Constraint::Length(4),
Constraint::Fill(1),
@@ -70,7 +70,7 @@ pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) {
board_block.render(main_area, buf);
let cells_area: Rect = board_area.inner(Margin {
horizontal: 1,
horizontal: 3,
vertical: 1,
});
+15 -15
View File
@@ -16,35 +16,35 @@ pub struct BoardWidget {
}
impl BoardWidget {
pub fn new(app: &App, area_width: u16, area_height: u16) -> Self {
let cell_width: u16 = 7;
let cell_height: u16 = 4;
pub fn new(app: &mut App, area_width: u16, area_height: u16) -> Self {
const CELL_HIGHT: u16 = 4;
const CELL_WIDTH: u16 = 7;
let cols: u16 = area_width / cell_width;
let rows: u16 = area_height / cell_height;
let rows: u16 = area_height / CELL_HIGHT;
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
} else {
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
} else {
0
};
} as usize;
// 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;
app.states.skirmish.horizontal_offset.set_max(h_max_offset);
app.states.skirmish.vertical_offset.set_max(v_max_offset);
Self {
cell_width,
cell_height,
cell_width: CELL_WIDTH,
cell_height: CELL_HIGHT,
cols,
rows,
h_offset: h_max_offset as usize,
v_offset: v_max_offset as usize,
h_offset: app.states.skirmish.horizontal_offset.get_value(),
v_offset: app.states.skirmish.vertical_offset.get_value(),
}
}
}