Files
OneCAD/crates/ui-egui/src/sketch_shortcut_tests.rs
T
Diogo Soares Rodrigues 1a5e961362 feat(ui): sketch tool shortcuts open a sketch on the selected plane (#737)
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.
2026-10-13 11:45:15 -04:00

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"));
}