mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Dimension tool: Shift shows the constrained line while picking the second point (#2432)
The Shift click already snapped the second point to 45-degree steps, but the dashed line from the first point followed the raw pointer, so the constraint looked absent until the click. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
285a3da81a
commit
6939a481a4
@@ -389,3 +389,21 @@ fn unknown_dimension_options_are_refused_by_commands_but_a_newer_file_still_open
|
||||
let doc = vectorcraft_format::load(&serde_json::to_vec(&v).unwrap()).unwrap();
|
||||
assert!(doc.node(NodeId(id)).unwrap().extras().dimension.is_some());
|
||||
}
|
||||
|
||||
/// With Shift down, the dashed line from the first picked point follows the 45-degree step the
|
||||
/// second click will pick (#2432), not the raw pointer.
|
||||
#[test]
|
||||
fn shift_shows_the_constrained_line_while_picking_the_second_point() {
|
||||
use vectorcraft_engine::tools::Overlay;
|
||||
let mut s = session();
|
||||
s.select_tool("dimension", ViewInfo::default()).unwrap();
|
||||
ev(&mut s, PointerKind::Down, 300.0, 300.0);
|
||||
ev(&mut s, PointerKind::Up, 300.0, 300.0);
|
||||
let end = |s: &mut Session, shift: bool| {
|
||||
let e = PointerEvent::new(PointerKind::Move, 372.0, 310.0).with_mods(Mods { shift, ..Mods::default() });
|
||||
s.pointer(&e, ViewInfo::default()).unwrap();
|
||||
s.overlays(ViewInfo::default()).into_iter().find_map(|o| if let Overlay::Line { b, .. } = o { Some(b) } else { None }).unwrap()
|
||||
};
|
||||
assert_eq!(end(&mut s, false).y, 310.0);
|
||||
assert!((end(&mut s, true).y - 300.0).abs() < 1e-9);
|
||||
}
|
||||
|
||||
@@ -60,9 +60,17 @@ pub struct DimensionTool {
|
||||
dragging: bool,
|
||||
hover: Option<Target>,
|
||||
at: Point,
|
||||
/// Whether Shift was down at the last pointer event: the picked line shows constrained.
|
||||
shift: bool,
|
||||
began: bool,
|
||||
}
|
||||
|
||||
/// `at` as a Shift click picks it: the direction from `last` snapped to 45° steps (from the
|
||||
/// constrain angle), the distance kept.
|
||||
fn constrained(cx: &ToolContext, last: Point, at: Point) -> Point {
|
||||
last + vectorcraft_geom::constrain_angle_from(at - last, 45.0, cx.constrain_angle)
|
||||
}
|
||||
|
||||
/// Nearest editable segment, with bounded work and no snapping to dimension artwork itself.
|
||||
pub fn pick(cx: &ToolContext, p: Point) -> Option<SegmentRef> {
|
||||
let mut best = None;
|
||||
@@ -217,7 +225,7 @@ impl DimensionTool {
|
||||
if mods.shift
|
||||
&& let Some((last, _)) = self.points.last()
|
||||
{
|
||||
at = *last + vectorcraft_geom::constrain_angle_from(at - *last, 45.0, cx.constrain_angle);
|
||||
at = constrained(cx, *last, at);
|
||||
reference = reference.filter(|r| r.position(cx.doc) == Some(at));
|
||||
}
|
||||
self.points.push((at, reference));
|
||||
@@ -293,6 +301,7 @@ impl Tool for DimensionTool {
|
||||
}
|
||||
fn pointer(&mut self, cx: &ToolContext, ev: &PointerEvent) -> Vec<Action> {
|
||||
self.at = ev.pos;
|
||||
self.shift = ev.mods.shift;
|
||||
match ev.kind {
|
||||
PointerKind::Move => {
|
||||
if self.pending.is_some() {
|
||||
@@ -393,7 +402,8 @@ impl Tool for DimensionTool {
|
||||
segment(edge, &mut out);
|
||||
}
|
||||
if let Some((p, _)) = self.points.last() {
|
||||
out.push(Overlay::Line { a: *p, b: self.at, color, dashed: true });
|
||||
let b = if self.shift { constrained(cx, *p, self.at) } else { self.at };
|
||||
out.push(Overlay::Line { a: *p, b, color, dashed: true });
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user