diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index 470b8bb7..b29da22d 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -1,7 +1,12 @@ [package] name = "ui" +description = "UI components for the GPUI" version = "0.1.0" edition = "2021" +publish = false + +[lib] +doctest = false [dependencies] gpui = { git = "https://github.com/zed-industries/zed.git" } diff --git a/crates/ui/src/scroll/scrollable.rs b/crates/ui/src/scroll/scrollable.rs index 652cbbb1..96f240ad 100644 --- a/crates/ui/src/scroll/scrollable.rs +++ b/crates/ui/src/scroll/scrollable.rs @@ -1,45 +1,51 @@ use gpui::{ - px, relative, AnyView, Bounds, ContentMask, Corners, Edges, Element, Hitbox, Hsla, IntoElement, - IsZero as _, PaintQuad, ScrollHandle, ScrollWheelEvent, Style, WindowContext, + px, relative, AnyView, Bounds, ContentMask, Corners, Edges, Element, ElementId, + GlobalElementId, Hitbox, Hsla, IntoElement, IsZero as _, LayoutId, PaintQuad, Pixels, Point, + Position, ScrollHandle, ScrollWheelEvent, Style, WindowContext, }; +/// The scroll axis direction. #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ScrollAxis { + /// Horizontal scroll. Horizontal, + /// Vertical scroll. Vertical, } -/// Make a scrollable element to cover the parent view with the mouse wheel event listening. +/// Make a scrollable mask element to cover the parent view with the mouse wheel event listening. /// -/// When the mouse wheel is scrolled, will move the `scroll_handle` to make parent view scrolling with the `axis` direction. +/// When the mouse wheel is scrolled, will move the `scroll_handle` scrolling with the `axis` direction. +/// You can use this `scroll_handle` to control what you want to scroll. /// This is only can handle once axis scrolling. -pub struct ScrollableHandleElement { +pub struct ScrollableMask { view: AnyView, axis: ScrollAxis, scroll_handle: ScrollHandle, debug: Option, } -impl ScrollableHandleElement { +impl ScrollableMask { + /// Create a new scrollable mask element. pub fn new(view: impl Into, axis: ScrollAxis, scroll_handle: &ScrollHandle) -> Self { Self { view: view.into(), - debug: None, - axis, scroll_handle: scroll_handle.clone(), + axis, + debug: None, } } - /// Enable the debug mode to show the scrollable handle bounds. + /// Enable the debug border, to show the mask bounds. #[allow(dead_code)] - pub fn debug_yellow(mut self) -> Self { + pub fn debug(mut self) -> Self { self.debug = Some(gpui::yellow()); self } } -impl IntoElement for ScrollableHandleElement { +impl IntoElement for ScrollableMask { type Element = Self; fn into_element(self) -> Self::Element { @@ -47,22 +53,22 @@ impl IntoElement for ScrollableHandleElement { } } -impl Element for ScrollableHandleElement { +impl Element for ScrollableMask { type RequestLayoutState = (); type PrepaintState = Hitbox; - fn id(&self) -> Option { + fn id(&self) -> Option { None } fn request_layout( &mut self, - _: Option<&gpui::GlobalElementId>, + _: Option<&GlobalElementId>, cx: &mut WindowContext, - ) -> (gpui::LayoutId, Self::RequestLayoutState) { + ) -> (LayoutId, Self::RequestLayoutState) { let mut style = Style::default(); // Set the layout style relative to the table view to get same size. - style.position = gpui::Position::Absolute; + style.position = Position::Absolute; style.flex_grow = 1.0; style.flex_shrink = 1.0; style.size.width = relative(1.).into(); @@ -73,14 +79,14 @@ impl Element for ScrollableHandleElement { fn prepaint( &mut self, - _: Option<&gpui::GlobalElementId>, - bounds: gpui::Bounds, + _: Option<&GlobalElementId>, + bounds: Bounds, _: &mut Self::RequestLayoutState, cx: &mut WindowContext, ) -> Self::PrepaintState { - // Move y to bounds height to cover the table. + // Move y to bounds height to cover the parent view. let cover_bounds = Bounds { - origin: gpui::Point { + origin: Point { x: bounds.origin.x, y: bounds.origin.y - bounds.size.height, }, @@ -92,8 +98,8 @@ impl Element for ScrollableHandleElement { fn paint( &mut self, - _: Option<&gpui::GlobalElementId>, - _: gpui::Bounds, + _: Option<&GlobalElementId>, + _: Bounds, _: &mut Self::RequestLayoutState, hitbox: &mut Self::PrepaintState, cx: &mut WindowContext, @@ -115,9 +121,9 @@ impl Element for ScrollableHandleElement { cx.on_mouse_event({ let mouse_position = cx.mouse_position(); let scroll_handle = self.scroll_handle.clone(); + let old_offset = scroll_handle.offset(); let view_id = self.view.entity_id(); let is_horizontal = self.axis == ScrollAxis::Horizontal; - // let callback = self.on_scroll_offset_changed.as_mut(); move |event: &ScrollWheelEvent, _, cx| { if bounds.contains(&mouse_position) { @@ -128,8 +134,6 @@ impl Element for ScrollableHandleElement { let mut offset = scroll_handle.offset(); offset.x += delta.x; scroll_handle.set_offset(offset); - cx.notify(view_id); - cx.stop_propagation(); } if !is_horizontal && !delta.y.is_zero() { @@ -137,6 +141,9 @@ impl Element for ScrollableHandleElement { let mut offset = scroll_handle.offset(); offset.y += delta.y; scroll_handle.set_offset(offset); + } + + if old_offset != scroll_handle.offset() { cx.notify(view_id); cx.stop_propagation(); } diff --git a/crates/ui/src/table.rs b/crates/ui/src/table.rs index 1fe12a9c..53733c6c 100644 --- a/crates/ui/src/table.rs +++ b/crates/ui/src/table.rs @@ -2,7 +2,7 @@ use std::{cell::Cell, rc::Rc, time::Duration}; use crate::{ h_flex, - scroll::{ScrollAxis, ScrollableHandleElement}, + scroll::{ScrollAxis, ScrollableMask}, scrollbar::Scrollbar, theme::{ActiveTheme, Colorize}, v_flex, @@ -447,7 +447,7 @@ where .border_color(cx.theme().border) .bg(cx.theme().card) .child(inner_table) - .child(ScrollableHandleElement::new( + .child(ScrollableMask::new( cx.view().clone(), ScrollAxis::Horizontal, &horizontal_scroll_handle,