use promkit_core::{Widget, grapheme::StyledGraphemes};
pub mod node;
use node::Kind;
#[path = "tree/tree.rs"]
mod inner;
pub use inner::Tree;
pub mod config;
pub use config::Config;
#[derive(Clone)]
pub struct State {
pub tree: Tree,
pub config: Config,
}
impl Widget for State {
fn create_graphemes(&self, _width: u16, height: u16) -> StyledGraphemes {
let symbol = |kind: &Kind| -> &str {
match kind {
Kind::Folded { .. } => &self.config.folded_symbol,
Kind::Unfolded { .. } => &self.config.unfolded_symbol,
}
};
let indent = |kind: &Kind| -> usize {
match kind {
Kind::Folded { path, .. } | Kind::Unfolded { path, .. } => {
path.len() * self.config.indent
}
}
};
let id = |kind: &Kind| -> String {
match kind {
Kind::Folded { id, .. } | Kind::Unfolded { id, .. } => id.clone(),
}
};
let height = match self.config.lines {
Some(lines) => lines.min(height as usize),
None => height as usize,
};
let kinds = self.tree.kinds();
let lines = kinds
.iter()
.enumerate()
.filter(|(i, _)| *i >= self.tree.position() && *i < self.tree.position() + height)
.map(|(i, kind)| {
if i == self.tree.position() {
StyledGraphemes::from_str(
format!("{}{}{}", symbol(kind), " ".repeat(indent(kind)), id(kind),),
self.config.active_item_style,
)
} else {
StyledGraphemes::from_str(
format!(
"{}{}{}",
" ".repeat(StyledGraphemes::from(symbol(kind)).widths()),
" ".repeat(indent(kind)),
id(kind),
),
self.config.inactive_item_style,
)
}
});
StyledGraphemes::from_lines(lines)
}
}