use ratatui::{
buffer::Buffer,
layout::Rect,
style::{Color, Style},
widgets::StatefulWidget,
};
use crate::popups::FileBrowserState;
use crate::scroll_list::ScrollList;
use crate::DEFAULT_HIGHLIGHT;
#[derive(Clone)]
pub struct FileBrowser {
dir_style: Style,
file_style: Style,
highlight_style: Style,
highlight_symbol: String,
dir_icon: String,
file_icon: String,
max_selected: Option<usize>,
}
impl FileBrowser {
pub fn new() -> Self {
Self {
dir_style: Style::new().fg(Color::Cyan),
file_style: Style::new().fg(Color::White),
highlight_style: DEFAULT_HIGHLIGHT,
highlight_symbol: crate::HIGHLIGHT_SYMBOL.to_string(),
dir_icon: "📁 ".to_string(),
file_icon: "📄 ".to_string(),
max_selected: None,
}
}
pub fn dir_style(mut self, style: Style) -> Self {
self.dir_style = style;
self
}
pub fn file_style(mut self, style: Style) -> Self {
self.file_style = style;
self
}
pub fn highlight_style(mut self, style: Style) -> Self {
self.highlight_style = style;
self
}
pub fn highlight_symbol(mut self, symbol: &str) -> Self {
self.highlight_symbol = symbol.to_string();
self
}
pub fn dir_icon(mut self, icon: &str) -> Self {
self.dir_icon = icon.to_string();
self
}
pub fn file_icon(mut self, icon: &str) -> Self {
self.file_icon = icon.to_string();
self
}
pub fn max_selected(mut self, max: usize) -> Self {
self.max_selected = Some(max);
self
}
pub fn no_max_selected(mut self) -> Self {
self.max_selected = None;
self
}
}
impl Default for FileBrowser {
fn default() -> Self {
Self::new()
}
}
impl StatefulWidget for FileBrowser {
type State = FileBrowserState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let items: Vec<(String, Style)> = state
.items
.iter()
.enumerate()
.map(|(i, (text, _))| {
let is_dir = state.entries.get(i).map(|e| e.is_dir).unwrap_or(false);
let style = if is_dir { self.dir_style } else { self.file_style };
(text.clone(), style)
})
.collect();
let mut scroll_state = state.choose_popup_state.scroll_list_state.clone();
scroll_state.follow = false;
let list = ScrollList::new_styled(items)
.highlight_style(self.highlight_style)
.highlight_symbol(&self.highlight_symbol);
list.render(area, buf, &mut scroll_state);
state.choose_popup_state.scroll_list_state = scroll_state;
}
}