mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
G12: ruler guides nudged with art keep to the page's axes at a turned Constrain Angle
With objects and ruler guides selected together, object.nudge moved the guides by the art's delta turned through General > Constrain Angle, so at 90 degrees a Right nudge moved a horizontal guide vertically. The guides in that edit now move by the page-axis delta, as guides selected alone already did (CodeRabbit finding on #3745). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014gCpjL3yUhaH3jRp7ksufh
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
e0c1548049
commit
52a43eefdb
@@ -380,6 +380,21 @@ pub(crate) fn transform_node(n: &mut Node, xf: Affine, sc: Scaling, objects: boo
|
||||
/// `anchors` (`ids` being the selection): with anchors selected with Direct Selection and no
|
||||
/// copy, only those anchors transform, their handles with them, and the objects selected whole.
|
||||
pub(crate) fn apply_transform(s: &mut Session, label: &str, ids: Vec<NodeId>, xf: Affine, p: &Value, anchors: bool) -> Result<Value> {
|
||||
apply_transform_moving_guides(s, label, ids, xf, p, anchors, None)
|
||||
}
|
||||
|
||||
/// [`apply_transform`], with the selected ruler guides moved by `guides` instead of by the
|
||||
/// translation `xf` when given (a nudge along a turned Constrain Angle moves the art along it and
|
||||
/// the guides along the page's axes).
|
||||
fn apply_transform_moving_guides(
|
||||
s: &mut Session,
|
||||
label: &str,
|
||||
ids: Vec<NodeId>,
|
||||
xf: Affine,
|
||||
p: &Value,
|
||||
anchors: bool,
|
||||
guides: Option<Vec2>,
|
||||
) -> Result<Value> {
|
||||
let copy = bool_or(p, "copy", false);
|
||||
let areas = bool_or(p, "typeAreas", false);
|
||||
let objects = transforms_objects(p);
|
||||
@@ -387,7 +402,7 @@ pub(crate) fn apply_transform(s: &mut Session, label: &str, ids: Vec<NodeId>, xf
|
||||
sc.patterns = transform_patterns(s, p, &ids)?;
|
||||
let c = xf.as_coeffs();
|
||||
let is_translation = (c[0] - 1.0).abs() < 1e-9 && c[1].abs() < 1e-9 && c[2].abs() < 1e-9 && (c[3] - 1.0).abs() < 1e-9;
|
||||
let delta = Vec2::new(c[4], c[5]);
|
||||
let delta = guides.unwrap_or(Vec2::new(c[4], c[5]));
|
||||
let with_guides = objects && ids_param(p, "ids").is_none() && is_translation;
|
||||
let has_guides = with_guides && !s.doc()?.selection.guides.is_empty();
|
||||
// A transform of ids that name no object, or an identity transform without a copy, moves
|
||||
@@ -564,7 +579,7 @@ fn nudge(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
return super::docmenu::guide_move(s, &json!({ "dx": gx, "dy": gy, "copy": copy }));
|
||||
}
|
||||
let ids = selected_roots_to_transform(s)?;
|
||||
apply_transform(s, "Move", ids, Affine::translate((dx, dy)), p, true)
|
||||
apply_transform_moving_guides(s, "Move", ids, Affine::translate((dx, dy)), p, true, Some(Vec2::new(gx, gy)))
|
||||
}
|
||||
|
||||
fn about(o: Point, a: Affine) -> Affine {
|
||||
|
||||
@@ -152,3 +152,28 @@ fn constrain_angle_whole_turns_nudge_as_zero() {
|
||||
set_pref(&mut s, "constrainAngle", json!(90));
|
||||
assert_eq!(moved(&mut s, 1, 0), Vec2::new(0.0, -10.0));
|
||||
}
|
||||
|
||||
/// General › Constrain Angle turns only the art's arrow-key axes: ruler guides selected with the
|
||||
/// art keep to the page's axes. At 90°, → moves the art straight up, a vertical guide 10 right and
|
||||
/// a horizontal guide not at all; ↓ moves the horizontal guide 10 down. Copies alike.
|
||||
#[test]
|
||||
fn constrain_angle_keeps_guides_selected_with_art_on_the_page_axes() {
|
||||
let mut s = new_doc();
|
||||
let id = rect(&mut s, 100.0, 100.0);
|
||||
set_pref(&mut s, "keyboardIncrement", json!(10));
|
||||
set_pref(&mut s, "constrainAngle", json!(90));
|
||||
let v = s.execute("guide.add", &json!({"vertical": true, "pos": 50})).unwrap()["index"].as_u64().unwrap() as usize;
|
||||
let h = s.execute("guide.add", &json!({"vertical": false, "pos": 50})).unwrap()["index"].as_u64().unwrap() as usize;
|
||||
s.execute("select.set", &json!({"ids": [id.0]})).unwrap();
|
||||
s.execute("guide.select", &json!({"indexes": [v, h], "toggle": true})).unwrap();
|
||||
let pos = |s: &Session| s.doc().unwrap().doc.guides.iter().map(|g| g.pos).collect::<Vec<_>>();
|
||||
let at = centre(&s, id);
|
||||
s.execute("object.nudge", &json!({"dx": 1, "dy": 0})).unwrap();
|
||||
assert_eq!(centre(&s, id) - at, Vec2::new(0.0, -10.0), "the art moves along the turned axis");
|
||||
assert_eq!(pos(&s), [60.0, 50.0], "→: the vertical guide moves right, the horizontal one stays");
|
||||
s.execute("object.nudge", &json!({"dx": 0, "dy": 1})).unwrap();
|
||||
assert_eq!(pos(&s), [60.0, 60.0], "↓: the horizontal guide moves down");
|
||||
// With a copy, the guides' copies keep to the page too.
|
||||
s.execute("object.nudge", &json!({"dx": 1, "dy": 0, "copy": true})).unwrap();
|
||||
assert_eq!(pos(&s), [60.0, 60.0, 70.0, 60.0]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user