Type-as-you-go suggestion popup above the input that filters known command names by substring (so `LEADER` surfaces both LEADER and MLEADER). Up / Down navigates the list, Enter dispatches the highlighted entry, clicking a row dispatches directly. Esc on a non-empty input clears the buffer instead of escalating to command-cancel. The name corpus comes from `inventory::submit!` blocks placed next to each `CadCommand` impl rather than a hand-maintained static list. Adding a new interactive command means dropping one `inventory::submit!` line in its own module file — the autocomplete picks it up at the next compile. 98 submissions seeded across 60 module files; `command::all_registered_command_names()` flattens them at runtime. One-shot dispatch arms in `app/commands.rs` (NEW, OPEN, SAVE, UNDO, …) don't have a `CadCommand` impl and are therefore absent from autocomplete by design. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
40 lines
967 B
Rust
40 lines
967 B
Rust
// ID command — report coordinates of a picked point.
|
|
|
|
use glam::Vec3;
|
|
|
|
use crate::command::{CadCommand, CmdResult};
|
|
|
|
pub struct IdCommand;
|
|
|
|
impl IdCommand {
|
|
pub fn new() -> Self {
|
|
Self
|
|
}
|
|
}
|
|
|
|
impl CadCommand for IdCommand {
|
|
fn name(&self) -> &'static str {
|
|
"ID"
|
|
}
|
|
|
|
fn prompt(&self) -> String {
|
|
"ID Specify point:".into()
|
|
}
|
|
|
|
fn on_point(&mut self, pt: Vec3) -> CmdResult {
|
|
// Y-up world: X stays X, Z→drawing Y, Y→elevation Z
|
|
let x = pt.x;
|
|
let y = pt.z;
|
|
let z = pt.y;
|
|
let msg = format!("X = {x:.4}, Y = {y:.4}, Z = {z:.4}");
|
|
CmdResult::Measurement(msg)
|
|
}
|
|
|
|
fn on_enter(&mut self) -> CmdResult {
|
|
CmdResult::Cancel
|
|
}
|
|
}
|
|
|
|
|
|
// ── Autocomplete registry ─────────────────────────────────
|
|
inventory::submit!(crate::command::CommandRegistration { names: &["ID"] }); // IdCommand
|