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
@@ -368,6 +368,7 @@ impl OpenCADStudio {
|
||||
cursor_type: self.cursor_type,
|
||||
crosshair_color: self.crosshair_color,
|
||||
lineweight_display_scale: self.lineweight_display_scale,
|
||||
ui_scale: self.ui_scale,
|
||||
isometric_drafting: self.isometric_drafting,
|
||||
iso_plane: self.iso_plane,
|
||||
snap_angle_deg: self.snap_angle_deg,
|
||||
@@ -425,6 +426,7 @@ impl OpenCADStudio {
|
||||
.map(crate::app::config::rgb_to_hex)
|
||||
.unwrap_or_default();
|
||||
self.lineweight_display_scale = s.lineweight_display_scale.clamp(25, 200);
|
||||
self.ui_scale = s.ui_scale.clamp(50, 200);
|
||||
self.isometric_drafting = s.isometric_drafting;
|
||||
self.iso_plane = s.iso_plane;
|
||||
self.snap_angle_deg = if s.snap_angle_deg.is_finite() {
|
||||
@@ -1394,6 +1396,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
// Design doc §8 stage 4: read back any persisted sketch
|
||||
// constraint sets right after the document is installed.
|
||||
self.tabs[i].scene.load_sketch_constraints_from_document();
|
||||
// named_parameters_design.md stage 2: same load-time hook,
|
||||
// for the document-wide parameter table.
|
||||
self.tabs[i].scene.load_named_parameters_from_document();
|
||||
self.tabs[i].active_layer = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
@@ -1660,6 +1665,9 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
// Design doc §8 stage 4: write any sketch constraint sets into the
|
||||
// document right before it's serialized.
|
||||
self.tabs[i].scene.materialize_sketch_constraints_for_save();
|
||||
// named_parameters_design.md stage 2: same save-time hook, for the
|
||||
// document-wide parameter table.
|
||||
self.tabs[i].scene.materialize_named_parameters_for_save();
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -2611,6 +2619,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
self.stamp_header_sysvars(i);
|
||||
self.sync_solid_models_for_save(i);
|
||||
self.tabs[i].scene.materialize_sketch_constraints_for_save();
|
||||
self.tabs[i].scene.materialize_named_parameters_for_save();
|
||||
let tab_id = self.tabs[i].id;
|
||||
let bounds = crate::ui::wrap_bar::dropdown_bounds(
|
||||
crate::app::view::VIEWPORT_CAPTURE_BOUNDS_ID,
|
||||
|
||||
@@ -5861,6 +5861,43 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// ── Named Parameters (PARAMETERS) ─────────────────────────────────
|
||||
Message::NamedParametersOpen => {
|
||||
let i = self.active_tab;
|
||||
self.named_parameter_editor_rows = self.tabs[i]
|
||||
.scene
|
||||
.named_parameters()
|
||||
.iter()
|
||||
.map(|p| crate::ui::window::named_parameters::ParamEditorRow { name: p.name.clone(), formula: p.source.clone() })
|
||||
.collect();
|
||||
self.active_modal = Some(super::ModalKind::NamedParameters);
|
||||
Task::none()
|
||||
}
|
||||
Message::NamedParametersInput { idx, field, value } => {
|
||||
use crate::ui::window::named_parameters::ParamField;
|
||||
if let Some(row) = self.named_parameter_editor_rows.get_mut(idx) {
|
||||
match field {
|
||||
ParamField::Name => row.name = value,
|
||||
ParamField::Formula => row.formula = value,
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::NamedParametersAdd => {
|
||||
self.named_parameter_editor_rows.push(crate::ui::window::named_parameters::ParamEditorRow::default());
|
||||
Task::none()
|
||||
}
|
||||
Message::NamedParametersRemove(idx) => {
|
||||
if idx < self.named_parameter_editor_rows.len() {
|
||||
self.named_parameter_editor_rows.remove(idx);
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::NamedParametersApply => {
|
||||
self.apply_named_parameter_editor_rows();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// ── Options / About windows ───────────────────────────────────
|
||||
Message::OptionsOpen => {
|
||||
self.active_modal = Some(super::ModalKind::Options);
|
||||
@@ -5900,6 +5937,12 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::UiScaleChanged(value) => {
|
||||
self.ui_scale = value.clamp(50, 200);
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::RibbonLabelFontSizeChanged(value) => {
|
||||
self.ribbon.set_label_font_size(value);
|
||||
self.save_config();
|
||||
|
||||
Reference in new issue
Block a user