use retroglyph_core::{Backend, Color, Rect, Style, Terminal};
use unicode_width::UnicodeWidthStr;
use super::{Meter, Text, Widget};
pub(super) fn default_label_style() -> Style {
Style::new().fg(Color::Rgb {
r: 180,
g: 180,
b: 200,
})
}
pub(super) fn render<B: Backend>(
term: &mut Terminal<B>,
area: Rect,
label: &str,
label_style: Style,
ratio: f32,
readout: &str,
) {
if area.width() < 4 {
return;
}
let y = area.top();
let ratio = ratio.clamp(0.0, 1.0);
let color = Meter::new(ratio).color();
let label_w = label.width().min(area.width_usize());
let reserved = label_w + 1 + readout.width() + 1; let bar_w = area.width_usize().saturating_sub(reserved);
let label_area = Rect::new(area.left(), y, label_w as u16, 1);
Text::new(label).style(label_style).render(label_area, term);
let mut x = area.left() + label_w as u16 + 1;
let filled = (ratio * bar_w as f32).round() as usize;
let filled_style = Style::new().fg(color);
let empty_style = Style::new().fg(Color::Rgb {
r: 50,
g: 50,
b: 60,
});
for i in 0..bar_w {
let (ch, style) = if i < filled {
('█', filled_style)
} else {
('░', empty_style)
};
term.put_styled(x, y, ch, style);
x += 1;
}
x += 1; let readout_area = Rect::new(x, y, area.right().saturating_sub(x), 1);
Text::new(readout)
.style(Style::new().fg(color))
.render(readout_area, term);
term.reset_style();
}
#[cfg(test)]
mod tests {
use retroglyph_core::Headless;
use super::*;
#[test]
fn wide_char_label_uses_display_width_not_byte_length() {
let area = Rect::new(0, 0, 20, 1);
let mut term = Terminal::new(Headless::new(20, 1));
render(&mut term, area, "あ", default_label_style(), 0.5, "");
assert_eq!(term.grid().get(3, 0).glyph(), '█');
}
}