mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 21:57:12 -06:00
Print: a Print Tiling origin on an artboard's right or bottom edge is measured from that artboard
The Print Tiling tool's press and print.tiling.set without `artboard` decided which artboard a point is on with Rect::contains, which leaves out the right and bottom edges. A press exactly on an artboard's right or bottom edge picked no artboard when no other artboard holds that point, so the drag did not snap to that artboard's edges. An origin there was measured from the first printed artboard: with artboards at 0 to 300 pt and 300 to 600 pt, an origin on the second one's right edge was saved as x 600 instead of 300. Both now count the edges as Document::art_on_artboard does, within a millionth of a point.
This commit is contained in:
@@ -27,6 +27,18 @@ fn snap1(v: f64, edges: [f64; 2], tol: f64) -> f64 {
|
||||
edges.into_iter().filter(|e| (e - v).abs() <= tol).min_by(|a, b| (a - v).abs().total_cmp(&(b - v).abs())).unwrap_or(v)
|
||||
}
|
||||
|
||||
/// Index of the first artboard holding `p`: one that holds it inside or on its left or top edge,
|
||||
/// else one that holds it on its right or bottom edge or within a millionth of a point outside an
|
||||
/// edge (the edges `Document::art_on_artboard` counts).
|
||||
fn artboard_holding(cx: &ToolContext, p: Point) -> Option<usize> {
|
||||
let rects = || cx.doc.artboards.iter().map(|a| a.rect);
|
||||
let holds = |r: Rect| {
|
||||
let r = r.inflate(1e-6, 1e-6);
|
||||
r.x0 <= p.x && p.x <= r.x1 && r.y0 <= p.y && p.y <= r.y1
|
||||
};
|
||||
rects().position(|r| r.contains(p)).or_else(|| rects().position(holds))
|
||||
}
|
||||
|
||||
impl Tool for PrintTilingTool {
|
||||
fn id(&self) -> &'static str {
|
||||
"printTiling"
|
||||
@@ -39,7 +51,7 @@ impl Tool for PrintTilingTool {
|
||||
fn pointer(&mut self, cx: &ToolContext, ev: &PointerEvent) -> Vec<Action> {
|
||||
match ev.kind {
|
||||
PointerKind::Down => {
|
||||
let hit = cx.doc.artboards.iter().position(|a| a.rect.contains(ev.pos));
|
||||
let hit = artboard_holding(cx, ev.pos);
|
||||
self.drag = Some((hit, hit.and_then(|i| cx.doc.artboards.get(i)).map(|a| a.rect)));
|
||||
(self.began, self.last) = (false, ev.pos);
|
||||
vec![]
|
||||
@@ -98,7 +110,7 @@ impl Tool for PrintTilingTool {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_doc::Selection;
|
||||
|
||||
use super::*;
|
||||
@@ -134,4 +146,31 @@ mod tests {
|
||||
assert_eq!(t.key(&c, ToolKey::Escape, Mods::default()), vec![Action::Cancel]);
|
||||
assert_eq!(crate::create("printTiling").id(), "printTiling");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_press_on_an_artboards_right_or_bottom_edge_drags_from_that_artboard() {
|
||||
// Artboard 0 is (0, 0) to (500, 500). Artboard 1 is (500, 0) to (800, 200), and its left edge lies on artboard 0's right edge.
|
||||
let (mut d, _) = doc_with_rect();
|
||||
let mut ab = d.artboards[0].clone();
|
||||
ab.rect = Rect::new(500.0, 0.0, 800.0, 200.0);
|
||||
d.artboards.push(ab);
|
||||
let (s, pd) = (Selection::default(), paint());
|
||||
let c = cx(&d, &s, &pd);
|
||||
// What a drag to 3 pt up and left of a press at (x, y) previews: the corner snaps to the
|
||||
// edges of the artboard the press picked.
|
||||
let drag = |x: f64, y: f64| {
|
||||
let mut t = PrintTilingTool::default();
|
||||
t.pointer(&c, &ev(PointerKind::Down, x, y));
|
||||
t.pointer(&c, &ev(PointerKind::Drag, x - 3.0, y - 3.0)).pop()
|
||||
};
|
||||
let preview =
|
||||
|origin: [f64; 2], artboard: Value| Some(Action::Preview("print.tiling.set".into(), json!({ "origin": origin, "artboard": artboard })));
|
||||
assert_eq!(drag(800.0, 100.0), preview([800.0, 97.0], json!(1)), "artboard 1's right edge");
|
||||
assert_eq!(drag(650.0, 200.0), preview([647.0, 200.0], json!(1)), "artboard 1's bottom edge");
|
||||
assert_eq!(drag(800.0, 200.0), preview([800.0, 200.0], json!(1)), "artboard 1's bottom right corner");
|
||||
assert_eq!(drag(300.0, 500.0), preview([297.0, 500.0], json!(0)), "artboard 0's bottom edge");
|
||||
assert_eq!(drag(500.0, 100.0), preview([500.0, 97.0], json!(1)), "the shared edge: the artboard to its right");
|
||||
assert_eq!(drag(800.0 + 1e-9, 100.0), preview([800.0, 97.0], json!(1)), "roundoff past the edge");
|
||||
assert_eq!(drag(800.001, 100.0), preview([800.001 - 3.0, 97.0], Value::Null), "beyond the edge");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user