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

@ -4598,7 +4598,7 @@ impl OpenCADStudio {
self.tabs[self.active_tab]
.properties
.edit_buf
.insert(field.to_string(), value);
.insert(crate::ui::properties::FieldKey::Geom(field), value);
Task::none()
}
@ -4642,11 +4642,8 @@ impl OpenCADStudio {
Message::PropSyncActive(focused) => {
let panel = &mut self.tabs[self.active_tab].properties;
if let Some(id) = focused.as_ref() {
if let Some(key) = crate::ui::properties::prop_field_key_for_id(
&panel.sections,
id,
) {
let changed = panel.active_field.as_deref() != Some(key.as_str());
if let Some(key) = panel.prop_field_key_for_id(id) {
let changed = panel.active_field.as_ref() != Some(&key);
panel.active_field = Some(key);
// Only select the whole value when focus landed on a
// field that wasn't already the active one; re-focusing
@ -4659,7 +4656,7 @@ impl OpenCADStudio {
}
}
if !crate::ui::properties::active_key_focused(
panel.active_field.as_deref(),
panel.active_field.as_ref(),
focused.as_ref(),
) {
panel.active_field = None;