use super::theme;
use ratatui::{buffer::Buffer, layout::Rect, style::Style, text::Span, widgets::Widget};
pub enum TabMode<'a> {
Sources { titles: &'a [String], active: usize },
Pages { current: usize, total: usize },
PackageSources {
sources: &'a [String],
selected: usize,
pkg_name: &'a str,
},
}
pub struct TabBar<'a> {
pub mode: TabMode<'a>,
}
impl<'a> Widget for TabBar<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
if area.height == 0 {
return;
}
for x in area.x..(area.x + area.width) {
buf.get_mut(x, area.y)
.set_char(' ')
.set_style(Style::default().bg(theme::bg_color()));
}
match self.mode {
TabMode::Sources { titles, active } => {
render_tabs(area, buf, titles, active);
}
TabMode::Pages { current, total } => {
let titles: Vec<String> = (1..=total)
.map(|p| {
if p == current + 1 {
format!("Page {}", p)
} else {
format!("{}", p)
}
})
.collect();
render_tabs(area, buf, &titles, current);
}
TabMode::PackageSources {
sources,
selected,
pkg_name,
} => {
let label = format!(" {} ▸ ", pkg_name);
let label_span = Span::styled(label.clone(), theme::dim());
let mut x = area.x + 1;
buf.set_span(x, area.y, &label_span, label.len() as u16);
x += label.len() as u16;
for (i, src) in sources.iter().enumerate() {
if x + src.len() as u16 + 5 >= area.x + area.width {
break;
}
let (style, border_l, border_r) = if i == selected {
(theme::active_tab(), "┃ ", " ┃")
} else {
(theme::tab(), "│ ", " │")
};
let tab_text = format!("{}{}{}", border_l, src, border_r);
let span = Span::styled(tab_text.clone(), style);
buf.set_span(x, area.y, &span, tab_text.len() as u16);
x += tab_text.len() as u16 + 1;
}
}
}
}
}
fn render_tabs(area: Rect, buf: &mut Buffer, titles: &[String], active: usize) {
let mut x = area.x + 1;
for (i, title) in titles.iter().enumerate() {
if x + title.len() as u16 + 5 >= area.x + area.width {
break;
}
let (style, border_l, border_r) = if i == active {
(theme::active_tab(), "┃ ", " ┃")
} else {
(theme::tab(), "│ ", " │")
};
let tab_text = format!("{}{}{}", border_l, title, border_r);
let span = Span::styled(tab_text.clone(), style);
buf.set_span(x, area.y, &span, tab_text.len() as u16);
x += tab_text.len() as u16 + 1;
}
}