Add `Context::debug_text` (#3864)
This is a very easy way to show some text under the mouse pointer:
```rs
ctx.debug_text("foo");
```
This commit is contained in:
parent
31cc31a67b
commit
aa67d3180b
|
|
@ -351,8 +351,6 @@ pub fn popup_above_or_below_widget<R>(
|
|||
.fixed_pos(pos)
|
||||
.pivot(pivot)
|
||||
.show(ui.ctx(), |ui| {
|
||||
// Note: we use a separate clip-rect for this area, so the popup can be outside the parent.
|
||||
// See https://github.com/emilk/egui/issues/825
|
||||
let frame = Frame::popup(ui.style());
|
||||
let frame_margin = frame.total_margin();
|
||||
frame
|
||||
|
|
|
|||
|
|
@ -231,6 +231,11 @@ impl ViewportRepaintInfo {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct DebugText {
|
||||
location: String,
|
||||
text: WidgetText,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ContextImpl {
|
||||
/// Since we could have multiple viewport across multiple monitors with
|
||||
|
|
@ -278,6 +283,8 @@ struct ContextImpl {
|
|||
accesskit_node_classes: accesskit::NodeClassSet,
|
||||
|
||||
loaders: Arc<Loaders>,
|
||||
|
||||
debug_texts: Vec<DebugText>,
|
||||
}
|
||||
|
||||
impl ContextImpl {
|
||||
|
|
@ -1060,6 +1067,31 @@ impl Context {
|
|||
Self::layer_painter(self, LayerId::debug())
|
||||
}
|
||||
|
||||
/// Print this text next to the cursor at the end of the frame.
|
||||
///
|
||||
/// If you call this multiple times, the text will be appended.
|
||||
///
|
||||
/// This only works if compiled with `debug_assertions`.
|
||||
///
|
||||
/// ```
|
||||
/// # let ctx = egui::Context::default();
|
||||
/// # let state = true;
|
||||
/// ctx.debug_text(format!("State: {state:?}"));
|
||||
/// ```
|
||||
#[track_caller]
|
||||
pub fn debug_text(&self, text: impl Into<WidgetText>) {
|
||||
if cfg!(debug_assertions) {
|
||||
let location = std::panic::Location::caller();
|
||||
let location = format!("{}:{}", location.file(), location.line());
|
||||
self.write(|c| {
|
||||
c.debug_texts.push(DebugText {
|
||||
location,
|
||||
text: text.into(),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// What operating system are we running on?
|
||||
///
|
||||
/// When compiling natively, this is
|
||||
|
|
@ -1578,6 +1610,63 @@ impl Context {
|
|||
crate::gui_zoom::zoom_with_keyboard(self);
|
||||
}
|
||||
|
||||
let debug_texts = self.write(|ctx| std::mem::take(&mut ctx.debug_texts));
|
||||
if !debug_texts.is_empty() {
|
||||
// Show debug-text next to the cursor.
|
||||
let mut pos = self
|
||||
.input(|i| i.pointer.latest_pos())
|
||||
.unwrap_or_else(|| self.screen_rect().center())
|
||||
+ 8.0 * Vec2::Y;
|
||||
|
||||
let painter = self.debug_painter();
|
||||
let where_to_put_background = painter.add(Shape::Noop);
|
||||
|
||||
let mut bounding_rect = Rect::from_points(&[pos]);
|
||||
|
||||
let color = Color32::GRAY;
|
||||
let font_id = FontId::new(10.0, FontFamily::Proportional);
|
||||
|
||||
for DebugText { location, text } in debug_texts {
|
||||
{
|
||||
// Paint location to left of `pos`:
|
||||
let location_galley =
|
||||
self.fonts(|f| f.layout(location, font_id.clone(), color, f32::INFINITY));
|
||||
let location_rect =
|
||||
Align2::RIGHT_TOP.anchor_size(pos - 4.0 * Vec2::X, location_galley.size());
|
||||
painter.galley(location_rect.min, location_galley, color);
|
||||
bounding_rect = bounding_rect.union(location_rect);
|
||||
}
|
||||
|
||||
{
|
||||
// Paint `text` to right of `pos`:
|
||||
let wrap = true;
|
||||
let available_width = self.screen_rect().max.x - pos.x;
|
||||
let galley = text.into_galley_impl(
|
||||
self,
|
||||
&self.style(),
|
||||
wrap,
|
||||
available_width,
|
||||
font_id.clone().into(),
|
||||
Align::TOP,
|
||||
);
|
||||
let rect = Align2::LEFT_TOP.anchor_size(pos, galley.size());
|
||||
painter.galley(rect.min, galley, color);
|
||||
bounding_rect = bounding_rect.union(rect);
|
||||
}
|
||||
|
||||
pos.y = bounding_rect.max.y + 4.0;
|
||||
}
|
||||
|
||||
painter.set(
|
||||
where_to_put_background,
|
||||
Shape::rect_filled(
|
||||
bounding_rect.expand(4.0),
|
||||
2.0,
|
||||
Color32::from_black_alpha(192),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
self.write(|ctx| ctx.end_frame())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,9 @@ impl Painter {
|
|||
self.debug_text(pos, Align2::LEFT_TOP, color, format!("🔥 {text}"))
|
||||
}
|
||||
|
||||
/// text with a background
|
||||
/// Text with a background.
|
||||
///
|
||||
/// See also [`Context::debug_text`].
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub fn debug_text(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -649,18 +649,39 @@ impl WidgetText {
|
|||
fallback_font: impl Into<FontSelection>,
|
||||
) -> Arc<Galley> {
|
||||
let wrap = wrap.unwrap_or_else(|| ui.wrap_text());
|
||||
let valign = ui.layout().vertical_align();
|
||||
let style = ui.style();
|
||||
|
||||
self.into_galley_impl(
|
||||
ui.ctx(),
|
||||
style,
|
||||
wrap,
|
||||
available_width,
|
||||
fallback_font.into(),
|
||||
valign,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn into_galley_impl(
|
||||
self,
|
||||
ctx: &crate::Context,
|
||||
style: &Style,
|
||||
wrap: bool,
|
||||
available_width: f32,
|
||||
fallback_font: FontSelection,
|
||||
default_valign: Align,
|
||||
) -> Arc<Galley> {
|
||||
let wrap_width = if wrap { available_width } else { f32::INFINITY };
|
||||
|
||||
match self {
|
||||
Self::RichText(text) => {
|
||||
let valign = ui.layout().vertical_align();
|
||||
let mut layout_job = text.into_layout_job(ui.style(), fallback_font.into(), valign);
|
||||
let mut layout_job = text.into_layout_job(style, fallback_font, default_valign);
|
||||
layout_job.wrap.max_width = wrap_width;
|
||||
ui.fonts(|f| f.layout_job(layout_job))
|
||||
ctx.fonts(|f| f.layout_job(layout_job))
|
||||
}
|
||||
Self::LayoutJob(mut job) => {
|
||||
job.wrap.max_width = wrap_width;
|
||||
ui.fonts(|f| f.layout_job(job))
|
||||
ctx.fonts(|f| f.layout_job(job))
|
||||
}
|
||||
Self::Galley(galley) => galley,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue