forked from 1b-agent/opencadstudio-upstream
feat(statusbar): selection filtering by object type (FILTER pill)
Add a per-type selection filter to the scene: the FILTER pill opens a checklist of the entity types in the layout, and unchecking a type excludes it from interactive picking (click, box and lasso selection all honour it). The pill lights up while any type is filtered out. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
834780ec5d
commit
f7eac09b55
8 files changed
+219
No files matched your search
@@ -177,6 +177,8 @@ pub(super) struct OpenCADStudio {
|
||||
units_popup_open: bool,
|
||||
/// True while the Isolate pill's action menu is open.
|
||||
isolate_popup_open: bool,
|
||||
/// True while the selection-filter type picker is open.
|
||||
selection_filter_popup_open: bool,
|
||||
/// Clean-screen mode: hide ribbon and side panels for a full canvas.
|
||||
clean_screen: bool,
|
||||
/// Quick Properties: show a compact floating property panel on selection.
|
||||
@@ -756,6 +758,12 @@ pub enum Message {
|
||||
ToggleTransparencyDisplay,
|
||||
/// Toggle the Quick Properties floating panel.
|
||||
ToggleQuickProperties,
|
||||
/// Toggle the selection-filter type picker open/closed.
|
||||
ToggleSelectionFilterPopup,
|
||||
/// Close the selection-filter type picker.
|
||||
CloseSelectionFilterPopup,
|
||||
/// Include/exclude an entity type from interactive selection.
|
||||
ToggleSelectionFilterType(String),
|
||||
/// Toggle the drawing-units picker open/closed.
|
||||
ToggleUnitsPopup,
|
||||
/// Close the drawing-units picker.
|
||||
@@ -1225,6 +1233,7 @@ impl OpenCADStudio {
|
||||
statusbar_menu_open: false,
|
||||
units_popup_open: false,
|
||||
isolate_popup_open: false,
|
||||
selection_filter_popup_open: false,
|
||||
statusbar_config: crate::ui::statusbar_config::StatusBarConfig::load(),
|
||||
clean_screen: false,
|
||||
quick_properties: false,
|
||||
|
||||
@@ -2889,6 +2889,8 @@ impl OpenCADStudio {
|
||||
vp_mat,
|
||||
bounds,
|
||||
));
|
||||
// Selection filter: keep only allowed types.
|
||||
handles.retain(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
||||
self.tabs[i].scene.deselect_all();
|
||||
for h in &handles {
|
||||
self.tabs[i].scene.select_entity(*h, false);
|
||||
@@ -2932,6 +2934,9 @@ impl OpenCADStudio {
|
||||
// body, not just the thin projected edges.
|
||||
self.tabs[i].scene.mesh_click_hit(p, vp_mat, bounds)
|
||||
});
|
||||
// Selection filter: drop a pick whose type is excluded.
|
||||
let hit =
|
||||
hit.filter(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
||||
if let Some(handle) = hit {
|
||||
// Individual picks accumulate (issue #47):
|
||||
// each plain click adds to the selection,
|
||||
@@ -2980,6 +2985,8 @@ impl OpenCADStudio {
|
||||
vp_mat,
|
||||
bounds,
|
||||
));
|
||||
// Selection filter: keep only allowed types.
|
||||
handles.retain(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
||||
self.tabs[i].scene.deselect_all();
|
||||
for h in &handles {
|
||||
self.tabs[i].scene.select_entity(*h, false);
|
||||
@@ -3594,6 +3601,21 @@ impl OpenCADStudio {
|
||||
self.quick_properties ^= true;
|
||||
Task::none()
|
||||
}
|
||||
Message::ToggleSelectionFilterPopup => {
|
||||
self.selection_filter_popup_open ^= true;
|
||||
Task::none()
|
||||
}
|
||||
Message::CloseSelectionFilterPopup => {
|
||||
self.selection_filter_popup_open = false;
|
||||
Task::none()
|
||||
}
|
||||
Message::ToggleSelectionFilterType(name) => {
|
||||
let f = &mut self.tabs[self.active_tab].scene.selection_filter;
|
||||
if !f.remove(&name) {
|
||||
f.insert(name);
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::ToggleUnitsPopup => {
|
||||
self.units_popup_open ^= true;
|
||||
Task::none()
|
||||
|
||||
@@ -1173,6 +1173,7 @@ impl OpenCADStudio {
|
||||
tab.scene.is_isolation_active(),
|
||||
tab.scene.transparency_display,
|
||||
self.quick_properties,
|
||||
tab.scene.selection_filter_active(),
|
||||
&self.statusbar_config,
|
||||
)
|
||||
})
|
||||
@@ -1232,6 +1233,21 @@ impl OpenCADStudio {
|
||||
iced::widget::Space::new().width(0).height(0).into()
|
||||
};
|
||||
|
||||
let sel_filter_layer: Element<'_, Message> = if self.selection_filter_popup_open {
|
||||
let types: Vec<String> = tab
|
||||
.scene
|
||||
.entity_type_names_in_layout()
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
crate::ui::selection_filter_popup::selection_filter_popup_overlay(
|
||||
types,
|
||||
&tab.scene.selection_filter,
|
||||
)
|
||||
} else {
|
||||
iced::widget::Space::new().width(0).height(0).into()
|
||||
};
|
||||
|
||||
let dropdown_layer: Element<'_, Message> = self
|
||||
.ribbon
|
||||
.dropdown_overlay(
|
||||
@@ -1270,6 +1286,7 @@ impl OpenCADStudio {
|
||||
statusbar_menu_layer,
|
||||
units_layer,
|
||||
isolate_layer,
|
||||
sel_filter_layer,
|
||||
dropdown_layer,
|
||||
layout_ctx_layer,
|
||||
qselect_layer,
|
||||
|
||||
Reference in new issue
Block a user