mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-24 02:46:51 -06:00
* Build: line tables only in dev, no debug info for dependencies * Tests: one integration-test binary per crate Each crate's tests/*.rs becomes a module of tests/it/main.rs. Files that install process-wide state (the file io hooks, user aliases, SAVETIME and SAVEFILEPATH, user linetype and pattern files, registered fonts) stay their own test binaries. * xtask ci: nextest, tests without examples, one wasm check call
61 lines
2.4 KiB
Rust
61 lines
2.4 KiB
Rust
//! Grip editing acts on the whole selection, as in AutoCAD: a stretched grip drags the
|
|
//! coincident grips of the other selected objects with it, and Move/Rotate/Scale/Mirror
|
|
//! transform every selected object.
|
|
|
|
use cadcraft_engine::Session;
|
|
use cadcraft_engine::doc::{EntityKind, Handle};
|
|
use cadcraft_engine::geom::Vec2;
|
|
use cadcraft_engine::grips::GripMode;
|
|
use serde_json::json;
|
|
|
|
fn line(s: &mut Session, a: [f64; 2], b: [f64; 2]) -> Handle {
|
|
let r = s.execute("line", &json!({ "points": [a, b] })).unwrap();
|
|
Handle::parse_hex(r["handles"][0].as_str().unwrap()).unwrap()
|
|
}
|
|
|
|
fn ends(s: &Session, h: Handle) -> (Vec2, Vec2) {
|
|
match &s.doc().unwrap().entity(h).unwrap().kind {
|
|
EntityKind::Line(l) => (l.a.xy(), l.b.xy()),
|
|
k => panic!("not a line: {k:?}"),
|
|
}
|
|
}
|
|
|
|
fn near(p: Vec2, x: f64, y: f64) -> bool {
|
|
p.near(Vec2::new(x, y), 1e-9)
|
|
}
|
|
|
|
#[test]
|
|
fn grip_edits_act_on_the_selection() {
|
|
// Two connected lines and a third one elsewhere, all selected.
|
|
let mut s = Session::new();
|
|
let a = line(&mut s, [0.0, 0.0], [10.0, 0.0]);
|
|
let b = line(&mut s, [10.0, 0.0], [10.0, 10.0]);
|
|
let c = line(&mut s, [20.0, 0.0], [30.0, 0.0]);
|
|
s.set_selection(vec![a, b, c]);
|
|
let undo = s.state().unwrap().undo.len();
|
|
|
|
// Stretching the shared corner grip of `a` moves `b`'s start with it; `c` stays.
|
|
s.grip_edit(a, 2, Vec2::new(12.0, 3.0), GripMode::Stretch).unwrap();
|
|
assert!(near(ends(&s, a).1, 12.0, 3.0));
|
|
assert!(near(ends(&s, b).0, 12.0, 3.0) && near(ends(&s, b).1, 10.0, 10.0), "{:?}", ends(&s, b));
|
|
assert!(near(ends(&s, c).0, 20.0, 0.0) && near(ends(&s, c).1, 30.0, 0.0));
|
|
assert_eq!(s.state().unwrap().undo.len(), undo + 1, "one undo step");
|
|
|
|
// Move about a grip of `a`: every selected object moves.
|
|
s.grip_edit(a, 0, Vec2::new(1.0, 1.0), GripMode::Move).unwrap();
|
|
assert!(near(ends(&s, a).0, 1.0, 1.0));
|
|
assert!(near(ends(&s, b).1, 11.0, 11.0));
|
|
assert!(near(ends(&s, c).0, 21.0, 1.0));
|
|
|
|
// Rotate 90° about the same grip: `c` turns too.
|
|
s.grip_edit(a, 0, Vec2::new(1.0, 5.0), GripMode::Rotate).unwrap();
|
|
assert!(near(ends(&s, c).0, 1.0, 21.0), "{:?}", ends(&s, c));
|
|
|
|
// An object that isn't selected is only edited through its own grip.
|
|
s.set_selection(vec![a]);
|
|
let before = ends(&s, b);
|
|
let g = s.grips_of(a).unwrap()[2];
|
|
s.grip_edit(a, 2, g + Vec2::new(1.0, 0.0), GripMode::Stretch).unwrap();
|
|
assert_eq!(ends(&s, b), before);
|
|
}
|