Refactor main.rs into focused modules: render, editor, glyph_picker
Splits the flat 432-line main.rs into four modules so each file has one clear job: render.rs owns layout constants and drawing primitives, editor.rs owns EditorTab/EditorState and the side panel, glyph_picker.rs owns the floating picker dialog with a decoupled (open, glyph) interface, and main.rs is reduced to AppMode, App, and the frame loop (~150 lines). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
use eframe::egui;
|
||||
use egui::{Align2, Color32, FontId, Rect, Sense, Stroke, vec2};
|
||||
|
||||
use crate::game::{Archetype, Glyph};
|
||||
use crate::render::{CELL_H, CELL_W, pos_to_cell};
|
||||
|
||||
/// Renders the floating glyph-picker dialog and updates `glyph` in place.
|
||||
///
|
||||
/// Shows three sections: board palette (unique glyphs on the current board),
|
||||
/// FG/BG color pickers, and a 16×6 printable-ASCII character grid.
|
||||
/// Closes when the window's X button is clicked, writing `false` to `open`.
|
||||
pub(crate) fn show(
|
||||
ctx: &egui::Context,
|
||||
open: &mut bool,
|
||||
glyph: &mut Glyph,
|
||||
board_cells: &[(Glyph, Archetype)],
|
||||
) {
|
||||
// Collect unique glyphs from the board before the window closure borrows
|
||||
// `glyph` mutably, to avoid a borrow conflict with `board_cells`.
|
||||
let board_glyphs: Vec<Glyph> = {
|
||||
let mut seen: Vec<Glyph> = Vec::new();
|
||||
for (g, _) in board_cells {
|
||||
if !seen.contains(g) {
|
||||
seen.push(*g);
|
||||
}
|
||||
}
|
||||
seen
|
||||
};
|
||||
|
||||
egui::Window::new("Glyph")
|
||||
.collapsible(false)
|
||||
.resizable(false)
|
||||
.open(open)
|
||||
.show(ctx, |ui| {
|
||||
// ----- Board palette -----
|
||||
ui.label("Board palette");
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for &g in &board_glyphs {
|
||||
let (r, resp) =
|
||||
ui.allocate_exact_size(vec2(CELL_W, CELL_H), Sense::click());
|
||||
{
|
||||
let p = ui.painter();
|
||||
p.rect_filled(r, 0.0, g.bg);
|
||||
p.text(r.center(), Align2::CENTER_CENTER, g.ch,
|
||||
FontId::monospace(CELL_H), g.fg);
|
||||
if g == *glyph {
|
||||
p.rect_stroke(r, 0.0, Stroke::new(1.0, Color32::WHITE),
|
||||
egui::epaint::StrokeKind::Middle);
|
||||
}
|
||||
}
|
||||
if resp.clicked() {
|
||||
*glyph = g;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
||||
// ----- Colors -----
|
||||
ui.label("Colors");
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("FG");
|
||||
egui::color_picker::color_edit_button_srgba(
|
||||
ui, &mut glyph.fg, egui::color_picker::Alpha::Opaque);
|
||||
ui.label("BG");
|
||||
egui::color_picker::color_edit_button_srgba(
|
||||
ui, &mut glyph.bg, egui::color_picker::Alpha::Opaque);
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
||||
// ----- Character grid -----
|
||||
// 16 columns × 6 rows covering printable ASCII 0x20–0x7E.
|
||||
ui.label("Character");
|
||||
const CHAR_COLS: usize = 16;
|
||||
let chars: Vec<char> =
|
||||
(0x20u32..=0x7eu32).filter_map(char::from_u32).collect();
|
||||
let rows = chars.len().div_ceil(CHAR_COLS);
|
||||
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());
|
||||
let fg = glyph.fg;
|
||||
let bg = glyph.bg;
|
||||
let cur_ch = glyph.ch;
|
||||
{
|
||||
let p = ui.painter();
|
||||
for (i, &ch) in chars.iter().enumerate() {
|
||||
let col = i % CHAR_COLS;
|
||||
let row = i / CHAR_COLS;
|
||||
let tl = grid_rect.min
|
||||
+ vec2(col as f32 * CELL_W, row as f32 * CELL_H);
|
||||
let cell = Rect::from_min_size(tl, vec2(CELL_W, CELL_H));
|
||||
p.rect_filled(cell, 0.0, bg);
|
||||
p.text(cell.center(), Align2::CENTER_CENTER, ch,
|
||||
FontId::monospace(CELL_H), fg);
|
||||
if ch == cur_ch {
|
||||
p.rect_stroke(cell, 0.0, Stroke::new(1.0, Color32::WHITE),
|
||||
egui::epaint::StrokeKind::Middle);
|
||||
}
|
||||
}
|
||||
}
|
||||
if grid_resp.clicked()
|
||||
&& let Some(pos) = grid_resp.interact_pointer_pos() {
|
||||
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) {
|
||||
glyph.ch = ch;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user