From d705f20e2d4c93a702d57fc236aef51f6bd41245 Mon Sep 17 00:00:00 2001 From: "Jens K." <47693+sectore@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:50:26 +0100 Subject: [PATCH] deciseconds (#19) --- src/app.rs | 53 +++-- src/widgets/clock.rs | 417 ++++++++++++++++++++++++++++++--------- src/widgets/countdown.rs | 16 +- src/widgets/pomodoro.rs | 45 ++++- src/widgets/timer.rs | 21 +- 5 files changed, 418 insertions(+), 134 deletions(-) diff --git a/src/app.rs b/src/app.rs index 48aed1e..018753a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4,7 +4,7 @@ use crate::{ events::{Event, EventHandler, Events}, terminal::Terminal, widgets::{ - clock::{self, Clock, Style as ClockStyle}, + clock::{self, Clock, ClockArgs, Style as ClockStyle}, countdown::{Countdown, CountdownWidget}, footer::Footer, header::Header, @@ -44,6 +44,7 @@ pub struct App { timer: Timer, pomodoro: Pomodoro, clock_style: ClockStyle, + with_decis: bool, } impl App { @@ -53,17 +54,24 @@ impl App { content: Content::Countdown, show_menu: false, clock_style: ClockStyle::Default, - countdown: Countdown::new(Clock::::new( - args.countdown, - Duration::from_millis(TICK_VALUE_MS), - )), - timer: Timer::new(Clock::::new( - Duration::ZERO, - Duration::from_millis(TICK_VALUE_MS), - )), + with_decis: false, + countdown: Countdown::new(Clock::::new(ClockArgs { + initial_value: args.countdown, + tick_value: Duration::from_millis(TICK_VALUE_MS), + style: ClockStyle::Default, + with_decis: false, + })), + timer: Timer::new(Clock::::new(ClockArgs { + initial_value: Duration::ZERO, + tick_value: Duration::from_millis(TICK_VALUE_MS), + style: ClockStyle::Default, + with_decis: false, + })), pomodoro: Pomodoro::new(PomodoroArgs { work: args.work, pause: args.pause, + style: ClockStyle::Default, + with_decis: false, }), } } @@ -102,7 +110,20 @@ impl App { KeyCode::Char('t') => self.content = Content::Timer, KeyCode::Char('p') => self.content = Content::Pomodoro, KeyCode::Char('m') => self.show_menu = !self.show_menu, - KeyCode::Char('b') => self.clock_style = self.clock_style.next(), + KeyCode::Char(',') => { + self.clock_style = self.clock_style.next(); + // update clocks + self.timer.set_style(self.clock_style); + self.countdown.set_style(self.clock_style); + self.pomodoro.set_style(self.clock_style); + } + KeyCode::Char('.') => { + self.with_decis = !self.with_decis; + // update clocks + self.timer.set_with_decis(self.with_decis); + self.countdown.set_with_decis(self.with_decis); + self.pomodoro.set_with_decis(self.with_decis); + } KeyCode::Up => self.show_menu = true, KeyCode::Down => self.show_menu = false, _ => {} @@ -122,15 +143,9 @@ struct AppWidget; impl AppWidget { fn render_content(&self, area: Rect, buf: &mut Buffer, state: &mut App) { match state.content { - Content::Timer => { - TimerWidget.render(area, buf, &mut (state.clock_style, state.timer.clone())) - } - Content::Countdown => { - CountdownWidget.render(area, buf, &mut (state.clock_style, state.countdown.clone())) - } - Content::Pomodoro => { - PomodoroWidget.render(area, buf, &mut (state.clock_style, state.pomodoro.clone())) - } + Content::Timer => TimerWidget.render(area, buf, &mut state.timer.clone()), + Content::Countdown => CountdownWidget.render(area, buf, &mut state.countdown.clone()), + Content::Pomodoro => PomodoroWidget.render(area, buf, &mut state.pomodoro.clone()), }; } } diff --git a/src/widgets/clock.rs b/src/widgets/clock.rs index 3fc14bb..2e0c50c 100644 --- a/src/widgets/clock.rs +++ b/src/widgets/clock.rs @@ -100,9 +100,18 @@ pub struct Clock { current_value: Duration, mode: Mode, format: Format, + pub style: Style, + pub with_decis: bool, phantom: PhantomData, } +pub struct ClockArgs { + pub initial_value: Duration, + pub tick_value: Duration, + pub style: Style, + pub with_decis: bool, +} + impl Clock { pub fn toggle_pause(&mut self) { self.mode = if self.mode == Mode::Tick { @@ -275,8 +284,9 @@ impl Clock { self.current_seconds() % SECS_PER_MINUTE } - fn current_tenths(&self) -> u32 { - self.current_value.subsec_millis() / 100 + // deciseconds + fn current_decis(&self) -> u64 { + (self.current_value.subsec_millis() / 100) as u64 } pub fn is_done(&mut self) -> bool { @@ -312,7 +322,7 @@ impl fmt::Display for Clock { self.current_hours_mod(), self.current_minutes_mod(), self.current_seconds_mod(), - self.current_tenths() + self.current_decis() ) } } @@ -321,13 +331,21 @@ impl fmt::Display for Clock { pub struct Countdown {} impl Clock { - pub fn new(initial_value: Duration, tick_value: Duration) -> Self { + pub fn new(args: ClockArgs) -> Self { + let ClockArgs { + initial_value, + tick_value, + style, + with_decis, + } = args; let mut instance = Self { initial_value, tick_value, current_value: initial_value, mode: Mode::Initial, format: Format::S, + style, + with_decis, phantom: PhantomData, }; // update format once @@ -378,7 +396,13 @@ impl Clock { pub struct Timer {} impl Clock { - pub fn new(initial_value: Duration, tick_value: Duration) -> Self { + pub fn new(args: ClockArgs) -> Self { + let ClockArgs { + initial_value, + tick_value, + style, + with_decis, + } = args; let mut instance = Self { initial_value, tick_value, @@ -386,6 +410,8 @@ impl Clock { mode: Mode::Initial, format: Format::S, phantom: PhantomData, + style, + with_decis, }; // update format once instance.update_format(); @@ -532,7 +558,6 @@ pub struct ClockWidget where T: std::fmt::Debug, { - style: Style, phantom: PhantomData, } @@ -540,15 +565,14 @@ impl ClockWidget where T: std::fmt::Debug, { - pub fn new(style: Style) -> Self { + pub fn new() -> Self { Self { - style, phantom: PhantomData, } } - fn get_digit_symbol(&self) -> &str { - match &self.style { + fn get_digit_symbol(&self, style: &Style) -> &str { + match &style { Style::Default => "█", Style::Empty => "░", Style::Cross => "╬", @@ -556,68 +580,103 @@ where } } - fn get_horizontal_lengths(&self, format: &Format) -> Vec { + fn get_horizontal_lengths(&self, format: &Format, with_decis: bool) -> Vec { + let add_decis = |mut lengths: Vec, with_decis: bool| -> Vec { + if with_decis { + lengths.extend_from_slice(&[ + COLON_WIDTH, // . + DIGIT_WIDTH, // ds + ]) + } + lengths + }; + match format { - Format::HhMmSs => vec![ - DIGIT_WIDTH, // h - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // h - COLON_WIDTH, // : - DIGIT_WIDTH, // m - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // m - COLON_WIDTH, // : - DIGIT_WIDTH, // s - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // s - ], - Format::HMmSs => vec![ - DIGIT_WIDTH, // h - COLON_WIDTH, // : - DIGIT_WIDTH, // m - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // m - COLON_WIDTH, // : - DIGIT_WIDTH, // s - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // s - ], - Format::MmSs => vec![ - DIGIT_WIDTH, // m - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // m - COLON_WIDTH, // : - DIGIT_WIDTH, // s - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // s - ], - Format::MSs => vec![ - DIGIT_WIDTH, // m - COLON_WIDTH, // : - DIGIT_WIDTH, // s - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // s - ], - Format::Ss => vec![ - DIGIT_WIDTH, // s - SPACE_WIDTH, // (space) - DIGIT_WIDTH, // s - ], - Format::S => vec![ - DIGIT_WIDTH, // s - ], + Format::HhMmSs => add_decis( + vec![ + DIGIT_WIDTH, // h + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // h + COLON_WIDTH, // : + DIGIT_WIDTH, // m + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // m + COLON_WIDTH, // : + DIGIT_WIDTH, // s + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // s + ], + with_decis, + ), + Format::HMmSs => add_decis( + vec![ + DIGIT_WIDTH, // h + COLON_WIDTH, // : + DIGIT_WIDTH, // m + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // m + COLON_WIDTH, // : + DIGIT_WIDTH, // s + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // s + ], + with_decis, + ), + Format::MmSs => add_decis( + vec![ + DIGIT_WIDTH, // m + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // m + COLON_WIDTH, // : + DIGIT_WIDTH, // s + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // s + ], + with_decis, + ), + Format::MSs => add_decis( + vec![ + DIGIT_WIDTH, // m + COLON_WIDTH, // : + DIGIT_WIDTH, // s + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // s + ], + with_decis, + ), + Format::Ss => add_decis( + vec![ + DIGIT_WIDTH, // s + SPACE_WIDTH, // (space) + DIGIT_WIDTH, // s + ], + with_decis, + ), + Format::S => add_decis( + vec![ + DIGIT_WIDTH, // s + ], + with_decis, + ), } } - pub fn get_width(&self, format: &Format) -> u16 { - self.get_horizontal_lengths(format).iter().sum() + pub fn get_width(&self, format: &Format, with_decis: bool) -> u16 { + self.get_horizontal_lengths(format, with_decis).iter().sum() } pub fn get_height(&self) -> u16 { DIGIT_HEIGHT } - fn render_digit(&self, number: u64, with_border: bool, area: Rect, buf: &mut Buffer) { + fn render_digit( + &self, + number: u64, + symbol: &str, + with_border: bool, + area: Rect, + buf: &mut Buffer, + ) { let left = area.left(); let top = area.top(); @@ -644,7 +703,7 @@ where y: top + y as u16, }; if let Some(cell) = buf.cell_mut(p) { - cell.set_symbol(self.get_digit_symbol()); + cell.set_symbol(symbol); } } }); @@ -663,7 +722,7 @@ where } } - fn render_colon(&self, area: Rect, buf: &mut Buffer) { + fn render_colon(&self, symbol: &str, area: Rect, buf: &mut Buffer) { let left = area.left(); let top = area.top(); @@ -688,7 +747,26 @@ where for pos in positions { if let Some(cell) = buf.cell_mut(pos) { - cell.set_symbol(self.get_digit_symbol()); + cell.set_symbol(symbol); + } + } + } + + fn render_dot(&self, symbol: &str, area: Rect, buf: &mut Buffer) { + let positions = [ + Position { + x: area.left() + 1, + y: area.top() + area.height - 2, + }, + Position { + x: area.left() + 2, + y: area.top() + area.height - 2, + }, + ]; + + for pos in positions { + if let Some(cell) = buf.cell_mut(pos) { + cell.set_symbol(symbol); } } } @@ -701,61 +779,212 @@ where type State = Clock; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { + let with_decis = state.with_decis; let format = state.format; - let widths = self.get_horizontal_lengths(&format); - let area = center_horizontal(area, Constraint::Length(self.get_width(&format))); + let symbol = self.get_digit_symbol(&state.style); + let widths = self.get_horizontal_lengths(&format, with_decis); + let area = center_horizontal( + area, + Constraint::Length(self.get_width(&format, with_decis)), + ); let edit_hours = matches!(state.mode, Mode::Editable(Time::Hours, _)); let edit_minutes = matches!(state.mode, Mode::Editable(Time::Minutes, _)); let edit_secs = matches!(state.mode, Mode::Editable(Time::Seconds, _)); match format { + Format::HhMmSs if with_decis => { + let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] = + Layout::horizontal(Constraint::from_lengths(widths)).areas(area); + self.render_digit(state.current_hours() / 10, symbol, edit_hours, hh, buf); + self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_colon(symbol, c_hm, buf); + self.render_digit( + state.current_minutes_mod() / 10, + symbol, + edit_minutes, + mm, + buf, + ); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_dot(symbol, d, buf); + self.render_digit(state.current_decis(), symbol, false, ds, buf); + } Format::HhMmSs => { let [hh, _, h, c_hm, mm, _, m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_hours() / 10, edit_hours, hh, buf); - self.render_digit(state.current_hours() % 10, edit_hours, h, buf); - self.render_colon(c_hm, buf); - self.render_digit(state.current_minutes_mod() / 10, edit_minutes, mm, buf); - self.render_digit(state.current_minutes_mod() % 10, edit_minutes, m, buf); - self.render_colon(c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, edit_secs, s, buf); + self.render_digit(state.current_hours() / 10, symbol, edit_hours, hh, buf); + self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_colon(symbol, c_hm, buf); + self.render_digit( + state.current_minutes_mod() / 10, + symbol, + edit_minutes, + mm, + buf, + ); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + } + Format::HMmSs if with_decis => { + let [h, c_hm, mm, _, m, c_ms, ss, _, s, d, ds] = + Layout::horizontal(Constraint::from_lengths(widths)).areas(area); + self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_colon(symbol, c_hm, buf); + self.render_digit( + state.current_minutes_mod() / 10, + symbol, + edit_minutes, + mm, + buf, + ); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_dot(symbol, d, buf); + self.render_digit(state.current_decis(), symbol, false, ds, buf); } Format::HMmSs => { let [h, c_hm, mm, _, m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_hours() % 10, edit_hours, h, buf); - self.render_colon(c_hm, buf); - self.render_digit(state.current_minutes_mod() / 10, edit_minutes, mm, buf); - self.render_digit(state.current_minutes_mod() % 10, edit_minutes, m, buf); - self.render_colon(c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, edit_secs, s, buf); + self.render_digit(state.current_hours() % 10, symbol, edit_hours, h, buf); + self.render_colon(symbol, c_hm, buf); + self.render_digit( + state.current_minutes_mod() / 10, + symbol, + edit_minutes, + mm, + buf, + ); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + } + Format::MmSs if with_decis => { + let [mm, _, m, c_ms, ss, _, s, d, ds] = + Layout::horizontal(Constraint::from_lengths(widths)).areas(area); + self.render_digit( + state.current_minutes_mod() / 10, + symbol, + edit_minutes, + mm, + buf, + ); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_dot(symbol, d, buf); + self.render_digit(state.current_decis(), symbol, false, ds, buf); } Format::MmSs => { let [mm, _, m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_minutes_mod() / 10, edit_minutes, mm, buf); - self.render_digit(state.current_minutes_mod() % 10, edit_minutes, m, buf); - self.render_colon(c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, edit_secs, s, buf); + self.render_digit( + state.current_minutes_mod() / 10, + symbol, + edit_minutes, + mm, + buf, + ); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + } + Format::MSs if with_decis => { + let [m, c_ms, ss, _, s, d, ds] = + Layout::horizontal(Constraint::from_lengths(widths)).areas(area); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_dot(symbol, d, buf); + self.render_digit(state.current_decis(), symbol, false, ds, buf); } Format::MSs => { let [m, c_ms, ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_minutes_mod() % 10, edit_minutes, m, buf); - self.render_colon(c_ms, buf); - self.render_digit(state.current_seconds_mod() / 10, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, edit_secs, s, buf); + self.render_digit( + state.current_minutes_mod() % 10, + symbol, + edit_minutes, + m, + buf, + ); + self.render_colon(symbol, c_ms, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + } + Format::Ss if state.with_decis => { + let [ss, _, s, d, ds] = + Layout::horizontal(Constraint::from_lengths(widths)).areas(area); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_dot(symbol, d, buf); + self.render_digit(state.current_decis(), symbol, false, ds, buf); } Format::Ss => { let [ss, _, s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_seconds_mod() / 10, edit_secs, ss, buf); - self.render_digit(state.current_seconds_mod() % 10, edit_secs, s, buf); + self.render_digit(state.current_seconds_mod() / 10, symbol, edit_secs, ss, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + } + Format::S if with_decis => { + let [s, d, ds] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); + self.render_dot(symbol, d, buf); + self.render_digit(state.current_decis(), symbol, false, ds, buf); } Format::S => { let [s] = Layout::horizontal(Constraint::from_lengths(widths)).areas(area); - self.render_digit(state.current_seconds_mod() % 10, edit_secs, s, buf); + self.render_digit(state.current_seconds_mod() % 10, symbol, edit_secs, s, buf); } } } diff --git a/src/widgets/countdown.rs b/src/widgets/countdown.rs index 975c81f..dc8bf06 100644 --- a/src/widgets/countdown.rs +++ b/src/widgets/countdown.rs @@ -24,6 +24,14 @@ impl Countdown { pub const fn new(clock: Clock) -> 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; + } } impl EventHandler for Countdown { @@ -69,17 +77,15 @@ impl EventHandler for Countdown { pub struct CountdownWidget; impl StatefulWidget for CountdownWidget { - type State = (Style, Countdown); + type State = Countdown; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { - let style = state.0; - let state = &mut state.1; - let clock = ClockWidget::new(style); + let clock = ClockWidget::new(); let label = Line::raw((format!("Countdown {}", state.clock.get_mode())).to_uppercase()); let area = center( area, Constraint::Length(max( - clock.get_width(&state.clock.get_format()), + clock.get_width(&state.clock.get_format(), state.clock.with_decis), label.width() as u16, )), Constraint::Length(clock.get_height() + 1 /* height of label */), diff --git a/src/widgets/pomodoro.rs b/src/widgets/pomodoro.rs index 3b9caf4..8cd4435 100644 --- a/src/widgets/pomodoro.rs +++ b/src/widgets/pomodoro.rs @@ -15,7 +15,7 @@ use std::{cmp::max, time::Duration}; use strum::Display; -use super::clock::Style; +use super::clock::{ClockArgs, Style}; #[derive(Debug, Clone, Display, Hash, Eq, PartialEq)] enum Mode { @@ -47,15 +47,33 @@ pub struct Pomodoro { pub struct PomodoroArgs { pub work: Duration, pub pause: Duration, + pub style: Style, + pub with_decis: bool, } impl Pomodoro { pub fn new(args: PomodoroArgs) -> Self { + let PomodoroArgs { + work, + pause, + style, + with_decis, + } = args; Self { mode: Mode::Work, clock_map: ClockMap { - work: Clock::::new(args.work, Duration::from_millis(TICK_VALUE_MS)), - pause: Clock::::new(args.pause, Duration::from_millis(TICK_VALUE_MS)), + work: Clock::::new(ClockArgs { + initial_value: work, + tick_value: Duration::from_millis(TICK_VALUE_MS), + style, + with_decis, + }), + pause: Clock::::new(ClockArgs { + initial_value: pause, + tick_value: Duration::from_millis(TICK_VALUE_MS), + style, + with_decis, + }), }, } } @@ -64,6 +82,16 @@ impl Pomodoro { self.clock_map.get(&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; + } + pub fn next(&mut self) { self.mode = match self.mode { Mode::Pause => Mode::Work, @@ -119,11 +147,9 @@ impl EventHandler for Pomodoro { pub struct PomodoroWidget; impl StatefulWidget for PomodoroWidget { - type State = (Style, Pomodoro); + type State = Pomodoro; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { - let style = state.0; - let state = &mut state.1; - let clock_widget = ClockWidget::new(style); + let clock_widget = ClockWidget::new(); let label = Line::raw( (format!( "Pomodoro {} {}", @@ -136,7 +162,10 @@ impl StatefulWidget for PomodoroWidget { let area = center( area, Constraint::Length(max( - clock_widget.get_width(&state.get_clock().get_format()), + clock_widget.get_width( + &state.get_clock().get_format(), + state.get_clock().with_decis, + ), label.width() as u16, )), Constraint::Length(clock_widget.get_height() + 1 /* height of mode_str */), diff --git a/src/widgets/timer.rs b/src/widgets/timer.rs index d2eb8bc..b133cea 100644 --- a/src/widgets/timer.rs +++ b/src/widgets/timer.rs @@ -1,7 +1,7 @@ use crate::{ events::{Event, EventHandler}, utils::center, - widgets::clock::{self, Clock, ClockWidget}, + widgets::clock::{self, Clock, ClockWidget, Style}, }; use ratatui::{ buffer::Buffer, @@ -12,8 +12,6 @@ use ratatui::{ }; use std::cmp::max; -use super::clock::Style; - #[derive(Debug, Clone)] pub struct Timer { clock: Clock, @@ -23,6 +21,14 @@ impl Timer { pub const fn new(clock: Clock) -> 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; + } } impl EventHandler for Timer { @@ -65,17 +71,16 @@ impl EventHandler for Timer { pub struct TimerWidget; impl StatefulWidget for &TimerWidget { - type State = (Style, Timer); + type State = Timer; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { - let style = state.0; - let clock = &mut state.1.clock; - let clock_widget = ClockWidget::new(style); + let clock = &mut state.clock; + let clock_widget = ClockWidget::new(); let label = Line::raw((format!("Timer {}", clock.get_mode())).to_uppercase()); let area = center( area, Constraint::Length(max( - clock_widget.get_width(&clock.get_format()), + clock_widget.get_width(&clock.get_format(), clock.with_decis), label.width() as u16, )), Constraint::Length(clock_widget.get_height() + 1 /* height of label */),