Update keybindings (#76)
* (pomodoro) reset both clocks at once * quit app by pressing `q` only * (countdown) enter/esc keybindings * (timer) enter/esc keybindings * (pomodoro) enter/esc keybindings * update footer label * fix(coundown): don't reset elapsed clock while skipping editing changes * fix(clock): order of actions matters for ESC handling. Set `pause` instead of `initial` mode while toggeling back. * fix(timer): order of actions matters (ESC key) * (footer) update order, lowercase standard keys
This commit is contained in:
parent
90d9988e7a
commit
e6291a3131
@ -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,
|
||||
|
||||
@ -74,6 +74,7 @@ pub struct ClockState<T> {
|
||||
name: Option<String>,
|
||||
initial_value: DurationEx,
|
||||
current_value: DurationEx,
|
||||
prev_value: DurationEx,
|
||||
tick_value: DurationEx,
|
||||
mode: Mode,
|
||||
format: Format,
|
||||
@ -151,14 +152,18 @@ impl<T> ClockState<T> {
|
||||
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<T> ClockState<T> {
|
||||
}
|
||||
}
|
||||
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<Countdown> {
|
||||
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<Timer> {
|
||||
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
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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,
|
||||
)
|
||||
|
||||
@ -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),
|
||||
},
|
||||
|
||||
@ -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 => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user