timr-tui/src/widgets/countdown.rs
2024-12-17 11:16:53 +01:00

91 lines
2.6 KiB
Rust

use ratatui::{
buffer::Buffer,
crossterm::event::KeyCode,
layout::{Constraint, Layout, Rect},
text::Line,
widgets::{StatefulWidget, Widget},
};
use std::cmp::max;
use crate::{
events::{Event, EventHandler},
utils::center,
widgets::clock::{self, Clock, ClockWidget},
};
#[derive(Debug, Clone)]
pub struct Countdown {
clock: Clock<clock::Countdown>,
}
impl Countdown {
pub const fn new(clock: Clock<clock::Countdown>) -> Self {
Self { clock }
}
}
impl EventHandler for Countdown {
fn update(&mut self, event: Event) -> Option<Event> {
let edit_mode = self.clock.is_edit_mode();
match event {
Event::Tick => {
self.clock.tick();
}
Event::Key(key) if key.code == KeyCode::Char('r') => {
self.clock.reset();
}
Event::Key(key) => match key.code {
KeyCode::Char('r') => {
self.clock.reset();
}
KeyCode::Char('s') => {
self.clock.toggle_pause();
}
KeyCode::Char('e') => {
self.clock.toggle_edit();
}
KeyCode::Left if edit_mode => {
self.clock.edit_next();
}
KeyCode::Right if edit_mode => {
self.clock.edit_prev();
}
KeyCode::Up if edit_mode => {
self.clock.edit_up();
}
KeyCode::Down if edit_mode => {
self.clock.edit_down();
}
_ => return Some(event),
},
_ => return Some(event),
}
None
}
}
pub struct CountdownWidget;
impl StatefulWidget for CountdownWidget {
type State = Countdown;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let clock = ClockWidget::new();
let headline = "Countdown".to_uppercase();
let label = Line::raw((format!("{} {}", headline, state.clock.get_mode())).to_uppercase());
let area = center(
area,
Constraint::Length(max(
clock.get_width(&state.clock.get_format()),
label.width() as u16,
)),
Constraint::Length(clock.get_height() + 1 /* height of label */),
);
let [v1, v2] =
Layout::vertical(Constraint::from_lengths([clock.get_height(), 1])).areas(area);
clock.render(v1, buf, &mut state.clock);
label.centered().render(v2, buf);
}
}