project panel: Make intermediate folded directories clickable (#18956)

- Closes: https://github.com/zed-industries/zed/issues/18770


Release Notes:

- Intermediate auto-folded project panel entries are now clickable.
This commit is contained in:
Piotr Osiewicz 2024-10-10 11:15:46 +02:00 committed by GitHub
parent db50467bbc
commit f6f5ad138d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2434,71 +2434,62 @@ impl ProjectPanel {
if let (Some(editor), true) = (Some(&self.filename_editor), show_editor) { if let (Some(editor), true) = (Some(&self.filename_editor), show_editor) {
h_flex().h_6().w_full().child(editor.clone()) h_flex().h_6().w_full().child(editor.clone())
} else { } else {
h_flex().h_6().map(|this| { h_flex().h_6().map(|mut this| {
if let Some(folded_ancestors) = if let Some(folded_ancestors) =
is_active.then(|| self.ancestors.get(&entry_id)).flatten() is_active.then(|| self.ancestors.get(&entry_id)).flatten()
{ {
let Some(part_to_highlight) = Path::new(&file_name) let components = Path::new(&file_name)
.ancestors() .components()
.nth(folded_ancestors.current_ancestor_depth) .map(|comp| {
else { let comp_str =
return this; comp.as_os_str().to_string_lossy().into_owned();
}; comp_str
})
let suffix = Path::new(&file_name) .collect::<Vec<_>>();
.strip_prefix(part_to_highlight) let components_len = components.len();
.ok() let active_index = components_len
.filter(|suffix| !suffix.as_os_str().is_empty()); - 1
let prefix = part_to_highlight - folded_ancestors.current_ancestor_depth;
.parent() const DELIMITER: SharedString =
.filter(|prefix| !prefix.as_os_str().is_empty()); SharedString::new_static(std::path::MAIN_SEPARATOR_STR);
let Some(part_to_highlight) = part_to_highlight for (index, component) in components.into_iter().enumerate() {
.file_name() if index != 0 {
.and_then(|name| name.to_str().map(String::from)) this = this.child(
else { Label::new(DELIMITER.clone())
return this;
};
this.children(prefix.and_then(|prefix| {
Some(
h_flex()
.child(
Label::new(prefix.to_str().map(String::from)?)
.single_line() .single_line()
.color(filename_text_color), .color(filename_text_color),
) );
.child( }
Label::new(std::path::MAIN_SEPARATOR_STR) let id = SharedString::from(format!(
.single_line() "project_panel_path_component_{}_{index}",
.color(filename_text_color), entry_id.to_usize()
), ));
) let label = div()
.id(id)
.on_click(cx.listener(move |this, _, cx| {
if index != active_index {
if let Some(folds) =
this.ancestors.get_mut(&entry_id)
{
folds.current_ancestor_depth =
components_len - 1 - index;
cx.notify();
}
}
})) }))
.child( .child(
Label::new(part_to_highlight) Label::new(component)
.single_line() .single_line()
.color(filename_text_color) .color(filename_text_color)
.underline(true), .when(index == active_index, |this| {
) this.underline(true)
.children(
suffix.and_then(|suffix| {
Some(
h_flex()
.child(
Label::new(std::path::MAIN_SEPARATOR_STR)
.single_line()
.color(filename_text_color),
)
.child(
Label::new(
suffix.to_str().map(String::from)?,
)
.single_line()
.color(filename_text_color),
),
)
}), }),
) );
this = this.child(label);
}
this
} else { } else {
this.child( this.child(
Label::new(file_name) Label::new(file_name)