diff --git a/README.md b/README.md index 3827ccb..1ed93c1 100644 --- a/README.md +++ b/README.md @@ -142,22 +142,24 @@ Extra option (if `--features sound` is enabled by local build only): | Esc | skip changes | | or | change selection | | | edit to go up | +| ctrl+↑ | edit to go up 10x | | | edit to go down | +| ctrl+↓ | edit to go down 10x | **In `Pomodoro` screen only:** | Key | Description | | --- | --- | | or | switch work/pause | -| ^r | reset round | -| ^s | save initial value | +| ctrl+r | reset round | +| ctrl+s | save initial value | **In `Countdown` screen only:** | Key | Description | | --- | --- | -| ^e | edit by local time | -| ^s | save initial value | +| ctrl+e | edit by local time | +| ctrl+s | save initial value | ## Appearance diff --git a/src/duration.rs b/src/duration.rs index 4e8126d..bf3f3c5 100644 --- a/src/duration.rs +++ b/src/duration.rs @@ -29,8 +29,10 @@ const HOURS_PER_DAY: u64 = 24; // ^ https://www.math.net/days-in-a-year const DAYS_PER_YEAR: u64 = 365; // ignore leap year of 366 days -// max. 999y 364d 23:59:59 (1000 years - 1 second) -pub const MAX_DURATION: Duration = ONE_YEAR.saturating_mul(1000).saturating_sub(ONE_SECOND); +// max. 999y 364d 23:59:59.9 (1000 years - 1 decisecond) +pub const MAX_DURATION: Duration = ONE_YEAR + .saturating_mul(1000) + .saturating_sub(ONE_DECI_SECOND); #[derive(Debug, Clone, Copy, PartialOrd)] pub struct DurationEx { diff --git a/src/widgets/clock.rs b/src/widgets/clock.rs index 620f595..0205a30 100644 --- a/src/widgets/clock.rs +++ b/src/widgets/clock.rs @@ -1,6 +1,6 @@ -use std::fmt; use std::marker::PhantomData; use std::time::Duration; +use std::{fmt, ops::Mul}; use strum::Display; use ratatui::{ @@ -148,6 +148,18 @@ pub fn time_by_format(format: &Format) -> Time { } } +pub fn count_by_mode(times: u32, mode: &Mode) -> Duration { + match mode { + Mode::Editable(Time::Decis, _) => ONE_DECI_SECOND.mul(times), + Mode::Editable(Time::Seconds, _) => ONE_SECOND.mul(times), + Mode::Editable(Time::Minutes, _) => ONE_MINUTE.mul(times), + Mode::Editable(Time::Hours, _) => ONE_HOUR.mul(times), + Mode::Editable(Time::Days, _) => ONE_DAY.mul(times), + Mode::Editable(Time::Years, _) => ONE_YEAR.mul(times), + _ => Duration::ZERO, + } +} + const RANGE_OF_DONE_COUNT: u64 = 4; const MAX_DONE_COUNT: u64 = RANGE_OF_DONE_COUNT * 5; @@ -276,89 +288,23 @@ impl ClockState { }; } - pub fn edit_current_up(&mut self) { - self.current_value = match self.mode { - Mode::Editable(Time::Decis, _) => { - if self - .current_value - .le(&MAX_DURATION.saturating_sub(ONE_DECI_SECOND).into()) - { - self.current_value.saturating_add(ONE_DECI_SECOND.into()) - } else { - self.current_value - } - } - Mode::Editable(Time::Seconds, _) => { - if self - .current_value - .le(&MAX_DURATION.saturating_sub(ONE_SECOND).into()) - { - self.current_value.saturating_add(ONE_SECOND.into()) - } else { - self.current_value - } - } - Mode::Editable(Time::Minutes, _) => { - if self - .current_value - .le(&MAX_DURATION.saturating_sub(ONE_MINUTE).into()) - { - self.current_value.saturating_add(ONE_MINUTE.into()) - } else { - self.current_value - } - } - Mode::Editable(Time::Hours, _) => { - if self - .current_value - .le(&MAX_DURATION.saturating_sub(ONE_HOUR).into()) - { - self.current_value.saturating_add(ONE_HOUR.into()) - } else { - self.current_value - } - } - Mode::Editable(Time::Days, _) => { - if self - .current_value - .le(&MAX_DURATION.saturating_sub(ONE_DAY).into()) - { - self.current_value.saturating_add(ONE_DAY.into()) - } else { - self.current_value - } - } - Mode::Editable(Time::Years, _) => { - if self - .current_value - .le(&MAX_DURATION.saturating_sub(ONE_YEAR).into()) - { - self.current_value.saturating_add(ONE_YEAR.into()) - } else { - self.current_value - } - } - _ => self.current_value, - }; - self.update_format(); + fn edit_current_up(&mut self, times: u32) { + let count_value = count_by_mode(times, self.get_mode()); + + if self + .get_current_value() + .le(&MAX_DURATION.saturating_sub(count_value).into()) + { + self.current_value = self.get_current_value().saturating_add(count_value.into()); + self.update_format(); + } } - pub fn edit_current_down(&mut self) { - self.current_value = match self.mode { - Mode::Editable(Time::Decis, _) => { - self.current_value.saturating_sub(ONE_DECI_SECOND.into()) - } - Mode::Editable(Time::Seconds, _) => { - self.current_value.saturating_sub(ONE_SECOND.into()) - } - Mode::Editable(Time::Minutes, _) => { - self.current_value.saturating_sub(ONE_MINUTE.into()) - } - Mode::Editable(Time::Hours, _) => self.current_value.saturating_sub(ONE_HOUR.into()), - Mode::Editable(Time::Days, _) => self.current_value.saturating_sub(ONE_DAY.into()), - Mode::Editable(Time::Years, _) => self.current_value.saturating_sub(ONE_YEAR.into()), - _ => self.current_value, - }; + fn edit_current_down(&mut self, times: u32) { + let count_value = count_by_mode(times, self.get_mode()).into(); + + self.current_value = self.get_current_value().saturating_sub(count_value); + self.update_format(); let updated_format = *self.get_format(); self.downgrade_mode_by_format(&updated_format); @@ -579,11 +525,19 @@ impl ClockState { } pub fn edit_up(&mut self) { - self.edit_current_up(); + self.edit_current_up(1); } pub fn edit_down(&mut self) { - self.edit_current_down(); + self.edit_current_down(1); + } + + pub fn edit_jump_up(&mut self) { + self.edit_current_up(10); + } + + pub fn edit_jump_down(&mut self) { + self.edit_current_down(10); } } @@ -647,11 +601,19 @@ impl ClockState { } pub fn edit_up(&mut self) { - self.edit_current_up(); + self.edit_current_up(1); } pub fn edit_down(&mut self) { - self.edit_current_down(); + self.edit_current_down(1); + } + + pub fn edit_jump_up(&mut self) { + self.edit_current_up(10); + } + + pub fn edit_jump_down(&mut self) { + self.edit_current_down(10); } } diff --git a/src/widgets/countdown.rs b/src/widgets/countdown.rs index e98579b..4d93de6 100644 --- a/src/widgets/countdown.rs +++ b/src/widgets/countdown.rs @@ -194,9 +194,15 @@ impl TuiEventHandler for CountdownState { KeyCode::Left => { self.clock.edit_next(); } + KeyCode::Up if key.modifiers.contains(KeyModifiers::CONTROL) => { + self.clock.edit_jump_up(); + } KeyCode::Up => { self.clock.edit_up(); } + KeyCode::Down if key.modifiers.contains(KeyModifiers::CONTROL) => { + self.clock.edit_jump_down(); + } KeyCode::Down => { self.clock.edit_down(); } diff --git a/src/widgets/footer.rs b/src/widgets/footer.rs index b825803..c7c9be8 100644 --- a/src/widgets/footer.rs +++ b/src/widgets/footer.rs @@ -220,11 +220,23 @@ impl StatefulWidget for Footer { scrollbar::VERTICAL.begin )), Span::from(SPACE), + Span::from(format!( + // ctrl + ↑ + "[^{}]edit up 10x", + scrollbar::VERTICAL.begin + )), + Span::from(SPACE), Span::from(format!( // ↓ "[{}]edit up", scrollbar::VERTICAL.end )), + Span::from(SPACE), + Span::from(format!( + // ctrl + ↓ + "[^{}]edit up 10x", + scrollbar::VERTICAL.end + )), ], } })), diff --git a/src/widgets/timer.rs b/src/widgets/timer.rs index af2bae2..abb48d4 100644 --- a/src/widgets/timer.rs +++ b/src/widgets/timer.rs @@ -4,6 +4,7 @@ use crate::{ utils::center, widgets::clock::{self, ClockState, ClockWidget}, }; +use crossterm::event::KeyModifiers; use ratatui::{ buffer::Buffer, crossterm::event::KeyCode, @@ -60,11 +61,17 @@ impl TuiEventHandler for TimerState { KeyCode::Right => { self.clock.edit_prev(); } + KeyCode::Up if key.modifiers.contains(KeyModifiers::CONTROL) => { + self.clock.edit_jump_up(); + } // change value up KeyCode::Up => { self.clock.edit_up(); } // change value down + KeyCode::Down if key.modifiers.contains(KeyModifiers::CONTROL) => { + self.clock.edit_jump_down(); + } KeyCode::Down => { self.clock.edit_down(); }