diff --git a/src/clock.rs b/src/clock.rs index 13e6cbb..181a884 100644 --- a/src/clock.rs +++ b/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, pub color_index: Option, + 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, 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( @@ -163,37 +165,35 @@ impl Clock { stdout: &mut RawTerminal, 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( &self, stdout: &mut RawTerminal, 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(()) } } diff --git a/src/clock/font.rs b/src/clock/font.rs new file mode 100644 index 0000000..15c73e3 --- /dev/null +++ b/src/clock/font.rs @@ -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 + "█▀▀▀█", + "█ █", + "▀▀▀▀▀", + " 🮐", + " 🮐" + ]], +}; +*/ diff --git a/src/consts.rs b/src/consts.rs index e7c9021..5c24442 100644 --- a/src/consts.rs +++ b/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: 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 - "█████", - "█ █", - "█████", - " █", - " █" - ] - ]; -} - diff --git a/src/layout.rs b/src/layout.rs index 859ae32..9e2a700 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -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. diff --git a/src/lib.rs b/src/lib.rs index d0b69aa..648fbe2 100644 --- a/src/lib.rs +++ b/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 { let mut command: Vec = 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 }