From 46471f930d63ebea772c9e8d8dcdfb26b26cfaf5 Mon Sep 17 00:00:00 2001 From: lucaspoffo <35241085+lucaspoffo@users.noreply.github.com> Date: Tue, 29 Dec 2020 08:24:57 -0300 Subject: [PATCH] Fix nested scrolling (#83) Add scroll_delta in FrameState to fix nested scrolling. Co-authored-by: Emil Ernerfeldt --- egui/src/containers/scroll_area.rs | 16 +++++++++++++--- egui/src/context.rs | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/egui/src/containers/scroll_area.rs b/egui/src/containers/scroll_area.rs index 0fce2c4d1..461d8571c 100644 --- a/egui/src/containers/scroll_area.rs +++ b/egui/src/containers/scroll_area.rs @@ -230,9 +230,19 @@ impl Prepared { } } - // TODO: check that nothing else is being interacted with + let max_offset = content_size.y - inner_rect.height(); if ui.rect_contains_mouse(outer_rect) { - state.offset.y -= ui.input().scroll_delta.y; + let mut frame_state = ui.ctx().frame_state(); + let scroll_delta = frame_state.scroll_delta; + + let scrolling_up = state.offset.y > 0.0 && scroll_delta.y > 0.0; + let scrolling_down = state.offset.y < max_offset && scroll_delta.y < 0.0; + + if scrolling_up || scrolling_down { + state.offset.y -= scroll_delta.y; + // Clear scroll delta so no parent scroll will use it. + frame_state.scroll_delta = Vec2::zero(); + } } let show_scroll_this_frame = content_is_too_small || always_show_scroll; @@ -286,7 +296,7 @@ impl Prepared { } state.offset.y = state.offset.y.max(0.0); - state.offset.y = state.offset.y.min(content_size.y - inner_rect.height()); + state.offset.y = state.offset.y.min(max_offset); // Avoid frame-delay by calculating a new handle rect: let mut handle_rect = Rect::from_min_max( diff --git a/egui/src/context.rs b/egui/src/context.rs index a094e04ce..824193aef 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -38,6 +38,7 @@ pub(crate) struct FrameState { /// How much space is used by panels. used_by_panels: Rect, + pub(crate) scroll_delta: Vec2, pub(crate) scroll_target: Option<(f32, Align)>, // TODO: move some things from `Memory` to here } @@ -48,6 +49,7 @@ impl Default for FrameState { available_rect: Rect::invalid(), unused_rect: Rect::invalid(), used_by_panels: Rect::invalid(), + scroll_delta: Vec2::zero(), scroll_target: None, } } @@ -58,6 +60,7 @@ impl FrameState { self.available_rect = input.screen_rect(); self.unused_rect = input.screen_rect(); self.used_by_panels = Rect::nothing(); + self.scroll_delta = input.scroll_delta; self.scroll_target = None; }