use ratatui_core::buffer::Buffer;
use ratatui_core::layout::Rect;
use ratatui_core::style::Style;
use ratatui_core::text::Line;
use ratatui_core::widgets::Widget;
use std::marker::PhantomData;
pub const SLANT_TL_BR: &str = "\u{e0b8}";
pub const SLANT_BL_TR: &str = "\u{e0ba}";
#[derive(Debug, Default, Clone)]
pub struct StatusLineStacked<'a> {
style: Style,
left: Vec<(Line<'a>, Line<'a>)>,
center_margin: u16,
center: Line<'a>,
right: Vec<(Line<'a>, Line<'a>)>,
phantom: PhantomData<&'a ()>,
}
impl<'a> StatusLineStacked<'a> {
pub fn new() -> Self {
Self::default()
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn start(mut self, text: impl Into<Line<'a>>, gap: impl Into<Line<'a>>) -> Self {
self.left.push((text.into(), gap.into()));
self
}
pub fn start_bare(mut self, text: impl Into<Line<'a>>) -> Self {
self.left.push((text.into(), "".into()));
self
}
pub fn center_margin(mut self, margin: u16) -> Self {
self.center_margin = margin;
self
}
pub fn center(mut self, text: impl Into<Line<'a>>) -> Self {
self.center = text.into();
self
}
pub fn end(mut self, text: impl Into<Line<'a>>, gap: impl Into<Line<'a>>) -> Self {
self.right.push((text.into(), gap.into()));
self
}
pub fn end_bare(mut self, text: impl Into<Line<'a>>) -> Self {
self.right.push((text.into(), "".into()));
self
}
}
impl<'a> Widget for StatusLineStacked<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
let mut x_end = area.right();
for (status, gap) in self.right {
let width = status.width() as u16;
status.style(self.style).render(
Rect::new(x_end.saturating_sub(width), area.y, width, 1),
buf,
);
x_end = x_end.saturating_sub(width);
let width = gap.width() as u16;
gap.style(self.style).render(
Rect::new(x_end.saturating_sub(width), area.y, width, 1),
buf,
);
x_end = x_end.saturating_sub(width);
}
let mut x_start = area.x;
for (status, gap) in self.left {
let width = status.width() as u16;
status
.style(self.style)
.render(Rect::new(x_start, area.y, width, 1), buf);
x_start += width;
let width = gap.width() as u16;
gap.style(self.style)
.render(Rect::new(x_start, area.y, width, 1), buf);
x_start += width;
}
buf.set_style(
Rect::new(x_start, area.y, x_end.saturating_sub(x_start), 1),
self.style,
);
let center_width = x_end
.saturating_sub(x_start)
.saturating_sub(self.center_margin * 2);
self.center.style(self.style).render(
Rect::new(x_start + self.center_margin, area.y, center_width, 1),
buf,
);
}
}