Fix #302: holding Space while drawing a shape moves it
The shape tools (Rectangle, Rounded Rectangle, Ellipse, Polygon, Star, Line Segment) ignored Space during a drag. While Space is held once the drag has begun, the drag's start now moves with the pointer, so the shape being drawn moves at its current size; letting go of Space resumes sizing from there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7feeb73a81
commit
736a1bde25
|
|
@ -1,8 +1,8 @@
|
|||
//! Shape tools: Rectangle, Rounded Rectangle, Ellipse, Polygon, Star, Line Segment.
|
||||
//!
|
||||
//! Drag draws (Shift constrains to square/circle/45°, Alt draws from the centre); a click without a
|
||||
//! drag asks the UI for the size dialog (like Illustrator). ↑/↓ during a polygon/star drag change the
|
||||
//! side/point count.
|
||||
//! Drag draws (Shift constrains to square/circle/45°, Alt draws from the centre, Space held moves
|
||||
//! the shape being drawn); a click without a drag asks the UI for the size dialog (like
|
||||
//! Illustrator). ↑/↓ during a polygon/star drag change the side/point count.
|
||||
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_geom::{Point, Rect};
|
||||
|
|
@ -120,10 +120,15 @@ impl Tool for ShapeTool {
|
|||
vec![]
|
||||
}
|
||||
PointerKind::Drag => {
|
||||
let Some(s) = self.start else { return vec![] };
|
||||
let Some(mut s) = self.start else { return vec![] };
|
||||
let (pos, g) = crate::guides::snap_draw(cx, ev.pos, &[]);
|
||||
self.guides = g;
|
||||
let ev = &PointerEvent { pos, ..*ev };
|
||||
// Space held while drawing: the shape moves with the pointer instead of growing.
|
||||
if ev.mods.space && self.began {
|
||||
s += ev.pos - self.last;
|
||||
self.start = Some(s);
|
||||
}
|
||||
self.last = ev.pos;
|
||||
self.mods = ev.mods;
|
||||
let mut out = vec![];
|
||||
|
|
@ -239,6 +244,31 @@ mod tests {
|
|||
assert_eq!(t.pointer(&cx, &PointerEvent::new(PointerKind::Up, 50.0, 30.0)), vec![Action::Commit]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn space_moves_the_shape_being_drawn() {
|
||||
let (d, _) = doc_with_rect();
|
||||
let s = Selection::default();
|
||||
let p = paint();
|
||||
let cx = cx(&d, &s, &p);
|
||||
let space = Mods { space: true, ..Default::default() };
|
||||
let mut t = ShapeTool::new("rectangle");
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Down, 50.0, 50.0));
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 150.0, 120.0));
|
||||
// Space held: the 100 × 70 rectangle follows the pointer.
|
||||
let a = t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 250.0, 170.0).with_mods(space));
|
||||
assert_eq!(a.last(), Some(&Action::Preview("shape.rectangle".into(), json!({"x": 150.0, "y": 100.0, "width": 100.0, "height": 70.0}))));
|
||||
// Let go of Space: it grows again, from where it was moved to.
|
||||
let a = t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 270.0, 190.0));
|
||||
assert_eq!(a.last(), Some(&Action::Preview("shape.rectangle".into(), json!({"x": 150.0, "y": 100.0, "width": 120.0, "height": 90.0}))));
|
||||
assert_eq!(t.pointer(&cx, &PointerEvent::new(PointerKind::Up, 270.0, 190.0)), vec![Action::Commit]);
|
||||
// A star (drawn from its centre) moves its centre.
|
||||
let mut t = ShapeTool::new("star");
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Down, 50.0, 50.0));
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 80.0, 50.0));
|
||||
let a = t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 90.0, 60.0).with_mods(space));
|
||||
assert!(matches!(a.last(), Some(Action::Preview(_, v)) if v["cx"] == 60.0 && v["cy"] == 60.0), "{a:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shift_square_alt_center() {
|
||||
let t = ShapeTool::new("ellipse");
|
||||
|
|
|
|||
Loading…
Reference in New Issue