use super::*;
pub(super) type TabHits = (
Vec<(usize, Rect)>,
Vec<(usize, Rect)>,
Option<Rect>,
Option<Rect>,
);
pub(super) fn draw_tabbar(f: &mut RenderTarget, area: Rect, app: &App, t: &Theme) -> TabHits {
f.render_widget(Block::new().style(Style::new().bg(t.mantle)), area);
let ws = app.ws();
let n = ws.tabs.len();
let active = ws.active_tab;
let mut tab_rects = Vec::new();
let mut close_rects = Vec::new();
let mut prev_rect = None;
let mut next_rect = None;
const CELL: u16 = 10; const GAP: u16 = 1;
const ARROW: u16 = 2;
let plus_w: u16 = 3;
let unit = CELL + GAP;
let left = area.x + 1;
let right = area.right();
let total = right.saturating_sub(left);
let fit_plain = ((total + GAP).saturating_sub(plus_w) / unit) as usize;
let need_scroll = n > fit_plain;
let avail = if need_scroll {
total.saturating_sub(plus_w + 2 * ARROW)
} else {
total.saturating_sub(plus_w)
};
let max_vis = (((avail + GAP) / unit).max(1) as usize).min(n.max(1));
let mut scroll = (active + 1).saturating_sub(max_vis);
scroll = scroll.min(n.saturating_sub(max_vis));
let mut x = left;
if need_scroll {
let style = if scroll > 0 {
Style::new().fg(t.accent).bold()
} else {
Style::new().fg(t.overlay0)
};
let r = Rect::new(x, area.y, ARROW, 1);
f.render_widget(Paragraph::new(Span::styled("‹ ", style)), r);
prev_rect = Some(r);
x += ARROW;
}
let end = (scroll + max_vis).min(n);
for i in scroll..end {
let is_git = ws.tabs.get(i).is_some_and(|tb| tb.is_git());
let title = |w: usize| {
if is_git {
format!("{:^w$}", "⎇ git", w = w)
} else {
format!("{:^w$}", i + 1, w = w)
}
};
if i == active {
let label = title((CELL - 2) as usize);
let style = Style::new().fg(t.crust).bg(t.accent).bold();
f.render_widget(
Paragraph::new(Span::styled(label, style)),
Rect::new(x, area.y, CELL - 2, 1),
);
let close = Rect::new(x + CELL - 2, area.y, 2, 1);
f.render_widget(
Paragraph::new(Span::styled("✕ ", Style::new().fg(t.crust).bg(t.accent))),
close,
);
close_rects.push((i, close));
} else {
let label = title(CELL as usize);
f.render_widget(
Paragraph::new(Span::styled(
label,
Style::new().fg(t.subtext0).bg(t.mantle),
)),
Rect::new(x, area.y, CELL, 1),
);
}
tab_rects.push((i, Rect::new(x, area.y, CELL, 1)));
x += unit;
}
if need_scroll {
let style = if end < n {
Style::new().fg(t.accent).bold()
} else {
Style::new().fg(t.overlay0)
};
let r = Rect::new(x, area.y, ARROW, 1);
f.render_widget(Paragraph::new(Span::styled("› ", style)), r);
next_rect = Some(r);
x += ARROW;
}
if x + plus_w <= right {
let rect = Rect::new(x, area.y, plus_w, 1);
f.render_widget(
Paragraph::new(Span::styled(
" + ",
Style::new().fg(t.accent).bg(t.surface0).bold(),
)),
rect,
);
tab_rects.push((n, rect));
}
(tab_rects, close_rects, prev_rect, next_rect)
}