forked from 1b-agent/opencadstudio-upstream
feat(statusbar): isolate / hide objects with status pill
Add a hidden-entity set to the scene that the tessellation visibility test skips, so hidden objects neither render nor hit-test. New commands ISOLATEOBJECTS (show only the selection), HIDEOBJECTS (hide the selection) and UNISOLATEOBJECTS (restore). An ISO status pill lights up while anything is hidden and restores everything on click. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
243a0bc923
commit
e0e7897952
5 files changed
+106
No files matched your search
@@ -549,6 +549,10 @@ pub struct Scene {
|
||||
pub document: CadDocument,
|
||||
/// Currently selected entity handles.
|
||||
pub selected: HashSet<Handle>,
|
||||
/// Entity handles hidden by Isolate / Hide. Empty = nothing hidden.
|
||||
/// `tessellate_block`'s visibility test skips these, so they neither
|
||||
/// render nor hit-test until isolation ends.
|
||||
pub hidden: HashSet<Handle>,
|
||||
/// In-progress preview wires while a command is active (rubber-band + object ghosts).
|
||||
pub preview_wires: Vec<WireModel>,
|
||||
/// Committed-segment wire drawn during multi-point commands (normal colour).
|
||||
@@ -693,6 +697,7 @@ impl Scene {
|
||||
selection: Rc::new(RefCell::new(SelectionState::default())),
|
||||
document: CadDocument::new(),
|
||||
selected: HashSet::new(),
|
||||
hidden: HashSet::new(),
|
||||
preview_wires: vec![],
|
||||
interim_wire: None,
|
||||
camera_generation: 0,
|
||||
@@ -1316,6 +1321,48 @@ impl Scene {
|
||||
.count()
|
||||
}
|
||||
|
||||
/// True when any entities are hidden by Isolate / Hide.
|
||||
pub fn is_isolation_active(&self) -> bool {
|
||||
!self.hidden.is_empty()
|
||||
}
|
||||
|
||||
/// Hide every drawable entity except the current selection (Isolate).
|
||||
pub fn isolate_selected(&mut self) {
|
||||
if self.selected.is_empty() {
|
||||
return;
|
||||
}
|
||||
let keep = self.selected.clone();
|
||||
self.hidden = self
|
||||
.document
|
||||
.entities()
|
||||
.map(|e| e.common().handle)
|
||||
.filter(|h| !h.is_null() && !keep.contains(h))
|
||||
.collect();
|
||||
self.selected.clear();
|
||||
self.bump_geometry();
|
||||
}
|
||||
|
||||
/// Hide the current selection (Hide Objects).
|
||||
pub fn hide_selected(&mut self) {
|
||||
if self.selected.is_empty() {
|
||||
return;
|
||||
}
|
||||
for h in self.selected.iter().copied() {
|
||||
self.hidden.insert(h);
|
||||
}
|
||||
self.selected.clear();
|
||||
self.bump_geometry();
|
||||
}
|
||||
|
||||
/// Clear isolation — bring every hidden entity back (End Isolation).
|
||||
pub fn end_isolation(&mut self) {
|
||||
if self.hidden.is_empty() {
|
||||
return;
|
||||
}
|
||||
self.hidden.clear();
|
||||
self.bump_geometry();
|
||||
}
|
||||
|
||||
/// True if any currently selected entity is a Viewport.
|
||||
/// Used to enable the scale picker when a viewport is selected in paper space.
|
||||
pub fn has_selected_viewport(&self) -> bool {
|
||||
@@ -1869,6 +1916,10 @@ impl Scene {
|
||||
if c.invisible {
|
||||
return false;
|
||||
}
|
||||
// Isolate / Hide: skip entities the user has hidden.
|
||||
if !self.hidden.is_empty() && self.hidden.contains(&c.handle) {
|
||||
return false;
|
||||
}
|
||||
// Block/BlockEnd are block-defn sentinels, not drawable geometry.
|
||||
// Without this skip they fall through to fallback_geometry's `_`
|
||||
// arm and emit a 1-unit phantom segment at world_offset that
|
||||
|
||||
Reference in new issue
Block a user