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
+30
-1
@@ -47,6 +47,7 @@ struct Cursor {
|
||||
}
|
||||
|
||||
type OnSelect = Rc<dyn Fn(&[SharedString], &mut Window, &mut App)>;
|
||||
type OnActivate = Rc<dyn Fn(&SharedString, &mut Window, &mut App)>;
|
||||
type Picker = Rc<dyn Fn(usize, Pick, &mut Window, &mut App)>;
|
||||
|
||||
/// Rows you select. A press picks one; with `multiple`, Cmd-press adds or drops one and Shift-press takes the range from the last pick. Up and Down move, Shift with them extends, Space toggles, Cmd-A takes all.
|
||||
@@ -58,6 +59,7 @@ pub struct SelectableList {
|
||||
selected: Vec<SharedString>,
|
||||
multiple: bool,
|
||||
on_change: Option<OnSelect>,
|
||||
on_activate: Option<OnActivate>,
|
||||
}
|
||||
|
||||
impl SelectableList {
|
||||
@@ -69,6 +71,7 @@ impl SelectableList {
|
||||
selected: Vec::new(),
|
||||
multiple: false,
|
||||
on_change: None,
|
||||
on_activate: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +91,15 @@ impl SelectableList {
|
||||
self
|
||||
}
|
||||
|
||||
/// Enter, or a double press, on a row.
|
||||
pub fn on_activate(
|
||||
mut self,
|
||||
handler: impl Fn(&SharedString, &mut Window, &mut App) + 'static,
|
||||
) -> Self {
|
||||
self.on_activate = Some(Rc::new(handler));
|
||||
self
|
||||
}
|
||||
|
||||
/// Gets the keys now selected, in row order.
|
||||
pub fn on_change(
|
||||
mut self,
|
||||
@@ -150,12 +162,21 @@ impl RenderOnce for SelectableList {
|
||||
}
|
||||
})
|
||||
};
|
||||
let activate: OnActivate = {
|
||||
let (id, on_activate) = (self.id.clone(), self.on_activate);
|
||||
Rc::new(move |key, window, cx| {
|
||||
log::info!("selectable list {id:?}: activated {key}");
|
||||
if let Some(on_activate) = &on_activate {
|
||||
on_activate(key, window, cx);
|
||||
}
|
||||
})
|
||||
};
|
||||
let rows: Vec<_> = self
|
||||
.rows
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(ix, (key, item))| {
|
||||
let (pick, focus) = (pick.clone(), focus.clone());
|
||||
let (pick, focus, activate) = (pick.clone(), focus.clone(), activate.clone());
|
||||
item.selected(selected.contains(&key))
|
||||
.current(focused && ix == at)
|
||||
.on_click(move |event, window, cx| {
|
||||
@@ -167,6 +188,9 @@ impl RenderOnce for SelectableList {
|
||||
};
|
||||
window.focus(&focus);
|
||||
pick(ix, how, window, cx);
|
||||
if event.click_count() == 2 {
|
||||
activate(&key, window, cx);
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
@@ -191,6 +215,11 @@ impl RenderOnce for SelectableList {
|
||||
"home" => (0, extend),
|
||||
"end" => (count - 1, extend),
|
||||
"space" => (at, Pick::Toggle),
|
||||
"enter" => {
|
||||
cx.stop_propagation();
|
||||
activate(&keys[at], window, cx);
|
||||
return;
|
||||
}
|
||||
"a" if held.platform => (at, Pick::All),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user