Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Context::debug_text #3864

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions crates/egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
89 changes: 89 additions & 0 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -278,6 +283,8 @@ struct ContextImpl {
accesskit_node_classes: accesskit::NodeClassSet,

loaders: Arc<Loaders>,

debug_texts: Vec<DebugText>,
}

impl ContextImpl {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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())
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/egui/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
29 changes: 25 additions & 4 deletions crates/egui/src/widget_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
Loading