diff options
author | 2023-04-17 23:41:12 +0200 | |
---|---|---|
committer | 2023-04-17 23:41:12 +0200 | |
commit | 4bae457c37b499f3cfddbdac9ff37a34cbce61d5 (patch) | |
tree | 79af93b2f7fabca1687900b48b165c5c74dcd26f /widget/src/scrollable.rs | |
parent | c0431aedd3bbef4161456f2fa5f29866e8f17fc5 (diff) | |
parent | 4b05f42fd6d18bf572b772dd60d6a4309ea5f343 (diff) | |
download | iced-4bae457c37b499f3cfddbdac9ff37a34cbce61d5.tar.gz iced-4bae457c37b499f3cfddbdac9ff37a34cbce61d5.tar.bz2 iced-4bae457c37b499f3cfddbdac9ff37a34cbce61d5.zip |
Merge branch 'master' into advanced-text
Diffstat (limited to 'widget/src/scrollable.rs')
-rw-r--r-- | widget/src/scrollable.rs | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 5a7481f7..161ae664 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -27,6 +27,7 @@ where Renderer::Theme: StyleSheet, { id: Option<Id>, + width: Length, height: Length, vertical: Properties, horizontal: Option<Properties>, @@ -44,6 +45,7 @@ where pub fn new(content: impl Into<Element<'a, Message, Renderer>>) -> Self { Scrollable { id: None, + width: Length::Shrink, height: Length::Shrink, vertical: Properties::default(), horizontal: None, @@ -59,6 +61,12 @@ where self } + /// Sets the width of the [`Scrollable`]. + pub fn width(mut self, width: impl Into<Length>) -> Self { + self.width = width.into(); + self + } + /// Sets the height of the [`Scrollable`]. pub fn height(mut self, height: impl Into<Length>) -> Self { self.height = height.into(); @@ -167,7 +175,7 @@ where } fn width(&self) -> Length { - self.content.as_widget().width() + self.width } fn height(&self) -> Length { @@ -182,7 +190,7 @@ where layout( renderer, limits, - Widget::<Message, Renderer>::width(self), + self.width, self.height, self.horizontal.is_some(), |renderer, limits| { @@ -391,15 +399,7 @@ pub fn layout<Renderer>( horizontal_enabled: bool, layout_content: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node, ) -> layout::Node { - let limits = limits - .max_height(f32::INFINITY) - .max_width(if horizontal_enabled { - f32::INFINITY - } else { - limits.max().width - }) - .width(width) - .height(height); + let limits = limits.width(width).height(height); let child_limits = layout::Limits::new( Size::new(limits.min().width, 0.0), @@ -851,8 +851,8 @@ pub fn draw<Renderer>( if let Some(scrollbar) = scrollbars.y { let style = if state.y_scroller_grabbed_at.is_some() { theme.dragging(style) - } else if mouse_over_y_scrollbar { - theme.hovered(style) + } else if mouse_over_scrollable { + theme.hovered(style, mouse_over_y_scrollbar) } else { theme.active(style) }; @@ -864,8 +864,8 @@ pub fn draw<Renderer>( if let Some(scrollbar) = scrollbars.x { let style = if state.x_scroller_grabbed_at.is_some() { theme.dragging_horizontal(style) - } else if mouse_over_x_scrollbar { - theme.hovered_horizontal(style) + } else if mouse_over_scrollable { + theme.hovered_horizontal(style, mouse_over_x_scrollbar) } else { theme.active_horizontal(style) }; @@ -889,7 +889,7 @@ pub fn draw<Renderer>( } fn notify_on_scroll<Message>( - state: &State, + state: &mut State, on_scroll: &Option<Box<dyn Fn(RelativeOffset) -> Message + '_>>, bounds: Rectangle, content_bounds: Rectangle, @@ -910,7 +910,23 @@ fn notify_on_scroll<Message>( .absolute(bounds.height, content_bounds.height) / (content_bounds.height - bounds.height); - shell.publish(on_scroll(RelativeOffset { x, y })) + let new_offset = RelativeOffset { x, y }; + + // Don't publish redundant offsets to shell + if let Some(prev_offset) = state.last_notified { + let unchanged = |a: f32, b: f32| { + (a - b).abs() <= f32::EPSILON || (a.is_nan() && b.is_nan()) + }; + + if unchanged(prev_offset.x, new_offset.x) + && unchanged(prev_offset.y, new_offset.y) + { + return; + } + } + + shell.publish(on_scroll(new_offset)); + state.last_notified = Some(new_offset); } } @@ -923,6 +939,7 @@ pub struct State { offset_x: Offset, x_scroller_grabbed_at: Option<f32>, keyboard_modifiers: keyboard::Modifiers, + last_notified: Option<RelativeOffset>, } impl Default for State { @@ -934,6 +951,7 @@ impl Default for State { offset_x: Offset::Absolute(0.0), x_scroller_grabbed_at: None, keyboard_modifiers: keyboard::Modifiers::default(), + last_notified: None, } } } |