use crate::*; use tengri::tui::ratatui::{style::{Color, Style}, prelude::Stylize}; pub(crate) use pad::PadStr; mod column; pub use self::column::*; mod string; pub use self::string::*; impl Content for Taggart { fn content (&self) -> impl Render { let sizer = Fill::xy(&self.size); let size = format!("{}x{}", self.size.w(), self.size.h()); let size_bar = status_bar(Align::e(size)); let titlebar = status_bar(Align::w(self.columns.header())); Bsp::n(size_bar, Bsp::s(titlebar, Bsp::b(sizer, Fill::xy(TreeTable(self))))) } } struct TreeTable<'a>(&'a Taggart); impl<'a> Content for TreeTable<'a> { fn render (&self, to: &mut TuiOut) { let area = to.area(); let Taggart { offset, paths, cursor, column, .. } = self.0; let (x, w) = self.0.columns.xw(*column); to.fill_bg([area.x() + x, area.y(), w, area.h()], Color::Rgb(0, 0, 0)); for (i, y) in area.iter_y().enumerate() { let i_offset = i + offset; let selected = *cursor == i_offset; if let Some(entry) = paths.get(i_offset) { for (index, _fragment) in entry.path.iter().enumerate() { if index == entry.depth - 1 { let _cursor = if selected { ">" } else { " " }; let label = self.0.columns.row_content(&entry); Content::render(&label) to.blit(&label, area.x(), y, entry.style()); if selected { let fill = [area.x(), y, area.w(), 1]; to.fill_fg(fill, Color::Rgb(0, 0, 0)); to.fill_bg(fill, Color::Rgb(192, 128, 0)); let fill = [area.x() + x as u16, y, w, 1]; to.fill_bg(fill, Color::Rgb(224, 192, 0)); if let Some((_index, value)) = &self.0.editing { let x = area.x() + if x > 0 { x + 1 } else { x } as u16; to.blit(&value, x, y, None) } } } } } else { break } } } } impl Entry { pub fn name (&self) -> Option> { let indent = "".pad_to_width((self.depth - 1) * 2); let icon = self.icon(); let name = self.path.iter().last().expect("empty path").display(); Some(format!("{indent}{icon} {name}").into()) } fn icon (&self) -> &'static str { if self.is_dir() { "" //"+" } else if self.is_img() { "" } else if self.is_mus() { "" } else { "⁇" } } fn style (&self) -> Option