feat: add category tree with expand/collapse in category panel
Add a tree-based category panel that supports expand/collapse of categories. Introduces CatTreeEntry and build_cat_tree to render categories as a collapsible tree. The category panel now displays categories with expand indicators (▶/▼) and shows items under expanded categories. CmdContext gains cat_tree_entry(), cat_at_cursor(), and cat_tree_len() methods to work with the tree. App tracks expanded_cats in a HashSet. Keymap updates: Enter in category panel now triggers filter-to-item. Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
This commit is contained in:
51
src/ui/cat_tree.rs
Normal file
51
src/ui/cat_tree.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use crate::model::Model;
|
||||
use std::collections::HashSet;
|
||||
|
||||
/// A flattened entry in the category panel tree.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CatTreeEntry {
|
||||
/// Category header row: name, item count, expanded?
|
||||
Category {
|
||||
name: String,
|
||||
item_count: usize,
|
||||
expanded: bool,
|
||||
},
|
||||
/// Item row under a category
|
||||
Item { cat_name: String, item_name: String },
|
||||
}
|
||||
|
||||
impl CatTreeEntry {
|
||||
/// The category this entry belongs to.
|
||||
pub fn cat_name(&self) -> &str {
|
||||
match self {
|
||||
CatTreeEntry::Category { name, .. } => name,
|
||||
CatTreeEntry::Item { cat_name, .. } => cat_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the flattened tree of categories and their items.
|
||||
pub fn build_cat_tree(model: &Model, expanded: &HashSet<String>) -> Vec<CatTreeEntry> {
|
||||
let mut entries = Vec::new();
|
||||
for cat_name in model.category_names() {
|
||||
let cat = model.category(cat_name);
|
||||
let item_count = cat.map(|c| c.items.len()).unwrap_or(0);
|
||||
let is_expanded = expanded.contains(cat_name);
|
||||
entries.push(CatTreeEntry::Category {
|
||||
name: cat_name.to_string(),
|
||||
item_count,
|
||||
expanded: is_expanded,
|
||||
});
|
||||
if is_expanded {
|
||||
if let Some(cat) = cat {
|
||||
for item_name in cat.ordered_item_names() {
|
||||
entries.push(CatTreeEntry::Item {
|
||||
cat_name: cat_name.to_string(),
|
||||
item_name: item_name.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
entries
|
||||
}
|
||||
Reference in New Issue
Block a user