diff --git a/src/app/mod.rs b/src/app/mod.rs index 6e3cf7c9..62a05551 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -250,6 +250,10 @@ pub(super) struct OpenCADStudio { video_thumbs: std::collections::HashMap, /// True while the boot-time playlist fetch is still in flight. videos_loading: bool, + /// Block references whose properties panel shows per-axis Scale X/Y/Z even + /// though the three factors are currently equal — the user unchecked the + /// "Uniform scale" box for them (#427). Keyed by entity handle. + props_asym_scale: std::collections::HashSet, /// Which Start-page section is shown when the page is too narrow for all /// three side by side and falls back to a tab bar. start_section: StartSection, @@ -2201,6 +2205,7 @@ impl OpenCADStudio { videos: Vec::new(), video_thumbs: std::collections::HashMap::new(), videos_loading: false, + props_asym_scale: std::collections::HashSet::new(), start_section: StartSection::default(), props_expanded: false, history_content: iced::widget::text_editor::Content::new(), diff --git a/src/app/properties.rs b/src/app/properties.rs index fda29189..65ddf3c4 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -139,6 +139,51 @@ impl OpenCADStudio { } } + // Uniform-scale checkbox for block references (#427): + // while the three scale factors are equal (and the user + // hasn't opted into per-axis editing) the panel shows one + // Scale row plus a checked "Uniform scale" box; unchecking + // expands the familiar Scale X/Y/Z rows. + if let acadrust::EntityType::Insert(ins) = entity { + let eq = (ins.x_scale() - ins.y_scale()).abs() < 1e-12 + && (ins.x_scale() - ins.z_scale()).abs() < 1e-12; + let uniform = + eq && !self.props_asym_scale.contains(&handle.value()); + for section in sections.iter_mut() { + let Some(xi) = + section.props.iter().position(|p| p.field == "x_scale") + else { + continue; + }; + let toggle = crate::scene::model::object::Property { + label: "Uniform scale".into(), + field: "ins_uniform", + value: crate::scene::model::object::PropValue::BoolToggle { + field: "ins_uniform", + value: uniform, + }, + }; + if uniform { + section + .props + .retain(|p| p.field != "y_scale" && p.field != "z_scale"); + let xi = section + .props + .iter() + .position(|p| p.field == "x_scale") + .unwrap_or(xi.min(section.props.len())); + section.props[xi] = crate::entities::common::edit_prop( + "Scale", + "u_scale", + ins.x_scale(), + ); + section.props.insert(xi, toggle); + } else { + section.props.insert(xi, toggle); + } + } + } + // In named plot-style mode (PSTYLEMODE=1) the Plot style row // picks a named style from the drawing's plot style table. In // the color-dependent mode it stays read-only (the object's diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index 2a7368dd..f16ef3a3 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -2622,6 +2622,32 @@ impl OpenCADStudio { crate::scene::view::dispatch::toggle_invisible(entity); } } + // Uniform-scale checkbox on a block reference + // (#427): checking collapses Y/Z onto X; unchecking + // only switches the panel to per-axis rows. + "ins_uniform" => { + let scales = match self.tabs[i].scene.document.get_entity(handle) { + Some(acadrust::EntityType::Insert(ins)) => { + Some((ins.x_scale(), ins.y_scale(), ins.z_scale())) + } + _ => None, + }; + let Some((sx, sy, sz)) = scales else { continue }; + let eq = (sx - sy).abs() < 1e-12 && (sx - sz).abs() < 1e-12; + let checked = + eq && !self.props_asym_scale.contains(&handle.value()); + if checked { + self.props_asym_scale.insert(handle.value()); + } else { + self.props_asym_scale.remove(&handle.value()); + if let Some(acadrust::EntityType::Insert(ins)) = + self.tabs[i].scene.document.get_entity_mut(handle) + { + ins.set_y_scale(sx); + ins.set_z_scale(sx); + } + } + } _ => { if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) diff --git a/src/entities/insert.rs b/src/entities/insert.rs index 2910cc75..c793f574 100644 --- a/src/entities/insert.rs +++ b/src/entities/insert.rs @@ -94,6 +94,12 @@ fn apply_geom_prop(ins: &mut Insert, field: &str, value: &str) { acadrust::Entity::translate(att, delta); } } + // Single Scale row shown while "Uniform scale" is checked (#427). + "u_scale" => { + ins.set_x_scale(v); + ins.set_y_scale(v); + ins.set_z_scale(v); + } "x_scale" => ins.set_x_scale(v), "y_scale" => ins.set_y_scale(v), "z_scale" => ins.set_z_scale(v),