diff --git a/crates/egui/src/id.rs b/crates/egui/src/id.rs index a02052fba..f269683fb 100644 --- a/crates/egui/src/id.rs +++ b/crates/egui/src/id.rs @@ -117,6 +117,7 @@ impl Id { Self(NonZeroU64::new(value).expect("Id must be non-zero.")) } + /// Paint a rectangle around the widget, if it can be found. pub fn try_highlight(self, ctx: &crate::Context) { let response = ctx.read_response(self); if let Some(response) = response { @@ -157,8 +158,7 @@ impl Id { #[cfg(debug_assertions)] mod id_source { - use crate::{AsId, CollapsingHeader, Id}; - use ahash::HashMap; + use crate::{AsId, CollapsingHeader, Id, IdMap}; use epaint::mutex::RwLock; use std::fmt::{Display, Formatter}; use std::hash::Hasher; @@ -192,8 +192,8 @@ mod id_source { } } - static ID_MAP: LazyLock>> = LazyLock::new(|| { - let mut map = HashMap::default(); + static ID_MAP: LazyLock>> = LazyLock::new(|| { + let mut map = IdMap::default(); map.insert( Id::NULL, IdInfo { @@ -247,7 +247,7 @@ mod id_source { let maybe_source_id = hasher.id(); - // Ideally we would just implement IdTriat for Id with specialization, but that's not + // Ideally we would just implement AsId for Id with specialization, but that's not // a thing yet :( So we check if the hash is already in the map, if so, the source must be // an Id. if let Some(maybe_source_id) = maybe_source_id { @@ -324,6 +324,23 @@ mod id_source { assert_eq!(hasher.id(), Some(id)); } + + #[test] + fn test_debug_format() { + let parent = Id::new("parent"); + let child = parent.with("child"); + let nested = Id::new(parent).with(child); + + assert_eq!(format!("{parent:?}"), r#"9DE0 ("parent")"#); + assert_eq!( + format!("{child:?}"), + r#"F27D ("child") <- 9DE0 ("parent")"# + ); + assert_eq!( + format!("{nested:?}"), + r#"A8BE(F27D ("child") <- 9DE0 ("parent")) <- B20C(9DE0 ("parent"))"# + ); + } } impl std::fmt::Debug for Id { diff --git a/crates/egui_kittest/tests/snapshots/id_popup_0.png b/crates/egui_kittest/tests/snapshots/id_popup_0.png new file mode 100644 index 000000000..aa962fed0 --- /dev/null +++ b/crates/egui_kittest/tests/snapshots/id_popup_0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a6b2bc514547975d3321bb1e09ab913a3733686c7412258180ad43be048d2fe +size 11889 diff --git a/crates/egui_kittest/tests/snapshots/id_popup_1.png b/crates/egui_kittest/tests/snapshots/id_popup_1.png new file mode 100644 index 000000000..841d3b38b --- /dev/null +++ b/crates/egui_kittest/tests/snapshots/id_popup_1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43d3a9d413de27ac0ace3afead63cb54f14c53fc5098ed493cd0e3592f9ff108 +size 20901 diff --git a/crates/egui_kittest/tests/tests.rs b/crates/egui_kittest/tests/tests.rs index 81f861451..8385c4a5a 100644 --- a/crates/egui_kittest/tests/tests.rs +++ b/crates/egui_kittest/tests/tests.rs @@ -1,4 +1,4 @@ -use egui::{Modifiers, ScrollArea, Vec2, include_image}; +use egui::{include_image, Id, Modifiers, ScrollArea, Vec2}; use egui_kittest::{Harness, SnapshotResults}; use kittest::Queryable as _; @@ -182,6 +182,30 @@ fn test_masking() { harness.snapshot("test_masking"); } +#[test] +fn test_id_popup() { + let ids = [ + Id::new("parent_id").with("with_source"), + Id::new(Id::new("parent_id")).with(Id::new("with_source").with("some other thing")), + ]; + + let mut results = SnapshotResults::new(); + for (idx, id) in ids.into_iter().enumerate() { + let mut harness = Harness::builder() + .with_size(Vec2::new(300.0, 400.0)) + .build_ui(move |ui| { + id.ui(ui); + }); + + + harness.get_by_label_contains(&id.short_debug_format()).hover(); + harness.run(); + harness.fit_contents(); + + results.add(harness.try_snapshot(format!("id_popup_{}", idx))); + } +} + #[test] fn test_remove_cursor() { let hovered = false;