forked from 1b-agent/opencadstudio-upstream
feat(modify): commercial solutions keyword options for MOVE, COPY, FILLET, CHAMFER, OFFSET
MOVE: Displacement, Enter at the second point uses the base as the vector. COPY: Displacement, mOde (Single/Multiple), Undo of the last copy. FILLET: Undo of the last fillet (the command refreshes its entity cache through the new CadCommand::on_document_undone hook after the host undoes the document step). CHAMFER: Multiple and Undo. OFFSET: Erase (the offset replaces its source), Layer (Current/Source), Undo, Exit. POLY3D, TRACE, MIRROR and MEASUREGEOM expose the keywords they already accepted as options, so the context menu and option buttons list them. The pinned prompt now keeps informational bracket groups such as "[3 objects]" and only drops real option listings when the buttons take over. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
1 parent
c0bc44c4f6
commit
d753874fe4
32 files changed
+760
-54
No files matched your search
+17
-4
@@ -71,15 +71,28 @@ fn mcp_status(enabled: bool, busy: bool) -> (&'static str, Color) {
|
||||
}
|
||||
|
||||
/// Drop a prompt's "[A / B / …]" option listing — used for the pinned line
|
||||
/// when the same options render as clickable buttons beside it. Collapses the
|
||||
/// leftover double spaces and the orphaned " :" the removal leaves behind.
|
||||
fn strip_option_listing(s: &str) -> String {
|
||||
/// when the same options render as clickable buttons beside it. Only a
|
||||
/// bracket group that reads as a listing goes (several choices, or a single
|
||||
/// choice that is one of `options`); an informational group such as
|
||||
/// "[3 objects]" or "[base 1.0,2.0]" stays. Collapses the leftover double
|
||||
/// spaces and the orphaned " :" the removal leaves behind.
|
||||
fn strip_option_listing(s: &str, options: &[CmdOption]) -> String {
|
||||
let Some(a) = s.find('[') else {
|
||||
return s.to_string();
|
||||
};
|
||||
let Some(off) = s[a..].find(']') else {
|
||||
return s.to_string();
|
||||
};
|
||||
let inner = s[a + 1..a + off].trim();
|
||||
let is_listing = inner.contains('/')
|
||||
|| inner.contains('|')
|
||||
|| inner.contains('=')
|
||||
|| options.iter().any(|o| {
|
||||
o.label.eq_ignore_ascii_case(inner) || o.keyword.eq_ignore_ascii_case(inner)
|
||||
});
|
||||
if !is_listing {
|
||||
return s.to_string();
|
||||
}
|
||||
let mut out = format!("{}{}", &s[..a], &s[a + off + 1..]);
|
||||
while out.contains(" ") {
|
||||
out = out.replace(" ", " ");
|
||||
@@ -638,7 +651,7 @@ impl CommandLine {
|
||||
// already name every choice, so the prompt's own "[A / B / …]"
|
||||
// listing is dropped here (the history log keeps the full text).
|
||||
if entry.pinned && !self.step_options.is_empty() {
|
||||
let shown = strip_option_listing(&entry.text);
|
||||
let shown = strip_option_listing(&entry.text, &self.step_options);
|
||||
let mut r = row![entry_text(shown)].spacing(6).align_y(iced::Center);
|
||||
for opt in &self.step_options {
|
||||
let btn = button(text(opt.label.to_uppercase()).size(11))
|
||||
|
||||
Reference in new issue
Block a user