egui changes

This commit is contained in:
2026-06-03 17:45:43 -05:00
parent dc5b903741
commit 353461dbfd
10 changed files with 630 additions and 375 deletions
+19 -9
View File
@@ -62,6 +62,7 @@ The game is a single Rust binary using **eframe 0.33 / egui 0.33** for the GUI.
- `BitmapFont::from_bytes(ctx, bytes, tile_w, tile_h, label)` — loads from embedded bytes
- `BitmapFont::create_placeholder(ctx)` — 16×16 grid of 8×8 procedural tiles (bit-pattern bars), used as fallback when no font file is present
- `BitmapFont::tile_uv(tile)` — returns a UV `Rect` for the given tile index (left-to-right, top-to-bottom). Unit-tested via `compute_tile_uv`.
- `BitmapFont::cell_size(zoom)` — pixel size (`Vec2`) of one rendered cell at the given integer zoom; centralizes the `tile_w * zoom` math used across rendering and hit-testing
- `BitmapFont::tile_cols()`, `tile_count()`, `img_w()`, `img_h()` — geometry helpers used by the glyph picker and font dialog
**`src/font_dialog.rs`** — font picker dialog:
@@ -81,24 +82,33 @@ The game is a single Rust binary using **eframe 0.33 / egui 0.33** for the GUI.
- `AppMode` enum (`Play` | `Edit`) — gates arrow-key input; toggles the side panel and viewport mode
- `App` holds `GameState`, `AppMode`, `EditorState`, `default_font: BitmapFont`, and `board_font: Option<BitmapFont>`
- `App::new(board, egui_ctx)` — loads `assets/vga-font-8x16.png` as the default font (falls back to `create_placeholder`); loads per-board font from `board.font` if present
- `App::update` is a thin sequence of phase methods: `handle_input` (table-driven arrow keys, Play only) → `menu_bar` (File Save/Save As via `save_to`/`save_as`, Exit, mode toggle) → `try_show_script_editor` (returns `true` to take over the frame) → editor side panel + font reload → `show_board``handle_board_click``show_glyph_pickers` → object-glyph writeback
- `App::active_font()` — resolves the per-board font or the default; used wherever an exclusive borrow of `self` is not also needed
- `App::show_board(&self) -> Option<(usize, usize)>` — draws the viewport and returns the clicked cell (Edit mode); the click is dispatched to `handle_board_click(&mut self, cx, cy)` *after* `show_board` returns, so the `&mut` handler never conflicts with the font borrow
- Font change detection: `font_spec_before` is snapshotted before `show_editor_panel`; if changed, `apply_font_spec` reloads `board_font`
- Borrow split: `let active_font = self.board_font.as_ref().unwrap_or(&self.default_font)` is extracted before mutable borrows of `editor` and `board.font` to satisfy the borrow checker
- Borrow split: at the editor-panel and glyph-picker call sites, `self.board_font.as_ref().unwrap_or(&self.default_font)` is used inline (not `active_font()`) so the font borrow stays disjoint from the `&mut self.editor`/`&mut board` borrows
- **Play mode**: arrow keys move player; `render::board_origin` centers or player-tracks the viewport
- **Edit mode**: `ScrollArea::both()` wraps the board; click-to-paint stamps `(editor.glyph, editor.selected)`; calls `editor::show_editor_panel` and `glyph_picker::show`
- **Edit mode**: `ScrollArea::both()` wraps the board; click-to-paint stamps `(editor.palette.glyph, editor.palette.selected)`; calls `editor::show_editor_panel` and `glyph_picker::show`
**`src/render.rs`** — cell rendering and drawing primitives:
- Window sizing constants (`DEFAULT_WINDOW_W = 840`, `DEFAULT_WINDOW_H = 524`, `MIN_WINDOW_W/H`); no fixed `CELL_W/H` — cell size comes from the active `BitmapFont`
- `rgba8_to_color32(c)` / `color32_to_rgba8(c)` — inverse bridges between core `color::Rgba8` and egui `Color32`
- `paint_glyph(painter, rect, glyph, font)``rect_filled` with `glyph.bg`, then `painter.image` tinted by `glyph.fg`
- `draw_glyph(painter, origin, x, y, glyph, font)` — sizes cell from `font.tile_w/tile_h`, delegates to `paint_glyph`
- `draw_board(painter, origin, board, font)` — draws all cells then player overlay
- `draw_object_overlays(painter, origin, board, font, selected)` — highlights all object cells in the Objects editor tab; the selected object gets a brighter border
- `board_origin(available, board_w, board_h, player, font)` — centers board or clamps to player with no empty space
- `glyph_preview_button(ui, glyph, font) -> Response` — allocates a one-cell swatch (unzoomed), paints `glyph`, returns the click response; used by the Palette and Objects tabs
- `draw_glyph(painter, origin, x, y, glyph, font, zoom)` — sizes cell via `font.cell_size(zoom)`, delegates to `paint_glyph`
- `draw_board(painter, origin, board, font, zoom)` — draws all cells then player overlay
- `draw_object_overlays(painter, origin, board, font, selected, zoom)` — highlights all object cells in the Objects editor tab; the selected object gets a brighter border
- `board_origin(available, board_w, board_h, player, font, zoom)` — centers board or clamps to player with no empty space
- `pos_to_cell(origin, pos, tile_w, tile_h) -> (i32, i32)` — pixel → cell coordinates; negatives signal out-of-bounds
**`src/editor.rs`** — editor state and side panel:
- `EditorTab` enum (`Palette` | `Board` | `Objects` | `World`) — which tab is active
- `EditorState`holds `selected: Archetype`, `glyph: Glyph`, `glyph_picker_open: bool`, `tab: EditorTab`, `font_dialog_open: bool`, `font_dialog_state: FontDialogState`, `selected_object: Option<usize>`, `object_glyph_picker_open: bool`, `object_editing_glyph: Glyph`, `placing_object: bool`; selecting a new archetype resets `glyph` to that archetype's default
- `show_editor_panel(ctx, editor, board, active_font)` — resizable right-side panel (default 200 px); Palette tab shows archetype list and glyph preview button; Board tab shows current font path and "Font…" button; Objects tab lists all board objects with click-to-select, glyph preview, **Passable/Opaque checkboxes**, and script combobox; World tab is a placeholder
- `EditorTab` enum (`Palette` | `Objects` | `Board` | `Scripts` | `World`) — which tab is active
- `EditorState``tab: EditorTab` plus four concern-grouped sub-structs so each tab takes only the borrow it needs:
- `palette: PaletteState``selected: Archetype`, `glyph: Glyph`, `picker_open: bool` (selecting a new archetype resets `glyph` to its default)
- `font_dialog: FontDialog``open: bool`, `state: FontDialogState`
- `objects: ObjectEdit``selected: Option<usize>`, `picker_open: bool`, `editing_glyph: Glyph`, `placing: bool`
- `scripts: ScriptEdit``editing: Option<String>`, `content: String`, `new_name: String`
- `show_editor_panel(ctx, editor, board, active_font)` — resizable right-side panel (default 200 px); renders the tab bar then dispatches to a per-tab function (`palette_tab`, `objects_tab`, `board_tab`, `scripts_tab`; World is empty), passing the relevant sub-struct(s). Palette shows the archetype list and glyph preview button; Board shows the font path, "Font…" button, and zoom slider; Objects lists the selected object's glyph preview, **Passable/Opaque checkboxes**, and script combobox; Scripts creates/edits named scripts
**`src/glyph_picker.rs`** — floating glyph picker dialog:
- `show(ctx, open, glyph, board_cells, font)` — takes `open: &mut bool` and `glyph: &mut Glyph` directly; no dependency on `EditorState`