diff --git a/src/alarm.rs b/src/alarm.rs index 87ad731..0f1b8ea 100644 --- a/src/alarm.rs +++ b/src/alarm.rs @@ -280,8 +280,8 @@ impl AlarmRoster { // Reset every alarm. pub fn reset_all(&mut self) { - for a in &mut self.list { - a.reset(); + for alarm in &mut self.list { + alarm.reset(); } } } diff --git a/src/clock.rs b/src/clock.rs index 181a884..4940dc3 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -15,7 +15,7 @@ pub struct Clock { pub paused: bool, paused_at: Option, pub color_index: Option, - font: font::Font, + pub font: font::Font, } impl Clock { @@ -71,6 +71,16 @@ impl Clock { } } + pub fn get_width(&self) -> u16 { + if self.elapsed >= 3600 { + // Hours + self.font.width * 6 + 3 + 10 + } else { + // Minutes and seconds only. + self.font.width * 4 + 2 + 5 + } + } + pub fn next_day(&mut self) { // Shift start 24h into the future. let next = self.start.clone() + time::Duration::from_secs(60 * 60 * 24); diff --git a/src/clock/font.rs b/src/clock/font.rs index 15c73e3..420874f 100644 --- a/src/clock/font.rs +++ b/src/clock/font.rs @@ -1,6 +1,5 @@ -pub const DIGIT_HEIGHT: u16 = 5; -pub const DIGIT_WIDTH: u16 = 5; +const DIGIT_HEIGHT: u16 = 5; pub struct Font { pub height: u16, diff --git a/src/layout.rs b/src/layout.rs index 9e2a700..1f0d9a7 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -1,12 +1,7 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use crate::Config; -use crate::clock::font::*; - -// If screen size falls below these values we skip computation of new -// positions. -const MIN_WIDTH: u16 = DIGIT_WIDTH * 6 + 13; -const MIN_HEIGHT: u16 = DIGIT_HEIGHT + 2; +use crate::clock::Clock; pub struct Position { pub line: u16, @@ -19,6 +14,9 @@ pub struct Layout { pub plain: bool, // Plain style clock. pub width: u16, pub height: u16, + clock_width: u16, + clock_height: u16, + digit_width: u16, pub clock_sec: Position, pub clock_colon0: Position, pub clock_min: Position, @@ -40,6 +38,9 @@ impl Layout { plain: config.plain, width: 0, height: 0, + clock_width: 0, + clock_height: 0, + digit_width: 0, clock_sec: Position {col: 0, line: 0}, clock_colon0: Position {col: 0, line: 0}, clock_min: Position {col: 0, line: 0}, @@ -53,13 +54,16 @@ impl Layout { } } - pub fn update(&mut self, display_hours: bool, force: bool) { + pub fn update(&mut self, clock: &Clock, force: bool) { if self.force_recalc.swap(false, Ordering::Relaxed) || force { let (width, height) = termion::terminal_size() .expect("Could not read terminal size!"); self.width = width; self.height = height; - self.compute(display_hours); + self.clock_width = clock.get_width(); + self.clock_height = clock.font.height; + self.digit_width = clock.font.width; + self.compute(clock.elapsed >= 3600); self.force_redraw = true; } } @@ -67,15 +71,18 @@ impl Layout { #[cfg(test)] pub fn test_update( &mut self, - hours: bool, + clock: &Clock, width: u16, height: u16, roster_width: u16, ) { self.width = width; self.height = height; + self.clock_width = clock.get_width(); + self.clock_height = clock.font.height; + self.digit_width = clock.font.width; self.roster_width = roster_width; - self.compute(hours); + self.compute(false); } pub fn can_hold(&self, other: &str) -> bool { @@ -87,27 +94,27 @@ impl Layout { // terminal. fn compute(&mut self, display_hours: bool) { // Prevent integer overflow at very low screen sizes. - if self.width < MIN_WIDTH || self.height < MIN_HEIGHT { return; } + if self.width < self.clock_width || self.height < self.clock_height { return; } let middle: u16 = self.height / 2 - 1; if display_hours { // Seconds digits. - self.clock_sec.col = (self.width + self.roster_width) / 2 + DIGIT_WIDTH + 6; + self.clock_sec.col = (self.width + self.roster_width) / 2 + self.digit_width + 6; // Colon separating minutes from seconds. - self.clock_colon0.col = (self.width + self.roster_width) / 2 + DIGIT_WIDTH + 3; + self.clock_colon0.col = (self.width + self.roster_width) / 2 + self.digit_width + 3; // Minute digits. - self.clock_min.col = (self.width + self.roster_width) / 2 - DIGIT_WIDTH; + self.clock_min.col = (self.width + self.roster_width) / 2 - self.digit_width; // Colon separating hours from minutes. self.clock_colon1 = Position { - col: (self.width + self.roster_width) / 2 - (DIGIT_WIDTH + 3), + col: (self.width + self.roster_width) / 2 - (self.digit_width + 3), line: middle, }; // Hour digits. self.clock_hr = Position { - col: (self.width + self.roster_width) / 2 - (DIGIT_WIDTH * 3 + 6), + col: (self.width + self.roster_width) / 2 - (self.digit_width * 3 + 6), line: middle, }; } else { @@ -116,7 +123,7 @@ impl Layout { // Colon separating minutes from seconds. self.clock_colon0.col = (self.width + self.roster_width) / 2; // Minute digits. - self.clock_min.col = (self.width + self.roster_width) / 2 - (DIGIT_WIDTH * 2 + 3); + self.clock_min.col = (self.width + self.roster_width) / 2 - (self.digit_width * 2 + 3); } self.clock_sec.line = middle; @@ -125,7 +132,7 @@ impl Layout { // Days (based on position of seconds). self.clock_days = Position { - line: self.clock_sec.line + DIGIT_HEIGHT, + line: self.clock_sec.line + self.digit_width, col: self.clock_sec.col, }; diff --git a/src/lib.rs b/src/lib.rs index 86092ce..cfb3b39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -130,7 +130,7 @@ pub fn run( // Update window size information and calculate the clock position. // Also enforce recalculation of layout if we start displaying // hours. - layout.update(clock.elapsed >= 3600, clock.elapsed == 3600); + layout.update(&clock, clock.elapsed == 3600); // Check for exceeded alarms. if let Some((time, label)) = alarm_roster.check(&mut clock, &layout, &mut countdown) { diff --git a/src/tests.rs b/src/tests.rs index 8645d2e..3105d00 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,4 +1,5 @@ use crate::layout::Layout; +use crate::clock::Clock; use crate::Config; fn default_config() -> Config { @@ -13,13 +14,24 @@ fn default_config() -> Config { #[test] fn layout_computation() { let config = default_config(); + let mut clock = Clock::new(&config); let mut layout = Layout::new(&config); + // Two segment display. for roster_width in &[0, 10, 20, 30, 40] { for width in 0..256 { for height in 0..128 { - layout.test_update(height & 1 == 0, width, height, *roster_width); + layout.test_update(&clock, width, height, *roster_width); } - } + } + } + // Three segment display. + clock.elapsed = 3600; + for roster_width in &[0, 10, 20, 30, 40] { + for width in 0..256 { + for height in 0..128 { + layout.test_update(&clock, width, height, *roster_width); + } + } } }