egui changes
This commit is contained in:
+29
-27
@@ -138,23 +138,26 @@ eframe requires `NativeOptions` (including window size) to be set before calling
|
||||
|
||||
`App` holds a `GameState`, an `AppMode` (`Play` | `Edit`), an `EditorState`, a `default_font: BitmapFont` (loaded from `assets/vga-font-8x16.png` at startup, falling back to `create_placeholder`), and a `board_font: Option<BitmapFont>` (loaded from `board.font` when a per-board font is set). `App::new` takes `&egui::Context` to upload textures before the first frame.
|
||||
|
||||
Font change detection: before calling `show_editor_panel`, `font_spec_before` is cloned; after the call, if `board.font` differs, `apply_font_spec` reloads `board_font`. The active font for the frame is `board_font.as_ref().unwrap_or(&default_font)`, extracted as a `let` binding before mutable borrows to satisfy the borrow checker.
|
||||
Font change detection: before calling `show_editor_panel`, `font_spec_before` is cloned; after the call, if `board.font` differs, `apply_font_spec` reloads `board_font`. `App::active_font()` resolves `board_font.as_ref().unwrap_or(&default_font)`; at the editor-panel and glyph-picker sites the same expression is used inline instead so the font borrow stays disjoint from the `&mut editor`/`&mut board` borrows (a method call would borrow all of `self`).
|
||||
|
||||
The `update` method phases:
|
||||
`update` is a thin sequence of phase methods, each owning one concern:
|
||||
|
||||
1. Reads arrow key input and calls `GameState::try_move` — **Play mode only**
|
||||
2. Draws the menu bar with a File menu and a Play/Edit mode toggle
|
||||
3. In Edit mode: calls `editor::show_editor_panel` — declared before `CentralPanel` so egui allocates its space first
|
||||
4. Draws the board and player via `render::draw_board` (see viewport sections below)
|
||||
5. In Edit mode: calls `glyph_picker::show` if `editor.glyph_picker_open`
|
||||
1. `handle_input` — table-driven arrow keys → `GameState::try_move` (**Play mode only**)
|
||||
2. `menu_bar` — File menu (Save/Save As via `save_to`/`save_as`, Exit) and the Play/Edit toggle
|
||||
3. `try_show_script_editor` — if a script is open, fills the `CentralPanel` with the code editor and returns `true`, ending the frame early
|
||||
4. Editor side panel (Edit mode) — `editor::show_editor_panel`, declared before `CentralPanel`; then the font-reload check
|
||||
5. `show_board` — draws the viewport and returns the clicked cell; the click is dispatched to `handle_board_click` *after* it returns
|
||||
6. `show_glyph_pickers` — the Palette and Objects glyph pickers; then the selected object's glyph is flushed back to `board.objects[i]`
|
||||
|
||||
**Click dispatch borrow split:** `show_board(&self)` only draws and returns `Option<(usize, usize)>` (validated cell coords). The mutating `handle_board_click(&mut self, cx, cy)` runs afterward, so the immutable font borrow held during drawing never conflicts with the `&mut self` handler.
|
||||
|
||||
**Viewport — Play mode:**
|
||||
`render::board_origin(available, board_w, board_h, player)` computes the pixel position of cell (0,0). If the board fits along an axis it is centered; if it overflows the viewport is centered on the player and clamped so no empty space appears at the board edges. No scroll bars.
|
||||
`render::board_origin(available, board_w, board_h, player, font, zoom)` computes the pixel position of cell (0,0). If the board fits along an axis it is centered; if it overflows the viewport is centered on the player and clamped so no empty space appears at the board edges. No scroll bars.
|
||||
|
||||
**Viewport — Edit mode:**
|
||||
The board is wrapped in `egui::ScrollArea::new([true, true])`, which shows scroll bars when the board overflows the viewport. Content is allocated at exact board size; `rect.min` from `allocate_exact_size` serves as the origin passed to `render::draw_board`.
|
||||
|
||||
**Stamp action:** `*board.get_mut(cx, cy) = (self.editor.glyph, self.editor.selected)` — the custom glyph and selected archetype are written together. The glyph can differ from the archetype's `default_glyph()` if the user has customized it.
|
||||
**Stamp action:** `*board.get_mut(cx, cy) = (self.editor.palette.glyph, self.editor.palette.selected)` — the custom glyph and selected archetype are written together. The glyph can differ from the archetype's `default_glyph()` if the user has customized it.
|
||||
|
||||
---
|
||||
|
||||
@@ -162,39 +165,38 @@ The board is wrapped in `egui::ScrollArea::new([true, true])`, which shows scrol
|
||||
|
||||
All pixel-level rendering knowledge lives here. No dependency on `EditorState` or `App`. Cell size is no longer a fixed constant — it comes from the active `BitmapFont`.
|
||||
|
||||
**Constants:** Window sizing (`DEFAULT_WINDOW_W = 840`, `DEFAULT_WINDOW_H = 524`, `MIN_WINDOW_W/H`) defined here. No `CELL_W`/`CELL_H` — those were removed when bitmap fonts were introduced.
|
||||
**Constants:** Window sizing (`DEFAULT_WINDOW_W = 840`, `DEFAULT_WINDOW_H = 524`, `MIN_WINDOW_W/H`) defined here. No `CELL_W`/`CELL_H` — those were removed when bitmap fonts were introduced. Per-cell pixel size comes from `BitmapFont::cell_size(zoom)`.
|
||||
|
||||
**`paint_glyph(painter, rect, glyph, font)`** — fills `rect` with `glyph.bg`, then draws the tile image tinted by `glyph.fg`. Used by both `draw_glyph` and `glyph_picker`.
|
||||
**`rgba8_to_color32(c)` / `color32_to_rgba8(c)`** — inverse conversions between the core `color::Rgba8` and egui's `Color32`, used at the glyph-picker boundary where colors cross between the two type systems.
|
||||
|
||||
**`draw_glyph(painter, origin, x, y, glyph, font)`** — computes the cell rect from `font.tile_w/tile_h`, delegates to `paint_glyph`.
|
||||
**`paint_glyph(painter, rect, glyph, font)`** — fills `rect` with `glyph.bg`, then draws the tile image tinted by `glyph.fg`. Used by `draw_glyph`, `glyph_preview_button`, and `glyph_picker`.
|
||||
|
||||
**`draw_board(painter, origin, board, font)`** — iterates all cells calling `draw_glyph`, then draws the player as an overlay on top.
|
||||
**`glyph_preview_button(ui, glyph, font) -> Response`** — allocates a one-cell swatch (unzoomed), paints `glyph`, and returns the click `Response`. Shared by the Palette and Objects editor tabs for their editable glyph swatches.
|
||||
|
||||
**`draw_object_overlays(painter, origin, board, font, selected)`** — called from Edit mode when the Objects tab is active. Draws a dim border on every object cell and a bright border on the selected one, making objects discoverable without obscuring the underlying tile.
|
||||
**`draw_glyph(painter, origin, x, y, glyph, font, zoom)`** — computes the cell rect from `font.cell_size(zoom)`, delegates to `paint_glyph`.
|
||||
|
||||
**`draw_board(painter, origin, board, font, zoom)`** — iterates all cells calling `draw_glyph`, then draws objects and the player as overlays on top.
|
||||
|
||||
**`draw_object_overlays(painter, origin, board, font, selected, zoom)`** — called from Edit mode when the Objects tab is active. Draws a dim border on every object cell and a bright border on the selected one, making objects discoverable without obscuring the underlying tile.
|
||||
|
||||
**`pos_to_cell(origin, pos, tile_w, tile_h) -> (i32, i32)`** — converts a pixel position to cell coordinates using floor division. Returns negative values for clicks above/left of the origin; callers must guard `>= 0`. Mirrors the rendering math so clicks land on the correct cell.
|
||||
|
||||
**`board_origin(available, board_w, board_h, player, font) -> Pos2`** — computes the pixel origin for Play-mode rendering (centering or player-tracking with edge clamping).
|
||||
**`board_origin(available, board_w, board_h, player, font, zoom) -> Pos2`** — computes the pixel origin for Play-mode rendering (centering or player-tracking with edge clamping).
|
||||
|
||||
---
|
||||
|
||||
### `editor.rs` — editor state and side panel
|
||||
|
||||
**`EditorTab`** (`Palette` | `Board` | `Objects` | `World`) — which tab is active in the side panel.
|
||||
**`EditorTab`** (`Palette` | `Objects` | `Board` | `Scripts` | `World`) — which tab is active in the side panel.
|
||||
|
||||
**`EditorState`** — transient editor state:
|
||||
- `selected: Archetype` — the archetype class to stamp
|
||||
- `glyph: Glyph` — the visual to stamp (independent of the archetype's default; resets to `archetype.default_glyph()` when the archetype selection changes)
|
||||
- `glyph_picker_open: bool` — whether the glyph picker dialog is visible
|
||||
**`EditorState`** — transient editor state, grouped by concern into sub-structs so each tab can take only the borrow it needs (the dispatch in `show_editor_panel` passes disjoint sub-struct borrows, e.g. `&mut editor.objects` and `&mut editor.scripts`):
|
||||
- `tab: EditorTab` — which side-panel tab is active
|
||||
- `font_dialog_open: bool` — whether the font picker dialog is visible
|
||||
- `font_dialog_state: FontDialogState` — in-progress edits for the font dialog
|
||||
- `selected_object: Option<usize>` — index into `board.objects` of the currently selected object
|
||||
- `object_glyph_picker_open: bool` — whether the object glyph picker is open
|
||||
- `object_editing_glyph: Glyph` — local copy of the selected object's glyph; written back to `board.objects[i].glyph` every frame
|
||||
- `placing_object: bool` — when `true`, the next board click creates a new `ObjectDef` at that cell
|
||||
- `palette: PaletteState` — `selected: Archetype` (class to stamp), `glyph: Glyph` (visual to stamp; resets to `archetype.default_glyph()` when the archetype changes), `picker_open: bool`
|
||||
- `font_dialog: FontDialog` — `open: bool`, `state: FontDialogState`
|
||||
- `objects: ObjectEdit` — `selected: Option<usize>` (index into `board.objects`), `picker_open: bool`, `editing_glyph: Glyph` (local copy written back to `board.objects[i].glyph` each frame), `placing: bool` (next board click creates a new `ObjectDef`)
|
||||
- `scripts: ScriptEdit` — `editing: Option<String>` (script open in the code editor), `content: String` (working copy), `new_name: String` (new-script draft)
|
||||
|
||||
**`show_editor_panel(ctx, editor, board, active_font)`** — renders the resizable right-side panel (default 200 px). Palette tab: scrollable archetype list and glyph preview button. Board tab: current font path label + "Font…" button. Objects tab: "Add Object" button that enters placement mode; lists objects by coordinate with click-to-select; for the selected object shows glyph preview, **Passable** and **Opaque** checkboxes (writing directly to `board.objects[i]`), and a script combobox. World tab: placeholder.
|
||||
**`show_editor_panel(ctx, editor, board, active_font)`** — renders the resizable right-side panel (default 200 px): a tab bar, then dispatch to one function per tab. `palette_tab`: scrollable archetype list and glyph preview button. `objects_tab`: "Add Object" placement toggle, click-to-select, and for the selected object a glyph preview, **Passable**/**Opaque** checkboxes (writing directly to `board.objects[i]`), and a script combobox. `board_tab`: font path label + "Font…" button + zoom slider. `scripts_tab`: create and edit named scripts. World tab: placeholder. The glyph preview swatches use `render::glyph_preview_button`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user