Add debug and debug below methods for observing the bounds of divs

Mikayla created

Change summary

crates/gpui2/src/elements/div.rs          |  7 -
crates/gpui2/src/elements/uniform_list.rs | 66 ++++++++++++------------
crates/gpui2/src/style.rs                 | 39 ++++++++++++++
crates/gpui2/src/styled.rs                | 12 ++++
4 files changed, 85 insertions(+), 39 deletions(-)

Detailed changes

crates/gpui2/src/elements/div.rs 🔗

@@ -640,10 +640,7 @@ impl Element for Div {
                 let z_index = style.z_index.unwrap_or(0);
 
                 cx.with_z_index(z_index, |cx| {
-                    cx.with_z_index(0, |cx| {
-                        style.paint(bounds, cx);
-                    });
-                    cx.with_z_index(1, |cx| {
+                    style.paint(bounds, cx, |cx| {
                         cx.with_text_style(style.text_style().cloned(), |cx| {
                             cx.with_content_mask(style.overflow_mask(bounds), |cx| {
                                 cx.with_element_offset(scroll_offset, |cx| {
@@ -653,7 +650,7 @@ impl Element for Div {
                                 })
                             })
                         })
-                    })
+                    });
                 })
             },
         );

crates/gpui2/src/elements/uniform_list.rs 🔗

@@ -197,41 +197,41 @@ impl Element for UniformList {
                 );
 
                 cx.with_z_index(style.z_index.unwrap_or(0), |cx| {
-                    style.paint(bounds, cx);
-
-                    if self.item_count > 0 {
-                        if let Some(scroll_handle) = self.scroll_handle.clone() {
-                            scroll_handle.0.borrow_mut().replace(ScrollHandleState {
-                                item_height,
-                                list_height: padded_bounds.size.height,
-                                scroll_offset: shared_scroll_offset,
+                    style.paint(bounds, cx, |cx| {
+                        if self.item_count > 0 {
+                            if let Some(scroll_handle) = self.scroll_handle.clone() {
+                                scroll_handle.0.borrow_mut().replace(ScrollHandleState {
+                                    item_height,
+                                    list_height: padded_bounds.size.height,
+                                    scroll_offset: shared_scroll_offset,
+                                });
+                            }
+
+                            let first_visible_element_ix =
+                                (-scroll_offset.y / item_height).floor() as usize;
+                            let last_visible_element_ix =
+                                ((-scroll_offset.y + padded_bounds.size.height) / item_height)
+                                    .ceil() as usize;
+                            let visible_range = first_visible_element_ix
+                                ..cmp::min(last_visible_element_ix, self.item_count);
+
+                            let items = (self.render_items)(visible_range.clone(), cx);
+                            cx.with_z_index(1, |cx| {
+                                let content_mask = ContentMask { bounds };
+                                cx.with_content_mask(Some(content_mask), |cx| {
+                                    for (item, ix) in items.into_iter().zip(visible_range) {
+                                        let item_origin = padded_bounds.origin
+                                            + point(px(0.), item_height * ix + scroll_offset.y);
+                                        let available_space = size(
+                                            AvailableSpace::Definite(padded_bounds.size.width),
+                                            AvailableSpace::Definite(item_height),
+                                        );
+                                        item.draw(item_origin, available_space, cx);
+                                    }
+                                });
                             });
                         }
-
-                        let first_visible_element_ix =
-                            (-scroll_offset.y / item_height).floor() as usize;
-                        let last_visible_element_ix =
-                            ((-scroll_offset.y + padded_bounds.size.height) / item_height).ceil()
-                                as usize;
-                        let visible_range = first_visible_element_ix
-                            ..cmp::min(last_visible_element_ix, self.item_count);
-
-                        let items = (self.render_items)(visible_range.clone(), cx);
-                        cx.with_z_index(1, |cx| {
-                            let content_mask = ContentMask { bounds };
-                            cx.with_content_mask(Some(content_mask), |cx| {
-                                for (item, ix) in items.into_iter().zip(visible_range) {
-                                    let item_origin = padded_bounds.origin
-                                        + point(px(0.), item_height * ix + scroll_offset.y);
-                                    let available_space = size(
-                                        AvailableSpace::Definite(padded_bounds.size.width),
-                                        AvailableSpace::Definite(item_height),
-                                    );
-                                    item.draw(item_origin, available_space, cx);
-                                }
-                            });
-                        });
-                    }
+                    });
                 })
             },
         );

crates/gpui2/src/style.rs 🔗

@@ -14,6 +14,9 @@ pub use taffy::style::{
     Overflow, Position,
 };
 
+#[cfg(debug_assertions)]
+pub struct DebugBelow;
+
 pub type StyleCascade = Cascade<Style>;
 
 #[derive(Clone, Refineable, Debug)]
@@ -108,6 +111,11 @@ pub struct Style {
     pub mouse_cursor: Option<CursorStyle>,
 
     pub z_index: Option<u32>,
+
+    #[cfg(debug_assertions)]
+    pub debug: bool,
+    #[cfg(debug_assertions)]
+    pub debug_below: bool,
 }
 
 impl Styled for StyleRefinement {
@@ -334,7 +342,22 @@ impl Style {
     }
 
     /// Paints the background of an element styled with this style.
-    pub fn paint(&self, bounds: Bounds<Pixels>, cx: &mut WindowContext) {
+    pub fn paint(
+        &self,
+        bounds: Bounds<Pixels>,
+        cx: &mut WindowContext,
+        continuation: impl FnOnce(&mut WindowContext),
+    ) {
+        #[cfg(debug_assertions)]
+        if self.debug_below {
+            cx.set_global(DebugBelow)
+        }
+
+        #[cfg(debug_assertions)]
+        if self.debug || cx.has_global::<DebugBelow>() {
+            cx.paint_quad(crate::outline(bounds, crate::red()));
+        }
+
         let rem_size = cx.rem_size();
 
         cx.with_z_index(0, |cx| {
@@ -357,6 +380,15 @@ impl Style {
                 ));
             });
         }
+
+        cx.with_z_index(2, |cx| {
+            continuation(cx);
+        });
+
+        #[cfg(debug_assertions)]
+        if self.debug_below {
+            cx.remove_global::<DebugBelow>();
+        }
     }
 
     fn is_border_visible(&self) -> bool {
@@ -404,6 +436,11 @@ impl Default for Style {
             text: TextStyleRefinement::default(),
             mouse_cursor: None,
             z_index: None,
+
+            #[cfg(debug_assertions)]
+            debug: false,
+            #[cfg(debug_assertions)]
+            debug_below: false,
         }
     }
 }

crates/gpui2/src/styled.rs 🔗

@@ -633,4 +633,16 @@ pub trait Styled: Sized {
             .line_height = Some(line_height.into());
         self
     }
+
+    #[cfg(debug_assertions)]
+    fn debug(mut self) -> Self {
+        self.style().debug = Some(true);
+        self
+    }
+
+    #[cfg(debug_assertions)]
+    fn debug_below(mut self) -> Self {
+        self.style().debug_below = Some(true);
+        self
+    }
 }