improve format handling + fix days rendering (#107)
* render_(format) functions, compact `YyyDddHhMmSs` * compact rendering of other formats * add `YDHhMmSs`+`YDdHhMmSs` formats * tests for `YDHhMmSs`+`YDdHhMmSs` * `YyDHhMmSs` + `YyDdHhMmSs` * `YyyDHhMmSs` + `YyyDdHhMmSs` * fix `edit_up` to compare `years` properly and add `test_edit_up_overflow_protection` * fix rendering `Format::YyyDdHhMmSs`
This commit is contained in:
parent
40eb602953
commit
816741f842
@ -2,6 +2,3 @@ pub static APP_NAME: &str = env!("CARGO_PKG_NAME");
|
||||
|
||||
pub static TICK_VALUE_MS: u64 = 1000 / 10; // 0.1 sec in milliseconds
|
||||
pub static FPS_VALUE_MS: u64 = 1000 / 60; // 60 FPS in milliseconds
|
||||
|
||||
pub static LABEL_DAYS: &str = "d";
|
||||
pub static LABEL_YEARS: &str = "y";
|
||||
|
||||
1613
src/widgets/clock.rs
1613
src/widgets/clock.rs
File diff suppressed because it is too large
Load Diff
@ -7,9 +7,13 @@ use ratatui::{
|
||||
pub const DIGIT_SIZE: usize = 5;
|
||||
pub const DIGIT_WIDTH: u16 = DIGIT_SIZE as u16;
|
||||
pub const DIGIT_HEIGHT: u16 = DIGIT_SIZE as u16 + 1 /* border height */;
|
||||
pub const TWO_DIGITS_WIDTH: u16 = DIGIT_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH; // digit-space-digit
|
||||
pub const THREE_DIGITS_WIDTH: u16 =
|
||||
DIGIT_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH + DIGIT_SPACE_WIDTH + DIGIT_WIDTH; // digit-space-digit-space-digit
|
||||
pub const COLON_WIDTH: u16 = 4; // incl. padding left + padding right
|
||||
pub const DOT_WIDTH: u16 = 4; // incl. padding left + padding right
|
||||
pub const DIGIT_SPACE_WIDTH: u16 = 1; // space between digits
|
||||
pub const DIGIT_LABEL_WIDTH: u16 = 3; // label (single char) incl. padding left + padding right
|
||||
|
||||
#[rustfmt::skip]
|
||||
const DIGIT_0: [u8; DIGIT_SIZE * DIGIT_SIZE] = [
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use crate::{
|
||||
common::ClockTypeId,
|
||||
duration::{ONE_DAY, ONE_DECI_SECOND, ONE_HOUR, ONE_MINUTE, ONE_SECOND, ONE_YEAR},
|
||||
duration::{
|
||||
MAX_DURATION, ONE_DAY, ONE_DECI_SECOND, ONE_HOUR, ONE_MINUTE, ONE_SECOND, ONE_YEAR,
|
||||
},
|
||||
widgets::clock::*,
|
||||
};
|
||||
use std::time::Duration;
|
||||
@ -114,20 +116,44 @@ fn test_get_format_boundaries() {
|
||||
// DddHhMmSs
|
||||
c.set_current_value((ONE_YEAR.saturating_sub(ONE_SECOND)).into());
|
||||
assert_eq!(c.get_format(), Format::DddHhMmSs);
|
||||
// YDddHhMmSs
|
||||
// YDHhMmSs
|
||||
c.set_current_value(ONE_YEAR.into());
|
||||
assert_eq!(c.get_format(), Format::YDHhMmSs);
|
||||
// YDdHhMmSs
|
||||
c.set_current_value((ONE_YEAR + (100 * ONE_DAY).saturating_sub(ONE_SECOND)).into());
|
||||
assert_eq!(c.get_format(), Format::YDdHhMmSs);
|
||||
// YDddHhMmSs
|
||||
c.set_current_value((ONE_YEAR + 100 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YDddHhMmSs);
|
||||
// YDddHhMmSs
|
||||
c.set_current_value(((10 * ONE_YEAR).saturating_sub(ONE_SECOND)).into());
|
||||
assert_eq!(c.get_format(), Format::YDddHhMmSs);
|
||||
// YyDddHhMmSs
|
||||
// YyDHhMmSs
|
||||
c.set_current_value((10 * ONE_YEAR).into());
|
||||
assert_eq!(c.get_format(), Format::YyDHhMmSs);
|
||||
// YyDdHhMmSs
|
||||
c.set_current_value((10 * ONE_YEAR + 10 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyDdHhMmSs);
|
||||
// YyDdHhMmSs
|
||||
c.set_current_value((10 * ONE_YEAR + (100 * ONE_DAY).saturating_sub(ONE_SECOND)).into());
|
||||
assert_eq!(c.get_format(), Format::YyDdHhMmSs);
|
||||
// YyDddHhMmSs
|
||||
c.set_current_value((10 * ONE_YEAR + 100 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyDddHhMmSs);
|
||||
// YyDddHhMmSs
|
||||
c.set_current_value(((100 * ONE_YEAR).saturating_sub(ONE_SECOND)).into());
|
||||
assert_eq!(c.get_format(), Format::YyDddHhMmSs);
|
||||
// YyyDddHhMmSs
|
||||
// YyyDHhMmSs
|
||||
c.set_current_value((100 * ONE_YEAR).into());
|
||||
assert_eq!(c.get_format(), Format::YyyDHhMmSs);
|
||||
// YyyDdHhMmSs
|
||||
c.set_current_value((100 * ONE_YEAR + 10 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyyDdHhMmSs);
|
||||
// YyyDdHhMmSs
|
||||
c.set_current_value((100 * ONE_YEAR + (100 * ONE_DAY).saturating_sub(ONE_SECOND)).into());
|
||||
assert_eq!(c.get_format(), Format::YyyDdHhMmSs);
|
||||
// YyyDddHhMmSs
|
||||
c.set_current_value((100 * ONE_YEAR + 100 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyyDddHhMmSs);
|
||||
}
|
||||
|
||||
@ -159,13 +185,43 @@ fn test_get_format_years() {
|
||||
with_decis: false,
|
||||
app_tx: None,
|
||||
});
|
||||
// YDddHhMmSs
|
||||
// YDHhMmSs (1 year, 0 days)
|
||||
assert_eq!(c.get_format(), Format::YDHhMmSs);
|
||||
|
||||
// YDHhMmSs (1 year, 1 day)
|
||||
c.set_current_value((ONE_YEAR + ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YDHhMmSs);
|
||||
|
||||
// YDdHhMmSs (1 year, 10 days)
|
||||
c.set_current_value((ONE_YEAR + 10 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YDdHhMmSs);
|
||||
|
||||
// YDddHhMmSs (1 year, 100 days)
|
||||
c.set_current_value((ONE_YEAR + 100 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YDddHhMmSs);
|
||||
// YyDddHhMmSs
|
||||
|
||||
// YyDHhMmSs (10 years)
|
||||
c.set_current_value((10 * ONE_YEAR).into());
|
||||
assert_eq!(c.get_format(), Format::YyDHhMmSs);
|
||||
|
||||
// YyDdHhMmSs (10 years, 10 days)
|
||||
c.set_current_value((10 * ONE_YEAR + 10 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyDdHhMmSs);
|
||||
|
||||
// YyDddHhMmSs (10 years, 100 days)
|
||||
c.set_current_value((10 * ONE_YEAR + 100 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyDddHhMmSs);
|
||||
|
||||
// YyyDHhMmSs (100 years)
|
||||
c.set_current_value((100 * ONE_YEAR).into());
|
||||
assert_eq!(c.get_format(), Format::YyyDHhMmSs);
|
||||
|
||||
// YyyDdHhMmSs (100 years, 10 days)
|
||||
c.set_current_value((100 * ONE_YEAR + 10 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyyDdHhMmSs);
|
||||
|
||||
// YyyDddHhMmSs (100 years, 100 days)
|
||||
c.set_current_value((100 * ONE_YEAR + 100 * ONE_DAY).into());
|
||||
assert_eq!(c.get_format(), Format::YyyDddHhMmSs);
|
||||
}
|
||||
|
||||
@ -280,6 +336,38 @@ fn test_edit_up_stays_in_days() {
|
||||
assert!(matches!(c.get_mode(), Mode::Editable(Time::Days, _)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_up_overflow_protection() {
|
||||
let mut c = ClockState::<Timer>::new(ClockStateArgs {
|
||||
initial_value: MAX_DURATION.saturating_sub(ONE_SECOND),
|
||||
current_value: MAX_DURATION.saturating_sub(ONE_SECOND),
|
||||
tick_value: ONE_DECI_SECOND,
|
||||
with_decis: false,
|
||||
app_tx: None,
|
||||
});
|
||||
|
||||
c.toggle_edit();
|
||||
c.edit_next(); // Hours
|
||||
c.edit_next(); // Days
|
||||
c.edit_next(); // Years
|
||||
c.edit_up(); // +1y
|
||||
assert!(Duration::from(*c.get_current_value()) <= MAX_DURATION);
|
||||
c.edit_prev(); // Days
|
||||
c.edit_up(); // +1d
|
||||
assert!(Duration::from(*c.get_current_value()) <= MAX_DURATION);
|
||||
c.edit_prev(); // Hours
|
||||
c.edit_up(); // +1h
|
||||
assert!(Duration::from(*c.get_current_value()) <= MAX_DURATION);
|
||||
c.edit_prev(); // Minutes
|
||||
c.edit_up(); // +1m
|
||||
assert!(Duration::from(*c.get_current_value()) <= MAX_DURATION);
|
||||
c.edit_prev(); // Sec.
|
||||
c.edit_up(); // +1s
|
||||
c.edit_up(); // +1s
|
||||
c.edit_up(); // +1s
|
||||
assert!(Duration::from(*c.get_current_value()) <= MAX_DURATION);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_down_years_to_days() {
|
||||
let mut c = ClockState::<Timer>::new(ClockStateArgs {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user