diff --git a/src/app.rs b/src/app.rs index 6ab323e..4d4a416 100644 --- a/src/app.rs +++ b/src/app.rs @@ -202,7 +202,7 @@ impl App { let handle_key_event = |app: &mut Self, key: KeyEvent| { debug!("Received key {:?}", key.code); match key.code { - KeyCode::Char('q') | KeyCode::Esc => app.mode = Mode::Quit, + KeyCode::Char('q') => app.mode = Mode::Quit, KeyCode::Char('c') => app.content = Content::Countdown, KeyCode::Char('t') => app.content = Content::Timer, KeyCode::Char('p') => app.content = Content::Pomodoro, diff --git a/src/widgets/clock.rs b/src/widgets/clock.rs index 56a96b4..d1449e6 100644 --- a/src/widgets/clock.rs +++ b/src/widgets/clock.rs @@ -74,6 +74,7 @@ pub struct ClockState { name: Option, initial_value: DurationEx, current_value: DurationEx, + prev_value: DurationEx, tick_value: DurationEx, mode: Mode, format: Format, @@ -151,14 +152,18 @@ impl ClockState { self.update_format(); } + pub fn get_prev_value(&self) -> &DurationEx { + &self.prev_value + } + pub fn toggle_edit(&mut self) { self.mode = match self.mode.clone() { Mode::Editable(_, prev) => { let p = *prev; - // special cases: Should `Mode` be updated? - // 1. `Done` -> `Initial` ? + // Update `Mode` + // 1. `Done` -> `Pause` if p == Mode::Done && self.current_value.gt(&Duration::ZERO.into()) { - Mode::Initial + Mode::Pause } // 2. `_` -> `Done` ? else if p != Mode::Done && self.current_value.eq(&Duration::ZERO.into()) { @@ -170,6 +175,8 @@ impl ClockState { } } mode => { + // store prev. value + self.prev_value = self.current_value; if self.format <= Format::Ss { Mode::Editable(Time::Seconds, Box::new(mode)) } else { @@ -402,6 +409,7 @@ impl ClockState { name: None, initial_value: initial_value.into(), current_value: current_value.into(), + prev_value: current_value.into(), tick_value: tick_value.into(), mode: if current_value == Duration::ZERO { Mode::Done @@ -475,6 +483,7 @@ impl ClockState { name: None, initial_value: initial_value.into(), current_value: current_value.into(), + prev_value: current_value.into(), tick_value: tick_value.into(), mode: if current_value == initial_value { Mode::Initial diff --git a/src/widgets/countdown.rs b/src/widgets/countdown.rs index bc01874..83ac8d9 100644 --- a/src/widgets/countdown.rs +++ b/src/widgets/countdown.rs @@ -187,33 +187,65 @@ impl TuiEventHandler for CountdownState { self.edit_time_done(edit_time); } } - // STRG + e => toggle edit time - KeyCode::Char('e') if key.modifiers.contains(KeyModifiers::CONTROL) => { - // reset both clocks - self.clock.reset(); - self.elapsed_clock.reset(); - - if let Some(edit_time) = &mut self.edit_time.clone() { - self.edit_time_done(edit_time) - } else { - // update `edit_time` - self.edit_time = Some(EditTimeState::new(EditTimeStateArgs { - time: self.time_to_edit(), - min: self.min_time_to_edit(), - max: self.max_time_to_edit(), - })); - } - } - // e => toggle edit clock - KeyCode::Char('e') => { - // toggle edit mode + // skip editing clock + KeyCode::Esc if self.is_clock_edit_mode() => { + // Important: set current value first + self.clock.set_current_value(*self.clock.get_prev_value()); + // before toggling back to non-edit mode self.clock.toggle_edit(); + } + // skip editing by local time + KeyCode::Esc if self.is_time_edit_mode() => { + self.edit_time = None; + } - // stop `elapsed_clock` + // Enter edit by local time mode + KeyCode::Char('e') + if key.modifiers.contains(KeyModifiers::CONTROL) + && !self.is_time_edit_mode() => + { + // set `edit_time` + self.edit_time = Some(EditTimeState::new(EditTimeStateArgs { + time: self.time_to_edit(), + min: self.min_time_to_edit(), + max: self.max_time_to_edit(), + })); + + // pause `elapsed_clock` if self.elapsed_clock.is_running() { self.elapsed_clock.toggle_pause(); } } + + // Enter edit clock + KeyCode::Char('e') if !self.is_clock_edit_mode() => { + // toggle edit mode + self.clock.toggle_edit(); + + // pause `elapsed_clock` + if self.elapsed_clock.is_running() { + self.elapsed_clock.toggle_pause(); + } + } + + // Apply changes of editing by local time + KeyCode::Enter if self.is_time_edit_mode() => { + if let Some(edit_time) = &mut self.edit_time.clone() { + self.edit_time_done(edit_time) + } + // always reset `elapsed_clock` + self.elapsed_clock.reset(); + } + + // Apply changes of editing clock + // Note: Using Ctrl+e is deprecated, use Enter instead + KeyCode::Enter if self.is_clock_edit_mode() => { + // toggle edit mode + self.clock.toggle_edit(); + // always reset `elapsed_clock` + self.elapsed_clock.reset(); + } + KeyCode::Left if self.is_clock_edit_mode() => { self.clock.edit_next(); } @@ -230,8 +262,6 @@ impl TuiEventHandler for CountdownState { } KeyCode::Up if self.is_clock_edit_mode() => { self.clock.edit_up(); - // whenever `clock`'s value is changed, reset `elapsed_clock` - self.elapsed_clock.reset(); } KeyCode::Up if self.is_time_edit_mode() => { // safe unwrap because of previous check in `is_time_edit_mode` @@ -239,8 +269,6 @@ impl TuiEventHandler for CountdownState { } KeyCode::Down if self.is_clock_edit_mode() => { self.clock.edit_down(); - // whenever clock value is changed, reset timer - self.elapsed_clock.reset(); } KeyCode::Down if self.is_time_edit_mode() => { // safe unwrap because of previous check in `is_time_edit_mode` diff --git a/src/widgets/footer.rs b/src/widgets/footer.rs index d9078b0..b67ef12 100644 --- a/src/widgets/footer.rs +++ b/src/widgets/footer.rs @@ -104,7 +104,7 @@ impl StatefulWidget for Footer { let widths = [Constraint::Length(12), Constraint::Percentage(100)]; let table = Table::new( [ - // content + // screens Row::new(vec![ Cell::from(Span::styled( "screens", @@ -112,27 +112,7 @@ impl StatefulWidget for Footer { )), Cell::from(Line::from(content_labels)), ]), - // format - Row::new(vec![ - Cell::from(Span::styled( - "appearance", - Style::default().add_modifier(Modifier::BOLD), - )), - Cell::from(Line::from(vec![ - Span::from("[,]change style"), - Span::from(SPACE), - Span::from("[.]toggle deciseconds"), - Span::from(SPACE), - Span::from(format!( - "[:]toggle {} time", - match self.app_time { - AppTime::Local(_) => "local", - AppTime::Utc(_) => "utc", - } - )), - ])), - ]), - // edit + // controls Row::new(vec![ Cell::from(Span::styled( "controls", @@ -170,12 +150,10 @@ impl StatefulWidget for Footer { } spans } - others => vec![ - Span::from(match others { - AppEditMode::Clock => "[e]dit done", - AppEditMode::Time => "[^e]dit done", - _ => "", - }), + _ => vec![ + Span::from("[enter]apply changes"), + Span::from(SPACE), + Span::from("[esc]skip changes"), Span::from(SPACE), Span::from(format!( "[{} {}]edit selection", @@ -190,6 +168,26 @@ impl StatefulWidget for Footer { } })), ]), + // appearance + Row::new(vec![ + Cell::from(Span::styled( + "appearance", + Style::default().add_modifier(Modifier::BOLD), + )), + Cell::from(Line::from(vec![ + Span::from("[,]change style"), + Span::from(SPACE), + Span::from("[.]toggle deciseconds"), + Span::from(SPACE), + Span::from(format!( + "[:]toggle {} time", + match self.app_time { + AppTime::Local(_) => "local", + AppTime::Utc(_) => "utc", + } + )), + ])), + ]), ], widths, ) diff --git a/src/widgets/pomodoro.rs b/src/widgets/pomodoro.rs index d32c6bf..f1d41e8 100644 --- a/src/widgets/pomodoro.rs +++ b/src/widgets/pomodoro.rs @@ -145,7 +145,18 @@ impl TuiEventHandler for PomodoroState { KeyCode::Char('s') => { self.get_clock_mut().toggle_pause(); } - KeyCode::Char('e') => { + // Skip changes + KeyCode::Esc if edit_mode => { + let clock = self.get_clock_mut(); + clock.toggle_edit(); + clock.set_current_value(*clock.get_prev_value()); + } + // Apply changes + KeyCode::Enter if edit_mode => { + self.get_clock_mut().toggle_edit(); + } + // Enter edit mode + KeyCode::Char('e') if !edit_mode => { self.get_clock_mut().toggle_edit(); } KeyCode::Left if edit_mode => { @@ -175,7 +186,9 @@ impl TuiEventHandler for PomodoroState { if self.get_mode() == &Mode::Work && self.get_clock().is_done() { self.round += 1; } - self.get_clock_mut().reset(); + // reset both clocks + self.clock_map.pause.reset(); + self.clock_map.work.reset(); } _ => return Some(event), }, diff --git a/src/widgets/timer.rs b/src/widgets/timer.rs index f825439..ac46bde 100644 --- a/src/widgets/timer.rs +++ b/src/widgets/timer.rs @@ -46,7 +46,16 @@ impl TuiEventHandler for TimerState { KeyCode::Char('r') => { self.clock.reset(); } - KeyCode::Char('e') => { + KeyCode::Esc if edit_mode => { + // Important: set current value first + self.clock.set_current_value(*self.clock.get_prev_value()); + // before toggling back to non-edit mode + self.clock.toggle_edit(); + } + KeyCode::Enter if edit_mode => { + self.clock.toggle_edit(); + } + KeyCode::Char('e') if !edit_mode => { self.clock.toggle_edit(); } KeyCode::Left if edit_mode => {