Files
vectorcraft/crates/ui-egui/src/dialogs/command.rs
T
bflatasticandClaude Opus 5.5 8255d606ae M8.14: Type and symbols in perspective are really projected and stay editable; attachments survive copies
Type and symbol instances attached to a plane keep their art and carry a projection
(Node.perspective.projection, append-only); the canvas and every export draw their outlines
through it (reshape/bake), so they are foreshortened and stay type and symbol instances. Bounds,
hit testing and transforms follow the projection. Object › Perspective › Edit Text
(perspective.editText, or double-clicking with the Perspective Selection tool) shows the type flat
where it is drawn in isolation mode; exiting isolation projects it again. Release with
Perspective keeps their look. Copies, pastes, duplicates and Selection-tool moves keep the
attachment (the art moves as dragged). Flare, spiral and polar grid draw on the active plane, and
so do the click-to-size shape dialogs (perspective.draw `at`: sizes in plane units).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:10:00 +07:00

48 lines
1.7 KiB
Rust

//! The generic parameter dialog (`ui.paramDialog`): edits a command's parameters (`__command`,
//! headed `__label`) and runs it on OK.
use serde_json::Value;
use super::{DialogSpec, form};
use crate::VectorcraftApp;
use crate::state::Dialog;
pub(super) const SPEC: DialogSpec = DialogSpec {
heading: |d| d.str("__label"),
body: |app, ui, d| {
let lengths = lengths(&d.str("__command"));
form::param_fields(ui, d, &|k| lengths.contains(&k), app.session.general_unit());
false
},
confirm,
..DialogSpec::FORM
};
/// The parameters of the commands this dialog edits that are distances.
fn lengths(command: &str) -> &'static [&'static str] {
match command {
"graph.create" => &["width", "height"],
"shape.flare" => &["diameter", "pathLength"],
"artboard.rearrange" => &["spacing"],
"perspective.grid.set" => &["cell", "distance"],
"object.repeat.options" => &["radius", "hSpacing", "vSpacing"],
"text.areaOptions" => &["gutter", "inset", "firstBaselineMin"],
_ => &[],
}
}
/// Closes before running, so a dialog the command opens stays open.
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
let cmd = d.str("__command");
let params = form::params(d);
app.ui.dialog = None;
// A tool's click-to-size shape (Flare) goes on the active perspective plane while the grid shows.
let at = |x: &str, y: &str| Some(vectorcraft_geom::Point::new(params.get(x)?.as_f64()?, params.get(y)?.as_f64()?));
if let Some((c, p)) =
at("cx", "cy").or_else(|| at("x", "y")).and_then(|pt| vectorcraft_engine::perspective_click(&app.session, &cmd, &params, pt))
{
return app.run(&c, p);
}
app.run(&cmd, params)
}