Hide and show joints in the browser, like other items (#1168)

Fixes #1160.
This commit is contained in:
bherbruck authored and GitHub committed 2026-10-14 15:04:57 -04:00
1 parent e3459edea8
commit 229de1484c
15 files changed
+470 -15

No files matched your search

+28 -4
View File
@@ -38,8 +38,9 @@ pub static COMMANDS: &[CommandSpec] = &[
),
CommandSpec::new("browser.order", "Order Browser Items", order).params("folder, component?, order: [keys] (the folder's items in display order)"),
CommandSpec::new("browser.visibility", "Show/Hide", visibility).icon("eye").noundo().params(
"visible: bool; items?: [sketch id or name | body name | construction name | O|X|Y|Z|XY|XZ|YZ]; \
or folder?: bodies|sketches|construction|origin (all of it); or paths?: [[occurrence ids]] (exact placements and descendants), isolate?: bool (requires paths and visible:true). Saved with the design; not an undo step",
"visible: bool; items?: [sketch id or name | body name | construction name | joint name | O|X|Y|Z|XY|XZ|YZ]; \
or joints?: [joint id or name] (their glyphs; they still constrain and move parts); \
or folder?: bodies|sketches|construction|origin|joints (all of it); or paths?: [[occurrence ids]] (exact placements and descendants), isolate?: bool (requires paths and visible:true). Saved with the design; not an undo step",
),
];
@@ -170,6 +171,8 @@ enum Shown {
Body(String),
/// Origin items and construction geometry, by name.
Origin(String),
/// An assembly joint's glyph, by joint id.
Joint(u64),
}
fn is_construction(k: &FeatureKind) -> bool {
@@ -188,6 +191,9 @@ fn shown_item(s: &Session, key: &str) -> Option<Shown> {
if s.world_state().bodies.iter().any(|b| b.name == key) {
return Some(Shown::Body(key.to_string()));
}
if let Some(j) = s.doc.assembly.joints.iter().find(|j| j.name == key) {
return Some(Shown::Joint(j.id));
}
ORIGIN.iter().find(|o| o.eq_ignore_ascii_case(key)).map(|o| Shown::Origin(o.to_string()))
}
@@ -255,12 +261,24 @@ fn visibility(s: &mut Session, p: &Value) -> Result<Value> {
return Ok(json!({"visible":visible,"changed":paths.len(),"visibility":s.visibility}));
}
let items: Vec<Shown> = match (str_(p, "folder"), p.get("items")) {
_ if p.get("joints").is_some() => {
if p.get("items").is_some() || p.get("folder").is_some() {
return Err(bad(cmd, "give `joints`, `items` or `folder`, not several"));
}
let list = p
.get("joints")
.and_then(Value::as_array)
.filter(|a| !a.is_empty() && a.len() <= 10_000)
.ok_or_else(|| bad(cmd, "`joints` must list 1..10000 joint ids or names"))?;
list.iter().map(|j| super::joints::joint_id(s, Some(j), cmd).map(Shown::Joint)).collect::<Result<_>>()?
}
(Some(_), Some(_)) => return Err(bad(cmd, "give `items` or `folder`, not both")),
(Some("bodies"), None) => s.world_state().bodies.iter().map(|b| Shown::Body(b.name.clone())).collect(),
(Some("sketches"), None) => s.model.state().sketches.iter().map(|x| Shown::Sketch(x.feature)).collect(),
(Some("construction"), None) => s.doc.features.iter().filter(|f| is_construction(&f.kind)).map(|f| Shown::Origin(f.name.clone())).collect(),
(Some("origin"), None) => ORIGIN.iter().map(|o| Shown::Origin(o.to_string())).collect(),
(Some(f), None) => return Err(bad(cmd, format!("unknown folder `{f}` (bodies, sketches, construction, origin)"))),
(Some("joints"), None) => s.doc.assembly.joints.iter().map(|j| Shown::Joint(j.id)).collect(),
(Some(f), None) => return Err(bad(cmd, format!("unknown folder `{f}` (bodies, sketches, construction, origin, joints)"))),
(None, Some(_)) => {
let keys = keys(p, "items", cmd)?;
if keys.is_empty() {
@@ -268,7 +286,7 @@ fn visibility(s: &mut Session, p: &Value) -> Result<Value> {
}
// Every item is found before anything changes.
keys.iter()
.map(|k| shown_item(s, k).ok_or_else(|| bad(cmd, format!("no sketch, body or construction item `{k}`"))))
.map(|k| shown_item(s, k).ok_or_else(|| bad(cmd, format!("no sketch, body, construction item or joint `{k}`"))))
.collect::<Result<_>>()?
}
(None, None) => return Err(bad(cmd, "`items` or `folder` is required")),
@@ -296,6 +314,12 @@ fn visibility(s: &mut Session, p: &Value) -> Result<Value> {
v.hidden_origin.push(n.clone());
}
}
Shown::Joint(id) => {
v.hidden_joints.retain(|x| x != id);
if !visible {
v.hidden_joints.push(*id);
}
}
}
}
s.revision += 1;