forked from 1b-agent/opencadstudio-upstream
fix(snap): typed overrides yield to the prompt's options; one point-step gate
#1707 took any snap name typed at a point prompt as an override, so a prompt offering Center, Tangent, Parallel or None (ARC, ELLIPSE, CIRCLE TTR, ...) could no longer be answered with that option's name. An option the prompt offers now wins. The point-step test it copied from MTP is one helper shared by MTP and the override on both input paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
45bc31f730
commit
23b21b5d77
3 files changed
+38
-73
No files matched your search
@@ -1121,46 +1121,14 @@ impl OpenCADStudio {
|
|||||||
let is_mtp = token.trim_start_matches('_').eq_ignore_ascii_case("MTP")
|
let is_mtp = token.trim_start_matches('_').eq_ignore_ascii_case("MTP")
|
||||||
|| token.trim_start_matches('_').eq_ignore_ascii_case("M2P");
|
|| token.trim_start_matches('_').eq_ignore_ascii_case("M2P");
|
||||||
if is_mtp {
|
if is_mtp {
|
||||||
let is_point_step = !self.tabs[i]
|
if self.point_modifier_step(i) {
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.input_kind().wants_text())
|
|
||||||
.unwrap_or(true)
|
|
||||||
|| self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.point_step_accepts_keywords())
|
|
||||||
.unwrap_or(false);
|
|
||||||
let not_entity_pick = !self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.needs_entity_pick())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if is_point_step && not_entity_pick {
|
|
||||||
self.start_mtp_modifier(i);
|
self.start_mtp_modifier(i);
|
||||||
return Task::none();
|
return Task::none();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(override_kind) = crate::snap::parse_snap_override(token) {
|
if let Some(kind) = self.typed_snap_override(i, token) {
|
||||||
let is_point_step = !self.tabs[i]
|
self.apply_snap_override(kind);
|
||||||
.active_cmd
|
return Task::none();
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.input_kind().wants_text())
|
|
||||||
.unwrap_or(true)
|
|
||||||
|| self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.point_step_accepts_keywords())
|
|
||||||
.unwrap_or(false);
|
|
||||||
let not_entity_pick = !self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.needs_entity_pick())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if is_point_step && not_entity_pick {
|
|
||||||
self.apply_snap_override(override_kind);
|
|
||||||
return Task::none();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some((coord, kind)) = crate::app::helpers::parse_coord(token) {
|
if let Some((coord, kind)) = crate::app::helpers::parse_coord(token) {
|
||||||
// Match the GUI command line: typed coordinates are in the active
|
// Match the GUI command line: typed coordinates are in the active
|
||||||
|
|||||||
@@ -814,48 +814,16 @@ impl OpenCADStudio {
|
|||||||
let is_mtp = raw.trim_start_matches('_').eq_ignore_ascii_case("MTP")
|
let is_mtp = raw.trim_start_matches('_').eq_ignore_ascii_case("MTP")
|
||||||
|| raw.trim_start_matches('_').eq_ignore_ascii_case("M2P");
|
|| raw.trim_start_matches('_').eq_ignore_ascii_case("M2P");
|
||||||
if is_mtp {
|
if is_mtp {
|
||||||
let is_point_step = !self.tabs[i]
|
if self.point_modifier_step(i) {
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.input_kind().wants_text())
|
|
||||||
.unwrap_or(true)
|
|
||||||
|| self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.point_step_accepts_keywords())
|
|
||||||
.unwrap_or(false);
|
|
||||||
let not_entity_pick = !self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.needs_entity_pick())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if is_point_step && not_entity_pick {
|
|
||||||
self.command_line.input.clear();
|
self.command_line.input.clear();
|
||||||
self.start_mtp_modifier(i);
|
self.start_mtp_modifier(i);
|
||||||
return self.focus_cmd_input();
|
return self.focus_cmd_input();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(override_kind) = crate::snap::parse_snap_override(&raw) {
|
if let Some(kind) = self.typed_snap_override(i, &raw) {
|
||||||
let is_point_step = !self.tabs[i]
|
self.command_line.input.clear();
|
||||||
.active_cmd
|
self.apply_snap_override(kind);
|
||||||
.as_ref()
|
return self.focus_cmd_input();
|
||||||
.map(|c| c.input_kind().wants_text())
|
|
||||||
.unwrap_or(true)
|
|
||||||
|| self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.point_step_accepts_keywords())
|
|
||||||
.unwrap_or(false);
|
|
||||||
let not_entity_pick = !self.tabs[i]
|
|
||||||
.active_cmd
|
|
||||||
.as_ref()
|
|
||||||
.map(|c| c.needs_entity_pick())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if is_point_step && not_entity_pick {
|
|
||||||
self.command_line.input.clear();
|
|
||||||
self.apply_snap_override(override_kind);
|
|
||||||
return self.focus_cmd_input();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let text = if free_text {
|
let text = if free_text {
|
||||||
raw
|
raw
|
||||||
|
|||||||
@@ -50,6 +50,35 @@ impl OpenCADStudio {
|
|||||||
self.accepted_snaps.clear();
|
self.accepted_snaps.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The active command is at a point prompt (keywords allowed) and not
|
||||||
|
/// picking an object: where MTP and typed snap overrides apply.
|
||||||
|
pub(crate) fn point_modifier_step(&self, i: usize) -> bool {
|
||||||
|
self.tabs[i].active_cmd.as_ref().is_some_and(|c| {
|
||||||
|
(!c.input_kind().wants_text() || c.point_step_accepts_keywords())
|
||||||
|
&& !c.needs_entity_pick()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A snap override typed at a point prompt (`MID`, `END`, `NON`, ...). An
|
||||||
|
/// option the prompt offers wins, so `CEN` where Center is offered picks
|
||||||
|
/// Center.
|
||||||
|
pub(crate) fn typed_snap_override(
|
||||||
|
&self,
|
||||||
|
i: usize,
|
||||||
|
token: &str,
|
||||||
|
) -> Option<crate::snap::SnapOverrideKind> {
|
||||||
|
let kind = crate::snap::parse_snap_override(token)?;
|
||||||
|
if !self.point_modifier_step(i) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let typed = token.trim().trim_start_matches('_').to_uppercase();
|
||||||
|
let offered = self.tabs[i].active_cmd.as_ref()?.options().iter().any(|option| {
|
||||||
|
option.keyword.eq_ignore_ascii_case(&typed)
|
||||||
|
|| option.label.to_uppercase().replace(' ', "").starts_with(&typed)
|
||||||
|
});
|
||||||
|
(!offered).then_some(kind)
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply a transparent one-shot snap override (from typed input or the context menu).
|
/// Apply a transparent one-shot snap override (from typed input or the context menu).
|
||||||
pub(crate) fn apply_snap_override(&mut self, kind: crate::snap::SnapOverrideKind) {
|
pub(crate) fn apply_snap_override(&mut self, kind: crate::snap::SnapOverrideKind) {
|
||||||
match kind {
|
match kind {
|
||||||
|
|||||||
Reference in new issue
Block a user