mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 02:37:01 -06:00
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>
48 lines
1.7 KiB
Rust
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, ¶ms, pt))
|
|
{
|
|
return app.run(&c, p);
|
|
}
|
|
app.run(&cmd, params)
|
|
}
|