forked from 1b-agent/opencadstudio-upstream
feat(properties): show & edit block attributes in panel
Selecting an INSERT with attributes now adds an editable "Attributes" section to the Properties panel — each tag is a row whose value can be changed inline (Enter commits, undo works, the attribute text repaints). Previously attribute values could only be reached through ATTEDIT, which didn't let them be changed (#192). Attribute tags are runtime strings, so they can't ride the geometry edit path whose field key is `&'static str`; a dedicated PropValue:: AttrText variant plus PropAttrInput/PropAttrCommit messages carry the tag. Values are stored verbatim (no expression evaluation, since attribute text is free-form). Also guard the panel's in-progress edit buffer: it now only carries across a rebuild when the selection is unchanged (a commit-triggered refresh), so a typed-but-uncommitted value can't display or commit onto a different entity — e.g. two title blocks sharing a REV1 tag. This closes a latent stale-buffer leak that affected geometry fields too. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
3da81571a1
commit
5f2e920b75
7 files changed
+133
-1
No files matched your search
@@ -1173,4 +1173,35 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
/// Commit an edited block-attribute value from the Properties panel.
|
||||
/// Writes the new value into the matching attribute (by tag) of every
|
||||
/// selected INSERT, then re-tessellates so the attribute text repaints.
|
||||
/// The value is stored verbatim (attribute values are free-form text, so
|
||||
/// it is not run through the expression evaluator like numeric fields).
|
||||
pub(super) fn on_prop_attr_commit(&mut self, tag: String) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
let key = crate::ui::properties::attr_edit_key(&tag);
|
||||
let handles = self.property_target_handles(i);
|
||||
if handles.is_empty() {
|
||||
return Task::none();
|
||||
}
|
||||
let Some(val) = self.tabs[i].properties.edit_buf.remove(&key) else {
|
||||
return Task::none();
|
||||
};
|
||||
self.push_undo_snapshot(i, "ATTEDIT");
|
||||
for &handle in &handles {
|
||||
if let Some(acadrust::EntityType::Insert(ins)) =
|
||||
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||
{
|
||||
if let Some(attr) = ins.attributes.iter_mut().find(|a| a.tag == tag) {
|
||||
attr.set_value(val.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
self.invalidate_property_targets(i, &handles);
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user