fix(dynin): read a comma-separated second point as cartesian, not W/H
A rectangle's opposite corner is entered through Width/Height dynamic fields, whose sign is taken from the cursor quadrant on commit. Typing "50,50" is a cartesian coordinate pair, not two cursor-signed dimensions, but the comma advance kept the Width/Height roles so the committed corner mirrored into whatever quadrant the cursor sat in. Key off `dyn_user_reshaped` (set only by `,`, never by Tab) to treat a comma-separated entry as a literal cartesian coordinate for every field, in both the point resolver and the live dyn-box display. Tab-separated entry still reads as signed Width/Height dimensions. Closes #269 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
62680883cd
commit
450dbf79ac
3 changed files with 25 additions and 6 deletions
|
|
@ -212,8 +212,15 @@ impl OpenCADStudio {
|
||||||
.unwrap_or(glam::Vec3::ZERO);
|
.unwrap_or(glam::Vec3::ZERO);
|
||||||
// Buffer value parsed as f32 (de-scaled by the role so a typed diameter
|
// Buffer value parsed as f32 (de-scaled by the role so a typed diameter
|
||||||
// becomes a radius), or the supplied geometric live value. Width/Height
|
// becomes a radius), or the supplied geometric live value. Width/Height
|
||||||
// are shown unsigned, so a typed value takes the sign of the cursor's
|
// are shown unsigned, so a typed value normally takes the sign of the
|
||||||
// delta on that axis (`live` is the signed delta in the cartesian arms).
|
// cursor's delta on that axis (`live` is the signed delta in the
|
||||||
|
// cartesian arms). But once the user separates the two values with `,`
|
||||||
|
// — e.g. the rectangle opposite corner entered as "50,50" — the entry
|
||||||
|
// is a cartesian coordinate pair, not cursor-signed W/H dimensions, so
|
||||||
|
// the typed sign must stay literal. `,` is the only thing that sets
|
||||||
|
// `dyn_user_reshaped`, so it cleanly distinguishes comma-cartesian entry
|
||||||
|
// from Tab-separated dimension entry (#269).
|
||||||
|
let comma_cartesian = self.dyn_user_reshaped;
|
||||||
let val = |idx: usize, live: f32| -> f32 {
|
let val = |idx: usize, live: f32| -> f32 {
|
||||||
match fields[idx]
|
match fields[idx]
|
||||||
.buffer
|
.buffer
|
||||||
|
|
@ -226,7 +233,8 @@ impl OpenCADStudio {
|
||||||
if matches!(
|
if matches!(
|
||||||
fields[idx].role,
|
fields[idx].role,
|
||||||
crate::command::DynRole::Width | crate::command::DynRole::Height
|
crate::command::DynRole::Width | crate::command::DynRole::Height
|
||||||
) {
|
) && !comma_cartesian
|
||||||
|
{
|
||||||
v.abs().copysign(live)
|
v.abs().copysign(live)
|
||||||
} else {
|
} else {
|
||||||
v
|
v
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,7 @@ pub(super) fn dyn_component_value(
|
||||||
w: glam::Vec3,
|
w: glam::Vec3,
|
||||||
base: Option<glam::Vec3>,
|
base: Option<glam::Vec3>,
|
||||||
xf: &super::super::helpers::UcsXform,
|
xf: &super::super::helpers::UcsXform,
|
||||||
|
comma_cartesian: bool,
|
||||||
) -> String {
|
) -> String {
|
||||||
if let Some(b) = &f.buffer {
|
if let Some(b) = &f.buffer {
|
||||||
return b.clone();
|
return b.clone();
|
||||||
|
|
@ -211,8 +212,12 @@ pub(super) fn dyn_component_value(
|
||||||
// coordinate use the same frame. See #35.
|
// coordinate use the same frame. See #35.
|
||||||
let has_base = base.is_some();
|
let has_base = base.is_some();
|
||||||
// Width / Height read as unsigned magnitudes (the sign is taken from the
|
// Width / Height read as unsigned magnitudes (the sign is taken from the
|
||||||
// cursor side on commit), matching the rectangle's two-edge entry.
|
// cursor side on commit), matching the rectangle's two-edge entry. But once
|
||||||
let wh = matches!(f.role, crate::command::DynRole::Width | crate::command::DynRole::Height);
|
// the user separates the values with `,` the entry is a cartesian
|
||||||
|
// coordinate pair, so the fields read as signed X/Y deltas to match the
|
||||||
|
// committed point (#269).
|
||||||
|
let wh = matches!(f.role, crate::command::DynRole::Width | crate::command::DynRole::Height)
|
||||||
|
&& !comma_cartesian;
|
||||||
match f.component {
|
match f.component {
|
||||||
DynComponent::X if has_base => format!("{:.4}", if wh { dx.abs() } else { dx }),
|
DynComponent::X if has_base => format!("{:.4}", if wh { dx.abs() } else { dx }),
|
||||||
DynComponent::Y if has_base => format!("{:.4}", if wh { dy.abs() } else { dy }),
|
DynComponent::Y if has_base => format!("{:.4}", if wh { dy.abs() } else { dy }),
|
||||||
|
|
|
||||||
|
|
@ -524,7 +524,13 @@ impl OpenCADStudio {
|
||||||
{
|
{
|
||||||
format!("{lv:.4}")
|
format!("{lv:.4}")
|
||||||
}
|
}
|
||||||
_ => dyn_component_value(f, w, base, &tab.ucs_xform()),
|
_ => dyn_component_value(
|
||||||
|
f,
|
||||||
|
w,
|
||||||
|
base,
|
||||||
|
&tab.ucs_xform(),
|
||||||
|
self.dyn_user_reshaped,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
crate::ui::overlay::DynBox {
|
crate::ui::overlay::DynBox {
|
||||||
label: f.role.label().to_string(),
|
label: f.role.label().to_string(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue