Skip to content

Commit

Permalink
Scroll::preserve_max_scroll
Browse files Browse the repository at this point in the history
  • Loading branch information
ecton committed Oct 6, 2024
1 parent 77f1bd4 commit 432a84b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Choosing one or more folders/directories
- `DynamicGuard::unlocked` executes a closure while the guard is temporarily
unlocked.
- `Scroll::preserve_max_scroll` controls whether the scroll view automatically
scrolls when currently scrolled to the maximum and its child grows.


[139]: https://github.com/khonsulabs/cushy/issues/139
Expand Down
26 changes: 21 additions & 5 deletions src/widgets/scroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::animation::{AnimationHandle, AnimationTarget, IntoAnimate, Spawn, Zer
use crate::context::{AsEventContext, EventContext, LayoutContext};
use crate::styles::components::{EasingIn, EasingOut, LineHeight};
use crate::styles::Dimension;
use crate::value::{Destination, Dynamic, Source};
use crate::value::{Destination, Dynamic, IntoValue, Source, Value};
use crate::widget::{EventHandling, MakeWidget, Widget, WidgetRef, HANDLED, IGNORED};
use crate::window::DeviceId;
use crate::ConstraintLimit;
Expand All @@ -26,6 +26,7 @@ pub struct Scroll {
control_size: Size<Px>,
scroll: Dynamic<Point<Px>>,
enabled: Point<bool>,
preserve_max_scroll: Value<bool>,
max_scroll: Dynamic<Point<Px>>,
scrollbar_opacity: Dynamic<ZeroToOne>,
scrollbar_opacity_animation: OpacityAnimationState,
Expand Down Expand Up @@ -64,6 +65,7 @@ impl Scroll {
bar_width: Px::default(),
line_height: Px::default(),
drag: DragInfo::default(),
preserve_max_scroll: Value::Constant(true),
}
}

Expand All @@ -84,6 +86,18 @@ impl Scroll {
Self::construct(contents, Point::new(false, true))
}

/// Sets whether the scroll view will stay scrolled to the maximum when a
/// child is resized.
///
/// When enabled, this setting allows the scroll view to remain scrolled to
/// the bottom or to the right when its contents grow. The default value for
/// this setting is `true`.
#[must_use]
pub fn preserve_max_scroll(mut self, preserve: impl IntoValue<bool>) -> Self {
self.preserve_max_scroll = preserve.into_value();
self
}

fn constrained_scroll(scroll: Point<Px>, max_scroll: Point<Px>) -> Point<Px> {
scroll.max(max_scroll).min(Point::default())
}
Expand Down Expand Up @@ -266,16 +280,18 @@ impl Widget for Scroll {
|| self.control_size.width != control_size.width
{
self.content_size.width = new_content_size.width;
let scroll_pct = scroll.x.into_float() / current_max_scroll.x.into_float();
scroll.x = max_scroll_x * scroll_pct;
if self.preserve_max_scroll.get() && scroll.x == current_max_scroll.x {
scroll.x = max_scroll_x;
}
}

if self.content_size.height != new_content_size.height
|| self.control_size.height != control_size.height
{
self.content_size.height = new_content_size.height;
let scroll_pct = scroll.y.into_float() / current_max_scroll.y.into_float();
scroll.y = max_scroll_y * scroll_pct;
if self.preserve_max_scroll.get() && scroll.y == current_max_scroll.y {
scroll.y = max_scroll_y;
}
}
// Set the current scroll, but prevent immediately triggering
// invalidate.
Expand Down

0 comments on commit 432a84b

Please sign in to comment.