Show `WidgetInfo` for each widget if `debug.show_interactive_widgets`
This was useful during debugging
This commit is contained in:
parent
aa2f87e0ff
commit
95b62ce144
|
|
@ -1202,6 +1202,19 @@ impl Context {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is called by [`Response::widget_info`], but can also be called directly.
|
||||||
|
///
|
||||||
|
/// With some debug flags it will store the widget info in [`WidgetRects`] for later display.
|
||||||
|
#[inline]
|
||||||
|
pub fn register_widget_info(&self, id: Id, make_info: impl Fn() -> crate::WidgetInfo) {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
self.write(|ctx| {
|
||||||
|
if ctx.memory.options.style.debug.show_interactive_widgets {
|
||||||
|
ctx.viewport().widgets_this_frame.set_info(id, make_info());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a full-screen painter for a new or existing layer
|
/// Get a full-screen painter for a new or existing layer
|
||||||
pub fn layer_painter(&self, layer_id: LayerId) -> Painter {
|
pub fn layer_painter(&self, layer_id: LayerId) -> Painter {
|
||||||
let screen_rect = self.screen_rect();
|
let screen_rect = self.screen_rect();
|
||||||
|
|
@ -1807,6 +1820,7 @@ impl Context {
|
||||||
self.write(|ctx| ctx.end_frame())
|
self.write(|ctx| ctx.end_frame())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called at the end of the frame.
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
fn debug_painting(&self) {
|
fn debug_painting(&self) {
|
||||||
let paint_widget = |widget: &WidgetRect, text: &str, color: Color32| {
|
let paint_widget = |widget: &WidgetRect, text: &str, color: Color32| {
|
||||||
|
|
@ -1839,8 +1853,8 @@ impl Context {
|
||||||
} else if rect.sense.drag {
|
} else if rect.sense.drag {
|
||||||
(Color32::from_rgb(0, 0, 0x88), "drag")
|
(Color32::from_rgb(0, 0, 0x88), "drag")
|
||||||
} else {
|
} else {
|
||||||
continue;
|
// unreachable since we only show interactive
|
||||||
// (Color32::from_rgb(0, 0, 0x88), "hover")
|
(Color32::from_rgb(0, 0, 0x88), "hover")
|
||||||
};
|
};
|
||||||
painter.debug_rect(rect.interact_rect, color, text);
|
painter.debug_rect(rect.interact_rect, color, text);
|
||||||
}
|
}
|
||||||
|
|
@ -1860,10 +1874,32 @@ impl Context {
|
||||||
hovered,
|
hovered,
|
||||||
} = interact_widgets;
|
} = interact_widgets;
|
||||||
|
|
||||||
if false {
|
if true {
|
||||||
for widget in contains_pointer {
|
for &id in &contains_pointer {
|
||||||
paint_widget_id(widget, "contains_pointer", Color32::BLUE);
|
paint_widget_id(id, "contains_pointer", Color32::BLUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let widget_rects = self.write(|w| w.viewport().widgets_this_frame.clone());
|
||||||
|
|
||||||
|
let mut contains_pointer: Vec<Id> = contains_pointer.iter().copied().collect();
|
||||||
|
contains_pointer.sort_by_key(|&id| {
|
||||||
|
widget_rects
|
||||||
|
.order(id)
|
||||||
|
.map(|(layer_id, order_in_layer)| (layer_id.order, order_in_layer))
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut debug_text = "Widgets in order:\n".to_owned();
|
||||||
|
for id in contains_pointer {
|
||||||
|
let mut widget_text = format!("{id:?}");
|
||||||
|
if let Some(rect) = widget_rects.get(id) {
|
||||||
|
widget_text += &format!(" {:?} {:?}", rect.rect, rect.sense);
|
||||||
|
}
|
||||||
|
if let Some(info) = widget_rects.info(id) {
|
||||||
|
widget_text += &format!(" {info:?}");
|
||||||
|
}
|
||||||
|
debug_text += &format!("{widget_text}\n");
|
||||||
|
}
|
||||||
|
self.debug_text(debug_text);
|
||||||
}
|
}
|
||||||
if true {
|
if true {
|
||||||
for widget in hovered {
|
for widget in hovered {
|
||||||
|
|
@ -1887,7 +1923,7 @@ impl Context {
|
||||||
drag,
|
drag,
|
||||||
} = hits;
|
} = hits;
|
||||||
|
|
||||||
if false {
|
if true {
|
||||||
for widget in &contains_pointer {
|
for widget in &contains_pointer {
|
||||||
paint_widget(widget, "contains_pointer", Color32::BLUE);
|
paint_widget(widget, "contains_pointer", Color32::BLUE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -745,6 +745,7 @@ impl Response {
|
||||||
/// Call after interacting and potential calls to [`Self::mark_changed`].
|
/// Call after interacting and potential calls to [`Self::mark_changed`].
|
||||||
pub fn widget_info(&self, make_info: impl Fn() -> crate::WidgetInfo) {
|
pub fn widget_info(&self, make_info: impl Fn() -> crate::WidgetInfo) {
|
||||||
use crate::output::OutputEvent;
|
use crate::output::OutputEvent;
|
||||||
|
|
||||||
let event = if self.clicked() {
|
let event = if self.clicked() {
|
||||||
Some(OutputEvent::Clicked(make_info()))
|
Some(OutputEvent::Clicked(make_info()))
|
||||||
} else if self.double_clicked() {
|
} else if self.double_clicked() {
|
||||||
|
|
@ -758,6 +759,7 @@ impl Response {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(event) = event {
|
if let Some(event) = event {
|
||||||
self.output_event(event);
|
self.output_event(event);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -765,6 +767,8 @@ impl Response {
|
||||||
self.ctx.accesskit_node_builder(self.id, |builder| {
|
self.ctx.accesskit_node_builder(self.id, |builder| {
|
||||||
self.fill_accesskit_node_from_widget_info(builder, make_info());
|
self.fill_accesskit_node_from_widget_info(builder, make_info());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.ctx.register_widget_info(self.id, make_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -773,6 +777,10 @@ impl Response {
|
||||||
self.ctx.accesskit_node_builder(self.id, |builder| {
|
self.ctx.accesskit_node_builder(self.id, |builder| {
|
||||||
self.fill_accesskit_node_from_widget_info(builder, event.widget_info().clone());
|
self.fill_accesskit_node_from_widget_info(builder, event.widget_info().clone());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.ctx
|
||||||
|
.register_widget_info(self.id, || event.widget_info().clone());
|
||||||
|
|
||||||
self.ctx.output_mut(|o| o.events.push(event));
|
self.ctx.output_mut(|o| o.events.push(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,25 @@ pub struct WidgetRect {
|
||||||
///
|
///
|
||||||
/// All [`Ui`]s have a [`WidgetRects`], but whether or not their rects are correct
|
/// All [`Ui`]s have a [`WidgetRects`], but whether or not their rects are correct
|
||||||
/// depends on if [`Ui::interact_bg`] was ever called.
|
/// depends on if [`Ui::interact_bg`] was ever called.
|
||||||
#[derive(Default, Clone, PartialEq, Eq)]
|
#[derive(Default, Clone)]
|
||||||
pub struct WidgetRects {
|
pub struct WidgetRects {
|
||||||
/// All widgets, in painting order.
|
/// All widgets, in painting order.
|
||||||
by_layer: HashMap<LayerId, Vec<WidgetRect>>,
|
by_layer: HashMap<LayerId, Vec<WidgetRect>>,
|
||||||
|
|
||||||
/// All widgets, by id, and their order in their respective layer
|
/// All widgets, by id, and their order in their respective layer
|
||||||
by_id: IdMap<(usize, WidgetRect)>,
|
by_id: IdMap<(usize, WidgetRect)>,
|
||||||
|
|
||||||
|
/// Info about some widgets.
|
||||||
|
///
|
||||||
|
/// Only filled in if the widget is interacted with,
|
||||||
|
/// or if this is a debug build.
|
||||||
|
infos: IdMap<WidgetInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for WidgetRects {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.by_layer == other.by_layer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetRects {
|
impl WidgetRects {
|
||||||
|
|
@ -90,18 +102,28 @@ impl WidgetRects {
|
||||||
|
|
||||||
/// Clear the contents while retaining allocated memory.
|
/// Clear the contents while retaining allocated memory.
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
let Self { by_layer, by_id } = self;
|
let Self {
|
||||||
|
by_layer,
|
||||||
|
by_id,
|
||||||
|
infos,
|
||||||
|
} = self;
|
||||||
|
|
||||||
for rects in by_layer.values_mut() {
|
for rects in by_layer.values_mut() {
|
||||||
rects.clear();
|
rects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
by_id.clear();
|
by_id.clear();
|
||||||
|
|
||||||
|
infos.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert the given widget rect in the given layer.
|
/// Insert the given widget rect in the given layer.
|
||||||
pub fn insert(&mut self, layer_id: LayerId, widget_rect: WidgetRect) {
|
pub fn insert(&mut self, layer_id: LayerId, widget_rect: WidgetRect) {
|
||||||
let Self { by_layer, by_id } = self;
|
let Self {
|
||||||
|
by_layer,
|
||||||
|
by_id,
|
||||||
|
infos: _,
|
||||||
|
} = self;
|
||||||
|
|
||||||
let layer_widgets = by_layer.entry(layer_id).or_default();
|
let layer_widgets = by_layer.entry(layer_id).or_default();
|
||||||
|
|
||||||
|
|
@ -134,4 +156,12 @@ impl WidgetRects {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_info(&mut self, id: Id, info: WidgetInfo) {
|
||||||
|
self.infos.insert(id, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn info(&self, id: Id) -> Option<&WidgetInfo> {
|
||||||
|
self.infos.get(&id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue