feat(plot): snap plot-window corners to geometry endpoints

PLOTWINDOW / PW now forces Endpoint object-snap while picking its two
corners, independent of the global OSNAP toggle, so the plot area lands
exactly on frame corners. The snapper's master toggle and configured
modes are saved and restored around the pick, so the user's OSNAP
settings are unchanged afterward.

- CadCommand::forces_endpoint_snap() opt-in (default false; PlotWindowCommand true).
- Snapper::snap_forced_corners() forces Endpoint only, then restores state.
  Intersection is deliberately excluded: it is O(n^2) over the hit-test wire
  set and froze the UI on large drawings when a plot window is picked
  zoomed-out. Frame corners are endpoints, so Endpoint alone suffices.
- the cursor-move handler routes the plot-window pick through the forced path.

Works in model and paper space (shared pick path). Tests: opt-in flag;
forced mode set is endpoint-only; snapper state is restored after the call.
This commit is contained in:
sLuCHa committed 2026-07-06 13:38:56 +02:00
1 parent b50921923f
commit 6cd422e5b9
4 files changed
+121 -2

No files matched your search

+15
View File
@@ -22,6 +22,10 @@ impl CadCommand for PlotWindowCommand {
"PLOTWINDOW"
}
fn forces_endpoint_snap(&self) -> bool {
true
}
fn prompt(&self) -> String {
if self.p1.is_none() {
"PLOTWINDOW Specify first corner of plot window:".into()
@@ -81,3 +85,14 @@ impl CadCommand for PlotWindowCommand {
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["PLOTWINDOW", "PW"] }); // PlotWindowCommand
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn plot_window_forces_endpoint_snap() {
let cmd = PlotWindowCommand::new();
assert!(cmd.forces_endpoint_snap());
}
}