diff --git a/src/widgets/datewidget.rs b/src/widgets/datewidget.rs new file mode 100644 index 0000000..338f9c5 --- /dev/null +++ b/src/widgets/datewidget.rs @@ -0,0 +1,52 @@ +use crate::TopBar; +use chrono::{Datelike, Local}; +use slint::{ComponentHandle, SharedString, Timer, TimerMode}; +use std::time::Duration; + +use super::common::run_cmd; + +// Format date as "Mon 20 Jan" +fn format_date() -> SharedString { + SharedString::from(Local::now().format("%a %d %b").to_string()) +} + +// Update the date_text property only when it actually changes +fn start_date_updater(ui: &TopBar) { + let weak = ui.as_weak(); + + // Store the previous date to detect changes + let mut last_day = Local::now().day(); + + // Initialize on start + if let Some(ui) = weak.upgrade() { + ui.set_date_text(format_date()); + } + + // 1-minute timer — cheap, safe, reliable + let timer = Box::leak(Box::new(Timer::default())); + timer.start(TimerMode::Repeated, Duration::from_secs(60), move || { + if let Some(ui) = weak.upgrade() { + let now = Local::now(); + let today = now.day(); + + if today != last_day { + // date changed (midnight or clock adjustments) + last_day = today; + ui.set_date_text(format_date()); + } + } + }); +} + +// Connect click callback + start updater +pub fn install(ui: &TopBar) { + let weak = ui.as_weak(); + + ui.on_show_calendar(move || { + if weak.upgrade().is_some() { + run_cmd("xclock"); // Fix later + } + }); + + start_date_updater(ui); +} diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 3859080..983d02c 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -1,13 +1,14 @@ mod common; +mod datewidget; mod timewidget; use crate::TopBar; pub fn install_callbacks(ui: &TopBar) { timewidget::install(ui); + datewidget::install(ui); // In the future: - // datewidget::install(ui); // networkwidget::install(ui); // batterywidget::install(ui); } diff --git a/ui/date-widget.slint b/ui/date-widget.slint new file mode 100644 index 0000000..212f486 --- /dev/null +++ b/ui/date-widget.slint @@ -0,0 +1,28 @@ +export component DateWidget { + in-out property date_text; + + callback show_calendar(); // Callback to execute things from Rust, because Slint can't + + Rectangle { + background: touch_area.pressed ? #704a4a : touch_area.has-hover ? #4d8a7a : #6f6291; // Bg color based on click & hover + border-radius: 3px; + + HorizontalLayout { + padding-right: 3px; + padding-left: 3px; + + Text { + text: date_text; + color: white; + vertical-alignment: center; + } + } + + // Area to sense click and hover + touch_area:= TouchArea { + clicked => { + show_calendar(); + } + } + } +} diff --git a/ui/topbar.slint b/ui/topbar.slint index 9847874..4f06a86 100644 --- a/ui/topbar.slint +++ b/ui/topbar.slint @@ -1,4 +1,5 @@ import { TimeWidget } from "time-widget.slint"; +import { DateWidget } from "date-widget.slint"; export component TopBar inherits Window { @@ -12,6 +13,10 @@ export component TopBar inherits Window { in-out property time_text; callback show_clock(); + // Date widget + in-out property date_text; + callback show_calendar(); + title: "chocobar"; width: bar_width *1px; height: bar_height *1px; @@ -56,9 +61,18 @@ export component TopBar inherits Window { HorizontalLayout { alignment: end; // Right-align + DateWidget { + // Get from root + date_text: root.date_text; + // Forward the widget's callback to the root's to access from Rust + show_calendar => root.show_calendar(); + } + TimeWidget { - time_text: root.time_text; // Get from root - show_clock => root.show_clock(); // Forward the widget's callback to the root's to access from Rust + // Get from root + time_text: root.time_text; + // Forward the widget's callback to the root's to access from Rust + show_clock => root.show_clock(); } } }