forked from 1b-agent/opencadstudio-upstream
fix(dyn-input): re-sync fields immediately after point commits (#35)
`sync_dyn_fields` only ran during `ViewportMove`, so a typed-coord or click-driven point commit left the previous iteration's field shape in place until the user nudged the mouse. After the first LINE click that meant the stale `[X, Y]` (built when there was no base) kept serving the next point's input as cartesian even though the command-default for a "Point with base" is now polar `[Distance, Angle]`. The original #35 fix preserved a `,`-reshaped cartesian set on purpose, but the same machinery now also held onto a never-explicitly-chosen `[X, Y]` carried over from "no base" → "has base". Track that intent explicitly with `dyn_user_reshaped` (set in `dyn_comma_advance`, cleared on point commit and command start) and only treat a non-matching shape as acceptable while that flag is on. Re-run `sync_dyn_fields` from every point-commit path (command-line typed coord, mouse click, dynamic-input locked commit) so the freshly updated `has_base` state immediately picks the right default and the user sees polar fields without having to move the mouse first.
This commit is contained in:
1 parent
f952fc9bb7
commit
8f02e1ca07
3 files changed
+40
-12
No files matched your search
@@ -15,6 +15,9 @@ impl OpenCADStudio {
|
||||
// Reset the last committed point so the first click of the new command
|
||||
// is not constrained by ortho/polar relative to a previous command's endpoint.
|
||||
self.last_point = None;
|
||||
// A fresh command starts at the polar/cartesian default — clear
|
||||
// any `,`-driven reshape from a previous command (#35).
|
||||
self.dyn_user_reshaped = false;
|
||||
|
||||
if let Some(path_str) = cmd.strip_prefix("OPEN_RECENT:") {
|
||||
let path = PathBuf::from(path_str);
|
||||
|
||||
@@ -88,6 +88,12 @@ pub(super) struct OpenCADStudio {
|
||||
/// edge, updated on move, cleared on release (which also runs the
|
||||
/// collapse pass).
|
||||
tile_drag: Option<TileDrag>,
|
||||
/// `true` once the user has reshaped the dynamic-input field set via
|
||||
/// the `,` separator during the current command iteration. Tells
|
||||
/// `sync_dyn_fields` to preserve the user's chosen shape instead of
|
||||
/// reverting to the command-default when `has_base` flips. Cleared
|
||||
/// on point commit / command start. See #35.
|
||||
dyn_user_reshaped: bool,
|
||||
/// Show the UCS icon in the bottom-left corner of model space (UCSICON).
|
||||
show_ucs_icon: bool,
|
||||
/// Whether the ViewCube 3D gizmo is visible in model space (NAVVCUBE).
|
||||
@@ -763,6 +769,7 @@ impl OpenCADStudio {
|
||||
dyn_input: true,
|
||||
awaiting_vports: false,
|
||||
tile_drag: None,
|
||||
dyn_user_reshaped: false,
|
||||
show_ucs_icon: true,
|
||||
show_viewcube: true,
|
||||
show_properties: true,
|
||||
|
||||
+30
-12
@@ -1097,6 +1097,8 @@ impl OpenCADStudio {
|
||||
}
|
||||
};
|
||||
self.last_point = Some(wcs_pt);
|
||||
self.dyn_user_reshaped = false;
|
||||
self.sync_dyn_fields();
|
||||
let result = self.tabs[i].active_cmd.as_mut().map(|c| c.on_point(wcs_pt));
|
||||
if let Some(r) = result {
|
||||
let task = self.apply_cmd_result(r);
|
||||
@@ -2476,6 +2478,8 @@ impl OpenCADStudio {
|
||||
}
|
||||
} else {
|
||||
self.last_point = Some(world_pt);
|
||||
self.dyn_user_reshaped = false;
|
||||
self.sync_dyn_fields();
|
||||
self.tabs[i]
|
||||
.active_cmd
|
||||
.as_mut()
|
||||
@@ -5400,19 +5404,28 @@ impl OpenCADStudio {
|
||||
// move.
|
||||
let current: Vec<DynComponent> =
|
||||
self.tabs[i].dyn_fields.iter().map(|f| f.component).collect();
|
||||
let current_is_acceptable = match field {
|
||||
crate::command::DynField::Distance => {
|
||||
matches!(current.as_slice(), [DynComponent::Distance])
|
||||
// Only treat a cartesian / polar variant as "good enough to keep"
|
||||
// when the user explicitly reshaped via `,`. Otherwise we follow
|
||||
// the command's default so e.g. clicking the first point of LINE
|
||||
// flips a stale `[X, Y]` (from before there was a base) over to
|
||||
// the polar `[Distance, Angle]` the prompt actually wants.
|
||||
let current_is_acceptable = if self.dyn_user_reshaped {
|
||||
match field {
|
||||
crate::command::DynField::Distance => {
|
||||
matches!(current.as_slice(), [DynComponent::Distance])
|
||||
}
|
||||
crate::command::DynField::Angle => {
|
||||
matches!(current.as_slice(), [DynComponent::Angle])
|
||||
}
|
||||
crate::command::DynField::Point => matches!(
|
||||
current.as_slice(),
|
||||
[DynComponent::Distance, DynComponent::Angle]
|
||||
| [DynComponent::X, DynComponent::Y]
|
||||
| [DynComponent::X, DynComponent::Y, DynComponent::Z]
|
||||
),
|
||||
}
|
||||
crate::command::DynField::Angle => {
|
||||
matches!(current.as_slice(), [DynComponent::Angle])
|
||||
}
|
||||
crate::command::DynField::Point => matches!(
|
||||
current.as_slice(),
|
||||
[DynComponent::Distance, DynComponent::Angle]
|
||||
| [DynComponent::X, DynComponent::Y]
|
||||
| [DynComponent::X, DynComponent::Y, DynComponent::Z]
|
||||
),
|
||||
} else {
|
||||
current == default
|
||||
};
|
||||
if !current_is_acceptable {
|
||||
self.tabs[i].dyn_fields = default.into_iter().map(DynFieldEntry::new).collect();
|
||||
@@ -5523,6 +5536,9 @@ impl OpenCADStudio {
|
||||
if self.tabs[i].dyn_fields.is_empty() {
|
||||
return;
|
||||
}
|
||||
// The user picked a shape — `sync_dyn_fields` preserves it until
|
||||
// the next commit / command-start clears the flag.
|
||||
self.dyn_user_reshaped = true;
|
||||
let active = self
|
||||
.tabs[i]
|
||||
.dyn_active
|
||||
@@ -5582,6 +5598,8 @@ impl OpenCADStudio {
|
||||
}
|
||||
let pt = self.dyn_resolve_point()?;
|
||||
self.last_point = Some(pt);
|
||||
self.dyn_user_reshaped = false;
|
||||
self.sync_dyn_fields();
|
||||
let result = self.tabs[i].active_cmd.as_mut().map(|c| c.on_point(pt));
|
||||
for f in self.tabs[i].dyn_fields.iter_mut() {
|
||||
f.buffer = None;
|
||||
|
||||
Reference in new issue
Block a user