Gauge: use f64 internally and allow to set any f64 between 0 and 1

This commit is contained in:
Karoline Pauls 2018-11-27 01:02:37 +00:00 committed by Florian Dehau
parent 89dac9d2a6
commit cc95c8cfb0
3 changed files with 95 additions and 13 deletions

View File

@ -22,7 +22,7 @@ use util::event::{Event, Events};
struct App {
progress1: u16,
progress2: u16,
progress3: u16,
progress3: f64,
progress4: u16,
}
@ -31,7 +31,7 @@ impl App {
App {
progress1: 0,
progress2: 0,
progress3: 0,
progress3: 0.0,
progress4: 0,
}
}
@ -45,9 +45,9 @@ impl App {
if self.progress2 > 100 {
self.progress2 = 0;
}
self.progress3 += 1;
if self.progress3 > 100 {
self.progress3 = 0;
self.progress3 += 0.001;
if self.progress3 > 1.0 {
self.progress3 = 0.0;
}
self.progress4 += 3;
if self.progress4 > 100 {
@ -98,12 +98,12 @@ fn main() -> Result<(), failure::Error> {
.label(&format!("{}/100", app.progress2))
.render(&mut f, chunks[1]);
Gauge::default()
.block(Block::default().title("Gauge2").borders(Borders::ALL))
.block(Block::default().title("Gauge3").borders(Borders::ALL))
.style(Style::default().fg(Color::Yellow))
.percent(app.progress3)
.ratio(app.progress3)
.render(&mut f, chunks[2]);
Gauge::default()
.block(Block::default().title("Gauge3").borders(Borders::ALL))
.block(Block::default().title("Gauge4").borders(Borders::ALL))
.style(Style::default().fg(Color::Cyan).modifier(Modifier::Italic))
.percent(app.progress4)
.label(&format!("{}/100", app.progress2))

View File

@ -22,7 +22,7 @@ use widgets::{Block, Widget};
/// ```
pub struct Gauge<'a> {
block: Option<Block<'a>>,
percent: u16,
ratio: f64,
label: Option<&'a str>,
style: Style,
}
@ -31,7 +31,7 @@ impl<'a> Default for Gauge<'a> {
fn default() -> Gauge<'a> {
Gauge {
block: None,
percent: 0,
ratio: 0.0,
label: None,
style: Default::default(),
}
@ -45,7 +45,21 @@ impl<'a> Gauge<'a> {
}
pub fn percent(mut self, percent: u16) -> Gauge<'a> {
self.percent = percent;
assert!(
percent <= 100,
"Percentage should be between 0 and 100 inclusively."
);
self.ratio = f64::from(percent) / 100.0;
self
}
/// Sets ratio ([0.0, 1.0]) directly.
pub fn ratio(mut self, ratio: f64) -> Gauge<'a> {
assert!(
ratio <= 1.0 && ratio >= 0.0,
"Ratio should be between 0 and 1 inclusively."
);
self.ratio = ratio;
self
}
@ -78,7 +92,7 @@ impl<'a> Widget for Gauge<'a> {
}
let center = gauge_area.height / 2 + gauge_area.top();
let width = (gauge_area.width * self.percent) / 100;
let width = (f64::from(gauge_area.width) * self.ratio).round() as u16;
let end = gauge_area.left() + width;
for y in gauge_area.top()..gauge_area.bottom() {
// Gauge
@ -88,7 +102,7 @@ impl<'a> Widget for Gauge<'a> {
if y == center {
// Label
let precent_label = format!("{}%", self.percent);
let precent_label = format!("{}%", (self.ratio * 100.0).round());
let label = self.label.unwrap_or(&precent_label);
let label_width = label.width() as u16;
let middle = (gauge_area.width - label_width) / 2 + gauge_area.left();
@ -104,3 +118,26 @@ impl<'a> Widget for Gauge<'a> {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn gauge_invalid_percentage() {
Gauge::default().percent(110);
}
#[test]
#[should_panic]
fn gauge_invalid_ratio_upper_bound() {
Gauge::default().ratio(1.1);
}
#[test]
#[should_panic]
fn gauge_invalid_ratio_lower_bound() {
Gauge::default().ratio(-0.5);
}
}

45
tests/gauge.rs Normal file
View File

@ -0,0 +1,45 @@
extern crate tui;
extern crate unicode_width;
use tui::backend::TestBackend;
use tui::buffer::Buffer;
use tui::layout::{Constraint, Direction, Layout};
use tui::widgets::{Block, Borders, Gauge, Widget};
use tui::Terminal;
#[test]
fn gauge_render() {
let backend = TestBackend::new(40, 10);
let mut terminal = Terminal::new(backend).unwrap();
let size = terminal.size().unwrap();
terminal
.draw(|mut f| {
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(2)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.split(size);
Gauge::default()
.block(Block::default().title("Percentage").borders(Borders::ALL))
.percent(43)
.render(&mut f, chunks[0]);
Gauge::default()
.block(Block::default().title("Ratio").borders(Borders::ALL))
.ratio(0.2113139343131)
.render(&mut f, chunks[1]);
}).unwrap();
let expected = Buffer::with_lines(vec![
" ",
" ",
" ┌Percentage────────────────────────┐ ",
" │ 43% │ ",
" └──────────────────────────────────┘ ",
" ┌Ratio─────────────────────────────┐ ",
" │ 21% │ ",
" └──────────────────────────────────┘ ",
" ",
" ",
]);
assert_eq!(&expected, terminal.backend().buffer());
}