use gpui::{Bounds, ListState, Pixels, Point, ScrollHandle, point, px};
#[derive(Clone)]
pub enum Scroller {
Pane(ScrollHandle),
List(ListState),
}
impl Scroller {
pub fn bounds(&self) -> Bounds<Pixels> {
match self {
Self::Pane(handle) => handle.bounds(),
Self::List(state) => state.viewport_bounds(),
}
}
pub fn offset(&self) -> Point<Pixels> {
match self {
Self::Pane(handle) => {
let (offset, max) = (handle.offset(), handle.max_offset());
point(
offset.x.clamp(-max.x, px(0.)),
offset.y.clamp(-max.y, px(0.)),
)
}
Self::List(state) => {
let offset = state.scroll_px_offset_for_scrollbar();
point(offset.x, offset.y.max(-state.max_offset_for_scrollbar().y))
}
}
}
pub fn max_offset(&self) -> Point<Pixels> {
match self {
Self::Pane(handle) => handle.max_offset(),
Self::List(state) => state.max_offset_for_scrollbar(),
}
}
pub fn set_offset(&self, offset: Point<Pixels>) {
match self {
Self::Pane(handle) => handle.set_offset(offset),
Self::List(state) => state.set_offset_from_scrollbar(offset),
}
}
pub fn scroll_to_end(&self) {
match self {
Self::Pane(handle) => {
handle.set_offset(point(handle.offset().x, -handle.max_offset().y))
}
Self::List(state) => state.scroll_to_end(),
}
}
}
impl From<ScrollHandle> for Scroller {
fn from(handle: ScrollHandle) -> Self {
Self::Pane(handle)
}
}
impl From<&ScrollHandle> for Scroller {
fn from(handle: &ScrollHandle) -> Self {
Self::Pane(handle.clone())
}
}
impl From<ListState> for Scroller {
fn from(state: ListState) -> Self {
Self::List(state)
}
}
impl From<&ListState> for Scroller {
fn from(state: &ListState) -> Self {
Self::List(state.clone())
}
}