1use crate::*;
9
10pub(crate) fn register(ctx: &Context) {
17 ctx.on_end_frame("debug_text", std::sync::Arc::new(State::end_frame));
18}
19
20#[track_caller]
32pub fn print(ctx: &Context, text: impl Into<WidgetText>) {
33 if !cfg!(debug_assertions) {
34 return;
35 }
36
37 let location = std::panic::Location::caller();
38 let location = format!("{}:{}", location.file(), location.line());
39 ctx.data_mut(|data| {
40 let state = data.get_temp_mut_or_default::<State>(Id::NULL);
44 state.entries.push(Entry {
45 location,
46 text: text.into(),
47 });
48 });
49}
50
51#[derive(Clone)]
52struct Entry {
53 location: String,
54 text: WidgetText,
55}
56
57#[derive(Clone, Default)]
61struct State {
62 entries: Vec<Entry>,
64}
65
66impl State {
67 fn end_frame(ctx: &Context) {
68 let state = ctx.data_mut(|data| data.remove_temp::<Self>(Id::NULL));
69 if let Some(state) = state {
70 state.paint(ctx);
71 }
72 }
73
74 fn paint(self, ctx: &Context) {
75 let Self { entries } = self;
76
77 if entries.is_empty() {
78 return;
79 }
80
81 let mut pos = ctx
83 .input(|i| i.pointer.latest_pos())
84 .unwrap_or_else(|| ctx.screen_rect().center())
85 + 8.0 * Vec2::Y;
86
87 let painter = ctx.debug_painter();
88 let where_to_put_background = painter.add(Shape::Noop);
89
90 let mut bounding_rect = Rect::from_points(&[pos]);
91
92 let color = Color32::GRAY;
93 let font_id = FontId::new(10.0, FontFamily::Proportional);
94
95 for Entry { location, text } in entries {
96 {
97 let location_galley =
99 ctx.fonts(|f| f.layout(location, font_id.clone(), color, f32::INFINITY));
100 let location_rect =
101 Align2::RIGHT_TOP.anchor_size(pos - 4.0 * Vec2::X, location_galley.size());
102 painter.galley(location_rect.min, location_galley, color);
103 bounding_rect = bounding_rect.union(location_rect);
104 }
105
106 {
107 let available_width = ctx.screen_rect().max.x - pos.x;
109 let galley = text.into_galley_impl(
110 ctx,
111 &ctx.style(),
112 text::TextWrapping::wrap_at_width(available_width),
113 font_id.clone().into(),
114 Align::TOP,
115 );
116 let rect = Align2::LEFT_TOP.anchor_size(pos, galley.size());
117 painter.galley(rect.min, galley, color);
118 bounding_rect = bounding_rect.union(rect);
119 }
120
121 pos.y = bounding_rect.max.y + 4.0;
122 }
123
124 painter.set(
125 where_to_put_background,
126 Shape::rect_filled(
127 bounding_rect.expand(4.0),
128 2.0,
129 Color32::from_black_alpha(192),
130 ),
131 );
132 }
133}