Add Visuals::debug_widgets to debug layouting by hovering widgets

This commit is contained in:
Emil Ernerfeldt 2021-03-21 10:33:10 +01:00
parent ec9f374d8c
commit e232264b53
4 changed files with 59 additions and 17 deletions

View file

@ -689,7 +689,8 @@ impl Layout {
) {
use epaint::*;
let cursor = self.next_widget_position(region);
let cursor = region.cursor;
let next_pos = self.next_widget_position(region);
let align;
@ -697,23 +698,33 @@ impl Layout {
match self.main_dir {
Direction::LeftToRight => {
painter.arrow(cursor, vec2(l, 0.0), stroke);
align = Align2::LEFT_TOP;
painter.line_segment([cursor.left_top(), cursor.left_bottom()], stroke);
painter.arrow(next_pos, vec2(l, 0.0), stroke);
align = Align2([Align::LEFT, self.vertical_align()]);
}
Direction::RightToLeft => {
painter.arrow(cursor, vec2(-l, 0.0), stroke);
align = Align2::RIGHT_TOP;
painter.line_segment([cursor.right_top(), cursor.right_bottom()], stroke);
painter.arrow(next_pos, vec2(-l, 0.0), stroke);
align = Align2([Align::RIGHT, self.vertical_align()]);
}
Direction::TopDown => {
painter.arrow(cursor, vec2(0.0, l), stroke);
align = Align2::LEFT_TOP;
painter.line_segment([cursor.left_top(), cursor.right_top()], stroke);
painter.arrow(next_pos, vec2(0.0, l), stroke);
align = Align2([self.horizontal_align(), Align::TOP]);
}
Direction::BottomUp => {
painter.arrow(cursor, vec2(0.0, -l), stroke);
align = Align2::LEFT_BOTTOM;
painter.line_segment([cursor.left_bottom(), cursor.right_bottom()], stroke);
painter.arrow(next_pos, vec2(0.0, -l), stroke);
align = Align2([self.horizontal_align(), Align::BOTTOM]);
}
}
painter.text(cursor, align, "cursor", TextStyle::Monospace, stroke.color);
painter.text(
next_pos,
align,
"cursor",
TextStyle::Monospace,
Color32::WHITE,
);
}
}

View file

@ -164,6 +164,7 @@ impl Placer {
item_spacing,
)
}
self.region.expand_to_include_rect(frame_rect); // e.g. for centered layouts: pretend we used whole frame
}
@ -233,7 +234,7 @@ impl Placer {
impl Placer {
pub(crate) fn debug_paint_cursor(&self, painter: &crate::Painter) {
let color = Color32::GREEN;
let color = Color32::GREEN.linear_multiply(0.5);
let stroke = Stroke::new(2.0, color);
if let Some(grid) = &self.grid {

View file

@ -181,6 +181,8 @@ pub struct Visuals {
// -----------------------------------------------
// Debug rendering:
/// however over widgets to see their rectangles
pub debug_widgets: bool,
/// Show which widgets make their parent wider
pub debug_expand_width: bool,
/// Show which widgets make their parent higher
@ -340,6 +342,7 @@ impl Visuals {
text_cursor_width: 2.0,
text_cursor_preview: false,
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
debug_widgets: false,
debug_expand_width: false,
debug_expand_height: false,
debug_resize: false,
@ -652,6 +655,7 @@ impl Visuals {
text_cursor_width,
text_cursor_preview,
clip_rect_margin,
debug_widgets,
debug_expand_width,
debug_expand_height,
debug_resize,
@ -684,6 +688,7 @@ impl Visuals {
ui.group(|ui| {
ui.label("DEBUG:");
ui.checkbox(debug_widgets, "Show widget bounds on hover");
ui.checkbox(
debug_expand_width,
"Show which widgets make their parent wider",

View file

@ -599,6 +599,12 @@ impl Ui {
let rect = self.allocate_space_impl(desired_size);
if self.visuals().debug_widgets && self.rect_contains_pointer(rect) {
let painter = self.ctx().debug_painter();
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
self.placer.debug_paint_cursor(&painter);
}
let debug_expand_width = self.visuals().debug_expand_width;
let debug_expand_height = self.visuals().debug_expand_height;
@ -649,7 +655,7 @@ impl Ui {
///
/// Ignore the layout of the `Ui: just put my widget here!
/// The layout cursor will advance to past this `rect`.
pub(crate) fn allocate_rect(&mut self, rect: Rect, sense: Sense) -> Response {
pub fn allocate_rect(&mut self, rect: Rect, sense: Sense) -> Response {
let id = self.advance_cursor_after_rect(rect);
self.interact(rect, id, sense)
}
@ -658,6 +664,12 @@ impl Ui {
let item_spacing = self.spacing().item_spacing;
self.placer.advance_after_rects(rect, rect, item_spacing);
if self.visuals().debug_widgets && self.rect_contains_pointer(rect) {
let painter = self.ctx().debug_painter();
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
self.placer.debug_paint_cursor(&painter);
}
self.next_auto_id = self.next_auto_id.wrapping_add(1);
Id::new(self.next_auto_id)
}
@ -684,6 +696,7 @@ impl Ui {
desired_size: Vec2,
add_contents: impl FnOnce(&mut Self) -> R,
) -> InnerResponse<R> {
debug_assert!(desired_size.x >= 0.0 && desired_size.y >= 0.0);
let item_spacing = self.spacing().item_spacing;
let frame_rect = self.placer.next_space(desired_size, item_spacing);
let child_rect = self.placer.justify_and_align(frame_rect, desired_size);
@ -692,11 +705,16 @@ impl Ui {
let ret = add_contents(&mut child_ui);
let final_child_rect = child_ui.min_rect();
self.placer.advance_after_rects(
frame_rect.union(final_child_rect),
final_child_rect,
item_spacing,
);
let final_frame = frame_rect.union(final_child_rect);
self.placer
.advance_after_rects(final_frame, final_child_rect, item_spacing);
if self.visuals().debug_widgets && self.rect_contains_pointer(final_frame) {
let painter = self.ctx().debug_painter();
painter.rect_stroke(frame_rect, 4.0, (1.0, Color32::LIGHT_BLUE));
painter.rect_stroke(final_child_rect, 4.0, (1.0, Color32::LIGHT_BLUE));
self.placer.debug_paint_cursor(&painter);
}
let response = self.interact(final_child_rect, child_ui.id, Sense::hover());
InnerResponse::new(ret, response)
@ -1324,6 +1342,13 @@ impl Ui {
let rect = child_ui.min_rect();
let item_spacing = self.spacing().item_spacing;
self.placer.advance_after_rects(rect, rect, item_spacing);
if self.visuals().debug_widgets && self.rect_contains_pointer(rect) {
let painter = self.ctx().debug_painter();
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
self.placer.debug_paint_cursor(&painter);
}
InnerResponse::new(inner, self.interact(rect, child_ui.id, Sense::hover()))
}