diff --git a/src/io/mod.rs b/src/io/mod.rs index 377557e90..2c7e5c9de 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -99,6 +99,7 @@ pub fn load_file(path: &Path) -> Result { .read() .map_err(|e| e.to_string())?; fix_viewport_status_flags(&mut doc); + fix_current_style_names(&mut doc); Ok(doc) } "dxf" => { @@ -108,6 +109,7 @@ pub fn load_file(path: &Path) -> Result { .map_err(|e| e.to_string())?; fix_dxf_dimension_rotations(&mut doc); fix_viewport_status_flags(&mut doc); + fix_current_style_names(&mut doc); Ok(doc) } _ => Err(format!("Unsupported file format: .{ext}")), @@ -235,6 +237,38 @@ pub fn save(doc: &CadDocument, path: &Path) -> Result<(), String> { // ── Post-load fixups ────────────────────────────────────────────────────── +// Resolve the current text / dimension / multiline style from the handle the +// DWG header stores into the *name* the app reads. DXF stores these as names +// directly ($TEXTSTYLE / $DIMSTYLE / $CMLSTYLE), but DWG only stores handles, +// so without this the current-style markers (and any code keyed on the name) +// fall back to "Standard". Only overrides when the handle resolves, leaving the +// DXF-provided names intact. +fn fix_current_style_names(doc: &mut CadDocument) { + use acadrust::objects::ObjectType; + + let h = doc.header.current_text_style_handle; + if h.is_valid() { + if let Some(name) = doc.text_styles.iter().find(|s| s.handle == h).map(|s| s.name.clone()) { + doc.header.current_text_style_name = name; + } + } + let h = doc.header.current_dimstyle_handle; + if h.is_valid() { + if let Some(name) = doc.dim_styles.iter().find(|s| s.handle == h).map(|s| s.name.clone()) { + doc.header.current_dimstyle_name = name; + } + } + let h = doc.header.current_multiline_style_handle; + if h.is_valid() { + if let Some(name) = doc.objects.values().find_map(|o| match o { + ObjectType::MLineStyle(s) if s.handle == h => Some(s.name.clone()), + _ => None, + }) { + doc.header.multiline_style = name; + } + } +} + // ── Corrupt-entity guard ────────────────────────────────────────────────── // // acadrust's DWG parser occasionally desynchronises on certain files and diff --git a/src/ui/style_list.rs b/src/ui/style_list.rs index c6728e157..c01c95f02 100644 --- a/src/ui/style_list.rs +++ b/src/ui/style_list.rs @@ -9,7 +9,7 @@ //! carries both `on_press` (select) and `on_double_click` (rename) itself. use crate::app::{Message, StyleKind}; -use iced::widget::{container, mouse_area, text, text_input}; +use iced::widget::{container, mouse_area, row, text, text_input}; use iced::{Background, Color, Element, Fill, Theme}; /// Shared id for the inline rename field, so the rename-start handler can focus @@ -30,13 +30,19 @@ const ACTIVE: Color = Color { b: 0.70, a: 1.0, }; +const CURRENT_CHECK: Color = Color { + r: 0.30, + g: 0.82, + b: 0.36, + a: 1.0, +}; /// One row of the style list. Renders an editable `text_input` when `name` is /// the style being renamed (`rename_active`), otherwise a selectable row whose -/// double click starts the rename. +/// double click starts the rename. The current style gets a green ✓. pub fn item<'a>( name: &str, - label: String, + is_current: bool, is_selected: bool, kind: StyleKind, on_select: Message, @@ -53,7 +59,16 @@ pub fn item<'a>( .width(Fill) .into() } else { - let row = container(text(label).size(11).color(TEXT)) + // Fixed-width ✓ column keeps every name left-aligned whether or not the + // row is current. + let check = if is_current { + text("✓").size(11).color(CURRENT_CHECK) + } else { + text("").size(11) + }; + let label = row![check.width(14), text(name.to_string()).size(11).color(TEXT)] + .align_y(iced::Center); + let cell = container(label) .padding([4, 8]) .width(Fill) .style(move |_: &Theme| container::Style { @@ -61,7 +76,7 @@ pub fn item<'a>( text_color: Some(TEXT), ..Default::default() }); - mouse_area(row) + mouse_area(cell) .on_press(on_select) .on_double_click(Message::StyleRenameStart(kind, name.to_string())) .into() diff --git a/src/ui/style_manager.rs b/src/ui/style_manager.rs index 6315f40a1..1e0ec2041 100644 --- a/src/ui/style_manager.rs +++ b/src/ui/style_manager.rs @@ -114,16 +114,10 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> { .iter() .map(|name| { let is_sel = name.as_str() == s.selected; - // Mark the current style with a leading ✓; pad the rest so names - // line up. - let label = if s.current == Some(name.as_str()) { - format!("✓ {name}") - } else { - format!(" {name}") - }; + let is_current = s.current == Some(name.as_str()); crate::ui::style_list::item( name, - label, + is_current, is_sel, s.kind, (s.on_select)(name.clone()),