feat(edit): 10x up/down (#110)
* feat(edit): 10x up/down * fix `MAX_DURATION` (decisecond) * footer: add `edit 10x` keybindings * README: update keybindings
This commit is contained in:
parent
6dc7eb81c2
commit
cb6c2d5142
10
README.md
10
README.md
@ -142,22 +142,24 @@ Extra option (if `--features sound` is enabled by local build only):
|
|||||||
| <kbd>Esc</kbd> | skip changes |
|
| <kbd>Esc</kbd> | skip changes |
|
||||||
| <kbd>←</kbd> or <kbd>→</kbd> | change selection |
|
| <kbd>←</kbd> or <kbd>→</kbd> | change selection |
|
||||||
| <kbd>↑</kbd> | edit to go up |
|
| <kbd>↑</kbd> | edit to go up |
|
||||||
|
| <kbd>ctrl+↑</kbd> | edit to go up 10x |
|
||||||
| <kbd>↓</kbd> | edit to go down |
|
| <kbd>↓</kbd> | edit to go down |
|
||||||
|
| <kbd>ctrl+↓</kbd> | edit to go down 10x |
|
||||||
|
|
||||||
**In `Pomodoro` screen only:**
|
**In `Pomodoro` screen only:**
|
||||||
|
|
||||||
| Key | Description |
|
| Key | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| <kbd>←</kbd> or <kbd>→</kbd> | switch work/pause |
|
| <kbd>←</kbd> or <kbd>→</kbd> | switch work/pause |
|
||||||
| <kbd>^r</kbd> | reset round |
|
| <kbd>ctrl+r</kbd> | reset round |
|
||||||
| <kbd>^s</kbd> | save initial value |
|
| <kbd>ctrl+s</kbd> | save initial value |
|
||||||
|
|
||||||
**In `Countdown` screen only:**
|
**In `Countdown` screen only:**
|
||||||
|
|
||||||
| Key | Description |
|
| Key | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| <kbd>^e</kbd> | edit by local time |
|
| <kbd>ctrl+e</kbd> | edit by local time |
|
||||||
| <kbd>^s</kbd> | save initial value |
|
| <kbd>ctrl+s</kbd> | save initial value |
|
||||||
|
|
||||||
## Appearance
|
## Appearance
|
||||||
|
|
||||||
|
|||||||
@ -29,8 +29,10 @@ const HOURS_PER_DAY: u64 = 24;
|
|||||||
// ^ https://www.math.net/days-in-a-year
|
// ^ https://www.math.net/days-in-a-year
|
||||||
const DAYS_PER_YEAR: u64 = 365; // ignore leap year of 366 days
|
const DAYS_PER_YEAR: u64 = 365; // ignore leap year of 366 days
|
||||||
|
|
||||||
// max. 999y 364d 23:59:59 (1000 years - 1 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_SECOND);
|
pub const MAX_DURATION: Duration = ONE_YEAR
|
||||||
|
.saturating_mul(1000)
|
||||||
|
.saturating_sub(ONE_DECI_SECOND);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialOrd)]
|
||||||
pub struct DurationEx {
|
pub struct DurationEx {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::fmt;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::{fmt, ops::Mul};
|
||||||
use strum::Display;
|
use strum::Display;
|
||||||
|
|
||||||
use ratatui::{
|
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 RANGE_OF_DONE_COUNT: u64 = 4;
|
||||||
const MAX_DONE_COUNT: u64 = RANGE_OF_DONE_COUNT * 5;
|
const MAX_DONE_COUNT: u64 = RANGE_OF_DONE_COUNT * 5;
|
||||||
|
|
||||||
@ -276,89 +288,23 @@ impl<T> ClockState<T> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_current_up(&mut self) {
|
fn edit_current_up(&mut self, times: u32) {
|
||||||
self.current_value = match self.mode {
|
let count_value = count_by_mode(times, self.get_mode());
|
||||||
Mode::Editable(Time::Decis, _) => {
|
|
||||||
if self
|
if self
|
||||||
.current_value
|
.get_current_value()
|
||||||
.le(&MAX_DURATION.saturating_sub(ONE_DECI_SECOND).into())
|
.le(&MAX_DURATION.saturating_sub(count_value).into())
|
||||||
{
|
{
|
||||||
self.current_value.saturating_add(ONE_DECI_SECOND.into())
|
self.current_value = self.get_current_value().saturating_add(count_value.into());
|
||||||
} else {
|
self.update_format();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_current_down(&mut self) {
|
fn edit_current_down(&mut self, times: u32) {
|
||||||
self.current_value = match self.mode {
|
let count_value = count_by_mode(times, self.get_mode()).into();
|
||||||
Mode::Editable(Time::Decis, _) => {
|
|
||||||
self.current_value.saturating_sub(ONE_DECI_SECOND.into())
|
self.current_value = self.get_current_value().saturating_sub(count_value);
|
||||||
}
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
self.update_format();
|
self.update_format();
|
||||||
let updated_format = *self.get_format();
|
let updated_format = *self.get_format();
|
||||||
self.downgrade_mode_by_format(&updated_format);
|
self.downgrade_mode_by_format(&updated_format);
|
||||||
@ -579,11 +525,19 @@ impl ClockState<Countdown> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_up(&mut self) {
|
pub fn edit_up(&mut self) {
|
||||||
self.edit_current_up();
|
self.edit_current_up(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_down(&mut self) {
|
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<Timer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_up(&mut self) {
|
pub fn edit_up(&mut self) {
|
||||||
self.edit_current_up();
|
self.edit_current_up(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_down(&mut self) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -194,9 +194,15 @@ impl TuiEventHandler for CountdownState {
|
|||||||
KeyCode::Left => {
|
KeyCode::Left => {
|
||||||
self.clock.edit_next();
|
self.clock.edit_next();
|
||||||
}
|
}
|
||||||
|
KeyCode::Up if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||||
|
self.clock.edit_jump_up();
|
||||||
|
}
|
||||||
KeyCode::Up => {
|
KeyCode::Up => {
|
||||||
self.clock.edit_up();
|
self.clock.edit_up();
|
||||||
}
|
}
|
||||||
|
KeyCode::Down if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||||
|
self.clock.edit_jump_down();
|
||||||
|
}
|
||||||
KeyCode::Down => {
|
KeyCode::Down => {
|
||||||
self.clock.edit_down();
|
self.clock.edit_down();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -220,11 +220,23 @@ impl StatefulWidget for Footer {
|
|||||||
scrollbar::VERTICAL.begin
|
scrollbar::VERTICAL.begin
|
||||||
)),
|
)),
|
||||||
Span::from(SPACE),
|
Span::from(SPACE),
|
||||||
|
Span::from(format!(
|
||||||
|
// ctrl + ↑
|
||||||
|
"[^{}]edit up 10x",
|
||||||
|
scrollbar::VERTICAL.begin
|
||||||
|
)),
|
||||||
|
Span::from(SPACE),
|
||||||
Span::from(format!(
|
Span::from(format!(
|
||||||
// ↓
|
// ↓
|
||||||
"[{}]edit up",
|
"[{}]edit up",
|
||||||
scrollbar::VERTICAL.end
|
scrollbar::VERTICAL.end
|
||||||
)),
|
)),
|
||||||
|
Span::from(SPACE),
|
||||||
|
Span::from(format!(
|
||||||
|
// ctrl + ↓
|
||||||
|
"[^{}]edit up 10x",
|
||||||
|
scrollbar::VERTICAL.end
|
||||||
|
)),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::{
|
|||||||
utils::center,
|
utils::center,
|
||||||
widgets::clock::{self, ClockState, ClockWidget},
|
widgets::clock::{self, ClockState, ClockWidget},
|
||||||
};
|
};
|
||||||
|
use crossterm::event::KeyModifiers;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
buffer::Buffer,
|
buffer::Buffer,
|
||||||
crossterm::event::KeyCode,
|
crossterm::event::KeyCode,
|
||||||
@ -60,11 +61,17 @@ impl TuiEventHandler for TimerState {
|
|||||||
KeyCode::Right => {
|
KeyCode::Right => {
|
||||||
self.clock.edit_prev();
|
self.clock.edit_prev();
|
||||||
}
|
}
|
||||||
|
KeyCode::Up if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||||
|
self.clock.edit_jump_up();
|
||||||
|
}
|
||||||
// change value up
|
// change value up
|
||||||
KeyCode::Up => {
|
KeyCode::Up => {
|
||||||
self.clock.edit_up();
|
self.clock.edit_up();
|
||||||
}
|
}
|
||||||
// change value down
|
// change value down
|
||||||
|
KeyCode::Down if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||||
|
self.clock.edit_jump_down();
|
||||||
|
}
|
||||||
KeyCode::Down => {
|
KeyCode::Down => {
|
||||||
self.clock.edit_down();
|
self.clock.edit_down();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user