//! Typed coordinates (xfig's keyboard panel, `w_keyboard.c`, Ctrl+K in xfig; //! xfig licence, see LICENSE-xfig): a small window with a text field; Enter //! (or a button) runs `tool.point`, which uses the typed point as if the //! canvas had been clicked with that mouse button. The last entries are //! kept as a history to click. use crate::App; use serde_json::json; const MAX_HISTORY: usize = 10; /// State of the entry window. #[derive(Default)] pub struct PointEntry { pub open: bool, pub text: String, pub history: Vec, pub error: String, focus: bool, } impl PointEntry { pub fn open(&mut self) { self.open = true; self.focus = true; } } fn submit(app: &mut App, button: &str) { let text = app.point_entry.text.trim().to_string(); if text.is_empty() { return; } match app.try_run("tool.point", &json!({"text": text, "button": button})) { Ok(_) => { let h = &mut app.point_entry.history; h.retain(|t| *t != text); h.insert(0, text); h.truncate(MAX_HISTORY); app.point_entry.text.clear(); app.point_entry.error.clear(); } Err(e) => app.point_entry.error = e, } app.point_entry.focus = true; } /// Draw the window when it is open. pub fn show(app: &mut App, ctx: &egui::Context) { if !app.point_entry.open { return; } let mut open = true; egui::Window::new("Xfig: Keyboard") .open(&mut open) .resizable(false) .default_pos(egui::pos2(300.0, 200.0)) .show(ctx, |ui| { crate::dialog_body(ui, |ui| { ui.label("Point as x,y or length