diff --git a/crates/story/src/scrollable_story.rs b/crates/story/src/scrollable_story.rs index 0c81cb66..57441ec2 100644 --- a/crates/story/src/scrollable_story.rs +++ b/crates/story/src/scrollable_story.rs @@ -1,4 +1,3 @@ -use std::cell::Cell; use std::rc::Rc; use gpui::{ @@ -18,7 +17,7 @@ pub struct ScrollableStory { focus_handle: gpui::FocusHandle, scroll_handle: ScrollHandle, scroll_size: gpui::Size, - scroll_state: Rc>, + scroll_state: ScrollbarState, items: Vec, item_sizes: Rc>>, test_width: Pixels, @@ -41,7 +40,7 @@ impl ScrollableStory { Self { focus_handle: cx.focus_handle(), scroll_handle: ScrollHandle::new(), - scroll_state: Rc::new(Cell::new(ScrollbarState::default())), + scroll_state: ScrollbarState::default(), scroll_size: gpui::Size::default(), items, item_sizes: Rc::new(item_sizes), @@ -80,7 +79,7 @@ impl ScrollableStory { .map(|_| size(self.test_width, ITEM_HEIGHT)) .collect::>() .into(); - self.scroll_state.set(ScrollbarState::default()); + self.scroll_state = ScrollbarState::default(); cx.notify(); } diff --git a/crates/ui/src/dock/tiles.rs b/crates/ui/src/dock/tiles.rs index 2b46c155..91b85bf3 100644 --- a/crates/ui/src/dock/tiles.rs +++ b/crates/ui/src/dock/tiles.rs @@ -1,8 +1,6 @@ use std::{ any::Any, - cell::Cell, fmt::{Debug, Formatter}, - rc::Rc, sync::Arc, }; @@ -139,7 +137,7 @@ pub struct Tiles { resizing_drag_data: Option, bounds: Bounds, history: History, - scroll_state: Rc>, + scroll_state: ScrollbarState, scroll_handle: ScrollHandle, } @@ -193,7 +191,7 @@ impl Tiles { resizing_drag_data: None, bounds: Bounds::default(), history: History::new().group_interval(std::time::Duration::from_millis(100)), - scroll_state: Rc::new(Cell::new(ScrollbarState::default())), + scroll_state: ScrollbarState::default(), scroll_handle: ScrollHandle::default(), } } diff --git a/crates/ui/src/input/state.rs b/crates/ui/src/input/state.rs index 65733dca..4c5ef357 100644 --- a/crates/ui/src/input/state.rs +++ b/crates/ui/src/input/state.rs @@ -4,7 +4,7 @@ //! https://github.com/zed-industries/zed/blob/main/crates/gpui/examples/input.rs use serde::Deserialize; use smallvec::SmallVec; -use std::cell::{Cell, RefCell}; +use std::cell::RefCell; use std::ops::{Deref, Range}; use std::rc::Rc; use unicode_segmentation::*; @@ -260,7 +260,7 @@ pub struct InputState { pub(super) pattern: Option, pub(super) validate: Option bool + 'static>>, pub(crate) scroll_handle: ScrollHandle, - pub(super) scrollbar_state: Rc>, + pub(super) scroll_state: ScrollbarState, /// The size of the scrollable content. pub(crate) scroll_size: gpui::Size, pub(crate) line_number_width: Pixels, @@ -337,7 +337,7 @@ impl InputState { last_line_height: px(20.), last_cursor_offset: None, scroll_handle: ScrollHandle::new(), - scrollbar_state: Rc::new(Cell::new(ScrollbarState::default())), + scroll_state: ScrollbarState::default(), scroll_size: gpui::size(px(0.), px(0.)), preferred_x_offset: None, line_number_width: px(0.), diff --git a/crates/ui/src/input/text_input.rs b/crates/ui/src/input/text_input.rs index 42bb1ddb..26dd429b 100644 --- a/crates/ui/src/input/text_input.rs +++ b/crates/ui/src/input/text_input.rs @@ -7,7 +7,7 @@ use gpui::{ use crate::button::{Button, ButtonVariants as _}; use crate::indicator::Indicator; use crate::input::clear_button; -use crate::scroll::{Scrollbar, ScrollbarAxis}; +use crate::scroll::Scrollbar; use crate::ActiveTheme; use crate::{h_flex, StyledExt}; use crate::{IconName, Size}; @@ -308,15 +308,12 @@ impl RenderOnce for TextInput { .left_0() .right(px(1.)) .bottom_0() - .child( - Scrollbar::vertical( - entity_id, - state.scrollbar_state.clone(), - state.scroll_handle.clone(), - scroll_size, - ) - .axis(ScrollbarAxis::Vertical), - ), + .child(Scrollbar::vertical( + entity_id, + state.scroll_state.clone(), + state.scroll_handle.clone(), + scroll_size, + )), ) } else { this diff --git a/crates/ui/src/list/list.rs b/crates/ui/src/list/list.rs index 41171780..bf62a0cb 100644 --- a/crates/ui/src/list/list.rs +++ b/crates/ui/src/list/list.rs @@ -1,6 +1,5 @@ use std::ops::Range; use std::time::Duration; -use std::{cell::Cell, rc::Rc}; use crate::actions::{Cancel, Confirm, SelectNext, SelectPrev}; use crate::input::InputState; @@ -161,7 +160,7 @@ pub struct List { querying: bool, scrollbar_visible: bool, vertical_scroll_handle: UniformListScrollHandle, - scrollbar_state: Rc>, + scroll_state: ScrollbarState, pub(crate) size: Size, selected_index: Option, right_clicked_index: Option, @@ -193,7 +192,7 @@ where selected_index: None, right_clicked_index: None, vertical_scroll_handle: UniformListScrollHandle::new(), - scrollbar_state: Rc::new(Cell::new(ScrollbarState::new())), + scroll_state: ScrollbarState::default(), max_height: None, scrollbar_visible: true, selectable: true, @@ -295,7 +294,7 @@ where Some(Scrollbar::uniform_scroll( cx.entity().entity_id(), - self.scrollbar_state.clone(), + self.scroll_state.clone(), self.vertical_scroll_handle.clone(), )) } diff --git a/crates/ui/src/menu/popup_menu.rs b/crates/ui/src/menu/popup_menu.rs index 796d606d..0901bd5c 100644 --- a/crates/ui/src/menu/popup_menu.rs +++ b/crates/ui/src/menu/popup_menu.rs @@ -12,7 +12,6 @@ use gpui::{ SharedString, StatefulInteractiveElement, Styled, WeakEntity, Window, }; use gpui::{MouseDownEvent, Subscription}; -use std::cell::Cell; use std::ops::Deref; use std::rc::Rc; @@ -109,7 +108,7 @@ pub struct PopupMenu { scrollable: bool, external_link_icon: bool, scroll_handle: ScrollHandle, - scroll_state: Rc>, + scroll_state: ScrollbarState, previous_focus_handle: Option, _subscriptions: Vec, @@ -144,7 +143,7 @@ impl PopupMenu { bounds: Bounds::default(), scrollable: false, scroll_handle: ScrollHandle::default(), - scroll_state: Rc::new(Cell::new(ScrollbarState::default())), + scroll_state: ScrollbarState::default(), external_link_icon: true, _subscriptions, }; diff --git a/crates/ui/src/scroll/scrollable.rs b/crates/ui/src/scroll/scrollable.rs index fadb3a3c..d6fa1eaa 100644 --- a/crates/ui/src/scroll/scrollable.rs +++ b/crates/ui/src/scroll/scrollable.rs @@ -75,7 +75,7 @@ where pub struct ScrollViewState { scroll_size: Rc>>, - state: Rc>, + state: ScrollbarState, handle: ScrollHandle, } @@ -84,7 +84,7 @@ impl Default for ScrollViewState { Self { handle: ScrollHandle::new(), scroll_size: Rc::new(Cell::new(Size::default())), - state: Rc::new(Cell::new(ScrollbarState::default())), + state: ScrollbarState::default(), } } } diff --git a/crates/ui/src/scroll/scrollbar.rs b/crates/ui/src/scroll/scrollbar.rs index defa48f8..37cf892e 100644 --- a/crates/ui/src/scroll/scrollbar.rs +++ b/crates/ui/src/scroll/scrollbar.rs @@ -1,5 +1,6 @@ use std::{ cell::Cell, + ops::Deref, rc::Rc, time::{Duration, Instant}, }; @@ -79,8 +80,11 @@ impl ScrollHandleOffsetable for UniformListScrollHandle { } } +#[derive(Debug, Clone)] +pub struct ScrollbarState(Rc>); + #[derive(Debug, Clone, Copy)] -pub struct ScrollbarState { +pub struct ScrollbarStateInner { hovered_axis: Option, hovered_on_thumb: Option, dragged_axis: Option, @@ -93,7 +97,7 @@ pub struct ScrollbarState { impl Default for ScrollbarState { fn default() -> Self { - Self { + Self(Rc::new(Cell::new(ScrollbarStateInner { hovered_axis: None, hovered_on_thumb: None, dragged_axis: None, @@ -101,15 +105,19 @@ impl Default for ScrollbarState { last_scroll_offset: point(px(0.), px(0.)), last_scroll_time: None, last_update: Instant::now(), - } + }))) } } -impl ScrollbarState { - pub fn new() -> Self { - Self::default() - } +impl Deref for ScrollbarState { + type Target = Rc>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ScrollbarStateInner { fn with_drag_pos(&self, axis: ScrollbarAxis, pos: Point) -> Self { let mut state = *self; if axis.is_vertical() { @@ -232,7 +240,7 @@ pub struct Scrollbar { axis: ScrollbarAxis, scroll_handle: Rc>, scroll_size: gpui::Size, - state: Rc>, + state: ScrollbarState, /// Maximum frames per second for scrolling by drag. Default is 120 FPS. /// /// This is used to limit the update rate of the scrollbar when it is @@ -243,7 +251,7 @@ pub struct Scrollbar { impl Scrollbar { fn new( view_id: EntityId, - state: Rc>, + state: ScrollbarState, axis: ScrollbarAxis, scroll_handle: impl ScrollHandleOffsetable + 'static, scroll_size: gpui::Size, @@ -261,7 +269,7 @@ impl Scrollbar { /// Create with vertical and horizontal scrollbar. pub fn both( view_id: EntityId, - state: Rc>, + state: ScrollbarState, scroll_handle: impl ScrollHandleOffsetable + 'static, scroll_size: gpui::Size, ) -> Self { @@ -277,7 +285,7 @@ impl Scrollbar { /// Create with horizontal scrollbar. pub fn horizontal( view_id: EntityId, - state: Rc>, + state: ScrollbarState, scroll_handle: impl ScrollHandleOffsetable + 'static, scroll_size: gpui::Size, ) -> Self { @@ -293,7 +301,7 @@ impl Scrollbar { /// Create with vertical scrollbar. pub fn vertical( view_id: EntityId, - state: Rc>, + state: ScrollbarState, scroll_handle: impl ScrollHandleOffsetable + 'static, scroll_size: gpui::Size, ) -> Self { @@ -309,7 +317,7 @@ impl Scrollbar { /// Create vertical scrollbar for uniform list. pub fn uniform_scroll( view_id: EntityId, - state: Rc>, + state: ScrollbarState, scroll_handle: UniformListScrollHandle, ) -> Self { let scroll_size = scroll_handle diff --git a/crates/ui/src/table.rs b/crates/ui/src/table.rs index 2ae993b2..aeec6548 100644 --- a/crates/ui/src/table.rs +++ b/crates/ui/src/table.rs @@ -1,4 +1,4 @@ -use std::{cell::Cell, ops::Range, rc::Rc, time::Duration}; +use std::{ops::Range, rc::Rc, time::Duration}; use crate::{ actions::{Cancel, SelectNext, SelectPrev}, @@ -147,9 +147,9 @@ pub struct Table { fixed_cols: FixedCols, pub vertical_scroll_handle: UniformListScrollHandle, - pub vertical_scrollbar_state: Rc>, + pub vertical_scroll_state: ScrollbarState, pub horizontal_scroll_handle: ScrollHandle, - pub horizontal_scrollbar_state: Rc>, + pub horizontal_scroll_state: ScrollbarState, scrollbar_visible: Edges, selected_row: Option, @@ -391,8 +391,8 @@ where fixed_cols: FixedCols::default(), horizontal_scroll_handle: ScrollHandle::new(), vertical_scroll_handle: UniformListScrollHandle::new(), - vertical_scrollbar_state: Rc::new(Cell::new(ScrollbarState::new())), - horizontal_scrollbar_state: Rc::new(Cell::new(ScrollbarState::new())), + vertical_scroll_state: ScrollbarState::default(), + horizontal_scroll_state: ScrollbarState::default(), selection_state: SelectionState::Row, selected_row: None, right_clicked_row: None, @@ -867,7 +867,7 @@ where _: &mut Window, cx: &mut Context, ) -> Option { - let state = self.vertical_scrollbar_state.clone(); + let state = self.vertical_scroll_state.clone(); Some( div() @@ -896,7 +896,7 @@ where _: &mut Window, cx: &mut Context, ) -> impl IntoElement { - let state = self.horizontal_scrollbar_state.clone(); + let state = self.horizontal_scroll_state.clone(); div() .occlude()