Implemented clock shifting.
This commit is contained in:
parent
84a2a11d79
commit
2a336236e1
5 changed files with 137 additions and 57 deletions
25
src/alarm.rs
25
src/alarm.rs
|
@ -31,6 +31,18 @@ impl Countdown {
|
||||||
self.position = None;
|
self.position = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, value: u32) {
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_position(&mut self, position: Position) {
|
||||||
|
self.position = Some(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_position(&self) -> bool {
|
||||||
|
self.position.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
// Draw countdown.
|
// Draw countdown.
|
||||||
pub fn draw<W: Write>(&self, stdout: &mut RawTerminal<W>)
|
pub fn draw<W: Write>(&self, stdout: &mut RawTerminal<W>)
|
||||||
-> Result<(), std::io::Error>
|
-> Result<(), std::io::Error>
|
||||||
|
@ -170,6 +182,7 @@ impl AlarmRoster {
|
||||||
clock: &mut Clock,
|
clock: &mut Clock,
|
||||||
layout: &Layout,
|
layout: &Layout,
|
||||||
countdown: &mut Countdown,
|
countdown: &mut Countdown,
|
||||||
|
force_redraw: bool,
|
||||||
) -> Option<(u32, &String)>
|
) -> Option<(u32, &String)>
|
||||||
{
|
{
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
|
@ -189,8 +202,8 @@ impl AlarmRoster {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Reached the alarm to exceed next. Update countdown accordingly.
|
// Reached the alarm to exceed next. Update countdown accordingly.
|
||||||
countdown.value = alarm.time - clock.elapsed;
|
countdown.set(alarm.time - clock.elapsed);
|
||||||
if countdown.position.is_none() || layout.force_redraw {
|
if !countdown.has_position() || force_redraw {
|
||||||
// Compute position.
|
// Compute position.
|
||||||
let mut col =
|
let mut col =
|
||||||
layout.roster.col
|
layout.roster.col
|
||||||
|
@ -210,7 +223,7 @@ impl AlarmRoster {
|
||||||
.unwrap_or(layout.roster.line);
|
.unwrap_or(layout.roster.line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
countdown.position = Some(Position { col, line, });
|
countdown.set_position(Position { col, line });
|
||||||
}
|
}
|
||||||
// Ignore other alarms.
|
// Ignore other alarms.
|
||||||
break;
|
break;
|
||||||
|
@ -317,6 +330,12 @@ impl AlarmRoster {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn time_travel(&mut self, time: u32) {
|
||||||
|
for alarm in self.list.iter_mut() {
|
||||||
|
alarm.exceeded = alarm.time <= time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read alarm times from stdin.
|
// Read alarm times from stdin.
|
||||||
pub fn from_stdin(&mut self, stdin: std::io::Stdin)
|
pub fn from_stdin(&mut self, stdin: std::io::Stdin)
|
||||||
-> Result<(), String>
|
-> Result<(), String>
|
||||||
|
|
46
src/clock.rs
46
src/clock.rs
|
@ -8,12 +8,18 @@ use crate::consts::COLOR;
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
use crate::layout::{Layout, Position};
|
use crate::layout::{Layout, Position};
|
||||||
|
|
||||||
|
enum Pause {
|
||||||
|
Instant(time::Instant),
|
||||||
|
Secs(u32),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Clock {
|
pub struct Clock {
|
||||||
pub start: time::Instant,
|
pub start: time::Instant,
|
||||||
pub elapsed: u32,
|
pub elapsed: u32,
|
||||||
pub days: u32,
|
pub days: u32,
|
||||||
pub paused: bool,
|
pub paused: bool,
|
||||||
paused_at: Option<time::Instant>,
|
paused_at: Pause,
|
||||||
pub color_index: Option<usize>,
|
pub color_index: Option<usize>,
|
||||||
pub font: &'static font::Font,
|
pub font: &'static font::Font,
|
||||||
}
|
}
|
||||||
|
@ -25,7 +31,7 @@ impl Clock {
|
||||||
elapsed: 0,
|
elapsed: 0,
|
||||||
days: 0,
|
days: 0,
|
||||||
paused: false,
|
paused: false,
|
||||||
paused_at: None,
|
paused_at: Pause::None,
|
||||||
color_index: None,
|
color_index: None,
|
||||||
font: config.font,
|
font: config.font,
|
||||||
}
|
}
|
||||||
|
@ -44,19 +50,24 @@ impl Clock {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&mut self) {
|
fn pause(&mut self) {
|
||||||
self.paused_at = Some(time::Instant::now());
|
self.paused_at = Pause::Instant(time::Instant::now());
|
||||||
self.paused = true;
|
self.paused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unpause(&mut self) {
|
fn unpause(&mut self) {
|
||||||
// Try to derive a new start instant.
|
match self.paused_at {
|
||||||
if let Some(delay) = self.paused_at {
|
Pause::Instant(delay) => {
|
||||||
if let Some(new_start) = self.start.checked_add(delay.elapsed()) {
|
if let Some(start) = self.start.checked_add(delay.elapsed()) {
|
||||||
self.start = new_start;
|
self.start = start;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
Pause::Secs(secs) => {
|
||||||
|
self.start = time::Instant::now() - time::Duration::from_secs(secs as u64);
|
||||||
|
},
|
||||||
|
Pause::None => (), // O_o
|
||||||
}
|
}
|
||||||
|
|
||||||
self.paused_at = None;
|
self.paused_at = Pause::None;
|
||||||
self.paused = false;
|
self.paused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +79,16 @@ impl Clock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shift(&mut self, shift: i32) {
|
||||||
|
let secs = if shift.is_negative() {
|
||||||
|
self.elapsed.saturating_sub(shift.abs() as u32)
|
||||||
|
} else {
|
||||||
|
self.elapsed.saturating_add(shift as u32)
|
||||||
|
};
|
||||||
|
self.paused_at = Pause::Secs(secs);
|
||||||
|
self.elapsed = secs;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_width(&self) -> u16 {
|
pub fn get_width(&self) -> u16 {
|
||||||
if self.elapsed >= 3600 {
|
if self.elapsed >= 3600 {
|
||||||
// Hours
|
// Hours
|
||||||
|
@ -95,6 +116,7 @@ impl Clock {
|
||||||
&self,
|
&self,
|
||||||
mut stdout: &mut RawTerminal<W>,
|
mut stdout: &mut RawTerminal<W>,
|
||||||
layout: &Layout,
|
layout: &Layout,
|
||||||
|
force_redraw: bool,
|
||||||
) -> Result<(), std::io::Error>
|
) -> Result<(), std::io::Error>
|
||||||
{
|
{
|
||||||
// Setup style and color if appropriate.
|
// Setup style and color if appropriate.
|
||||||
|
@ -106,7 +128,7 @@ impl Clock {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run once every hour or on request.
|
// Run once every hour or on request.
|
||||||
if layout.force_redraw || self.elapsed % 3600 == 0 {
|
if force_redraw || self.elapsed % 3600 == 0 {
|
||||||
// Draw hours if necessary.
|
// Draw hours if necessary.
|
||||||
if self.elapsed >= 3600 {
|
if self.elapsed >= 3600 {
|
||||||
self.draw_digit_pair(
|
self.draw_digit_pair(
|
||||||
|
@ -142,7 +164,7 @@ impl Clock {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw minutes if necessary. Once every minute or on request.
|
// Draw minutes if necessary. Once every minute or on request.
|
||||||
if layout.force_redraw || self.elapsed % 60 == 0 {
|
if force_redraw || self.elapsed % 60 == 0 {
|
||||||
self.draw_digit_pair(
|
self.draw_digit_pair(
|
||||||
&mut stdout,
|
&mut stdout,
|
||||||
(self.elapsed % 3600) / 60,
|
(self.elapsed % 3600) / 60,
|
||||||
|
@ -151,7 +173,7 @@ impl Clock {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw colon if necessary.
|
// Draw colon if necessary.
|
||||||
if layout.force_redraw {
|
if force_redraw {
|
||||||
self.draw_colon(
|
self.draw_colon(
|
||||||
&mut stdout,
|
&mut stdout,
|
||||||
&layout.clock_colon0,
|
&layout.clock_colon0,
|
||||||
|
|
|
@ -39,5 +39,7 @@ SIGNALS: <SIGUSR1> Reset clock.
|
||||||
"[0-9] Add [d] Delete [SPACE] Pause [r] Reset [c] Clear [q] Quit";
|
"[0-9] Add [d] Delete [SPACE] Pause [r] Reset [c] Clear [q] Quit";
|
||||||
pub const MENUBAR_INS: &str =
|
pub const MENUBAR_INS: &str =
|
||||||
"Format: HH:MM:SS/LABEL [ENTER] Accept [ESC] Cancel [CTR-C] Quit";
|
"Format: HH:MM:SS/LABEL [ENTER] Accept [ESC] Cancel [CTR-C] Quit";
|
||||||
|
pub const MENUBAR_PAUSED: &str =
|
||||||
|
"[SPACE] Continue [r] Reset [UP]/[DOWN] Set clock";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub struct Position {
|
||||||
|
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
pub force_redraw: bool, // Redraw elements on screen.
|
pub force_redraw: bool, // Redraw elements on screen.
|
||||||
pub force_recalc: bool, // Recalculate position of elements.
|
force_recalc: bool, // Recalculate position of elements.
|
||||||
pub width: u16,
|
pub width: u16,
|
||||||
pub height: u16,
|
pub height: u16,
|
||||||
clock_width: u16,
|
clock_width: u16,
|
||||||
|
@ -48,8 +48,9 @@ impl Layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update layout. Returns true when changes were made.
|
||||||
pub fn update(&mut self, clock: &Clock, force: bool)
|
pub fn update(&mut self, clock: &Clock, force: bool)
|
||||||
-> Result<(), std::io::Error>
|
-> Result<bool, std::io::Error>
|
||||||
{
|
{
|
||||||
if self.force_recalc || force {
|
if self.force_recalc || force {
|
||||||
self.force_recalc = false;
|
self.force_recalc = false;
|
||||||
|
@ -60,9 +61,14 @@ impl Layout {
|
||||||
self.clock_height = clock.font.height;
|
self.clock_height = clock.font.height;
|
||||||
self.digit_width = clock.font.width;
|
self.digit_width = clock.font.width;
|
||||||
self.compute(clock.elapsed >= 3600);
|
self.compute(clock.elapsed >= 3600);
|
||||||
self.force_redraw = true;
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
}
|
}
|
||||||
Ok(())
|
}
|
||||||
|
|
||||||
|
pub fn schedule_recalc(&mut self) {
|
||||||
|
self.force_recalc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
107
src/lib.rs
107
src/lib.rs
|
@ -43,6 +43,7 @@ pub fn run(
|
||||||
let mut input_keys = async_stdin.keys();
|
let mut input_keys = async_stdin.keys();
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
let mut stdout = stdout.lock().into_raw_mode()?;
|
let mut stdout = stdout.lock().into_raw_mode()?;
|
||||||
|
let mut force_redraw = true;
|
||||||
|
|
||||||
// Register signals.
|
// Register signals.
|
||||||
let mut signals = Signals::new(&[
|
let mut signals = Signals::new(&[
|
||||||
|
@ -65,22 +66,22 @@ pub fn run(
|
||||||
// Continuing after SIGTSTP or SIGSTOP.
|
// Continuing after SIGTSTP or SIGSTOP.
|
||||||
SIGCONT => {
|
SIGCONT => {
|
||||||
restore_after_suspend(&mut stdout)?;
|
restore_after_suspend(&mut stdout)?;
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
},
|
},
|
||||||
SIGWINCH => layout.force_recalc = true,
|
SIGWINCH => layout.schedule_recalc(),
|
||||||
// Exit main loop on SIGTERM and SIGINT.
|
// Exit main loop on SIGTERM and SIGINT.
|
||||||
SIGTERM | SIGINT => break 'outer,
|
SIGTERM | SIGINT => break 'outer,
|
||||||
// Reset clock on SIGUSR1.
|
// Reset clock on SIGUSR1.
|
||||||
SIGUSR1 => {
|
SIGUSR1 => {
|
||||||
clock.reset();
|
clock.reset();
|
||||||
alarm_roster.reset_all();
|
alarm_roster.reset_all();
|
||||||
layout.force_recalc = true;
|
layout.schedule_recalc();
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
},
|
},
|
||||||
// (Un-)Pause clock on SIGUSR2.
|
// (Un-)Pause clock on SIGUSR2.
|
||||||
SIGUSR2 => {
|
SIGUSR2 => {
|
||||||
clock.toggle();
|
clock.toggle();
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
},
|
},
|
||||||
// We didn't register anything else.
|
// We didn't register anything else.
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -98,7 +99,7 @@ pub fn run(
|
||||||
|
|
||||||
// Conditional inner loop. Runs once every second or when explicitly
|
// Conditional inner loop. Runs once every second or when explicitly
|
||||||
// requested.
|
// requested.
|
||||||
if elapsed != clock.elapsed || layout.force_redraw {
|
if elapsed != clock.elapsed || force_redraw {
|
||||||
// Update clock. Advance one day after 24 hours.
|
// Update clock. Advance one day after 24 hours.
|
||||||
if elapsed < 24 * 60 * 60 {
|
if elapsed < 24 * 60 * 60 {
|
||||||
clock.elapsed = elapsed;
|
clock.elapsed = elapsed;
|
||||||
|
@ -106,36 +107,49 @@ pub fn run(
|
||||||
clock.next_day();
|
clock.next_day();
|
||||||
// "clock.elapsed" set by "clock.next_day()".
|
// "clock.elapsed" set by "clock.next_day()".
|
||||||
alarm_roster.reset_all();
|
alarm_roster.reset_all();
|
||||||
layout.force_recalc = true;
|
layout.schedule_recalc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update window size information and calculate the clock position.
|
// Update window size information and calculate the clock position.
|
||||||
// Also enforce recalculation of layout if we start displaying
|
// Also enforce recalculation of layout if we start displaying
|
||||||
// hours.
|
// hours.
|
||||||
layout.update(&clock, clock.elapsed == 3600)?;
|
match layout.update(&clock, clock.elapsed == 3600) {
|
||||||
|
Ok(true) => force_redraw = true,
|
||||||
|
Ok(false) => (),
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
|
|
||||||
// Check for exceeded alarms.
|
// Check for exceeded alarms.
|
||||||
if let Some((time, label)) = alarm_roster.check(&mut clock, &layout, &mut countdown) {
|
if let Some((time, label)) = alarm_roster.check(
|
||||||
// Write ASCII bell code.
|
&mut clock,
|
||||||
write!(stdout, "{}", 0x07 as char)?;
|
&layout,
|
||||||
layout.force_redraw = true;
|
&mut countdown,
|
||||||
|
force_redraw)
|
||||||
|
{
|
||||||
|
// Do not react to exceeded alarms if the clock is paused.
|
||||||
|
if !clock.paused {
|
||||||
|
force_redraw = true;
|
||||||
|
|
||||||
match config.command {
|
// Write ASCII bell code.
|
||||||
// Run command if configured and no command is running.
|
write!(stdout, "{}", 0x07 as char)?;
|
||||||
Some(ref command) if spawned.is_none() => {
|
|
||||||
*spawned = exec_command(command, time, &label);
|
match config.command {
|
||||||
},
|
// Run command if configured and no command is running.
|
||||||
// Last command is still running.
|
Some(ref command) if spawned.is_none() => {
|
||||||
Some(_) => eprintln!("Not executing command, as its predecessor is still running"),
|
*spawned = exec_command(command, time, &label);
|
||||||
None => (),
|
},
|
||||||
|
// Last command is still running.
|
||||||
|
Some(_) => eprintln!("Not executing command, as its predecessor is still running"),
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
// Quit if configured.
|
||||||
|
if config.quit && alarm_roster.idle() { break };
|
||||||
}
|
}
|
||||||
// Quit if configured.
|
|
||||||
if config.quit && alarm_roster.idle() { break };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the window and redraw menu bar, alarm roster and buffer if
|
// Clear the window and redraw menu bar, alarm roster and buffer if
|
||||||
// requested.
|
// requested.
|
||||||
if layout.force_redraw {
|
if force_redraw {
|
||||||
// Write menu at the top.
|
// Write menu at the top.
|
||||||
write!(stdout,
|
write!(stdout,
|
||||||
"{}{}{}{}{}",
|
"{}{}{}{}{}",
|
||||||
|
@ -144,6 +158,7 @@ pub fn run(
|
||||||
// Switch menu bars. Use a compressed version or none at
|
// Switch menu bars. Use a compressed version or none at
|
||||||
// all if necessary.
|
// all if necessary.
|
||||||
match buffer.visible {
|
match buffer.visible {
|
||||||
|
_ if clock.paused && layout.can_hold(MENUBAR_PAUSED) => MENUBAR_PAUSED,
|
||||||
true if layout.can_hold(MENUBAR_INS) => MENUBAR_INS,
|
true if layout.can_hold(MENUBAR_INS) => MENUBAR_INS,
|
||||||
false if layout.can_hold(MENUBAR) => MENUBAR,
|
false if layout.can_hold(MENUBAR) => MENUBAR,
|
||||||
false if layout.can_hold(MENUBAR_SHORT) => MENUBAR_SHORT,
|
false if layout.can_hold(MENUBAR_SHORT) => MENUBAR_SHORT,
|
||||||
|
@ -162,7 +177,7 @@ pub fn run(
|
||||||
buffer.draw(&mut stdout, &mut layout)?;
|
buffer.draw(&mut stdout, &mut layout)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock.draw(&mut stdout, &layout)?;
|
clock.draw(&mut stdout, &layout, force_redraw)?;
|
||||||
|
|
||||||
// Display countdown.
|
// Display countdown.
|
||||||
if countdown.value > 0 {
|
if countdown.value > 0 {
|
||||||
|
@ -191,7 +206,7 @@ pub fn run(
|
||||||
|
|
||||||
// End of conditional inner loop.
|
// End of conditional inner loop.
|
||||||
// Reset redraw_all and flush stdout.
|
// Reset redraw_all and flush stdout.
|
||||||
layout.force_redraw = false;
|
force_redraw = false;
|
||||||
stdout.flush()?;
|
stdout.flush()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,21 +231,21 @@ pub fn run(
|
||||||
}
|
}
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
buffer.visible = false;
|
buffer.visible = false;
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Escape and ^U clear input buffer.
|
// Escape and ^U clear input buffer.
|
||||||
Key::Esc | Key::Ctrl('u') => {
|
Key::Esc | Key::Ctrl('u') => {
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
buffer.visible = false;
|
buffer.visible = false;
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
},
|
},
|
||||||
// ^W removes last word.
|
// ^W removes last word.
|
||||||
Key::Ctrl('w') => {
|
Key::Ctrl('w') => {
|
||||||
buffer.strip_word();
|
buffer.strip_word();
|
||||||
if buffer.is_empty() {
|
if buffer.is_empty() {
|
||||||
buffer.visible = false;
|
buffer.visible = false;
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Backspace.
|
// Backspace.
|
||||||
|
@ -239,9 +254,25 @@ pub fn run(
|
||||||
buffer.strip_char();
|
buffer.strip_char();
|
||||||
if buffer.is_empty() {
|
if buffer.is_empty() {
|
||||||
buffer.visible = false;
|
buffer.visible = false;
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Set clock.
|
||||||
|
Key::Up if clock.paused => {
|
||||||
|
clock.shift(10);
|
||||||
|
// We would very likely not detect us passing the hour
|
||||||
|
// barrier and would panic when trying to draw hours
|
||||||
|
// without position if we do not schedule a recalculation
|
||||||
|
// here.
|
||||||
|
layout.schedule_recalc();
|
||||||
|
force_redraw = true;
|
||||||
|
},
|
||||||
|
Key::Down if clock.paused => {
|
||||||
|
clock.shift(-10);
|
||||||
|
alarm_roster.time_travel(clock.elapsed);
|
||||||
|
layout.schedule_recalc();
|
||||||
|
force_redraw = true;
|
||||||
|
},
|
||||||
// Forward every char if in insert mode.
|
// Forward every char if in insert mode.
|
||||||
Key::Char(c) if buffer.visible => {
|
Key::Char(c) if buffer.visible => {
|
||||||
buffer.push(c);
|
buffer.push(c);
|
||||||
|
@ -250,18 +281,18 @@ pub fn run(
|
||||||
Key::Char('r') => {
|
Key::Char('r') => {
|
||||||
clock.reset();
|
clock.reset();
|
||||||
alarm_roster.reset_all();
|
alarm_roster.reset_all();
|
||||||
layout.force_recalc = true;
|
layout.schedule_recalc();
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
},
|
},
|
||||||
// (Un-)Pause on space.
|
// (Un-)Pause on space.
|
||||||
Key::Char(' ') => {
|
Key::Char(' ') => {
|
||||||
clock.toggle();
|
clock.toggle();
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
},
|
},
|
||||||
// Clear clock color on 'c'.
|
// Clear clock color on 'c'.
|
||||||
Key::Char('c') => {
|
Key::Char('c') => {
|
||||||
clock.color_index = None;
|
clock.color_index = None;
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
},
|
},
|
||||||
// Delete last alarm on 'd'.
|
// Delete last alarm on 'd'.
|
||||||
Key::Char('d') => {
|
Key::Char('d') => {
|
||||||
|
@ -270,20 +301,20 @@ pub fn run(
|
||||||
// manually. It is safe to do it anyway.
|
// manually. It is safe to do it anyway.
|
||||||
layout.set_roster_width(alarm_roster.width());
|
layout.set_roster_width(alarm_roster.width());
|
||||||
countdown.reset();
|
countdown.reset();
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Exit on q and ^C.
|
// Exit on q and ^C.
|
||||||
Key::Char('q') | Key::Ctrl('c') => break,
|
Key::Char('q') | Key::Ctrl('c') => break,
|
||||||
// Force redraw on ^R.
|
// Force redraw on ^R.
|
||||||
Key::Ctrl('r') => layout.force_redraw = true,
|
Key::Ctrl('r') => force_redraw = true,
|
||||||
// Suspend an ^Z.
|
// Suspend an ^Z.
|
||||||
Key::Ctrl('z') => {
|
Key::Ctrl('z') => {
|
||||||
suspend(&mut stdout)?;
|
suspend(&mut stdout)?;
|
||||||
// Clear SIGCONT, as we have already taken care to reset
|
// Clear SIGCONT, as we have already taken care to reset
|
||||||
// the terminal.
|
// the terminal.
|
||||||
//signal.compare_and_swap(SIGCONT, 0, Ordering::Relaxed);
|
//signal.compare_and_swap(SIGCONT, 0, Ordering::Relaxed);
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
// Jump to the start of the main loop.
|
// Jump to the start of the main loop.
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
@ -291,7 +322,7 @@ pub fn run(
|
||||||
if c.is_ascii_digit() {
|
if c.is_ascii_digit() {
|
||||||
buffer.push(c);
|
buffer.push(c);
|
||||||
buffer.visible = true;
|
buffer.visible = true;
|
||||||
layout.force_redraw = true;
|
force_redraw = true;
|
||||||
} else if !buffer.is_empty() && c == ':' {
|
} else if !buffer.is_empty() && c == ':' {
|
||||||
buffer.push(':');
|
buffer.push(':');
|
||||||
}
|
}
|
||||||
|
@ -300,7 +331,7 @@ pub fn run(
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Main loop delay.
|
// Main loop delay. Skipped after key press.
|
||||||
thread::sleep(time::Duration::from_millis(100));
|
thread::sleep(time::Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue