Outside a sketch, a sketch tool's shortcut opens Create Sketch on the selected plane or planar face (or asks for one), then starts that tool in the new sketch.
94 lines
3.7 KiB
Rust
94 lines
3.7 KiB
Rust
use crate::scenario::Harness;
|
|
use serde_json::json;
|
|
use solidcraft_engine::Sel;
|
|
use solidcraft_engine::doc::{FeatureKind, PlaneRef};
|
|
|
|
fn tool(h: &Harness) -> Option<&str> {
|
|
h.app.tool.as_ref().map(|t| t.cmd)
|
|
}
|
|
|
|
fn normal(h: &Harness) -> solidcraft_engine::geom::Vec3 {
|
|
let active = h.app.session.active_sketch;
|
|
h.app.session.world_state().sketches.iter().find(|s| Some(s.feature) == active).map(|s| s.plane.normal()).unwrap_or_default()
|
|
}
|
|
|
|
fn press(h: &mut Harness, key: &str) {
|
|
h.step(&json!({"key": key})).unwrap();
|
|
h.settle();
|
|
}
|
|
|
|
#[test]
|
|
fn sketch_keys_outside_a_sketch_sketch_on_the_selected_plane_and_start_their_tool() {
|
|
for (key, cmd) in
|
|
[("C", "sketch.circle.center"), ("L", "sketch.line"), ("R", "sketch.rectangle.two_point"), ("D", "sketch.dimension"), ("P", "sketch.project")]
|
|
{
|
|
let mut h = Harness::new();
|
|
h.app.session.selection = vec![Sel::Plane { name: "XZ".into() }];
|
|
press(&mut h, key);
|
|
assert!(h.app.session.active_sketch.is_some(), "{key}: no sketch opened");
|
|
assert_eq!(h.app.session.world_state().sketches.len(), 1, "{key}");
|
|
assert!(normal(&h).y.abs() > 0.999, "{key}: not on XZ: {:?}", normal(&h));
|
|
assert_eq!(tool(&h), Some(cmd), "{key}");
|
|
assert!(h.app.dialog.is_none(), "{key}: dialog left open");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn a_sketch_key_sketches_on_the_selected_planar_face() {
|
|
let mut h = Harness::new();
|
|
h.app.ui.show_origin = false;
|
|
h.app.ui.pick_bodies = false;
|
|
h.app.run("solid.box", json!({"length":10,"width":10,"height":10,"body_name":"BaseBox"})).unwrap();
|
|
h.call("ui.view", json!({"view":"top"}));
|
|
h.call("ui.view", json!({"view":"fit"}));
|
|
h.settle();
|
|
h.step(&json!({"click":{"world":[3,4,10]}})).unwrap();
|
|
assert!(matches!(h.app.session.selection.as_slice(), [Sel::Face { body, .. }] if body == "BaseBox"), "{:?}", h.app.session.selection);
|
|
press(&mut h, "C");
|
|
let sketch = h.app.session.active_sketch.expect("sketch opened on the face");
|
|
let FeatureKind::Sketch { plane: PlaneRef::Face { anchor: Some(anchor), .. }, .. } = &h.app.session.doc.feature(sketch).unwrap().kind else {
|
|
panic!("the sketch must sit on the picked face");
|
|
};
|
|
assert_eq!(anchor.target.body, "BaseBox");
|
|
assert_eq!(tool(&h), Some("sketch.circle.center"));
|
|
}
|
|
|
|
#[test]
|
|
fn a_sketch_key_with_nothing_selected_asks_for_the_plane_then_starts_the_tool() {
|
|
let mut h = Harness::new();
|
|
press(&mut h, "C");
|
|
assert!(matches!(h.app.dialog.as_ref().map(|d| &d.kind), Some(crate::dialogs::Kind::Sketch)));
|
|
assert!(h.app.session.active_sketch.is_none());
|
|
assert!(tool(&h).is_none());
|
|
h.step(&json!({"click":{"plane":"XY"}})).unwrap();
|
|
h.settle();
|
|
assert!(normal(&h).z.abs() > 0.999, "{:?}", normal(&h));
|
|
assert_eq!(tool(&h), Some("sketch.circle.center"));
|
|
assert!(h.app.dialog.is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn escape_drops_the_tool_waiting_for_a_sketch() {
|
|
let mut h = Harness::new();
|
|
press(&mut h, "C");
|
|
press(&mut h, "Escape");
|
|
assert!(h.app.dialog.is_none());
|
|
h.step(&json!({"start":"sketch.create"})).unwrap();
|
|
h.step(&json!({"click":{"plane":"XY"}})).unwrap();
|
|
h.settle();
|
|
assert!(h.app.session.active_sketch.is_some());
|
|
assert!(tool(&h).is_none(), "a cancelled tool came back: {:?}", tool(&h));
|
|
}
|
|
|
|
#[test]
|
|
fn construction_key_outside_a_sketch_opens_nothing_and_keys_in_a_sketch_keep_it() {
|
|
let mut h = Harness::new();
|
|
press(&mut h, "X");
|
|
assert!(h.app.dialog.is_none());
|
|
assert!(h.app.session.active_sketch.is_none());
|
|
h.app.run("sketch.create", json!({"plane":"XY"})).unwrap();
|
|
press(&mut h, "C");
|
|
assert_eq!(h.app.session.world_state().sketches.len(), 1);
|
|
assert_eq!(tool(&h), Some("sketch.circle.center"));
|
|
}
|