From f05578c8f88b38cb538657e40c2feb725e72c7d8 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Thu, 22 Oct 2020 16:05:44 -0500 Subject: [PATCH] Update scrollbar logic and introduce outer_bounds --- graphics/src/widget/scrollable.rs | 33 +++++++++++++++++++------------ native/src/widget/scrollable.rs | 13 +++++++++--- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/graphics/src/widget/scrollable.rs b/graphics/src/widget/scrollable.rs index 0a3191fa..fed79c18 100644 --- a/graphics/src/widget/scrollable.rs +++ b/graphics/src/widget/scrollable.rs @@ -28,29 +28,41 @@ where offset: u32, scrollbar_width: u16, scrollbar_margin: u16, - _scroller_width: u16, + scroller_width: u16, ) -> Option { if content_bounds.height > bounds.height { + let outer_width = + scrollbar_width.max(scroller_width) + 2 * scrollbar_margin; + + let outer_bounds = Rectangle { + x: bounds.x + bounds.width - outer_width as f32, + y: bounds.y, + width: outer_width as f32, + height: bounds.height, + }; + let scrollbar_bounds = Rectangle { x: bounds.x + bounds.width - - f32::from(scrollbar_width + 2 * scrollbar_margin), + - f32::from(outer_width / 2 + scrollbar_width / 2), y: bounds.y, - width: f32::from(scrollbar_width + 2 * scrollbar_margin), + width: scrollbar_width as f32, height: bounds.height, }; let ratio = bounds.height / content_bounds.height; - let scrollbar_height = bounds.height * ratio; + let scroller_height = bounds.height * ratio; let y_offset = offset as f32 * ratio; let scroller_bounds = Rectangle { - x: scrollbar_bounds.x + f32::from(scrollbar_margin), + x: bounds.x + bounds.width + - f32::from(outer_width / 2 + scroller_width / 2), y: scrollbar_bounds.y + y_offset, - width: scrollbar_bounds.width - f32::from(2 * scrollbar_margin), - height: scrollbar_height, + width: scroller_width as f32, + height: scroller_height, }; Some(scrollable::Scrollbar { + outer_bounds, bounds: scrollbar_bounds, margin: scrollbar_margin, scroller: scrollable::Scroller { @@ -110,12 +122,7 @@ where let scrollbar = if is_scrollbar_visible { Primitive::Quad { - bounds: Rectangle { - x: scrollbar.bounds.x + f32::from(scrollbar.margin), - width: scrollbar.bounds.width - - f32::from(2 * scrollbar.margin), - ..scrollbar.bounds - }, + bounds: scrollbar.bounds, background: style .background .unwrap_or(Background::Color(Color::TRANSPARENT)), diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index 1cbc2bbf..cb181899 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -31,7 +31,7 @@ impl<'a, Message, Renderer: self::Renderer> Scrollable<'a, Message, Renderer> { height: Length::Shrink, max_height: u32::MAX, scrollbar_width: 10, - scrollbar_margin: 2, + scrollbar_margin: 0, scroller_width: 10, content: Column::new(), style: Renderer::Style::default(), @@ -459,6 +459,13 @@ impl State { /// [`Scrollable`]: struct.Scrollable.html #[derive(Debug)] pub struct Scrollbar { + /// The outer bounds of the scrollable, including the [`Scrollbar`] and + /// [`Scroller`]. + /// + /// [`Scrollbar`]: struct.Scrollbar.html + /// [`Scroller`]: struct.Scroller.html + pub outer_bounds: Rectangle, + /// The bounds of the [`Scrollbar`]. /// /// [`Scrollbar`]: struct.Scrollbar.html @@ -477,11 +484,11 @@ pub struct Scrollbar { impl Scrollbar { fn is_mouse_over(&self, cursor_position: Point) -> bool { - self.bounds.contains(cursor_position) + self.outer_bounds.contains(cursor_position) } fn grab_scroller(&self, cursor_position: Point) -> Option { - if self.bounds.contains(cursor_position) { + if self.outer_bounds.contains(cursor_position) { Some(if self.scroller.bounds.contains(cursor_position) { (cursor_position.y - self.scroller.bounds.y) / self.scroller.bounds.height