feat(props): uniform-scale checkbox for block references
A selected INSERT's Geometry section gains a "Uniform scale" box (#427): while the three factors are equal it is checked and the panel shows a single Scale row that writes all three axes; unchecking expands the familiar Scale X/Y/Z rows without touching the values (remembered per entity), and re-checking collapses Y/Z onto X as an undoable CHPROP step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d154a01cb4
commit
8821bb7131
4 changed files with 82 additions and 0 deletions
|
|
@ -250,6 +250,10 @@ pub(super) struct OpenCADStudio {
|
|||
video_thumbs: std::collections::HashMap<String, iced::widget::image::Handle>,
|
||||
/// 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<u64>,
|
||||
/// 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(),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Reference in a new issue