tiles: Add scrollbar_show option to Tiles (#1496)
This commit is contained in:
parent
b7815ed6ec
commit
fbaddbe9e3
3 changed files with 67 additions and 27 deletions
|
|
@ -7,6 +7,7 @@ use gpui_component::{
|
|||
PanelState, PanelView, register_panel,
|
||||
},
|
||||
input::{Input, InputState},
|
||||
scroll::ScrollbarShow,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
|
@ -239,6 +240,17 @@ impl StoryTiles {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn set_scrollbar_show(dock_area: &mut DockArea, cx: &mut App) {
|
||||
match dock_area.items() {
|
||||
DockItem::Tiles { view, .. } => {
|
||||
view.update(cx, |this, cx| {
|
||||
this.set_scrollbar_show(Some(ScrollbarShow::Always), cx);
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_tiles(
|
||||
dock_area: Entity<DockArea>,
|
||||
window: &mut Window,
|
||||
|
|
@ -273,7 +285,7 @@ impl StoryTiles {
|
|||
|
||||
dock_area.update(cx, |dock_area, cx| {
|
||||
dock_area.load(state, window, cx).context("load layout")?;
|
||||
|
||||
Self::set_scrollbar_show(dock_area, cx);
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})
|
||||
}
|
||||
|
|
@ -284,11 +296,12 @@ impl StoryTiles {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let dock_item = Self::init_default_layout(&dock_area, window, cx);
|
||||
_ = dock_area.update(cx, |view, cx| {
|
||||
view.set_version(TILES_DOCK_AREA.version, window, cx);
|
||||
view.set_center(dock_item, window, cx);
|
||||
_ = dock_area.update(cx, |dock_area, cx| {
|
||||
dock_area.set_version(TILES_DOCK_AREA.version, window, cx);
|
||||
dock_area.set_center(dock_item, window, cx);
|
||||
|
||||
Self::save_tiles(&view.dump(cx)).unwrap();
|
||||
Self::set_scrollbar_show(dock_area, cx);
|
||||
Self::save_tiles(&dock_area.dump(cx)).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
use crate::{
|
||||
h_flex,
|
||||
history::{History, HistoryItem},
|
||||
scroll::{Scrollbar, ScrollbarState},
|
||||
scroll::{Scrollbar, ScrollbarShow, ScrollbarState},
|
||||
v_flex, ActiveTheme, Icon, IconName,
|
||||
};
|
||||
|
||||
|
|
@ -15,10 +15,11 @@ use super::{
|
|||
DockArea, Panel, PanelEvent, PanelInfo, PanelState, PanelView, StackPanel, TabPanel, TileMeta,
|
||||
};
|
||||
use gpui::{
|
||||
actions, canvas, div, px, size, AnyElement, App, AppContext, Bounds, Context, DismissEvent,
|
||||
DragMoveEvent, Empty, EntityId, EventEmitter, FocusHandle, Focusable, InteractiveElement,
|
||||
IntoElement, MouseButton, MouseDownEvent, MouseUpEvent, ParentElement, Pixels, Point, Render,
|
||||
ScrollHandle, Size, StatefulInteractiveElement, Styled, WeakEntity, Window,
|
||||
actions, canvas, div, prelude::FluentBuilder, px, size, AnyElement, App, AppContext, Bounds,
|
||||
Context, DismissEvent, DragMoveEvent, Empty, EntityId, EventEmitter, FocusHandle, Focusable,
|
||||
InteractiveElement, IntoElement, MouseButton, MouseDownEvent, MouseUpEvent, ParentElement,
|
||||
Pixels, Point, Render, ScrollHandle, Size, StatefulInteractiveElement, Styled, WeakEntity,
|
||||
Window,
|
||||
};
|
||||
|
||||
actions!(tiles, [Undo, Redo]);
|
||||
|
|
@ -140,6 +141,7 @@ pub struct Tiles {
|
|||
history: History<TileChange>,
|
||||
scroll_state: ScrollbarState,
|
||||
scroll_handle: ScrollHandle,
|
||||
scrollbar_show: Option<ScrollbarShow>,
|
||||
}
|
||||
|
||||
impl Panel for Tiles {
|
||||
|
|
@ -189,6 +191,7 @@ impl Tiles {
|
|||
dragging_initial_mouse: Point::default(),
|
||||
dragging_initial_bounds: Bounds::default(),
|
||||
resizing_id: None,
|
||||
scrollbar_show: None,
|
||||
resizing_drag_data: None,
|
||||
bounds: Bounds::default(),
|
||||
history: History::new().group_interval(std::time::Duration::from_millis(100)),
|
||||
|
|
@ -197,6 +200,16 @@ impl Tiles {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the scrollbar show mode [`ScrollbarShow`], if not set use the `cx.theme().scrollbar_show`.
|
||||
pub fn set_scrollbar_show(
|
||||
&mut self,
|
||||
scrollbar_show: Option<ScrollbarShow>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.scrollbar_show = scrollbar_show;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn panels(&self) -> &[TileItem] {
|
||||
&self.panels
|
||||
}
|
||||
|
|
@ -1058,7 +1071,10 @@ impl Render for Tiles {
|
|||
.bottom_0()
|
||||
.child(
|
||||
Scrollbar::both(&self.scroll_state, &self.scroll_handle)
|
||||
.scroll_size(scroll_size),
|
||||
.scroll_size(scroll_size)
|
||||
.when_some(self.scrollbar_show, |this, scrollbar_show| {
|
||||
this.scrollbar_show(scrollbar_show)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.size_full()
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ use std::{
|
|||
|
||||
use crate::{ActiveTheme, AxisExt};
|
||||
use gpui::{
|
||||
fill, point, px, relative, size, App, Axis, BorderStyle, Bounds, ContentMask, Corner,
|
||||
CursorStyle, Edges, Element, GlobalElementId, Hitbox, HitboxBehavior, Hsla, InspectorElementId,
|
||||
IntoElement, IsZero, LayoutId, ListState, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
|
||||
PaintQuad, Pixels, Point, Position, ScrollHandle, ScrollWheelEvent, Size, Style, Timer,
|
||||
UniformListScrollHandle, Window,
|
||||
fill, point, px, relative, size, App, Axis, BorderStyle, Bounds,
|
||||
ContentMask, Corner, CursorStyle, Edges, Element, GlobalElementId, Hitbox, HitboxBehavior,
|
||||
Hsla, InspectorElementId, IntoElement, IsZero, LayoutId, ListState, MouseDownEvent,
|
||||
MouseMoveEvent, MouseUpEvent, PaintQuad, Pixels, Point, Position, ScrollHandle,
|
||||
ScrollWheelEvent, Size, Style, Timer, UniformListScrollHandle, Window,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -289,6 +289,7 @@ impl ScrollbarAxis {
|
|||
/// Scrollbar control for scroll-area or a uniform-list.
|
||||
pub struct Scrollbar {
|
||||
axis: ScrollbarAxis,
|
||||
scrollbar_show: Option<ScrollbarShow>,
|
||||
scroll_handle: Rc<Box<dyn ScrollHandleOffsetable>>,
|
||||
state: ScrollbarState,
|
||||
scroll_size: Option<Size<Pixels>>,
|
||||
|
|
@ -308,6 +309,7 @@ impl Scrollbar {
|
|||
Self {
|
||||
state: state.clone(),
|
||||
axis: axis.into(),
|
||||
scrollbar_show: None,
|
||||
scroll_handle: Rc::new(Box::new(scroll_handle.clone())),
|
||||
max_fps: 120,
|
||||
scroll_size: None,
|
||||
|
|
@ -327,6 +329,12 @@ impl Scrollbar {
|
|||
Self::new(ScrollbarAxis::Both, state, scroll_handle)
|
||||
}
|
||||
|
||||
/// Set the scrollbar show mode [`ScrollbarShow`], if not set use the `cx.theme().scrollbar_show`.
|
||||
pub fn scrollbar_show(mut self, scrollbar_show: ScrollbarShow) -> Self {
|
||||
self.scrollbar_show = Some(scrollbar_show);
|
||||
self
|
||||
}
|
||||
|
||||
/// Create with horizontal scrollbar.
|
||||
pub fn horizontal(
|
||||
state: &ScrollbarState,
|
||||
|
|
@ -408,8 +416,9 @@ impl Scrollbar {
|
|||
)
|
||||
}
|
||||
|
||||
fn style_for_normal(cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) {
|
||||
let (width, inset, radius) = match cx.theme().scrollbar_show {
|
||||
fn style_for_normal(&self, cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) {
|
||||
let scrollbar_show = self.scrollbar_show.unwrap_or(cx.theme().scrollbar_show);
|
||||
let (width, inset, radius) = match scrollbar_show {
|
||||
ScrollbarShow::Scrolling => (THUMB_WIDTH, THUMB_INSET, THUMB_RADIUS),
|
||||
_ => (THUMB_ACTIVE_WIDTH, THUMB_ACTIVE_INSET, THUMB_ACTIVE_RADIUS),
|
||||
};
|
||||
|
|
@ -424,8 +433,9 @@ impl Scrollbar {
|
|||
)
|
||||
}
|
||||
|
||||
fn style_for_idle(cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) {
|
||||
let (width, inset, radius) = match cx.theme().scrollbar_show {
|
||||
fn style_for_idle(&self, cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) {
|
||||
let scrollbar_show = self.scrollbar_show.unwrap_or(cx.theme().scrollbar_show);
|
||||
let (width, inset, radius) = match scrollbar_show {
|
||||
ScrollbarShow::Scrolling => (THUMB_WIDTH, THUMB_INSET, THUMB_RADIUS),
|
||||
_ => (THUMB_ACTIVE_WIDTH, THUMB_ACTIVE_INSET, THUMB_ACTIVE_RADIUS),
|
||||
};
|
||||
|
|
@ -577,9 +587,10 @@ impl Element for Scrollbar {
|
|||
},
|
||||
};
|
||||
|
||||
let scrollbar_show = self.scrollbar_show.unwrap_or(cx.theme().scrollbar_show);
|
||||
let state = self.state.clone();
|
||||
let is_always_to_show = cx.theme().scrollbar_show.is_always();
|
||||
let is_hover_to_show = cx.theme().scrollbar_show.is_hover();
|
||||
let is_always_to_show = scrollbar_show.is_always();
|
||||
let is_hover_to_show = scrollbar_show.is_hover();
|
||||
let is_hovered_on_bar = state.get().hovered_axis == Some(axis);
|
||||
let is_hovered_on_thumb = state.get().hovered_on_thumb == Some(axis);
|
||||
let is_offset_changed = state.get().last_scroll_offset != self.scroll_handle.offset();
|
||||
|
|
@ -594,7 +605,7 @@ impl Element for Scrollbar {
|
|||
Self::style_for_hovered_bar(cx)
|
||||
}
|
||||
} else if is_offset_changed {
|
||||
Self::style_for_normal(cx)
|
||||
self.style_for_normal(cx)
|
||||
} else if is_always_to_show {
|
||||
if is_hovered_on_thumb {
|
||||
Self::style_for_hovered_thumb(cx)
|
||||
|
|
@ -602,7 +613,7 @@ impl Element for Scrollbar {
|
|||
Self::style_for_hovered_bar(cx)
|
||||
}
|
||||
} else {
|
||||
let mut idle_state = Self::style_for_idle(cx);
|
||||
let mut idle_state = self.style_for_idle(cx);
|
||||
// Delay 2s to fade out the scrollbar thumb (in 1s)
|
||||
if let Some(last_time) = state.get().last_scroll_time {
|
||||
let elapsed = Instant::now().duration_since(last_time).as_secs_f32();
|
||||
|
|
@ -705,11 +716,11 @@ impl Element for Scrollbar {
|
|||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
let scrollbar_show = self.scrollbar_show.unwrap_or(cx.theme().scrollbar_show);
|
||||
let view_id = window.current_view();
|
||||
let hitbox_bounds = prepaint.hitbox.bounds;
|
||||
let is_visible =
|
||||
self.state.get().is_scrollbar_visible() || cx.theme().scrollbar_show.is_always();
|
||||
let is_hover_to_show = cx.theme().scrollbar_show.is_hover();
|
||||
let is_visible = self.state.get().is_scrollbar_visible() || scrollbar_show.is_always();
|
||||
let is_hover_to_show = scrollbar_show.is_hover();
|
||||
|
||||
// Update last_scroll_time when offset is changed.
|
||||
if self.scroll_handle.offset() != self.state.get().last_scroll_offset {
|
||||
|
|
|
|||
Loading…
Reference in a new issue