Simplify main.rs: extract draw_board/pos_to_cell, deduplicate logic
- Extract draw_board() to eliminate duplicated board+player render loop in Edit and Play branches - Extract pos_to_cell() to eliminate duplicated click-to-cell floor math in board and char grid handlers - Simplify glyph dedup to use Glyph: PartialEq directly instead of manual key tuples - Merge two identical clicked() handlers in archetype list into one || check - Remove WHAT-explaining comments Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+35
-62
@@ -173,13 +173,9 @@ impl eframe::App for App {
|
||||
p.text(r.center(), Align2::CENTER_CENTER,
|
||||
glyph.ch, FontId::monospace(CELL_H), glyph.fg);
|
||||
}
|
||||
if cell_resp.clicked() {
|
||||
self.editor.selected = archetype;
|
||||
self.editor.glyph = archetype.default_glyph();
|
||||
}
|
||||
if ui.selectable_label(is_selected, archetype.name())
|
||||
.clicked()
|
||||
{
|
||||
let label_resp =
|
||||
ui.selectable_label(is_selected, archetype.name());
|
||||
if cell_resp.clicked() || label_resp.clicked() {
|
||||
self.editor.selected = archetype;
|
||||
self.editor.glyph = archetype.default_glyph();
|
||||
}
|
||||
@@ -227,29 +223,10 @@ impl eframe::App for App {
|
||||
// overflows the viewport, showing scroll bars as needed.
|
||||
egui::ScrollArea::new([true, true]).show(ui, |ui| {
|
||||
let (rect, response) = ui.allocate_exact_size(board_px, Sense::click());
|
||||
{
|
||||
let board = &self.state.board;
|
||||
let painter = ui.painter();
|
||||
for y in 0..board.height {
|
||||
for x in 0..board.width {
|
||||
let (glyph, _) = board.get(x, y);
|
||||
draw_glyph(painter, rect.min, x, y, glyph);
|
||||
}
|
||||
}
|
||||
let player_glyph = Glyph::player();
|
||||
draw_glyph(
|
||||
painter,
|
||||
rect.min,
|
||||
board.player.x as usize,
|
||||
board.player.y as usize,
|
||||
&player_glyph,
|
||||
);
|
||||
}
|
||||
draw_board(ui.painter(), rect.min, &self.state.board);
|
||||
if response.clicked() {
|
||||
if let Some(pos) = response.interact_pointer_pos() {
|
||||
let rel = pos - rect.min;
|
||||
let cx = (rel.x / CELL_W).floor() as i32;
|
||||
let cy = (rel.y / CELL_H).floor() as i32;
|
||||
let (cx, cy) = pos_to_cell(rect.min, pos);
|
||||
// floor() keeps out-of-bounds negatives negative; caught here.
|
||||
if cx >= 0 && cy >= 0 {
|
||||
let cx = cx as usize;
|
||||
@@ -268,27 +245,7 @@ impl eframe::App for App {
|
||||
let available = ui.available_rect_before_wrap();
|
||||
let player = self.state.board.player;
|
||||
let origin = board_origin(available, board_w, board_h, player);
|
||||
{
|
||||
let board = &self.state.board;
|
||||
let painter = ui.painter();
|
||||
for y in 0..board.height {
|
||||
for x in 0..board.width {
|
||||
let (glyph, _) = board.get(x, y);
|
||||
draw_glyph(painter, origin, x, y, glyph);
|
||||
}
|
||||
}
|
||||
// Draw the player on top of the board. The player is not stored as
|
||||
// a board cell, so it is rendered as a separate overlay. This will
|
||||
// change once the player becomes a scripted object.
|
||||
let player_glyph = Glyph::player();
|
||||
draw_glyph(
|
||||
painter,
|
||||
origin,
|
||||
board.player.x as usize,
|
||||
board.player.y as usize,
|
||||
&player_glyph,
|
||||
);
|
||||
}
|
||||
draw_board(ui.painter(), origin, &self.state.board);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -298,16 +255,13 @@ impl eframe::App for App {
|
||||
// Collect unique glyphs from the board before the window closure
|
||||
// borrows self mutably, to avoid a conflict with self.state.board.
|
||||
let board_glyphs: Vec<Glyph> = {
|
||||
let mut seen: Vec<(u32, [u8; 4], [u8; 4])> = Vec::new();
|
||||
let mut out: Vec<Glyph> = Vec::new();
|
||||
let mut seen: Vec<Glyph> = Vec::new();
|
||||
for (glyph, _) in &self.state.board.cells {
|
||||
let key = (glyph.ch as u32, glyph.fg.to_array(), glyph.bg.to_array());
|
||||
if !seen.contains(&key) {
|
||||
seen.push(key);
|
||||
out.push(*glyph);
|
||||
if !seen.contains(glyph) {
|
||||
seen.push(*glyph);
|
||||
}
|
||||
}
|
||||
out
|
||||
seen
|
||||
};
|
||||
|
||||
// Use a local bool so the window's close button can write to it
|
||||
@@ -365,7 +319,6 @@ impl eframe::App for App {
|
||||
let grid_size = vec2(CHAR_COLS as f32 * CELL_W, rows as f32 * CELL_H);
|
||||
let (grid_rect, grid_resp) =
|
||||
ui.allocate_exact_size(grid_size, Sense::click());
|
||||
// Copy colors and selected char before painter borrow.
|
||||
let fg = self.editor.glyph.fg;
|
||||
let bg = self.editor.glyph.bg;
|
||||
let cur_ch = self.editor.glyph.ch;
|
||||
@@ -388,17 +341,14 @@ impl eframe::App for App {
|
||||
}
|
||||
if grid_resp.clicked() {
|
||||
if let Some(pos) = grid_resp.interact_pointer_pos() {
|
||||
let rel = pos - grid_rect.min;
|
||||
let col = (rel.x / CELL_W).floor() as usize;
|
||||
let row = (rel.y / CELL_H).floor() as usize;
|
||||
let idx = row * CHAR_COLS + col;
|
||||
let (col, row) = pos_to_cell(grid_rect.min, pos);
|
||||
let idx = row as usize * CHAR_COLS + col as usize;
|
||||
if let Some(&ch) = chars.get(idx) {
|
||||
self.editor.glyph.ch = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// Window's close button sets picker_open to false.
|
||||
self.editor.glyph_picker_open = picker_open;
|
||||
}
|
||||
|
||||
@@ -425,6 +375,29 @@ fn draw_glyph(painter: &egui::Painter, origin: Pos2, x: usize, y: usize, glyph:
|
||||
painter.text(center, Align2::CENTER_CENTER, glyph.ch, FontId::monospace(CELL_H), glyph.fg);
|
||||
}
|
||||
|
||||
/// Draws all board cells then the player overlay at `origin`.
|
||||
fn draw_board(painter: &egui::Painter, origin: Pos2, board: &game::Board) {
|
||||
for y in 0..board.height {
|
||||
for x in 0..board.width {
|
||||
let (glyph, _) = board.get(x, y);
|
||||
draw_glyph(painter, origin, x, y, glyph);
|
||||
}
|
||||
}
|
||||
// The player is not a board cell; it is rendered on top as an overlay.
|
||||
// This separate draw will be removed once the player becomes a scripted object.
|
||||
let player_glyph = Glyph::player();
|
||||
draw_glyph(painter, origin, board.player.x as usize, board.player.y as usize, &player_glyph);
|
||||
}
|
||||
|
||||
/// Converts a pixel position to cell coordinates relative to `origin`.
|
||||
///
|
||||
/// Uses floor so positions above or left of `origin` produce negative values —
|
||||
/// callers must guard `>= 0` before treating the result as a valid cell index.
|
||||
fn pos_to_cell(origin: Pos2, pos: Pos2) -> (i32, i32) {
|
||||
let rel = pos - origin;
|
||||
((rel.x / CELL_W).floor() as i32, (rel.y / CELL_H).floor() as i32)
|
||||
}
|
||||
|
||||
/// Computes the pixel position of board cell (0, 0) within `available`.
|
||||
///
|
||||
/// If the board fits along an axis, it is centered. If it overflows, the
|
||||
|
||||
Reference in New Issue
Block a user