glyph picker

This commit is contained in:
2026-06-20 15:27:09 -05:00
parent e74d015d1b
commit 05142e5712
12 changed files with 638 additions and 26 deletions
+44
View File
@@ -10,6 +10,7 @@
use kiln_ui::code_editor::{CodeEditor, CodeEditorOutcome};
use kiln_ui::dialog::{Dialog, DialogResult, ListDialogResponse};
use kiln_ui::glyph_dialog::GlyphDialog;
use crate::log::{log_preview_line, LogWidget};
use crate::render::{board_to_screen, screen_to_board, BoardWidget};
use crate::ui::Ui;
@@ -55,6 +56,9 @@ pub(crate) struct EditorState {
/// The open script code editor, if any. While `Some` it replaces the board view and
/// the editor is in [`InputMode::CodeEditor`](crate::input::InputMode::CodeEditor).
pub(crate) code_editor: Option<CodeEditor>,
/// The open glyph picker overlay, if any. While `Some` the editor is in
/// [`InputMode::GlyphDialog`](crate::input::InputMode::GlyphDialog).
pub(crate) glyph_dialog: Option<GlyphDialog<EditorState>>,
/// Cursor position in board cells, clamped to the board bounds.
cursor: (i32, i32),
/// Width of the right-hand sidebar in terminal columns (mouse-resizable).
@@ -81,6 +85,7 @@ impl EditorState {
menu: vec![MenuLevel::Main],
dialog: None,
code_editor: None,
glyph_dialog: None,
cursor: (0, 0),
sidebar_width: DEFAULT_SIDEBAR_WIDTH,
blink_on: true,
@@ -176,6 +181,27 @@ impl EditorState {
self.dialog = Some(Dialog::list("Boards", names, false, |_resp, _ed: &mut EditorState| {}));
}
/// Opens the glyph picker seeded from the glyph currently under the cursor.
/// On OK the chosen glyph is logged (there is no paint tool yet).
pub(crate) fn open_glyph_picker(&mut self) {
let glyph = {
let board = self.board();
board.glyph_at(self.cursor.0 as usize, self.cursor.1 as usize)
};
self.glyph_dialog = Some(GlyphDialog::new(
"Glyph",
glyph,
|chosen, ed: &mut EditorState| {
if let Some(g) = chosen {
ed.log.push(LogLine::raw(format!(
"glyph tile={} fg=#{:02X}{:02X}{:02X} bg=#{:02X}{:02X}{:02X}",
g.tile, g.fg.r, g.fg.g, g.fg.b, g.bg.r, g.bg.g, g.bg.b
)));
}
},
));
}
/// Borrows the board currently being edited.
pub(crate) fn board(&self) -> Ref<'_, Board> {
self.world.boards[&self.board_name].borrow()
@@ -235,6 +261,24 @@ pub(crate) fn handle_dialog_input(event: Event, ed: &mut EditorState) {
}
}
/// Handles an input event while the glyph picker is open ([`InputMode::GlyphDialog`](crate::input::InputMode::GlyphDialog)).
///
/// Mirrors [`handle_dialog_input`]: forwards to the picker and, on `Submit`/`Cancel`,
/// takes it out of [`EditorState::glyph_dialog`] and fires its callback via
/// [`GlyphDialog::finish`].
pub(crate) fn handle_glyph_dialog_input(event: Event, ed: &mut EditorState) {
let Some(dialog) = ed.glyph_dialog.as_mut() else {
return;
};
match dialog.handle_event(&event) {
DialogResult::Continue => {}
result => {
let dialog = ed.glyph_dialog.take().expect("glyph dialog present");
dialog.finish(result, ed);
}
}
}
/// Handles an input event while the code editor is open ([`InputMode::CodeEditor`](crate::input::InputMode::CodeEditor)).
///
/// Forwards key/mouse events to the editor; on `Exit` (Esc) it closes and saves the script.