mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 22:00:03 -04:00
Add nice Id popup
This commit is contained in:
@@ -3185,10 +3185,16 @@ impl Context {
|
|||||||
if !is_visible {
|
if !is_visible {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let text = format!("{} - {:?}", layer_id.short_debug_format(), area.rect(),);
|
|
||||||
// TODO(emilk): `Sense::hover_highlight()`
|
// TODO(emilk): `Sense::hover_highlight()`
|
||||||
let response =
|
let response = ui
|
||||||
ui.add(Label::new(RichText::new(text).monospace()).sense(Sense::click()));
|
.horizontal(|ui| {
|
||||||
|
ui.style_mut().interaction.selectable_labels = false;
|
||||||
|
ui.label(layer_id.order.short_debug_format());
|
||||||
|
layer_id.id.ui(ui);
|
||||||
|
ui.monospace(area.rect().to_string());
|
||||||
|
})
|
||||||
|
.response
|
||||||
|
.interact(Sense::click());
|
||||||
if response.hovered() && is_visible {
|
if response.hovered() && is_visible {
|
||||||
ui.ctx()
|
ui.ctx()
|
||||||
.debug_painter()
|
.debug_painter()
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
// TODO(emilk): have separate types `PositionId` and `UniqueId`. ?
|
// TODO(emilk): have separate types `PositionId` and `UniqueId`. ?
|
||||||
|
|
||||||
|
use crate::id::id_source::IdSource;
|
||||||
|
use crate::CollapsingHeader;
|
||||||
|
use epaint::Color32;
|
||||||
use std::num::NonZeroU64;
|
use std::num::NonZeroU64;
|
||||||
|
|
||||||
/// egui tracks widgets frame-to-frame using [`Id`]s.
|
/// egui tracks widgets frame-to-frame using [`Id`]s.
|
||||||
@@ -97,12 +100,133 @@ impl Id {
|
|||||||
self.value().into()
|
self.value().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Nice debug ui
|
fn source_ui(ui: &mut crate::Ui, source: IdSource) {
|
||||||
// pub fn ui(self, ui: &mut crate::Ui) -> crate::Response {
|
match source {
|
||||||
// ui.code(self.short_debug_format()).on_hover_ui(|ui| {
|
IdSource::Id(id) => {
|
||||||
// let data = self.info();
|
Self::parent_ui(ui, id);
|
||||||
// })
|
}
|
||||||
// }
|
IdSource::Other(other) => {
|
||||||
|
ui.code(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_ui(ui: &mut crate::Ui, id: Id) {
|
||||||
|
let data = id.info();
|
||||||
|
if let Some(data) = data {
|
||||||
|
if let Some(parent) = data.parent {
|
||||||
|
Self::parent_ui(ui, parent);
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.code(".with(");
|
||||||
|
Self::source_ui(ui, data.source);
|
||||||
|
ui.code(format!(" /* {} */", id.short_debug_format()));
|
||||||
|
ui.code(")");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.code("Id::new(");
|
||||||
|
Self::source_ui(ui, data.source);
|
||||||
|
ui.code(format!(" /* {} */", id.short_debug_format()));
|
||||||
|
ui.code(")");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ui.code(format!("Id::from_hash({})", id.short_debug_format()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn group_ui(ui: &mut crate::Ui, id: Id) {
|
||||||
|
ui.group(|ui| {
|
||||||
|
let info = id.info();
|
||||||
|
if let Some(info) = info {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Id(");
|
||||||
|
ui.code(format!("{:04X}", id.value() as u16));
|
||||||
|
ui.label(")");
|
||||||
|
|
||||||
|
ui.label("Source:");
|
||||||
|
match info.source {
|
||||||
|
IdSource::Id(id) => {
|
||||||
|
Self::group_ui(ui, id);
|
||||||
|
}
|
||||||
|
IdSource::Other(other) => {
|
||||||
|
ui.code(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if let Some(parent) = info.parent {
|
||||||
|
ui.label("^ with");
|
||||||
|
Self::group_ui(ui, parent);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_ui(ui: &mut crate::Ui, id: Id, prefix: &str, depth: usize) {
|
||||||
|
let info = id.info();
|
||||||
|
if let Some(info) = info {
|
||||||
|
let response =
|
||||||
|
CollapsingHeader::new(format!("{}Id({})", prefix, id.short_debug_format()))
|
||||||
|
.default_open(depth < 4)
|
||||||
|
.show(ui, |ui| {
|
||||||
|
match info.source {
|
||||||
|
IdSource::Id(id_source) => {
|
||||||
|
Self::tree_ui(ui, id_source, "Source: ", depth + 1);
|
||||||
|
}
|
||||||
|
IdSource::Other(other) => {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.add_space(ui.spacing().indent);
|
||||||
|
ui.label("Source:");
|
||||||
|
ui.code(other);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(parent) = info.parent {
|
||||||
|
Self::tree_ui(ui, parent, "Parent: ", depth + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if response.header_response.hovered() {
|
||||||
|
id.try_highlight(ui.ctx());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_highlight(self, ctx: &crate::Context) {
|
||||||
|
let response = ctx.read_response(self);
|
||||||
|
if let Some(response) = response {
|
||||||
|
ctx.debug_painter().debug_rect(
|
||||||
|
response.rect,
|
||||||
|
Color32::GREEN,
|
||||||
|
self.short_debug_format(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(area_rect) = ctx.memory(|mem| mem.area_rect(self)) {
|
||||||
|
ctx.debug_painter()
|
||||||
|
.debug_rect(area_rect, Color32::RED, self.short_debug_format());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ui(self, ui: &mut crate::Ui) -> crate::Response {
|
||||||
|
let data = self.info();
|
||||||
|
let label = if let Some(data) = &data {
|
||||||
|
format!("{} ({})", self.short_debug_format(), data.source)
|
||||||
|
} else {
|
||||||
|
self.short_debug_format()
|
||||||
|
};
|
||||||
|
let response = ui.code(label).on_hover_ui(|ui| {
|
||||||
|
Self::tree_ui(ui, self, "", 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
if response.hovered() {
|
||||||
|
self.try_highlight(ui.ctx());
|
||||||
|
}
|
||||||
|
|
||||||
|
response
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -110,6 +234,7 @@ mod id_source {
|
|||||||
use crate::{AsId, Id};
|
use crate::{AsId, Id};
|
||||||
use ahash::HashMap;
|
use ahash::HashMap;
|
||||||
use epaint::mutex::RwLock;
|
use epaint::mutex::RwLock;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
@@ -127,6 +252,19 @@ mod id_source {
|
|||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for IdSource {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
IdSource::Id(id) => {
|
||||||
|
write!(f, "{}", id.short_debug_format())
|
||||||
|
}
|
||||||
|
IdSource::Other(other) => {
|
||||||
|
write!(f, "{}", other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ID_MAP: LazyLock<RwLock<HashMap<Id, IdInfo>>> = LazyLock::new(|| {
|
static ID_MAP: LazyLock<RwLock<HashMap<Id, IdInfo>>> = LazyLock::new(|| {
|
||||||
let mut map = HashMap::default();
|
let mut map = HashMap::default();
|
||||||
map.insert(
|
map.insert(
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ impl InteractionSnapshot {
|
|||||||
|
|
||||||
fn id_ui<'a>(ui: &mut crate::Ui, widgets: impl IntoIterator<Item = &'a Id>) {
|
fn id_ui<'a>(ui: &mut crate::Ui, widgets: impl IntoIterator<Item = &'a Id>) {
|
||||||
for id in widgets {
|
for id in widgets {
|
||||||
ui.label(format!("{:?}", id));
|
id.ui(ui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#![allow(rustdoc::missing_crate_level_docs)] // it's an example
|
#![allow(rustdoc::missing_crate_level_docs)] // it's an example
|
||||||
|
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
|
use eframe::egui::{Id, Ui};
|
||||||
|
|
||||||
fn main() -> eframe::Result {
|
fn main() -> eframe::Result {
|
||||||
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
|
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
|
||||||
@@ -28,6 +29,18 @@ fn main() -> eframe::Result {
|
|||||||
age += 1;
|
age += 1;
|
||||||
}
|
}
|
||||||
ui.label(format!("Hello '{name}', age {age}"));
|
ui.label(format!("Hello '{name}', age {age}"));
|
||||||
|
|
||||||
|
Id::new(Id::new("Hi").with((123, "456")))
|
||||||
|
.with(Id::new("lol"))
|
||||||
|
.ui(ui);
|
||||||
|
|
||||||
|
ui.id().ui(ui);
|
||||||
|
Id::ui(Ui::id(ui), ui);
|
||||||
|
|
||||||
|
ui.unique_id().ui(ui);
|
||||||
|
|
||||||
|
let some_button = ui.button("Some button");
|
||||||
|
some_button.id.ui(ui);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user