use iced::widget::{button, text}; use iced::{Element, Task}; use crate::module::{BarModule, ModuleMsg}; use crate::subscriptions::clock::{ClockKind, ClockPayload}; use crate::subscriptions::Subscription; use crate::Message; /// A dummy clock module: subscribes to second ticks, stores the latest /// value, renders it as text in the bar. Clicking toggles between showing /// seconds (HH:MM:SS) and hiding them (HH:MM) — purely a display choice, /// the subscription always ticks seconds. #[derive(Clone)] pub enum ClockMsg { /// The bar was clicked; toggle the seconds suffix. ToggleSeconds, } pub struct Clock { value: String, show_seconds: bool, } impl Clock { pub fn new() -> Self { Self { value: "--:--:--".to_string(), show_seconds: true, } } } impl BarModule for Clock { fn id(&self) -> &'static str { "clock" } fn view(&self, window_id: Option) -> Element<'_, ModuleMsg> { let _ = window_id; // Derive the display string from the stored value each render, so a // click just flips `show_seconds` and the text updates. let shown = if self.show_seconds { self.value.clone() } else { self.value .split(':') // [hh, mm, ss] .take(2) .collect::>() .join(":") }; button(text(shown).size(16)) .padding(0) // kill default 5/10 asymmetric padding; row centers it .on_press(ModuleMsg::new(self.id(), ClockMsg::ToggleSeconds)) .into() } fn update(&mut self, msg: ModuleMsg) -> Task { // The subscription fan-out delivers a raw `ClockPayload` (never // wrapped in `ClockMsg`) — handle it first. if let Some(payload) = msg.downcast::() { self.value = payload.value.clone(); return Task::none(); } // Module-local messages (button clicks) come as `ClockMsg`. if let Some(ClockMsg::ToggleSeconds) = msg.downcast::() { self.show_seconds = !self.show_seconds; } Task::none() } fn subscriptions(&self) -> Vec { vec![Subscription::Clock(ClockKind::Seconds)] } }