diff --git a/src/app/properties.rs b/src/app/properties.rs index a243f06ce..a33679064 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -914,6 +914,13 @@ impl OpenCADStudio { crate::io::xref::layer_overrides(doc, &br.name, &br.xref_path, &base_dir); xref_rows(&mut sections, ins, &br.xref_path, factor, overrides); } + // A dynamic block's visibility states, picked like its grip. + if let Some(row) = Self::visibility_property(doc, handle) { + sections.push(crate::scene::model::object::PropSection { + title: t!("Custom").into_owned(), + props: vec![row], + }); + } // An associative array's counts and spacings. if let Some(array) = crate::scene::assoc_array::array_of_insert(doc, handle) { sections.push(crate::scene::assoc_array::property_section(doc, &array)); diff --git a/src/app/update/command.rs b/src/app/update/command.rs index 06d1d7360..7eba0c6f9 100644 --- a/src/app/update/command.rs +++ b/src/app/update/command.rs @@ -3394,6 +3394,20 @@ impl OpenCADStudio { _ => {} } } + } else if field == "dyn_visibility" { + // A visibility state picked in Properties, applied like a + // pick from the reference's visibility grip. + self.tabs[i].properties.edit_choice_open = false; + for &handle in &handles { + let state = self.tabs[i] + .scene + .document + .dynamic_visibility_for_insert(handle) + .and_then(|(_, param)| param.states.iter().position(|s| s.name == value)); + if let Some(state) = state { + self.apply_visibility_state(handle, state); + } + } } else if field == "block" { // Name dropdown on a block reference: re-point the // selected inserts to the picked definition. A stale diff --git a/src/app/visibility.rs b/src/app/visibility.rs index 60d38bd15..15755d39a 100644 --- a/src/app/visibility.rs +++ b/src/app/visibility.rs @@ -117,6 +117,34 @@ impl OpenCADStudio { }) } + /// The visibility parameter of a dynamic-block reference as a Properties + /// row: the parameter's name, its states, and the one shown now. + pub(super) fn visibility_property( + doc: &codec::CadDocument, + handle: Handle, + ) -> Option { + let Some(EntityType::Insert(ins)) = doc.get_entity(handle) else { + return None; + }; + let (def_block, param) = doc.dynamic_visibility_for_insert(handle)?; + let options: Vec = param.states.iter().map(|s| s.name.clone()).collect(); + let current = Self::current_visibility_state(doc, def_block, &ins.block_name, param); + // An unnamed parameter takes the name a new one gets in the file. + let label = if param.element_name.trim().is_empty() { + "Visibility1".to_string() + } else { + param.element_name.clone() + }; + Some(crate::scene::model::object::Property { + label, + field: "dyn_visibility", + value: crate::scene::model::object::PropValue::Choice { + selected: current.and_then(|c| options.get(c).cloned()).unwrap_or_default(), + options, + }, + }) + } + /// Recompute the visibility grip for the active tab's single selection and /// append it (as a Triangle grip) to `selected_grips`. Clears it when the /// selection is not a dynamic-block reference. `wo` is the world offset