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