Persist window state across runs

This commit is contained in:
2026-04-04 23:05:53 -04:00
parent f7b37caccb
commit e75bef634b
10 changed files with 342 additions and 155 deletions
+50 -26
View File
@@ -5,6 +5,7 @@ use egui::{
TextureOptions, Ui, ViewportBuilder,
};
use egui_extras::{Column, Size, StripBuilder, TableBuilder};
use serde::{Deserialize, Serialize};
use crate::{
emulator::SimId,
@@ -12,36 +13,56 @@ use crate::{
memory::{MemoryClient, MemoryView},
window::{
AppWindow,
utils::{NumberEdit, UiExt},
utils::{NumberEdit, UiData, UiExt},
},
};
use super::utils::{self, CellData, CharacterGrid};
#[derive(Clone, PartialEq, Serialize, Deserialize)]
struct State {
cell_index: usize,
generic_palette: bool,
scale: f32,
show_grid: bool,
}
impl Default for State {
fn default() -> Self {
Self {
cell_index: 0,
generic_palette: false,
scale: 1.0,
show_grid: false,
}
}
}
pub struct BgMapWindow {
sim_id: SimId,
memory: Arc<MemoryClient>,
bgmaps: MemoryView,
cell_index: usize,
generic_palette: bool,
params: ImageParams<BgMapParams>,
scale: f32,
show_grid: bool,
state: UiData<State>,
}
impl BgMapWindow {
pub fn new(sim_id: SimId, memory: &Arc<MemoryClient>, images: &ImageTextureLoader) -> Self {
let state: UiData<State> = UiData::new();
let renderer = BgMapRenderer::new(sim_id, memory);
let params = images.add(sim_id, renderer, BgMapParams::default());
let params = images.add(
sim_id,
renderer,
BgMapParams {
cell_index: state.cell_index,
generic_palette: state.generic_palette,
},
);
Self {
sim_id,
memory: memory.clone(),
bgmaps: memory.watch(sim_id, 0x00020000, 0x20000),
cell_index: params.cell_index,
generic_palette: params.generic_palette,
params,
scale: 1.0,
show_grid: false,
state,
}
}
@@ -57,10 +78,11 @@ impl BgMapWindow {
ui.label("Map");
});
row.col(|ui| {
let mut bgmap_index = self.cell_index / 4096;
let mut bgmap_index = self.state.cell_index / 4096;
ui.add(NumberEdit::new(&mut bgmap_index).range(0..16));
if bgmap_index != self.cell_index / 4096 {
self.cell_index = (bgmap_index * 4096) + (self.cell_index % 4096);
if bgmap_index != self.state.cell_index / 4096 {
self.state.cell_index =
(bgmap_index * 4096) + (self.state.cell_index % 4096);
}
});
});
@@ -69,7 +91,7 @@ impl BgMapWindow {
ui.label("Cell");
});
row.col(|ui| {
ui.add(NumberEdit::new(&mut self.cell_index).range(0..16 * 4096));
ui.add(NumberEdit::new(&mut self.state.cell_index).range(0..16 * 4096));
});
});
body.row(row_height, |mut row| {
@@ -77,7 +99,7 @@ impl BgMapWindow {
ui.label("Address");
});
row.col(|ui| {
let address = 0x00020000 + (self.cell_index * 2);
let address = 0x00020000 + (self.state.cell_index * 2);
let mut address_str = format!("{address:08x}");
ui.add_enabled(
false,
@@ -91,7 +113,7 @@ impl BgMapWindow {
.texture_options(TextureOptions::NEAREST);
ui.add(image);
ui.section("Cell", |ui| {
let mut data = self.bgmaps.borrow().read::<u16>(self.cell_index);
let mut data = self.bgmaps.borrow().read::<u16>(self.state.cell_index);
let mut cell = CellData::parse(data);
TableBuilder::new(ui)
.column(Column::remainder())
@@ -134,7 +156,7 @@ impl BgMapWindow {
});
});
if cell.update(&mut data) {
let address = 0x00020000 + (self.cell_index * 2);
let address = 0x00020000 + (self.state.cell_index * 2);
self.memory.write(self.sim_id, address as u32, &data);
}
});
@@ -142,28 +164,28 @@ impl BgMapWindow {
ui.horizontal(|ui| {
ui.label("Scale");
ui.spacing_mut().slider_width = ui.available_width();
let slider = Slider::new(&mut self.scale, 1.0..=10.0)
let slider = Slider::new(&mut self.state.scale, 1.0..=10.0)
.step_by(1.0)
.show_value(false);
ui.add(slider);
});
ui.checkbox(&mut self.show_grid, "Show grid");
ui.checkbox(&mut self.generic_palette, "Generic palette");
ui.checkbox(&mut self.state.show_grid, "Show grid");
ui.checkbox(&mut self.state.generic_palette, "Generic palette");
});
});
self.params.write(BgMapParams {
cell_index: self.cell_index,
generic_palette: self.generic_palette,
cell_index: self.state.cell_index,
generic_palette: self.state.generic_palette,
});
}
fn show_bgmap(&mut self, ui: &mut Ui) {
let grid = CharacterGrid::new(self.image_url("bgmap"))
.with_scale(self.scale)
.with_grid(self.show_grid)
.with_selected(self.cell_index % 4096);
.with_scale(self.state.scale)
.with_grid(self.state.show_grid)
.with_selected(self.state.cell_index % 4096);
if let Some(selected) = grid.show(ui) {
self.cell_index = (self.cell_index / 4096 * 4096) + selected;
self.state.cell_index = (self.state.cell_index / 4096 * 4096) + selected;
}
}
}
@@ -180,6 +202,7 @@ impl AppWindow for BgMapWindow {
}
fn show(&mut self, ui: &mut Ui) {
self.state.load(ui);
CentralPanel::default().show_inside(ui, |ui| {
ui.horizontal_top(|ui| {
StripBuilder::new(ui)
@@ -195,6 +218,7 @@ impl AppWindow for BgMapWindow {
})
});
});
self.state.save(ui);
}
}