From a7fd9ecb45bd1d274c5b5ddbd972e334f31e4169 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Tue, 21 Jul 2026 11:55:17 +0300 Subject: [PATCH] fix(dyn): an explicit minus keeps its sign in the angle field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dynamic-input angle field stripped the typed sign and re-signed the value from the cursor's side of the X axis, so a negative angle could not be entered at all — 330 had to stand in for -30 (#417). An explicit -/+ prefix is now taken literally; unsigned entries keep the cursor-side behaviour. Co-Authored-By: Claude Fable 5 --- src/app/update/dynamic.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/app/update/dynamic.rs b/src/app/update/dynamic.rs index 6f1919381..e8eebaed4 100644 --- a/src/app/update/dynamic.rs +++ b/src/app/update/dynamic.rs @@ -274,14 +274,20 @@ impl OpenCADStudio { let live_a = dy.atan2(dx); // radians, in the UCS plane // A typed angle is shown unsigned (0..180); give it the sign of the // cursor's current side so an entry made below the X axis sweeps - // downward to match the arc instead of mirroring up. Untyped → live. + // downward to match the arc instead of mirroring up. An EXPLICIT + // `-`/`+` prefix keeps its literal sign though — "-30" must mean + // −30° (= 330°) regardless of where the cursor sits (#417). + // Untyped → live. let angle_rad = |idx: usize| -> f64 { - match fields[idx] + let raw = fields[idx] .buffer .as_ref() - .map(|s| s.trim().replace(',', ".")) - .and_then(|s| crate::app::expr_eval::eval_number(&s)) - { + .map(|s| s.trim().replace(',', ".")); + let explicit_sign = raw + .as_deref() + .is_some_and(|s| s.starts_with('-') || s.starts_with('+')); + match raw.and_then(|s| crate::app::expr_eval::eval_number(&s)) { + Some(v) if explicit_sign => v.to_radians(), Some(mag) => mag.abs().to_radians().copysign(dy), None => live_a, }