editor: Refactor scrollbar-related code (#24134)
This PR is primarily an implementation of @osiewicz [comment](https://github.com/zed-industries/zed/pull/19495#pullrequestreview-2488877957) in an effort to increase maintainability after the horizontal editor scrollbar was added in #19495 . I also want to build on these changes in future PRs to adress some other small bugs. This primarily does the following: 1. Uses `along` wherever possible 2. Fixes the amount of mouse event listeners attached to the editor when scrollbars are displayed to 2 instead of 2-4 in case both scrollbars are displayed. This can be done since only one scrollbar can be dragged by the cursor at any given time, so the event listeners now account for that. The state reflecting the scrollbar dragging state was also updated accordingly. It does not change any functionality besides the aforementioned event listener code as well as some minor bugs which where present after #19495 , namely: - One missing `cx.stop_propagation()` (see [here](a8741dc310/crates/editor/src/element.rs (L4684)
) and [here](a8741dc310/crates/editor/src/element.rs (L4838)
) respectively). - The horizontal scrollbar thumb having a small border on the left side, which seems to be unintended for the horizontal scrollbar whilst intended for the vertical one. Since this is a minimal change, I figured it could be already included in this PR. This PR admittetly grew quite large over time, however, much of the diff is just renames to account for the code now working for both axes as well as moved code. The logic remains (or should at least be) unaffected. If I should split this into two PRs or remove some of the changes, please let me know. Release Notes: - N/A
This commit is contained in:
parent
1574a3a2fd
commit
a65ea2708c
3 changed files with 394 additions and 563 deletions
|
@ -2,7 +2,7 @@ mod actions;
|
|||
pub(crate) mod autoscroll;
|
||||
pub(crate) mod scroll_amount;
|
||||
|
||||
use crate::editor_settings::{ScrollBeyondLastLine, ScrollbarAxes};
|
||||
use crate::editor_settings::ScrollBeyondLastLine;
|
||||
use crate::{
|
||||
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||
hover_popover::hide_hover,
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||
};
|
||||
pub use autoscroll::{Autoscroll, AutoscrollStrategy};
|
||||
use core::fmt::Debug;
|
||||
use gpui::{point, px, Along, App, Axis, Context, Global, Pixels, Task, Window};
|
||||
use gpui::{point, px, App, Axis, Context, Global, Pixels, Task, Window};
|
||||
use language::{Bias, Point};
|
||||
pub use scroll_amount::ScrollAmount;
|
||||
use settings::Settings;
|
||||
|
@ -61,55 +61,6 @@ impl ScrollAnchor {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AxisPair<T: Clone> {
|
||||
pub vertical: T,
|
||||
pub horizontal: T,
|
||||
}
|
||||
|
||||
pub fn axis_pair<T: Clone>(horizontal: T, vertical: T) -> AxisPair<T> {
|
||||
AxisPair {
|
||||
vertical,
|
||||
horizontal,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> AxisPair<T> {
|
||||
pub fn as_xy(&self) -> (&T, &T) {
|
||||
(&self.horizontal, &self.vertical)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Along for AxisPair<T> {
|
||||
type Unit = T;
|
||||
|
||||
fn along(&self, axis: gpui::Axis) -> Self::Unit {
|
||||
match axis {
|
||||
gpui::Axis::Horizontal => self.horizontal.clone(),
|
||||
gpui::Axis::Vertical => self.vertical.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_along(&self, axis: gpui::Axis, f: impl FnOnce(Self::Unit) -> Self::Unit) -> Self {
|
||||
match axis {
|
||||
gpui::Axis::Horizontal => Self {
|
||||
horizontal: f(self.horizontal.clone()),
|
||||
vertical: self.vertical.clone(),
|
||||
},
|
||||
gpui::Axis::Vertical => Self {
|
||||
horizontal: self.horizontal.clone(),
|
||||
vertical: f(self.vertical.clone()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ScrollbarAxes> for AxisPair<bool> {
|
||||
fn from(value: ScrollbarAxes) -> Self {
|
||||
axis_pair(value.horizontal, value.vertical)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct OngoingScroll {
|
||||
last_event: Instant,
|
||||
|
@ -180,7 +131,7 @@ pub struct ScrollManager {
|
|||
last_autoscroll: Option<(gpui::Point<f32>, f32, f32, AutoscrollStrategy)>,
|
||||
show_scrollbars: bool,
|
||||
hide_scrollbar_task: Option<Task<()>>,
|
||||
dragging_scrollbar: AxisPair<bool>,
|
||||
dragging_scrollbar: Option<Axis>,
|
||||
visible_line_count: Option<f32>,
|
||||
forbid_vertical_scroll: bool,
|
||||
}
|
||||
|
@ -194,7 +145,7 @@ impl ScrollManager {
|
|||
autoscroll_request: None,
|
||||
show_scrollbars: true,
|
||||
hide_scrollbar_task: None,
|
||||
dragging_scrollbar: axis_pair(false, false),
|
||||
dragging_scrollbar: None,
|
||||
last_autoscroll: None,
|
||||
visible_line_count: None,
|
||||
forbid_vertical_scroll: false,
|
||||
|
@ -312,7 +263,7 @@ impl ScrollManager {
|
|||
}
|
||||
self.anchor = anchor;
|
||||
cx.emit(EditorEvent::ScrollPositionChanged { local, autoscroll });
|
||||
self.show_scrollbar(window, cx);
|
||||
self.show_scrollbars(window, cx);
|
||||
self.autoscroll_request.take();
|
||||
if let Some(workspace_id) = workspace_id {
|
||||
let item_id = cx.entity().entity_id().as_u64() as ItemId;
|
||||
|
@ -334,7 +285,7 @@ impl ScrollManager {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn show_scrollbar(&mut self, window: &mut Window, cx: &mut Context<Editor>) {
|
||||
pub fn show_scrollbars(&mut self, window: &mut Window, cx: &mut Context<Editor>) {
|
||||
if !self.show_scrollbars {
|
||||
self.show_scrollbars = true;
|
||||
cx.notify();
|
||||
|
@ -365,18 +316,26 @@ impl ScrollManager {
|
|||
self.autoscroll_request.map(|(autoscroll, _)| autoscroll)
|
||||
}
|
||||
|
||||
pub fn is_dragging_scrollbar(&self, axis: Axis) -> bool {
|
||||
self.dragging_scrollbar.along(axis)
|
||||
pub fn dragging_scrollbar_axis(&self) -> Option<Axis> {
|
||||
self.dragging_scrollbar
|
||||
}
|
||||
|
||||
pub fn set_is_dragging_scrollbar(
|
||||
&mut self,
|
||||
axis: Axis,
|
||||
dragging: bool,
|
||||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
self.dragging_scrollbar = self.dragging_scrollbar.apply_along(axis, |_| dragging);
|
||||
cx.notify();
|
||||
pub fn any_scrollbar_dragged(&self) -> bool {
|
||||
self.dragging_scrollbar.is_some()
|
||||
}
|
||||
|
||||
pub fn set_dragged_scrollbar_axis(&mut self, axis: Axis, cx: &mut Context<Editor>) {
|
||||
if self.dragging_scrollbar != Some(axis) {
|
||||
self.dragging_scrollbar = Some(axis);
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset_scrollbar_dragging_state(&mut self, cx: &mut Context<Editor>) {
|
||||
if self.dragging_scrollbar.is_some() {
|
||||
self.dragging_scrollbar = None;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clamp_scroll_left(&mut self, max: f32) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue