forked from 1b-agent/opencadstudio-upstream
feat(dynamic-input): per-step DynSpec framework + guide overhaul
Introduce a per-command, per-step dynamic-input description so each step
shows the value boxes and guide geometry that make sense for it, instead
of a one-size-fits-all distance/angle pair.
- command: add DynSpec{anchor, fields(role+label), guide}, DynRole
(X/Y/Z/Distance/Angle/Radius/Diameter/Width/Height/Factor/Count with
label + value scaling), DynGuide(None/Polar/AxisDelta/Radius/RectSides)
and DynAnchor. New dyn_spec() trait method defaults to None so commands
on the legacy dyn_field() path are unchanged.
- overlay: redraw the dynamic-input layer by guide — polar reference line
+ angle arc, single radius line, dotted axis legs, or a cursor row —
and place each box by its role. Angle reads as the unsigned magnitude
of the short arc; a typed polar angle takes the sign of the cursor side.
- app: route fields/guide/anchor through the tab; resolve points from the
step anchor and de-scale typed values by role (typed diameter -> radius).
- circle: CR shows a radius value on one line to the cursor; CD shows the
diameter (twice the cursor radius). No angle arc on radius steps.
- pline/mline: keep polar dynamic input on vertex steps that also accept
keyword letters via point_step_accepts_keywords().
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
18f1688486
commit
b0ee1c39bd
8 files changed
+613
-150
No files matched your search
@@ -189,6 +189,21 @@ impl CadCommand for CircleCommand {
|
||||
StepCR::Radius(_) => DynField::Distance,
|
||||
}
|
||||
}
|
||||
|
||||
fn dyn_spec(&self) -> Option<crate::command::DynSpec> {
|
||||
use crate::command::{DynAnchor, DynFieldSpec, DynGuide, DynRole, DynSpec};
|
||||
match self.step {
|
||||
// Center is a normal first-point pick.
|
||||
StepCR::Center => None,
|
||||
// Radius: a single R value with one dotted line from the centre to
|
||||
// the cursor (no angle, no axis legs).
|
||||
StepCR::Radius(c) => Some(DynSpec {
|
||||
anchor: DynAnchor::Point(c),
|
||||
fields: vec![DynFieldSpec::new(DynRole::Radius)],
|
||||
guide: DynGuide::Radius,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Command: Center, Diameter ──────────────────────────────────────────────
|
||||
@@ -262,6 +277,20 @@ impl CadCommand for CircleCDCommand {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn dyn_spec(&self) -> Option<crate::command::DynSpec> {
|
||||
use crate::command::{DynAnchor, DynFieldSpec, DynGuide, DynRole, DynSpec};
|
||||
match self.step {
|
||||
StepCR::Center => None,
|
||||
// Diameter: the box shows/accepts twice the cursor radius; resolved
|
||||
// back to a radius point by the host (role scaling).
|
||||
StepCR::Radius(c) => Some(DynSpec {
|
||||
anchor: DynAnchor::Point(c),
|
||||
fields: vec![DynFieldSpec::new(DynRole::Diameter)],
|
||||
guide: DynGuide::Radius,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Command: 2-Point ──────────────────────────────────────────────────────
|
||||
|
||||
@@ -63,6 +63,13 @@ impl CadCommand for MlineCommand {
|
||||
self.waiting_scale || !self.points.is_empty()
|
||||
}
|
||||
|
||||
fn point_step_accepts_keywords(&self) -> bool {
|
||||
// The vertex steps accept J / S keywords but are point picks, so keep
|
||||
// polar dynamic input. The scale prompt (`waiting_scale`) is genuine
|
||||
// text entry and is excluded.
|
||||
!self.waiting_scale && !self.points.is_empty()
|
||||
}
|
||||
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
// Waiting for scale value
|
||||
if self.waiting_scale {
|
||||
|
||||
@@ -253,6 +253,12 @@ impl CadCommand for PlineCommand {
|
||||
!self.vertices.is_empty()
|
||||
}
|
||||
|
||||
fn point_step_accepts_keywords(&self) -> bool {
|
||||
// Each segment is a point pick that also accepts A / L / C / U, so the
|
||||
// polar dynamic-input distance/angle stays visible.
|
||||
!self.vertices.is_empty()
|
||||
}
|
||||
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
match text.trim().to_uppercase().as_str() {
|
||||
"A" | "ARC" => {
|
||||
|
||||
Reference in new issue
Block a user