mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Smoother progress bars
This commit is contained in:
parent
a4111accce
commit
acf075369c
@ -37,7 +37,7 @@ fn phase_1(s: &mut Cursive) {
|
|||||||
// Phase 1 is easy: a simple pre-loading.
|
// Phase 1 is easy: a simple pre-loading.
|
||||||
|
|
||||||
// Number of ticks
|
// Number of ticks
|
||||||
let n_max = 500;
|
let n_max = 1000;
|
||||||
|
|
||||||
// This is the callback channel
|
// This is the callback channel
|
||||||
let cb = s.cb_sink().clone();
|
let cb = s.cb_sink().clone();
|
||||||
|
@ -41,13 +41,29 @@ pub struct ProgressBar {
|
|||||||
|
|
||||||
fn make_percentage(value: usize, (min, max): (usize, usize)) -> String {
|
fn make_percentage(value: usize, (min, max): (usize, usize)) -> String {
|
||||||
if value < min {
|
if value < min {
|
||||||
// ?? Negative progress?
|
return format!("0 %");
|
||||||
let percent = 101 * (min - value) / (1 + max - min);
|
|
||||||
format!("-{} %", percent)
|
|
||||||
} else {
|
|
||||||
let percent = 101 * (value - min) / (1 + max - min);
|
|
||||||
format!("{} %", percent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (percentage, extra) = ratio(value - min, max - min, 100);
|
||||||
|
let percentage = if extra > 4 { percentage + 1 } else { percentage };
|
||||||
|
format!("{} %", percentage)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns length * value/max
|
||||||
|
///
|
||||||
|
/// Constraint: `value` from 0 to `max` should, as much as possible, produce equal-sized segments
|
||||||
|
/// from 0 to length.
|
||||||
|
///
|
||||||
|
/// Returns a tuple with:
|
||||||
|
/// * The integer part of the division
|
||||||
|
/// * A value between 0 and 8 (exclusive) corresponding to the remainder.
|
||||||
|
fn ratio(value: usize, max: usize, length: usize) -> (usize, usize) {
|
||||||
|
let integer = length * value / max;
|
||||||
|
let fraction = length * value - max * integer;
|
||||||
|
|
||||||
|
let fraction = fraction * 8 / max;
|
||||||
|
|
||||||
|
(integer, fraction)
|
||||||
}
|
}
|
||||||
|
|
||||||
new_default!(ProgressBar);
|
new_default!(ProgressBar);
|
||||||
@ -165,6 +181,20 @@ impl ProgressBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sub_block(extra: usize) -> &'static str {
|
||||||
|
match extra {
|
||||||
|
0 => " ",
|
||||||
|
1 => "▏",
|
||||||
|
2 => "▎",
|
||||||
|
3 => "▍",
|
||||||
|
4 => "▌",
|
||||||
|
5 => "▋",
|
||||||
|
6 => "▊",
|
||||||
|
7 => "▉",
|
||||||
|
_ => "█",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl View for ProgressBar {
|
impl View for ProgressBar {
|
||||||
fn draw(&self, printer: &Printer) {
|
fn draw(&self, printer: &Printer) {
|
||||||
// Now, the bar itself...
|
// Now, the bar itself...
|
||||||
@ -175,21 +205,25 @@ impl View for ProgressBar {
|
|||||||
// If we're under the minimum, don't draw anything.
|
// 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
|
// 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.
|
// will crop us anyway, so it's not a big deal.
|
||||||
let length = if value < self.min {
|
let (length, extra) = if value < self.min {
|
||||||
0
|
(0, 0)
|
||||||
} else {
|
} else {
|
||||||
((1 + available) * (value - self.min)) / (1 + self.max - self.min)
|
ratio(value - self.min, self.max - self.min, available)
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
printer.with_color(ColorStyle::highlight(), |printer| {
|
printer.with_color(ColorStyle::highlight(), |printer| {
|
||||||
|
// Draw the right half of the label in reverse
|
||||||
printer.with_effect(Effect::Reverse, |printer| {
|
printer.with_effect(Effect::Reverse, |printer| {
|
||||||
|
printer.print((length, 0), sub_block(extra));
|
||||||
printer.print((offset, 0), &label);
|
printer.print((offset, 0), &label);
|
||||||
});
|
});
|
||||||
let printer = &printer.cropped((length, 1));
|
let printer = &printer.cropped((length, 1));
|
||||||
printer.print_hline((0, 0), length, " ");
|
printer.print_hline((0, 0), length, " ");
|
||||||
|
|
||||||
|
// Draw the left part in highlight (it may be cropped)
|
||||||
printer.print((offset, 0), &label);
|
printer.print((offset, 0), &label);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user