Support dynamic rectangle resizing via grip editing

This commit is contained in:
Marcel committed 2026-09-11 20:52:33 +02:00
1 parent f30b490831
commit 913705106e
8 files changed
+282 -41

No files matched your search

+53
View File
@@ -1004,6 +1004,44 @@ bg={bg_ms:.1}ms n={view_count}"
w,
)
});
let rectangle_values = tab
.active_grip
.as_ref()
.and_then(|grip| grip.rectangle_frame)
.map(|(opposite, width_axis, height_axis)| {
let delta = w - opposite;
(delta.dot(width_axis).abs(), delta.dot(height_axis).abs())
});
let rectangle_label_screens = tab
.active_grip
.as_ref()
.and_then(|grip| grip.rectangle_frame)
.and_then(|(opposite, width_axis, height_axis)| {
let delta = w - opposite;
let width = delta.dot(width_axis);
let height = delta.dot(height_axis);
let width_center = opposite + width_axis * (width * 0.5);
let height_center = opposite
+ width_axis * width
+ height_axis * (height * 0.5);
let (vw, vh) = tab.scene.selection.borrow().vp_size;
let (camera, bounds) = tab
.scene
.viewport_edit_frame((vw, vh))
.unwrap_or_else(|| {
(
tab.scene.camera.borrow().clone(),
tab.scene.active_model_tile_bounds(vw, vh),
)
});
let project = |point| {
camera.project(point, bounds).map(|screen| iced::Point::new(
bounds.x + screen.x,
bounds.y + screen.y,
))
};
Some((project(width_center)?, project(height_center)?))
});
let boxes: Vec<crate::ui::overlay::DynBox> = tab
.dyn_fields
.iter()
@@ -1011,6 +1049,14 @@ bg={bg_ms:.1}ms n={view_count}"
.map(|(idx, f)| {
let value = match (&f.buffer, live) {
(Some(b), _) => b.clone(),
(None, _) if rectangle_values.is_some() => {
let (width, height) = rectangle_values.unwrap();
match f.role {
crate::command::DynRole::Width => format!("{width:.4}"),
crate::command::DynRole::Height => format!("{height:.4}"),
_ => String::new(),
}
}
// An angle step with a command-supplied live value
// (ARC span / direction) shows it in degrees.
(None, Some(lv)) if f.component == DynComponent::Angle => {
@@ -1039,6 +1085,13 @@ bg={bg_ms:.1}ms n={view_count}"
active: idx == tab.dyn_active,
locked: f.locked(),
role: f.role,
center: rectangle_label_screens.and_then(|(width, height)| {
match f.role {
crate::command::DynRole::Width => Some(width),
crate::command::DynRole::Height => Some(height),
_ => None,
}
}),
}
})
.collect();