From b6bdef3de6e6954290efdf19c89f501d3544ec10 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Thu, 8 Oct 2026 02:45:19 +0700 Subject: [PATCH] Perspective grid: coming back from a temporary tool keeps a hidden grid hidden (review of #333) Choosing a perspective tool shows the grid, but the canvas also re-selected the tool after a Cmd-drag with the borrowed Selection tool, so a grid hidden with the tool chosen came back after any Cmd-drag. `Session::switch_tool` (and the app's `restore_tool`) switch without choosing; the temporary-tool return uses it. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/tests_distort.rs | 16 ++++++++++++++++ crates/engine/src/tooling.rs | 8 +++++++- crates/ui-egui/src/canvas.rs | 2 +- crates/ui-egui/src/lib.rs | 13 ++++++++++++- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/crates/engine/src/tests_distort.rs b/crates/engine/src/tests_distort.rs index 9b298cc78..ec09ce096 100644 --- a/crates/engine/src/tests_distort.rs +++ b/crates/engine/src/tests_distort.rs @@ -267,6 +267,22 @@ fn the_grid_hides_while_a_perspective_tool_is_chosen() { } } +#[test] +fn a_hidden_grid_stays_hidden_back_from_a_temporary_tool() { + // Cmd-dragging with a perspective tool borrows the Selection tool; going back to the + // perspective tool is not choosing it, so the grid hidden meanwhile stays hidden. + let mut s = session(); + let v = ViewInfo::default(); + s.select_tool("perspectiveGrid", v).unwrap(); + s.execute("perspective.grid.show", &json!({"visible": false})).unwrap(); + s.switch_tool("selection", v).unwrap(); + s.switch_tool("perspectiveGrid", v).unwrap(); + assert!(s.overlays(v).is_empty()); + s.select_tool("selection", v).unwrap(); + s.select_tool("perspectiveGrid", v).unwrap(); + assert!(s.overlays(v).len() > 20, "choosing it shows the grid"); +} + #[test] fn grid_preset_and_set_are_undoable() { let mut s = session(); diff --git a/crates/engine/src/tooling.rs b/crates/engine/src/tooling.rs index eed19ed80..80872f59c 100644 --- a/crates/engine/src/tooling.rs +++ b/crates/engine/src/tooling.rs @@ -56,7 +56,7 @@ impl Session { self.tool.id() } - /// Switch tools (finishing any pending tool work first). + /// Choose a tool (the toolbar, its shortcut, MCP), finishing any pending tool work first. pub fn select_tool(&mut self, id: &str, view: ViewInfo) -> Result<()> { // Choosing a perspective tool shows the document's perspective grid; Hide Grid hides it // again, the tool staying chosen. @@ -65,6 +65,12 @@ impl Session { { crate::cmd::distortcmds::silent(self, |g| g.visible = true)?; } + self.switch_tool(id, view) + } + + /// Switch to tool `id` without choosing it afresh (back from a temporary tool: a hidden + /// perspective grid stays hidden), finishing any pending tool work first. + pub fn switch_tool(&mut self, id: &str, view: ViewInfo) -> Result<()> { if self.tool.id() == id { return Ok(()); } diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 8624af902..37434d3bb 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -560,7 +560,7 @@ fn handle_input(app: &mut VectorcraftApp, ui: &Ui, resp: &egui::Response, rect: if matches!(d, Drag::TempSelect | Drag::Art { temp: true }) && let Some(prev) = ui.data(|dd| dd.get_temp::(temp_tool_id())) { - app.select_tool(&prev); + app.restore_tool(&prev); } } Drag::Pan { .. } | Drag::RotateView { .. } => {} diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index eb298cf08..0b437b374 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -510,8 +510,19 @@ impl VectorcraftApp { /// Select a tool (also used by the toolbar and shortcuts). pub fn select_tool(&mut self, id: &str) { + self.change_tool(id, true); + } + + /// Go back to tool `id` after a temporary one, without choosing it afresh + /// ([`vectorcraft_engine::Session::switch_tool`]). + pub fn restore_tool(&mut self, id: &str) { + self.change_tool(id, false); + } + + fn change_tool(&mut self, id: &str, choose: bool) { let v = self.view_info(); - if let Err(e) = self.session.select_tool(id, v) { + let r = if choose { self.session.select_tool(id, v) } else { self.session.switch_tool(id, v) }; + if let Err(e) = r { self.ui.status = e.to_string(); } if let Some(g) = vectorcraft_tools::catalog::group_of(id)