This commit is contained in:
MrSubidubi 2025-08-12 19:53:57 +02:00
parent d705585a2e
commit c28d873a2f
34 changed files with 1295 additions and 2348 deletions

View file

@ -7,12 +7,11 @@ use collections::{BTreeSet, HashMap, hash_map};
use command_palette_hooks::CommandPaletteFilter;
use db::kvp::KEY_VALUE_STORE;
use editor::{
Editor, EditorEvent, EditorSettings, ShowScrollbar,
Editor, EditorEvent,
items::{
entry_diagnostic_aware_icon_decoration_and_color,
entry_diagnostic_aware_icon_name_and_color, entry_git_aware_label_color,
},
scroll::ScrollbarAutoHide,
};
use file_icons::FileIcons;
use git::status::GitSummary;
@ -58,8 +57,8 @@ use std::{
use theme::ThemeSettings;
use ui::{
Color, ContextMenu, DecoratedIcon, Icon, IconDecoration, IconDecorationKind, IndentGuideColors,
IndentGuideLayout, KeyBinding, Label, LabelSize, ListItem, ListItemSpacing, ScrollableHandle,
Scrollbar, ScrollbarState, StickyCandidate, Tooltip, prelude::*, v_flex,
IndentGuideLayout, KeyBinding, Label, LabelSize, ListItem, ListItemSpacing, ScrollAxes,
ScrollableHandle, Scrollbars, StickyCandidate, Tooltip, WithScrollbar, prelude::*, v_flex,
};
use util::{ResultExt, TakeUntilExt, TryFutureExt, maybe, paths::compare_paths};
use workspace::{
@ -109,10 +108,6 @@ pub struct ProjectPanel {
workspace: WeakEntity<Workspace>,
width: Option<Pixels>,
pending_serialization: Task<Option<()>>,
show_scrollbar: bool,
vertical_scrollbar_state: ScrollbarState,
horizontal_scrollbar_state: ScrollbarState,
hide_scrollbar_task: Option<Task<()>>,
diagnostics: HashMap<(WorktreeId, PathBuf), DiagnosticSeverity>,
max_width_item_index: Option<usize>,
diagnostic_summary_update: Task<()>,
@ -430,7 +425,6 @@ impl ProjectPanel {
cx.on_focus(&focus_handle, window, Self::focus_in).detach();
cx.on_focus_out(&focus_handle, window, |this, _, window, cx| {
this.focus_out(window, cx);
this.hide_scrollbar(window, cx);
})
.detach();
@ -624,12 +618,6 @@ impl ProjectPanel {
workspace: workspace.weak_handle(),
width: None,
pending_serialization: Task::ready(None),
show_scrollbar: !Self::should_autohide_scrollbar(cx),
hide_scrollbar_task: None,
vertical_scrollbar_state: ScrollbarState::new(scroll_handle.clone())
.parent_entity(&cx.entity()),
horizontal_scrollbar_state: ScrollbarState::new(scroll_handle.clone())
.parent_entity(&cx.entity()),
max_width_item_index: None,
diagnostics: Default::default(),
diagnostic_summary_update: Task::ready(()),
@ -4731,103 +4719,6 @@ impl ProjectPanel {
}
}
fn render_vertical_scrollbar(&self, cx: &mut Context<Self>) -> Option<Stateful<Div>> {
if !Self::should_show_scrollbar(cx)
|| !(self.show_scrollbar || self.vertical_scrollbar_state.is_dragging())
{
return None;
}
Some(
div()
.occlude()
.id("project-panel-vertical-scroll")
.on_mouse_move(cx.listener(|_, _, _, cx| {
cx.notify();
cx.stop_propagation()
}))
.on_hover(|_, _, cx| {
cx.stop_propagation();
})
.on_any_mouse_down(|_, _, cx| {
cx.stop_propagation();
})
.on_mouse_up(
MouseButton::Left,
cx.listener(|this, _, window, cx| {
if !this.vertical_scrollbar_state.is_dragging()
&& !this.focus_handle.contains_focused(window, cx)
{
this.hide_scrollbar(window, cx);
cx.notify();
}
cx.stop_propagation();
}),
)
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
cx.notify();
}))
.h_full()
.absolute()
.right_1()
.top_1()
.bottom_1()
.w(px(12.))
.cursor_default()
.children(Scrollbar::vertical(
// percentage as f32..end_offset as f32,
self.vertical_scrollbar_state.clone(),
)),
)
}
fn render_horizontal_scrollbar(&self, cx: &mut Context<Self>) -> Option<Stateful<Div>> {
if !Self::should_show_scrollbar(cx)
|| !(self.show_scrollbar || self.horizontal_scrollbar_state.is_dragging())
{
return None;
}
Scrollbar::horizontal(self.horizontal_scrollbar_state.clone()).map(|scrollbar| {
div()
.occlude()
.id("project-panel-horizontal-scroll")
.on_mouse_move(cx.listener(|_, _, _, cx| {
cx.notify();
cx.stop_propagation()
}))
.on_hover(|_, _, cx| {
cx.stop_propagation();
})
.on_any_mouse_down(|_, _, cx| {
cx.stop_propagation();
})
.on_mouse_up(
MouseButton::Left,
cx.listener(|this, _, window, cx| {
if !this.horizontal_scrollbar_state.is_dragging()
&& !this.focus_handle.contains_focused(window, cx)
{
this.hide_scrollbar(window, cx);
cx.notify();
}
cx.stop_propagation();
}),
)
.on_scroll_wheel(cx.listener(|_, _, _, cx| {
cx.notify();
}))
.w_full()
.absolute()
.right_1()
.left_1()
.bottom_1()
.h(px(12.))
.cursor_default()
.child(scrollbar)
})
}
fn dispatch_context(&self, window: &Window, cx: &Context<Self>) -> KeyContext {
let mut dispatch_context = KeyContext::new_with_defaults();
dispatch_context.add("ProjectPanel");
@ -4843,52 +4734,6 @@ impl ProjectPanel {
dispatch_context
}
fn should_show_scrollbar(cx: &App) -> bool {
let show = ProjectPanelSettings::get_global(cx)
.scrollbar
.show
.unwrap_or_else(|| EditorSettings::get_global(cx).scrollbar.show);
match show {
ShowScrollbar::Auto => true,
ShowScrollbar::System => true,
ShowScrollbar::Always => true,
ShowScrollbar::Never => false,
}
}
fn should_autohide_scrollbar(cx: &App) -> bool {
let show = ProjectPanelSettings::get_global(cx)
.scrollbar
.show
.unwrap_or_else(|| EditorSettings::get_global(cx).scrollbar.show);
match show {
ShowScrollbar::Auto => true,
ShowScrollbar::System => cx
.try_global::<ScrollbarAutoHide>()
.map_or_else(|| cx.should_auto_hide_scrollbars(), |autohide| autohide.0),
ShowScrollbar::Always => false,
ShowScrollbar::Never => true,
}
}
fn hide_scrollbar(&mut self, window: &mut Window, cx: &mut Context<Self>) {
const SCROLLBAR_SHOW_INTERVAL: Duration = Duration::from_secs(1);
if !Self::should_autohide_scrollbar(cx) {
return;
}
self.hide_scrollbar_task = Some(cx.spawn_in(window, async move |panel, cx| {
cx.background_executor()
.timer(SCROLLBAR_SHOW_INTERVAL)
.await;
panel
.update(cx, |panel, cx| {
panel.show_scrollbar = false;
cx.notify();
})
.log_err();
}))
}
fn reveal_entry(
&mut self,
project: Entity<Project>,
@ -5238,15 +5083,6 @@ impl Render for ProjectPanel {
this.refresh_drag_cursor_style(&event.modifiers, window, cx);
},
))
.on_hover(cx.listener(|this, hovered, window, cx| {
if *hovered {
this.show_scrollbar = true;
this.hide_scrollbar_task.take();
cx.notify();
} else if !this.focus_handle.contains_focused(window, cx) {
this.hide_scrollbar(window, cx);
}
}))
.on_click(cx.listener(|this, event, _, cx| {
if matches!(event, gpui::ClickEvent::Keyboard(_)) {
return;
@ -5511,10 +5347,14 @@ impl Render for ProjectPanel {
.with_width_from_item(self.max_width_item_index)
.track_scroll(self.scroll_handle.clone()),
)
.children(self.render_vertical_scrollbar(cx))
.when_some(self.render_horizontal_scrollbar(cx), |this, scrollbar| {
this.pb_4().child(scrollbar)
})
.custom_scrollbars(
Scrollbars::for_settings::<ProjectPanelSettings>()
.tracked_scroll_handle(self.scroll_handle.clone())
.with_track_along(ScrollAxes::Horizontal)
.tracked_entity(cx.entity()),
window,
cx,
)
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
deferred(
anchored()

View file

@ -1,8 +1,9 @@
use editor::ShowScrollbar;
use editor::EditorSettings;
use gpui::Pixels;
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use settings::{Settings, SettingsSources};
use ui::scrollbars::{ScrollbarVisibilitySetting, ShowScrollbar};
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, Copy, PartialEq)]
#[serde(rename_all = "snake_case")]
@ -162,6 +163,14 @@ pub struct ProjectPanelSettingsContent {
pub sticky_scroll: Option<bool>,
}
impl ScrollbarVisibilitySetting for ProjectPanelSettings {
fn scrollbar_visibility(&self, cx: &ui::App) -> ShowScrollbar {
self.scrollbar
.show
.unwrap_or_else(|| EditorSettings::get_global(cx).scrollbar.show)
}
}
impl Settings for ProjectPanelSettings {
const KEY: Option<&'static str> = Some("project_panel");