forked from 1b-agent/opencadstudio-upstream
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec: the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders, Block, …) with the spec's rows and real computed values — Diameter, Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio, etc. — plus apply routing for the editable rows. Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines, Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid, Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport, Attribute, OLE). The 3D Visualization/Material group and the full Dimension spec are deferred (they need document access for material/dimstyle name resolution). Rows whose data is not in the pinned acadrust revision are shown as empty placeholders, to be filled when the dependency is bumped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
b2b2bfb246
commit
b9cebab951
26 files changed
+1917
-1558
No files matched your search
+171
-149
@@ -385,26 +385,33 @@ impl Grippable for AttributeDefinition {
|
||||
|
||||
impl PropertyEditable for AttributeDefinition {
|
||||
fn geometry_properties(&self, text_style_names: &[String]) -> Vec<PropSection> {
|
||||
let mut props = vec![
|
||||
let mut text_props = vec![
|
||||
ro("Tag", "att_tag", self.tag.clone()),
|
||||
ro("Prompt", "att_prompt", self.prompt.clone()),
|
||||
Property {
|
||||
label: "Default".into(),
|
||||
label: "Value".into(),
|
||||
field: "att_default",
|
||||
value: PropValue::EditText(self.default_value.clone()),
|
||||
},
|
||||
edit("Insert X", "att_ix", self.insertion_point.x),
|
||||
edit("Insert Y", "att_iy", self.insertion_point.y),
|
||||
edit("Insert Z", "att_iz", self.insertion_point.z),
|
||||
edit("Align X", "att_ax", self.alignment_point.x),
|
||||
edit("Align Y", "att_ay", self.alignment_point.y),
|
||||
edit("Align Z", "att_az", self.alignment_point.z),
|
||||
edit("Height", "att_h", self.height),
|
||||
edit("Rotation", "att_rot", self.rotation.to_degrees()),
|
||||
edit("Width Factor", "att_wf", self.width_factor),
|
||||
edit("Oblique Angle", "att_ob", self.oblique_angle.to_degrees()),
|
||||
Property {
|
||||
label: "H-Align".into(),
|
||||
label: "Style".into(),
|
||||
field: "att_style",
|
||||
value: PropValue::Choice {
|
||||
selected: if self.text_style.trim().is_empty() {
|
||||
"Standard".into()
|
||||
} else {
|
||||
self.text_style.clone()
|
||||
},
|
||||
options: text_style_names.to_vec(),
|
||||
},
|
||||
},
|
||||
ro(
|
||||
"Annotative",
|
||||
"att_annotative",
|
||||
bool_yn(self.flags.annotative),
|
||||
),
|
||||
Property {
|
||||
label: "Justify".into(),
|
||||
field: "att_halign",
|
||||
value: PropValue::Choice {
|
||||
selected: halign_str(self.horizontal_alignment).to_string(),
|
||||
@@ -425,63 +432,71 @@ impl PropertyEditable for AttributeDefinition {
|
||||
.collect(),
|
||||
},
|
||||
},
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
field: "att_style",
|
||||
value: PropValue::Choice {
|
||||
selected: if self.text_style.trim().is_empty() {
|
||||
"Standard".into()
|
||||
} else {
|
||||
self.text_style.clone()
|
||||
},
|
||||
options: text_style_names.to_vec(),
|
||||
},
|
||||
},
|
||||
edit("Height", "att_h", self.height),
|
||||
edit("Rotation", "att_rot", self.rotation.to_degrees()),
|
||||
edit("Width factor", "att_wf", self.width_factor),
|
||||
edit("Obliquing", "att_ob", self.oblique_angle.to_degrees()),
|
||||
edit("Text alignment X", "att_ax", self.alignment_point.x),
|
||||
edit("Text alignment Y", "att_ay", self.alignment_point.y),
|
||||
edit("Text alignment Z", "att_az", self.alignment_point.z),
|
||||
ro(
|
||||
"Generation",
|
||||
"att_gen_flags",
|
||||
format!("{:#06b}", self.text_generation_flags & 0xff),
|
||||
),
|
||||
ro(
|
||||
"Field Length",
|
||||
"Boundary width",
|
||||
"att_field_len",
|
||||
self.field_length.to_string(),
|
||||
),
|
||||
Property {
|
||||
label: "MText Mode".into(),
|
||||
field: "att_mtext_flag",
|
||||
value: PropValue::Choice {
|
||||
selected: mtext_flag_str(self.mtext_flag).to_string(),
|
||||
options: ["SingleLine", "MultiLine", "ConstantMultiLine"]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
},
|
||||
},
|
||||
ro("Multiline", "att_is_multiline", bool_yn(self.is_multiline)),
|
||||
ro("Line Count", "att_line_count", self.line_count.to_string()),
|
||||
ro("Lock Position", "att_lock_pos", bool_yn(self.lock_position)),
|
||||
ro("Invisible", "att_invisible", bool_yn(self.flags.invisible)),
|
||||
ro("Constant", "att_constant", bool_yn(self.flags.constant)),
|
||||
ro("Verify", "att_verify", bool_yn(self.flags.verify)),
|
||||
ro("Preset", "att_preset", bool_yn(self.flags.preset)),
|
||||
ro(
|
||||
"Annotative",
|
||||
"att_annotative",
|
||||
bool_yn(self.flags.annotative),
|
||||
"Upside down",
|
||||
"att_upside_down",
|
||||
bool_yn(self.text_generation_flags & 0x4 != 0),
|
||||
),
|
||||
ro(
|
||||
"Backward",
|
||||
"att_backward",
|
||||
bool_yn(self.text_generation_flags & 0x2 != 0),
|
||||
),
|
||||
];
|
||||
// Constant attributes can't be edited at insert time — surface that
|
||||
// by marking the Default field read-only.
|
||||
// by marking the Value field read-only.
|
||||
if self.flags.constant {
|
||||
if let Some(p) = props.iter_mut().find(|p| p.field == "att_default") {
|
||||
if let Some(p) = text_props.iter_mut().find(|p| p.field == "att_default") {
|
||||
p.value = PropValue::ReadOnly(self.default_value.clone());
|
||||
}
|
||||
}
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
props,
|
||||
}]
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
props: text_props,
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
props: vec![
|
||||
edit("Position X", "att_ix", self.insertion_point.x),
|
||||
edit("Position Y", "att_iy", self.insertion_point.y),
|
||||
edit("Position Z", "att_iz", self.insertion_point.z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
props: vec![
|
||||
ro("Invisible", "att_invisible", bool_yn(self.flags.invisible)),
|
||||
ro("Constant", "att_constant", bool_yn(self.flags.constant)),
|
||||
ro("Verify", "att_verify", bool_yn(self.flags.verify)),
|
||||
ro("Preset", "att_preset", bool_yn(self.flags.preset)),
|
||||
ro("Lock position", "att_lock_pos", bool_yn(self.lock_position)),
|
||||
Property {
|
||||
label: "Multiple lines".into(),
|
||||
field: "att_mtext_flag",
|
||||
value: PropValue::Choice {
|
||||
selected: mtext_flag_str(self.mtext_flag).to_string(),
|
||||
options: ["SingleLine", "MultiLine", "ConstantMultiLine"]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn apply_geom_prop(&mut self, field: &str, value: &str) {
|
||||
@@ -626,101 +641,108 @@ impl Grippable for AttributeEntity {
|
||||
|
||||
impl PropertyEditable for AttributeEntity {
|
||||
fn geometry_properties(&self, text_style_names: &[String]) -> Vec<PropSection> {
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
props: vec![
|
||||
ro("Tag", "atte_tag", self.tag.clone()),
|
||||
Property {
|
||||
label: "Value".into(),
|
||||
field: "atte_val",
|
||||
value: PropValue::EditText(self.value.clone()),
|
||||
},
|
||||
edit("Insert X", "atte_ix", self.insertion_point.x),
|
||||
edit("Insert Y", "atte_iy", self.insertion_point.y),
|
||||
edit("Insert Z", "atte_iz", self.insertion_point.z),
|
||||
edit("Align X", "atte_ax", self.alignment_point.x),
|
||||
edit("Align Y", "atte_ay", self.alignment_point.y),
|
||||
edit("Align Z", "atte_az", self.alignment_point.z),
|
||||
edit("Height", "atte_h", self.height),
|
||||
edit("Rotation", "atte_rot", self.rotation.to_degrees()),
|
||||
edit("Width Factor", "atte_wf", self.width_factor),
|
||||
edit("Oblique Angle", "atte_ob", self.oblique_angle.to_degrees()),
|
||||
Property {
|
||||
label: "H-Align".into(),
|
||||
field: "atte_halign",
|
||||
value: PropValue::Choice {
|
||||
selected: halign_str(self.horizontal_alignment).to_string(),
|
||||
options: ["Left", "Center", "Right", "Aligned", "Middle", "Fit"]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Text".into(),
|
||||
props: vec![
|
||||
ro("Tag", "atte_tag", self.tag.clone()),
|
||||
ro("Prompt", "atte_prompt", String::new()),
|
||||
Property {
|
||||
label: "Value".into(),
|
||||
field: "atte_val",
|
||||
value: PropValue::EditText(self.value.clone()),
|
||||
},
|
||||
},
|
||||
Property {
|
||||
label: "V-Align".into(),
|
||||
field: "atte_valign",
|
||||
value: PropValue::Choice {
|
||||
selected: valign_str(self.vertical_alignment).to_string(),
|
||||
options: ["Baseline", "Bottom", "Middle", "Top"]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
},
|
||||
},
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
field: "atte_style",
|
||||
value: PropValue::Choice {
|
||||
selected: if self.text_style.trim().is_empty() {
|
||||
"Standard".into()
|
||||
} else {
|
||||
self.text_style.clone()
|
||||
Property {
|
||||
label: "Style".into(),
|
||||
field: "atte_style",
|
||||
value: PropValue::Choice {
|
||||
selected: if self.text_style.trim().is_empty() {
|
||||
"Standard".into()
|
||||
} else {
|
||||
self.text_style.clone()
|
||||
},
|
||||
options: text_style_names.to_vec(),
|
||||
},
|
||||
options: text_style_names.to_vec(),
|
||||
},
|
||||
},
|
||||
ro(
|
||||
"Generation",
|
||||
"atte_gen_flags",
|
||||
format!("{:#06b}", self.text_generation_flags & 0xff),
|
||||
),
|
||||
ro(
|
||||
"Field Length",
|
||||
"atte_field_len",
|
||||
self.field_length.to_string(),
|
||||
),
|
||||
ro(
|
||||
"MText Mode",
|
||||
"atte_mtext_flag",
|
||||
mtext_flag_str(self.mtext_flag),
|
||||
),
|
||||
ro("Multiline", "atte_is_multiline", bool_yn(self.is_multiline)),
|
||||
ro("Line Count", "atte_line_count", self.line_count.to_string()),
|
||||
ro(
|
||||
"Lock Position",
|
||||
"atte_lock_pos",
|
||||
bool_yn(self.lock_position),
|
||||
),
|
||||
ro(
|
||||
"Definition",
|
||||
"atte_attdef",
|
||||
if self.attdef_handle.is_null() {
|
||||
"(none)".into()
|
||||
} else {
|
||||
format!("{:X}", self.attdef_handle.value())
|
||||
Property {
|
||||
label: "Justify".into(),
|
||||
field: "atte_halign",
|
||||
value: PropValue::Choice {
|
||||
selected: halign_str(self.horizontal_alignment).to_string(),
|
||||
options: ["Left", "Center", "Right", "Aligned", "Middle", "Fit"]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
},
|
||||
},
|
||||
),
|
||||
ro("Invisible", "atte_invisible", bool_yn(self.flags.invisible)),
|
||||
ro("Constant", "atte_constant", bool_yn(self.flags.constant)),
|
||||
ro("Verify", "atte_verify", bool_yn(self.flags.verify)),
|
||||
ro("Preset", "atte_preset", bool_yn(self.flags.preset)),
|
||||
ro(
|
||||
"Annotative",
|
||||
"atte_annotative",
|
||||
bool_yn(self.flags.annotative),
|
||||
),
|
||||
],
|
||||
}]
|
||||
Property {
|
||||
label: "V-Align".into(),
|
||||
field: "atte_valign",
|
||||
value: PropValue::Choice {
|
||||
selected: valign_str(self.vertical_alignment).to_string(),
|
||||
options: ["Baseline", "Bottom", "Middle", "Top"]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
},
|
||||
},
|
||||
ro(
|
||||
"Annotative",
|
||||
"atte_annotative",
|
||||
bool_yn(self.flags.annotative),
|
||||
),
|
||||
edit("Height", "atte_h", self.height),
|
||||
edit("Rotation", "atte_rot", self.rotation.to_degrees()),
|
||||
edit("Width factor", "atte_wf", self.width_factor),
|
||||
edit("Obliquing", "atte_ob", self.oblique_angle.to_degrees()),
|
||||
edit("Text alignment X", "atte_ax", self.alignment_point.x),
|
||||
edit("Text alignment Y", "atte_ay", self.alignment_point.y),
|
||||
edit("Text alignment Z", "atte_az", self.alignment_point.z),
|
||||
ro(
|
||||
"Boundary width",
|
||||
"atte_field_len",
|
||||
self.field_length.to_string(),
|
||||
),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Geometry".into(),
|
||||
props: vec![
|
||||
edit("Position X", "atte_ix", self.insertion_point.x),
|
||||
edit("Position Y", "atte_iy", self.insertion_point.y),
|
||||
edit("Position Z", "atte_iz", self.insertion_point.z),
|
||||
],
|
||||
},
|
||||
PropSection {
|
||||
title: "Misc".into(),
|
||||
props: vec![
|
||||
ro(
|
||||
"Upside down",
|
||||
"atte_upside_down",
|
||||
bool_yn(self.text_generation_flags & 0x4 != 0),
|
||||
),
|
||||
ro(
|
||||
"Backward",
|
||||
"atte_backward",
|
||||
bool_yn(self.text_generation_flags & 0x2 != 0),
|
||||
),
|
||||
ro("Invisible", "atte_invisible", bool_yn(self.flags.invisible)),
|
||||
ro(
|
||||
"Multiple lines",
|
||||
"atte_mtext_flag",
|
||||
mtext_flag_str(self.mtext_flag),
|
||||
),
|
||||
ro("Constant", "atte_constant", bool_yn(self.flags.constant)),
|
||||
ro("Verify", "atte_verify", bool_yn(self.flags.verify)),
|
||||
ro("Preset", "atte_preset", bool_yn(self.flags.preset)),
|
||||
ro(
|
||||
"Lock position",
|
||||
"atte_lock_pos",
|
||||
bool_yn(self.lock_position),
|
||||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn apply_geom_prop(&mut self, field: &str, value: &str) {
|
||||
|
||||
Reference in new issue
Block a user