Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/interactive.rs         | 10 +++-
crates/storybook2/src/stories/scroll.rs | 57 ++++++++++++++++++++------
2 files changed, 50 insertions(+), 17 deletions(-)

Detailed changes

crates/gpui3/src/interactive.rs 🔗

@@ -479,9 +479,10 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
                 let line_height = cx.line_height();
                 let scroll_max = (content_size - bounds.size).max(&Size::default());
 
-                cx.on_mouse_event(move |_, event: &ScrollWheelEvent, _, cx| {
-                    if bounds.contains_point(&event.position) {
+                cx.on_mouse_event(move |_, event: &ScrollWheelEvent, phase, cx| {
+                    if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
                         let mut scroll_offset = scroll_offset.lock();
+                        let old_scroll_offset = *scroll_offset;
                         let delta = event.delta.pixel_delta(line_height);
 
                         if overflow.x == Overflow::Scroll {
@@ -494,7 +495,10 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
                                 (scroll_offset.y - delta.y).clamp(px(0.), scroll_max.height);
                         }
 
-                        cx.notify();
+                        if *scroll_offset != old_scroll_offset {
+                            cx.notify();
+                            cx.stop_propagation();
+                        }
                     }
                 });
             }

crates/storybook2/src/stories/scroll.rs 🔗

@@ -1,5 +1,8 @@
 use crate::themes::rose_pine;
-use gpui3::{div, view, Context, ParentElement, Styled, View, WindowContext};
+use gpui3::{
+    div, px, view, Context, Element, ParentElement, SharedString, Styled, View, WindowContext,
+};
+use ui::ElementExt;
 
 pub struct ScrollStory {
     text: View<()>,
@@ -9,20 +12,46 @@ impl ScrollStory {
     pub fn view(cx: &mut WindowContext) -> View<()> {
         let theme = rose_pine();
 
-        view(cx.entity(|cx| ()), move |_, cx| {
+        view(cx.entity(|cx| ()), move |_, cx| checkerboard(1))
+    }
+}
+
+fn checkerboard<S>(depth: usize) -> impl Element<ViewState = S>
+where
+    S: 'static + Send + Sync,
+{
+    let theme = rose_pine();
+    let color_1 = theme.lowest.positive.default.background;
+    let color_2 = theme.lowest.warning.default.background;
+
+    div()
+        .id("parent")
+        .bg(theme.lowest.base.default.background)
+        .size_full()
+        .overflow_scroll()
+        .children((0..10).map(|row| {
             div()
-                .id("parent")
-                .bg(theme.lowest.base.default.background)
-                .size_full()
-                .overflow_x_scroll()
-                .child(div().w_96().flex().flex_row().children((0..3).map(|ix| {
-                    let bg = if ix % 2 == 0 {
-                        theme.middle.positive.default.background
+                .w(px(1000.))
+                .h(px(100.))
+                .flex()
+                .flex_row()
+                .children((0..10).map(|column| {
+                    let id = SharedString::from(format!("{}, {}", row, column));
+                    let bg = if row % 2 == column % 2 {
+                        color_1
                     } else {
-                        theme.middle.warning.default.background
+                        color_2
                     };
-                    div().bg(bg).flex_1().h_20()
-                })))
-        })
-    }
+                    div().id(id).bg(bg).size(px(100. / depth as f32)).when(
+                        row >= 5 && column >= 5,
+                        |d| {
+                            d.overflow_scroll()
+                                .child(div().size(px(50.)).bg(color_1))
+                                .child(div().size(px(50.)).bg(color_2))
+                                .child(div().size(px(50.)).bg(color_1))
+                                .child(div().size(px(50.)).bg(color_2))
+                        },
+                    )
+                }))
+        }))
 }