mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-15 01:15:25 +00:00
Pencil: the continuation cursor follows the snapped release; Precise Cursors tests keep the badges
This commit is contained in:
@@ -723,8 +723,10 @@ fn use_precise_cursors_swaps_the_tools_own_pointers_for_a_crosshair() {
|
||||
assert_eq!(cursor(&mut s, tool), Cursor::Crosshair, "{tool} off");
|
||||
}
|
||||
s.execute("prefs.set", &json!({"key": "usePreciseCursors", "value": true})).unwrap();
|
||||
for (tool, _) in own {
|
||||
assert_eq!(cursor(&mut s, tool), Cursor::Crosshair, "{tool} on");
|
||||
for (tool, c) in own {
|
||||
// The Pencil's star is drawn on the crosshair and keeps its badge.
|
||||
let want = if tool == "pencil" { c } else { Cursor::Crosshair };
|
||||
assert_eq!(cursor(&mut s, tool), want, "{tool} on");
|
||||
}
|
||||
for tool in always {
|
||||
assert_eq!(cursor(&mut s, tool), Cursor::Crosshair, "{tool} on");
|
||||
@@ -758,8 +760,8 @@ fn use_precise_cursors_keeps_the_smooth_tools_not_allowed_pointer() {
|
||||
}
|
||||
}
|
||||
|
||||
/// With Alt held while drawing, the Pencil and the Paintbrush show their closing cursors, and Use Precise Cursors
|
||||
/// turns those into a crosshair too.
|
||||
/// With Alt held while drawing, the Pencil and the Paintbrush show their closing cursors. Use Precise Cursors keeps
|
||||
/// them: they are drawn on the crosshair, and the ring says the release closes the path.
|
||||
#[test]
|
||||
fn alt_shows_the_pencil_and_paintbrush_closing_cursors() {
|
||||
use vectorcraft_tools::{Cursor, Mods, PointerEvent, PointerKind};
|
||||
@@ -773,7 +775,7 @@ fn alt_shows_the_pencil_and_paintbrush_closing_cursors() {
|
||||
s.select_tool(tool, ViewInfo::default()).unwrap();
|
||||
s.pointer(&PointerEvent::new(PointerKind::Down, 250.0, 250.0), ViewInfo::default()).unwrap();
|
||||
s.pointer(&PointerEvent::new(PointerKind::Drag, 300.0, 300.0), ViewInfo::default()).unwrap();
|
||||
assert_eq!(s.cursor(at, alt, ViewInfo::default()), if precise { Cursor::Crosshair } else { c }, "{tool}, precise {precise}");
|
||||
assert_eq!(s.cursor(at, alt, ViewInfo::default()), c, "{tool}, precise {precise}");
|
||||
s.pointer(&PointerEvent::new(PointerKind::Up, 300.0, 300.0), ViewInfo::default()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,9 @@ pub struct GestureTool {
|
||||
/// A release where the pointer last dragged to would close the stroke because it ends near
|
||||
/// its start (Close Paths When Ends Are Within): the cursor shows the closing ring.
|
||||
near_start: bool,
|
||||
/// A release where the pointer last dragged to would connect the continued path to another
|
||||
/// selected path's open end (`finish`): the cursor shows the continuation cursor.
|
||||
connects: bool,
|
||||
/// Pencil/Paintbrush continuing a selected open path: (path, continue from its start).
|
||||
extend: Option<(NodeId, bool)>,
|
||||
/// The other end of the path `extend` continues: a release near it closes the path.
|
||||
@@ -819,6 +822,7 @@ impl GestureTool {
|
||||
active: false,
|
||||
began: false,
|
||||
near_start: false,
|
||||
connects: false,
|
||||
extend: None,
|
||||
close_to: None,
|
||||
connect_to: vec![],
|
||||
@@ -1303,6 +1307,7 @@ impl Tool for GestureTool {
|
||||
self.active = true;
|
||||
self.began = false;
|
||||
self.near_start = false;
|
||||
self.connects = false;
|
||||
// Alt switches the Pencil when its toggle is on, the Blob Brush always, and the
|
||||
// Paintbrush when the press has a selected path.
|
||||
self.smoothing = ev.mods.alt
|
||||
@@ -1380,10 +1385,12 @@ impl Tool for GestureTool {
|
||||
let kept = self.points.last().copied().filter(|l| l.distance(p) < cx.tol(1.0) && !self.snaps());
|
||||
let release_end = kept.unwrap_or(end);
|
||||
self.near_start = self.release_closes_near_start(cx, release_end);
|
||||
self.connects = self.connects_at(cx, release_end).is_some();
|
||||
return vec![];
|
||||
}
|
||||
self.push(p, ev);
|
||||
self.near_start = self.release_closes_near_start(cx, end);
|
||||
self.connects = self.connects_at(cx, end).is_some();
|
||||
if !self.draws_path() || self.smoothing {
|
||||
return vec![];
|
||||
}
|
||||
@@ -1444,6 +1451,7 @@ impl Tool for GestureTool {
|
||||
self.active = false;
|
||||
self.began = false;
|
||||
self.near_start = false;
|
||||
self.connects = false;
|
||||
self.smoothing = false;
|
||||
self.straight = false;
|
||||
self.unconstrained = false;
|
||||
@@ -1479,6 +1487,7 @@ impl Tool for GestureTool {
|
||||
self.active = false;
|
||||
self.began = false;
|
||||
self.near_start = false;
|
||||
self.connects = false;
|
||||
self.smoothing = false;
|
||||
self.straight = false;
|
||||
self.unconstrained = false;
|
||||
@@ -1509,6 +1518,7 @@ impl Tool for GestureTool {
|
||||
self.snap.clear();
|
||||
self.active = false;
|
||||
self.near_start = false;
|
||||
self.connects = false;
|
||||
self.began = false;
|
||||
self.smoothing = false;
|
||||
self.straight = false;
|
||||
@@ -1597,8 +1607,8 @@ impl Tool for GestureTool {
|
||||
return if self.find_extend(cx, p).is_some() { Cursor::PencilContinue } else { Cursor::PencilStraight };
|
||||
}
|
||||
// A continuing Pencil stroke that a release would connect to another selected path's open
|
||||
// end (`finish`) shows that it continues on.
|
||||
if self.id == "pencil" && self.active && self.points.last().is_some_and(|&end| self.connects_at(cx, end).is_some()) {
|
||||
// end (`finish`) shows that it continues on; `connects` tests the point the release keeps.
|
||||
if self.id == "pencil" && self.active && self.connects {
|
||||
return Cursor::PencilContinue;
|
||||
}
|
||||
// Alt held at the release closes the path (`finish`).
|
||||
|
||||
@@ -959,6 +959,40 @@ fn a_continued_stroke_shows_where_it_connects_or_closes() {
|
||||
assert_eq!((shown, v["closed"].clone()), (Cursor::Pencil, json!(false)), "at 0 px");
|
||||
}
|
||||
|
||||
/// The continuation cursor tests where the release ends, after snapping, not the pointer: here
|
||||
/// Snap to Grid moves a stroke's end from 13 pt away from another selected path's end (outside Edit
|
||||
/// Selected Paths' 12 px) to 9 pt away, so the release connects, and the cursor says so.
|
||||
#[test]
|
||||
fn the_continuation_cursor_follows_the_snapped_release() {
|
||||
let (mut d, _) = doc_with_rect();
|
||||
let l = d.layers[0].id;
|
||||
let add = |d: &mut vectorcraft_doc::Document, a: (f64, f64), b: (f64, f64)| {
|
||||
let id = d.alloc_id();
|
||||
let els = vec![vectorcraft_geom::PathEl::MoveTo(Point::new(a.0, a.1)), vectorcraft_geom::PathEl::LineTo(Point::new(b.0, b.1))];
|
||||
let pd = vectorcraft_geom::PathData::from_bezpath(&vectorcraft_geom::BezPath::from_vec(els));
|
||||
d.insert(Some(l), 1, vectorcraft_doc::Node::path(id, pd, vectorcraft_doc::Appearance::default_art())).unwrap();
|
||||
id
|
||||
};
|
||||
// On the 9 pt grid.
|
||||
let a = add(&mut d, (306.0, 306.0), (405.0, 405.0));
|
||||
let b = add(&mut d, (504.0, 504.0), (603.0, 504.0));
|
||||
let p = paint();
|
||||
let mut both = Selection::default();
|
||||
both.set([a, b]);
|
||||
let mut cx = cx(&d, &both, &p);
|
||||
cx.smart_guides = false;
|
||||
cx.snap_to_point = false;
|
||||
cx.snap_to_grid = true;
|
||||
let mut t = GestureTool::new("pencil");
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Down, 405.0, 405.0));
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 460.0, 450.0));
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 517.0, 504.0));
|
||||
assert_eq!(t.cursor(&cx, Point::new(517.0, 504.0), Mods::default()), Cursor::PencilContinue);
|
||||
let acts = t.pointer(&cx, &PointerEvent::new(PointerKind::Up, 517.0, 504.0));
|
||||
let Some(Action::Preview(_, v)) = acts.first() else { panic!("{acts:?}") };
|
||||
assert_eq!(v["connect"], json!({"id": b.0, "end": "start"}), "{v}");
|
||||
}
|
||||
|
||||
/// #3846: Alt during a Shift line doesn't promise a close the release can't do, and with Alt
|
||||
/// Toggles to Smooth, Alt pressed after the press doesn't turn the line into a smoothing drag.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user