use ratatui::prelude::{Widget, Rect, Buffer, Style, symbols, Color};
#[derive(Debug, Clone, Copy, Default)]
pub struct Meter {
meter_style: Style,
use_ascii: bool,
ratio: f64,
}
impl Meter {
pub fn ratio(self, ratio: f64) -> Self {
Self { ratio, ..self }
}
pub fn style(self, meter_style: Style) -> Self {
Self { meter_style, ..self }
}
pub fn use_ascii(self, use_ascii: bool) -> Self {
Self { use_ascii, ..self }
}
}
impl Widget for Meter {
fn render(self, area: Rect, buf: &mut Buffer) {
if area.is_empty() {
return;
}
buf.set_style(area, self.meter_style);
let filled_width = f64::from(area.width) * self.ratio;
let end = if self.use_ascii {
area.left() + filled_width.round() as u16
} else {
area.left() + filled_width.floor() as u16
};
for y in area.top()..area.bottom() {
for x in area.left()..end {
buf.get_mut(x, y)
.set_symbol(symbols::block::FULL)
.set_fg(self.meter_style.fg.unwrap_or(Color::Reset))
.set_bg(self.meter_style.bg.unwrap_or(Color::Reset));
}
if !self.use_ascii && self.ratio < 1.0 {
let symbol = match ((filled_width % 1.0) * 8.0).round() as u16 {
1 => symbols::block::ONE_EIGHTH,
2 => symbols::block::ONE_QUARTER,
3 => symbols::block::THREE_EIGHTHS,
4 => symbols::block::HALF,
5 => symbols::block::FIVE_EIGHTHS,
6 => symbols::block::THREE_QUARTERS,
7 => symbols::block::SEVEN_EIGHTHS,
8 => symbols::block::FULL,
_ => " ",
};
buf.get_mut(end, y).set_symbol(symbol);
}
}
}
}