Skip to content

Commit

Permalink
Apply suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmerlin committed Jul 4, 2024
1 parent 65b0676 commit d173e54
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 31 deletions.
10 changes: 5 additions & 5 deletions crates/egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,20 +809,20 @@ impl Prepared {
.frame_state_mut(|state| state.scroll_target[d].take());

if scroll_enabled[d] {
let update = if let Some((target_range, align, animation)) = scroll_target {
let update = if let Some(target) = 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];
let (start, end) = (target_range.min, target_range.max);
let (start, end) = (target.range.min, target.range.max);
let clip_start = clip_rect.min[d];
let clip_end = clip_rect.max[d];
let mut spacing = ui.spacing().item_spacing[d];

let delta = if let Some(align) = align {
let delta = if let Some(align) = target.align {
let center_factor = align.to_factor();

let offset =
lerp(target_range, center_factor) - lerp(visible_range, center_factor);
lerp(target.range, center_factor) - lerp(visible_range, center_factor);

// Depending on the alignment we need to add or subtract the spacing
spacing *= remap(center_factor, 0.0..=1.0, -1.0..=1.0);
Expand Down Expand Up @@ -859,7 +859,7 @@ impl Prepared {
// The further we scroll, the more time we take.
let now = ui.input(|i| i.time);
let animation_duration = (delta.abs() / animation.points_per_second)
.clamp(animation.min_duration, animation.max_duration);
.clamp(animation.duration.min, animation.duration.max);
state.offset_target[d] = Some(ScrollTarget {
animation_time_span: (now, now + animation_duration as f64),
target_offset,
Expand Down
21 changes: 19 additions & 2 deletions crates/egui/src/frame_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@ pub struct PerLayerState {
pub widget_with_tooltip: Option<Id>,
}

#[derive(Clone, Debug)]
pub struct ScrollTarget {
pub range: Rangef,
pub align: Option<Align>,
pub animation: style::ScrollAnimation,
}

impl ScrollTarget {
pub fn new(range: Rangef, align: Option<Align>, animation: style::ScrollAnimation) -> Self {
Self {
range,
align,
animation,
}
}
}

#[cfg(feature = "accesskit")]
#[derive(Clone)]
pub struct AccessKitFrameState {
Expand Down Expand Up @@ -79,7 +96,7 @@ pub struct FrameState {
pub used_by_panels: Rect,

/// The current scroll area should scroll to this range (horizontal, vertical).
pub scroll_target: [Option<(Rangef, Option<Align>, style::ScrollAnimation)>; 2],
pub scroll_target: [Option<ScrollTarget>; 2],

/// The current scroll area should scroll by this much.
///
Expand Down Expand Up @@ -153,7 +170,7 @@ impl FrameState {
*unused_rect = screen_rect;
*used_by_panels = Rect::NOTHING;
*scroll_target = [None, None];
*scroll_delta = (Vec2::default(), style::ScrollAnimation::none());
*scroll_delta = Default::default();

#[cfg(debug_assertions)]
{
Expand Down
17 changes: 12 additions & 5 deletions crates/egui/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use std::{any::Any, sync::Arc};

use crate::{
emath::{Align, Pos2, Rect, Vec2},
menu, AreaState, Context, CursorIcon, Id, LayerId, Order, PointerButton, Sense, Ui, WidgetRect,
WidgetText,
frame_state, menu, AreaState, Context, CursorIcon, Id, LayerId, Order, PointerButton, Sense,
Ui, WidgetRect, WidgetText,
};

// ----------------------------------------------------------------------------

/// The result of adding a widget to a [`Ui`].
Expand Down Expand Up @@ -855,8 +854,16 @@ impl Response {
animation: crate::style::ScrollAnimation,
) {
self.ctx.frame_state_mut(|state| {
state.scroll_target[0] = Some((self.rect.x_range(), align, animation));
state.scroll_target[1] = Some((self.rect.y_range(), align, animation));
state.scroll_target[0] = Some(frame_state::ScrollTarget::new(
self.rect.x_range(),
align,
animation,
));
state.scroll_target[1] = Some(frame_state::ScrollTarget::new(
self.rect.y_range(),
align,
animation,
));
});
}

Expand Down
40 changes: 26 additions & 14 deletions crates/egui/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,39 +695,51 @@ impl ScrollStyle {

// ----------------------------------------------------------------------------

#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
/// Scroll animation configuration, used when programmatically scrolling somewhere (e.g. with `[crate::Ui::scroll_to_cursor]`)
/// The animation duration is calculated based on the distance to be scrolled via `[ScrollAnimation::points_per_second]`
/// and can be clamped to a min / max duration via `[ScrollAnimation::duration]`.
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct ScrollAnimation {
/// With what speed should we scroll? (Default: 1000.0)
pub points_per_second: f32,
pub min_duration: f32,
pub max_duration: f32,

/// The min / max scroll duration.
pub duration: Rangef,
}

impl Default for ScrollAnimation {
fn default() -> Self {
Self {
points_per_second: 1000.0,
min_duration: 0.1,
max_duration: 0.3,
duration: Rangef::new(0.1, 0.3),
}
}
}

impl ScrollAnimation {
/// New scroll animation
pub fn new(points_per_second: f32, duration: Rangef) -> Self {
Self {
points_per_second,
duration,
}
}

/// No animation, scroll instantly.
pub fn none() -> Self {
Self {
points_per_second: 0.0,
min_duration: 0.0,
max_duration: 0.0,
points_per_second: f32::INFINITY,
duration: Rangef::new(0.0, 0.0),
}
}

/// Scroll with a fixed duration, regardless of distance.
pub fn duration(t: f32) -> Self {
Self {
points_per_second: 0.0,
min_duration: t,
max_duration: t,
points_per_second: f32::INFINITY,
duration: Rangef::new(t, t),
}
}

Expand All @@ -744,16 +756,16 @@ impl ScrollAnimation {

ui.label("Min duration:");
ui.add(
DragValue::new(&mut self.min_duration)
DragValue::new(&mut self.duration.min)
.speed(0.01)
.range(0.0..=self.max_duration),
.range(0.0..=self.duration.max),
);
ui.label("seconds");
ui.end_row();

ui.label("Max duration:");
ui.add(
DragValue::new(&mut self.max_duration)
DragValue::new(&mut self.duration.max)
.speed(0.01)
.range(0.0..=1.0),
);
Expand Down
13 changes: 8 additions & 5 deletions crates/egui/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::{
containers::*, ecolor::*, epaint::text::Fonts, layout::*, menu::MenuState, placer::Placer,
util::IdTypeMap, widgets::*, *,
};

// ----------------------------------------------------------------------------

/// This is what you use to place widgets.
Expand Down Expand Up @@ -1227,8 +1226,10 @@ impl Ui {
) {
for d in 0..2 {
let range = Rangef::new(rect.min[d], rect.max[d]);
self.ctx()
.frame_state_mut(|state| state.scroll_target[d] = Some((range, align, animation)));
self.ctx().frame_state_mut(|state| {
state.scroll_target[d] =
Some(frame_state::ScrollTarget::new(range, align, animation))
});
}
}

Expand Down Expand Up @@ -1267,8 +1268,10 @@ impl Ui {
let target = self.next_widget_position();
for d in 0..2 {
let target = Rangef::point(target[d]);
self.ctx()
.frame_state_mut(|state| state.scroll_target[d] = Some((target, align, animation)));
self.ctx().frame_state_mut(|state| {
state.scroll_target[d] =
Some(frame_state::ScrollTarget::new(target, align, animation))
});
}
}

Expand Down

0 comments on commit d173e54

Please sign in to comment.