diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 50136f1a9..6e6806e07 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -50,7 +50,7 @@ use fill::fill_uncovered; use fill::{fill_view, polygon_area}; #[cfg(test)] use grid::ruler_rects; -use grid::{LineLook, PIXEL_GRID, PIXEL_GRID_ZOOM, checker, clip_segment, grid, ruler_input, rulers, textured_quad, view_bounds}; +use grid::{LineLook, PIXEL_GRID, PIXEL_GRID_ZOOM, checker, clip_segment, grid, ruler_input, rulers, rulers_hidden, textured_quad, view_bounds}; pub(crate) use grid::{RulerScale, checker_texture, ruler_label, ruler_origin_dragging}; #[cfg(test)] pub(crate) use grid::{TRANSPARENCY_GRID, vertical_label_height}; @@ -283,7 +283,7 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) { ui.ctx().request_repaint_after_secs(secs as f32); } let hover_still = wait.is_none(); - let origin_preview = if app.ui.view.rulers && app.ui.screen_mode < 3 { ruler_input(app, ui, full, rect, &xf) } else { None }; + let origin_preview = if app.ui.view.rulers && app.ui.screen_mode < 3 { ruler_input(app, ui, full, rect, &xf) } else { rulers_hidden(app, ui) }; crate::document_drag::drop_on_canvas(app, &resp, &xf); panel_drop(app, ui, &resp, &xf); // In Presentation Mode a right click or a long touch opens no context menu. diff --git a/crates/ui-egui/src/canvas/grid.rs b/crates/ui-egui/src/canvas/grid.rs index 0f6fc7d91..2c99c618d 100644 --- a/crates/ui-egui/src/canvas/grid.rs +++ b/crates/ui-egui/src/canvas/grid.rs @@ -285,8 +285,7 @@ pub(super) fn ruler_input(app: &mut VectorcraftApp, ui: &Ui, full: egui::Rect, c app.session.ruler_origin_drag(pointer, app.view_info()) }; if corner.drag_stopped_by(egui::PointerButton::Primary) { - ui.data_mut(|d| d.remove::<(Option, bool)>(drag_id)); - app.session.end_ruler_origin_drag(); + end_ruler_origin_drag(app, ui); if !cancelled && let Some(at) = at && let Err(e) = app.run("document.setRulerOrigin", json!({"x": at.x, "y": at.y, "artboard": app.view().map_or(0, |v| v.artboard)})) @@ -294,8 +293,7 @@ pub(super) fn ruler_input(app: &mut VectorcraftApp, ui: &Ui, full: egui::Rect, c app.status(e.to_string()); } } else if !ui.input(|i| i.pointer.primary_down()) { - ui.data_mut(|d| d.remove::<(Option, bool)>(drag_id)); - app.session.end_ruler_origin_drag(); + end_ruler_origin_drag(app, ui); } else { ui.data_mut(|d| d.insert_temp(drag_id, (started_in, cancelled))); if !cancelled { @@ -306,6 +304,21 @@ pub(super) fn ruler_input(app: &mut VectorcraftApp, ui: &Ui, full: egui::Rect, c preview } +/// The rulers are hidden (View › Rulers, Presentation Mode): a drag of their origin they were +/// showing for is cancelled, so its snapping guides don't stay on the canvas. Nothing previews. +pub(super) fn rulers_hidden(app: &mut VectorcraftApp, ui: &Ui) -> Option { + if ruler_origin_dragging(ui.ctx()) { + end_ruler_origin_drag(app, ui); + } + None +} + +/// Ends a drag from the rulers' corner, released or cancelled: its state and its snapping guides go. +fn end_ruler_origin_drag(app: &mut VectorcraftApp, ui: &Ui) { + ui.data_mut(|d| d.remove::<(Option, bool)>(ruler_origin_drag_id())); + app.session.end_ruler_origin_drag(); +} + /// The key of the ruler origin drag's state in egui's temporary data. fn ruler_origin_drag_id() -> egui::Id { egui::Id::unique("ruler-origin-drag") diff --git a/crates/ui-egui/src/tests/ruler_origin.rs b/crates/ui-egui/src/tests/ruler_origin.rs index 55e20df8c..5e93993fe 100644 --- a/crates/ui-egui/src/tests/ruler_origin.rs +++ b/crates/ui-egui/src/tests/ruler_origin.rs @@ -153,8 +153,9 @@ fn ruler_origin_cancelled_drags_do_not_modify_either_document() { Escape, Focus, Document, + HideRulers, } - for cancel in [Cancel::Outside, Cancel::Escape, Cancel::Focus, Cancel::Document] { + for cancel in [Cancel::Outside, Cancel::Escape, Cancel::Focus, Cancel::Document, Cancel::HideRulers] { let mut app = app(); app.run("document.setRulerOrigin", json!({"x": 25, "y": 30})).unwrap(); let ctx = context(); @@ -179,6 +180,14 @@ fn ruler_origin_cancelled_drags_do_not_modify_either_document() { app.run("file.new", json!({"width": 400, "height": 300})).unwrap(); to } + Cancel::HideRulers => { + assert!(!app.session.overlays(app.view_info()).is_empty(), "the snapping guides show"); + app.ui.view.rulers = false; + frame(&mut app, &ctx, vec![], canvas::show); + assert!(app.session.overlays(app.view_info()).is_empty(), "the snapping guides go with the rulers"); + assert!(!canvas::ruler_origin_dragging(&ctx)); + to + } }; frame(&mut app, &ctx, vec![Event::PointerMoved(release), press(release, false)], canvas::show); if cancel == Cancel::Document {