forked from 1b-agent/opencadstudio-upstream
feat(ucs): interactive UCS command — UCS Z 90 typable everywhere (F2, #169)
Bare `UCS` now enters an interactive front-end (UcsCommand) that gathers the option then its value as separate steps, instead of the command line submitting `UCS` alone on the first Space. The front-end delegates execution back to the existing inline `UCS <option> …` handler via a new `CmdResult::Dispatch(String)`, so the coordinate-system math and the save/persist path are untouched. Now `UCS Z 90` works the same from the command line (Space-separated), headless automation, and any source that feeds the active command — closing the input half of #169. Inline `UCS Z 90` (one-shot / paste) still hits the inline handler directly. Second phase of routing input sources through the unified step driver: the interactive command is driven by feed_command like any tool. Adds headless test ucs_interactive_inline_args. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
5fdd212592
commit
36d2f33301
6 files changed
+159
-2
No files matched your search
@@ -565,6 +565,27 @@ mod tests {
|
||||
assert_eq!(app.automation_op(r#"{"op":"run"}"#)["ok"], false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ucs_interactive_inline_args() {
|
||||
// `UCS Z 90` must drive the interactive UCS command step-by-step (option
|
||||
// "Z" then value "90") and rotate the active UCS 90° about Z. (#169)
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
app.automation_op(r#"{"op":"run","cmd":"UCS Z 90"}"#);
|
||||
let i = app.active_tab;
|
||||
let ucs = app.tabs[i]
|
||||
.active_ucs
|
||||
.as_ref()
|
||||
.expect("UCS Z 90 should set an active UCS");
|
||||
// 90° about Z sends the X axis (1,0,0) → (0,1,0).
|
||||
assert!(
|
||||
ucs.x_axis.x.abs() < 1e-6 && (ucs.x_axis.y - 1.0).abs() < 1e-6,
|
||||
"x_axis after UCS Z 90 = ({}, {})",
|
||||
ucs.x_axis.x,
|
||||
ucs.x_axis.y
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_then_open_round_trips() {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
|
||||
@@ -567,6 +567,15 @@ impl OpenCADStudio {
|
||||
self.restore_pre_cmd_tangent();
|
||||
let _ = self.dispatch_command(&cmd);
|
||||
}
|
||||
CmdResult::Dispatch(cmd) => {
|
||||
// End this interactive front-end, then run the assembled command
|
||||
// through the normal dispatcher. Selection is left untouched.
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.restore_pre_cmd_tangent();
|
||||
let _ = self.dispatch_command(&cmd);
|
||||
}
|
||||
CmdResult::MatchEntityLayer { dest, src } => {
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
|
||||
+12
-2
@@ -3618,8 +3618,18 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
// ── UCS management ───────────────────────────────────────────
|
||||
cmd if cmd == "UCS" || cmd.starts_with("UCS ") => {
|
||||
// Bare UCS → interactive front-end (option then value as steps), so
|
||||
// `UCS Z 90` is typable in the command line and works headlessly.
|
||||
// The front-end delegates back to the inline handler below. (#169)
|
||||
"UCS" => {
|
||||
use crate::modules::view::ucs_cmd::UcsCommand;
|
||||
let cmd_obj = UcsCommand::new();
|
||||
self.command_line.push_info(&cmd_obj.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd_obj));
|
||||
}
|
||||
|
||||
// ── UCS management (inline `UCS <option> …`) ─────────────────────
|
||||
cmd if cmd.starts_with("UCS ") => {
|
||||
use super::helpers::{ucs_rotated_z, ucs_to_wcs, ucs_z_axis};
|
||||
use acadrust::tables::Ucs;
|
||||
use acadrust::types::Vector3;
|
||||
|
||||
Reference in new issue
Block a user