use std::cell::RefCell;
use promkit_widgets::{
text::{self, Text},
tree::{self, node::Node},
};
use crate::{
crossterm::style::{Attribute, Attributes, Color, ContentStyle},
switch::ActiveKeySwitcher,
Prompt,
};
pub mod keymap;
pub mod render;
pub struct Tree {
keymap: ActiveKeySwitcher<keymap::Keymap>,
title_state: text::State,
tree_state: tree::State,
}
impl Tree {
pub fn new(root: Node) -> Self {
Self {
keymap: ActiveKeySwitcher::new("default", self::keymap::default),
title_state: text::State {
style: ContentStyle {
attributes: Attributes::from(Attribute::Bold),
..Default::default()
},
..Default::default()
},
tree_state: tree::State {
tree: tree::Tree::new(root),
folded_symbol: String::from("▶︎ "),
unfolded_symbol: String::from("▼ "),
active_item_style: ContentStyle {
foreground_color: Some(Color::DarkCyan),
..Default::default()
},
inactive_item_style: ContentStyle::default(),
lines: Default::default(),
indent: 2,
},
}
}
pub fn title<T: AsRef<str>>(mut self, text: T) -> Self {
self.title_state.text = Text::from(text);
self
}
pub fn title_style(mut self, style: ContentStyle) -> Self {
self.title_state.style = style;
self
}
pub fn folded_symbol<T: AsRef<str>>(mut self, symbol: T) -> Self {
self.tree_state.folded_symbol = symbol.as_ref().to_string();
self
}
pub fn unfolded_symbol<T: AsRef<str>>(mut self, symbol: T) -> Self {
self.tree_state.unfolded_symbol = symbol.as_ref().to_string();
self
}
pub fn active_item_style(mut self, style: ContentStyle) -> Self {
self.tree_state.active_item_style = style;
self
}
pub fn inactive_item_style(mut self, style: ContentStyle) -> Self {
self.tree_state.inactive_item_style = style;
self
}
pub fn tree_lines(mut self, lines: usize) -> Self {
self.tree_state.lines = Some(lines);
self
}
pub fn indent(mut self, indent: usize) -> Self {
self.tree_state.indent = indent;
self
}
pub fn register_keymap<K: AsRef<str>>(mut self, key: K, handler: keymap::Keymap) -> Self {
self.keymap = self.keymap.register(key, handler);
self
}
pub fn prompt(self) -> anyhow::Result<Prompt<render::Renderer>> {
Ok(Prompt {
renderer: render::Renderer {
keymap: RefCell::new(self.keymap),
title_state: self.title_state,
tree_state: self.tree_state,
},
})
}
}