diff --git a/src/app/mod.rs b/src/app/mod.rs index 8ac1d22e4..3f79d0e10 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -237,6 +237,11 @@ pub(super) struct OpenCADStudio { /// updates only the overlay rather than re-tessellating the whole model. /// Committed (un-hidden + one re-tess) when the drag ends. `None` = idle. grip_preview_handle: Option, + /// Snapshot of the edited entity taken at the start of a grip drag, used to + /// restore it if the user presses Esc to cancel the drag. The drag mutates + /// the document live (so grips / properties track), so cancel reverts from + /// this backup. Dropped (kept) on a normal commit. + grip_original: Option, /// Open Quick Select panel state. `None` = panel closed. Filters are /// applied via `Message::QSelectApply`; the panel is dismissed on /// Apply / Cancel / Esc / outside-click. @@ -1279,6 +1284,7 @@ impl OpenCADStudio { grip_pending: None, grip_add_provisional: None, grip_preview_handle: None, + grip_original: None, qselect: None, show_ucs_icon: true, show_viewcube: true, diff --git a/src/app/update.rs b/src/app/update.rs index 48c3bff4b..50abeeaba 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -1313,13 +1313,20 @@ impl OpenCADStudio { self.tabs[i].scene.bump_geometry(); self.refresh_selected_grips(); } - // Commit/cleanup an in-progress grip drag: un-hide the - // edited entity, re-tessellate once, drop the preview. + // Cancel an in-progress grip drag: restore the edited + // entity from its pre-drag backup, un-hide it, re-tessellate + // once, and drop the preview. if let Some(h) = self.grip_preview_handle.take() { let i = self.active_tab; + if let Some(orig) = self.grip_original.take() { + if let Some(e) = self.tabs[i].scene.document.get_entity_mut(h) { + *e = orig; + } + } self.tabs[i].scene.hidden.remove(&h); self.tabs[i].scene.clear_preview_wire(); self.tabs[i].scene.bump_geometry(); + self.refresh_selected_grips(); } self.tabs[self.active_tab].snap_result = None; self.refresh_properties(); @@ -2116,6 +2123,9 @@ impl OpenCADStudio { if let Some(prev) = self.grip_preview_handle.take() { self.tabs[i].scene.hidden.remove(&prev); } + // Back up the original geometry so Esc can cancel the drag. + self.grip_original = + self.tabs[i].scene.document.get_entity(grip.handle).cloned(); self.tabs[i].scene.hidden.insert(grip.handle); self.tabs[i].scene.bump_geometry(); self.grip_preview_handle = Some(grip.handle); @@ -2633,10 +2643,11 @@ impl OpenCADStudio { return Task::none(); } self.tabs[i].active_grip = None; - // Commit the grip drag: un-hide the edited entity and - // re-tessellate the base once with its final geometry, - // dropping the overlay preview. + // Commit the grip drag: keep the doc's dragged geometry + // (drop the cancel backup), un-hide the edited entity and + // re-tessellate the base once, dropping the overlay preview. if let Some(h) = self.grip_preview_handle.take() { + self.grip_original = None; self.tabs[i].scene.hidden.remove(&h); self.tabs[i].scene.clear_preview_wire(); self.tabs[i].scene.bump_geometry();