Files
tlock/src/main.rs

133 lines
3.4 KiB
Rust

use std::{
io::{self, Write},
thread,
time::Duration,
};
use chrono::{Local, Timelike};
use config::Config;
use crossterm::{
cursor,
event::{self, Event, KeyCode, KeyModifiers},
execute, queue,
style::{self, Color},
terminal::{self, ClearType},
};
mod config;
mod symbols;
fn main() -> io::Result<()> {
// Load config
let config = config::load_from_file("config");
let mut stdout = io::stdout();
// Switch to alternate screen, hide the cursor and enable raw mode
execute!(stdout, terminal::EnterAlternateScreen, cursor::Hide)?;
let _ = terminal::enable_raw_mode()?;
// Main loop
let mut quit = false;
while !quit {
// Handle events
while event::poll(Duration::ZERO)? {
match event::read()? {
Event::Key(e) => match e.code {
KeyCode::Char(x) => {
// Handle CTRL-C
if x == 'c' && e.modifiers.contains(KeyModifiers::CONTROL) {
quit = true;
}
}
_ => {}
},
_ => {}
}
}
// Clear frame
queue!(stdout, terminal::Clear(ClearType::All))?;
// Render
render_frame(&config)?;
stdout.flush()?;
thread::sleep(Duration::from_millis(1000 / config.fps));
}
// Disale raw mode, leave the alternate screen and show the cursor back
let _ = terminal::disable_raw_mode().unwrap();
execute!(stdout, terminal::LeaveAlternateScreen, cursor::Show)?;
// Be polite
if config.be_polite {
println!("CTRL-C pressed, bye!\n");
}
return Ok(());
}
fn render_frame(config: &Config) -> io::Result<()> {
let (width, height) = terminal::size()?;
let time = Local::now();
let hour = time.hour().to_string();
let minute = time.minute().to_string();
// Display current time
let text_width = 6 + 7 + 6 + 7 + 6;
let text_height = 5;
let color = config.color;
let x = width / 2 - text_width / 2;
let y = height / 2 - text_height / 2;
// Hour
if hour.len() == 1 {
draw_symbol('0', x - 0 + 0 * 7, y, color)?;
} else {
draw_symbol(hour.chars().nth(0).unwrap(), x - 0 + 0 * 7, y, color)?;
}
draw_symbol(hour.chars().last().unwrap(), x - 0 + 1 * 7, y, color)?;
draw_symbol(':', x - 1 + 2 * 7, y, color)?;
// Minutes
if minute.len() == 1 {
draw_symbol('0', x - 2 + 3 * 7, y, color)?;
} else {
draw_symbol(minute.chars().nth(0).unwrap(), x - 2 + 3 * 7, y, color)?;
}
draw_symbol(minute.chars().last().unwrap(), x - 2 + 4 * 7, y, color)?;
return Ok(());
}
fn draw_symbol(symbol: char, x: u16, y: u16, color: Color) -> io::Result<()> {
let mut stdout = io::stdout();
let data = symbols::symbol_to_render_data(symbol);
for oy in 0..data.len() {
for ox in 0..data[oy].len() {
if data[oy][ox] {
let cx = ox as u16;
let cy = oy as u16;
// Render cursor at position by setting background color and using space
queue!(
stdout,
cursor::MoveTo(x + cx, y + cy),
style::SetBackgroundColor(color)
)?;
write!(stdout, " ")?;
queue!(stdout, style::ResetColor)?;
}
}
}
return Ok(());
}