T13c Files: FileTree with git status and filter, DirectoryListing, SelectableList activation (review pending: codex 401)
This commit is contained in:
11 files changed
+859
-10
No files matched your search
+21
-1
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user