Browser tree: components with an activation radio (others drawn faded), ground pin, groups in Bodies/Sketches/Construction (new, from selection, rename, ungroup, kept in the design: browser.group/ungroup/rename_group/move/order), drag and drop to reorder, into and out of groups and into another component, Ctrl/Shift multi-select, hover lights the bodies, folds remembered; occurrence Move/Copy with a gizmo and Capture Position/Revert; the viewport shows bodies where their occurrences place them

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-08 03:37:36 +00:00
1 parent 7e373ff1f7
commit 9a9caa6511
7 files changed
+839 -174

No files matched your search

+11
View File
@@ -192,6 +192,8 @@ impl SolveApp {
"pick_bodies": self.ui.pick_bodies,
"auto_project": self.session.auto_project,
"visual_style": self.ui.visual_style,
"browser_collapsed": self.tree.collapsed,
"browser_expanded": self.tree.expanded,
})
.to_string()
}
@@ -218,6 +220,15 @@ impl SolveApp {
if let Some(s) = v.get("visual_style").and_then(Value::as_u64) {
self.ui.visual_style = u8::try_from(s.min(2)).unwrap_or(0);
}
// Browser folders the user opened or closed.
let keys = |k: &str| -> std::collections::BTreeSet<String> {
v.get(k)
.and_then(Value::as_array)
.map(|a| a.iter().take(10_000).filter_map(|x| x.as_str().map(str::to_string)).collect())
.unwrap_or_default()
};
self.tree.collapsed = keys("browser_collapsed");
self.tree.expanded = keys("browser_expanded");
}
pub fn with_control(mut self, rx: Receiver<ControlRequest>) -> Self {