diff options
-rw-r--r-- | native/src/widget/scrollable.rs | 44 | ||||
-rw-r--r-- | native/src/widget/slider.rs | 24 | ||||
-rw-r--r-- | native/src/widget/vertical_slider.rs | 24 | ||||
-rw-r--r-- | style/src/slider.rs | 2 | ||||
-rw-r--r-- | style/src/theme.rs | 1 |
5 files changed, 43 insertions, 52 deletions
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index d9cdf296..78dcdca2 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -33,6 +33,7 @@ where Renderer::Theme: StyleSheet, { id: Option<Id>, + width: Length, height: Length, vertical: Properties, horizontal: Option<Properties>, @@ -50,6 +51,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, @@ -65,6 +67,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(); @@ -173,7 +181,7 @@ where } fn width(&self) -> Length { - self.content.as_widget().width() + self.width } fn height(&self) -> Length { @@ -188,7 +196,7 @@ where layout( renderer, limits, - Widget::<Message, Renderer>::width(self), + self.width, self.height, self.horizontal.is_some(), |renderer, limits| { @@ -397,15 +405,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), @@ -895,7 +895,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, @@ -916,7 +916,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); } } @@ -929,6 +945,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 { @@ -940,6 +957,7 @@ impl Default for State { offset_x: Offset::Absolute(0.0), x_scroller_grabbed_at: None, keyboard_modifiers: keyboard::Modifiers::default(), + last_notified: None, } } } diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 69c06140..ba467834 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -391,7 +391,7 @@ pub fn draw<T, R>( let offset = if range_start >= range_end { 0.0 } else { - (bounds.width - handle_width) * (value - range_start) + (bounds.width - handle_width / 2.0) * (value - range_start) / (range_end - range_start) }; @@ -402,16 +402,10 @@ pub fn draw<T, R>( bounds: Rectangle { x: bounds.x, y: rail_y - style.rail.width / 2.0, - width: offset, + width: offset + handle_width / 2.0, height: style.rail.width, }, - border_radius: [ - style.rail.border_radius, - 0.0, - 0.0, - style.rail.border_radius, - ] - .into(), + border_radius: Default::default(), border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -421,18 +415,12 @@ pub fn draw<T, R>( renderer.fill_quad( renderer::Quad { bounds: Rectangle { - x: bounds.x + offset, + x: bounds.x + offset + handle_width / 2.0, y: rail_y - style.rail.width / 2.0, width: bounds.width - offset, height: style.rail.width, }, - border_radius: [ - 0.0, - style.rail.border_radius, - style.rail.border_radius, - 0.0, - ] - .into(), + border_radius: Default::default(), border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -442,7 +430,7 @@ pub fn draw<T, R>( renderer.fill_quad( renderer::Quad { bounds: Rectangle { - x: bounds.x + offset.round(), + x: bounds.x + offset, y: rail_y - handle_height / 2.0, width: handle_width, height: handle_height, diff --git a/native/src/widget/vertical_slider.rs b/native/src/widget/vertical_slider.rs index a06a200f..5af69676 100644 --- a/native/src/widget/vertical_slider.rs +++ b/native/src/widget/vertical_slider.rs @@ -384,7 +384,7 @@ pub fn draw<T, R>( let offset = if range_start >= range_end { 0.0 } else { - (bounds.height - handle_width) * (value - range_end) + (bounds.height - handle_width / 2.0) * (value - range_end) / (range_start - range_end) }; @@ -396,15 +396,9 @@ pub fn draw<T, R>( x: rail_x - style.rail.width / 2.0, y: bounds.y, width: style.rail.width, - height: offset, + height: offset + handle_width / 2.0, }, - border_radius: [ - style.rail.border_radius, - style.rail.border_radius, - 0.0, - 0.0, - ] - .into(), + border_radius: Default::default(), border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -415,17 +409,11 @@ pub fn draw<T, R>( renderer::Quad { bounds: Rectangle { x: rail_x - style.rail.width / 2.0, - y: bounds.y + offset, + y: bounds.y + offset + handle_width / 2.0, width: style.rail.width, height: bounds.height - offset, }, - border_radius: [ - 0.0, - 0.0, - style.rail.border_radius, - style.rail.border_radius, - ] - .into(), + border_radius: Default::default(), border_width: 0.0, border_color: Color::TRANSPARENT, }, @@ -436,7 +424,7 @@ pub fn draw<T, R>( renderer::Quad { bounds: Rectangle { x: rail_x - handle_height / 2.0, - y: bounds.y + offset.round(), + y: bounds.y + offset, width: handle_height, height: handle_width, }, diff --git a/style/src/slider.rs b/style/src/slider.rs index d5db1853..884d3871 100644 --- a/style/src/slider.rs +++ b/style/src/slider.rs @@ -17,8 +17,6 @@ pub struct Rail { pub colors: (Color, Color), /// The width of the stroke of a slider rail. pub width: f32, - /// The border radius of the slider. - pub border_radius: f32, } /// The appearance of the handle of a slider. diff --git a/style/src/theme.rs b/style/src/theme.rs index b195940e..6711fd72 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -422,7 +422,6 @@ impl slider::StyleSheet for Theme { palette.primary.base.color, ), width: 2.0, - border_radius: 2.0, }, handle: slider::Handle { color: palette.background.base.color, |