feat: add diff view component

This commit is contained in:
2026-11-06 08:01:23 +07:00
parent f272f80d09
commit 7214c70ea7
11 changed files with 1067 additions and 35 deletions
+22 -15
View File
@@ -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 {