mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-24 01:46:31 +00:00
Make progressbar more robust to invalid min/max values
This commit is contained in:
parent
2cedc8ae76
commit
8290c3f62a
@ -2,6 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use std::cmp;
|
||||||
|
|
||||||
use {Cursive, Printer};
|
use {Cursive, Printer};
|
||||||
use align::HAlign;
|
use align::HAlign;
|
||||||
@ -44,8 +45,14 @@ pub struct ProgressBar {
|
|||||||
pub type Ticker = Box<Fn(usize) + Send>;
|
pub type Ticker = Box<Fn(usize) + Send>;
|
||||||
|
|
||||||
fn make_percentage(value: usize, (min, max): (usize, usize)) -> String {
|
fn make_percentage(value: usize, (min, max): (usize, usize)) -> String {
|
||||||
let percent = 101 * (value - min) / (1 + max - min);
|
if value < min {
|
||||||
format!("{} %", percent)
|
// ?? Negative progress?
|
||||||
|
let percent = 101 * (min - value) / (1 + max - min);
|
||||||
|
format!("-{} %", percent)
|
||||||
|
} else {
|
||||||
|
let percent = 101 * (value - min) / (1 + max - min);
|
||||||
|
format!("{} %", percent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_default!(ProgressBar);
|
new_default!(ProgressBar);
|
||||||
@ -125,22 +132,36 @@ impl ProgressBar {
|
|||||||
/// Sets the minimum value.
|
/// Sets the minimum value.
|
||||||
///
|
///
|
||||||
/// When `value` equals `min`, the bar is at the minimum level.
|
/// When `value` equals `min`, the bar is at the minimum level.
|
||||||
|
///
|
||||||
|
/// If `self.min > max`, `self.min` is set to `max`.
|
||||||
pub fn min(mut self, min: usize) -> Self {
|
pub fn min(mut self, min: usize) -> Self {
|
||||||
self.min = min;
|
self.min = min;
|
||||||
|
self.max = cmp::max(self.max, self.min);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the maximum value.
|
/// Sets the maximum value.
|
||||||
///
|
///
|
||||||
/// When `value` equals `max`, the bar is at the maximum level.
|
/// When `value` equals `max`, the bar is at the maximum level.
|
||||||
|
///
|
||||||
|
/// If `min > self.max`, `self.max` is set to `min`.
|
||||||
pub fn max(mut self, max: usize) -> Self {
|
pub fn max(mut self, max: usize) -> Self {
|
||||||
self.max = max;
|
self.max = max;
|
||||||
|
self.min = cmp::min(self.min, self.max);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the `min` and `max` range for the value.
|
/// Sets the `min` and `max` range for the value.
|
||||||
|
///
|
||||||
|
/// If `min > max`, swap the two values.
|
||||||
pub fn range(self, min: usize, max: usize) -> Self {
|
pub fn range(self, min: usize, max: usize) -> Self {
|
||||||
self.min(min).max(max)
|
if min > max {
|
||||||
|
self.min(max).max(min)
|
||||||
|
} else {
|
||||||
|
self.min(min).max(max)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current value.
|
/// Sets the current value.
|
||||||
@ -157,8 +178,15 @@ impl View for ProgressBar {
|
|||||||
let available = printer.size.x;
|
let available = printer.size.x;
|
||||||
|
|
||||||
let value = self.value.load(Ordering::Relaxed);
|
let value = self.value.load(Ordering::Relaxed);
|
||||||
let length = ((1 + available) * (value - self.min)) /
|
|
||||||
(1 + self.max - self.min);
|
// If we're under the minimum, don't draw anything.
|
||||||
|
// If we're over the maximum, we'll try to draw more, but the printer
|
||||||
|
// will crop us anyway, so it's not a big deal.
|
||||||
|
let length = if value < self.min {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
((1 + available) * (value - self.min)) / (1 + self.max - self.min)
|
||||||
|
};
|
||||||
|
|
||||||
let label = (self.label_maker)(value, (self.min, self.max));
|
let label = (self.label_maker)(value, (self.min, self.max));
|
||||||
let offset = HAlign::Center.get_offset(label.len(), printer.size.x);
|
let offset = HAlign::Center.get_offset(label.len(), printer.size.x);
|
||||||
|
Loading…
Reference in New Issue
Block a user