mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-26 11:09:23 -06:00
LR-BEHAV-BG-TASKS: one whole-percent rule for the bar text and its announced value
This commit is contained in:
@@ -142,12 +142,12 @@ pub fn detail_toggle(app: &mut LightcraftApp, ui: &mut egui::Ui, id: PhotoId, on
|
||||
}
|
||||
|
||||
/// The bar under the Denoise slider while a photo's picture is made: at most 240 px wide, and
|
||||
/// sweeping while the number of tiles is not known yet. The percentage is floored, as the bar's
|
||||
/// accessible value is (and the SAM bar's text): 100 % only once done.
|
||||
/// sweeping while the number of tiles is not known yet. The percentage is `progress::percent`, as the
|
||||
/// bar's accessible value is: 100 % only once done.
|
||||
pub(crate) fn detail_bar(ui: &mut egui::Ui, done: u64, total: u64) -> egui::Response {
|
||||
let fraction = crate::progress::fraction_of(done, total);
|
||||
let text = match fraction {
|
||||
Some(f) => tr_format!("Making the denoised picture… {}%", (f * 100.0).floor() as u32),
|
||||
Some(f) => tr_format!("Making the denoised picture… {}%", crate::progress::percent(f)),
|
||||
None => tr("Starting…").to_string(),
|
||||
};
|
||||
crate::progress::Progress::new(fraction).label(text).width(ui.available_width().min(240.0)).widget("denoise:progress").show(ui)
|
||||
|
||||
@@ -766,7 +766,7 @@ pub(crate) fn start_describe(app: &mut LightcraftApp, op: &str) {
|
||||
pub(crate) fn sam_download_bar(ui: &mut egui::Ui, done: u64, total: u64, width: f32) -> egui::Response {
|
||||
let fraction = crate::progress::fraction_of(done, total);
|
||||
let label = match fraction {
|
||||
Some(f) => format!("SAM 3: {} %", (f64::from(f) * 100.0).floor()),
|
||||
Some(f) => format!("SAM 3: {} %", crate::progress::percent(f)),
|
||||
None => "SAM 3".to_string(),
|
||||
};
|
||||
crate::progress::Progress::new(fraction).label(label).width(width).widget("maskSamProgress").show(ui)
|
||||
|
||||
@@ -45,6 +45,15 @@ pub fn fraction_of(done: u64, total: u64) -> Option<f32> {
|
||||
(total > 0).then(|| clamp_fraction(done as f32 / total as f32))
|
||||
}
|
||||
|
||||
/// The whole percent a bar says for `fraction`: rounded down, so 100 comes only at exactly 1.0, but
|
||||
/// with a little slack so a fraction that is exact in decimals (53 of 100, held as 0.52999997)
|
||||
/// still says 53. A bar's text and its accessible value both come from here, so they agree.
|
||||
pub fn percent(fraction: f32) -> u32 {
|
||||
let f = clamp_fraction(fraction);
|
||||
let whole = (f64::from(f) * 100.0 + 1e-3).floor() as u32;
|
||||
if f < 1.0 { whole.min(99) } else { 100 }
|
||||
}
|
||||
|
||||
/// A progress bar, built and then shown with [`Progress::show`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Progress {
|
||||
@@ -103,7 +112,7 @@ impl Progress {
|
||||
Some(l) => egui::WidgetInfo::labeled(egui::WidgetType::ProgressIndicator, ui.is_enabled(), l),
|
||||
None => egui::WidgetInfo::new(egui::WidgetType::ProgressIndicator),
|
||||
};
|
||||
info.value = self.fraction.map(|f| f64::from(f * 100.0).floor());
|
||||
info.value = self.fraction.map(|f| f64::from(percent(f)));
|
||||
info
|
||||
});
|
||||
if let Some(w) = &self.widget {
|
||||
|
||||
@@ -240,13 +240,27 @@ fn the_denoise_bars_keep_their_widths_in_a_wide_container() {
|
||||
|
||||
#[test]
|
||||
fn the_denoise_bar_label_and_its_accessible_value_agree() {
|
||||
// 3 of 7 is 42.86 %: the number drawn on the bar is the one announced
|
||||
let (nodes, _, _) = frames(Vec::new(), |ui| {
|
||||
crate::panels::denoise::detail_bar(ui, 3, 7);
|
||||
});
|
||||
let bar = nodes.iter().find(|n| n.role == "ProgressIndicator").unwrap_or_else(|| panic!("{nodes:?}"));
|
||||
let shown: f64 = bar.label.rsplit(' ').next().unwrap().trim_end_matches('%').parse().unwrap();
|
||||
assert_eq!(bar.value, Some(shown), "{bar:?}");
|
||||
// the number drawn on the bar is the one announced, and exact decimals stay exact
|
||||
for (done, total, says) in
|
||||
[(3, 7, 42.0), (53, 100, 53.0), (59, 100, 59.0), (29, 100, 29.0), (99, 100, 99.0), (100, 100, 100.0), (999, 1000, 99.0)]
|
||||
{
|
||||
let (nodes, _, _) = frames(Vec::new(), |ui| {
|
||||
crate::panels::denoise::detail_bar(ui, done, total);
|
||||
});
|
||||
let bar = nodes.iter().find(|n| n.role == "ProgressIndicator").unwrap_or_else(|| panic!("{nodes:?}"));
|
||||
let shown: f64 = bar.label.rsplit(' ').next().unwrap().trim_end_matches('%').parse().unwrap();
|
||||
assert_eq!((shown, bar.value), (says, Some(says)), "{done}/{total}: {bar:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_sam_bar_text_and_its_accessible_value_agree() {
|
||||
for (done, total, says) in [(53, 100, 53.0), (59, 100, 59.0), (29, 100, 29.0), (999, 1000, 99.0), (100, 100, 100.0)] {
|
||||
let (nodes, _, _) = frames(Vec::new(), |ui| crate::panels::masking::sam_download_bar(ui, done, total, 200.0).rect.width());
|
||||
let bar = nodes.iter().find(|n| n.role == "ProgressIndicator").unwrap_or_else(|| panic!("{nodes:?}"));
|
||||
assert_eq!(bar.label, format!("SAM 3: {says} %"), "{done}/{total}");
|
||||
assert_eq!(bar.value, Some(says), "{done}/{total}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user