diff --git a/egui/src/containers/collapsing_header.rs b/egui/src/containers/collapsing_header.rs index 2f76ce17..ffbeb40e 100644 --- a/egui/src/containers/collapsing_header.rs +++ b/egui/src/containers/collapsing_header.rs @@ -191,8 +191,7 @@ impl CollapsingHeader { // TODO: horizontal layout, with icon and text as labels. Insert background behind using Frame. let title = label.text(); - let id_source = id_source.unwrap_or_else(|| Id::new(title)); - let id = ui.make_unique_child_id(id_source); + let id = ui.make_unique_child_id_full(id_source, Some(title)); let available = ui.available_finite(); let text_pos = available.min + vec2(ui.style().indent, 0.0); diff --git a/egui/src/context.rs b/egui/src/context.rs index 3bed6f80..76a8f7eb 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -231,6 +231,10 @@ impl Context { self.register_unique_id(Id::new(source), source, pos) } + pub fn is_unique_id(&self, id: Id) -> bool { + !self.used_ids.lock().contains_key(&id) + } + /// If the given Id is not unique, an error will be printed at the given position. pub fn register_unique_id(&self, id: Id, source_name: impl std::fmt::Debug, pos: Pos2) -> Id { if let Some(clash_pos) = self.used_ids.lock().insert(id, pos) { diff --git a/egui/src/ui.rs b/egui/src/ui.rs index ae2ec01c..bbf743c4 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -295,6 +295,29 @@ impl Ui { self.ctx.register_unique_id(id, id_source, self.cursor) } + /// Ideally, all widgets should use this. TODO + /// Widgets can set an explicit id source (user picked, e.g. some loop index), + /// and a defualt id source (e.g. label). + /// If they fail to be unique, a positional id will be used instead. + pub fn make_unique_child_id_full( + &mut self, + explicit_id_source: Option, + default_id_source: Option<&str>, + ) -> Id + { + let id = if let Some(explicit_id_source) = explicit_id_source { + self.id.with(&explicit_id_source) + } else { + let id = self.id.with(default_id_source); + if self.ctx.is_unique_id(id) { + id + } else { + self.make_position_id() + } + }; + self.ctx.register_unique_id(id, default_id_source.unwrap_or_default(), self.cursor) + } + /// Make an Id that is unique to this positon. /// Can be used for widgets that do NOT persist state in Memory /// but you still need to interact with (e.g. buttons, sliders).