Constraints: the settings checkboxes show or hide all, dropping per-object exceptions (part of #1134) (#1144)

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Marco Arnulfo
2026-10-19 02:54:03 -04:00
committed by GitHub
co-authored by Brandon Thomas Claude Opus 5.5
parent 00f521858a
commit 5f390e6e6a
2 changed files with 58 additions and 0 deletions
+7
View File
@@ -956,6 +956,13 @@ fn run_constraintsettings(s: &mut Session, p: &Value) -> Result<Value> {
set.angle_tolerance = f64_or(p, "angleTolerance", set.angle_tolerance).clamp(0.0, 45.0);
set.bars_visible = bool_or(p, "barsVisible", set.bars_visible);
set.dims_visible = bool_or(p, "dimsVisible", set.dims_visible);
// The checkboxes act like Show All / Hide All: exceptions are relative to the old value and would flip.
if set.bars_visible != cur.bars_visible {
set.bar_exceptions.clear();
}
if set.dims_visible != cur.dims_visible {
set.dim_exceptions.clear();
}
if let Some(t) = p.get("barTransparency").and_then(Value::as_f64).filter(|v| v.is_finite()) {
set.bar_transparency = t.clamp(0.0, 90.0) as u8;
}
@@ -296,3 +296,54 @@ fn dcangular_constrains_the_drawn_angle_whichever_way_the_lines_run() {
assert!((got - 100.0).abs() < 1e-6, "{b_pts:?}: drawn angle {got}");
}
}
/// Same rule as the overlay in `ui-egui/src/parametric.rs` that draws dynamic constraints.
fn dim_shown(s: &Session, h: &str) -> bool {
let d = s.doc().unwrap();
let set = &d.parametric.settings;
let c = d.constraints.iter().find(|c| c.refs.iter().any(|r| r.handle.hex() == h)).unwrap();
set.dims_visible != c.refs.iter().any(|r| set.dim_exceptions.contains(&r.handle))
}
#[test]
fn settings_dims_checkbox_clears_exceptions() {
let mut s = Session::new();
let a = line(&mut s, [0.0, 0.0], [10.0, 0.0]);
s.execute("dclinear", &json!({ "h1": a, "expr": "10" })).unwrap();
s.execute("dcdisplay.hideall", &json!({})).unwrap();
let b = line(&mut s, [20.0, 0.0], [25.0, 0.0]);
s.execute("dclinear", &json!({ "h1": b, "expr": "5" })).unwrap();
let r = s.execute("dcdisplay", &json!({ "mode": "show", "handles": [b] })).unwrap();
assert_eq!(r["exceptions"], json!([b]));
assert!(!dim_shown(&s, &a) && dim_shown(&s, &b));
// Re-stating the current value keeps the exceptions.
s.execute("constraintsettings", &json!({ "dimsVisible": false })).unwrap();
assert_eq!(s.doc().unwrap().parametric.settings.dim_exceptions.len(), 1);
// Ticking "Show dynamic constraints" shows all of them, like Show All.
s.execute("constraintsettings", &json!({ "dimsVisible": true })).unwrap();
assert!(s.doc().unwrap().parametric.settings.dim_exceptions.is_empty());
assert!(dim_shown(&s, &a) && dim_shown(&s, &b));
}
#[test]
fn settings_bars_checkbox_clears_exceptions() {
let mut s = Session::new();
let a = line(&mut s, [0.0, 0.0], [10.0, 0.0]);
s.execute("gchorizontal", &json!({ "h1": a })).unwrap();
s.execute("constraintbar.hideall", &json!({})).unwrap();
let b = line(&mut s, [0.0, 5.0], [10.0, 5.0]);
s.execute("gchorizontal", &json!({ "h1": b })).unwrap();
let r = s.execute("constraintbar", &json!({ "mode": "show", "handles": [b] })).unwrap();
assert_eq!(r["exceptions"], json!([b]));
// Same rule as the bar overlay in `ui-egui/src/parametric.rs`.
let bar = |s: &Session, h: &str| {
let set = &s.doc().unwrap().parametric.settings;
set.bars_visible != set.bar_exceptions.contains(&Handle::parse_hex(h).unwrap())
};
assert!(!bar(&s, &a) && bar(&s, &b));
s.execute("constraintsettings", &json!({ "barsVisible": false })).unwrap();
assert_eq!(s.doc().unwrap().parametric.settings.bar_exceptions.len(), 1);
s.execute("constraintsettings", &json!({ "barsVisible": true })).unwrap();
assert!(s.doc().unwrap().parametric.settings.bar_exceptions.is_empty());
assert!(bar(&s, &a) && bar(&s, &b));
}