forked from 1b-agent/opencadstudio-upstream
Add named parameters, UI scale setting, OPTIONS/OP dispatch, and help manual
Named parameters (docs/named_parameters_design.md, stages 3-4): - ParameterTable (src/scene/named_parameters.rs): a document-wide table of named formulas, each resolved through a shared expression evaluator with cross-parameter references, cycle detection, and division-by-zero/parse error reporting. SketchConstraint::driving_param becomes DrivingValue (Literal | Named) instead of a bare f64, resolved at solve time by sketch_solve::build_constraint via Scene::named_parameters. - Persistence (src/scene/named_parameters_persist.rs): same lazy XRecord model sketch_persist.rs already established, synced around open/save. Bumps the sketch-constraint XRecord's own format version (1 -> 2) since DrivingValue's shape doesn't line up with a version-1 blob's bytes. - PARAMETERS command and its editor (src/ui/window/named_parameters.rs): add/remove/edit rows, live validation, duplicate-name detection: Apply defines the table and re-solves every constraint scope with a named-parameter-driven constraint (command_driver.rs). Distance/Angle constraint prompts (modules/draw/constrain/value.rs) now accept either a literal or an existing parameter's name, mirroring how the constraint's own value prompt already worked. - Undo scope-down carried over from this project's own established pattern (constraint-system stage 9): the geometry an Apply moves is one undo step, but the parameter table edit itself has no undo entry yet — a documented follow-up, not a silent gap. UI scale setting (src/app/settings.rs, app/mod.rs, ui/window/options.rs): a whole-interface scale percentage (50-200%), wired directly into iced's own per-window scale_factor hook rather than per-panel font-size plumbing, so it applies immediately to every panel, dialog, and the ribbon at once. Persisted alongside the existing lineweight-display-scale setting. OPTIONS/OP command dispatch (app/commands/view.rs, app/commands/mod.rs): OPTIONS was registered for autocomplete but had no dispatch arm — the Start-tab welcome screen's own button was the only way to reach it. Found live-testing the UI-scale setting, unrelated to that feature itself. "OP" is AutoCAD's own short alias. help/: a new self-contained static user-help manual (manual.md as the authored source, tools/build_help.py splits it into the committed static HTML pages plus search index) — not yet wired into the application. 64 new/updated tests across the named-parameters and constraint-prompt changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e2d39b049d
commit
7cddf31bcb
47 files changed
+4136
-52
No files matched your search
@@ -48,7 +48,15 @@ fn remove_xrecord(document: &mut CadDocument, owner: Handle, key: &str) {
|
||||
/// or panicking — design doc §5.2's explicit call-out, and §7's flagged
|
||||
/// "no migration path designed yet": bumping this is the signal a real
|
||||
/// migration is needed, not a substitute for one.
|
||||
const FORMAT_VERSION: u8 = 1;
|
||||
///
|
||||
/// Bumped 1 -> 2 by `named_parameters_design.md` stage 3:
|
||||
/// `SketchConstraint::driving_param` changed from a bare `Option<f64>` to
|
||||
/// `Option<named_parameters::DrivingValue>` (an enum, with its own
|
||||
/// discriminant), so a version-1 blob's bytes no longer line up with the
|
||||
/// current struct shape — exactly the "detected and gracefully skipped"
|
||||
/// case this version byte exists for, not something to migrate (no
|
||||
/// migration path exists yet, per the call-out above).
|
||||
const FORMAT_VERSION: u8 = 2;
|
||||
|
||||
fn encode(set: &SketchConstraintSet) -> Option<Vec<u8>> {
|
||||
let mut bytes = vec![FORMAT_VERSION];
|
||||
@@ -192,7 +200,11 @@ mod tests {
|
||||
vec![SketchRef::point(a, 1), SketchRef::point(b, 0)],
|
||||
None,
|
||||
);
|
||||
scene.sketch_constraint_set_mut(SketchScope::ModelSpace).add(ConstraintKind::Distance, vec![SketchRef::whole(b)], Some(12.5));
|
||||
scene.sketch_constraint_set_mut(SketchScope::ModelSpace).add(
|
||||
ConstraintKind::Distance,
|
||||
vec![SketchRef::whole(b)],
|
||||
Some(crate::scene::named_parameters::DrivingValue::Literal(12.5)),
|
||||
);
|
||||
|
||||
scene.materialize_sketch_constraints_for_save();
|
||||
let bytes = crate::io::save_to_bytes(&scene.document, ext, scene.document.version)
|
||||
@@ -213,7 +225,7 @@ mod tests {
|
||||
assert_eq!(restored.constraints.len(), 2);
|
||||
assert_eq!(restored.constraints[0].kind, ConstraintKind::Coincident);
|
||||
assert_eq!(restored.constraints[1].kind, ConstraintKind::Distance);
|
||||
assert_eq!(restored.constraints[1].driving_param, Some(12.5));
|
||||
assert_eq!(restored.constraints[1].driving_param, Some(crate::scene::named_parameters::DrivingValue::Literal(12.5)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -222,7 +234,7 @@ mod tests {
|
||||
assert_eq!(restored.constraints.len(), 2);
|
||||
assert_eq!(restored.constraints[0].kind, ConstraintKind::Coincident);
|
||||
assert_eq!(restored.constraints[1].kind, ConstraintKind::Distance);
|
||||
assert_eq!(restored.constraints[1].driving_param, Some(12.5));
|
||||
assert_eq!(restored.constraints[1].driving_param, Some(crate::scene::named_parameters::DrivingValue::Literal(12.5)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user