forked from 1b-agent/opencadstudio-upstream
Correct circle size input and persistence
This commit is contained in:
1 parent
573ed3245e
commit
b0e464f4b4
2 files changed
+97
-29
No files matched your search
@@ -5,7 +5,6 @@ use std::cell::Cell;
|
||||
|
||||
thread_local! {
|
||||
static CIRCLE_RADIUS: Cell<f64> = Cell::new(1.0);
|
||||
static CIRCLE_DIAM: Cell<f64> = Cell::new(2.0);
|
||||
static ROTATE_ANGLE: Cell<f64> = Cell::new(0.0); // degrees
|
||||
static SCALE_FACTOR: Cell<f64> = Cell::new(1.0);
|
||||
static OFFSET_DIST: Cell<f64> = Cell::new(1.0);
|
||||
@@ -34,7 +33,13 @@ macro_rules! accessors {
|
||||
}
|
||||
|
||||
accessors!(get_circle_radius, set_circle_radius, CIRCLE_RADIUS);
|
||||
accessors!(get_circle_diam, set_circle_diam, CIRCLE_DIAM);
|
||||
pub fn get_circle_diam() -> f64 {
|
||||
get_circle_radius() * 2.0
|
||||
}
|
||||
|
||||
pub fn set_circle_diam(value: f64) {
|
||||
set_circle_radius(value * 0.5);
|
||||
}
|
||||
accessors!(get_rotate_angle, set_rotate_angle, ROTATE_ANGLE);
|
||||
accessors!(get_scale_factor, set_scale_factor, SCALE_FACTOR);
|
||||
accessors!(get_offset_dist, set_offset_dist, OFFSET_DIST);
|
||||
|
||||
@@ -151,6 +151,7 @@ pub struct CircleCommand {
|
||||
enum StepCR {
|
||||
Center,
|
||||
Radius(DVec3),
|
||||
Diameter(DVec3),
|
||||
}
|
||||
|
||||
impl CircleCommand {
|
||||
@@ -186,6 +187,11 @@ impl CadCommand for CircleCommand {
|
||||
)
|
||||
.into_owned()
|
||||
}
|
||||
StepCR::Diameter(_) => crate::tf!(
|
||||
"CIRCLE Specify diameter <{:.4}>:",
|
||||
self.default_r * 2.0
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,15 +202,16 @@ impl CadCommand for CircleCommand {
|
||||
CmdOption::new("3P", "3P"),
|
||||
CmdOption::new("2P", "2P"),
|
||||
CmdOption::new("Ttr", "TTR"),
|
||||
CmdOption::new("Ttt", "TTT"),
|
||||
],
|
||||
StepCR::Radius(_) => vec![
|
||||
CmdOption::new(t!("Diameter").as_ref(), "D"),
|
||||
],
|
||||
StepCR::Radius(_) => vec![],
|
||||
StepCR::Diameter(_) => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn point_step_accepts_keywords(&self) -> bool {
|
||||
matches!(self.step, StepCR::Center)
|
||||
!matches!(self.step, StepCR::Diameter(_))
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
match &self.step {
|
||||
@@ -214,27 +221,49 @@ impl CadCommand for CircleCommand {
|
||||
}
|
||||
StepCR::Radius(c) => {
|
||||
let r = plane_distance(*c, pt, self.plane);
|
||||
if r <= 1.0e-9 {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
defaults::set_circle_radius(r);
|
||||
CmdResult::CommitAndExit(make_circle(*c, r, self.plane))
|
||||
}
|
||||
StepCR::Diameter(c) => {
|
||||
let radius = plane_distance(*c, pt, self.plane);
|
||||
if radius <= 1.0e-9 {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
defaults::set_circle_radius(radius);
|
||||
CmdResult::CommitAndExit(make_circle(*c, radius, self.plane))
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
if let StepCR::Radius(c) = &self.step {
|
||||
let c = *c;
|
||||
let r = self.default_r;
|
||||
return CmdResult::CommitAndExit(make_circle(c, r, self.plane));
|
||||
match self.step {
|
||||
StepCR::Radius(center) => {
|
||||
CmdResult::CommitAndExit(make_circle(center, self.default_r, self.plane))
|
||||
}
|
||||
StepCR::Diameter(center) => {
|
||||
CmdResult::CommitAndExit(make_circle(center, self.default_r, self.plane))
|
||||
}
|
||||
StepCR::Center => CmdResult::Cancel,
|
||||
}
|
||||
CmdResult::Cancel
|
||||
}
|
||||
fn on_escape(&mut self) -> CmdResult {
|
||||
CmdResult::Cancel
|
||||
}
|
||||
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
||||
if let StepCR::Radius(c) = &self.step {
|
||||
Some(circle_wire(*c, plane_distance(*c, pt, self.plane), self.plane))
|
||||
} else {
|
||||
None
|
||||
match self.step {
|
||||
StepCR::Radius(center) => Some(circle_wire(
|
||||
center,
|
||||
plane_distance(center, pt, self.plane),
|
||||
self.plane,
|
||||
)),
|
||||
StepCR::Diameter(center) => Some(circle_wire(
|
||||
center,
|
||||
plane_distance(center, pt, self.plane),
|
||||
self.plane,
|
||||
)),
|
||||
StepCR::Center => None,
|
||||
}
|
||||
}
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
@@ -245,11 +274,15 @@ impl CadCommand for CircleCommand {
|
||||
"3P" => Some(CmdResult::Dispatch("CIRCLE_3P".into())),
|
||||
"2P" => Some(CmdResult::Dispatch("CIRCLE_2P".into())),
|
||||
"T" | "TTR" => Some(CmdResult::Dispatch("CIRCLE_TTR".into())),
|
||||
"TTT" => Some(CmdResult::Dispatch("CIRCLE_TTT".into())),
|
||||
"D" | "DIAMETER" => Some(CmdResult::Dispatch("CIRCLE_CD".into())),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
if let StepCR::Radius(center) = &self.step {
|
||||
if matches!(text.trim().to_uppercase().as_str(), "D" | "DIAMETER") {
|
||||
self.step = StepCR::Diameter(*center);
|
||||
return Some(CmdResult::NeedPoint);
|
||||
}
|
||||
}
|
||||
if let StepCR::Radius(c) = &self.step {
|
||||
let r: f64 = text.trim().replace(',', ".").parse().ok()?;
|
||||
if r > 0.0 {
|
||||
@@ -257,12 +290,23 @@ impl CadCommand for CircleCommand {
|
||||
return Some(CmdResult::CommitAndExit(make_circle(*c, r, self.plane)));
|
||||
}
|
||||
}
|
||||
if let StepCR::Diameter(c) = &self.step {
|
||||
let diameter: f64 = text.trim().replace(',', ".").parse().ok()?;
|
||||
if diameter > 0.0 {
|
||||
defaults::set_circle_diam(diameter);
|
||||
return Some(CmdResult::CommitAndExit(make_circle(
|
||||
*c,
|
||||
diameter * 0.5,
|
||||
self.plane,
|
||||
)));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
fn dyn_field(&self) -> DynField {
|
||||
match self.step {
|
||||
StepCR::Center => DynField::Point,
|
||||
StepCR::Radius(_) => DynField::Distance,
|
||||
StepCR::Radius(_) | StepCR::Diameter(_) => DynField::Distance,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,6 +323,12 @@ impl CadCommand for CircleCommand {
|
||||
guide: DynGuide::Radius,
|
||||
ref_point: None,
|
||||
}),
|
||||
StepCR::Diameter(c) => Some(DynSpec {
|
||||
anchor: DynAnchor::Point(c),
|
||||
fields: vec![DynFieldSpec::new(DynRole::Diameter)],
|
||||
guide: DynGuide::Radius,
|
||||
ref_point: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,28 +362,33 @@ impl CadCommand for CircleCDCommand {
|
||||
fn prompt(&self) -> String {
|
||||
match &self.step {
|
||||
StepCR::Center => t!("CIRCLE CD Specify center point:").into_owned(),
|
||||
StepCR::Radius(c) => crate::tf!(
|
||||
StepCR::Diameter(c) => crate::tf!(
|
||||
"CIRCLE CD Specify diameter or type value <{:.4}> [center ({:.3},{:.3})]:",
|
||||
self.default_d, c.x, c.y
|
||||
)
|
||||
.into_owned(),
|
||||
StepCR::Radius(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
match &self.step {
|
||||
StepCR::Center => {
|
||||
self.step = StepCR::Radius(pt);
|
||||
self.step = StepCR::Diameter(pt);
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
StepCR::Radius(c) => {
|
||||
let d = plane_distance(*c, pt, self.plane) * 2.0;
|
||||
defaults::set_circle_diam(d);
|
||||
CmdResult::CommitAndExit(make_circle(*c, d / 2.0, self.plane))
|
||||
StepCR::Diameter(c) => {
|
||||
let radius = plane_distance(*c, pt, self.plane);
|
||||
if radius <= 1.0e-9 {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
defaults::set_circle_radius(radius);
|
||||
CmdResult::CommitAndExit(make_circle(*c, radius, self.plane))
|
||||
}
|
||||
StepCR::Radius(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
if let StepCR::Radius(c) = &self.step {
|
||||
if let StepCR::Diameter(c) = &self.step {
|
||||
let c = *c;
|
||||
let d = self.default_d;
|
||||
return CmdResult::CommitAndExit(make_circle(c, d / 2.0, self.plane));
|
||||
@@ -344,15 +399,18 @@ impl CadCommand for CircleCDCommand {
|
||||
CmdResult::Cancel
|
||||
}
|
||||
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
|
||||
// Preview radius = distance to cursor; on commit that distance becomes the radius (diameter = 2x).
|
||||
if let StepCR::Radius(c) = &self.step {
|
||||
Some(circle_wire(*c, plane_distance(*c, pt, self.plane), self.plane))
|
||||
if let StepCR::Diameter(c) = &self.step {
|
||||
Some(circle_wire(
|
||||
*c,
|
||||
plane_distance(*c, pt, self.plane),
|
||||
self.plane,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
if let StepCR::Radius(c) = &self.step {
|
||||
if let StepCR::Diameter(c) = &self.step {
|
||||
let d: f64 = text.trim().replace(',', ".").parse().ok()?;
|
||||
if d > 0.0 {
|
||||
defaults::set_circle_diam(d);
|
||||
@@ -368,12 +426,13 @@ impl CadCommand for CircleCDCommand {
|
||||
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 {
|
||||
StepCR::Diameter(c) => Some(DynSpec {
|
||||
anchor: DynAnchor::Point(c),
|
||||
fields: vec![DynFieldSpec::new(DynRole::Diameter)],
|
||||
guide: DynGuide::Radius,
|
||||
ref_point: None,
|
||||
}),
|
||||
StepCR::Radius(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -418,6 +477,10 @@ impl CadCommand for Circle2PCommand {
|
||||
Some(p1) => {
|
||||
let center = (p1 + pt) * 0.5;
|
||||
let radius = plane_distance(p1, pt, self.plane) / 2.0;
|
||||
if radius <= 1.0e-9 {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
defaults::set_circle_radius(radius);
|
||||
CmdResult::CommitAndExit(make_circle(center, radius, self.plane))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user