forked from 1b-agent/opencadstudio-upstream
feat(styles): overhaul style managers
Unify editor layouts, live previews, comparisons, read-only behavior, and localized controls across all named style managers. Refs #629
This commit is contained in:
1 parent
d06a1022f2
commit
25515fa33c
27 files changed
+5506
-1662
No files matched your search
+60
-1
@@ -670,9 +670,18 @@ pub(super) struct OpenCADStudio {
|
||||
|
||||
// ── MLineStyle Dialog ─────────────────────────────────────────────────
|
||||
mlstyle_selected: String,
|
||||
mlstyle_tab: u8,
|
||||
mlstyle_compare: String,
|
||||
mln_description: String,
|
||||
mln_start_angle: String,
|
||||
mln_end_angle: String,
|
||||
mln_fill_color: String,
|
||||
mln_elements: Vec<[String; 3]>,
|
||||
|
||||
// ── MLeaderStyle Dialog ───────────────────────────────────────────────
|
||||
mleaderstyle_selected: String,
|
||||
mleaderstyle_tab: u8,
|
||||
mleaderstyle_compare: String,
|
||||
/// Colour field whose expanded palette is open (line/text/block).
|
||||
mls_color_open: Option<&'static str>,
|
||||
mls_landing_distance: String,
|
||||
@@ -697,6 +706,8 @@ pub(super) struct OpenCADStudio {
|
||||
|
||||
// ── TableStyle Dialog ─────────────────────────────────────────────────
|
||||
tablestyle_selected: String,
|
||||
tablestyle_tab: u8,
|
||||
tablestyle_compare: String,
|
||||
/// Edit buffers for the table style's general margins.
|
||||
ts_hmargin: String,
|
||||
ts_vmargin: String,
|
||||
@@ -732,6 +743,8 @@ pub(super) struct OpenCADStudio {
|
||||
|
||||
// ── TextStyle Font Browser ────────────────────────────────────────────
|
||||
textstyle_selected: String,
|
||||
textstyle_tab: u8,
|
||||
textstyle_compare: String,
|
||||
/// Edit buffer for font file name.
|
||||
textstyle_font: String,
|
||||
/// Edit buffer for width factor.
|
||||
@@ -868,8 +881,10 @@ pub(super) struct OpenCADStudio {
|
||||
dimstyle_selected: String,
|
||||
/// Which colour field currently has its expanded palette open (if any).
|
||||
ds_color_open: Option<DsField>,
|
||||
/// Active tab: 0=Lines, 1=Arrows, 2=Text, 3=Scale/Units, 4=Tolerances.
|
||||
/// Active property group in the dimension style manager.
|
||||
dimstyle_tab: u8,
|
||||
/// Style used by the manager's comparison summary.
|
||||
dimstyle_compare: String,
|
||||
// Edit buffers (strings while typing):
|
||||
ds_dimdle: String,
|
||||
ds_dimdli: String,
|
||||
@@ -2438,6 +2453,8 @@ pub enum Message {
|
||||
#[allow(dead_code)]
|
||||
TextStyleDialogClose,
|
||||
TextStyleDialogSelect(String),
|
||||
TextStyleDialogTab(u8),
|
||||
TextStyleDialogCompare(String),
|
||||
TextStyleDialogSetCurrent,
|
||||
TextStyleDialogNew,
|
||||
TextStyleDialogCopy,
|
||||
@@ -2465,6 +2482,8 @@ pub enum Message {
|
||||
#[allow(dead_code)]
|
||||
TableStyleDialogClose,
|
||||
TableStyleDialogSelect(String),
|
||||
TableStyleDialogTab(u8),
|
||||
TableStyleDialogCompare(String),
|
||||
TableStyleDialogNew,
|
||||
TableStyleDialogCopy,
|
||||
TableStyleDialogDelete,
|
||||
@@ -2523,16 +2542,32 @@ pub enum Message {
|
||||
#[allow(dead_code)]
|
||||
MlStyleDialogClose,
|
||||
MlStyleDialogSelect(String),
|
||||
MlStyleDialogTab(u8),
|
||||
MlStyleDialogCompare(String),
|
||||
MlStyleDialogSetCurrent,
|
||||
MlStyleApply,
|
||||
MlStyleDialogNew,
|
||||
MlStyleDialogCopy,
|
||||
MlStyleDialogDelete,
|
||||
MlStyleEdit {
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
MlStyleToggle(&'static str),
|
||||
MlStyleElementEdit {
|
||||
index: usize,
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
MlStyleElementAdd,
|
||||
MlStyleElementDelete(usize),
|
||||
// ── MLeaderStyle Dialog ───────────────────────────────────────────────
|
||||
MLeaderStyleDialogOpen,
|
||||
#[allow(dead_code)]
|
||||
MLeaderStyleDialogClose,
|
||||
MLeaderStyleDialogSelect(String),
|
||||
MLeaderStyleDialogTab(u8),
|
||||
MLeaderStyleDialogCompare(String),
|
||||
MLeaderStyleDialogSetCurrent,
|
||||
MLeaderStyleDialogNew,
|
||||
MLeaderStyleDialogCopy,
|
||||
@@ -2565,6 +2600,8 @@ pub enum Message {
|
||||
DimStyleDialogSelect(String),
|
||||
/// Switch the active tab.
|
||||
DimStyleDialogTab(u8),
|
||||
/// Change the style used by the comparison summary.
|
||||
DimStyleDialogCompare(String),
|
||||
/// Create a new empty style (prompts via command line).
|
||||
DimStyleDialogNew,
|
||||
DimStyleDialogCopy,
|
||||
@@ -2575,6 +2612,14 @@ pub enum Message {
|
||||
// Field edit messages:
|
||||
DsEdit(DsField, String),
|
||||
DsToggle(DsField),
|
||||
/// Select the mutually-exclusive tolerance presentation.
|
||||
DsToleranceMode(String),
|
||||
/// Change the feet/inches mode in a zero-suppression bit field.
|
||||
DsZeroBase(DsField, i16),
|
||||
/// Toggle leading/trailing suppression in a zero-suppression bit field.
|
||||
DsZeroFlag(DsField, i16),
|
||||
/// Select no center mark, a mark, or centerlines.
|
||||
DsCenterMarkMode(String),
|
||||
/// Toggle the expanded colour palette for a DimStyle colour field.
|
||||
DsColorMore(DsField),
|
||||
/// Open the `iced_aw` colour picker for a field and its current colour.
|
||||
@@ -2887,6 +2932,8 @@ impl OpenCADStudio {
|
||||
style_rename_buf: String::new(),
|
||||
style_stage: None,
|
||||
textstyle_selected: "Standard".to_string(),
|
||||
textstyle_tab: 0,
|
||||
textstyle_compare: String::new(),
|
||||
textstyle_font: String::new(),
|
||||
textstyle_width: "1.0".to_string(),
|
||||
textstyle_oblique: "0.0".to_string(),
|
||||
@@ -2895,6 +2942,8 @@ impl OpenCADStudio {
|
||||
textstyle_ttf: String::new(),
|
||||
// TableStyle dialog
|
||||
tablestyle_selected: "Standard".to_string(),
|
||||
tablestyle_tab: 0,
|
||||
tablestyle_compare: String::new(),
|
||||
ts_hmargin: "1.5".to_string(),
|
||||
ts_vmargin: "1.5".to_string(),
|
||||
ts_description: String::new(),
|
||||
@@ -2911,8 +2960,17 @@ impl OpenCADStudio {
|
||||
ts_border_spacing: Default::default(),
|
||||
// MLineStyle dialog
|
||||
mlstyle_selected: "Standard".to_string(),
|
||||
mlstyle_tab: 0,
|
||||
mlstyle_compare: String::new(),
|
||||
mln_description: String::new(),
|
||||
mln_start_angle: "90".to_string(),
|
||||
mln_end_angle: "90".to_string(),
|
||||
mln_fill_color: "256".to_string(),
|
||||
mln_elements: Vec::new(),
|
||||
// MLeaderStyle dialog
|
||||
mleaderstyle_selected: "Standard".to_string(),
|
||||
mleaderstyle_tab: 0,
|
||||
mleaderstyle_compare: String::new(),
|
||||
mls_color_open: None,
|
||||
mls_landing_distance: String::new(),
|
||||
mls_landing_gap: String::new(),
|
||||
@@ -2937,6 +2995,7 @@ impl OpenCADStudio {
|
||||
dimstyle_selected: "Standard".to_string(),
|
||||
ds_color_open: None,
|
||||
dimstyle_tab: 0,
|
||||
dimstyle_compare: String::new(),
|
||||
ds_dimdle: "0".to_string(),
|
||||
ds_dimdli: "3.75".to_string(),
|
||||
ds_dimgap: "0.625".to_string(),
|
||||
|
||||
+29
-1
@@ -301,7 +301,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
fn style_in_use(&self, kind: StyleKind, name: &str) -> bool {
|
||||
pub(super) fn style_in_use(&self, kind: StyleKind, name: &str) -> bool {
|
||||
use acadrust::entities::EntityType;
|
||||
|
||||
let i = self.active_tab;
|
||||
@@ -613,6 +613,20 @@ impl OpenCADStudio {
|
||||
|
||||
pub(super) fn style_delete(&mut self, kind: StyleKind) {
|
||||
let name = self.style_selected(kind);
|
||||
if matches!(kind, StyleKind::Dim)
|
||||
&& self.tabs[self.active_tab]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get(&name)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
})
|
||||
{
|
||||
self.command_line
|
||||
.push_error(crate::t!("Referenced styles are read only.").as_ref());
|
||||
return;
|
||||
}
|
||||
if name.eq_ignore_ascii_case("Standard") {
|
||||
self.command_line
|
||||
.push_error(crate::t!("Cannot delete the Standard style.").as_ref());
|
||||
@@ -657,6 +671,20 @@ impl OpenCADStudio {
|
||||
if new.is_empty() || new.eq_ignore_ascii_case(&old) {
|
||||
return;
|
||||
}
|
||||
if matches!(kind, StyleKind::Dim)
|
||||
&& self.tabs[self.active_tab]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get(&old)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
})
|
||||
{
|
||||
self.command_line
|
||||
.push_error(crate::t!("Referenced styles are read only.").as_ref());
|
||||
return;
|
||||
}
|
||||
if old.eq_ignore_ascii_case("Standard") {
|
||||
self.command_line
|
||||
.push_error(crate::t!("Cannot rename the Standard style.").as_ref());
|
||||
|
||||
+208
-8
@@ -5408,11 +5408,25 @@ impl OpenCADStudio {
|
||||
self.load_textstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::TextStyleDialogTab(tab) => {
|
||||
self.textstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::TextStyleDialogCompare(name) => {
|
||||
self.textstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::TextStyleDialogSetCurrent => {
|
||||
// Staged: persists on Apply.
|
||||
let i = self.active_tab;
|
||||
let name = self.textstyle_selected.clone();
|
||||
if self.tabs[i].scene.document.text_styles.get(&name).is_some() {
|
||||
if self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.text_styles
|
||||
.get(&name)
|
||||
.is_some_and(|style| !style.xref_dependent)
|
||||
{
|
||||
self.tabs[i].scene.document.header.current_text_style_name = name.clone();
|
||||
self.sync_ribbon_styles();
|
||||
self.command_line
|
||||
@@ -5468,9 +5482,13 @@ impl OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let name = self.textstyle_selected.clone();
|
||||
if let Some(s) = self.tabs[i].scene.document.text_styles.get_mut(&name) {
|
||||
if s.xref_dependent {
|
||||
return Task::none();
|
||||
}
|
||||
match field {
|
||||
"backward" => s.flags.backward = !s.flags.backward,
|
||||
"upside_down" => s.flags.upside_down = !s.flags.upside_down,
|
||||
"vertical" => s.is_vertical = !s.is_vertical,
|
||||
"annotative" => s.annotative = !s.annotative,
|
||||
_ => {}
|
||||
}
|
||||
@@ -5481,8 +5499,17 @@ impl OpenCADStudio {
|
||||
Message::TextStyleFontPick(font_file) => {
|
||||
// Staged: update the buffer + live style; persist on Apply.
|
||||
let i = self.active_tab;
|
||||
self.textstyle_font = font_file.clone();
|
||||
let name = self.textstyle_selected.clone();
|
||||
if self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.text_styles
|
||||
.get(&name)
|
||||
.is_some_and(|style| style.xref_dependent)
|
||||
{
|
||||
return Task::none();
|
||||
}
|
||||
self.textstyle_font = font_file.clone();
|
||||
if let Some(s) = self.tabs[i].scene.document.text_styles.get_mut(&name) {
|
||||
s.font_file = font_file;
|
||||
}
|
||||
@@ -5516,12 +5543,23 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
Message::TableStyleDialogSelect(name) => {
|
||||
for row in 0..3 {
|
||||
let _ = self.on_table_style_cell_apply(row);
|
||||
}
|
||||
self.stage_tablestyle_bufs();
|
||||
self.tablestyle_selected = name;
|
||||
let i = self.active_tab;
|
||||
self.load_tablestyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::TableStyleDialogTab(tab) => {
|
||||
self.tablestyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::TableStyleDialogCompare(name) => {
|
||||
self.tablestyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleEdit { field, value } => {
|
||||
match field {
|
||||
@@ -5534,6 +5572,9 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
Message::TableStyleApply => {
|
||||
for row in 0..3 {
|
||||
let _ = self.on_table_style_cell_apply(row);
|
||||
}
|
||||
self.stage_tablestyle_bufs();
|
||||
self.style_stage_commit();
|
||||
Task::none()
|
||||
@@ -5728,7 +5769,18 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogSelect(name) => {
|
||||
self.stage_mlstyle_bufs();
|
||||
self.mlstyle_selected = name;
|
||||
let i = self.active_tab;
|
||||
self.load_mlstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogTab(tab) => {
|
||||
self.mlstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogCompare(name) => {
|
||||
self.mlstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogSetCurrent => {
|
||||
@@ -5749,13 +5801,8 @@ impl OpenCADStudio {
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
// Placeholder so the Multiline manager has the same Set Current +
|
||||
// Apply pair as every other style manager. The editor is currently
|
||||
// read-only, so there is nothing to apply yet — wire this up when
|
||||
// editable MLineStyle properties land.
|
||||
Message::MlStyleApply => {
|
||||
// Multiline styles have no editable properties yet; Apply still
|
||||
// commits any staged structural / current-style changes.
|
||||
self.stage_mlstyle_bufs();
|
||||
self.style_stage_commit();
|
||||
Task::none()
|
||||
}
|
||||
@@ -5771,6 +5818,66 @@ impl OpenCADStudio {
|
||||
self.style_delete(crate::app::StyleKind::MLine);
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleEdit { field, value } => {
|
||||
match field {
|
||||
"description" => self.mln_description = value,
|
||||
"start_angle" => self.mln_start_angle = value,
|
||||
"end_angle" => self.mln_end_angle = value,
|
||||
"fill_color" => self.mln_fill_color = value,
|
||||
_ => {}
|
||||
}
|
||||
self.stage_mlstyle_bufs();
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleToggle(field) => {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.mlstyle_mut(i) {
|
||||
match field {
|
||||
"fill" => style.flags.fill_on = !style.flags.fill_on,
|
||||
"joints" => style.flags.display_joints = !style.flags.display_joints,
|
||||
"start_square" => style.flags.start_square_cap = !style.flags.start_square_cap,
|
||||
"start_inner" => style.flags.start_inner_arcs_cap = !style.flags.start_inner_arcs_cap,
|
||||
"start_round" => style.flags.start_round_cap = !style.flags.start_round_cap,
|
||||
"end_square" => style.flags.end_square_cap = !style.flags.end_square_cap,
|
||||
"end_inner" => style.flags.end_inner_arcs_cap = !style.flags.end_inner_arcs_cap,
|
||||
"end_round" => style.flags.end_round_cap = !style.flags.end_round_cap,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleElementEdit { index, field, value } => {
|
||||
if let Some(element) = self.mln_elements.get_mut(index) {
|
||||
match field {
|
||||
"offset" => element[0] = value,
|
||||
"color" => element[1] = value,
|
||||
"linetype" => element[2] = value,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.stage_mlstyle_bufs();
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleElementAdd => {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.mlstyle_mut(i) {
|
||||
style
|
||||
.elements
|
||||
.push(acadrust::objects::MLineStyleElement::default());
|
||||
}
|
||||
self.load_mlstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleElementDelete(index) => {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.mlstyle_mut(i) {
|
||||
if style.elements.len() > 1 && index < style.elements.len() {
|
||||
style.elements.remove(index);
|
||||
}
|
||||
}
|
||||
self.load_mlstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// ── MLeaderStyle Dialog ───────────────────────────────────────────
|
||||
Message::MLeaderStyleDialogOpen => self.on_mleader_style_dialog_open(),
|
||||
@@ -5785,6 +5892,14 @@ impl OpenCADStudio {
|
||||
self.load_mleaderstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleDialogTab(tab) => {
|
||||
self.mleaderstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleDialogCompare(name) => {
|
||||
self.mleaderstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleDialogSetCurrent => self.on_mleader_style_dialog_set_current(),
|
||||
Message::MLeaderStyleDialogNew => {
|
||||
self.style_new(crate::app::StyleKind::MLeader);
|
||||
@@ -5864,6 +5979,10 @@ impl OpenCADStudio {
|
||||
self.dimstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::DimStyleDialogCompare(name) => {
|
||||
self.dimstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::DimStyleDialogNew => {
|
||||
self.style_new(crate::app::StyleKind::Dim);
|
||||
Task::none()
|
||||
@@ -5875,6 +5994,19 @@ impl OpenCADStudio {
|
||||
Message::DimStyleDialogSetCurrent => {
|
||||
// Staged: persists on Apply.
|
||||
let i = self.active_tab;
|
||||
let read_only = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get(&self.dimstyle_selected)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference
|
||||
|| style.xref_dependent
|
||||
|| !style.xref_handle.is_null()
|
||||
});
|
||||
if read_only {
|
||||
return Task::none();
|
||||
}
|
||||
self.tabs[i].scene.document.header.current_dimstyle_name =
|
||||
self.dimstyle_selected.clone();
|
||||
self.sync_ribbon_styles();
|
||||
@@ -5894,7 +6026,75 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
Message::DsToggle(field) => {
|
||||
let separate_arrows = field == crate::app::DsField::Dimsah;
|
||||
self.apply_ds_toggle(field);
|
||||
if separate_arrows && self.ds_dimsah {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get_mut(&self.dimstyle_selected)
|
||||
{
|
||||
if style.dimblk1.is_null() {
|
||||
style.dimblk1 = style.dimblk;
|
||||
}
|
||||
if style.dimblk2.is_null() {
|
||||
style.dimblk2 = style.dimblk1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::DsToleranceMode(mode) => {
|
||||
self.ds_dimlim = mode == "limits";
|
||||
self.ds_dimtol = matches!(mode.as_str(), "symmetrical" | "deviation");
|
||||
if mode == "symmetrical" {
|
||||
self.ds_dimtm = self.ds_dimtp.clone();
|
||||
}
|
||||
let gap = self.ds_dimgap.trim().parse::<f64>().unwrap_or(0.625).abs();
|
||||
self.ds_dimgap = if mode == "basic" {
|
||||
format!("-{}", gap.max(f64::EPSILON))
|
||||
} else {
|
||||
format!("{}", gap)
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::DsZeroBase(field, base) => {
|
||||
let current = match &field {
|
||||
crate::app::DsField::Dimzin => &self.ds_dimzin,
|
||||
crate::app::DsField::Dimaltz => &self.ds_dimaltz,
|
||||
crate::app::DsField::Dimalttz => &self.ds_dimalttz,
|
||||
crate::app::DsField::Dimtzin => &self.ds_dimtzin,
|
||||
_ => return Task::none(),
|
||||
}
|
||||
.trim()
|
||||
.parse::<i16>()
|
||||
.unwrap_or(0);
|
||||
self.apply_ds_edit(field, ((current & !3) | (base & 3)).to_string());
|
||||
Task::none()
|
||||
}
|
||||
Message::DsZeroFlag(field, bit) => {
|
||||
let current = match &field {
|
||||
crate::app::DsField::Dimzin => &self.ds_dimzin,
|
||||
crate::app::DsField::Dimaltz => &self.ds_dimaltz,
|
||||
crate::app::DsField::Dimalttz => &self.ds_dimalttz,
|
||||
crate::app::DsField::Dimtzin => &self.ds_dimtzin,
|
||||
_ => return Task::none(),
|
||||
}
|
||||
.trim()
|
||||
.parse::<i16>()
|
||||
.unwrap_or(0);
|
||||
self.apply_ds_edit(field, (current ^ bit).to_string());
|
||||
Task::none()
|
||||
}
|
||||
Message::DsCenterMarkMode(mode) => {
|
||||
let size = self.ds_dimcen.trim().parse::<f64>().unwrap_or(0.09).abs();
|
||||
self.ds_dimcen = match mode.as_str() {
|
||||
"mark" => size.max(f64::EPSILON).to_string(),
|
||||
"lines" => format!("-{}", size.max(f64::EPSILON)),
|
||||
_ => "0".to_string(),
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::DsColorMore(field) => {
|
||||
|
||||
+140
-9
@@ -22,6 +22,91 @@ use iced::{mouse, Point, Task};
|
||||
|
||||
|
||||
impl OpenCADStudio {
|
||||
pub(in crate::app) fn mlstyle_mut(
|
||||
&mut self,
|
||||
tab: usize,
|
||||
) -> Option<&mut acadrust::objects::MLineStyle> {
|
||||
use acadrust::objects::ObjectType;
|
||||
let name = self.mlstyle_selected.clone();
|
||||
self.tabs[tab]
|
||||
.scene
|
||||
.document
|
||||
.objects
|
||||
.values_mut()
|
||||
.find_map(|object| match object {
|
||||
ObjectType::MLineStyle(style) if style.name == name => Some(style),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub(in crate::app) fn load_mlstyle_bufs(&mut self, tab: usize) {
|
||||
use acadrust::objects::ObjectType;
|
||||
let name = self.mlstyle_selected.clone();
|
||||
let Some((description, start_angle, end_angle, fill_color, elements)) = self.tabs[tab]
|
||||
.scene
|
||||
.document
|
||||
.objects
|
||||
.values()
|
||||
.find_map(|object| match object {
|
||||
ObjectType::MLineStyle(style) if style.name == name => Some((
|
||||
style.description.clone(),
|
||||
style.start_angle.to_degrees(),
|
||||
style.end_angle.to_degrees(),
|
||||
style.fill_color.index().unwrap_or(256),
|
||||
style
|
||||
.elements
|
||||
.iter()
|
||||
.map(|element| {
|
||||
[
|
||||
format!("{}", element.offset),
|
||||
element.color.index().unwrap_or(256).to_string(),
|
||||
element.linetype.clone(),
|
||||
]
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)),
|
||||
_ => None,
|
||||
})
|
||||
else {
|
||||
return;
|
||||
};
|
||||
self.mln_description = description;
|
||||
self.mln_start_angle = format!("{start_angle:.4}");
|
||||
self.mln_end_angle = format!("{end_angle:.4}");
|
||||
self.mln_fill_color = fill_color.to_string();
|
||||
self.mln_elements = elements;
|
||||
}
|
||||
|
||||
pub(in crate::app) fn stage_mlstyle_bufs(&mut self) {
|
||||
let tab = self.active_tab;
|
||||
let description = self.mln_description.clone();
|
||||
let start_angle = self.mln_start_angle.trim().parse::<f64>().ok();
|
||||
let end_angle = self.mln_end_angle.trim().parse::<f64>().ok();
|
||||
let fill_color = self.mln_fill_color.trim().parse::<i16>().ok();
|
||||
let elements = self.mln_elements.clone();
|
||||
if let Some(style) = self.mlstyle_mut(tab) {
|
||||
style.description = description;
|
||||
if let Some(value) = start_angle {
|
||||
style.start_angle = value.to_radians();
|
||||
}
|
||||
if let Some(value) = end_angle {
|
||||
style.end_angle = value.to_radians();
|
||||
}
|
||||
if let Some(value) = fill_color {
|
||||
style.fill_color = acadrust::types::Color::from_index(value);
|
||||
}
|
||||
for (element, values) in style.elements.iter_mut().zip(elements) {
|
||||
if let Ok(value) = values[0].trim().parse::<f64>() {
|
||||
element.offset = value;
|
||||
}
|
||||
if let Ok(value) = values[1].trim().parse::<i16>() {
|
||||
element.color = acadrust::types::Color::from_index(value);
|
||||
}
|
||||
element.linetype = values[2].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::app) fn tablestyle_mut(&mut self, tab: usize) -> Option<&mut acadrust::objects::TableStyle> {
|
||||
use acadrust::objects::ObjectType;
|
||||
let name = self.tablestyle_selected.clone();
|
||||
@@ -163,8 +248,8 @@ impl OpenCADStudio {
|
||||
self.mls_text_height = format!("{:.4}", s.text_height);
|
||||
self.mls_scale_factor = format!("{:.4}", s.scale_factor);
|
||||
self.mls_break_gap = format!("{:.4}", s.break_gap_size);
|
||||
self.mls_first_seg_angle = format!("{:.4}", s.first_segment_angle);
|
||||
self.mls_second_seg_angle = format!("{:.4}", s.second_segment_angle);
|
||||
self.mls_first_seg_angle = format!("{:.4}", s.first_segment_angle.to_degrees());
|
||||
self.mls_second_seg_angle = format!("{:.4}", s.second_segment_angle.to_degrees());
|
||||
self.mls_max_points = s.max_leader_points.to_string();
|
||||
self.mls_default_text = s.default_text.clone();
|
||||
self.mls_line_color = s
|
||||
@@ -184,7 +269,7 @@ impl OpenCADStudio {
|
||||
.index()
|
||||
.map(|c| c.to_string())
|
||||
.unwrap_or_default();
|
||||
self.mls_block_rotation = format!("{:.4}", s.block_content_rotation);
|
||||
self.mls_block_rotation = format!("{:.4}", s.block_content_rotation.to_degrees());
|
||||
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);
|
||||
@@ -273,6 +358,20 @@ impl OpenCADStudio {
|
||||
|
||||
pub(in crate::app) fn apply_dimstyle_bufs(&mut self, tab: usize) {
|
||||
let doc = &mut self.tabs[tab].scene.document;
|
||||
let read_only = doc
|
||||
.dim_styles
|
||||
.get(&self.dimstyle_selected)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
});
|
||||
if read_only {
|
||||
return;
|
||||
}
|
||||
let text_style_handle = doc
|
||||
.text_styles
|
||||
.get(&self.ds_dimtxsty)
|
||||
.map(|style| style.handle)
|
||||
.unwrap_or(acadrust::types::Handle::NULL);
|
||||
let Some(ds) = doc.dim_styles.get_mut(&self.dimstyle_selected) else {
|
||||
return;
|
||||
};
|
||||
@@ -323,6 +422,7 @@ impl OpenCADStudio {
|
||||
ds.dimlim = self.ds_dimlim;
|
||||
ds.dimpost = self.ds_dimpost.clone();
|
||||
ds.dimtxsty = self.ds_dimtxsty.clone();
|
||||
ds.dimtxsty_handle = text_style_handle;
|
||||
ds.annotative = self.ds_annotative;
|
||||
set_i16!(dimclrd, self.ds_dimclrd);
|
||||
set_i16!(dimlwd, self.ds_dimlwd);
|
||||
@@ -392,7 +492,15 @@ impl OpenCADStudio {
|
||||
Dimlunit => self.ds_dimlunit = val,
|
||||
Dimdec => self.ds_dimdec = val,
|
||||
Dimpost => self.ds_dimpost = val,
|
||||
Dimtp => self.ds_dimtp = val,
|
||||
Dimtp => {
|
||||
let symmetrical = self.ds_dimtol
|
||||
&& !self.ds_dimlim
|
||||
&& self.ds_dimtp.trim() == self.ds_dimtm.trim();
|
||||
self.ds_dimtp = val.clone();
|
||||
if symmetrical {
|
||||
self.ds_dimtm = val;
|
||||
}
|
||||
}
|
||||
Dimtm => self.ds_dimtm = val,
|
||||
Dimtdec => self.ds_dimtdec = val,
|
||||
Dimtfac => self.ds_dimtfac = val,
|
||||
@@ -518,6 +626,9 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
let bigfont = self.textstyle_bigfont.clone();
|
||||
let ttf = self.textstyle_ttf.clone();
|
||||
if let Some(s) = self.tabs[i].scene.document.text_styles.get_mut(&name) {
|
||||
if s.xref_dependent {
|
||||
return;
|
||||
}
|
||||
s.font_file = font;
|
||||
s.big_font_file = bigfont;
|
||||
s.true_type_font = ttf;
|
||||
@@ -629,6 +740,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
.unwrap_or_else(|| "Standard".to_string())
|
||||
};
|
||||
self.active_modal = Some(crate::app::ModalKind::MlStyle);
|
||||
self.load_mlstyle_bufs(i);
|
||||
self.style_stage_begin();
|
||||
Task::none()
|
||||
}
|
||||
@@ -818,7 +930,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
pub(super) fn on_mleader_style_set_handle(&mut self, field: &'static str, value: String) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let handle: Option<acadrust::types::Handle> = if value == "None" {
|
||||
let handle: Option<acadrust::types::Handle> = if value == "None"
|
||||
|| value == "ByBlock"
|
||||
|| value == "Closed filled"
|
||||
{
|
||||
None
|
||||
} else {
|
||||
match field {
|
||||
@@ -897,10 +1012,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
s.break_gap_size = v;
|
||||
}
|
||||
if let Some(v) = fsa {
|
||||
s.first_segment_angle = v;
|
||||
s.first_segment_angle = v.to_radians();
|
||||
}
|
||||
if let Some(v) = ssa {
|
||||
s.second_segment_angle = v;
|
||||
s.second_segment_angle = v.to_radians();
|
||||
}
|
||||
if let Some(v) = mp {
|
||||
s.max_leader_points = v;
|
||||
@@ -920,7 +1035,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
s.block_content_color = acadrust::types::Color::from_index(v);
|
||||
}
|
||||
if let Some(v) = brot {
|
||||
s.block_content_rotation = v;
|
||||
s.block_content_rotation = v.to_radians();
|
||||
}
|
||||
if let Some(v) = bsx {
|
||||
s.block_content_scale_x = v;
|
||||
@@ -962,6 +1077,14 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
.unwrap_or_else(|| "Standard".to_string())
|
||||
};
|
||||
self.dimstyle_selected = selected.clone();
|
||||
self.dimstyle_compare = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.iter()
|
||||
.map(|style| style.name.clone())
|
||||
.find(|name| !name.eq_ignore_ascii_case(&selected))
|
||||
.unwrap_or_default();
|
||||
self.load_dimstyle_bufs(i);
|
||||
self.active_modal = Some(crate::app::ModalKind::DimStyle);
|
||||
self.style_stage_begin();
|
||||
@@ -1018,6 +1141,11 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
"dimltex_handle" | "dimltex1_handle" | "dimltex2_handle"
|
||||
);
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
if doc.dim_styles.get(&name).is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
}) {
|
||||
return Task::none();
|
||||
}
|
||||
let handle = if value == "Default" || value == "ByBlock" {
|
||||
acadrust::types::Handle::NULL
|
||||
} else if is_lt {
|
||||
@@ -1037,7 +1165,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
||||
if let Some(ds) = self.tabs[i].scene.document.dim_styles.get_mut(&name) {
|
||||
match field {
|
||||
"dimblk" => ds.dimblk = handle,
|
||||
"dimblk1" => ds.dimblk1 = handle,
|
||||
"dimblk1" => {
|
||||
ds.dimblk1 = handle;
|
||||
ds.dimblk2 = handle;
|
||||
}
|
||||
"dimblk2" => ds.dimblk2 = handle,
|
||||
"dimldrblk" => ds.dimldrblk = handle,
|
||||
"dimltex_handle" => ds.dimltex_handle = handle,
|
||||
|
||||
+423
-47
@@ -362,6 +362,7 @@ impl OpenCADStudio {
|
||||
),
|
||||
super::super::ModalKind::TextStyle => {
|
||||
let tab = &self.tabs[self.active_tab];
|
||||
let doc = &tab.scene.document;
|
||||
let styles: Vec<String> = tab
|
||||
.scene
|
||||
.document
|
||||
@@ -369,23 +370,77 @@ impl OpenCADStudio {
|
||||
.iter()
|
||||
.map(|s| s.name.clone())
|
||||
.collect();
|
||||
let (backward, upside_down, annotative) = tab
|
||||
.scene
|
||||
.document
|
||||
let selected_style = doc
|
||||
.text_styles
|
||||
.get(&self.textstyle_selected)
|
||||
.map(|s| (s.flags.backward, s.flags.upside_down, s.annotative))
|
||||
.unwrap_or((false, false, false));
|
||||
.get(&self.textstyle_selected);
|
||||
let (backward, upside_down, vertical, annotative, read_only) = selected_style
|
||||
.map(|style| {
|
||||
(
|
||||
style.flags.backward,
|
||||
style.flags.upside_down,
|
||||
style.is_vertical,
|
||||
style.annotative,
|
||||
style.xref_dependent,
|
||||
)
|
||||
})
|
||||
.unwrap_or((false, false, false, false, false));
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::Text,
|
||||
&self.textstyle_selected,
|
||||
);
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.textstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.textstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, doc.text_styles.get(&compare_name)) {
|
||||
if (
|
||||
&a.font_file,
|
||||
&a.big_font_file,
|
||||
&a.true_type_font,
|
||||
a.is_shape_file,
|
||||
) != (
|
||||
&b.font_file,
|
||||
&b.big_font_file,
|
||||
&b.true_type_font,
|
||||
b.is_shape_file,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Fonts").into_owned());
|
||||
}
|
||||
if (a.height, a.width_factor, a.oblique_angle, a.last_height)
|
||||
!= (b.height, b.width_factor, b.oblique_angle, b.last_height)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Size").into_owned());
|
||||
}
|
||||
if (a.flags, a.is_vertical, a.annotative)
|
||||
!= (b.flags, b.is_vertical, b.annotative)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Effects").into_owned());
|
||||
}
|
||||
}
|
||||
sized_flow(
|
||||
ex,
|
||||
860,
|
||||
480,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::textstyle::view_window(
|
||||
crate::ui::style::textstyle::TextStyleView {
|
||||
styles: styles.clone(),
|
||||
selected: &self.textstyle_selected,
|
||||
current: &tab.scene.document.header.current_text_style_name,
|
||||
tab: self.textstyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
read_only,
|
||||
in_use,
|
||||
font_buf: &self.textstyle_font,
|
||||
width_buf: &self.textstyle_width,
|
||||
oblique_buf: &self.textstyle_oblique,
|
||||
@@ -394,6 +449,7 @@ impl OpenCADStudio {
|
||||
ttf_buf: &self.textstyle_ttf,
|
||||
backward,
|
||||
upside_down,
|
||||
vertical,
|
||||
annotative,
|
||||
rename_active: self.style_rename.as_deref(),
|
||||
rename_buf: &self.style_rename_buf,
|
||||
@@ -420,18 +476,60 @@ impl OpenCADStudio {
|
||||
ObjectType::MLineStyle(s) if s.name == self.mlstyle_selected => Some(s),
|
||||
_ => None,
|
||||
});
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.mlstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.mlstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let compare_style = tab.scene.document.objects.values().find_map(|object| match object {
|
||||
ObjectType::MLineStyle(style) if style.name == compare_name => Some(style),
|
||||
_ => None,
|
||||
});
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, compare_style) {
|
||||
if (&a.description, a.flags, a.fill_color, a.start_angle, a.end_angle)
|
||||
!= (&b.description, b.flags, b.fill_color, b.start_angle, b.end_angle)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Caps and Fill").into_owned());
|
||||
}
|
||||
if a.elements != b.elements {
|
||||
comparison_sections.push(crate::i18n::translate("Elements").into_owned());
|
||||
}
|
||||
}
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::MLine,
|
||||
&self.mlstyle_selected,
|
||||
);
|
||||
sized_flow(
|
||||
ex,
|
||||
620,
|
||||
420,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::mlstyle::view_window(
|
||||
styles.clone(),
|
||||
&self.mlstyle_selected,
|
||||
selected_style,
|
||||
tab.scene.document.header.multiline_style.clone(),
|
||||
self.style_rename.as_deref(),
|
||||
&self.style_rename_buf,
|
||||
crate::ui::style::mlstyle::MlStyleView {
|
||||
styles: styles.clone(),
|
||||
selected: &self.mlstyle_selected,
|
||||
style: selected_style,
|
||||
current: tab.scene.document.header.multiline_style.clone(),
|
||||
tab: self.mlstyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
in_use,
|
||||
description: &self.mln_description,
|
||||
start_angle: &self.mln_start_angle,
|
||||
end_angle: &self.mln_end_angle,
|
||||
fill_color: &self.mln_fill_color,
|
||||
elements: &self.mln_elements,
|
||||
rename_active: self.style_rename.as_deref(),
|
||||
rename_buf: &self.style_rename_buf,
|
||||
},
|
||||
flow,
|
||||
)
|
||||
},
|
||||
@@ -454,32 +552,89 @@ impl OpenCADStudio {
|
||||
ObjectType::TableStyle(s) if s.name == self.tablestyle_selected => Some(s),
|
||||
_ => None,
|
||||
});
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.tablestyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.tablestyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let compare_style = tab.scene.document.objects.values().find_map(|object| match object {
|
||||
ObjectType::TableStyle(style) if style.name == compare_name => Some(style),
|
||||
_ => None,
|
||||
});
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, compare_style) {
|
||||
if (
|
||||
&a.description,
|
||||
a.flow_direction,
|
||||
a.horizontal_margin,
|
||||
a.vertical_margin,
|
||||
a.title_suppressed,
|
||||
a.header_suppressed,
|
||||
a.annotative,
|
||||
) != (
|
||||
&b.description,
|
||||
b.flow_direction,
|
||||
b.horizontal_margin,
|
||||
b.vertical_margin,
|
||||
b.title_suppressed,
|
||||
b.header_suppressed,
|
||||
b.annotative,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("General").into_owned());
|
||||
}
|
||||
for (label, different) in [
|
||||
("Data Row", a.data_row_style != b.data_row_style),
|
||||
("Header Row", a.header_row_style != b.header_row_style),
|
||||
("Title Row", a.title_row_style != b.title_row_style),
|
||||
] {
|
||||
if different {
|
||||
comparison_sections.push(crate::i18n::translate(label).into_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::Table,
|
||||
&self.tablestyle_selected,
|
||||
);
|
||||
sized_flow(
|
||||
ex,
|
||||
620,
|
||||
420,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::tablestyle::view_window(
|
||||
styles.clone(),
|
||||
&self.tablestyle_selected,
|
||||
&self.ribbon.active_table_style,
|
||||
selected_style,
|
||||
&self.ts_hmargin,
|
||||
&self.ts_vmargin,
|
||||
&self.ts_description,
|
||||
&self.ts_cell_textstyle,
|
||||
&self.ts_cell_height,
|
||||
&self.ts_cell_textcolor,
|
||||
&self.ts_cell_fillcolor,
|
||||
&self.ts_cell_datatype,
|
||||
&self.ts_cell_unittype,
|
||||
&self.ts_cell_format,
|
||||
&self.ts_border_lw,
|
||||
&self.ts_border_color,
|
||||
&self.ts_border_spacing,
|
||||
self.style_rename.as_deref(),
|
||||
&self.style_rename_buf,
|
||||
self.ts_color_open,
|
||||
crate::ui::style::tablestyle::TableStyleView {
|
||||
styles: styles.clone(),
|
||||
selected: &self.tablestyle_selected,
|
||||
current: &tab.scene.document.header.current_table_style_name,
|
||||
style: selected_style,
|
||||
tab: self.tablestyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
in_use,
|
||||
hmargin: &self.ts_hmargin,
|
||||
vmargin: &self.ts_vmargin,
|
||||
description: &self.ts_description,
|
||||
cell_textstyle: &self.ts_cell_textstyle,
|
||||
cell_height: &self.ts_cell_height,
|
||||
cell_textcolor: &self.ts_cell_textcolor,
|
||||
cell_fillcolor: &self.ts_cell_fillcolor,
|
||||
cell_datatype: &self.ts_cell_datatype,
|
||||
cell_unittype: &self.ts_cell_unittype,
|
||||
cell_format: &self.ts_cell_format,
|
||||
border_lw: &self.ts_border_lw,
|
||||
border_color: &self.ts_border_color,
|
||||
border_spacing: &self.ts_border_spacing,
|
||||
rename_active: self.style_rename.as_deref(),
|
||||
rename_buf: &self.style_rename_buf,
|
||||
color_open: self.ts_color_open,
|
||||
},
|
||||
flow,
|
||||
)
|
||||
},
|
||||
@@ -507,7 +662,9 @@ impl OpenCADStudio {
|
||||
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()];
|
||||
let mut arrow_opts: Vec<String> = vec!["Closed filled".to_string()];
|
||||
arrow_opts.extend(doc.block_records.iter().map(|b| b.name.clone()));
|
||||
let mut lt_opts: Vec<String> = vec!["ByBlock".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()));
|
||||
@@ -529,8 +686,8 @@ impl OpenCADStudio {
|
||||
.iter()
|
||||
.find(|lt| lt.handle == h)
|
||||
.map(|lt| lt.name.clone())
|
||||
.unwrap_or_else(|| "None".to_string()),
|
||||
None => "None".to_string(),
|
||||
.unwrap_or_else(|| "ByBlock".to_string()),
|
||||
None => "ByBlock".to_string(),
|
||||
}
|
||||
};
|
||||
let opt_ts = |h: Option<acadrust::types::Handle>| -> String {
|
||||
@@ -548,16 +705,153 @@ impl OpenCADStudio {
|
||||
match selected_style {
|
||||
Some(s) => (
|
||||
opt_lt(s.line_type_handle),
|
||||
opt_block(s.arrowhead_handle),
|
||||
s.arrowhead_handle
|
||||
.and_then(|handle| {
|
||||
doc.block_records
|
||||
.iter()
|
||||
.find(|record| record.handle == handle)
|
||||
.map(|record| record.name.clone())
|
||||
})
|
||||
.unwrap_or_else(|| "Closed filled".to_string()),
|
||||
opt_ts(s.text_style_handle),
|
||||
opt_block(s.block_content_handle),
|
||||
),
|
||||
None => Default::default(),
|
||||
};
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.mleaderstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.mleaderstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let compare_style = doc.objects.values().find_map(|object| match object {
|
||||
ObjectType::MultiLeaderStyle(style) if style.name == compare_name => Some(style),
|
||||
_ => None,
|
||||
});
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, compare_style) {
|
||||
if (
|
||||
&a.description,
|
||||
a.path_type,
|
||||
a.line_color,
|
||||
a.line_type_handle,
|
||||
a.line_weight,
|
||||
a.arrowhead_handle,
|
||||
a.arrowhead_size,
|
||||
a.break_gap_size,
|
||||
) != (
|
||||
&b.description,
|
||||
b.path_type,
|
||||
b.line_color,
|
||||
b.line_type_handle,
|
||||
b.line_weight,
|
||||
b.arrowhead_handle,
|
||||
b.arrowhead_size,
|
||||
b.break_gap_size,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Leader Format").into_owned());
|
||||
}
|
||||
if (
|
||||
a.enable_landing,
|
||||
a.enable_dogleg,
|
||||
a.landing_distance,
|
||||
a.landing_gap,
|
||||
a.scale_factor,
|
||||
a.align_space,
|
||||
a.max_leader_points,
|
||||
a.first_segment_angle,
|
||||
a.second_segment_angle,
|
||||
a.leader_draw_order,
|
||||
a.multileader_draw_order,
|
||||
a.is_annotative,
|
||||
) != (
|
||||
b.enable_landing,
|
||||
b.enable_dogleg,
|
||||
b.landing_distance,
|
||||
b.landing_gap,
|
||||
b.scale_factor,
|
||||
b.align_space,
|
||||
b.max_leader_points,
|
||||
b.first_segment_angle,
|
||||
b.second_segment_angle,
|
||||
b.leader_draw_order,
|
||||
b.multileader_draw_order,
|
||||
b.is_annotative,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Leader Structure").into_owned());
|
||||
}
|
||||
if (
|
||||
a.content_type,
|
||||
&a.default_text,
|
||||
a.text_style_handle,
|
||||
a.text_height,
|
||||
a.text_color,
|
||||
a.text_angle_type,
|
||||
a.text_alignment,
|
||||
) != (
|
||||
b.content_type,
|
||||
&b.default_text,
|
||||
b.text_style_handle,
|
||||
b.text_height,
|
||||
b.text_color,
|
||||
b.text_angle_type,
|
||||
b.text_alignment,
|
||||
) || (
|
||||
a.text_left_attachment,
|
||||
a.text_right_attachment,
|
||||
a.text_top_attachment,
|
||||
a.text_bottom_attachment,
|
||||
a.text_attachment_direction,
|
||||
a.text_frame,
|
||||
a.text_always_left,
|
||||
) != (
|
||||
b.text_left_attachment,
|
||||
b.text_right_attachment,
|
||||
b.text_top_attachment,
|
||||
b.text_bottom_attachment,
|
||||
b.text_attachment_direction,
|
||||
b.text_frame,
|
||||
b.text_always_left,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Content").into_owned());
|
||||
}
|
||||
if (
|
||||
a.block_content_handle,
|
||||
a.block_content_color,
|
||||
a.block_content_connection,
|
||||
a.block_content_rotation,
|
||||
a.block_content_scale_x,
|
||||
a.block_content_scale_y,
|
||||
a.block_content_scale_z,
|
||||
a.enable_block_scale,
|
||||
a.enable_block_rotation,
|
||||
) != (
|
||||
b.block_content_handle,
|
||||
b.block_content_color,
|
||||
b.block_content_connection,
|
||||
b.block_content_rotation,
|
||||
b.block_content_scale_x,
|
||||
b.block_content_scale_y,
|
||||
b.block_content_scale_z,
|
||||
b.enable_block_scale,
|
||||
b.enable_block_rotation,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Block Content").into_owned());
|
||||
}
|
||||
}
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::MLeader,
|
||||
&self.mleaderstyle_selected,
|
||||
);
|
||||
sized_flow(
|
||||
ex,
|
||||
560,
|
||||
560,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::mleaderstyle::view_window(
|
||||
crate::ui::style::mleaderstyle::MLeaderStyleView {
|
||||
@@ -565,6 +859,11 @@ impl OpenCADStudio {
|
||||
selected: &self.mleaderstyle_selected,
|
||||
style: selected_style,
|
||||
current: tab.active_mleader_style.clone(),
|
||||
tab: self.mleaderstyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
in_use,
|
||||
landing_distance: &self.mls_landing_distance,
|
||||
landing_gap: &self.mls_landing_gap,
|
||||
arrowhead_size: &self.mls_arrowhead_size,
|
||||
@@ -585,6 +884,7 @@ impl OpenCADStudio {
|
||||
block_scale_y: &self.mls_block_scale_y,
|
||||
block_scale_z: &self.mls_block_scale_z,
|
||||
block_opts: block_opts.clone(),
|
||||
arrow_opts: arrow_opts.clone(),
|
||||
lt_opts: lt_opts.clone(),
|
||||
textstyle_opts: textstyle_opts.clone(),
|
||||
line_type_name: line_type_name.clone(),
|
||||
@@ -630,6 +930,13 @@ impl OpenCADStudio {
|
||||
);
|
||||
let mut lt_opts: Vec<String> = vec!["ByBlock".to_string()];
|
||||
lt_opts.extend(doc.line_types.iter().map(|lt| lt.name.clone()));
|
||||
let text_style_opts: Vec<String> =
|
||||
doc.text_styles.iter().map(|style| style.name.clone()).collect();
|
||||
let text_style_fixed_height = doc
|
||||
.text_styles
|
||||
.get(&self.ds_dimtxsty)
|
||||
.map(|style| style.height)
|
||||
.filter(|height| *height > 0.0);
|
||||
let blk_name = |h: acadrust::types::Handle| -> String {
|
||||
if h.is_null() {
|
||||
"Default".to_string()
|
||||
@@ -653,6 +960,70 @@ impl OpenCADStudio {
|
||||
}
|
||||
};
|
||||
let ds_sel = doc.dim_styles.get(&self.dimstyle_selected);
|
||||
let read_only = ds_sel.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
});
|
||||
let in_use = doc.entities().any(|entity| {
|
||||
matches!(entity, acadrust::EntityType::Dimension(dimension)
|
||||
if dimension.base().style_name.eq_ignore_ascii_case(&self.dimstyle_selected))
|
||||
});
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.dimstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.dimstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (ds_sel, doc.dim_styles.get(&compare_name)) {
|
||||
if (a.dimdle, a.dimdli, a.dimgap, a.dimclrd, a.dimlwd, a.dimsd1, a.dimsd2)
|
||||
!= (b.dimdle, b.dimdli, b.dimgap, b.dimclrd, b.dimlwd, b.dimsd1, b.dimsd2)
|
||||
|| (a.dimexe, a.dimexo, a.dimclre, a.dimlwe, a.dimse1, a.dimse2, a.dimfxl, a.dimfxlon)
|
||||
!= (b.dimexe, b.dimexo, b.dimclre, b.dimlwe, b.dimse1, b.dimse2, b.dimfxl, b.dimfxlon)
|
||||
|| (a.dimltex_handle, a.dimltex1_handle, a.dimltex2_handle)
|
||||
!= (b.dimltex_handle, b.dimltex1_handle, b.dimltex2_handle)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Lines").into_owned());
|
||||
}
|
||||
if (a.dimasz, a.dimblk, a.dimblk1, a.dimblk2, a.dimldrblk, a.dimsah, a.dimcen, a.dimtsz)
|
||||
!= (b.dimasz, b.dimblk, b.dimblk1, b.dimblk2, b.dimldrblk, b.dimsah, b.dimcen, b.dimtsz)
|
||||
|| (a.dimarcsym, a.dimjogang) != (b.dimarcsym, b.dimjogang)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Symbols and Arrows").into_owned());
|
||||
}
|
||||
if (a.dimclrt, a.dimtxt, &a.dimtxsty, a.dimjust, a.dimtad, a.dimtvp)
|
||||
!= (b.dimclrt, b.dimtxt, &b.dimtxsty, b.dimjust, b.dimtad, b.dimtvp)
|
||||
|| (a.dimtih, a.dimtoh, a.dimtfill, a.dimtfillclr, a.dimtxtdirection)
|
||||
!= (b.dimtih, b.dimtoh, b.dimtfill, b.dimtfillclr, b.dimtxtdirection)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Text").into_owned());
|
||||
}
|
||||
if (a.dimatfit, a.dimtix, a.dimsoxd, a.dimtmove, a.dimupt, a.dimtofl, a.dimscale, a.annotative)
|
||||
!= (b.dimatfit, b.dimtix, b.dimsoxd, b.dimtmove, b.dimupt, b.dimtofl, b.dimscale, b.annotative)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Fit").into_owned());
|
||||
}
|
||||
if (a.dimlfac, a.dimlunit, a.dimdec, &a.dimpost, a.dimdsep, a.dimrnd, a.dimzin, a.dimfrac)
|
||||
!= (b.dimlfac, b.dimlunit, b.dimdec, &b.dimpost, b.dimdsep, b.dimrnd, b.dimzin, b.dimfrac)
|
||||
|| (a.dimaunit, a.dimadec, a.dimazin) != (b.dimaunit, b.dimadec, b.dimazin)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Primary Units").into_owned());
|
||||
}
|
||||
if (a.dimalt, a.dimaltf, a.dimaltd, a.dimaltu, a.dimalttd, a.dimaltrnd, &a.dimapost, a.dimaltz, a.dimalttz)
|
||||
!= (b.dimalt, b.dimaltf, b.dimaltd, b.dimaltu, b.dimalttd, b.dimaltrnd, &b.dimapost, b.dimaltz, b.dimalttz)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Alternate Units").into_owned());
|
||||
}
|
||||
if (a.dimtol, a.dimlim, a.dimtp, a.dimtm, a.dimtdec, a.dimtfac, a.dimtolj, a.dimtzin)
|
||||
!= (b.dimtol, b.dimlim, b.dimtp, b.dimtm, b.dimtdec, b.dimtfac, b.dimtolj, b.dimtzin)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Tolerances").into_owned());
|
||||
}
|
||||
}
|
||||
let (
|
||||
dimblk_name,
|
||||
dimblk1_name,
|
||||
@@ -673,7 +1044,7 @@ impl OpenCADStudio {
|
||||
),
|
||||
None => Default::default(),
|
||||
};
|
||||
sized_flow(ex, 720, 560, |flow| {
|
||||
sized_flow(ex, 960, 680, |flow| {
|
||||
crate::ui::style::dimstyle::view_window(
|
||||
styles.clone(),
|
||||
&self.dimstyle_selected,
|
||||
@@ -734,14 +1105,12 @@ impl OpenCADStudio {
|
||||
dimtmove: &self.ds_dimtmove,
|
||||
dimupt: self.ds_dimupt,
|
||||
dimtofl: self.ds_dimtofl,
|
||||
dimfit: &self.ds_dimfit,
|
||||
dimdsep: &self.ds_dimdsep,
|
||||
dimrnd: &self.ds_dimrnd,
|
||||
dimzin: &self.ds_dimzin,
|
||||
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,
|
||||
@@ -763,6 +1132,13 @@ impl OpenCADStudio {
|
||||
dimltex2_name: dimltex2_name.clone(),
|
||||
block_opts: block_opts.clone(),
|
||||
lt_opts: lt_opts.clone(),
|
||||
text_style_opts: text_style_opts.clone(),
|
||||
text_style_fixed_height,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
read_only,
|
||||
in_use,
|
||||
color_open: self.ds_color_open.clone(),
|
||||
},
|
||||
self.style_rename.as_deref(),
|
||||
|
||||
Reference in new issue
Block a user