feat: add diff view component
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
@@ -54,9 +55,9 @@ struct AutohideState {
|
||||
}
|
||||
|
||||
impl Autohide {
|
||||
pub(crate) fn new(window: &mut Window, cx: &mut App) -> Self {
|
||||
pub(crate) fn new(key: ElementId, window: &mut Window, cx: &mut App) -> Self {
|
||||
let view = window.current_view();
|
||||
let state = window.use_keyed_state("scrollbar-autohide", cx, |_, _| AutohideState {
|
||||
let state = window.use_keyed_state(key, cx, |_, _| AutohideState {
|
||||
last_activity: None,
|
||||
hide_task: None,
|
||||
});
|
||||
@@ -195,6 +196,11 @@ impl ScrollArea {
|
||||
}
|
||||
}
|
||||
|
||||
/// Names keyed state under the scrollbar's own id.
|
||||
pub fn scrollbar_state_key(name: &'static str, id: &ElementId) -> ElementId {
|
||||
ElementId::NamedChild(Arc::new(id.clone()), SharedString::from(name))
|
||||
}
|
||||
|
||||
/// Pure thumb geometry for an overlay scrollbar.
|
||||
pub(crate) fn thumb_geometry(
|
||||
viewport: Pixels,
|
||||
@@ -247,11 +253,12 @@ impl RenderOnce for ScrollArea {
|
||||
ScrollbarVisibility::Always => false,
|
||||
ScrollbarVisibility::Autohide => true,
|
||||
};
|
||||
let id = self.id.clone();
|
||||
wrapper.extend(std::iter::once(
|
||||
canvas(|_, _, _| {}, {
|
||||
let handle = handle.clone();
|
||||
move |_, _, window, cx| {
|
||||
paint_scrollbar(&handle, autohide, window, cx);
|
||||
paint_scrollbar(&handle, &id, autohide, window, cx);
|
||||
}
|
||||
})
|
||||
.absolute()
|
||||
@@ -265,7 +272,13 @@ impl RenderOnce for ScrollArea {
|
||||
}
|
||||
|
||||
/// Paints the overlay scrollbar thumb.
|
||||
fn paint_scrollbar(handle: &ScrollHandle, autohide: bool, window: &mut Window, cx: &mut App) {
|
||||
fn paint_scrollbar(
|
||||
handle: &ScrollHandle,
|
||||
key: &ElementId,
|
||||
autohide: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
let theme = cx.theme();
|
||||
let view = window.current_view();
|
||||
|
||||
@@ -281,8 +294,9 @@ fn paint_scrollbar(handle: &ScrollHandle, autohide: bool, window: &mut Window, c
|
||||
return;
|
||||
}
|
||||
|
||||
let autohide_state = autohide.then(|| Autohide::new(window, cx));
|
||||
let drag = window.use_keyed_state("scrollbar-thumb-drag", cx, |_, _| {
|
||||
let autohide_state =
|
||||
autohide.then(|| Autohide::new(scrollbar_state_key("autohide", key), window, cx));
|
||||
let drag = window.use_keyed_state(scrollbar_state_key("thumb-drag", key), cx, |_, _| {
|
||||
Option::<(Pixels, Pixels)>::None
|
||||
});
|
||||
let dragging = drag.read(cx).is_some();
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
//! Overlay scrollbars for scroll surfaces, including gpui's virtualized
|
||||
//! `uniform_list` and `list`. Render the scrollbar as a later child of a
|
||||
//! `.relative()` container around the scrolled surface:
|
||||
//!
|
||||
//! ```
|
||||
//! div().relative()
|
||||
//! .child(uniform_list(...).track_scroll(&handle))
|
||||
//! .child(Scrollbar::vertical(handle))
|
||||
//! ```
|
||||
//! Overlay scrollbars for scroll surfaces.
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use gpui::{
|
||||
App, Bounds, DispatchPhase, IntoElement, ListState, MouseButton, MouseDownEvent,
|
||||
App, Bounds, DispatchPhase, ElementId, IntoElement, ListState, MouseButton, MouseDownEvent,
|
||||
MouseMoveEvent, MouseUpEvent, Pixels, Point, RenderOnce, ScrollEvent, ScrollHandle,
|
||||
Styled as _, UniformListScrollHandle, Window, canvas, fill, point,
|
||||
};
|
||||
use gpui_native_theme::ActiveTheme as _;
|
||||
|
||||
use crate::scroll_area::{Autohide, thumb_geometry, thumb_style};
|
||||
use crate::scroll_area::{Autohide, scrollbar_state_key, thumb_geometry, thumb_style};
|
||||
|
||||
/// Re-exported so callers only need the scrollbar module.
|
||||
pub use crate::scroll_area::ScrollbarVisibility;
|
||||
@@ -130,12 +122,13 @@ impl Axis {
|
||||
}
|
||||
}
|
||||
|
||||
/// An overlay scrollbar; the caller renders it over the scrolled surface.
|
||||
/// An overlay scrollbar, the caller renders it over the scrolled surface.
|
||||
#[derive(IntoElement)]
|
||||
pub struct Scrollbar {
|
||||
axis: Axis,
|
||||
handle: Rc<dyn ScrollbarHandle>,
|
||||
visibility: ScrollbarVisibility,
|
||||
key: ElementId,
|
||||
}
|
||||
|
||||
impl Scrollbar {
|
||||
@@ -148,6 +141,7 @@ impl Scrollbar {
|
||||
axis: Axis::Vertical,
|
||||
handle: Rc::new(handle),
|
||||
visibility: ScrollbarVisibility::default(),
|
||||
key: ElementId::Name("scrollbar".into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +154,7 @@ impl Scrollbar {
|
||||
axis: Axis::Horizontal,
|
||||
handle: Rc::new(handle),
|
||||
visibility: ScrollbarVisibility::default(),
|
||||
key: ElementId::Name("scrollbar".into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +163,12 @@ impl Scrollbar {
|
||||
self.visibility = visibility;
|
||||
self
|
||||
}
|
||||
|
||||
/// Names this scrollbar's state.
|
||||
pub fn key(mut self, key: impl Into<ElementId>) -> Self {
|
||||
self.key = key.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for Scrollbar {
|
||||
@@ -176,7 +177,8 @@ impl RenderOnce for Scrollbar {
|
||||
let handle = self.handle;
|
||||
let axis = self.axis;
|
||||
let visibility = self.visibility;
|
||||
move |_, _, window, cx| paint_scrollbar(&handle, axis, visibility, window, cx)
|
||||
let key = self.key;
|
||||
move |_, _, window, cx| paint_scrollbar(&handle, axis, visibility, &key, window, cx)
|
||||
})
|
||||
.absolute()
|
||||
.inset_0()
|
||||
@@ -190,6 +192,7 @@ fn paint_scrollbar(
|
||||
handle: &Rc<dyn ScrollbarHandle>,
|
||||
axis: Axis,
|
||||
visibility: ScrollbarVisibility,
|
||||
key: &ElementId,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
@@ -214,7 +217,9 @@ fn paint_scrollbar(
|
||||
ScrollbarVisibility::Always => false,
|
||||
ScrollbarVisibility::Autohide => true,
|
||||
};
|
||||
let autohide_state = autohide.then(|| Autohide::new(window, cx));
|
||||
|
||||
let autohide_state =
|
||||
autohide.then(|| Autohide::new(scrollbar_state_key("autohide", key), window, cx));
|
||||
|
||||
let track_length = viewport_along - inset * 2.0;
|
||||
|
||||
@@ -262,7 +267,9 @@ fn paint_scrollbar(
|
||||
}
|
||||
};
|
||||
|
||||
let drag = window.use_keyed_state("scrollbar-thumb-drag", cx, |_, _| Drag::None);
|
||||
let drag = window.use_keyed_state(scrollbar_state_key("thumb-drag", key), cx, |_, _| {
|
||||
Drag::None
|
||||
});
|
||||
let dragging = drag.read(cx).is_some();
|
||||
|
||||
let alpha = match &autohide_state {
|
||||
|
||||
Reference in New Issue
Block a user