mirror of
https://github.com/danbulant/cushy
synced 2026-06-24 17:12:11 +00:00
Scroll::preserve_max_scroll
This commit is contained in:
parent
77f1bd46f7
commit
432a84be04
2 changed files with 23 additions and 5 deletions
|
|
@ -217,6 +217,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Choosing one or more folders/directories
|
- Choosing one or more folders/directories
|
||||||
- `DynamicGuard::unlocked` executes a closure while the guard is temporarily
|
- `DynamicGuard::unlocked` executes a closure while the guard is temporarily
|
||||||
unlocked.
|
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
|
[139]: https://github.com/khonsulabs/cushy/issues/139
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::animation::{AnimationHandle, AnimationTarget, IntoAnimate, Spawn, Zer
|
||||||
use crate::context::{AsEventContext, EventContext, LayoutContext};
|
use crate::context::{AsEventContext, EventContext, LayoutContext};
|
||||||
use crate::styles::components::{EasingIn, EasingOut, LineHeight};
|
use crate::styles::components::{EasingIn, EasingOut, LineHeight};
|
||||||
use crate::styles::Dimension;
|
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::widget::{EventHandling, MakeWidget, Widget, WidgetRef, HANDLED, IGNORED};
|
||||||
use crate::window::DeviceId;
|
use crate::window::DeviceId;
|
||||||
use crate::ConstraintLimit;
|
use crate::ConstraintLimit;
|
||||||
|
|
@ -26,6 +26,7 @@ pub struct Scroll {
|
||||||
control_size: Size<Px>,
|
control_size: Size<Px>,
|
||||||
scroll: Dynamic<Point<Px>>,
|
scroll: Dynamic<Point<Px>>,
|
||||||
enabled: Point<bool>,
|
enabled: Point<bool>,
|
||||||
|
preserve_max_scroll: Value<bool>,
|
||||||
max_scroll: Dynamic<Point<Px>>,
|
max_scroll: Dynamic<Point<Px>>,
|
||||||
scrollbar_opacity: Dynamic<ZeroToOne>,
|
scrollbar_opacity: Dynamic<ZeroToOne>,
|
||||||
scrollbar_opacity_animation: OpacityAnimationState,
|
scrollbar_opacity_animation: OpacityAnimationState,
|
||||||
|
|
@ -64,6 +65,7 @@ impl Scroll {
|
||||||
bar_width: Px::default(),
|
bar_width: Px::default(),
|
||||||
line_height: Px::default(),
|
line_height: Px::default(),
|
||||||
drag: DragInfo::default(),
|
drag: DragInfo::default(),
|
||||||
|
preserve_max_scroll: Value::Constant(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,6 +86,18 @@ impl Scroll {
|
||||||
Self::construct(contents, Point::new(false, true))
|
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> {
|
fn constrained_scroll(scroll: Point<Px>, max_scroll: Point<Px>) -> Point<Px> {
|
||||||
scroll.max(max_scroll).min(Point::default())
|
scroll.max(max_scroll).min(Point::default())
|
||||||
}
|
}
|
||||||
|
|
@ -266,16 +280,18 @@ impl Widget for Scroll {
|
||||||
|| self.control_size.width != control_size.width
|
|| self.control_size.width != control_size.width
|
||||||
{
|
{
|
||||||
self.content_size.width = new_content_size.width;
|
self.content_size.width = new_content_size.width;
|
||||||
let scroll_pct = scroll.x.into_float() / current_max_scroll.x.into_float();
|
if self.preserve_max_scroll.get() && scroll.x == current_max_scroll.x {
|
||||||
scroll.x = max_scroll_x * scroll_pct;
|
scroll.x = max_scroll_x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.content_size.height != new_content_size.height
|
if self.content_size.height != new_content_size.height
|
||||||
|| self.control_size.height != control_size.height
|
|| self.control_size.height != control_size.height
|
||||||
{
|
{
|
||||||
self.content_size.height = new_content_size.height;
|
self.content_size.height = new_content_size.height;
|
||||||
let scroll_pct = scroll.y.into_float() / current_max_scroll.y.into_float();
|
if self.preserve_max_scroll.get() && scroll.y == current_max_scroll.y {
|
||||||
scroll.y = max_scroll_y * scroll_pct;
|
scroll.y = max_scroll_y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Set the current scroll, but prevent immediately triggering
|
// Set the current scroll, but prevent immediately triggering
|
||||||
// invalidate.
|
// invalidate.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue