Merge pull request #4659 from storytold/fix/units-guides-reopen

Guides: a ruler guide shows while dragged with Real-time Drawing off (#4646)
This commit is contained in:
BFlat
2026-10-30 08:27:39 +07:00
committed by GitHub
5 changed files with 78 additions and 3 deletions
+17
View File
@@ -1616,6 +1616,23 @@ fn real_time_drawing_off_skips_tool_previews_until_commit() {
assert!(s.doc().unwrap().revision > rev, "on again: previews run while dragging");
}
/// #4646: with Real-time Drawing off, a ruler guide moved with the Selection tool still moves
/// while it is dragged (the guide is all the drag shows).
#[test]
fn real_time_drawing_off_still_shows_a_dragged_guide() {
let mut s = Session::new();
s.execute("file.new", &json!({"width": 400, "height": 400})).unwrap();
s.execute("guide.add", &json!({"vertical": true, "pos": 100})).unwrap();
let v = ViewInfo::default();
s.select_tool("selection", v).unwrap();
set_pref(&mut s, "realTimeDrawing", json!(false));
s.pointer(&PointerEvent::new(PointerKind::Down, 100.0, 200.0), v).unwrap();
s.pointer(&PointerEvent::new(PointerKind::Drag, 150.0, 200.0), v).unwrap();
assert_eq!(s.doc().unwrap().doc.guides[0].pos, 150.0, "the guide moves while dragged");
s.pointer(&PointerEvent::new(PointerKind::Up, 150.0, 200.0), v).unwrap();
assert_eq!((s.doc().unwrap().doc.guides[0].pos, s.doc().unwrap().history.undo.last().map(|e| e.label.as_str())), (150.0, Some("Move Guide")));
}
/// Real-time Drawing turned on mid-drag still applies the deferred preview on commit.
#[test]
fn real_time_drawing_turned_on_mid_drag_still_commits_deferred_preview() {
+22
View File
@@ -562,3 +562,25 @@ fn eps_save_bounds_large_page_preview_without_cropping_vector_or_editing_data()
assert_eq!(native.artboards, s.doc().unwrap().doc.artboards);
assert_eq!(native.layers, s.doc().unwrap().doc.layers);
}
/// #4646: a new document's units and ruler guides survive Save, Close and Open in every format
/// that carries the whole document (an SVG keeps them only with Preserve Editing).
#[test]
fn units_and_ruler_guides_survive_save_and_reopen() {
let d = dir("units-guides");
for ext in ["vectorcraft", "pdf", "ai", "eps"] {
let mut s = Session::new();
s.execute("file.new", &json!({"width": 200, "height": 100, "units": "Millimeters"})).unwrap();
s.execute("guide.add", &json!({"vertical": true, "pos": 50})).unwrap();
s.execute("guide.add", &json!({"vertical": false, "pos": 30})).unwrap();
rect(&mut s);
let p = path(&d, &format!("a.{ext}"));
s.execute("document.save", &json!({"path": p})).unwrap();
s.execute("file.close", &json!({})).unwrap();
s.execute("document.open", &json!({"path": p})).unwrap();
let doc = &s.doc().unwrap().doc;
let guides: Vec<_> = doc.guides.iter().map(|g| (g.vertical, g.pos)).collect();
assert_eq!((doc.units, guides), (vectorcraft_doc::Unit::Millimeters, vec![(true, 50.0), (false, 30.0)]), "{ext}");
}
let _ = std::fs::remove_dir_all(d);
}
+3 -2
View File
@@ -743,8 +743,9 @@ impl Session {
Action::Begin(label) => self.begin_interaction(&label)?,
Action::Preview(cmd, p) => {
// Performance › Real-time Drawing and Editing (#394): off, remember the latest
// params and apply them once on Commit instead of every move.
if !self.prefs.real_time_drawing {
// params and apply them once on Commit instead of every move. A ruler guide
// being dragged still shows: the guide is all there is to see (#4646).
if !self.prefs.real_time_drawing && !matches!(cmd.as_str(), "guide.add" | "guide.move") {
self.clear_deferred_overlay_cache();
let st = self.doc_mut()?;
if let Some(it) = &mut st.interaction {
+33
View File
@@ -1032,6 +1032,39 @@ fn a_drag_from_a_ruler_onto_the_canvas_makes_a_guide() {
assert_eq!(app.session.active().unwrap().doc.art_bounds(), None, "the tool drew nothing");
}
/// #4646: a guide dragged out of a ruler shows as a line across the canvas while it is dragged,
/// also with Preferences › Performance › Real-time Drawing and Editing off (only its position
/// label showed then).
#[test]
fn a_guide_dragged_out_of_a_ruler_shows_while_dragged() {
for real_time in [true, false] {
let mut app = VectorcraftApp::new(Session::new(), Default::default());
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
app.session.execute("prefs.set", &json!({"key": "realTimeDrawing", "value": real_time})).unwrap();
app.ui.view.rulers = true;
app.ui.view.smart_guides = false;
app.ui.view.snap_to_point = false;
let ctx = egui::Context::default();
frame(&mut app, &ctx, vec![]);
let rect = app.canvas_rect.unwrap();
let zoom = app.view().unwrap().zoom as f32;
let from = pos2(rect.center().x, rect.top() - RULER / 2.0);
let at = pos2(rect.center().x, rect.top() + 120.0);
let button = |pos, pressed| egui::Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
frame(&mut app, &ctx, vec![egui::Event::PointerMoved(from)]);
frame(&mut app, &ctx, vec![button(from, true)]);
frame(&mut app, &ctx, vec![egui::Event::PointerMoved(at)]);
// A horizontal line across the canvas at the pointer (snapped to a whole point at most).
let across = |s: &Shape| {
matches!(s, Shape::LineSegment { points, .. }
if (points[0].y - at.y).abs() <= zoom && points[0].y == points[1].y && (points[1].x - points[0].x).abs() >= rect.width() - 0.5)
};
assert!(shapes(&mut app, &ctx).iter().any(across), "real-time drawing {real_time}: the guide shows while dragged");
frame(&mut app, &ctx, vec![button(at, false)]);
assert_eq!(app.session.active().unwrap().doc.guides.len(), 1, "real-time drawing {real_time}: released, it is made");
}
}
#[test]
fn new_ruler_guides_follow_alt_through_preview_release_and_undo() {
use egui::{Event, Modifiers};
File diff suppressed because one or more lines are too long