ui: Clean up scrollbar component (#35121)
This PR does some minor cleanup to the scrollbar component. Namely, it removes some clones, reduces the amount of unnecessary notifies and ensures the scrollbar hover state is more accurately updated. Release Notes: - N/A
This commit is contained in:
parent
4854f83e8c
commit
e911364664
1 changed files with 48 additions and 34 deletions
|
@ -4,8 +4,8 @@ use crate::{IntoElement, prelude::*, px, relative};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Along, App, Axis as ScrollbarAxis, BorderStyle, Bounds, ContentMask, Corners, CursorStyle,
|
Along, App, Axis as ScrollbarAxis, BorderStyle, Bounds, ContentMask, Corners, CursorStyle,
|
||||||
Edges, Element, ElementId, Entity, EntityId, GlobalElementId, Hitbox, HitboxBehavior, Hsla,
|
Edges, Element, ElementId, Entity, EntityId, GlobalElementId, Hitbox, HitboxBehavior, Hsla,
|
||||||
IsZero, LayoutId, ListState, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point,
|
IsZero, LayoutId, ListState, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
|
||||||
ScrollHandle, ScrollWheelEvent, Size, Style, UniformListScrollHandle, Window, quad,
|
Point, ScrollHandle, ScrollWheelEvent, Size, Style, UniformListScrollHandle, Window, quad,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Scrollbar {
|
pub struct Scrollbar {
|
||||||
|
@ -301,8 +301,6 @@ impl Element for Scrollbar {
|
||||||
window.set_cursor_style(CursorStyle::Arrow, hitbox);
|
window.set_cursor_style(CursorStyle::Arrow, hitbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
let scroll = self.state.scroll_handle.clone();
|
|
||||||
|
|
||||||
enum ScrollbarMouseEvent {
|
enum ScrollbarMouseEvent {
|
||||||
GutterClick,
|
GutterClick,
|
||||||
ThumbDrag(Pixels),
|
ThumbDrag(Pixels),
|
||||||
|
@ -337,10 +335,12 @@ impl Element for Scrollbar {
|
||||||
};
|
};
|
||||||
|
|
||||||
window.on_mouse_event({
|
window.on_mouse_event({
|
||||||
let scroll = scroll.clone();
|
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
move |event: &MouseDownEvent, phase, _, _| {
|
move |event: &MouseDownEvent, phase, _, _| {
|
||||||
if !(phase.bubble() && bounds.contains(&event.position)) {
|
if !phase.bubble()
|
||||||
|
|| event.button != MouseButton::Left
|
||||||
|
|| bounds.contains(&event.position)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,57 +348,71 @@ impl Element for Scrollbar {
|
||||||
let offset = event.position.along(axis) - thumb_bounds.origin.along(axis);
|
let offset = event.position.along(axis) - thumb_bounds.origin.along(axis);
|
||||||
state.set_dragging(offset);
|
state.set_dragging(offset);
|
||||||
} else {
|
} else {
|
||||||
|
let scroll_handle = state.scroll_handle();
|
||||||
let click_offset = compute_click_offset(
|
let click_offset = compute_click_offset(
|
||||||
event.position,
|
event.position,
|
||||||
scroll.max_offset(),
|
scroll_handle.max_offset(),
|
||||||
ScrollbarMouseEvent::GutterClick,
|
ScrollbarMouseEvent::GutterClick,
|
||||||
);
|
);
|
||||||
scroll.set_offset(scroll.offset().apply_along(axis, |_| click_offset));
|
scroll_handle
|
||||||
|
.set_offset(scroll_handle.offset().apply_along(axis, |_| click_offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.on_mouse_event({
|
window.on_mouse_event({
|
||||||
let scroll = scroll.clone();
|
let scroll_handle = self.state.scroll_handle().clone();
|
||||||
move |event: &ScrollWheelEvent, phase, window, _| {
|
move |event: &ScrollWheelEvent, phase, window, _| {
|
||||||
if phase.bubble() && bounds.contains(&event.position) {
|
if phase.bubble() && bounds.contains(&event.position) {
|
||||||
let current_offset = scroll.offset();
|
let current_offset = scroll_handle.offset();
|
||||||
scroll.set_offset(
|
scroll_handle.set_offset(
|
||||||
current_offset + event.delta.pixel_delta(window.line_height()),
|
current_offset + event.delta.pixel_delta(window.line_height()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let state = self.state.clone();
|
window.on_mouse_event({
|
||||||
window.on_mouse_event(move |event: &MouseMoveEvent, _, window, cx| {
|
let state = self.state.clone();
|
||||||
match state.thumb_state.get() {
|
move |event: &MouseMoveEvent, phase, window, cx| {
|
||||||
ThumbState::Dragging(drag_state) if event.dragging() => {
|
if phase.bubble() {
|
||||||
let drag_offset = compute_click_offset(
|
match state.thumb_state.get() {
|
||||||
event.position,
|
ThumbState::Dragging(drag_state) if event.dragging() => {
|
||||||
scroll.max_offset(),
|
let scroll_handle = state.scroll_handle();
|
||||||
ScrollbarMouseEvent::ThumbDrag(drag_state),
|
let drag_offset = compute_click_offset(
|
||||||
);
|
event.position,
|
||||||
scroll.set_offset(scroll.offset().apply_along(axis, |_| drag_offset));
|
scroll_handle.max_offset(),
|
||||||
window.refresh();
|
ScrollbarMouseEvent::ThumbDrag(drag_state),
|
||||||
if let Some(id) = state.parent_id {
|
);
|
||||||
cx.notify(id);
|
scroll_handle.set_offset(
|
||||||
|
scroll_handle.offset().apply_along(axis, |_| drag_offset),
|
||||||
|
);
|
||||||
|
window.refresh();
|
||||||
|
if let Some(id) = state.parent_id {
|
||||||
|
cx.notify(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ if event.pressed_button.is_none() => {
|
||||||
|
state.set_thumb_hovered(thumb_bounds.contains(&event.position))
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => state.set_thumb_hovered(thumb_bounds.contains(&event.position)),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let state = self.state.clone();
|
|
||||||
let scroll = self.state.scroll_handle.clone();
|
window.on_mouse_event({
|
||||||
window.on_mouse_event(move |event: &MouseUpEvent, phase, _, cx| {
|
let state = self.state.clone();
|
||||||
if phase.bubble() {
|
move |event: &MouseUpEvent, phase, _, cx| {
|
||||||
if state.is_dragging() {
|
if phase.bubble() {
|
||||||
|
if state.is_dragging() {
|
||||||
|
state.scroll_handle().drag_ended();
|
||||||
|
if let Some(id) = state.parent_id {
|
||||||
|
cx.notify(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
state.set_thumb_hovered(thumb_bounds.contains(&event.position));
|
state.set_thumb_hovered(thumb_bounds.contains(&event.position));
|
||||||
}
|
}
|
||||||
scroll.drag_ended();
|
|
||||||
if let Some(id) = state.parent_id {
|
|
||||||
cx.notify(id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue