fix: allow file tree to scroll
This commit is contained in:
@@ -120,6 +120,13 @@ impl DiffViewState {
|
||||
) {
|
||||
self.0.borrow_mut().new_side_highlights = Some(highlights);
|
||||
}
|
||||
|
||||
pub(crate) fn scroll_to_diff_line(&mut self, line_i: util::diff::DiffLineIndex) {
|
||||
self.0
|
||||
.borrow_mut()
|
||||
.list_state
|
||||
.scroll_to_reveal_item(line_i.into());
|
||||
}
|
||||
}
|
||||
|
||||
impl gpui::RenderOnce for DiffView {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use std::{cell::RefCell, collections::HashSet, rc::Rc, sync::Arc};
|
||||
|
||||
use gpui::{
|
||||
InteractiveElement, IntoElement, ParentElement, StatefulInteractiveElement, Styled, div, list,
|
||||
prelude::FluentBuilder, px,
|
||||
InteractiveElement, IntoElement, ListHorizontalSizingBehavior, ListSizingBehavior,
|
||||
ParentElement, StatefulInteractiveElement, Styled, UniformListScrollHandle, div,
|
||||
prelude::FluentBuilder, px, uniform_list,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -11,10 +12,7 @@ use crate::{
|
||||
font_icon::{FontIcon, font_icon},
|
||||
text::text,
|
||||
},
|
||||
util::{
|
||||
self,
|
||||
file::{FileTreeItem, FileTreeItemKind},
|
||||
},
|
||||
util::{self, file::FileTreeItemKind},
|
||||
};
|
||||
|
||||
#[derive(gpui::IntoElement)]
|
||||
@@ -36,10 +34,11 @@ pub(crate) struct Item {
|
||||
pub(crate) struct FileTreeState(Rc<RefCell<FileTreeStateInner>>);
|
||||
|
||||
struct FileTreeStateInner {
|
||||
list_state: gpui::ListState,
|
||||
scroll_handle: UniformListScrollHandle,
|
||||
collapsed_dirs: HashSet<Arc<str>>,
|
||||
visible_items: Vec<usize>,
|
||||
highlighted_items: HashSet<usize>,
|
||||
max_width_item_index: Option<usize>,
|
||||
}
|
||||
|
||||
pub(crate) fn file_tree(
|
||||
@@ -56,17 +55,18 @@ pub(crate) fn file_tree(
|
||||
impl FileTreeState {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self(Rc::new(RefCell::new(FileTreeStateInner {
|
||||
list_state: gpui::ListState::new(0, gpui::ListAlignment::Top, px(50.)),
|
||||
scroll_handle: UniformListScrollHandle::new(),
|
||||
collapsed_dirs: HashSet::new(),
|
||||
visible_items: Vec::new(),
|
||||
highlighted_items: HashSet::new(),
|
||||
max_width_item_index: None,
|
||||
})))
|
||||
}
|
||||
|
||||
pub(crate) fn reset(&self, items: &[util::file::FileTreeItem]) {
|
||||
let mut state = self.0.borrow_mut();
|
||||
state.list_state.reset(items.len());
|
||||
state.visible_items = (0..items.len()).collect::<Vec<_>>();
|
||||
state.update_max_width_item_index(items);
|
||||
}
|
||||
|
||||
pub(crate) fn highlight_item(&mut self, index: usize) {
|
||||
@@ -104,7 +104,21 @@ impl FileTreeState {
|
||||
state.visible_items.push(i);
|
||||
}
|
||||
|
||||
state.list_state.reset(state.visible_items.len());
|
||||
state.update_max_width_item_index(items);
|
||||
}
|
||||
}
|
||||
|
||||
impl FileTreeStateInner {
|
||||
fn update_max_width_item_index(&mut self, items: &[util::file::FileTreeItem]) {
|
||||
self.max_width_item_index = self
|
||||
.visible_items
|
||||
.iter()
|
||||
.enumerate()
|
||||
.max_by_key(|(_, item_i)| {
|
||||
let item = &items[**item_i];
|
||||
item.level.saturating_mul(2) + item.name.chars().count()
|
||||
})
|
||||
.map(|(visible_i, _)| visible_i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,28 +138,41 @@ impl gpui::RenderOnce for FileTree {
|
||||
_window: &mut gpui::Window,
|
||||
_cx: &mut gpui::App,
|
||||
) -> impl gpui::prelude::IntoElement {
|
||||
let list_state = self.state.0.borrow().list_state.clone();
|
||||
let state = self.state.0.borrow();
|
||||
let item_count = state.visible_items.len();
|
||||
let scroll_handle = state.scroll_handle.clone();
|
||||
let max_width_item_index = state.max_width_item_index;
|
||||
drop(state);
|
||||
|
||||
list(list_state, move |i, window, cx| {
|
||||
let state = self.state.0.borrow();
|
||||
let item_index = state.visible_items[i];
|
||||
let on_item_click = self.on_item_click.as_ref().map(Rc::clone);
|
||||
uniform_list("file-tree", item_count, move |range, window, cx| {
|
||||
range
|
||||
.map(|i| {
|
||||
let item_index = self.state.0.borrow().visible_items[i];
|
||||
let on_item_click = self.on_item_click.as_ref().map(Rc::clone);
|
||||
|
||||
let item = (self.item)(item_index, window, cx);
|
||||
let item = Item {
|
||||
is_expanded: !state.collapsed_dirs.contains(&item.full_path),
|
||||
is_highlighed: state.highlighted_items.contains(&item_index),
|
||||
item,
|
||||
on_click: Box::new(move |window, cx| {
|
||||
if let Some(f) = &on_item_click {
|
||||
f(&i, window, cx);
|
||||
}
|
||||
}),
|
||||
};
|
||||
let item = (self.item)(item_index, window, cx);
|
||||
let state = self.state.0.borrow();
|
||||
let item = Item {
|
||||
is_expanded: !state.collapsed_dirs.contains(&item.full_path),
|
||||
is_highlighed: state.highlighted_items.contains(&item_index),
|
||||
item,
|
||||
on_click: Box::new(move |window, cx| {
|
||||
if let Some(f) = &on_item_click {
|
||||
f(&item_index, window, cx);
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
item.into_any_element()
|
||||
item.into_any_element()
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.size_full()
|
||||
.h_full()
|
||||
.min_w_full()
|
||||
.with_sizing_behavior(ListSizingBehavior::Infer)
|
||||
.with_horizontal_sizing_behavior(ListHorizontalSizingBehavior::Unconstrained)
|
||||
.with_width_from_item(max_width_item_index)
|
||||
.track_scroll(scroll_handle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +181,7 @@ impl gpui::RenderOnce for Item {
|
||||
let theme = app::current_theme(cx);
|
||||
div()
|
||||
.id(gpui::SharedString::new(self.item.full_path))
|
||||
.w_full()
|
||||
.min_w_full()
|
||||
.flex()
|
||||
.flex_row()
|
||||
.items_center()
|
||||
@@ -162,7 +189,6 @@ impl gpui::RenderOnce for Item {
|
||||
.pr_2()
|
||||
.py_0p5()
|
||||
.pl(px(8. + (8 * self.item.level) as f32))
|
||||
.rounded_sm()
|
||||
.hover(|it| {
|
||||
if self.is_highlighed {
|
||||
it
|
||||
@@ -191,6 +217,11 @@ impl gpui::RenderOnce for Item {
|
||||
it.bg(theme.colors.accent_muted)
|
||||
.text_color(theme.colors.accent_fg)
|
||||
})
|
||||
.child(text(gpui::SharedString::new(self.item.name)).text_sm())
|
||||
.child(
|
||||
text(gpui::SharedString::new(self.item.name))
|
||||
.text_sm()
|
||||
.whitespace_nowrap()
|
||||
.flex_shrink_0(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user