forked from 1b-agent/opencadstudio-upstream
feat(styles): green ✓ for current style + resolve it from DWG files
- The current-style marker is now a green ✓ in its own fixed-width column so names stay aligned; rendered as a separate coloured glyph rather than baked into the label string. - Resolve the current text / dimension / multiline style from the handle the DWG header stores into the name the app reads (fix_current_style_names on load). DXF already provides these as names ($TEXTSTYLE / $DIMSTYLE / $CMLSTYLE); DWG only stores handles, so the marker previously always fell back to "Standard". Only overrides when the handle resolves. Note: table and multileader current styles are not surfaced by the file reader (no header name/handle exposed), so those markers still default to the app's active selection until acadrust exposes them. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
885bacd0f6
commit
b3ba3a53d1
3 files changed
+56
-13
No files matched your search
@@ -99,6 +99,7 @@ pub fn load_file(path: &Path) -> Result<CadDocument, String> {
|
||||
.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<CadDocument, String> {
|
||||
.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
|
||||
|
||||
+20
-5
@@ -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()
|
||||
|
||||
@@ -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()),
|
||||
|
||||
Reference in new issue
Block a user