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
6 changed files with 116 additions and 165 deletions

View File

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

View File

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

View File

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

View File

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

View File

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