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:
parent
eead4eb5f0
commit
c3e3132b39
4 changed files with 114 additions and 83 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -2005,7 +2005,10 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
// selected inserts to the picked definition. A stale
|
||||
// typed value in the text buffer would mask the pick,
|
||||
// so drop it; the pick also closes the list.
|
||||
self.tabs[i].properties.edit_buf.remove("block");
|
||||
self.tabs[i]
|
||||
.properties
|
||||
.edit_buf
|
||||
.remove(&crate::ui::properties::FieldKey::Geom("block"));
|
||||
self.tabs[i].properties.edit_choice_open = false;
|
||||
let canon = self.tabs[i]
|
||||
.scene
|
||||
|
|
@ -2144,7 +2147,11 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
self.tabs[i].properties.active_field = None;
|
||||
let handles = self.property_target_handles(i);
|
||||
if !handles.is_empty() {
|
||||
if let Some(raw_val) = self.tabs[i].properties.edit_buf.remove(field) {
|
||||
if let Some(raw_val) = self.tabs[i]
|
||||
.properties
|
||||
.edit_buf
|
||||
.remove(&crate::ui::properties::FieldKey::Geom(field))
|
||||
{
|
||||
// Block names are free-form text — a name like "10-5"
|
||||
// must not be arithmetic-evaluated.
|
||||
let val = if field == "block" {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue