feat(styles): complete MLeader field coverage + Dimension DIMUNIT

MLeader Style editor now exposes every MultiLeaderStyle field: line
weight, line type / arrowhead block / text style / block-content blocks
(handle dropdowns from the document's tables), the four text attachments
+ attachment direction, the full block-content group (color, connection,
rotation, X/Y/Z scale, enable scale/rotation), leader & multileader draw
order, align space, and description.

Dimension Style editor adds the last uncovered DIMUNIT field.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-03 21:04:22 +03:00
1 parent a584e772ba
commit 6ae24cceee
5 files changed
+390 -17

No files matched your search

+25
View File
@@ -309,6 +309,14 @@ pub(super) struct OpenCADStudio {
mls_default_text: String,
mls_line_color: String,
mls_text_color: String,
mls_description: String,
mls_line_weight: String,
mls_align_space: String,
mls_block_color: String,
mls_block_rotation: String,
mls_block_scale_x: String,
mls_block_scale_y: String,
mls_block_scale_z: String,
// ── TableStyle Dialog ─────────────────────────────────────────────────
tablestyle_selected: String,
@@ -448,6 +456,7 @@ pub(super) struct OpenCADStudio {
ds_dimfrac: String,
ds_dimaunit: String,
ds_dimadec: String,
ds_dimunit: String,
ds_dimazin: String,
// Alternate units
ds_dimalt: bool,
@@ -533,6 +542,7 @@ pub enum DsField {
Dimfrac,
Dimaunit,
Dimadec,
Dimunit,
Dimazin,
Dimalt,
Dimaltf,
@@ -1058,6 +1068,12 @@ pub enum Message {
field: &'static str,
value: String,
},
/// Set an Option<Handle> field (linetype / arrowhead / text style / block)
/// from a dropdown of record names ("None" clears it).
MLeaderStyleSetHandle {
field: &'static str,
value: String,
},
MLeaderStyleApply,
// ── DimStyle Dialog ───────────────────────────────────────────────────
DimStyleDialogOpen,
@@ -1251,6 +1267,14 @@ impl OpenCADStudio {
mls_default_text: String::new(),
mls_line_color: String::new(),
mls_text_color: String::new(),
mls_description: String::new(),
mls_line_weight: String::new(),
mls_align_space: String::new(),
mls_block_color: String::new(),
mls_block_rotation: String::new(),
mls_block_scale_x: String::new(),
mls_block_scale_y: String::new(),
mls_block_scale_z: String::new(),
// DimStyle dialog
dimstyle_selected: "Standard".to_string(),
dimstyle_tab: 0,
@@ -1311,6 +1335,7 @@ impl OpenCADStudio {
ds_dimfrac: "0".to_string(),
ds_dimaunit: "0".to_string(),
ds_dimadec: "0".to_string(),
ds_dimunit: "2".to_string(),
ds_dimazin: "0".to_string(),
ds_dimalt: false,
ds_dimaltf: "25.4".to_string(),
+149 -1
View File
@@ -6277,6 +6277,14 @@ impl OpenCADStudio {
"default_text" => self.mls_default_text = value,
"line_color" => self.mls_line_color = value,
"text_color" => self.mls_text_color = value,
"description" => self.mls_description = value,
"line_weight" => self.mls_line_weight = value,
"align_space" => self.mls_align_space = value,
"block_color" => self.mls_block_color = value,
"block_rotation" => self.mls_block_rotation = value,
"block_scale_x" => self.mls_block_scale_x = value,
"block_scale_y" => self.mls_block_scale_y = value,
"block_scale_z" => self.mls_block_scale_z = value,
_ => {}
}
Task::none()
@@ -6290,6 +6298,10 @@ impl OpenCADStudio {
"text_frame" => s.text_frame = !s.text_frame,
"text_always_left" => s.text_always_left = !s.text_always_left,
"annotative" => s.is_annotative = !s.is_annotative,
"enable_block_scale" => s.enable_block_scale = !s.enable_block_scale,
"enable_block_rotation" => {
s.enable_block_rotation = !s.enable_block_rotation
}
_ => {}
}
self.push_undo_snapshot(i, "MLEADERSTYLE EDIT");
@@ -6300,8 +6312,32 @@ impl OpenCADStudio {
}
Message::MLeaderStyleSetEnum { field, value } => {
use acadrust::objects::{
LeaderContentType, MultiLeaderPathType, TextAlignmentType, TextAngleType,
BlockContentConnectionType, LeaderContentType, LeaderDrawOrderType,
MultiLeaderDrawOrderType, MultiLeaderPathType, TextAlignmentType,
TextAngleType, TextAttachmentDirectionType, TextAttachmentType,
};
// Parse a TextAttachmentType from its debug name.
fn parse_att(v: &str) -> TextAttachmentType {
match v {
"TopOfTopLine" => TextAttachmentType::TopOfTopLine,
"MiddleOfText" => TextAttachmentType::MiddleOfText,
"MiddleOfBottomLine" => TextAttachmentType::MiddleOfBottomLine,
"BottomOfBottomLine" => TextAttachmentType::BottomOfBottomLine,
"BottomLine" => TextAttachmentType::BottomLine,
"BottomOfTopLineUnderlineBottomLine" => {
TextAttachmentType::BottomOfTopLineUnderlineBottomLine
}
"BottomOfTopLineUnderlineTopLine" => {
TextAttachmentType::BottomOfTopLineUnderlineTopLine
}
"BottomOfTopLineUnderlineAll" => {
TextAttachmentType::BottomOfTopLineUnderlineAll
}
"CenterOfText" => TextAttachmentType::CenterOfText,
"CenterOfTextOverline" => TextAttachmentType::CenterOfTextOverline,
_ => TextAttachmentType::MiddleOfTopLine,
}
}
let i = self.active_tab;
if let Some(s) = self.mleaderstyle_mut(i) {
match field {
@@ -6336,6 +6372,73 @@ impl OpenCADStudio {
_ => TextAlignmentType::Left,
};
}
"text_left_attachment" => s.text_left_attachment = parse_att(&value),
"text_right_attachment" => s.text_right_attachment = parse_att(&value),
"text_top_attachment" => s.text_top_attachment = parse_att(&value),
"text_bottom_attachment" => s.text_bottom_attachment = parse_att(&value),
"text_attachment_direction" => {
s.text_attachment_direction = match value.as_str() {
"Vertical" => TextAttachmentDirectionType::Vertical,
_ => TextAttachmentDirectionType::Horizontal,
};
}
"block_content_connection" => {
s.block_content_connection = match value.as_str() {
"BasePoint" => BlockContentConnectionType::BasePoint,
_ => BlockContentConnectionType::BlockExtents,
};
}
"leader_draw_order" => {
s.leader_draw_order = match value.as_str() {
"LeaderTailFirst" => LeaderDrawOrderType::LeaderTailFirst,
_ => LeaderDrawOrderType::LeaderHeadFirst,
};
}
"multileader_draw_order" => {
s.multileader_draw_order = match value.as_str() {
"LeaderFirst" => MultiLeaderDrawOrderType::LeaderFirst,
_ => MultiLeaderDrawOrderType::ContentFirst,
};
}
_ => {}
}
self.push_undo_snapshot(i, "MLEADERSTYLE EDIT");
self.tabs[i].dirty = true;
self.tabs[i].scene.bump_geometry();
}
Task::none()
}
Message::MLeaderStyleSetHandle { field, value } => {
let i = self.active_tab;
let doc = &self.tabs[i].scene.document;
let handle: Option<acadrust::types::Handle> = if value == "None" {
None
} else {
match field {
"line_type_handle" => doc
.line_types
.iter()
.find(|lt| lt.name == value)
.map(|lt| lt.handle),
"text_style_handle" => doc
.text_styles
.iter()
.find(|t| t.name == value)
.map(|t| t.handle),
"arrowhead_handle" | "block_content_handle" => doc
.block_records
.iter()
.find(|b| b.name == value)
.map(|b| b.handle),
_ => None,
}
};
if let Some(s) = self.mleaderstyle_mut(i) {
match field {
"line_type_handle" => s.line_type_handle = handle,
"text_style_handle" => s.text_style_handle = handle,
"arrowhead_handle" => s.arrowhead_handle = handle,
"block_content_handle" => s.block_content_handle = handle,
_ => {}
}
self.push_undo_snapshot(i, "MLEADERSTYLE EDIT");
@@ -6373,6 +6476,14 @@ impl OpenCADStudio {
self.mls_line_color.parse::<i16>().ok(),
self.mls_text_color.parse::<i16>().ok(),
);
let desc = self.mls_description.clone();
let lw = self.mls_line_weight.parse::<i16>().ok();
let align = self.mls_align_space.parse::<f64>().ok();
let bclr = self.mls_block_color.parse::<i16>().ok();
let brot = self.mls_block_rotation.parse::<f64>().ok();
let bsx = self.mls_block_scale_x.parse::<f64>().ok();
let bsy = self.mls_block_scale_y.parse::<f64>().ok();
let bsz = self.mls_block_scale_z.parse::<f64>().ok();
if let Some(s) = self.mleaderstyle_mut(i) {
if let Some(v) = ld {
s.landing_distance = v;
@@ -6408,6 +6519,28 @@ impl OpenCADStudio {
if let Some(v) = tc {
s.text_color = acadrust::types::Color::from_index(v);
}
s.description = desc;
if let Some(v) = lw {
s.line_weight = acadrust::types::LineWeight::from_value(v);
}
if let Some(v) = align {
s.align_space = v;
}
if let Some(v) = bclr {
s.block_content_color = acadrust::types::Color::from_index(v);
}
if let Some(v) = brot {
s.block_content_rotation = v;
}
if let Some(v) = bsx {
s.block_content_scale_x = v;
}
if let Some(v) = bsy {
s.block_content_scale_y = v;
}
if let Some(v) = bsz {
s.block_content_scale_z = v;
}
self.push_undo_snapshot(i, "MLEADERSTYLE EDIT");
self.tabs[i].dirty = true;
self.tabs[i].scene.bump_geometry();
@@ -7067,6 +7200,18 @@ impl OpenCADStudio {
.index()
.map(|c| c.to_string())
.unwrap_or_default();
self.mls_description = s.description.clone();
self.mls_line_weight = s.line_weight.value().to_string();
self.mls_align_space = format!("{:.4}", s.align_space);
self.mls_block_color = s
.block_content_color
.index()
.map(|c| c.to_string())
.unwrap_or_default();
self.mls_block_rotation = format!("{:.4}", s.block_content_rotation);
self.mls_block_scale_x = format!("{:.4}", s.block_content_scale_x);
self.mls_block_scale_y = format!("{:.4}", s.block_content_scale_y);
self.mls_block_scale_z = format!("{:.4}", s.block_content_scale_z);
}
/// Populate all edit buffers from the currently selected dim style.
@@ -7132,6 +7277,7 @@ impl OpenCADStudio {
self.ds_dimfrac = format!("{}", ds.dimfrac);
self.ds_dimaunit = format!("{}", ds.dimaunit);
self.ds_dimadec = format!("{}", ds.dimadec);
self.ds_dimunit = format!("{}", ds.dimunit);
self.ds_dimazin = format!("{}", ds.dimazin);
self.ds_dimalt = ds.dimalt;
self.ds_dimaltf = format!("{}", ds.dimaltf);
@@ -7216,6 +7362,7 @@ impl OpenCADStudio {
set_i16!(dimfrac, self.ds_dimfrac);
set_i16!(dimaunit, self.ds_dimaunit);
set_i16!(dimadec, self.ds_dimadec);
set_i16!(dimunit, self.ds_dimunit);
set_i16!(dimazin, self.ds_dimazin);
set_f64!(dimaltf, self.ds_dimaltf);
set_i16!(dimaltd, self.ds_dimaltd);
@@ -7288,6 +7435,7 @@ impl OpenCADStudio {
Dimfrac => self.ds_dimfrac = val,
Dimaunit => self.ds_dimaunit = val,
Dimadec => self.ds_dimadec = val,
Dimunit => self.ds_dimunit = val,
Dimazin => self.ds_dimazin = val,
Dimaltf => self.ds_dimaltf = val,
Dimaltd => self.ds_dimaltd = val,
+66
View File
@@ -186,6 +186,56 @@ impl OpenCADStudio {
None
}
});
let doc = &tab.scene.document;
let mut block_opts: Vec<String> = vec!["None".to_string()];
block_opts.extend(doc.block_records.iter().map(|b| b.name.clone()));
let mut lt_opts: Vec<String> = vec!["None".to_string()];
lt_opts.extend(doc.line_types.iter().map(|lt| lt.name.clone()));
let mut textstyle_opts: Vec<String> = vec!["None".to_string()];
textstyle_opts.extend(doc.text_styles.iter().map(|t| t.name.clone()));
let opt_block = |h: Option<acadrust::types::Handle>| -> String {
match h {
Some(h) => doc
.block_records
.iter()
.find(|b| b.handle == h)
.map(|b| b.name.clone())
.unwrap_or_else(|| "None".to_string()),
None => "None".to_string(),
}
};
let opt_lt = |h: Option<acadrust::types::Handle>| -> String {
match h {
Some(h) => doc
.line_types
.iter()
.find(|lt| lt.handle == h)
.map(|lt| lt.name.clone())
.unwrap_or_else(|| "None".to_string()),
None => "None".to_string(),
}
};
let opt_ts = |h: Option<acadrust::types::Handle>| -> String {
match h {
Some(h) => doc
.text_styles
.iter()
.find(|t| t.handle == h)
.map(|t| t.name.clone())
.unwrap_or_else(|| "None".to_string()),
None => "None".to_string(),
}
};
let (line_type_name, arrowhead_name, text_style_name, block_content_name) =
match selected_style {
Some(s) => (
opt_lt(s.line_type_handle),
opt_block(s.arrowhead_handle),
opt_ts(s.text_style_handle),
opt_block(s.block_content_handle),
),
None => Default::default(),
};
return crate::ui::mleaderstyle::view_window(crate::ui::mleaderstyle::MLeaderStyleView {
styles,
selected: &self.mleaderstyle_selected,
@@ -203,6 +253,21 @@ impl OpenCADStudio {
default_text: &self.mls_default_text,
line_color: &self.mls_line_color,
text_color: &self.mls_text_color,
description: &self.mls_description,
line_weight: &self.mls_line_weight,
align_space: &self.mls_align_space,
block_color: &self.mls_block_color,
block_rotation: &self.mls_block_rotation,
block_scale_x: &self.mls_block_scale_x,
block_scale_y: &self.mls_block_scale_y,
block_scale_z: &self.mls_block_scale_z,
block_opts,
lt_opts,
textstyle_opts,
line_type_name,
arrowhead_name,
text_style_name,
block_content_name,
});
}
if Some(window_id) == self.layout_manager_window {
@@ -346,6 +411,7 @@ impl OpenCADStudio {
dimfrac: &self.ds_dimfrac,
dimaunit: &self.ds_dimaunit,
dimadec: &self.ds_dimadec,
dimunit: &self.ds_dimunit,
dimazin: &self.ds_dimazin,
dimalt: self.ds_dimalt,
dimaltf: &self.ds_dimaltf,