Skip to content

Commit aa67d31

Browse files
authored
Add Context::debug_text (#3864)
This is a very easy way to show some text under the mouse pointer: ```rs ctx.debug_text("foo"); ```
1 parent 31cc31a commit aa67d31

File tree

4 files changed

+117
-7
lines changed

4 files changed

+117
-7
lines changed

crates/egui/src/containers/popup.rs

-2
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,6 @@ pub fn popup_above_or_below_widget<R>(
351351
.fixed_pos(pos)
352352
.pivot(pivot)
353353
.show(ui.ctx(), |ui| {
354-
// Note: we use a separate clip-rect for this area, so the popup can be outside the parent.
355-
// See https://github.com/emilk/egui/issues/825
356354
let frame = Frame::popup(ui.style());
357355
let frame_margin = frame.total_margin();
358356
frame

crates/egui/src/context.rs

+89
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ impl ViewportRepaintInfo {
231231

232232
// ----------------------------------------------------------------------------
233233

234+
struct DebugText {
235+
location: String,
236+
text: WidgetText,
237+
}
238+
234239
#[derive(Default)]
235240
struct ContextImpl {
236241
/// Since we could have multiple viewport across multiple monitors with
@@ -278,6 +283,8 @@ struct ContextImpl {
278283
accesskit_node_classes: accesskit::NodeClassSet,
279284

280285
loaders: Arc<Loaders>,
286+
287+
debug_texts: Vec<DebugText>,
281288
}
282289

283290
impl ContextImpl {
@@ -1060,6 +1067,31 @@ impl Context {
10601067
Self::layer_painter(self, LayerId::debug())
10611068
}
10621069

1070+
/// Print this text next to the cursor at the end of the frame.
1071+
///
1072+
/// If you call this multiple times, the text will be appended.
1073+
///
1074+
/// This only works if compiled with `debug_assertions`.
1075+
///
1076+
/// ```
1077+
/// # let ctx = egui::Context::default();
1078+
/// # let state = true;
1079+
/// ctx.debug_text(format!("State: {state:?}"));
1080+
/// ```
1081+
#[track_caller]
1082+
pub fn debug_text(&self, text: impl Into<WidgetText>) {
1083+
if cfg!(debug_assertions) {
1084+
let location = std::panic::Location::caller();
1085+
let location = format!("{}:{}", location.file(), location.line());
1086+
self.write(|c| {
1087+
c.debug_texts.push(DebugText {
1088+
location,
1089+
text: text.into(),
1090+
});
1091+
});
1092+
}
1093+
}
1094+
10631095
/// What operating system are we running on?
10641096
///
10651097
/// When compiling natively, this is
@@ -1578,6 +1610,63 @@ impl Context {
15781610
crate::gui_zoom::zoom_with_keyboard(self);
15791611
}
15801612

1613+
let debug_texts = self.write(|ctx| std::mem::take(&mut ctx.debug_texts));
1614+
if !debug_texts.is_empty() {
1615+
// Show debug-text next to the cursor.
1616+
let mut pos = self
1617+
.input(|i| i.pointer.latest_pos())
1618+
.unwrap_or_else(|| self.screen_rect().center())
1619+
+ 8.0 * Vec2::Y;
1620+
1621+
let painter = self.debug_painter();
1622+
let where_to_put_background = painter.add(Shape::Noop);
1623+
1624+
let mut bounding_rect = Rect::from_points(&[pos]);
1625+
1626+
let color = Color32::GRAY;
1627+
let font_id = FontId::new(10.0, FontFamily::Proportional);
1628+
1629+
for DebugText { location, text } in debug_texts {
1630+
{
1631+
// Paint location to left of `pos`:
1632+
let location_galley =
1633+
self.fonts(|f| f.layout(location, font_id.clone(), color, f32::INFINITY));
1634+
let location_rect =
1635+
Align2::RIGHT_TOP.anchor_size(pos - 4.0 * Vec2::X, location_galley.size());
1636+
painter.galley(location_rect.min, location_galley, color);
1637+
bounding_rect = bounding_rect.union(location_rect);
1638+
}
1639+
1640+
{
1641+
// Paint `text` to right of `pos`:
1642+
let wrap = true;
1643+
let available_width = self.screen_rect().max.x - pos.x;
1644+
let galley = text.into_galley_impl(
1645+
self,
1646+
&self.style(),
1647+
wrap,
1648+
available_width,
1649+
font_id.clone().into(),
1650+
Align::TOP,
1651+
);
1652+
let rect = Align2::LEFT_TOP.anchor_size(pos, galley.size());
1653+
painter.galley(rect.min, galley, color);
1654+
bounding_rect = bounding_rect.union(rect);
1655+
}
1656+
1657+
pos.y = bounding_rect.max.y + 4.0;
1658+
}
1659+
1660+
painter.set(
1661+
where_to_put_background,
1662+
Shape::rect_filled(
1663+
bounding_rect.expand(4.0),
1664+
2.0,
1665+
Color32::from_black_alpha(192),
1666+
),
1667+
);
1668+
}
1669+
15811670
self.write(|ctx| ctx.end_frame())
15821671
}
15831672
}

crates/egui/src/painter.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,9 @@ impl Painter {
219219
self.debug_text(pos, Align2::LEFT_TOP, color, format!("🔥 {text}"))
220220
}
221221

222-
/// text with a background
222+
/// Text with a background.
223+
///
224+
/// See also [`Context::debug_text`].
223225
#[allow(clippy::needless_pass_by_value)]
224226
pub fn debug_text(
225227
&self,

crates/egui/src/widget_text.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -649,18 +649,39 @@ impl WidgetText {
649649
fallback_font: impl Into<FontSelection>,
650650
) -> Arc<Galley> {
651651
let wrap = wrap.unwrap_or_else(|| ui.wrap_text());
652+
let valign = ui.layout().vertical_align();
653+
let style = ui.style();
654+
655+
self.into_galley_impl(
656+
ui.ctx(),
657+
style,
658+
wrap,
659+
available_width,
660+
fallback_font.into(),
661+
valign,
662+
)
663+
}
664+
665+
pub fn into_galley_impl(
666+
self,
667+
ctx: &crate::Context,
668+
style: &Style,
669+
wrap: bool,
670+
available_width: f32,
671+
fallback_font: FontSelection,
672+
default_valign: Align,
673+
) -> Arc<Galley> {
652674
let wrap_width = if wrap { available_width } else { f32::INFINITY };
653675

654676
match self {
655677
Self::RichText(text) => {
656-
let valign = ui.layout().vertical_align();
657-
let mut layout_job = text.into_layout_job(ui.style(), fallback_font.into(), valign);
678+
let mut layout_job = text.into_layout_job(style, fallback_font, default_valign);
658679
layout_job.wrap.max_width = wrap_width;
659-
ui.fonts(|f| f.layout_job(layout_job))
680+
ctx.fonts(|f| f.layout_job(layout_job))
660681
}
661682
Self::LayoutJob(mut job) => {
662683
job.wrap.max_width = wrap_width;
663-
ui.fonts(|f| f.layout_job(job))
684+
ctx.fonts(|f| f.layout_job(job))
664685
}
665686
Self::Galley(galley) => galley,
666687
}

0 commit comments

Comments
 (0)