mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-14 22:35:26 +00:00
Place: a grid previews the cells it places on a rotated spread
The preview divided the dragged rectangle on the canvas and the release divided it on the spread, so on a rotated spread two columns previewed across the canvas and landed down it. The preview now takes the release's cells and shows each where it lands on the canvas.
This commit is contained in:
1 parent
e4f82e243e
commit
d721ef9f62
2 files changed
+46
-4
No files matched your search
@@ -197,11 +197,16 @@ impl Tool for PlaceGun {
|
||||
// no frame is drawn yet, the loaded cursor shows what lands.
|
||||
let click = (self.cur - a).hypot() < cx.tol(3.0);
|
||||
// A grid draws its cells; one too small for them falls back to the single frame, as the
|
||||
// release does.
|
||||
if !click {
|
||||
let cells = grid_cells(designcraft_geom::Rect::from_points(a, self.cur), self.columns, self.rows);
|
||||
// release does. The cells are the release's, worked out on the spread: on a rotated spread
|
||||
// its columns don't run across the canvas.
|
||||
if !click && let Some((sr, sa)) = cx.layout.spread_at(a) {
|
||||
let cells = grid_cells(designcraft_geom::Rect::from_points(sa, cx.layout.to_spread(sr, self.cur)), self.columns, self.rows);
|
||||
if !cells.is_empty() {
|
||||
return cells.into_iter().map(crate::Overlay::Marquee).collect();
|
||||
let on_canvas = |x: f64, y: f64| cx.layout.to_canvas(sr, Point::new(x, y));
|
||||
return cells
|
||||
.into_iter()
|
||||
.map(|c| crate::Overlay::Marquee(designcraft_geom::Rect::from_points(on_canvas(c.x0, c.y0), on_canvas(c.x1, c.y1))))
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
let Some(size) = cx.loaded else {
|
||||
|
||||
@@ -2441,3 +2441,40 @@ fn place_gun_grid_too_small_for_its_cells_previews_and_places_one_frame() {
|
||||
assert_eq!(out, single_out);
|
||||
assert!(matches!(out.as_slice(), [Action::Exec(cmd, _)] if cmd == "place.drop"), "{out:?}");
|
||||
}
|
||||
|
||||
/// On a rotated spread a place-cursor grid previews the cells it places: worked out on the spread,
|
||||
/// then shown on the canvas, so two columns on the spread don't preview as two across the canvas.
|
||||
#[test]
|
||||
fn place_gun_grid_preview_matches_the_release_on_a_rotated_spread() {
|
||||
let mut d = Document::new(&NewDocument::default());
|
||||
std::sync::Arc::make_mut(&mut d.spreads[0]).pages[0].view_rotation = 1;
|
||||
let (s, c, l) = (Selection::default(), Cache::new(), CanvasLayout::new(&d, false));
|
||||
let cx = ctx(&d, &s, &c, &l);
|
||||
let (start, end) = (Point::new(10.0, 10.0), Point::new(210.0, 110.0));
|
||||
let (spread, a) = l.spread_at(start).unwrap();
|
||||
let b = l.to_spread(spread, end);
|
||||
let mut t = create("placeGun");
|
||||
let _ = t.pointer(&cx, &PointerEvent::new(PointerKind::Down, start.x, start.y));
|
||||
let _ = t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, end.x, end.y));
|
||||
assert_eq!(t.key(&cx, ToolKey::Right, Mods::default()), vec![Action::Handled]);
|
||||
let shown = t.overlays(&cx);
|
||||
let out = t.pointer(&cx, &PointerEvent::new(PointerKind::Up, end.x, end.y));
|
||||
assert!(matches!(out.as_slice(), [Action::Exec(cmd, p)] if cmd == "place.grid" && p["columns"] == 2), "{out:?}");
|
||||
// Two columns on the spread, 6 pt apart, each shown where its corners land on the canvas.
|
||||
let r = Rect::from_points(a, b);
|
||||
let w = (r.width() - 6.0) / 2.0;
|
||||
let expected: Vec<Overlay> = [r.x0, r.x0 + w + 6.0]
|
||||
.into_iter()
|
||||
.map(|x| Overlay::Marquee(Rect::from_points(l.to_canvas(spread, Point::new(x, r.y0)), l.to_canvas(spread, Point::new(x + w, r.y1)))))
|
||||
.collect();
|
||||
assert_eq!(shown.len(), 2, "{shown:?}");
|
||||
for (got, want) in shown.iter().zip(&expected) {
|
||||
let (Overlay::Marquee(got), Overlay::Marquee(want)) = (got, want) else { panic!("{got:?}") };
|
||||
for (g, w) in [(got.x0, want.x0), (got.y0, want.y0), (got.x1, want.x1), (got.y1, want.y1)] {
|
||||
assert!((g - w).abs() < 1e-6, "{shown:?} against {expected:?}");
|
||||
}
|
||||
}
|
||||
// A quarter turn: the columns stack down the canvas.
|
||||
let (Overlay::Marquee(first), Overlay::Marquee(second)) = (&shown[0], &shown[1]) else { panic!("{shown:?}") };
|
||||
assert!((first.x0 - second.x0).abs() < 1e-6, "{shown:?}");
|
||||
}
|
||||
Reference in new issue
Block a user