refactor(props): key active fields by a typed enum, not a sentinel string

The \\\x01attr\\x01…\ sentinel-prefixed string was used to tell geometry
fields (\&'static str\ names) apart from block attribute rows (runtime
tags) in \ctive_field\ and \dit_buf\. Replace it with a \FieldKey\
enum (\Geom(&'static str)\ / \Attr(String)\), so the two namespaces can't
collide by construction: \dit_buf\ is now \HashMap<FieldKey, String>\,
\ctive_field\ is \Option<FieldKey>\, and the sentinel decoding in
\ctive_key_id\ is replaced by \FieldKey::widget_id\.

While touching the key plumbing, replace \prop_field_key_for_id\'s
per-event scan of every section x prop (with a \String\ format per
candidate) with an O(1) precomputed \HashMap<iced::widget::Id, FieldKey>\
(\ield_key_by_id\), built once in \
efresh_properties\ alongside the
sections — and rebuilt after \make_sections_read_only\ so rows demoted
to read-only stop mapping. \PropSyncActive\ now does a single map lookup
per event.
This commit is contained in:
Karim Jerbi 2026-08-15 14:29:20 +01:00
commit c3e3132b39
4 changed files with 114 additions and 83 deletions

View file

@ -1432,6 +1432,9 @@ impl OpenCADStudio {
}
}
};
// Precompute the focused-id → field-key map for O(1) lookups on
// `PropSyncActive`; derived from `sections`, so rebuild it here.
panel.field_key_by_id = crate::ui::properties::build_field_key_map(&panel.sections);
panel.color_palette_open = color_palette_open;
let new_handles: Vec<acadrust::Handle> = selected.iter().map(|(h, _)| *h).collect();
// Carry the in-progress edits only when the selection is unchanged
@ -1466,6 +1469,10 @@ impl OpenCADStudio {
.all(|handle| self.tabs[i].scene.is_layer_locked(*handle));
if locked_only {
make_sections_read_only(&mut panel.sections);
// Rows demoted to read-only no longer back an editable field;
// drop them from the id→key map so focus can't map onto them.
panel.field_key_by_id =
crate::ui::properties::build_field_key_map(&panel.sections);
panel.edit_buf.clear();
panel.active_field = None;
panel.color_picker_open = false;