T13c Files: FileTree with git status and filter, DirectoryListing, SelectableList activation (review pending: codex 401)

This commit is contained in:
ZacharyZhang-NY committed 2026-09-25 20:06:00 -04:00
1 parent db3b993cac
commit 9eddfeb48b
11 files changed
+859 -10

No files matched your search

+21 -1
View File
@@ -2,7 +2,7 @@ use std::collections::HashSet;
use gpui::SharedString;
use crate::{forms::CheckState, primitives::IconName};
use crate::{data_display::Tone, forms::CheckState, primitives::IconName};
/// What a node holds under it.
#[derive(Clone, Debug, PartialEq)]
@@ -19,6 +19,8 @@ pub struct TreeNode {
pub(crate) key: SharedString,
pub(crate) label: SharedString,
pub(crate) icon: Option<IconName>,
pub(crate) note: Option<SharedString>,
pub(crate) tone: Option<Tone>,
pub(crate) children: Children,
}
@@ -29,10 +31,24 @@ impl TreeNode {
key: key.into(),
label: label.into(),
icon: None,
note: None,
tone: None,
children: Children::Leaf,
}
}
/// Quiet text at the row's end, such as a status letter.
pub fn note(mut self, note: impl Into<SharedString>) -> Self {
self.note = Some(note.into());
self
}
/// Tints the label and the note.
pub fn tone(mut self, tone: impl Into<Tone>) -> Self {
self.tone = Some(tone.into());
self
}
pub fn icon(mut self, icon: IconName) -> Self {
self.icon = Some(icon);
self
@@ -89,6 +105,8 @@ pub(crate) enum Shown {
key: SharedString,
label: SharedString,
icon: Option<IconName>,
note: Option<SharedString>,
tone: Option<Tone>,
opens: bool,
open: bool,
},
@@ -129,6 +147,8 @@ pub(crate) fn rows(nodes: &[TreeNode], open: &HashSet<SharedString>) -> Vec<Row>
key: node.key.clone(),
label: node.label.clone(),
icon: node.icon,
note: node.note.clone(),
tone: node.tone,
opens: node.opens(),
open: is_open,
},
+13
View File
@@ -79,6 +79,7 @@ fn row(rows: &Rows, ix: usize, window: &mut Window, cx: &mut App) -> AnyElement
icon,
opens,
open,
..
} => (key.clone(), label.clone(), *icon, *opens, *open),
Shown::Loading => return waiting(rows, ix, item.depth, cx),
};
@@ -100,6 +101,10 @@ fn row(rows: &Rows, ix: usize, window: &mut Window, cx: &mut App) -> AnyElement
let theme = cx.theme();
let colors = &theme.colors;
let indent = theme.tree_indent();
let (note, ink) = match &item.shown {
Shown::Node { note, tone, .. } => (note.clone(), tone.map(|tone| tone.colors(colors).1)),
Shown::Loading => (None, None),
};
let selected = rows.selected.contains(&key);
let (toggle, pick, activate, focus) = (
rows.toggle.clone(),
@@ -147,6 +152,7 @@ fn row(rows: &Rows, ix: usize, window: &mut Window, cx: &mut App) -> AnyElement
.flex_1()
.min_w_0()
.truncate()
.when_some(ink, |text, ink| text.text_color(ink))
.child(label.clone())
.into_any_element(),
};
@@ -202,6 +208,13 @@ fn row(rows: &Rows, ix: usize, window: &mut Window, cx: &mut App) -> AnyElement
)
.children(icon.map(|icon| Icon::new(icon).size(IconSize::Sm).color(colors.fg_muted)))
.child(body)
.children(note.map(|note| {
div()
.flex_none()
.text_size(theme.text_size(TextSize::Xs))
.text_color(ink.unwrap_or(colors.fg_subtle))
.child(note)
}))
.children(landing.filter(|at| *at != DropAt::Inside).map(line))
.on_click(move |event, window, cx| {
window.focus(&focus);