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  | 
