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,
|
p.text(r.center(), Align2::CENTER_CENTER,
|
||||||
glyph.ch, FontId::monospace(CELL_H), glyph.fg);
|
glyph.ch, FontId::monospace(CELL_H), glyph.fg);
|
||||||
}
|
}
|
||||||
if cell_resp.clicked() {
|
let label_resp =
|
||||||
self.editor.selected = archetype;
|
ui.selectable_label(is_selected, archetype.name());
|
||||||
self.editor.glyph = archetype.default_glyph();
|
if cell_resp.clicked() || label_resp.clicked() {
|
||||||
}
|
|
||||||
if ui.selectable_label(is_selected, archetype.name())
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
self.editor.selected = archetype;
|
self.editor.selected = archetype;
|
||||||
self.editor.glyph = archetype.default_glyph();
|
self.editor.glyph = archetype.default_glyph();
|
||||||
}
|
}
|
||||||
@@ -227,29 +223,10 @@ impl eframe::App for App {
|
|||||||
// overflows the viewport, showing scroll bars as needed.
|
// overflows the viewport, showing scroll bars as needed.
|
||||||
egui::ScrollArea::new([true, true]).show(ui, |ui| {
|
egui::ScrollArea::new([true, true]).show(ui, |ui| {
|
||||||
let (rect, response) = ui.allocate_exact_size(board_px, Sense::click());
|
let (rect, response) = ui.allocate_exact_size(board_px, Sense::click());
|
||||||
{
|
draw_board(ui.painter(), rect.min, &self.state.board);
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if response.clicked() {
|
if response.clicked() {
|
||||||
if let Some(pos) = response.interact_pointer_pos() {
|
if let Some(pos) = response.interact_pointer_pos() {
|
||||||
let rel = pos - rect.min;
|
let (cx, cy) = pos_to_cell(rect.min, pos);
|
||||||
let cx = (rel.x / CELL_W).floor() as i32;
|
|
||||||
let cy = (rel.y / CELL_H).floor() as i32;
|
|
||||||
// floor() keeps out-of-bounds negatives negative; caught here.
|
// floor() keeps out-of-bounds negatives negative; caught here.
|
||||||
if cx >= 0 && cy >= 0 {
|
if cx >= 0 && cy >= 0 {
|
||||||
let cx = cx as usize;
|
let cx = cx as usize;
|
||||||
@@ -268,27 +245,7 @@ impl eframe::App for App {
|
|||||||
let available = ui.available_rect_before_wrap();
|
let available = ui.available_rect_before_wrap();
|
||||||
let player = self.state.board.player;
|
let player = self.state.board.player;
|
||||||
let origin = board_origin(available, board_w, board_h, player);
|
let origin = board_origin(available, board_w, board_h, player);
|
||||||
{
|
draw_board(ui.painter(), origin, &self.state.board);
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -298,16 +255,13 @@ impl eframe::App for App {
|
|||||||
// Collect unique glyphs from the board before the window closure
|
// Collect unique glyphs from the board before the window closure
|
||||||
// borrows self mutably, to avoid a conflict with self.state.board.
|
// borrows self mutably, to avoid a conflict with self.state.board.
|
||||||
let board_glyphs: Vec<Glyph> = {
|
let board_glyphs: Vec<Glyph> = {
|
||||||
let mut seen: Vec<(u32, [u8; 4], [u8; 4])> = Vec::new();
|
let mut seen: Vec<Glyph> = Vec::new();
|
||||||
let mut out: Vec<Glyph> = Vec::new();
|
|
||||||
for (glyph, _) in &self.state.board.cells {
|
for (glyph, _) in &self.state.board.cells {
|
||||||
let key = (glyph.ch as u32, glyph.fg.to_array(), glyph.bg.to_array());
|
if !seen.contains(glyph) {
|
||||||
if !seen.contains(&key) {
|
seen.push(*glyph);
|
||||||
seen.push(key);
|
|
||||||
out.push(*glyph);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out
|
seen
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use a local bool so the window's close button can write to it
|
// 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_size = vec2(CHAR_COLS as f32 * CELL_W, rows as f32 * CELL_H);
|
||||||
let (grid_rect, grid_resp) =
|
let (grid_rect, grid_resp) =
|
||||||
ui.allocate_exact_size(grid_size, Sense::click());
|
ui.allocate_exact_size(grid_size, Sense::click());
|
||||||
// Copy colors and selected char before painter borrow.
|
|
||||||
let fg = self.editor.glyph.fg;
|
let fg = self.editor.glyph.fg;
|
||||||
let bg = self.editor.glyph.bg;
|
let bg = self.editor.glyph.bg;
|
||||||
let cur_ch = self.editor.glyph.ch;
|
let cur_ch = self.editor.glyph.ch;
|
||||||
@@ -388,17 +341,14 @@ impl eframe::App for App {
|
|||||||
}
|
}
|
||||||
if grid_resp.clicked() {
|
if grid_resp.clicked() {
|
||||||
if let Some(pos) = grid_resp.interact_pointer_pos() {
|
if let Some(pos) = grid_resp.interact_pointer_pos() {
|
||||||
let rel = pos - grid_rect.min;
|
let (col, row) = pos_to_cell(grid_rect.min, pos);
|
||||||
let col = (rel.x / CELL_W).floor() as usize;
|
let idx = row as usize * CHAR_COLS + col as usize;
|
||||||
let row = (rel.y / CELL_H).floor() as usize;
|
|
||||||
let idx = row * CHAR_COLS + col;
|
|
||||||
if let Some(&ch) = chars.get(idx) {
|
if let Some(&ch) = chars.get(idx) {
|
||||||
self.editor.glyph.ch = ch;
|
self.editor.glyph.ch = ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Window's close button sets picker_open to false.
|
|
||||||
self.editor.glyph_picker_open = picker_open;
|
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);
|
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`.
|
/// 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
|
/// If the board fits along an axis, it is centered. If it overflows, the
|
||||||
|
|||||||
Reference in New Issue
Block a user