feat(dimstyle): block/linetype Handle cyclers for arrowheads & ext lines
The arrowhead-block (DIMBLK/DIMBLK1/DIMBLK2/DIMLDRBLK) and ext-line linetype (DIMLTYPE/DIMLTEX1/DIMLTEX2) Handle fields are now editable in the Dimension Style manager. Each shows the resolved block-record / linetype name and a Cycle button that advances through the available records (NULL = Default arrowhead / ByBlock linetype). Edits bump geometry so dimensions re-render with the new arrowheads/linetypes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
df44031ae8
commit
1b7edf6cae
4 changed files with 132 additions and 0 deletions
|
|
@ -1071,6 +1071,9 @@ pub enum Message {
|
||||||
// Field edit messages:
|
// Field edit messages:
|
||||||
DsEdit(DsField, String),
|
DsEdit(DsField, String),
|
||||||
DsToggle(DsField),
|
DsToggle(DsField),
|
||||||
|
/// Cycle a block/linetype Handle field on the selected dim style to the
|
||||||
|
/// next available block-record / linetype.
|
||||||
|
DsCycleHandle(&'static str),
|
||||||
// ── Raster Image ──────────────────────────────────────────────────────
|
// ── Raster Image ──────────────────────────────────────────────────────
|
||||||
/// Open file-picker dialog for IMAGE command (async).
|
/// Open file-picker dialog for IMAGE command (async).
|
||||||
ImagePick,
|
ImagePick,
|
||||||
|
|
|
||||||
|
|
@ -6534,6 +6534,53 @@ impl OpenCADStudio {
|
||||||
self.apply_ds_toggle(field);
|
self.apply_ds_toggle(field);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
Message::DsCycleHandle(field) => {
|
||||||
|
let i = self.active_tab;
|
||||||
|
let name = self.dimstyle_selected.clone();
|
||||||
|
let is_lt = matches!(
|
||||||
|
field,
|
||||||
|
"dimltex_handle" | "dimltex1_handle" | "dimltex2_handle"
|
||||||
|
);
|
||||||
|
let doc = &self.tabs[i].scene.document;
|
||||||
|
let mut candidates: Vec<acadrust::types::Handle> =
|
||||||
|
vec![acadrust::types::Handle::NULL];
|
||||||
|
if is_lt {
|
||||||
|
candidates.extend(doc.line_types.iter().map(|lt| lt.handle));
|
||||||
|
} else {
|
||||||
|
candidates.extend(doc.block_records.iter().map(|b| b.handle));
|
||||||
|
}
|
||||||
|
let Some(ds) = doc.dim_styles.get(&name) else {
|
||||||
|
return Task::none();
|
||||||
|
};
|
||||||
|
let cur = match field {
|
||||||
|
"dimblk" => ds.dimblk,
|
||||||
|
"dimblk1" => ds.dimblk1,
|
||||||
|
"dimblk2" => ds.dimblk2,
|
||||||
|
"dimldrblk" => ds.dimldrblk,
|
||||||
|
"dimltex_handle" => ds.dimltex_handle,
|
||||||
|
"dimltex1_handle" => ds.dimltex1_handle,
|
||||||
|
"dimltex2_handle" => ds.dimltex2_handle,
|
||||||
|
_ => return Task::none(),
|
||||||
|
};
|
||||||
|
let idx = candidates.iter().position(|h| *h == cur).unwrap_or(0);
|
||||||
|
let next = candidates[(idx + 1) % candidates.len()];
|
||||||
|
self.push_undo_snapshot(i, "DIMSTYLE EDIT");
|
||||||
|
if let Some(ds) = self.tabs[i].scene.document.dim_styles.get_mut(&name) {
|
||||||
|
match field {
|
||||||
|
"dimblk" => ds.dimblk = next,
|
||||||
|
"dimblk1" => ds.dimblk1 = next,
|
||||||
|
"dimblk2" => ds.dimblk2 = next,
|
||||||
|
"dimldrblk" => ds.dimldrblk = next,
|
||||||
|
"dimltex_handle" => ds.dimltex_handle = next,
|
||||||
|
"dimltex1_handle" => ds.dimltex1_handle = next,
|
||||||
|
"dimltex2_handle" => ds.dimltex2_handle = next,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.tabs[i].dirty = true;
|
||||||
|
self.tabs[i].scene.bump_geometry();
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,50 @@ impl OpenCADStudio {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.name.clone())
|
.map(|s| s.name.clone())
|
||||||
.collect();
|
.collect();
|
||||||
|
let doc = &tab.scene.document;
|
||||||
|
let blk_name = |h: acadrust::types::Handle| -> String {
|
||||||
|
if h.is_null() {
|
||||||
|
"Default".to_string()
|
||||||
|
} else {
|
||||||
|
doc.block_records
|
||||||
|
.iter()
|
||||||
|
.find(|b| b.handle == h)
|
||||||
|
.map(|b| b.name.trim_start_matches('_').to_string())
|
||||||
|
.unwrap_or_else(|| "?".to_string())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let lt_name = |h: acadrust::types::Handle| -> String {
|
||||||
|
if h.is_null() {
|
||||||
|
"ByBlock".to_string()
|
||||||
|
} else {
|
||||||
|
doc.line_types
|
||||||
|
.iter()
|
||||||
|
.find(|lt| lt.handle == h)
|
||||||
|
.map(|lt| lt.name.clone())
|
||||||
|
.unwrap_or_else(|| "?".to_string())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let ds_sel = doc.dim_styles.get(&self.dimstyle_selected);
|
||||||
|
let (
|
||||||
|
dimblk_name,
|
||||||
|
dimblk1_name,
|
||||||
|
dimblk2_name,
|
||||||
|
dimldrblk_name,
|
||||||
|
dimltex_name,
|
||||||
|
dimltex1_name,
|
||||||
|
dimltex2_name,
|
||||||
|
) = match ds_sel {
|
||||||
|
Some(d) => (
|
||||||
|
blk_name(d.dimblk),
|
||||||
|
blk_name(d.dimblk1),
|
||||||
|
blk_name(d.dimblk2),
|
||||||
|
blk_name(d.dimldrblk),
|
||||||
|
lt_name(d.dimltex_handle),
|
||||||
|
lt_name(d.dimltex1_handle),
|
||||||
|
lt_name(d.dimltex2_handle),
|
||||||
|
),
|
||||||
|
None => Default::default(),
|
||||||
|
};
|
||||||
return crate::ui::dimstyle::view_window(
|
return crate::ui::dimstyle::view_window(
|
||||||
styles,
|
styles,
|
||||||
&self.dimstyle_selected,
|
&self.dimstyle_selected,
|
||||||
|
|
@ -308,6 +352,13 @@ impl OpenCADStudio {
|
||||||
dimalttz: &self.ds_dimalttz,
|
dimalttz: &self.ds_dimalttz,
|
||||||
dimtolj: &self.ds_dimtolj,
|
dimtolj: &self.ds_dimtolj,
|
||||||
dimtzin: &self.ds_dimtzin,
|
dimtzin: &self.ds_dimtzin,
|
||||||
|
dimblk_name,
|
||||||
|
dimblk1_name,
|
||||||
|
dimblk2_name,
|
||||||
|
dimldrblk_name,
|
||||||
|
dimltex_name,
|
||||||
|
dimltex1_name,
|
||||||
|
dimltex2_name,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,14 @@ pub struct DimStyleValues<'a> {
|
||||||
pub dimalttz: &'a str,
|
pub dimalttz: &'a str,
|
||||||
pub dimtolj: &'a str,
|
pub dimtolj: &'a str,
|
||||||
pub dimtzin: &'a str,
|
pub dimtzin: &'a str,
|
||||||
|
// Resolved display names for the block/linetype Handle fields.
|
||||||
|
pub dimblk_name: String,
|
||||||
|
pub dimblk1_name: String,
|
||||||
|
pub dimblk2_name: String,
|
||||||
|
pub dimldrblk_name: String,
|
||||||
|
pub dimltex_name: String,
|
||||||
|
pub dimltex1_name: String,
|
||||||
|
pub dimltex2_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||||
|
|
@ -376,6 +384,22 @@ pub fn view_window<'a>(
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Block / linetype Handle cycler: shows the resolved name and a button that
|
||||||
|
// advances to the next available block-record (arrowheads) or linetype.
|
||||||
|
let hrow = move |label: &'static str, name: String, field: &'static str| -> Element<'a, Message> {
|
||||||
|
row![
|
||||||
|
lbl(label),
|
||||||
|
text(name).size(11).width(110),
|
||||||
|
button(text("Cycle").size(10))
|
||||||
|
.on_press(Message::DsCycleHandle(field))
|
||||||
|
.style(btn_s(false))
|
||||||
|
.padding([2, 8]),
|
||||||
|
]
|
||||||
|
.spacing(8)
|
||||||
|
.align_y(iced::Center)
|
||||||
|
.into()
|
||||||
|
};
|
||||||
|
|
||||||
let tab_content: Element<'_, Message> = match tab {
|
let tab_content: Element<'_, Message> = match tab {
|
||||||
0 => column![
|
0 => column![
|
||||||
text("Dimension Line").size(11).color(ACCENT),
|
text("Dimension Line").size(11).color(ACCENT),
|
||||||
|
|
@ -420,11 +444,18 @@ pub fn view_window<'a>(
|
||||||
row![lbl("Ext line weight (DIMLWE)"), mk_field(DsField::Dimlwe, vals.dimlwe)].spacing(8).align_y(iced::Center),
|
row![lbl("Ext line weight (DIMLWE)"), mk_field(DsField::Dimlwe, vals.dimlwe)].spacing(8).align_y(iced::Center),
|
||||||
chk("Fixed-length ext lines (DIMFXLON)", vals.dimfxlon, DsField::Dimfxlon),
|
chk("Fixed-length ext lines (DIMFXLON)", vals.dimfxlon, DsField::Dimfxlon),
|
||||||
row![lbl("Fixed length (DIMFXL)"), mk_field(DsField::Dimfxl, vals.dimfxl)].spacing(8).align_y(iced::Center),
|
row![lbl("Fixed length (DIMFXL)"), mk_field(DsField::Dimfxl, vals.dimfxl)].spacing(8).align_y(iced::Center),
|
||||||
|
hrow("Dim line linetype (DIMLTYPE)", vals.dimltex_name.clone(), "dimltex_handle"),
|
||||||
|
hrow("Ext line 1 linetype (DIMLTEX1)", vals.dimltex1_name.clone(), "dimltex1_handle"),
|
||||||
|
hrow("Ext line 2 linetype (DIMLTEX2)", vals.dimltex2_name.clone(), "dimltex2_handle"),
|
||||||
]
|
]
|
||||||
.spacing(7)
|
.spacing(7)
|
||||||
.into(),
|
.into(),
|
||||||
1 => column![
|
1 => column![
|
||||||
text("Arrows").size(11).color(ACCENT),
|
text("Arrows").size(11).color(ACCENT),
|
||||||
|
hrow("Arrowhead (DIMBLK)", vals.dimblk_name.clone(), "dimblk"),
|
||||||
|
hrow("1st arrowhead (DIMBLK1)", vals.dimblk1_name.clone(), "dimblk1"),
|
||||||
|
hrow("2nd arrowhead (DIMBLK2)", vals.dimblk2_name.clone(), "dimblk2"),
|
||||||
|
hrow("Leader arrowhead (DIMLDRBLK)", vals.dimldrblk_name.clone(), "dimldrblk"),
|
||||||
row![
|
row![
|
||||||
lbl("Arrow size (DIMASZ)"),
|
lbl("Arrow size (DIMASZ)"),
|
||||||
mk_field(DsField::Dimasz, vals.dimasz)
|
mk_field(DsField::Dimasz, vals.dimasz)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue