From ca7ebb6c730151e75d1f354b7cadaa72e8d7c441 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Mon, 1 Apr 2024 22:36:21 +0200 Subject: [PATCH 1/7] Fix scroll_with_delta only scrolling if the ScrollArea is focussed --- crates/egui/src/containers/scroll_area.rs | 4 +++- crates/egui/src/input_state.rs | 10 ++++++++++ crates/egui/src/ui.rs | 6 ++++-- crates/egui_demo_lib/src/demo/scrolling.rs | 8 ++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index c448269fb0c..f06d57d1c73 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -870,7 +870,8 @@ impl Prepared { let max_offset = content_size - inner_rect.size(); let is_hovering_outer_rect = ui.rect_contains_pointer(outer_rect); - if scrolling_enabled && is_hovering_outer_rect { + let force_current_scroll_area = ui.input(|i| i.force_current_scroll_area); + if scrolling_enabled && is_hovering_outer_rect || force_current_scroll_area { let always_scroll_enabled_direction = ui.style().always_scroll_the_only_direction && scroll_enabled[0] != scroll_enabled[1]; for d in 0..2 { @@ -898,6 +899,7 @@ impl Prepared { } else { input.smooth_scroll_delta[d] = 0.0; } + input.force_current_scroll_area = false; }); state.scroll_stuck_to_end[d] = false; diff --git a/crates/egui/src/input_state.rs b/crates/egui/src/input_state.rs index 9c6103e0a54..ff6a1165e31 100644 --- a/crates/egui/src/input_state.rs +++ b/crates/egui/src/input_state.rs @@ -70,6 +70,10 @@ pub struct InputState { /// at the end of the frame this will be zero if a scroll-area consumed the delta. pub smooth_scroll_delta: Vec2, + /// Force the current scroll area to consume the [Self::smooth_scroll_delta], independent of the focus / mouse position. + /// This is used when using [crate::Ui::scroll_with_delta] to scroll the current scroll area. + pub(crate) force_current_scroll_area: bool, + /// Zoom scale factor this frame (e.g. from ctrl-scroll or pinch gesture). /// /// * `zoom = 1`: no change. @@ -154,6 +158,7 @@ impl Default for InputState { unprocessed_scroll_delta: Vec2::ZERO, raw_scroll_delta: Vec2::ZERO, smooth_scroll_delta: Vec2::ZERO, + force_current_scroll_area: false, zoom_factor_delta: 1.0, screen_rect: Rect::from_min_size(Default::default(), vec2(10_000.0, 10_000.0)), pixels_per_point: 1.0, @@ -255,6 +260,7 @@ impl InputState { unprocessed_scroll_delta, raw_scroll_delta, smooth_scroll_delta, + force_current_scroll_area: false, zoom_factor_delta, screen_rect, pixels_per_point, @@ -1113,6 +1119,7 @@ impl InputState { unprocessed_scroll_delta, raw_scroll_delta, smooth_scroll_delta, + force_current_scroll_area, zoom_factor_delta, screen_rect, @@ -1157,6 +1164,9 @@ impl InputState { ui.label(format!( "smooth_scroll_delta: {smooth_scroll_delta:?} points" )); + ui.label(format!( + "force_current_scroll_area: {force_current_scroll_area}" + )); ui.label(format!("zoom_factor_delta: {zoom_factor_delta:4.2}x")); ui.label(format!("screen_rect: {screen_rect:?} points")); ui.label(format!( diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index 9ff05a267e8..ac14cfe3aa1 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1091,8 +1091,10 @@ impl Ui { /// # }); /// ``` pub fn scroll_with_delta(&self, delta: Vec2) { - self.ctx() - .input_mut(|input| input.smooth_scroll_delta += delta); + self.ctx().input_mut(|input| { + input.smooth_scroll_delta += delta; + input.force_current_scroll_area = true; + }); } } diff --git a/crates/egui_demo_lib/src/demo/scrolling.rs b/crates/egui_demo_lib/src/demo/scrolling.rs index 9c490d23d8a..d7bee754c5b 100644 --- a/crates/egui_demo_lib/src/demo/scrolling.rs +++ b/crates/egui_demo_lib/src/demo/scrolling.rs @@ -258,6 +258,7 @@ impl super::View for ScrollTo { let mut go_to_scroll_offset = false; let mut scroll_top = false; let mut scroll_bottom = false; + let mut scroll_delta = None; ui.horizontal(|ui| { ui.label("Scroll to a specific item index:"); @@ -292,6 +293,9 @@ impl super::View for ScrollTo { ui.horizontal(|ui| { scroll_top |= ui.button("Scroll to top").clicked(); scroll_bottom |= ui.button("Scroll to bottom").clicked(); + if ui.button("Scroll down by 64px").clicked() { + scroll_delta = Some(Vec2::new(0.0, -64.0)); + } }); let mut scroll_area = ScrollArea::vertical().max_height(200.0).auto_shrink(false); @@ -305,6 +309,10 @@ impl super::View for ScrollTo { if scroll_top { ui.scroll_to_cursor(Some(Align::TOP)); } + if let Some(scroll_delta) = scroll_delta { + ui.scroll_with_delta(scroll_delta); + } + ui.vertical(|ui| { for item in 1..=num_items { if track_item && item == self.track_item { From 5c4c1910845fc1a7622dda0a99bf13b7d1fc3487 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Tue, 2 Apr 2024 13:11:38 +0200 Subject: [PATCH 2/7] Add scroll_delta to FrameState --- crates/egui/src/containers/scroll_area.rs | 63 +++++++++++----------- crates/egui/src/frame_state.rs | 8 ++- crates/egui/src/input_state.rs | 10 ---- crates/egui/src/ui.rs | 5 +- crates/egui_demo_lib/src/demo/scrolling.rs | 2 +- 5 files changed, 43 insertions(+), 45 deletions(-) diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index f06d57d1c73..b3a4e6b9f64 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -785,12 +785,12 @@ impl Prepared { for d in 0..2 { // We always take both scroll targets regardless of which scroll axes are enabled. This // is to avoid them leaking to other scroll areas. - let scroll_target = content_ui - .ctx() - .frame_state_mut(|state| state.scroll_target[d].take()); + let (scroll_target, scroll_delta) = content_ui.ctx().frame_state_mut(|state| { + (state.scroll_target[d].take(), state.scroll_delta[d].take()) + }); if scroll_enabled[d] { - if let Some((target_range, align)) = scroll_target { + let mut delta = if let Some((target_range, align)) = scroll_target { let min = content_ui.min_rect().min[d]; let clip_rect = content_ui.clip_rect(); let visible_range = min..=min + clip_rect.size()[d]; @@ -799,7 +799,7 @@ impl Prepared { let clip_end = clip_rect.max[d]; let mut spacing = ui.spacing().item_spacing[d]; - let delta = if let Some(align) = align { + if let Some(align) = align { let center_factor = align.to_factor(); let offset = @@ -816,31 +816,36 @@ impl Prepared { } else { // Ui is already in view, no need to adjust scroll. 0.0 - }; + } + } else { + 0.0 + }; - if delta != 0.0 { - let target_offset = state.offset[d] + delta; + if let Some(scroll_delta) = scroll_delta { + delta += scroll_delta; + } - if !animated { - state.offset[d] = target_offset; - } else if let Some(animation) = &mut state.offset_target[d] { - // For instance: the user is continuously calling `ui.scroll_to_cursor`, - // so we don't want to reset the animation, but perhaps update the target: - animation.target_offset = target_offset; - } else { - // The further we scroll, the more time we take. - // TODO(emilk): let users configure this in `Style`. - let now = ui.input(|i| i.time); - let points_per_second = 1000.0; - let animation_duration = - (delta.abs() / points_per_second).clamp(0.1, 0.3); - state.offset_target[d] = Some(ScrollTarget { - animation_time_span: (now, now + animation_duration as f64), - target_offset, - }); - } - ui.ctx().request_repaint(); + if delta != 0.0 { + let target_offset = state.offset[d] + delta; + + if !animated { + state.offset[d] = target_offset; + } else if let Some(animation) = &mut state.offset_target[d] { + // For instance: the user is continuously calling `ui.scroll_to_cursor`, + // so we don't want to reset the animation, but perhaps update the target: + animation.target_offset = target_offset; + } else { + // The further we scroll, the more time we take. + // TODO(emilk): let users configure this in `Style`. + let now = ui.input(|i| i.time); + let points_per_second = 1000.0; + let animation_duration = (delta.abs() / points_per_second).clamp(0.1, 0.3); + state.offset_target[d] = Some(ScrollTarget { + animation_time_span: (now, now + animation_duration as f64), + target_offset, + }); } + ui.ctx().request_repaint(); } } } @@ -870,8 +875,7 @@ impl Prepared { let max_offset = content_size - inner_rect.size(); let is_hovering_outer_rect = ui.rect_contains_pointer(outer_rect); - let force_current_scroll_area = ui.input(|i| i.force_current_scroll_area); - if scrolling_enabled && is_hovering_outer_rect || force_current_scroll_area { + if scrolling_enabled && is_hovering_outer_rect { let always_scroll_enabled_direction = ui.style().always_scroll_the_only_direction && scroll_enabled[0] != scroll_enabled[1]; for d in 0..2 { @@ -899,7 +903,6 @@ impl Prepared { } else { input.smooth_scroll_delta[d] = 0.0; } - input.force_current_scroll_area = false; }); state.scroll_stuck_to_end[d] = false; diff --git a/crates/egui/src/frame_state.rs b/crates/egui/src/frame_state.rs index 87074c2a725..fb6d785025f 100644 --- a/crates/egui/src/frame_state.rs +++ b/crates/egui/src/frame_state.rs @@ -38,9 +38,12 @@ pub(crate) struct FrameState { /// Initialized to `None` at the start of each frame. pub(crate) tooltip_state: Option, - /// horizontal, vertical + /// The current scroll area should scroll to this range (horizontal, vertical). pub(crate) scroll_target: [Option<(Rangef, Option)>; 2], + /// The current scroll area should scroll by this much (horizontal, vertical). + pub(crate) scroll_delta: [Option; 2], + #[cfg(feature = "accesskit")] pub(crate) accesskit_state: Option, @@ -63,6 +66,7 @@ impl Default for FrameState { used_by_panels: Rect::NAN, tooltip_state: None, scroll_target: [None, None], + scroll_delta: [None, None], #[cfg(feature = "accesskit")] accesskit_state: None, highlight_this_frame: Default::default(), @@ -84,6 +88,7 @@ impl FrameState { used_by_panels, tooltip_state, scroll_target, + scroll_delta, #[cfg(feature = "accesskit")] accesskit_state, highlight_this_frame, @@ -99,6 +104,7 @@ impl FrameState { *used_by_panels = Rect::NOTHING; *tooltip_state = None; *scroll_target = [None, None]; + *scroll_delta = [None, None]; #[cfg(debug_assertions)] { diff --git a/crates/egui/src/input_state.rs b/crates/egui/src/input_state.rs index ff6a1165e31..9c6103e0a54 100644 --- a/crates/egui/src/input_state.rs +++ b/crates/egui/src/input_state.rs @@ -70,10 +70,6 @@ pub struct InputState { /// at the end of the frame this will be zero if a scroll-area consumed the delta. pub smooth_scroll_delta: Vec2, - /// Force the current scroll area to consume the [Self::smooth_scroll_delta], independent of the focus / mouse position. - /// This is used when using [crate::Ui::scroll_with_delta] to scroll the current scroll area. - pub(crate) force_current_scroll_area: bool, - /// Zoom scale factor this frame (e.g. from ctrl-scroll or pinch gesture). /// /// * `zoom = 1`: no change. @@ -158,7 +154,6 @@ impl Default for InputState { unprocessed_scroll_delta: Vec2::ZERO, raw_scroll_delta: Vec2::ZERO, smooth_scroll_delta: Vec2::ZERO, - force_current_scroll_area: false, zoom_factor_delta: 1.0, screen_rect: Rect::from_min_size(Default::default(), vec2(10_000.0, 10_000.0)), pixels_per_point: 1.0, @@ -260,7 +255,6 @@ impl InputState { unprocessed_scroll_delta, raw_scroll_delta, smooth_scroll_delta, - force_current_scroll_area: false, zoom_factor_delta, screen_rect, pixels_per_point, @@ -1119,7 +1113,6 @@ impl InputState { unprocessed_scroll_delta, raw_scroll_delta, smooth_scroll_delta, - force_current_scroll_area, zoom_factor_delta, screen_rect, @@ -1164,9 +1157,6 @@ impl InputState { ui.label(format!( "smooth_scroll_delta: {smooth_scroll_delta:?} points" )); - ui.label(format!( - "force_current_scroll_area: {force_current_scroll_area}" - )); ui.label(format!("zoom_factor_delta: {zoom_factor_delta:4.2}x")); ui.label(format!("screen_rect: {screen_rect:?} points")); ui.label(format!( diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index ac14cfe3aa1..5a5b80a7a36 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1091,9 +1091,8 @@ impl Ui { /// # }); /// ``` pub fn scroll_with_delta(&self, delta: Vec2) { - self.ctx().input_mut(|input| { - input.smooth_scroll_delta += delta; - input.force_current_scroll_area = true; + self.ctx().frame_state_mut(|state| { + state.scroll_delta = [Some(delta.x), Some(delta.y)]; }); } } diff --git a/crates/egui_demo_lib/src/demo/scrolling.rs b/crates/egui_demo_lib/src/demo/scrolling.rs index d7bee754c5b..6e2c1d0128f 100644 --- a/crates/egui_demo_lib/src/demo/scrolling.rs +++ b/crates/egui_demo_lib/src/demo/scrolling.rs @@ -294,7 +294,7 @@ impl super::View for ScrollTo { scroll_top |= ui.button("Scroll to top").clicked(); scroll_bottom |= ui.button("Scroll to bottom").clicked(); if ui.button("Scroll down by 64px").clicked() { - scroll_delta = Some(Vec2::new(0.0, -64.0)); + scroll_delta = Some(Vec2::new(0.0, 64.0)); } }); From 6e735324b60947c538a03b0989babac02494e840 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Mon, 22 Apr 2024 16:09:13 +0200 Subject: [PATCH 3/7] Change scroll_delta to be Vec2 --- crates/egui/src/containers/scroll_area.rs | 18 ++++++++++-------- crates/egui/src/frame_state.rs | 8 ++++---- crates/egui/src/ui.rs | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index b3a4e6b9f64..855ba5dc582 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -782,15 +782,21 @@ impl Prepared { let content_size = content_ui.min_size(); + let scroll_delta = content_ui + .ctx() + .frame_state_mut(|state| std::mem::take(&mut state.scroll_delta)); + for d in 0..2 { + let mut delta = scroll_delta[d]; + // We always take both scroll targets regardless of which scroll axes are enabled. This // is to avoid them leaking to other scroll areas. - let (scroll_target, scroll_delta) = content_ui.ctx().frame_state_mut(|state| { - (state.scroll_target[d].take(), state.scroll_delta[d].take()) - }); + let scroll_target = content_ui + .ctx() + .frame_state_mut(|state| state.scroll_target[d].take()); if scroll_enabled[d] { - let mut delta = if let Some((target_range, align)) = scroll_target { + delta += if let Some((target_range, align)) = scroll_target { let min = content_ui.min_rect().min[d]; let clip_rect = content_ui.clip_rect(); let visible_range = min..=min + clip_rect.size()[d]; @@ -821,10 +827,6 @@ impl Prepared { 0.0 }; - if let Some(scroll_delta) = scroll_delta { - delta += scroll_delta; - } - if delta != 0.0 { let target_offset = state.offset[d] + delta; diff --git a/crates/egui/src/frame_state.rs b/crates/egui/src/frame_state.rs index fb6d785025f..3ed1a3691de 100644 --- a/crates/egui/src/frame_state.rs +++ b/crates/egui/src/frame_state.rs @@ -41,8 +41,8 @@ pub(crate) struct FrameState { /// The current scroll area should scroll to this range (horizontal, vertical). pub(crate) scroll_target: [Option<(Rangef, Option)>; 2], - /// The current scroll area should scroll by this much (horizontal, vertical). - pub(crate) scroll_delta: [Option; 2], + /// The current scroll area should scroll by this much. + pub(crate) scroll_delta: Vec2, #[cfg(feature = "accesskit")] pub(crate) accesskit_state: Option, @@ -66,7 +66,7 @@ impl Default for FrameState { used_by_panels: Rect::NAN, tooltip_state: None, scroll_target: [None, None], - scroll_delta: [None, None], + scroll_delta: Vec2::default(), #[cfg(feature = "accesskit")] accesskit_state: None, highlight_this_frame: Default::default(), @@ -104,7 +104,7 @@ impl FrameState { *used_by_panels = Rect::NOTHING; *tooltip_state = None; *scroll_target = [None, None]; - *scroll_delta = [None, None]; + *scroll_delta = Vec2::default(); #[cfg(debug_assertions)] { diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index 5a5b80a7a36..65cb2c9401f 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1092,7 +1092,7 @@ impl Ui { /// ``` pub fn scroll_with_delta(&self, delta: Vec2) { self.ctx().frame_state_mut(|state| { - state.scroll_delta = [Some(delta.x), Some(delta.y)]; + state.scroll_delta = delta; }); } } From cbcccd2f621da00630bbde049bb4476e5121989b Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Mon, 27 May 2024 17:16:42 +0200 Subject: [PATCH 4/7] Combine scroll delta when calling scroll_with_delta multiple times per frame --- crates/egui/src/ui.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index 65cb2c9401f..ab8ace57e1b 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1073,6 +1073,8 @@ impl Ui { /// A positive Y-value indicates the content is being moved down, /// as when swiping down on a touch-screen or track-pad with natural scrolling. /// + /// If this is called multiple times per frame for the same ScrollArea, the deltas will be combined. + /// /// /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`] /// /// ``` @@ -1092,7 +1094,7 @@ impl Ui { /// ``` pub fn scroll_with_delta(&self, delta: Vec2) { self.ctx().frame_state_mut(|state| { - state.scroll_delta = delta; + state.scroll_delta += delta; }); } } From 6c58dbe578e6ecf9d12dc29e70d3dec543493b0f Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Mon, 27 May 2024 17:20:09 +0200 Subject: [PATCH 5/7] Fix scroll_with_delta behaviour being inverted --- crates/egui/src/containers/scroll_area.rs | 3 ++- crates/egui/src/frame_state.rs | 8 ++++++++ crates/egui/src/ui.rs | 2 +- crates/egui_demo_lib/src/demo/scrolling.rs | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index 855ba5dc582..3bdac533ba2 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -787,7 +787,8 @@ impl Prepared { .frame_state_mut(|state| std::mem::take(&mut state.scroll_delta)); for d in 0..2 { - let mut delta = scroll_delta[d]; + // FrameState::scroll_delta is inverted from the way we apply the delta, so we need to negate it. + let mut delta = -scroll_delta[d]; // We always take both scroll targets regardless of which scroll axes are enabled. This // is to avoid them leaking to other scroll areas. diff --git a/crates/egui/src/frame_state.rs b/crates/egui/src/frame_state.rs index 3ed1a3691de..5b7de3d10b3 100644 --- a/crates/egui/src/frame_state.rs +++ b/crates/egui/src/frame_state.rs @@ -42,6 +42,14 @@ pub(crate) struct FrameState { pub(crate) scroll_target: [Option<(Rangef, Option)>; 2], /// The current scroll area should scroll by this much. + /// + /// The delta dictates how the _content_ should move. + /// + /// A positive X-value indicates the content is being moved right, + /// as when swiping right on a touch-screen or track-pad with natural scrolling. + /// + /// A positive Y-value indicates the content is being moved down, + /// as when swiping down on a touch-screen or track-pad with natural scrolling. pub(crate) scroll_delta: Vec2, #[cfg(feature = "accesskit")] diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index ab8ace57e1b..e34a3ad1cb9 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1073,7 +1073,7 @@ impl Ui { /// A positive Y-value indicates the content is being moved down, /// as when swiping down on a touch-screen or track-pad with natural scrolling. /// - /// If this is called multiple times per frame for the same ScrollArea, the deltas will be combined. + /// If this is called multiple times per frame for the same [`ScrollArea`], the deltas will be combined. /// /// /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`] /// diff --git a/crates/egui_demo_lib/src/demo/scrolling.rs b/crates/egui_demo_lib/src/demo/scrolling.rs index 6e2c1d0128f..d7bee754c5b 100644 --- a/crates/egui_demo_lib/src/demo/scrolling.rs +++ b/crates/egui_demo_lib/src/demo/scrolling.rs @@ -294,7 +294,7 @@ impl super::View for ScrollTo { scroll_top |= ui.button("Scroll to top").clicked(); scroll_bottom |= ui.button("Scroll to bottom").clicked(); if ui.button("Scroll down by 64px").clicked() { - scroll_delta = Some(Vec2::new(0.0, 64.0)); + scroll_delta = Some(Vec2::new(0.0, -64.0)); } }); From f8c9592a431ab7d538b2177dbd333be70fb535fa Mon Sep 17 00:00:00 2001 From: lucasmerlin Date: Mon, 27 May 2024 23:12:59 +0200 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Emil Ernerfeldt --- crates/egui/src/ui.rs | 2 +- crates/egui_demo_lib/src/demo/scrolling.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index e34a3ad1cb9..fac5ea2b60d 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1073,7 +1073,7 @@ impl Ui { /// A positive Y-value indicates the content is being moved down, /// as when swiping down on a touch-screen or track-pad with natural scrolling. /// - /// If this is called multiple times per frame for the same [`ScrollArea`], the deltas will be combined. + /// If this is called multiple times per frame for the same [`ScrollArea`], the deltas will be summed. /// /// /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`] /// diff --git a/crates/egui_demo_lib/src/demo/scrolling.rs b/crates/egui_demo_lib/src/demo/scrolling.rs index d7bee754c5b..cd9dd13ebf5 100644 --- a/crates/egui_demo_lib/src/demo/scrolling.rs +++ b/crates/egui_demo_lib/src/demo/scrolling.rs @@ -294,7 +294,7 @@ impl super::View for ScrollTo { scroll_top |= ui.button("Scroll to top").clicked(); scroll_bottom |= ui.button("Scroll to bottom").clicked(); if ui.button("Scroll down by 64px").clicked() { - scroll_delta = Some(Vec2::new(0.0, -64.0)); + scroll_delta = Some(64.0 * Vec2::UP); // move contents up } }); From f65eb519a62f9a13909cae728d36109ee0b2bef3 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Mon, 27 May 2024 23:27:30 +0200 Subject: [PATCH 7/7] Improve scroll by example --- crates/egui_demo_lib/src/demo/scrolling.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/egui_demo_lib/src/demo/scrolling.rs b/crates/egui_demo_lib/src/demo/scrolling.rs index cd9dd13ebf5..71d47f9d84c 100644 --- a/crates/egui_demo_lib/src/demo/scrolling.rs +++ b/crates/egui_demo_lib/src/demo/scrolling.rs @@ -236,6 +236,7 @@ struct ScrollTo { track_item: usize, tack_item_align: Option, offset: f32, + delta: f32, } impl Default for ScrollTo { @@ -244,6 +245,7 @@ impl Default for ScrollTo { track_item: 25, tack_item_align: Some(Align::Center), offset: 0.0, + delta: 64.0, } } } @@ -293,8 +295,19 @@ impl super::View for ScrollTo { ui.horizontal(|ui| { scroll_top |= ui.button("Scroll to top").clicked(); scroll_bottom |= ui.button("Scroll to bottom").clicked(); - if ui.button("Scroll down by 64px").clicked() { - scroll_delta = Some(64.0 * Vec2::UP); // move contents up + }); + + ui.horizontal(|ui| { + ui.label("Scroll by"); + DragValue::new(&mut self.delta) + .speed(1.0) + .suffix("px") + .ui(ui); + if ui.button("⬇").clicked() { + scroll_delta = Some(self.delta * Vec2::UP); // scroll down (move contents up) + } + if ui.button("⬆").clicked() { + scroll_delta = Some(self.delta * Vec2::DOWN); // scroll up (move contents down) } });