From 7d3735f0fa88372157e7f1041be3e2513067c80b Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 24 Feb 2024 19:46:44 +0100 Subject: Assert `scrollable` content size never fills scrolling axis --- examples/scrollable/src/main.rs | 60 ++++++++++++++++++++--------------------- widget/src/scrollable.rs | 34 ++++++++++++++++------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index ac18fd38..bae23775 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -2,7 +2,7 @@ use iced::executor; use iced::widget::scrollable::Properties; use iced::widget::{ button, column, container, horizontal_space, progress_bar, radio, row, - scrollable, slider, text, vertical_space, + scrollable, slider, text, vertical_space, Scrollable, }; use iced::{ Alignment, Application, Color, Command, Element, Length, Settings, Theme, @@ -212,7 +212,7 @@ impl Application for ScrollableDemo { let scrollable_content: Element = Element::from(match self.scrollable_direction { - Direction::Vertical => scrollable( + Direction::Vertical => Scrollable::with_direction( column![ scroll_to_end_button(), text("Beginning!"), @@ -225,19 +225,19 @@ impl Application for ScrollableDemo { .align_items(Alignment::Center) .padding([40, 0, 40, 0]) .spacing(40), + scrollable::Direction::Vertical( + Properties::new() + .width(self.scrollbar_width) + .margin(self.scrollbar_margin) + .scroller_width(self.scroller_width) + .alignment(self.alignment), + ), ) .width(Length::Fill) .height(Length::Fill) - .direction(scrollable::Direction::Vertical( - Properties::new() - .width(self.scrollbar_width) - .margin(self.scrollbar_margin) - .scroller_width(self.scroller_width) - .alignment(self.alignment), - )) .id(SCROLLABLE_ID.clone()) .on_scroll(Message::Scrolled), - Direction::Horizontal => scrollable( + Direction::Horizontal => Scrollable::with_direction( row![ scroll_to_end_button(), text("Beginning!"), @@ -251,19 +251,19 @@ impl Application for ScrollableDemo { .align_items(Alignment::Center) .padding([0, 40, 0, 40]) .spacing(40), + scrollable::Direction::Horizontal( + Properties::new() + .width(self.scrollbar_width) + .margin(self.scrollbar_margin) + .scroller_width(self.scroller_width) + .alignment(self.alignment), + ), ) .width(Length::Fill) .height(Length::Fill) - .direction(scrollable::Direction::Horizontal( - Properties::new() - .width(self.scrollbar_width) - .margin(self.scrollbar_margin) - .scroller_width(self.scroller_width) - .alignment(self.alignment), - )) .id(SCROLLABLE_ID.clone()) .on_scroll(Message::Scrolled), - Direction::Multi => scrollable( + Direction::Multi => Scrollable::with_direction( //horizontal content row![ column![ @@ -293,21 +293,21 @@ impl Application for ScrollableDemo { .align_items(Alignment::Center) .padding([0, 40, 0, 40]) .spacing(40), + { + let properties = Properties::new() + .width(self.scrollbar_width) + .margin(self.scrollbar_margin) + .scroller_width(self.scroller_width) + .alignment(self.alignment); + + scrollable::Direction::Both { + horizontal: properties, + vertical: properties, + } + }, ) .width(Length::Fill) .height(Length::Fill) - .direction({ - let properties = Properties::new() - .width(self.scrollbar_width) - .margin(self.scrollbar_margin) - .scroller_width(self.scroller_width) - .alignment(self.alignment); - - scrollable::Direction::Both { - horizontal: properties, - vertical: properties, - } - }) .id(SCROLLABLE_ID.clone()) .on_scroll(Message::Scrolled), }); diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 3814c590..c4873648 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -47,16 +47,38 @@ where Theme: StyleSheet, Renderer: crate::core::Renderer, { - /// Creates a new [`Scrollable`]. + /// Creates a new vertical [`Scrollable`]. pub fn new( content: impl Into>, ) -> Self { + Self::with_direction(content, Direction::default()) + } + + /// Creates a new [`Scrollable`] with the given [`Direction`]. + pub fn with_direction( + content: impl Into>, + direction: Direction, + ) -> Self { + let content = content.into(); + + debug_assert!( + direction.vertical().is_none() + || !content.as_widget().size_hint().height.is_fill(), + "scrollable content must not fill its vertical scrolling axis" + ); + + debug_assert!( + direction.horizontal().is_none() + || !content.as_widget().size_hint().width.is_fill(), + "scrollable content must not fill its horizontal scrolling axis" + ); + Scrollable { id: None, width: Length::Shrink, height: Length::Shrink, - direction: Direction::default(), - content: content.into(), + direction, + content, on_scroll: None, style: Default::default(), } @@ -80,12 +102,6 @@ where self } - /// Sets the [`Direction`] of the [`Scrollable`] . - pub fn direction(mut self, direction: Direction) -> Self { - self.direction = direction; - self - } - /// Sets a function to call when the [`Scrollable`] is scrolled. /// /// The function takes the [`Viewport`] of the [`Scrollable`] -- cgit