Refactored clock code.
This commit is contained in:
parent
557358a4c0
commit
5eef3dd811
5 changed files with 296 additions and 275 deletions
68
src/clock.rs
68
src/clock.rs
|
@ -1,9 +1,11 @@
|
|||
pub mod font;
|
||||
|
||||
use std::time;
|
||||
use std::io::Write;
|
||||
use termion::{color, cursor, style};
|
||||
use termion::raw::RawTerminal;
|
||||
use crate::consts::COLOR;
|
||||
use crate::consts::digits::*;
|
||||
use crate::Config;
|
||||
use crate::layout::{Layout, Position};
|
||||
|
||||
pub struct Clock {
|
||||
|
@ -13,10 +15,11 @@ pub struct Clock {
|
|||
pub paused: bool,
|
||||
paused_at: Option<time::Instant>,
|
||||
pub color_index: Option<usize>,
|
||||
font: font::Font,
|
||||
}
|
||||
|
||||
impl Clock {
|
||||
pub fn new() -> Clock {
|
||||
pub fn new(config: &Config) -> Clock {
|
||||
Clock {
|
||||
start: time::Instant::now(),
|
||||
elapsed: 0,
|
||||
|
@ -24,6 +27,10 @@ impl Clock {
|
|||
paused: false,
|
||||
paused_at: None,
|
||||
color_index: None,
|
||||
font: match config.plain {
|
||||
false => font::NORMAL,
|
||||
true => font::PLAIN,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,13 +88,14 @@ impl Clock {
|
|||
&mut self,
|
||||
mut stdout: &mut RawTerminal<W>,
|
||||
layout: &Layout,
|
||||
) {
|
||||
) -> Result<(), std::io::Error>
|
||||
{
|
||||
// Setup style and color if appropriate.
|
||||
if self.paused {
|
||||
write!(stdout, "{}", style::Faint).unwrap();
|
||||
write!(stdout, "{}", style::Faint)?;
|
||||
}
|
||||
if let Some(c) = self.color_index {
|
||||
write!(stdout, "{}", color::Fg(COLOR[c])).unwrap();
|
||||
write!(stdout, "{}", color::Fg(COLOR[c]))?;
|
||||
}
|
||||
|
||||
// Draw hours if necessary.
|
||||
|
@ -96,14 +104,12 @@ impl Clock {
|
|||
self.draw_digit_pair(
|
||||
&mut stdout,
|
||||
self.elapsed / 3600,
|
||||
&layout.clock_hr,
|
||||
layout.plain);
|
||||
&layout.clock_hr)?;
|
||||
|
||||
// Draw colon.
|
||||
self.draw_colon(
|
||||
&mut stdout,
|
||||
&layout.clock_colon1,
|
||||
layout.plain);
|
||||
&layout.clock_colon1)?;
|
||||
}
|
||||
|
||||
// Draw days.
|
||||
|
@ -119,8 +125,7 @@ impl Clock {
|
|||
layout.clock_days.col,
|
||||
layout.clock_days.line,
|
||||
),
|
||||
day_count)
|
||||
.unwrap();
|
||||
day_count)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,33 +134,30 @@ impl Clock {
|
|||
self.draw_digit_pair(
|
||||
&mut stdout,
|
||||
(self.elapsed % 3600) / 60,
|
||||
&layout.clock_min,
|
||||
layout.plain);
|
||||
&layout.clock_min)?;
|
||||
}
|
||||
|
||||
// Draw colon if necessary.
|
||||
if layout.force_redraw {
|
||||
self.draw_colon(
|
||||
&mut stdout,
|
||||
&layout.clock_colon0,
|
||||
layout.plain);
|
||||
&layout.clock_colon0)?;
|
||||
}
|
||||
|
||||
// Draw seconds.
|
||||
self.draw_digit_pair(
|
||||
&mut stdout,
|
||||
self.elapsed % 60,
|
||||
&layout.clock_sec,
|
||||
layout.plain);
|
||||
&layout.clock_sec)?;
|
||||
|
||||
// Reset color and style.
|
||||
if self.paused || self.color_index != None {
|
||||
write!(stdout,
|
||||
"{}{}",
|
||||
style::NoFaint,
|
||||
color::Fg(color::Reset))
|
||||
.unwrap();
|
||||
color::Fg(color::Reset))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_digit_pair<W: Write>(
|
||||
|
@ -163,37 +165,35 @@ impl Clock {
|
|||
stdout: &mut RawTerminal<W>,
|
||||
value: u32,
|
||||
pos: &Position,
|
||||
plain: bool,
|
||||
) {
|
||||
let digits = if plain { DIGITS_PLAIN } else { DIGITS };
|
||||
|
||||
for l in 0..DIGIT_HEIGHT {
|
||||
) -> Result<(), std::io::Error>
|
||||
{
|
||||
for l in 0..self.font.height {
|
||||
write!(stdout,
|
||||
"{}{} {}",
|
||||
cursor::Goto(pos.col, pos.line + l),
|
||||
// First digit.
|
||||
digits[(value / 10) as usize][l as usize],
|
||||
self.font.digits[(value / 10) as usize][l as usize],
|
||||
// Second digit.
|
||||
digits[(value % 10) as usize][l as usize])
|
||||
.unwrap();
|
||||
self.font.digits[(value % 10) as usize][l as usize]
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_colon<W: Write>(
|
||||
&self,
|
||||
stdout: &mut RawTerminal<W>,
|
||||
pos: &Position,
|
||||
plain: bool,
|
||||
) {
|
||||
let dot = if plain {'█'} else {'■'};
|
||||
|
||||
) -> Result<(), std::io::Error>
|
||||
{
|
||||
write!(stdout,
|
||||
"{}{}{}{}",
|
||||
cursor::Goto(pos.col, pos.line + 1),
|
||||
dot,
|
||||
self.font.dot,
|
||||
cursor::Goto(pos.col, pos.line + 3),
|
||||
dot)
|
||||
.unwrap();
|
||||
self.font.dot,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
243
src/clock/font.rs
Normal file
243
src/clock/font.rs
Normal file
|
@ -0,0 +1,243 @@
|
|||
|
||||
pub const DIGIT_HEIGHT: u16 = 5;
|
||||
pub const DIGIT_WIDTH: u16 = 5;
|
||||
|
||||
pub struct Font {
|
||||
pub height: u16,
|
||||
pub width: u16,
|
||||
pub dot: char,
|
||||
pub digits: [[&'static str; DIGIT_HEIGHT as usize]; 10],
|
||||
}
|
||||
|
||||
pub const NORMAL: Font = Font {
|
||||
height: DIGIT_HEIGHT,
|
||||
width: 5,
|
||||
dot: '■',
|
||||
digits: [[
|
||||
// 0
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█▄▄▄█",
|
||||
], [
|
||||
// 1
|
||||
" ▀█ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 2
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
"█▀▀▀▀",
|
||||
"█ ",
|
||||
"█▄▄▄▄"
|
||||
], [
|
||||
// 3
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" ▀▀▀█",
|
||||
" █",
|
||||
"▄▄▄▄█"
|
||||
], [
|
||||
// 4
|
||||
"█ ",
|
||||
"█ █ ",
|
||||
"▀▀▀█▀",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 5
|
||||
"█▀▀▀▀",
|
||||
"█ ",
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
"▄▄▄▄█"
|
||||
], [
|
||||
// 6
|
||||
"█ ",
|
||||
"█ ",
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█▄▄▄█"
|
||||
], [
|
||||
// 7
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
], [
|
||||
// 8
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█▄▄▄█"
|
||||
], [
|
||||
// 9
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" █"
|
||||
]],
|
||||
};
|
||||
|
||||
pub const PLAIN: Font = Font {
|
||||
height: DIGIT_HEIGHT,
|
||||
width: 5,
|
||||
dot: '█',
|
||||
digits: [[
|
||||
// 0
|
||||
"█████",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█████"
|
||||
], [
|
||||
// 1
|
||||
" ██ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 2
|
||||
"█████",
|
||||
" █",
|
||||
"█████",
|
||||
"█ ",
|
||||
"█████"
|
||||
], [
|
||||
// 3
|
||||
"█████",
|
||||
" █",
|
||||
" ████",
|
||||
" █",
|
||||
"█████"
|
||||
], [
|
||||
// 4
|
||||
"█ ",
|
||||
"█ █ ",
|
||||
"█████",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 5
|
||||
"█████",
|
||||
"█ ",
|
||||
"█████",
|
||||
" █",
|
||||
"█████"
|
||||
], [
|
||||
// 6
|
||||
"█ ",
|
||||
"█ ",
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████"
|
||||
], [
|
||||
// 7
|
||||
"█████",
|
||||
" █",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 8
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████"
|
||||
], [
|
||||
// 9
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████",
|
||||
" █",
|
||||
" █"
|
||||
]],
|
||||
};
|
||||
|
||||
/*
|
||||
pub const FANCE: Font = Font {
|
||||
height: DIGIT_HEIGHT,
|
||||
width: 5,
|
||||
dot: '■',
|
||||
digits: [[
|
||||
// 0
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀ ▀",
|
||||
"🮐 🮐",
|
||||
"🮐🮏🮏🮏🮐",
|
||||
], [
|
||||
// 1
|
||||
" ▀█ ",
|
||||
" █ ",
|
||||
" ▀ ",
|
||||
" 🮐 ",
|
||||
" 🮐 "
|
||||
], [
|
||||
// 2
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
"▀▀▀▀▀",
|
||||
"🮐 ",
|
||||
"🮐🮏🮏🮏🮏"
|
||||
], [
|
||||
// 3
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" ▀▀▀▀",
|
||||
" 🮐",
|
||||
"🮏🮏🮏🮏🮐"
|
||||
], [
|
||||
// 4
|
||||
"█ ",
|
||||
"█ █ ",
|
||||
"▀▀▀▀▀",
|
||||
" 🮐 ",
|
||||
" 🮐 "
|
||||
], [
|
||||
// 5
|
||||
"█▀▀▀▀",
|
||||
"█ ",
|
||||
"▀▀▀▀▀",
|
||||
" 🮐",
|
||||
"🮏🮏🮏🮏🮐"
|
||||
], [
|
||||
// 6
|
||||
"█ ",
|
||||
"█ ",
|
||||
"▀▀▀▀▀",
|
||||
"🮐 🮐",
|
||||
"🮐🮏🮏🮏🮐"
|
||||
], [
|
||||
// 7
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" ▀ ",
|
||||
" 🮐 ",
|
||||
" 🮐 ",
|
||||
], [
|
||||
// 8
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀▀▀▀▀",
|
||||
"🮐 🮐",
|
||||
"🮐🮏🮏🮏🮐"
|
||||
], [
|
||||
// 9
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀▀▀▀▀",
|
||||
" 🮐",
|
||||
" 🮐"
|
||||
]],
|
||||
};
|
||||
*/
|
228
src/consts.rs
228
src/consts.rs
|
@ -9,7 +9,7 @@ pub const COLOR: [&dyn termion::color::Color; 6] = [
|
|||
];
|
||||
|
||||
// Maximum length of labels.
|
||||
pub const LABEL_SIZE_LIMIT: usize = 48;
|
||||
pub const LABEL_SIZE_LIMIT: usize = 42;
|
||||
|
||||
pub mod ui {
|
||||
pub const NAME: &str = env!("CARGO_PKG_NAME");
|
||||
|
@ -40,229 +40,3 @@ SIGNALS: <SIGUSR1> Reset clock.
|
|||
"Format: HH:MM:SS/LABEL [ENTER] Accept [ESC] Cancel [CTR-C] Quit";
|
||||
}
|
||||
|
||||
pub mod digits {
|
||||
pub const DIGIT_HEIGHT: u16 = 5;
|
||||
pub const DIGIT_WIDTH: u16 = 5;
|
||||
pub const DIGITS: [[&str; DIGIT_HEIGHT as usize]; 10] = [
|
||||
[
|
||||
// 0
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█▄▄▄█",
|
||||
], [
|
||||
// 1
|
||||
" ▀█ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 2
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
"█▀▀▀▀",
|
||||
"█ ",
|
||||
"█▄▄▄▄"
|
||||
], [
|
||||
// 3
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" ▀▀▀█",
|
||||
" █",
|
||||
"▄▄▄▄█"
|
||||
], [
|
||||
// 4
|
||||
"█ ",
|
||||
"█ █ ",
|
||||
"▀▀▀█▀",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 5
|
||||
"█▀▀▀▀",
|
||||
"█ ",
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
"▄▄▄▄█"
|
||||
], [
|
||||
// 6
|
||||
"█ ",
|
||||
"█ ",
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█▄▄▄█"
|
||||
], [
|
||||
// 7
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
], [
|
||||
// 8
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"█▄▄▄█"
|
||||
], [
|
||||
// 9
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" █"
|
||||
]
|
||||
];
|
||||
|
||||
pub const _DIGITS_FANCY: [[&str; DIGIT_HEIGHT as usize]; 10] = [
|
||||
[
|
||||
// 0
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀ ▀",
|
||||
"🮐 🮐",
|
||||
"🮐🮏🮏🮏🮐",
|
||||
], [
|
||||
// 1
|
||||
" ▀█ ",
|
||||
" █ ",
|
||||
" ▀ ",
|
||||
" 🮐 ",
|
||||
" 🮐 "
|
||||
], [
|
||||
// 2
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
"▀▀▀▀▀",
|
||||
"🮐 ",
|
||||
"🮐🮏🮏🮏🮏"
|
||||
], [
|
||||
// 3
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" ▀▀▀▀",
|
||||
" 🮐",
|
||||
"🮏🮏🮏🮏🮐"
|
||||
], [
|
||||
// 4
|
||||
"█ ",
|
||||
"█ █ ",
|
||||
"▀▀▀▀▀",
|
||||
" 🮐 ",
|
||||
" 🮐 "
|
||||
], [
|
||||
// 5
|
||||
"█▀▀▀▀",
|
||||
"█ ",
|
||||
"▀▀▀▀▀",
|
||||
" 🮐",
|
||||
"🮏🮏🮏🮏🮐"
|
||||
], [
|
||||
// 6
|
||||
"█ ",
|
||||
"█ ",
|
||||
"▀▀▀▀▀",
|
||||
"🮐 🮐",
|
||||
"🮐🮏🮏🮏🮐"
|
||||
], [
|
||||
// 7
|
||||
"▀▀▀▀█",
|
||||
" █",
|
||||
" ▀ ",
|
||||
" 🮐 ",
|
||||
" 🮐 ",
|
||||
], [
|
||||
// 8
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀▀▀▀▀",
|
||||
"🮐 🮐",
|
||||
"🮐🮏🮏🮏🮐"
|
||||
], [
|
||||
// 9
|
||||
"█▀▀▀█",
|
||||
"█ █",
|
||||
"▀▀▀▀▀",
|
||||
" 🮐",
|
||||
" 🮐"
|
||||
]
|
||||
];
|
||||
|
||||
pub const DIGITS_PLAIN: [[&str; DIGIT_HEIGHT as usize]; 10] = [
|
||||
[
|
||||
// 0
|
||||
"█████",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█ █",
|
||||
"█████"
|
||||
], [
|
||||
// 1
|
||||
" ██ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 2
|
||||
"█████",
|
||||
" █",
|
||||
"█████",
|
||||
"█ ",
|
||||
"█████"
|
||||
], [
|
||||
// 3
|
||||
"█████",
|
||||
" █",
|
||||
" ████",
|
||||
" █",
|
||||
"█████"
|
||||
], [
|
||||
// 4
|
||||
"█ ",
|
||||
"█ █ ",
|
||||
"█████",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 5
|
||||
"█████",
|
||||
"█ ",
|
||||
"█████",
|
||||
" █",
|
||||
"█████"
|
||||
], [
|
||||
// 6
|
||||
"█ ",
|
||||
"█ ",
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████"
|
||||
], [
|
||||
// 7
|
||||
"█████",
|
||||
" █",
|
||||
" █ ",
|
||||
" █ ",
|
||||
" █ "
|
||||
], [
|
||||
// 8
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████"
|
||||
], [
|
||||
// 9
|
||||
"█████",
|
||||
"█ █",
|
||||
"█████",
|
||||
" █",
|
||||
" █"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use crate::Config;
|
||||
use crate::consts::digits::*;
|
||||
use crate::clock::font::*;
|
||||
|
||||
// If screen size falls below these values we skip computation of new
|
||||
// positions.
|
||||
|
|
30
src/lib.rs
30
src/lib.rs
|
@ -45,7 +45,7 @@ pub fn run(
|
|||
layout.force_recalc = sigwinch;
|
||||
// Initialise roster_width.
|
||||
layout.set_roster_width(alarm_roster.width());
|
||||
let mut clock = Clock::new();
|
||||
let mut clock = Clock::new(&config);
|
||||
let mut countdown = Countdown::new();
|
||||
let mut buffer = Buffer::new();
|
||||
|
||||
|
@ -182,7 +182,7 @@ pub fn run(
|
|||
buffer.draw(&mut stdout, &mut layout)?;
|
||||
}
|
||||
|
||||
clock.draw(&mut stdout, &layout);
|
||||
clock.draw(&mut stdout, &layout)?;
|
||||
|
||||
// Display countdown.
|
||||
if countdown.value > 0 {
|
||||
|
@ -392,33 +392,37 @@ impl Config {
|
|||
// for process::Command::new().
|
||||
fn parse_to_command(input: &str) -> Vec<String> {
|
||||
let mut command: Vec<String> = Vec::new();
|
||||
let mut buffer: String = String::new();
|
||||
let mut segment: String = String::new();
|
||||
let mut quoted = false;
|
||||
let mut escaped = false;
|
||||
|
||||
for byte in input.chars() {
|
||||
match byte {
|
||||
for c in input.chars() {
|
||||
match c {
|
||||
'\\' if !escaped => {
|
||||
// Next char is escaped.
|
||||
// Next char is escaped. (If not escaped itself.)
|
||||
escaped = true;
|
||||
continue;
|
||||
},
|
||||
' ' if escaped || quoted => { &buffer.push(' '); },
|
||||
// Keep spaces when escaped or quoted.
|
||||
' ' if escaped || quoted => { &segment.push(' '); },
|
||||
// Otherwise end the current segment.
|
||||
' ' => {
|
||||
if !&buffer.is_empty() {
|
||||
command.push(buffer.clone());
|
||||
&buffer.clear();
|
||||
if !&segment.is_empty() {
|
||||
command.push(segment.clone());
|
||||
&segment.clear();
|
||||
}
|
||||
},
|
||||
// Quotation marks toggle quote.
|
||||
'"' | '\'' if !escaped => quoted = !quoted,
|
||||
// Carry everything else. Escape if found escaped.
|
||||
_ => {
|
||||
if escaped { &buffer.push('\\'); }
|
||||
&buffer.push(byte);
|
||||
if escaped { &segment.push('\\'); }
|
||||
&segment.push(c);
|
||||
},
|
||||
}
|
||||
escaped = false;
|
||||
}
|
||||
command.push(buffer);
|
||||
command.push(segment);
|
||||
command.shrink_to_fit();
|
||||
command
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue