diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5aa3609..3470b00 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,8 +2,14 @@
## [unreleased]
+### Features
+
+- (event) New `event` screen to count custom date times in the future or past. [#117](https://github.com/sectore/timr-tui/pull/117), [#120](https://github.com/sectore/timr-tui/pull/120), [#122](https://github.com/sectore/timr-tui/pull/122), [#123](https://github.com/sectore/timr-tui/pull/123), [#124](https://github.com/sectore/timr-tui/pull/124), [#125](https://github.com/sectore/timr-tui/pull/125)
+- (screens) switch by `←` or `→` keys [#127](https://github.com/sectore/timr-tui/pull/127)
+
### Breaking change
+- (pomodoro)! new keybindings `ctrl+←` or `ctrl+→` to switch `work`/`pause` [#127](https://github.com/sectore/timr-tui/pull/127)
- (keybindings)! change keys for `screens` [#126](https://github.com/sectore/timr-tui/pull/126)
- (cli)! Remove `--countdown-target` argument [#121](https://github.com/sectore/timr-tui/pull/121)
diff --git a/README.md b/README.md
index 25f1606..1b21be3 100644
--- a/README.md
+++ b/README.md
@@ -126,6 +126,8 @@ Extra option (if `--features sound` is enabled by local build only):
| 3 | Timer |
| 4 | Event |
| 0 | Local Time |
+| → | next screen |
+| ← | previous screen |
## Controls
@@ -152,7 +154,7 @@ Extra option (if `--features sound` is enabled by local build only):
| Key | Description |
| --- | --- |
-| ← or → | switch work/pause |
+| ctrl+← or ctrl+→ | switch work/pause |
| ctrl+r | reset round |
| ctrl+s | save initial value |
diff --git a/src/app.rs b/src/app.rs
index aec9400..30f0174 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -242,11 +242,19 @@ impl App {
debug!("Received key {:?}", key.code);
match key.code {
KeyCode::Char('q') => app.mode = Mode::Quit,
- KeyCode::Char('1') | KeyCode::Char('c') /* TODO: deprecated, remove it in next verson */ => app.content = Content::Countdown,
- KeyCode::Char('2') | KeyCode::Char('t') /* TODO: deprecated, remove it in next verson */ => app.content = Content::Timer,
- KeyCode::Char('3') | KeyCode::Char('p') /* TODO: deprecated, remove it in next verson */ => app.content = Content::Pomodoro,
+ KeyCode::Char('1') | KeyCode::Char('c') /* TODO: deprecated, remove it in next version */ => app.content = Content::Countdown,
+ KeyCode::Char('2') | KeyCode::Char('t') /* TODO: deprecated, remove it in next version */ => app.content = Content::Timer,
+ KeyCode::Char('3') | KeyCode::Char('p') /* TODO: deprecated, remove it in next version */ => app.content = Content::Pomodoro,
KeyCode::Char('4') => app.content = Content::Event,
- KeyCode::Char('0') | KeyCode::Char('l') /* TODO: deprecated, remove it in next verson */ => app.content = Content::LocalTime,
+ // toogle app time format
+ KeyCode::Char('0') | KeyCode::Char('l') /* TODO: deprecated, remove it in next version */ => app.content = Content::LocalTime,
+ // switch `screens`
+ KeyCode::Right => {
+ app.content = app.content.next();
+ }
+ KeyCode::Left => {
+ app.content = app.content.prev();
+ }
// toogle app time format
KeyCode::Char(':') => {
if app.content == Content::LocalTime {
diff --git a/src/common.rs b/src/common.rs
index 2090f3e..c1b3ee7 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -21,6 +21,28 @@ pub enum Content {
LocalTime,
}
+impl Content {
+ pub fn next(&self) -> Self {
+ match self {
+ Content::Countdown => Content::Timer,
+ Content::Timer => Content::Pomodoro,
+ Content::Pomodoro => Content::Event,
+ Content::Event => Content::LocalTime,
+ Content::LocalTime => Content::Countdown,
+ }
+ }
+
+ pub fn prev(&self) -> Self {
+ match self {
+ Content::Countdown => Content::LocalTime,
+ Content::Timer => Content::Countdown,
+ Content::Pomodoro => Content::Timer,
+ Content::Event => Content::Pomodoro,
+ Content::LocalTime => Content::Event,
+ }
+ }
+}
+
#[derive(Clone, Debug)]
pub enum ClockTypeId {
Countdown,
@@ -254,4 +276,48 @@ mod tests {
"local"
);
}
+
+ #[test]
+ fn test_content_next() {
+ let start = Content::Countdown;
+ let mut current = start;
+
+ // Cycle through: Countdown -> Timer -> Pomodoro -> Event -> LocalTime -> Countdown
+ current = current.next();
+ assert_eq!(current, Content::Timer);
+
+ current = current.next();
+ assert_eq!(current, Content::Pomodoro);
+
+ current = current.next();
+ assert_eq!(current, Content::Event);
+
+ current = current.next();
+ assert_eq!(current, Content::LocalTime);
+
+ current = current.next();
+ assert_eq!(current, start, "Should cycle back to start");
+ }
+
+ #[test]
+ fn test_content_prev() {
+ let start = Content::Countdown;
+ let mut current = start;
+
+ // Cycle backwards: Countdown -> LocalTime -> Event -> Pomodoro -> Timer -> Countdown
+ current = current.prev();
+ assert_eq!(current, Content::LocalTime);
+
+ current = current.prev();
+ assert_eq!(current, Content::Event);
+
+ current = current.prev();
+ assert_eq!(current, Content::Pomodoro);
+
+ current = current.prev();
+ assert_eq!(current, Content::Timer);
+
+ current = current.prev();
+ assert_eq!(current, start, "Should cycle back to start");
+ }
}
diff --git a/src/widgets/footer.rs b/src/widgets/footer.rs
index af7adbb..b2b0d8a 100644
--- a/src/widgets/footer.rs
+++ b/src/widgets/footer.rs
@@ -85,7 +85,7 @@ impl StatefulWidget for Footer {
.render(border_area, buf);
// show menu
if state.show_menu {
- let content_labels: Vec = content_labels
+ let mut content_labels: Vec = content_labels
.iter()
.enumerate()
.map(|(index, (content, label))| {
@@ -103,6 +103,13 @@ impl StatefulWidget for Footer {
})
.collect();
+ content_labels.extend_from_slice(&[
+ Span::from(SPACE),
+ Span::from("[→]next"),
+ Span::from(SPACE),
+ Span::from("[←]prev."),
+ ]);
+
const SPACE: &str = " "; // 2 empty spaces
let widths = [Constraint::Length(12), Constraint::Percentage(100)];
let mut table_rows = vec![
@@ -136,7 +143,10 @@ impl StatefulWidget for Footer {
]),
];
- if self.selected_content != Content::LocalTime {
+ // Controls (except for `localtime` and `event`)
+ if self.selected_content != Content::LocalTime
+ && self.selected_content != Content::Event
+ {
table_rows.extend_from_slice(&[
// controls - 1. row
Row::new(vec![
@@ -202,7 +212,7 @@ impl StatefulWidget for Footer {
let mut spans = vec![];
if self.selected_content == Content::Pomodoro {
spans.extend_from_slice(&[Span::from(
- "[← →]switch work/pause",
+ "[^←] or [^→] switch work/pause",
)]);
}
spans
diff --git a/src/widgets/pomodoro.rs b/src/widgets/pomodoro.rs
index b7c1843..cb63714 100644
--- a/src/widgets/pomodoro.rs
+++ b/src/widgets/pomodoro.rs
@@ -198,12 +198,12 @@ impl TuiEventHandler for PomodoroState {
self.get_clock_mut().toggle_edit();
}
// toggle WORK/PAUSE
- KeyCode::Left => {
+ KeyCode::Left if key.modifiers.contains(KeyModifiers::CONTROL) => {
// `next` is acting as same as a "prev" function we don't have
self.next();
}
// toggle WORK/PAUSE
- KeyCode::Right => {
+ KeyCode::Right if key.modifiers.contains(KeyModifiers::CONTROL) => {
self.next();
}
// reset rounds AND clocks