Propagate digit size through clock.
This commit is contained in:
parent
a95c00aa57
commit
f3b48aa7a8
6 changed files with 54 additions and 26 deletions
|
@ -280,8 +280,8 @@ impl AlarmRoster {
|
||||||
|
|
||||||
// Reset every alarm.
|
// Reset every alarm.
|
||||||
pub fn reset_all(&mut self) {
|
pub fn reset_all(&mut self) {
|
||||||
for a in &mut self.list {
|
for alarm in &mut self.list {
|
||||||
a.reset();
|
alarm.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/clock.rs
12
src/clock.rs
|
@ -15,7 +15,7 @@ pub struct Clock {
|
||||||
pub paused: bool,
|
pub paused: bool,
|
||||||
paused_at: Option<time::Instant>,
|
paused_at: Option<time::Instant>,
|
||||||
pub color_index: Option<usize>,
|
pub color_index: Option<usize>,
|
||||||
font: font::Font,
|
pub font: font::Font,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clock {
|
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) {
|
pub fn next_day(&mut self) {
|
||||||
// Shift start 24h into the future.
|
// Shift start 24h into the future.
|
||||||
let next = self.start.clone() + time::Duration::from_secs(60 * 60 * 24);
|
let next = self.start.clone() + time::Duration::from_secs(60 * 60 * 24);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
pub const DIGIT_HEIGHT: u16 = 5;
|
const DIGIT_HEIGHT: u16 = 5;
|
||||||
pub const DIGIT_WIDTH: u16 = 5;
|
|
||||||
|
|
||||||
pub struct Font {
|
pub struct Font {
|
||||||
pub height: u16,
|
pub height: u16,
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
use crate::clock::font::*;
|
use crate::clock::Clock;
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub line: u16,
|
pub line: u16,
|
||||||
|
@ -19,6 +14,9 @@ pub struct Layout {
|
||||||
pub plain: bool, // Plain style clock.
|
pub plain: bool, // Plain style clock.
|
||||||
pub width: u16,
|
pub width: u16,
|
||||||
pub height: u16,
|
pub height: u16,
|
||||||
|
clock_width: u16,
|
||||||
|
clock_height: u16,
|
||||||
|
digit_width: u16,
|
||||||
pub clock_sec: Position,
|
pub clock_sec: Position,
|
||||||
pub clock_colon0: Position,
|
pub clock_colon0: Position,
|
||||||
pub clock_min: Position,
|
pub clock_min: Position,
|
||||||
|
@ -40,6 +38,9 @@ impl Layout {
|
||||||
plain: config.plain,
|
plain: config.plain,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
|
clock_width: 0,
|
||||||
|
clock_height: 0,
|
||||||
|
digit_width: 0,
|
||||||
clock_sec: Position {col: 0, line: 0},
|
clock_sec: Position {col: 0, line: 0},
|
||||||
clock_colon0: Position {col: 0, line: 0},
|
clock_colon0: Position {col: 0, line: 0},
|
||||||
clock_min: 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 {
|
if self.force_recalc.swap(false, Ordering::Relaxed) || force {
|
||||||
let (width, height) = termion::terminal_size()
|
let (width, height) = termion::terminal_size()
|
||||||
.expect("Could not read terminal size!");
|
.expect("Could not read terminal size!");
|
||||||
self.width = width;
|
self.width = width;
|
||||||
self.height = height;
|
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;
|
self.force_redraw = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,15 +71,18 @@ impl Layout {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn test_update(
|
pub fn test_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
hours: bool,
|
clock: &Clock,
|
||||||
width: u16,
|
width: u16,
|
||||||
height: u16,
|
height: u16,
|
||||||
roster_width: u16,
|
roster_width: u16,
|
||||||
) {
|
) {
|
||||||
self.width = width;
|
self.width = width;
|
||||||
self.height = height;
|
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.roster_width = roster_width;
|
||||||
self.compute(hours);
|
self.compute(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_hold(&self, other: &str) -> bool {
|
pub fn can_hold(&self, other: &str) -> bool {
|
||||||
|
@ -87,27 +94,27 @@ impl Layout {
|
||||||
// terminal.
|
// terminal.
|
||||||
fn compute(&mut self, display_hours: bool) {
|
fn compute(&mut self, display_hours: bool) {
|
||||||
// Prevent integer overflow at very low screen sizes.
|
// 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;
|
let middle: u16 = self.height / 2 - 1;
|
||||||
|
|
||||||
if display_hours {
|
if display_hours {
|
||||||
// Seconds digits.
|
// 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.
|
// 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.
|
// 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.
|
// Colon separating hours from minutes.
|
||||||
self.clock_colon1 = Position {
|
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,
|
line: middle,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hour digits.
|
// Hour digits.
|
||||||
self.clock_hr = Position {
|
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,
|
line: middle,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,7 +123,7 @@ impl Layout {
|
||||||
// Colon separating minutes from seconds.
|
// Colon separating minutes from seconds.
|
||||||
self.clock_colon0.col = (self.width + self.roster_width) / 2;
|
self.clock_colon0.col = (self.width + self.roster_width) / 2;
|
||||||
// Minute digits.
|
// 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;
|
self.clock_sec.line = middle;
|
||||||
|
@ -125,7 +132,7 @@ impl Layout {
|
||||||
|
|
||||||
// Days (based on position of seconds).
|
// Days (based on position of seconds).
|
||||||
self.clock_days = Position {
|
self.clock_days = Position {
|
||||||
line: self.clock_sec.line + DIGIT_HEIGHT,
|
line: self.clock_sec.line + self.digit_width,
|
||||||
col: self.clock_sec.col,
|
col: self.clock_sec.col,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ pub fn run(
|
||||||
// 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.elapsed >= 3600, clock.elapsed == 3600);
|
layout.update(&clock, clock.elapsed == 3600);
|
||||||
|
|
||||||
// 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(&mut clock, &layout, &mut countdown) {
|
||||||
|
|
14
src/tests.rs
14
src/tests.rs
|
@ -1,4 +1,5 @@
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
|
use crate::clock::Clock;
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
|
|
||||||
fn default_config() -> Config {
|
fn default_config() -> Config {
|
||||||
|
@ -13,12 +14,23 @@ fn default_config() -> Config {
|
||||||
#[test]
|
#[test]
|
||||||
fn layout_computation() {
|
fn layout_computation() {
|
||||||
let config = default_config();
|
let config = default_config();
|
||||||
|
let mut clock = Clock::new(&config);
|
||||||
let mut layout = Layout::new(&config);
|
let mut layout = Layout::new(&config);
|
||||||
|
|
||||||
|
// Two segment display.
|
||||||
for roster_width in &[0, 10, 20, 30, 40] {
|
for roster_width in &[0, 10, 20, 30, 40] {
|
||||||
for width in 0..256 {
|
for width in 0..256 {
|
||||||
for height in 0..128 {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue