diff --git a/crates/egui/src/containers/panel.rs b/crates/egui/src/containers/panel.rs index 9b74da3a..a94f7b21 100644 --- a/crates/egui/src/containers/panel.rs +++ b/crates/egui/src/containers/panel.rs @@ -215,6 +215,7 @@ impl SidePanel { } width = clamp_to_range(width, width_range.clone()).at_most(available_rect.width()); side.set_rect_width(&mut panel_rect, width); + ui.ctx().check_for_id_clash(id, panel_rect, "SidePanel"); } let mut resize_hover = false; @@ -642,6 +643,8 @@ impl TopBottomPanel { }; height = clamp_to_range(height, height_range.clone()).at_most(available_rect.height()); side.set_rect_height(&mut panel_rect, height); + ui.ctx() + .check_for_id_clash(id, panel_rect, "TopBottomPanel"); } let mut resize_hover = false; diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 8449ca30..6a2fed5b 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -279,16 +279,45 @@ impl Context { return; } - let show_error = |pos: Pos2, text: String| { + let show_error = |widget_rect: Rect, text: String| { + let text = format!("🔥 {}", text); + let color = self.style().visuals.error_fg_color; let painter = self.debug_painter(); - let rect = painter.error(pos, text); + painter.rect_stroke(widget_rect, 0.0, (1.0, color)); + + let below = widget_rect.bottom() + 32.0 < self.input().screen_rect.bottom(); + + let text_rect = if below { + painter.debug_text( + widget_rect.left_bottom() + vec2(0.0, 2.0), + Align2::LEFT_TOP, + color, + text, + ) + } else { + painter.debug_text( + widget_rect.left_top() - vec2(0.0, 2.0), + Align2::LEFT_BOTTOM, + color, + text, + ) + }; + if let Some(pointer_pos) = self.pointer_hover_pos() { - if rect.contains(pointer_pos) { + if text_rect.contains(pointer_pos) { + let tooltip_pos = if below { + text_rect.left_bottom() + vec2(2.0, 4.0) + } else { + text_rect.left_top() + vec2(2.0, -4.0) + }; + painter.error( - rect.left_bottom() + vec2(2.0, 4.0), - "ID clashes happens when things like Windows or CollapsingHeaders share names,\n\ + tooltip_pos, + format!("Widget is {} this text.\n\n\ + ID clashes happens when things like Windows or CollapsingHeaders share names,\n\ or when things like Plot and Grid:s aren't given unique id_source:s.\n\n\ Sometimes the solution is to use ui.push_id.", + if below { "above" } else { "below" }) ); } } @@ -297,19 +326,10 @@ impl Context { let id_str = id.short_debug_format(); if prev_rect.min.distance(new_rect.min) < 4.0 { - show_error( - new_rect.min, - format!("Double use of {} ID {}", what, id_str), - ); + show_error(new_rect, format!("Double use of {} ID {}", what, id_str)); } else { - show_error( - prev_rect.min, - format!("First use of {} ID {}", what, id_str), - ); - show_error( - new_rect.min, - format!("Second use of {} ID {}", what, id_str), - ); + show_error(prev_rect, format!("First use of {} ID {}", what, id_str)); + show_error(new_rect, format!("Second use of {} ID {}", what, id_str)); } } } diff --git a/crates/egui/src/painter.rs b/crates/egui/src/painter.rs index 13cb6046..76a6d669 100644 --- a/crates/egui/src/painter.rs +++ b/crates/egui/src/painter.rs @@ -243,7 +243,7 @@ impl Painter { self.add(Shape::rect_filled( frame_rect, 0.0, - Color32::from_black_alpha(240), + Color32::from_black_alpha(150), )); self.galley(rect.min, galley); frame_rect