diff options
Diffstat (limited to '')
-rw-r--r-- | examples/tour.rs | 2 | ||||
-rw-r--r-- | native/src/renderer/null.rs | 23 | ||||
-rw-r--r-- | native/src/widget.rs | 2 | ||||
-rw-r--r-- | native/src/widget/scrollable.rs | 108 | ||||
-rw-r--r-- | wgpu/src/renderer/widget/scrollable.rs | 102 |
5 files changed, 105 insertions, 132 deletions
diff --git a/examples/tour.rs b/examples/tour.rs index 0121c3bd..6b366957 100644 --- a/examples/tour.rs +++ b/examples/tour.rs @@ -145,7 +145,7 @@ impl Steps { Step::Debugger, Step::End, ], - current: 0, + current: 6, } } diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index c06d1dfa..2ce150c0 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -1,7 +1,7 @@ use crate::{ button, checkbox, column, radio, row, scrollable, text, text_input, Background, Color, Element, Font, HorizontalAlignment, Layout, Point, - Rectangle, Renderer, ScrollbarGrab, Size, VerticalAlignment, + Rectangle, Renderer, Size, VerticalAlignment, }; /// A renderer that does nothing. @@ -61,24 +61,17 @@ impl text::Renderer for Null { } impl scrollable::Renderer for Null { - fn scrollbar_bounds( - &self, - _bounds: Rectangle, - _content_bounds: Rectangle, - _offset: u32, - ) -> (Rectangle, Rectangle) { + fn scrollbar_bounds(_bounds: Rectangle) -> Rectangle { Default::default() } - fn scrollbar_grab( - &self, + fn scroller_bounds( _bounds: Rectangle, _content_bounds: Rectangle, - _background_bounds: Rectangle, - _scroller_bounds: Rectangle, - _cursor_position: Point, - ) -> Option<ScrollbarGrab> { - None + _scrollbar_bounds: Rectangle, + _offset: u32, + ) -> Rectangle { + Default::default() } fn draw( @@ -88,6 +81,8 @@ impl scrollable::Renderer for Null { _content_bounds: Rectangle, _is_mouse_over: bool, _is_mouse_over_scrollbar: bool, + _scrollbar_bounds: Rectangle, + _scroller_bounds: Rectangle, _offset: u32, _content: Self::Output, ) { diff --git a/native/src/widget.rs b/native/src/widget.rs index a2d3aa12..71dcdc0d 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -47,7 +47,7 @@ pub use radio::Radio; #[doc(no_inline)] pub use row::Row; #[doc(no_inline)] -pub use scrollable::{Scrollable, ScrollbarGrab}; +pub use scrollable::Scrollable; #[doc(no_inline)] pub use slider::Slider; #[doc(no_inline)] diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs index ab1a203b..b48ae492 100644 --- a/native/src/widget/scrollable.rs +++ b/native/src/widget/scrollable.rs @@ -162,12 +162,17 @@ where let content_bounds = content.bounds(); let offset = self.state.offset(bounds, content_bounds); - let (background_bounds, scroller_bounds) = - renderer.scrollbar_bounds(bounds, content_bounds, offset); - let scrollbar_grab = renderer.scrollbar_grab( + let scrollbar_bounds = Renderer::scrollbar_bounds(bounds); + let scroller_bounds = Renderer::scroller_bounds( bounds, content_bounds, - background_bounds, + scrollbar_bounds, + offset, + ); + let scrollbar_grab = ScrollbarItem::from_cursor_position( + bounds, + content_bounds, + scrollbar_bounds, scroller_bounds, cursor_position, ); @@ -190,7 +195,7 @@ where } } - if self.state.currently_grabbed() || scrollbar_grab.is_some() { + if self.state.is_scroller_grabbed() || scrollbar_grab.is_some() { match event { Event::Mouse(mouse::Event::Input { button: mouse::Button::Left, @@ -199,8 +204,8 @@ where ButtonState::Pressed => { let scroller_grabbed_at = match scrollbar_grab.unwrap() { - ScrollbarGrab::Background => 0.5, - ScrollbarGrab::Scroller => { + ScrollbarItem::Background => 0.5, + ScrollbarItem::Scroller => { (cursor_position.y - scroller_bounds.y) / scroller_bounds.height } @@ -245,7 +250,7 @@ where } let cursor_position = if is_mouse_over - && !(scrollbar_grab.is_some() || self.state.currently_grabbed()) + && !(scrollbar_grab.is_some() || self.state.is_scroller_grabbed()) { Point::new( cursor_position.x, @@ -281,17 +286,21 @@ where let offset = self.state.offset(bounds, content_bounds); let is_mouse_over = bounds.contains(cursor_position); - let (background_bounds, scroller_bounds) = - renderer.scrollbar_bounds(bounds, content_bounds, offset); - let is_mouse_over_scrollbar = renderer - .scrollbar_grab( - bounds, - content_bounds, - background_bounds, - scroller_bounds, - cursor_position, - ) - .is_some(); + let scrollbar_bounds = Renderer::scrollbar_bounds(bounds); + let scroller_bounds = Renderer::scroller_bounds( + bounds, + content_bounds, + scrollbar_bounds, + offset, + ); + let is_mouse_over_scrollbar = ScrollbarItem::from_cursor_position( + bounds, + content_bounds, + scrollbar_bounds, + scroller_bounds, + cursor_position, + ) + .is_some(); let content = { let cursor_position = if is_mouse_over && !is_mouse_over_scrollbar { @@ -310,6 +319,8 @@ where content_layout.bounds(), is_mouse_over, is_mouse_over_scrollbar, + scrollbar_bounds, + scroller_bounds, offset, content, ) @@ -392,21 +403,41 @@ impl State { self.offset.min(hidden_content as f32) as u32 } - /// Returns whether the scrollbar is currently grabbed or not. - pub fn currently_grabbed(&self) -> bool { + /// Returns whether the scroller is currently grabbed or not. + pub fn is_scroller_grabbed(&self) -> bool { self.scroller_grabbed_at.is_some() } } #[derive(Debug, Clone, Copy)] -/// What the mouse is grabbing on the scrollbar -pub enum ScrollbarGrab { - /// The mouse is grabbing the background +enum ScrollbarItem { Background, - /// The mouse is grabbing the scroller Scroller, } +impl ScrollbarItem { + /// `None` means the cursor is not over any item + fn from_cursor_position( + bounds: Rectangle, + content_bounds: Rectangle, + scrollbar_bounds: Rectangle, + scroller_bounds: Rectangle, + cursor_position: Point, + ) -> Option<ScrollbarItem> { + if content_bounds.height > bounds.height + && scrollbar_bounds.contains(cursor_position) + { + Some(if scroller_bounds.contains(cursor_position) { + ScrollbarItem::Scroller + } else { + ScrollbarItem::Background + }) + } else { + None + } + } +} + /// The renderer of a [`Scrollable`]. /// /// Your [renderer] will need to implement this trait before being @@ -416,27 +447,16 @@ pub enum ScrollbarGrab { /// [renderer]: ../../renderer/index.html pub trait Renderer: crate::Renderer + Sized { /// Returns the bounds of the scrollbar - /// - Background - /// - Movable Scroller - fn scrollbar_bounds( - &self, - bounds: Rectangle, - content_bounds: Rectangle, - offset: u32, - ) -> (Rectangle, Rectangle); + fn scrollbar_bounds(bounds: Rectangle) -> Rectangle; - /// Returns what part of the scrollbar is being grabbed by the mouse - /// given the bounds of the [`Scrollable`] and its contents. - /// - /// [`Scrollable`]: struct.Scrollable.html - fn scrollbar_grab( - &self, + /// Returns the bounds of the scroller + /// "The part that you can drag around with your mouse to scroll" + fn scroller_bounds( bounds: Rectangle, content_bounds: Rectangle, - background_bounds: Rectangle, - scroller_bounds: Rectangle, - cursor_position: Point, - ) -> Option<ScrollbarGrab>; + scrollbar_bounds: Rectangle, + offset: u32, + ) -> Rectangle; /// Draws the [`Scrollable`]. /// @@ -457,6 +477,8 @@ pub trait Renderer: crate::Renderer + Sized { content_bounds: Rectangle, is_mouse_over: bool, is_mouse_over_scrollbar: bool, + scrollbar_bounds: Rectangle, + scroller_bounds: Rectangle, offset: u32, content: Self::Output, ) -> Self::Output; diff --git a/wgpu/src/renderer/widget/scrollable.rs b/wgpu/src/renderer/widget/scrollable.rs index 175fac11..b83cee1b 100644 --- a/wgpu/src/renderer/widget/scrollable.rs +++ b/wgpu/src/renderer/widget/scrollable.rs @@ -1,72 +1,34 @@ use crate::{Primitive, Renderer}; -use iced_native::{ - scrollable, Background, MouseCursor, Point, Rectangle, ScrollbarGrab, - Vector, -}; +use iced_native::{scrollable, Background, MouseCursor, Rectangle, Vector}; const SCROLLBAR_WIDTH: u16 = 10; const SCROLLBAR_MARGIN: u16 = 2; -fn background_bounds(bounds: Rectangle) -> Rectangle { - Rectangle { - x: bounds.x + bounds.width - - f32::from(SCROLLBAR_WIDTH + 2 * SCROLLBAR_MARGIN), - y: bounds.y, - width: f32::from(SCROLLBAR_WIDTH + 2 * SCROLLBAR_MARGIN), - height: bounds.height, - } -} - -fn scroller_bounds( - bounds: Rectangle, - content_bounds: Rectangle, - background_bounds: Rectangle, - offset: u32, -) -> Rectangle { - let ratio = bounds.height / content_bounds.height; - let scrollbar_height = bounds.height * ratio; - let y_offset = offset as f32 * ratio; - - Rectangle { - x: background_bounds.x + f32::from(SCROLLBAR_MARGIN), - y: background_bounds.y + y_offset, - width: background_bounds.width - f32::from(2 * SCROLLBAR_MARGIN), - height: scrollbar_height, - } -} - impl scrollable::Renderer for Renderer { - fn scrollbar_bounds( - &self, - bounds: Rectangle, - content_bounds: Rectangle, - offset: u32, - ) -> (Rectangle, Rectangle) { - let background_bounds = background_bounds(bounds); - let scroller_bounds = - scroller_bounds(bounds, content_bounds, background_bounds, offset); - - (background_bounds, scroller_bounds) + fn scrollbar_bounds(bounds: Rectangle) -> Rectangle { + Rectangle { + x: bounds.x + bounds.width + - f32::from(SCROLLBAR_WIDTH + 2 * SCROLLBAR_MARGIN), + y: bounds.y, + width: f32::from(SCROLLBAR_WIDTH + 2 * SCROLLBAR_MARGIN), + height: bounds.height, + } } - fn scrollbar_grab( - &self, + fn scroller_bounds( bounds: Rectangle, content_bounds: Rectangle, - background_bounds: Rectangle, - scroller_bounds: Rectangle, - cursor_position: Point, - ) -> Option<ScrollbarGrab> { - if content_bounds.height > bounds.height - && background_bounds.contains(cursor_position) - { - Some(if scroller_bounds.contains(cursor_position) { - ScrollbarGrab::Scroller - } else { - ScrollbarGrab::Background - }) - } else { - None + scrollbar_bounds: Rectangle, + offset: u32, + ) -> Rectangle { + let ratio = bounds.height / content_bounds.height; + let scrollbar_height = bounds.height * ratio; + let y_offset = offset as f32 * ratio; + Rectangle { + x: scrollbar_bounds.x + f32::from(SCROLLBAR_MARGIN), + y: scrollbar_bounds.y + y_offset, + width: scrollbar_bounds.width - f32::from(2 * SCROLLBAR_MARGIN), + height: scrollbar_height, } } @@ -77,11 +39,12 @@ impl scrollable::Renderer for Renderer { content_bounds: Rectangle, is_mouse_over: bool, is_mouse_over_scrollbar: bool, + scrollbar_bounds: Rectangle, + scroller_bounds: Rectangle, offset: u32, (content, mouse_cursor): Self::Output, ) -> Self::Output { let is_content_overflowing = content_bounds.height > bounds.height; - let background_bounds = background_bounds(bounds); let clip = Primitive::Clip { bounds, @@ -91,28 +54,21 @@ impl scrollable::Renderer for Renderer { ( if is_content_overflowing - && (is_mouse_over || state.currently_grabbed()) + && (is_mouse_over || state.is_scroller_grabbed()) { - let scroller_bounds = scroller_bounds( - bounds, - content_bounds, - background_bounds, - offset, - ); let scrollbar = Primitive::Quad { bounds: scroller_bounds, background: Background::Color([0.0, 0.0, 0.0, 0.7].into()), border_radius: 5, }; - if is_mouse_over_scrollbar || state.currently_grabbed() { + if is_mouse_over_scrollbar || state.is_scroller_grabbed() { let scrollbar_background = Primitive::Quad { bounds: Rectangle { - x: background_bounds.x - + f32::from(SCROLLBAR_MARGIN), - width: background_bounds.width + x: scrollbar_bounds.x + f32::from(SCROLLBAR_MARGIN), + width: scrollbar_bounds.width - f32::from(2 * SCROLLBAR_MARGIN), - ..background_bounds + ..scrollbar_bounds }, background: Background::Color( [0.0, 0.0, 0.0, 0.3].into(), @@ -131,7 +87,7 @@ impl scrollable::Renderer for Renderer { } else { clip }, - if is_mouse_over_scrollbar || state.currently_grabbed() { + if is_mouse_over_scrollbar || state.is_scroller_grabbed() { MouseCursor::Idle } else { mouse_cursor |