simplify style settings, improve naming (#44)

* simplify style settings by passing `style` directly to Widgets. No need to store it in `state` of widgets.
* remove unneeded things
* naming (state vs. widgets)
This commit is contained in:
Jens Krause 2025-01-07 19:02:57 +01:00 committed by GitHub
parent 8603a823e4
commit 468b4a5abf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 116 additions and 165 deletions

View File

@ -6,12 +6,12 @@ use crate::{
storage::AppStorage, storage::AppStorage,
terminal::Terminal, terminal::Terminal,
widgets::{ widgets::{
clock::{self, Clock, ClockArgs}, clock::{self, ClockState, ClockStateArgs},
countdown::{Countdown, CountdownWidget}, countdown::{Countdown, CountdownState},
footer::{Footer, FooterState}, footer::{Footer, FooterState},
header::Header, header::Header,
pomodoro::{Mode as PomodoroMode, Pomodoro, PomodoroArgs, PomodoroWidget}, pomodoro::{Mode as PomodoroMode, PomodoroState, PomodoroStateArgs, PomodoroWidget},
timer::{Timer, TimerWidget}, timer::{Timer, TimerState},
}, },
}; };
use color_eyre::Result; use color_eyre::Result;
@ -36,12 +36,12 @@ pub struct App {
content: Content, content: Content,
mode: Mode, mode: Mode,
app_time: AppTime, app_time: AppTime,
countdown: Countdown, countdown: CountdownState,
timer: Timer, timer: TimerState,
pomodoro: Pomodoro, pomodoro: PomodoroState,
style: Style, style: Style,
with_decis: bool, with_decis: bool,
footer_state: FooterState, footer: FooterState,
} }
pub struct AppArgs { pub struct AppArgs {
@ -115,30 +115,27 @@ impl App {
app_time: get_app_time(), app_time: get_app_time(),
style, style,
with_decis, with_decis,
countdown: Countdown::new(Clock::<clock::Countdown>::new(ClockArgs { countdown: CountdownState::new(ClockState::<clock::Countdown>::new(ClockStateArgs {
initial_value: initial_value_countdown, initial_value: initial_value_countdown,
current_value: current_value_countdown, current_value: current_value_countdown,
tick_value: Duration::from_millis(TICK_VALUE_MS), tick_value: Duration::from_millis(TICK_VALUE_MS),
style,
with_decis, with_decis,
})), })),
timer: Timer::new(Clock::<clock::Timer>::new(ClockArgs { timer: TimerState::new(ClockState::<clock::Timer>::new(ClockStateArgs {
initial_value: Duration::ZERO, initial_value: Duration::ZERO,
current_value: current_value_timer, current_value: current_value_timer,
tick_value: Duration::from_millis(TICK_VALUE_MS), tick_value: Duration::from_millis(TICK_VALUE_MS),
style,
with_decis, with_decis,
})), })),
pomodoro: Pomodoro::new(PomodoroArgs { pomodoro: PomodoroState::new(PomodoroStateArgs {
mode: pomodoro_mode, mode: pomodoro_mode,
initial_value_work, initial_value_work,
current_value_work, current_value_work,
initial_value_pause, initial_value_pause,
current_value_pause, current_value_pause,
style,
with_decis, with_decis,
}), }),
footer_state: FooterState::new(show_menu, app_time_format), footer: FooterState::new(show_menu, app_time_format),
} }
} }
@ -204,17 +201,11 @@ impl App {
KeyCode::Char('t') => self.content = Content::Timer, KeyCode::Char('t') => self.content = Content::Timer,
KeyCode::Char('p') => self.content = Content::Pomodoro, KeyCode::Char('p') => self.content = Content::Pomodoro,
// toogle app time format // toogle app time format
KeyCode::Char(':') => self.footer_state.toggle_app_time_format(), KeyCode::Char(':') => self.footer.toggle_app_time_format(),
// toogle menu // toogle menu
KeyCode::Char('m') => self KeyCode::Char('m') => self.footer.set_show_menu(!self.footer.get_show_menu()),
.footer_state
.set_show_menu(!self.footer_state.get_show_menu()),
KeyCode::Char(',') => { KeyCode::Char(',') => {
self.style = self.style.next(); self.style = self.style.next();
// update clocks
self.timer.set_style(self.style);
self.countdown.set_style(self.style);
self.pomodoro.set_style(self.style);
} }
KeyCode::Char('.') => { KeyCode::Char('.') => {
self.with_decis = !self.with_decis; self.with_decis = !self.with_decis;
@ -223,8 +214,8 @@ impl App {
self.countdown.set_with_decis(self.with_decis); self.countdown.set_with_decis(self.with_decis);
self.pomodoro.set_with_decis(self.with_decis); self.pomodoro.set_with_decis(self.with_decis);
} }
KeyCode::Up => self.footer_state.set_show_menu(true), KeyCode::Up => self.footer.set_show_menu(true),
KeyCode::Down => self.footer_state.set_show_menu(false), KeyCode::Down => self.footer.set_show_menu(false),
_ => {} _ => {}
}; };
} }
@ -239,8 +230,8 @@ impl App {
pub fn to_storage(&self) -> AppStorage { pub fn to_storage(&self) -> AppStorage {
AppStorage { AppStorage {
content: self.content, content: self.content,
show_menu: self.footer_state.get_show_menu(), show_menu: self.footer.get_show_menu(),
app_time_format: *self.footer_state.app_time_format(), app_time_format: *self.footer.app_time_format(),
style: self.style, style: self.style,
with_decis: self.with_decis, with_decis: self.with_decis,
pomodoro_mode: self.pomodoro.get_mode().clone(), pomodoro_mode: self.pomodoro.get_mode().clone(),
@ -266,9 +257,15 @@ struct AppWidget;
impl AppWidget { impl AppWidget {
fn render_content(&self, area: Rect, buf: &mut Buffer, state: &mut App) { fn render_content(&self, area: Rect, buf: &mut Buffer, state: &mut App) {
match state.content { match state.content {
Content::Timer => TimerWidget.render(area, buf, &mut state.timer.clone()), Content::Timer => {
Content::Countdown => CountdownWidget.render(area, buf, &mut state.countdown.clone()), Timer { style: state.style }.render(area, buf, &mut state.timer);
Content::Pomodoro => PomodoroWidget.render(area, buf, &mut state.pomodoro.clone()), }
Content::Countdown => {
Countdown { style: state.style }.render(area, buf, &mut state.countdown)
}
Content::Pomodoro => {
PomodoroWidget { style: state.style }.render(area, buf, &mut state.pomodoro)
}
}; };
} }
} }
@ -279,11 +276,7 @@ impl StatefulWidget for AppWidget {
let [v0, v1, v2] = Layout::vertical([ let [v0, v1, v2] = Layout::vertical([
Constraint::Length(1), Constraint::Length(1),
Constraint::Percentage(100), Constraint::Percentage(100),
Constraint::Length(if state.footer_state.get_show_menu() { Constraint::Length(if state.footer.get_show_menu() { 4 } else { 1 }),
4
} else {
1
}),
]) ])
.areas(area); .areas(area);
@ -295,12 +288,12 @@ impl StatefulWidget for AppWidget {
// content // content
self.render_content(v1, buf, state); self.render_content(v1, buf, state);
// footer // footer
let footer = Footer { Footer {
running_clock: state.clock_is_running(), running_clock: state.clock_is_running(),
selected_content: state.content, selected_content: state.content,
edit_mode: state.is_edit_mode(), edit_mode: state.is_edit_mode(),
app_time: state.app_time, app_time: state.app_time,
}; }
StatefulWidget::render(footer, v2, buf, &mut state.footer_state); .render(v2, buf, &mut state.footer);
} }
} }

View File

@ -73,26 +73,24 @@ pub enum Format {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Clock<T> { pub struct ClockState<T> {
initial_value: DurationEx, initial_value: DurationEx,
current_value: DurationEx, current_value: DurationEx,
tick_value: DurationEx, tick_value: DurationEx,
mode: Mode, mode: Mode,
format: Format, format: Format,
pub style: Style,
pub with_decis: bool, pub with_decis: bool,
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
pub struct ClockArgs { pub struct ClockStateArgs {
pub initial_value: Duration, pub initial_value: Duration,
pub current_value: Duration, pub current_value: Duration,
pub tick_value: Duration, pub tick_value: Duration,
pub style: Style,
pub with_decis: bool, pub with_decis: bool,
} }
impl<T> Clock<T> { impl<T> ClockState<T> {
pub fn toggle_pause(&mut self) { pub fn toggle_pause(&mut self) {
self.mode = if self.mode == Mode::Tick { self.mode = if self.mode == Mode::Tick {
Mode::Pause Mode::Pause
@ -296,10 +294,6 @@ impl<T> Clock<T> {
self.update_format(); self.update_format();
} }
pub fn is_done(&self) -> bool {
self.mode == Mode::Done
}
fn update_format(&mut self) { fn update_format(&mut self) {
self.format = self.get_format(); self.format = self.get_format();
} }
@ -324,13 +318,12 @@ impl<T> Clock<T> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Countdown {} pub struct Countdown {}
impl Clock<Countdown> { impl ClockState<Countdown> {
pub fn new(args: ClockArgs) -> Self { pub fn new(args: ClockStateArgs) -> Self {
let ClockArgs { let ClockStateArgs {
initial_value, initial_value,
current_value, current_value,
tick_value, tick_value,
style,
with_decis, with_decis,
} = args; } = args;
let mut instance = Self { let mut instance = Self {
@ -345,7 +338,6 @@ impl Clock<Countdown> {
Mode::Pause Mode::Pause
}, },
format: Format::S, format: Format::S,
style,
with_decis, with_decis,
phantom: PhantomData, phantom: PhantomData,
}; };
@ -394,13 +386,12 @@ impl Clock<Countdown> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Timer {} pub struct Timer {}
impl Clock<Timer> { impl ClockState<Timer> {
pub fn new(args: ClockArgs) -> Self { pub fn new(args: ClockStateArgs) -> Self {
let ClockArgs { let ClockStateArgs {
initial_value, initial_value,
current_value, current_value,
tick_value, tick_value,
style,
with_decis, with_decis,
} = args; } = args;
let mut instance = Self { let mut instance = Self {
@ -416,7 +407,6 @@ impl Clock<Timer> {
}, },
format: Format::S, format: Format::S,
phantom: PhantomData, phantom: PhantomData,
style,
with_decis, with_decis,
}; };
// update format once // update format once
@ -461,6 +451,7 @@ pub struct ClockWidget<T>
where where
T: std::fmt::Debug, T: std::fmt::Debug,
{ {
style: Style,
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
@ -468,8 +459,9 @@ impl<T> ClockWidget<T>
where where
T: std::fmt::Debug, T: std::fmt::Debug,
{ {
pub fn new() -> Self { pub fn new(style: Style) -> Self {
Self { Self {
style,
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -568,12 +560,12 @@ impl<T> StatefulWidget for ClockWidget<T>
where where
T: std::fmt::Debug, T: std::fmt::Debug,
{ {
type State = Clock<T>; type State = ClockState<T>;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let with_decis = state.with_decis; let with_decis = state.with_decis;
let format = state.format; let format = state.format;
let symbol = state.style.get_digit_symbol(); let symbol = self.style.get_digit_symbol();
let widths = self.get_horizontal_lengths(&format, with_decis); let widths = self.get_horizontal_lengths(&format, with_decis);
let area = center_horizontal( let area = center_horizontal(
area, area,

View File

@ -1,5 +1,4 @@
use crate::{ use crate::{
common::Style,
duration::{ONE_DECI_SECOND, ONE_HOUR, ONE_MINUTE, ONE_SECOND}, duration::{ONE_DECI_SECOND, ONE_HOUR, ONE_MINUTE, ONE_SECOND},
widgets::clock::*, widgets::clock::*,
}; };
@ -7,11 +6,10 @@ use std::time::Duration;
#[test] #[test]
fn test_toggle_edit() { fn test_toggle_edit() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_HOUR, initial_value: ONE_HOUR,
current_value: ONE_HOUR, current_value: ONE_HOUR,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
// off by default // off by default
@ -26,11 +24,10 @@ fn test_toggle_edit() {
#[test] #[test]
fn test_default_edit_mode_hhmmss() { fn test_default_edit_mode_hhmmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_HOUR, initial_value: ONE_HOUR,
current_value: ONE_HOUR, current_value: ONE_HOUR,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
@ -41,11 +38,10 @@ fn test_default_edit_mode_hhmmss() {
#[test] #[test]
fn test_default_edit_mode_mmss() { fn test_default_edit_mode_mmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_MINUTE, initial_value: ONE_MINUTE,
current_value: ONE_MINUTE, current_value: ONE_MINUTE,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
// toggle on // toggle on
@ -55,11 +51,10 @@ fn test_default_edit_mode_mmss() {
#[test] #[test]
fn test_default_edit_mode_ss() { fn test_default_edit_mode_ss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_SECOND, initial_value: ONE_SECOND,
current_value: ONE_SECOND, current_value: ONE_SECOND,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
// toggle on // toggle on
@ -69,11 +64,10 @@ fn test_default_edit_mode_ss() {
#[test] #[test]
fn test_edit_next_hhmmssd() { fn test_edit_next_hhmmssd() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_HOUR, initial_value: ONE_HOUR,
current_value: ONE_HOUR, current_value: ONE_HOUR,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
@ -91,11 +85,10 @@ fn test_edit_next_hhmmssd() {
#[test] #[test]
fn test_edit_next_hhmmss() { fn test_edit_next_hhmmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_HOUR, initial_value: ONE_HOUR,
current_value: ONE_HOUR, current_value: ONE_HOUR,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -111,11 +104,10 @@ fn test_edit_next_hhmmss() {
#[test] #[test]
fn test_edit_next_mmssd() { fn test_edit_next_mmssd() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_MINUTE, initial_value: ONE_MINUTE,
current_value: ONE_MINUTE, current_value: ONE_MINUTE,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
@ -131,11 +123,10 @@ fn test_edit_next_mmssd() {
#[test] #[test]
fn test_edit_next_mmss() { fn test_edit_next_mmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_MINUTE, initial_value: ONE_MINUTE,
current_value: ONE_MINUTE, current_value: ONE_MINUTE,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -149,11 +140,10 @@ fn test_edit_next_mmss() {
#[test] #[test]
fn test_edit_next_ssd() { fn test_edit_next_ssd() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_SECOND * 3, initial_value: ONE_SECOND * 3,
current_value: ONE_SECOND * 3, current_value: ONE_SECOND * 3,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
@ -165,11 +155,10 @@ fn test_edit_next_ssd() {
#[test] #[test]
fn test_edit_next_ss() { fn test_edit_next_ss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_SECOND * 3, initial_value: ONE_SECOND * 3,
current_value: ONE_SECOND * 3, current_value: ONE_SECOND * 3,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -182,11 +171,10 @@ fn test_edit_next_ss() {
#[test] #[test]
fn test_edit_prev_hhmmssd() { fn test_edit_prev_hhmmssd() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_HOUR, initial_value: ONE_HOUR,
current_value: ONE_HOUR, current_value: ONE_HOUR,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
@ -203,11 +191,10 @@ fn test_edit_prev_hhmmssd() {
#[test] #[test]
fn test_edit_prev_hhmmss() { fn test_edit_prev_hhmmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_HOUR, initial_value: ONE_HOUR,
current_value: ONE_HOUR, current_value: ONE_HOUR,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -222,11 +209,10 @@ fn test_edit_prev_hhmmss() {
#[test] #[test]
fn test_edit_prev_mmssd() { fn test_edit_prev_mmssd() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_MINUTE, initial_value: ONE_MINUTE,
current_value: ONE_MINUTE, current_value: ONE_MINUTE,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
@ -243,11 +229,10 @@ fn test_edit_prev_mmssd() {
#[test] #[test]
fn test_edit_prev_mmss() { fn test_edit_prev_mmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_MINUTE, initial_value: ONE_MINUTE,
current_value: ONE_MINUTE, current_value: ONE_MINUTE,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -262,11 +247,10 @@ fn test_edit_prev_mmss() {
#[test] #[test]
fn test_edit_prev_ssd() { fn test_edit_prev_ssd() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_SECOND, initial_value: ONE_SECOND,
current_value: ONE_SECOND, current_value: ONE_SECOND,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: true, with_decis: true,
}); });
@ -281,11 +265,10 @@ fn test_edit_prev_ssd() {
#[test] #[test]
fn test_edit_prev_ss() { fn test_edit_prev_ss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: ONE_SECOND, initial_value: ONE_SECOND,
current_value: ONE_SECOND, current_value: ONE_SECOND,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -298,11 +281,10 @@ fn test_edit_prev_ss() {
#[test] #[test]
fn test_edit_up_ss() { fn test_edit_up_ss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: Duration::ZERO, initial_value: Duration::ZERO,
current_value: Duration::ZERO, current_value: Duration::ZERO,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -315,11 +297,10 @@ fn test_edit_up_ss() {
#[test] #[test]
fn test_edit_up_mmss() { fn test_edit_up_mmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: Duration::ZERO, initial_value: Duration::ZERO,
current_value: Duration::from_secs(60), current_value: Duration::from_secs(60),
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -335,11 +316,10 @@ fn test_edit_up_mmss() {
#[test] #[test]
fn test_edit_up_hhmmss() { fn test_edit_up_hhmmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: Duration::ZERO, initial_value: Duration::ZERO,
current_value: Duration::from_secs(3600), current_value: Duration::from_secs(3600),
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -357,11 +337,10 @@ fn test_edit_up_hhmmss() {
#[test] #[test]
fn test_edit_down_ss() { fn test_edit_down_ss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: Duration::ZERO, initial_value: Duration::ZERO,
current_value: ONE_SECOND, current_value: ONE_SECOND,
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -378,11 +357,10 @@ fn test_edit_down_ss() {
#[test] #[test]
fn test_edit_down_mmss() { fn test_edit_down_mmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: Duration::ZERO, initial_value: Duration::ZERO,
current_value: Duration::from_secs(120), current_value: Duration::from_secs(120),
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });
@ -401,11 +379,10 @@ fn test_edit_down_mmss() {
#[test] #[test]
fn test_edit_down_hhmmss() { fn test_edit_down_hhmmss() {
let mut c = Clock::<Timer>::new(ClockArgs { let mut c = ClockState::<Timer>::new(ClockStateArgs {
initial_value: Duration::ZERO, initial_value: Duration::ZERO,
current_value: Duration::from_secs(3600), current_value: Duration::from_secs(3600),
tick_value: ONE_DECI_SECOND, tick_value: ONE_DECI_SECOND,
style: Style::default(),
with_decis: false, with_decis: false,
}); });

View File

@ -11,33 +11,29 @@ use crate::{
common::Style, common::Style,
events::{Event, EventHandler}, events::{Event, EventHandler},
utils::center, utils::center,
widgets::clock::{self, Clock, ClockWidget}, widgets::clock::{self, ClockState, ClockWidget},
}; };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Countdown { pub struct CountdownState {
clock: Clock<clock::Countdown>, clock: ClockState<clock::Countdown>,
} }
impl Countdown { impl CountdownState {
pub const fn new(clock: Clock<clock::Countdown>) -> Self { pub const fn new(clock: ClockState<clock::Countdown>) -> Self {
Self { clock } Self { clock }
} }
pub fn set_style(&mut self, style: Style) {
self.clock.style = style;
}
pub fn set_with_decis(&mut self, with_decis: bool) { pub fn set_with_decis(&mut self, with_decis: bool) {
self.clock.with_decis = with_decis; self.clock.with_decis = with_decis;
} }
pub fn get_clock(&self) -> &Clock<clock::Countdown> { pub fn get_clock(&self) -> &ClockState<clock::Countdown> {
&self.clock &self.clock
} }
} }
impl EventHandler for Countdown { impl EventHandler for CountdownState {
fn update(&mut self, event: Event) -> Option<Event> { fn update(&mut self, event: Event) -> Option<Event> {
let edit_mode = self.clock.is_edit_mode(); let edit_mode = self.clock.is_edit_mode();
match event { match event {
@ -77,12 +73,14 @@ impl EventHandler for Countdown {
} }
} }
pub struct CountdownWidget; pub struct Countdown {
pub style: Style,
}
impl StatefulWidget for CountdownWidget { impl StatefulWidget for Countdown {
type State = Countdown; type State = CountdownState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let clock = ClockWidget::new(); let clock = ClockWidget::new(self.style);
let label = Line::raw((format!("Countdown {}", state.clock.get_mode())).to_uppercase()); let label = Line::raw((format!("Countdown {}", state.clock.get_mode())).to_uppercase());
let area = center( let area = center(

View File

@ -3,7 +3,7 @@ use crate::{
constants::TICK_VALUE_MS, constants::TICK_VALUE_MS,
events::{Event, EventHandler}, events::{Event, EventHandler},
utils::center, utils::center,
widgets::clock::{Clock, ClockWidget, Countdown}, widgets::clock::{ClockState, ClockWidget, Countdown},
}; };
use ratatui::{ use ratatui::{
buffer::Buffer, buffer::Buffer,
@ -18,7 +18,7 @@ use strum::Display;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::clock::ClockArgs; use super::clock::ClockStateArgs;
#[derive(Debug, Clone, Display, Hash, Eq, PartialEq, Deserialize, Serialize)] #[derive(Debug, Clone, Display, Hash, Eq, PartialEq, Deserialize, Serialize)]
pub enum Mode { pub enum Mode {
@ -28,18 +28,18 @@ pub enum Mode {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ClockMap { pub struct ClockMap {
work: Clock<Countdown>, work: ClockState<Countdown>,
pause: Clock<Countdown>, pause: ClockState<Countdown>,
} }
impl ClockMap { impl ClockMap {
fn get_mut(&mut self, mode: &Mode) -> &mut Clock<Countdown> { fn get_mut(&mut self, mode: &Mode) -> &mut ClockState<Countdown> {
match mode { match mode {
Mode::Work => &mut self.work, Mode::Work => &mut self.work,
Mode::Pause => &mut self.pause, Mode::Pause => &mut self.pause,
} }
} }
fn get(&self, mode: &Mode) -> &Clock<Countdown> { fn get(&self, mode: &Mode) -> &ClockState<Countdown> {
match mode { match mode {
Mode::Work => &self.work, Mode::Work => &self.work,
Mode::Pause => &self.pause, Mode::Pause => &self.pause,
@ -48,66 +48,62 @@ impl ClockMap {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Pomodoro { pub struct PomodoroState {
mode: Mode, mode: Mode,
clock_map: ClockMap, clock_map: ClockMap,
} }
pub struct PomodoroArgs { pub struct PomodoroStateArgs {
pub mode: Mode, pub mode: Mode,
pub initial_value_work: Duration, pub initial_value_work: Duration,
pub current_value_work: Duration, pub current_value_work: Duration,
pub initial_value_pause: Duration, pub initial_value_pause: Duration,
pub current_value_pause: Duration, pub current_value_pause: Duration,
pub style: Style,
pub with_decis: bool, pub with_decis: bool,
} }
impl Pomodoro { impl PomodoroState {
pub fn new(args: PomodoroArgs) -> Self { pub fn new(args: PomodoroStateArgs) -> Self {
let PomodoroArgs { let PomodoroStateArgs {
mode, mode,
initial_value_work, initial_value_work,
current_value_work, current_value_work,
initial_value_pause, initial_value_pause,
current_value_pause, current_value_pause,
style,
with_decis, with_decis,
} = args; } = args;
Self { Self {
mode, mode,
clock_map: ClockMap { clock_map: ClockMap {
work: Clock::<Countdown>::new(ClockArgs { work: ClockState::<Countdown>::new(ClockStateArgs {
initial_value: initial_value_work, initial_value: initial_value_work,
current_value: current_value_work, current_value: current_value_work,
tick_value: Duration::from_millis(TICK_VALUE_MS), tick_value: Duration::from_millis(TICK_VALUE_MS),
style,
with_decis, with_decis,
}), }),
pause: Clock::<Countdown>::new(ClockArgs { pause: ClockState::<Countdown>::new(ClockStateArgs {
initial_value: initial_value_pause, initial_value: initial_value_pause,
current_value: current_value_pause, current_value: current_value_pause,
tick_value: Duration::from_millis(TICK_VALUE_MS), tick_value: Duration::from_millis(TICK_VALUE_MS),
style,
with_decis, with_decis,
}), }),
}, },
} }
} }
fn get_clock_mut(&mut self) -> &mut Clock<Countdown> { fn get_clock_mut(&mut self) -> &mut ClockState<Countdown> {
self.clock_map.get_mut(&self.mode) self.clock_map.get_mut(&self.mode)
} }
pub fn get_clock(&self) -> &Clock<Countdown> { pub fn get_clock(&self) -> &ClockState<Countdown> {
self.clock_map.get(&self.mode) self.clock_map.get(&self.mode)
} }
pub fn get_clock_work(&self) -> &Clock<Countdown> { pub fn get_clock_work(&self) -> &ClockState<Countdown> {
&self.clock_map.work &self.clock_map.work
} }
pub fn get_clock_pause(&self) -> &Clock<Countdown> { pub fn get_clock_pause(&self) -> &ClockState<Countdown> {
&self.clock_map.pause &self.clock_map.pause
} }
@ -115,11 +111,6 @@ impl Pomodoro {
&self.mode &self.mode
} }
pub fn set_style(&mut self, style: Style) {
self.clock_map.work.style = style;
self.clock_map.pause.style = style;
}
pub fn set_with_decis(&mut self, with_decis: bool) { pub fn set_with_decis(&mut self, with_decis: bool) {
self.clock_map.work.with_decis = with_decis; self.clock_map.work.with_decis = with_decis;
self.clock_map.pause.with_decis = with_decis; self.clock_map.pause.with_decis = with_decis;
@ -133,7 +124,7 @@ impl Pomodoro {
} }
} }
impl EventHandler for Pomodoro { impl EventHandler for PomodoroState {
fn update(&mut self, event: Event) -> Option<Event> { fn update(&mut self, event: Event) -> Option<Event> {
let edit_mode = self.get_clock().is_edit_mode(); let edit_mode = self.get_clock().is_edit_mode();
match event { match event {
@ -177,12 +168,14 @@ impl EventHandler for Pomodoro {
} }
} }
pub struct PomodoroWidget; pub struct PomodoroWidget {
pub style: Style,
}
impl StatefulWidget for PomodoroWidget { impl StatefulWidget for PomodoroWidget {
type State = Pomodoro; type State = PomodoroState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let clock_widget = ClockWidget::new(); let clock_widget = ClockWidget::new(self.style);
let label = Line::raw( let label = Line::raw(
(format!( (format!(
"Pomodoro {} {}", "Pomodoro {} {}",

View File

@ -2,7 +2,7 @@ use crate::{
common::Style, common::Style,
events::{Event, EventHandler}, events::{Event, EventHandler},
utils::center, utils::center,
widgets::clock::{self, Clock, ClockWidget}, widgets::clock::{self, ClockState, ClockWidget},
}; };
use ratatui::{ use ratatui::{
buffer::Buffer, buffer::Buffer,
@ -14,29 +14,25 @@ use ratatui::{
use std::cmp::max; use std::cmp::max;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Timer { pub struct TimerState {
clock: Clock<clock::Timer>, clock: ClockState<clock::Timer>,
} }
impl Timer { impl TimerState {
pub const fn new(clock: Clock<clock::Timer>) -> Self { pub const fn new(clock: ClockState<clock::Timer>) -> Self {
Self { clock } Self { clock }
} }
pub fn set_style(&mut self, style: Style) {
self.clock.style = style;
}
pub fn set_with_decis(&mut self, with_decis: bool) { pub fn set_with_decis(&mut self, with_decis: bool) {
self.clock.with_decis = with_decis; self.clock.with_decis = with_decis;
} }
pub fn get_clock(&self) -> &Clock<clock::Timer> { pub fn get_clock(&self) -> &ClockState<clock::Timer> {
&self.clock &self.clock
} }
} }
impl EventHandler for Timer { impl EventHandler for TimerState {
fn update(&mut self, event: Event) -> Option<Event> { fn update(&mut self, event: Event) -> Option<Event> {
let edit_mode = self.clock.is_edit_mode(); let edit_mode = self.clock.is_edit_mode();
match event { match event {
@ -73,13 +69,15 @@ impl EventHandler for Timer {
} }
} }
pub struct TimerWidget; pub struct Timer {
pub style: Style,
}
impl StatefulWidget for &TimerWidget { impl StatefulWidget for Timer {
type State = Timer; type State = TimerState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let clock = &mut state.clock; let clock = &mut state.clock;
let clock_widget = ClockWidget::new(); let clock_widget = ClockWidget::new(self.style);
let label = Line::raw((format!("Timer {}", clock.get_mode())).to_uppercase()); let label = Line::raw((format!("Timer {}", clock.get_mode())).to_uppercase());
let area = center( let area = center(