DurationEx
This commit is contained in:
parent
ae1a48e5e8
commit
ed7c17caf9
20
src/app.rs
20
src/app.rs
@ -232,13 +232,19 @@ impl App {
|
|||||||
style: self.style,
|
style: self.style,
|
||||||
with_decis: self.with_decis,
|
with_decis: self.with_decis,
|
||||||
pomodoro_mode: self.pomodoro.get_mode().clone(),
|
pomodoro_mode: self.pomodoro.get_mode().clone(),
|
||||||
inital_value_work: self.pomodoro.get_clock_work().initial_value,
|
inital_value_work: Duration::from(*self.pomodoro.get_clock_work().get_initial_value()),
|
||||||
current_value_work: self.pomodoro.get_clock_work().current_value,
|
current_value_work: Duration::from(*self.pomodoro.get_clock_work().get_current_value()),
|
||||||
inital_value_pause: self.pomodoro.get_clock_pause().initial_value,
|
inital_value_pause: Duration::from(
|
||||||
current_value_pause: self.pomodoro.get_clock_pause().current_value,
|
*self.pomodoro.get_clock_pause().get_initial_value(),
|
||||||
inital_value_countdown: self.countdown.get_clock().initial_value,
|
),
|
||||||
current_value_countdown: self.countdown.get_clock().current_value,
|
current_value_pause: Duration::from(
|
||||||
current_value_timer: self.timer.get_clock().current_value,
|
*self.pomodoro.get_clock_pause().get_current_value(),
|
||||||
|
),
|
||||||
|
inital_value_countdown: Duration::from(*self.countdown.get_clock().get_initial_value()),
|
||||||
|
current_value_countdown: Duration::from(
|
||||||
|
*self.countdown.get_clock().get_current_value(),
|
||||||
|
),
|
||||||
|
current_value_timer: Duration::from(*self.timer.get_clock().get_current_value()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
143
src/duration.rs
Normal file
143
src/duration.rs
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
use std::fmt;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
pub const ONE_SECOND: Duration = Duration::from_secs(1);
|
||||||
|
pub const ONE_MINUTE: Duration = Duration::from_secs(SECS_PER_MINUTE);
|
||||||
|
pub const ONE_HOUR: Duration = Duration::from_secs(MINS_PER_HOUR * SECS_PER_MINUTE);
|
||||||
|
|
||||||
|
// unstable
|
||||||
|
// https://doc.rust-lang.org/src/core/time.rs.html#32
|
||||||
|
pub const SECS_PER_MINUTE: u64 = 60;
|
||||||
|
// unstable
|
||||||
|
// https://doc.rust-lang.org/src/core/time.rs.html#34
|
||||||
|
pub const MINS_PER_HOUR: u64 = 60;
|
||||||
|
// unstable
|
||||||
|
// https://doc.rust-lang.org/src/core/time.rs.html#36
|
||||||
|
const HOURS_PER_DAY: u64 = 24;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialOrd)]
|
||||||
|
pub struct DurationEx {
|
||||||
|
inner: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for DurationEx {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.inner == other.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Duration> for DurationEx {
|
||||||
|
fn from(inner: Duration) -> Self {
|
||||||
|
Self { inner }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DurationEx> for Duration {
|
||||||
|
fn from(ex: DurationEx) -> Self {
|
||||||
|
ex.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DurationEx {
|
||||||
|
pub fn seconds(&self) -> u64 {
|
||||||
|
self.inner.as_secs()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn seconds_mod(&self) -> u64 {
|
||||||
|
self.seconds() % SECS_PER_MINUTE
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hours(&self) -> u64 {
|
||||||
|
self.seconds() / (SECS_PER_MINUTE * MINS_PER_HOUR)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hours_mod(&self) -> u64 {
|
||||||
|
self.hours() % HOURS_PER_DAY
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minutes(&self) -> u64 {
|
||||||
|
self.seconds() / MINS_PER_HOUR
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minutes_mod(&self) -> u64 {
|
||||||
|
self.minutes() % SECS_PER_MINUTE
|
||||||
|
}
|
||||||
|
|
||||||
|
// deciseconds
|
||||||
|
pub fn decis(&self) -> u64 {
|
||||||
|
(self.inner.subsec_millis() / 100) as u64
|
||||||
|
}
|
||||||
|
// milliseconds
|
||||||
|
pub fn millis(&self) -> u128 {
|
||||||
|
self.inner.as_millis()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn saturating_add(&self, ex: DurationEx) -> Self {
|
||||||
|
let inner = self.inner.saturating_add(ex.inner);
|
||||||
|
Self { inner }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn saturating_sub(&self, ex: DurationEx) -> Self {
|
||||||
|
let inner = self.inner.saturating_sub(ex.inner);
|
||||||
|
Self { inner }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for DurationEx {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
if self.hours() >= 10 {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{:02}:{:02}:{:02}",
|
||||||
|
self.hours_mod(),
|
||||||
|
self.minutes_mod(),
|
||||||
|
self.seconds_mod(),
|
||||||
|
)
|
||||||
|
} else if self.hours() >= 1 {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}:{:02}:{:02}",
|
||||||
|
self.hours(),
|
||||||
|
self.minutes_mod(),
|
||||||
|
self.seconds_mod()
|
||||||
|
)
|
||||||
|
} else if self.minutes() >= 10 {
|
||||||
|
write!(f, "{:02}:{:02}", self.minutes_mod(), self.seconds_mod())
|
||||||
|
} else if self.minutes() >= 1 {
|
||||||
|
write!(f, "{}:{:02}", self.minutes(), self.seconds_mod())
|
||||||
|
} else if self.seconds() >= 10 {
|
||||||
|
write!(f, "{:02}", self.seconds_mod())
|
||||||
|
} else {
|
||||||
|
write!(f, "{}", self.seconds())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fmt() {
|
||||||
|
// hh:mm:ss
|
||||||
|
let ex: DurationEx = Duration::from_secs(36001).into();
|
||||||
|
assert_eq!(format!("{}", ex), "10:00:01");
|
||||||
|
// h:mm:ss
|
||||||
|
let ex: DurationEx = Duration::from_secs(3601).into();
|
||||||
|
assert_eq!(format!("{}", ex), "1:00:01");
|
||||||
|
// mm:ss
|
||||||
|
let ex: DurationEx = Duration::from_secs(71).into();
|
||||||
|
assert_eq!(format!("{}", ex), "1:11");
|
||||||
|
// m:ss
|
||||||
|
let ex: DurationEx = Duration::from_secs(61).into();
|
||||||
|
assert_eq!(format!("{}", ex), "1:01");
|
||||||
|
// ss
|
||||||
|
let ex: DurationEx = Duration::from_secs(11).into();
|
||||||
|
assert_eq!(format!("{}", ex), "11");
|
||||||
|
// s
|
||||||
|
let ex: DurationEx = Duration::from_secs(1).into();
|
||||||
|
assert_eq!(format!("{}", ex), "1");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ mod events;
|
|||||||
mod logging;
|
mod logging;
|
||||||
|
|
||||||
mod args;
|
mod args;
|
||||||
|
mod duration;
|
||||||
mod storage;
|
mod storage;
|
||||||
mod terminal;
|
mod terminal;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|||||||
@ -12,7 +12,14 @@ use ratatui::{
|
|||||||
widgets::StatefulWidget,
|
widgets::StatefulWidget,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::center_horizontal;
|
use crate::{
|
||||||
|
duration::{DurationEx, MINS_PER_HOUR, ONE_HOUR, ONE_MINUTE, ONE_SECOND, SECS_PER_MINUTE},
|
||||||
|
utils::center_horizontal,
|
||||||
|
};
|
||||||
|
|
||||||
|
// max. 99:59:59
|
||||||
|
const MAX_DURATION: Duration =
|
||||||
|
Duration::from_secs(100 * MINS_PER_HOUR * SECS_PER_MINUTE).saturating_sub(ONE_SECOND);
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Display, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Display, PartialEq, Eq)]
|
||||||
pub enum Time {
|
pub enum Time {
|
||||||
@ -49,24 +56,6 @@ impl fmt::Display for Mode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unstable
|
|
||||||
// https://doc.rust-lang.org/src/core/time.rs.html#32
|
|
||||||
const SECS_PER_MINUTE: u64 = 60;
|
|
||||||
// unstable
|
|
||||||
// https://doc.rust-lang.org/src/core/time.rs.html#34
|
|
||||||
const MINS_PER_HOUR: u64 = 60;
|
|
||||||
// unstable
|
|
||||||
// https://doc.rust-lang.org/src/core/time.rs.html#36
|
|
||||||
const HOURS_PER_DAY: u64 = 24;
|
|
||||||
|
|
||||||
// max. 99:59:59
|
|
||||||
const MAX_DURATION: Duration =
|
|
||||||
Duration::from_secs(100 * MINS_PER_HOUR * SECS_PER_MINUTE).saturating_sub(ONE_SECOND);
|
|
||||||
|
|
||||||
const ONE_SECOND: Duration = Duration::from_secs(1);
|
|
||||||
const ONE_MINUTE: Duration = Duration::from_secs(SECS_PER_MINUTE);
|
|
||||||
const ONE_HOUR: Duration = Duration::from_secs(MINS_PER_HOUR * SECS_PER_MINUTE);
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Display, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Display, PartialOrd, Ord)]
|
||||||
pub enum Format {
|
pub enum Format {
|
||||||
S,
|
S,
|
||||||
@ -115,9 +104,9 @@ impl Style {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Clock<T> {
|
pub struct Clock<T> {
|
||||||
pub initial_value: Duration,
|
initial_value: DurationEx,
|
||||||
pub current_value: Duration,
|
current_value: DurationEx,
|
||||||
tick_value: Duration,
|
tick_value: DurationEx,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
format: Format,
|
format: Format,
|
||||||
pub style: Style,
|
pub style: Style,
|
||||||
@ -142,17 +131,25 @@ impl<T> Clock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_initial_value(&self) -> &DurationEx {
|
||||||
|
&self.initial_value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_current_value(&self) -> &DurationEx {
|
||||||
|
&self.current_value
|
||||||
|
}
|
||||||
|
|
||||||
pub fn toggle_edit(&mut self) {
|
pub fn toggle_edit(&mut self) {
|
||||||
self.mode = match self.mode.clone() {
|
self.mode = match self.mode.clone() {
|
||||||
Mode::Editable(_, prev) => {
|
Mode::Editable(_, prev) => {
|
||||||
let p = *prev;
|
let p = *prev;
|
||||||
// special cases: Should `Mode` be updated?
|
// special cases: Should `Mode` be updated?
|
||||||
// 1. `Done` -> `Initial` ?
|
// 1. `Done` -> `Initial` ?
|
||||||
if p == Mode::Done && self.current_value.gt(&Duration::ZERO) {
|
if p == Mode::Done && self.current_value.gt(&Duration::ZERO.into()) {
|
||||||
Mode::Initial
|
Mode::Initial
|
||||||
}
|
}
|
||||||
// 2. `_` -> `Done` ?
|
// 2. `_` -> `Done` ?
|
||||||
else if p != Mode::Done && self.current_value.eq(&Duration::ZERO) {
|
else if p != Mode::Done && self.current_value.eq(&Duration::ZERO.into()) {
|
||||||
Mode::Done
|
Mode::Done
|
||||||
}
|
}
|
||||||
// 3. `_` -> `_` (no change)
|
// 3. `_` -> `_` (no change)
|
||||||
@ -171,14 +168,14 @@ impl<T> Clock<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_current_up(&mut self) {
|
pub fn edit_current_up(&mut self) {
|
||||||
self.current_value = match self.mode {
|
match self.mode {
|
||||||
Mode::Editable(Time::Seconds, _) => {
|
Mode::Editable(Time::Seconds, _) => {
|
||||||
if self
|
if self
|
||||||
.current_value
|
.current_value
|
||||||
// < 99:59:58
|
// < 99:59:58
|
||||||
.le(&MAX_DURATION.saturating_sub(ONE_SECOND))
|
.le(&MAX_DURATION.saturating_sub(ONE_SECOND).into())
|
||||||
{
|
{
|
||||||
self.current_value.saturating_add(ONE_SECOND)
|
self.current_value.saturating_add(ONE_SECOND.into())
|
||||||
} else {
|
} else {
|
||||||
self.current_value
|
self.current_value
|
||||||
}
|
}
|
||||||
@ -187,9 +184,9 @@ impl<T> Clock<T> {
|
|||||||
if self
|
if self
|
||||||
.current_value
|
.current_value
|
||||||
// < 99:58:59
|
// < 99:58:59
|
||||||
.le(&MAX_DURATION.saturating_sub(ONE_MINUTE))
|
.le(&MAX_DURATION.saturating_sub(ONE_MINUTE).into())
|
||||||
{
|
{
|
||||||
self.current_value.saturating_add(ONE_MINUTE)
|
self.current_value.saturating_add(ONE_MINUTE.into())
|
||||||
} else {
|
} else {
|
||||||
self.current_value
|
self.current_value
|
||||||
}
|
}
|
||||||
@ -198,9 +195,9 @@ impl<T> Clock<T> {
|
|||||||
if self
|
if self
|
||||||
.current_value
|
.current_value
|
||||||
// < 98:59:59
|
// < 98:59:59
|
||||||
.lt(&MAX_DURATION.saturating_sub(ONE_HOUR))
|
.lt(&MAX_DURATION.saturating_sub(ONE_HOUR).into())
|
||||||
{
|
{
|
||||||
self.current_value.saturating_add(ONE_HOUR)
|
self.current_value.saturating_add(ONE_HOUR.into())
|
||||||
} else {
|
} else {
|
||||||
self.current_value
|
self.current_value
|
||||||
}
|
}
|
||||||
@ -211,9 +208,13 @@ impl<T> Clock<T> {
|
|||||||
}
|
}
|
||||||
pub fn edit_current_down(&mut self) {
|
pub fn edit_current_down(&mut self) {
|
||||||
self.current_value = match self.mode {
|
self.current_value = match self.mode {
|
||||||
Mode::Editable(Time::Seconds, _) => self.current_value.saturating_sub(ONE_SECOND),
|
Mode::Editable(Time::Seconds, _) => {
|
||||||
Mode::Editable(Time::Minutes, _) => self.current_value.saturating_sub(ONE_MINUTE),
|
self.current_value.saturating_sub(ONE_SECOND.into())
|
||||||
Mode::Editable(Time::Hours, _) => self.current_value.saturating_sub(ONE_HOUR),
|
}
|
||||||
|
Mode::Editable(Time::Minutes, _) => {
|
||||||
|
self.current_value.saturating_sub(ONE_MINUTE.into())
|
||||||
|
}
|
||||||
|
Mode::Editable(Time::Hours, _) => self.current_value.saturating_sub(ONE_HOUR.into()),
|
||||||
_ => self.current_value,
|
_ => self.current_value,
|
||||||
};
|
};
|
||||||
self.update_format();
|
self.update_format();
|
||||||
@ -285,35 +286,6 @@ impl<T> Clock<T> {
|
|||||||
self.update_format();
|
self.update_format();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_hours(&self) -> u64 {
|
|
||||||
self.current_seconds() / (SECS_PER_MINUTE * MINS_PER_HOUR)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_hours_mod(&self) -> u64 {
|
|
||||||
self.current_hours() % HOURS_PER_DAY
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_minutes(&self) -> u64 {
|
|
||||||
self.current_seconds() / MINS_PER_HOUR
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_minutes_mod(&self) -> u64 {
|
|
||||||
self.current_minutes() % SECS_PER_MINUTE
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_seconds(&self) -> u64 {
|
|
||||||
self.current_value.as_secs()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn current_seconds_mod(&self) -> u64 {
|
|
||||||
self.current_seconds() % SECS_PER_MINUTE
|
|
||||||
}
|
|
||||||
|
|
||||||
// deciseconds
|
|
||||||
fn current_decis(&self) -> u64 {
|
|
||||||
(self.current_value.subsec_millis() / 100) as u64
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_done(&self) -> bool {
|
pub fn is_done(&self) -> bool {
|
||||||
self.mode == Mode::Done
|
self.mode == Mode::Done
|
||||||
}
|
}
|
||||||
@ -323,15 +295,15 @@ impl<T> Clock<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_format(&self) -> Format {
|
pub fn get_format(&self) -> Format {
|
||||||
if self.current_hours() >= 10 {
|
if self.current_value.hours() >= 10 {
|
||||||
Format::HhMmSs
|
Format::HhMmSs
|
||||||
} else if self.current_hours() >= 1 {
|
} else if self.current_value.hours() >= 1 {
|
||||||
Format::HMmSs
|
Format::HMmSs
|
||||||
} else if self.current_minutes() >= 10 {
|
} else if self.current_value.minutes() >= 10 {
|
||||||
Format::MmSs
|
Format::MmSs
|
||||||
} else if self.current_minutes() >= 1 {
|
} else if self.current_value.minutes() >= 1 {
|
||||||
Format::MSs
|
Format::MSs
|
||||||
} else if self.current_seconds() >= 10 {
|
} else if self.current_value.seconds() >= 10 {
|
||||||
Format::Ss
|
Format::Ss
|
||||||
} else {
|
} else {
|
||||||
Format::S
|
Format::S
|
||||||
@ -339,19 +311,6 @@ impl<T> Clock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Display for Clock<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{:02}:{:02}:{:02}.{}",
|
|
||||||
self.current_hours_mod(),
|
|
||||||
self.current_minutes_mod(),
|
|
||||||
self.current_seconds_mod(),
|
|
||||||
self.current_decis()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Countdown {}
|
pub struct Countdown {}
|
||||||
|
|
||||||
@ -365,9 +324,9 @@ impl Clock<Countdown> {
|
|||||||
with_decis,
|
with_decis,
|
||||||
} = args;
|
} = args;
|
||||||
let mut instance = Self {
|
let mut instance = Self {
|
||||||
initial_value,
|
initial_value: initial_value.into(),
|
||||||
current_value,
|
current_value: current_value.into(),
|
||||||
tick_value,
|
tick_value: tick_value.into(),
|
||||||
mode: if current_value == Duration::ZERO {
|
mode: if current_value == Duration::ZERO {
|
||||||
Mode::Done
|
Mode::Done
|
||||||
} else if current_value == initial_value {
|
} else if current_value == initial_value {
|
||||||
@ -394,19 +353,15 @@ impl Clock<Countdown> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_done(&mut self) {
|
fn set_done(&mut self) {
|
||||||
if self.current_value.is_zero() {
|
if self.current_value.eq(&Duration::ZERO.into()) {
|
||||||
self.mode = Mode::Done;
|
self.mode = Mode::Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_percentage_done(&self) -> u16 {
|
pub fn get_percentage_done(&self) -> u16 {
|
||||||
let initial = self.initial_value.as_millis();
|
let elapsed = self.initial_value.saturating_sub(self.current_value);
|
||||||
let elapsed = self
|
|
||||||
.initial_value
|
|
||||||
.saturating_sub(self.current_value)
|
|
||||||
.as_millis();
|
|
||||||
|
|
||||||
(elapsed * 100 / initial) as u16
|
(elapsed.millis() * 100 / self.initial_value.millis()) as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_next(&mut self) {
|
pub fn edit_next(&mut self) {
|
||||||
@ -447,9 +402,9 @@ impl Clock<Timer> {
|
|||||||
with_decis,
|
with_decis,
|
||||||
} = args;
|
} = args;
|
||||||
let mut instance = Self {
|
let mut instance = Self {
|
||||||
initial_value,
|
initial_value: initial_value.into(),
|
||||||
current_value,
|
current_value: current_value.into(),
|
||||||
tick_value,
|
tick_value: tick_value.into(),
|
||||||
mode: if current_value == initial_value {
|
mode: if current_value == initial_value {
|
||||||
Mode::Initial
|
Mode::Initial
|
||||||
} else if current_value >= MAX_DURATION {
|
} else if current_value >= MAX_DURATION {
|
||||||
@ -469,14 +424,14 @@ impl Clock<Timer> {
|
|||||||
|
|
||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
if self.mode == Mode::Tick {
|
if self.mode == Mode::Tick {
|
||||||
self.current_value = self.current_value.saturating_add(self.tick_value);
|
self.current_value.saturating_add(self.tick_value);
|
||||||
self.set_done();
|
self.set_done();
|
||||||
self.update_format();
|
self.update_format();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_done(&mut self) {
|
fn set_done(&mut self) {
|
||||||
if self.current_value >= MAX_DURATION {
|
if self.current_value.ge(&MAX_DURATION.into()) {
|
||||||
self.mode = Mode::Done;
|
self.mode = Mode::Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -846,197 +801,341 @@ where
|
|||||||
Format::HhMmSs if with_decis => {
|
Format::HhMmSs if with_decis => {
|
||||||
let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] =
|
let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_hours() / 10, symbol, edit_hours, hh, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf);
|
state.current_value.hours() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_hours,
|
||||||
|
hh,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf);
|
||||||
self.render_colon(symbol, c_hm, buf);
|
self.render_colon(symbol, c_hm, buf);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() / 10,
|
state.current_value.minutes_mod() / 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
mm,
|
mm,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
self.render_dot(symbol, d, buf);
|
self.render_dot(symbol, d, buf);
|
||||||
self.render_digit(state.current_decis(), symbol, false, ds, buf);
|
self.render_digit(state.current_value.decis(), symbol, false, ds, buf);
|
||||||
}
|
}
|
||||||
Format::HhMmSs => {
|
Format::HhMmSs => {
|
||||||
let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s] =
|
let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_hours() / 10, symbol, edit_hours, hh, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf);
|
state.current_value.hours() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_hours,
|
||||||
|
hh,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf);
|
||||||
self.render_colon(symbol, c_hm, buf);
|
self.render_colon(symbol, c_hm, buf);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() / 10,
|
state.current_value.minutes_mod() / 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
mm,
|
mm,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Format::HMmSs if with_decis => {
|
Format::HMmSs if with_decis => {
|
||||||
let [h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] =
|
let [h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf);
|
self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf);
|
||||||
self.render_colon(symbol, c_hm, buf);
|
self.render_colon(symbol, c_hm, buf);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() / 10,
|
state.current_value.minutes_mod() / 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
mm,
|
mm,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
self.render_dot(symbol, d, buf);
|
self.render_dot(symbol, d, buf);
|
||||||
self.render_digit(state.current_decis(), symbol, false, ds, buf);
|
self.render_digit(state.current_value.decis(), symbol, false, ds, buf);
|
||||||
}
|
}
|
||||||
Format::HMmSs => {
|
Format::HMmSs => {
|
||||||
let [h, c_hm, mm, _, m, c_ms, ss, _, s] =
|
let [h, c_hm, mm, _, m, c_ms, ss, _, s] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf);
|
self.render_digit(state.current_value.hours() % 10, symbol, edit_hours, h, buf);
|
||||||
self.render_colon(symbol, c_hm, buf);
|
self.render_colon(symbol, c_hm, buf);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() / 10,
|
state.current_value.minutes_mod() / 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
mm,
|
mm,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Format::MmSs if with_decis => {
|
Format::MmSs if with_decis => {
|
||||||
let [mm, _, m, c_ms, ss, _, s, d, ds] =
|
let [mm, _, m, c_ms, ss, _, s, d, ds] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() / 10,
|
state.current_value.minutes_mod() / 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
mm,
|
mm,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
self.render_dot(symbol, d, buf);
|
self.render_dot(symbol, d, buf);
|
||||||
self.render_digit(state.current_decis(), symbol, false, ds, buf);
|
self.render_digit(state.current_value.decis(), symbol, false, ds, buf);
|
||||||
}
|
}
|
||||||
Format::MmSs => {
|
Format::MmSs => {
|
||||||
let [mm, _, m, c_ms, ss, _, s] =
|
let [mm, _, m, c_ms, ss, _, s] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() / 10,
|
state.current_value.minutes_mod() / 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
mm,
|
mm,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Format::MSs if with_decis => {
|
Format::MSs if with_decis => {
|
||||||
let [m, c_ms, ss, _, s, d, ds] =
|
let [m, c_ms, ss, _, s, d, ds] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
self.render_dot(symbol, d, buf);
|
self.render_dot(symbol, d, buf);
|
||||||
self.render_digit(state.current_decis(), symbol, false, ds, buf);
|
self.render_digit(state.current_value.decis(), symbol, false, ds, buf);
|
||||||
}
|
}
|
||||||
Format::MSs => {
|
Format::MSs => {
|
||||||
let [m, c_ms, ss, _, s] =
|
let [m, c_ms, ss, _, s] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(
|
self.render_digit(
|
||||||
state.current_minutes_mod() % 10,
|
state.current_value.minutes_mod() % 10,
|
||||||
symbol,
|
symbol,
|
||||||
edit_minutes,
|
edit_minutes,
|
||||||
m,
|
m,
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
self.render_colon(symbol, c_ms, buf);
|
self.render_colon(symbol, c_ms, buf);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Format::Ss if state.with_decis => {
|
Format::Ss if state.with_decis => {
|
||||||
let [ss, _, s, d, ds] =
|
let [ss, _, s, d, ds] =
|
||||||
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
self.render_dot(symbol, d, buf);
|
self.render_dot(symbol, d, buf);
|
||||||
self.render_digit(state.current_decis(), symbol, false, ds, buf);
|
self.render_digit(state.current_value.decis(), symbol, false, ds, buf);
|
||||||
}
|
}
|
||||||
Format::Ss => {
|
Format::Ss => {
|
||||||
let [ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
let [ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf);
|
self.render_digit(
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
state.current_value.seconds_mod() / 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
ss,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Format::S if with_decis => {
|
Format::S if with_decis => {
|
||||||
let [s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
let [s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
self.render_dot(symbol, d, buf);
|
self.render_dot(symbol, d, buf);
|
||||||
self.render_digit(state.current_decis(), symbol, false, ds, buf);
|
self.render_digit(state.current_value.decis(), symbol, false, ds, buf);
|
||||||
}
|
}
|
||||||
Format::S => {
|
Format::S => {
|
||||||
let [s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
let [s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area);
|
||||||
self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf);
|
self.render_digit(
|
||||||
|
state.current_value.seconds_mod() % 10,
|
||||||
|
symbol,
|
||||||
|
edit_secs,
|
||||||
|
s,
|
||||||
|
buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user