forked from 1b-agent/opencadstudio-upstream
feat(commands): step the remaining inquiry / solid commands (bucket E)
- ValuePromptCommand: CAL/QUICKCALC/QC (expression), FIND, FINDALL (search). - SelectThenKeywordCommand (select the solid, then axis + value): SECTION, SLICE, 3DMIRROR, 3DROTATE. SLICE's optional TOP/BOTTOM stays typeable. - TwoValuePromptCommand: PYRAMID (radius + height; sides typeable). Left as-is by design: UNDO (bare already undoes one step — a correct default, not a usage line); POLYSOLID (select a polyline then width + height — needs a two-value-after-selection form) and 3DALIGN (six 3-D points) stay typeable.
This commit is contained in:
1 parent
f0f9a57bf6
commit
49c10bc806
2 files changed
+101
-30
No files matched your search
+75
-21
@@ -838,11 +838,17 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
// PYRAMID <radius> <height> [sides] — create an n-sided pyramid mesh.
|
||||
cmd if cmd == "PYRAMID"
|
||||
|| cmd.starts_with("PYRAMID ")
|
||||
|| cmd == "PYR"
|
||||
|| cmd.starts_with("PYR ") =>
|
||||
{
|
||||
"PYRAMID" | "PYR" => {
|
||||
use crate::command::TwoValuePromptCommand;
|
||||
let c = TwoValuePromptCommand::new(
|
||||
"PYRAMID",
|
||||
"PYRAMID base radius:",
|
||||
"PYRAMID height (add sides by typing a 3rd number):",
|
||||
);
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
cmd if cmd.starts_with("PYRAMID ") || cmd.starts_with("PYR ") => {
|
||||
let nums: Vec<f64> = cmd
|
||||
.split_whitespace()
|
||||
.skip(1)
|
||||
@@ -857,7 +863,23 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
// SECTION [X|Y|Z] <value> — draw the cross-section outline of the solid.
|
||||
cmd if cmd == "SECTION" || cmd.starts_with("SECTION ") => {
|
||||
"SECTION" => {
|
||||
use crate::command::SelectThenKeywordCommand;
|
||||
let has_sel = !self.tabs[i].scene.selected_entities().is_empty();
|
||||
let c = SelectThenKeywordCommand::new(
|
||||
"SECTION",
|
||||
"SECTION cutting-plane axis [X / Y / Z]:",
|
||||
vec![
|
||||
("X", "X", Some("SECTION offset along X:")),
|
||||
("Y", "Y", Some("SECTION offset along Y:")),
|
||||
("Z", "Z", Some("SECTION offset along Z:")),
|
||||
],
|
||||
has_sel,
|
||||
);
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
cmd if cmd.starts_with("SECTION ") => {
|
||||
let parts: Vec<String> = cmd
|
||||
.split_whitespace()
|
||||
.skip(1)
|
||||
@@ -903,11 +925,19 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
// 3DMIRROR [X|Y|Z] — add a mirror of the selected solid across a plane.
|
||||
cmd if cmd == "3DMIRROR"
|
||||
|| cmd == "MIRROR3D"
|
||||
|| cmd.starts_with("3DMIRROR ")
|
||||
|| cmd.starts_with("MIRROR3D ") =>
|
||||
{
|
||||
"3DMIRROR" | "MIRROR3D" => {
|
||||
use crate::command::SelectThenKeywordCommand;
|
||||
let has_sel = !self.tabs[i].scene.selected_entities().is_empty();
|
||||
let c = SelectThenKeywordCommand::new(
|
||||
"3DMIRROR",
|
||||
"3DMIRROR mirror plane [X / Y / Z]:",
|
||||
vec![("X", "X", None), ("Y", "Y", None), ("Z", "Z", None)],
|
||||
has_sel,
|
||||
);
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
cmd if cmd.starts_with("3DMIRROR ") || cmd.starts_with("MIRROR3D ") => {
|
||||
let parts: Vec<String> = cmd
|
||||
.split_whitespace()
|
||||
.skip(1)
|
||||
@@ -928,11 +958,23 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
// 3DROTATE [X|Y|Z] <angle> — rotate the selected solid about an axis.
|
||||
cmd if cmd == "3DROTATE"
|
||||
|| cmd == "ROTATE3D"
|
||||
|| cmd.starts_with("3DROTATE ")
|
||||
|| cmd.starts_with("ROTATE3D ") =>
|
||||
{
|
||||
"3DROTATE" | "ROTATE3D" => {
|
||||
use crate::command::SelectThenKeywordCommand;
|
||||
let has_sel = !self.tabs[i].scene.selected_entities().is_empty();
|
||||
let c = SelectThenKeywordCommand::new(
|
||||
"3DROTATE",
|
||||
"3DROTATE rotation axis [X / Y / Z]:",
|
||||
vec![
|
||||
("X", "X", Some("3DROTATE angle in degrees:")),
|
||||
("Y", "Y", Some("3DROTATE angle in degrees:")),
|
||||
("Z", "Z", Some("3DROTATE angle in degrees:")),
|
||||
],
|
||||
has_sel,
|
||||
);
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
cmd if cmd.starts_with("3DROTATE ") || cmd.starts_with("ROTATE3D ") => {
|
||||
let parts: Vec<String> = cmd
|
||||
.split_whitespace()
|
||||
.skip(1)
|
||||
@@ -954,11 +996,23 @@ impl OpenCADStudio {
|
||||
|
||||
// SLICE [X|Y|Z] <value> [TOP|BOTTOM] — cut the selected solid with an
|
||||
// axis-aligned plane, keeping the lower half by default.
|
||||
cmd if cmd == "SLICE"
|
||||
|| cmd == "SL"
|
||||
|| cmd.starts_with("SLICE ")
|
||||
|| cmd.starts_with("SL ") =>
|
||||
{
|
||||
"SLICE" | "SL" => {
|
||||
use crate::command::SelectThenKeywordCommand;
|
||||
let has_sel = !self.tabs[i].scene.selected_entities().is_empty();
|
||||
let c = SelectThenKeywordCommand::new(
|
||||
"SLICE",
|
||||
"SLICE cutting-plane axis [X / Y / Z] (add TOP/BOTTOM by typing):",
|
||||
vec![
|
||||
("X", "X", Some("SLICE offset along X:")),
|
||||
("Y", "Y", Some("SLICE offset along Y:")),
|
||||
("Z", "Z", Some("SLICE offset along Z:")),
|
||||
],
|
||||
has_sel,
|
||||
);
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
cmd if cmd.starts_with("SLICE ") || cmd.starts_with("SL ") => {
|
||||
let parts: Vec<String> = cmd
|
||||
.split_whitespace()
|
||||
.skip(1)
|
||||
|
||||
@@ -55,10 +55,13 @@ impl OpenCADStudio {
|
||||
|
||||
// CAL / QUICKCALC <expression> — evaluate an arithmetic expression
|
||||
// (+ - * /, parentheses, unary minus, decimals).
|
||||
cmd if cmd == "CAL"
|
||||
|| cmd == "QUICKCALC"
|
||||
|| cmd == "QC"
|
||||
|| cmd.starts_with("CAL ")
|
||||
"CAL" | "QUICKCALC" | "QC" => {
|
||||
use crate::command::ValuePromptCommand;
|
||||
let c = ValuePromptCommand::new("CAL", "CAL expression (e.g. (2+3)*4):");
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[self.active_tab].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
cmd if cmd.starts_with("CAL ")
|
||||
|| cmd.starts_with("QUICKCALC ")
|
||||
|| cmd.starts_with("QC ") =>
|
||||
{
|
||||
@@ -922,11 +925,25 @@ impl OpenCADStudio {
|
||||
// FIND <search> — list all Text/MText/Dimension containing <search>
|
||||
// FIND <search> REPLACE <rep> — replace first occurrence (case-insensitive)
|
||||
// FINDALL <search> REPLACE <rep> — replace all occurrences
|
||||
cmd if cmd == "FIND"
|
||||
|| cmd.starts_with("FIND ")
|
||||
|| cmd == "FINDALL"
|
||||
|| cmd.starts_with("FINDALL ") =>
|
||||
{
|
||||
"FIND" => {
|
||||
use crate::command::ValuePromptCommand;
|
||||
let c = ValuePromptCommand::new(
|
||||
"FIND",
|
||||
"FIND text to find (add REPLACE <text> by typing):",
|
||||
);
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[self.active_tab].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
"FINDALL" => {
|
||||
use crate::command::ValuePromptCommand;
|
||||
let c = ValuePromptCommand::new(
|
||||
"FINDALL",
|
||||
"FINDALL text to find (add REPLACE <text> by typing):",
|
||||
);
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[self.active_tab].active_cmd = Some(Box::new(c));
|
||||
}
|
||||
cmd if cmd.starts_with("FIND ") || cmd.starts_with("FINDALL ") => {
|
||||
let all_mode = cmd.starts_with("FINDALL");
|
||||
let rest = cmd.split_once(' ').map(|(_, r)| r.trim()).unwrap_or("");
|
||||
|
||||
|
||||
Reference in new issue
Block a user