Aligned dimensional constraint: Point & line, 2Lines, value and property parity

DCALIGNED opens with `[Object/Point & line/2Lines] <Object>`. Point & line
asks `Specify constraint point or [Line] <Line>:` then `Select line:` (or the
line first and `Select constraint point:`), measures perpendicular to the
line from the constraint point to the line end nearest to it, and stores a
directed distance with the line as direction reference. 2Lines asks
`Select first line:` and `Select second line to make parallel:`, adds a
Parallel constraint solved with the first line pinned, then measures on the
solved geometry between the nearest ends. Unsupported line picks report the
reference's message; the same measurement again reports `The constraint
already exists on the selected objects.` and ends the command; an invalid
expression reports both reference lines and asks again.

The offered default and seeded expression carry twelve significant digits;
a typed value moves the second point (or the other object) while the first
point and its measured line stay, negative values keep their sign in the
parameter and use their magnitude, zero folds the points together, and the
dynamic dimension's origins follow every solve. The lock mark sits after the
text, a selected dynamic dimension shows triangle grips at its points and the
text square, and its Properties show the Constraint section (Name and
Expression editable) plus Text rotation.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ramox81andClaude Fable 5.1 committed 2026-09-21 14:52:37 +03:00
1 parent 971abe64a4
commit 6969c19746
8 files changed
+855 -64

No files matched your search

+10
View File
@@ -3259,6 +3259,16 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
}
pub(super) fn on_prop_geom_commit(&mut self, field: &'static str) -> Task<Message> {
use crate::ui::window::named_parameters::ParamField;
// A dynamic dimension's Name/Expression rows edit its parameter.
let dynamic_field = match field {
"dyn_constraint_name" => Some(ParamField::Name),
"dyn_constraint_expression" => Some(ParamField::Formula),
_ => None,
};
if let Some(param_field) = dynamic_field {
return self.on_dynamic_dimension_field_commit(field, param_field);
}
let i = self.active_tab;
self.tabs[i].properties.active_field = None;
let handles = self.property_target_handles(i);