From 0ccab6df134569884c97f83bb3f26a52a3bc1c0a Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 26 Aug 2021 10:22:47 -0700 Subject: [PATCH] Move time_button into its own custom widget --- src/main.rs | 1 + src/time_button.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++ src/window.rs | 36 ++----------------- 3 files changed, 90 insertions(+), 34 deletions(-) create mode 100644 src/time_button.rs diff --git a/src/main.rs b/src/main.rs index 3afbc48f..1b8b2cc3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use gtk4::{gdk, glib, prelude::*}; mod deref_cell; mod mpris; +mod time_button; mod window; mod x; diff --git a/src/time_button.rs b/src/time_button.rs new file mode 100644 index 00000000..31a06419 --- /dev/null +++ b/src/time_button.rs @@ -0,0 +1,87 @@ +use cascade::cascade; +use gtk4::{ + glib::{self, clone}, + prelude::*, + subclass::prelude::*, +}; + +use crate::deref_cell::DerefCell; +use crate::mpris::MprisControls; + +#[derive(Default)] +pub struct TimeButtonInner { + menu_button: DerefCell, +} + +#[glib::object_subclass] +impl ObjectSubclass for TimeButtonInner { + const NAME: &'static str = "S76TimeButton"; + type ParentType = gtk4::Widget; + type Type = TimeButton; + + fn class_init(klass: &mut Self::Class) { + klass.set_layout_manager_type::(); + } +} + +impl ObjectImpl for TimeButtonInner { + fn constructed(&self, obj: &TimeButton) { + let menu_button = cascade! { + gtk4::MenuButton::new(); + ..set_parent(obj); + ..set_direction(gtk4::ArrowType::None); + ..set_popover(Some(&cascade! { + gtk4::Popover::new(); + ..set_child(Some(&cascade! { + gtk4::Box::new(gtk4::Orientation::Horizontal, 0); + ..append(&MprisControls::new()); + ..append(&cascade! { + gtk4::Calendar::new(); + }); + })); + })); + }; + + self.menu_button.set(menu_button); + + // TODO: better way to do this? + glib::timeout_add_seconds_local( + 1, + clone!(@weak obj => @default-return glib::Continue(false), move || { + obj.update_time(); + glib::Continue(true) + }), + ); + obj.update_time(); + } + + fn dispose(&self, obj: &TimeButton) { + self.menu_button.unparent(); + } +} + +impl WidgetImpl for TimeButtonInner {} + +glib::wrapper! { + pub struct TimeButton(ObjectSubclass) + @extends gtk4::Widget; +} + +impl TimeButton { + pub fn new() -> Self { + glib::Object::new(&[]).unwrap() + } + + fn inner(&self) -> &TimeButtonInner { + TimeButtonInner::from_instance(self) + } + + fn update_time(&self) { + // TODO: Locale-based formatting? + let time = chrono::Local::now(); + self.inner() + .menu_button + .set_label(&time.format("%b %-d %-I:%M %p").to_string()); + // time.format("%B %-d %Y") + } +} diff --git a/src/window.rs b/src/window.rs index e548d683..b9f0d7e3 100644 --- a/src/window.rs +++ b/src/window.rs @@ -2,25 +2,10 @@ use cascade::cascade; use glib::clone; use gtk4::{gdk, glib, prelude::*}; -use crate::mpris::MprisControls; +use crate::time_button::TimeButton; use crate::x; pub fn window(monitor: gdk::Monitor) -> gtk4::Window { - let time_button = cascade! { - gtk4::MenuButton::new(); - ..set_direction(gtk4::ArrowType::None); - ..set_popover(Some(&cascade! { - gtk4::Popover::new(); - ..set_child(Some(&cascade! { - gtk4::Box::new(gtk4::Orientation::Horizontal, 0); - ..append(&MprisControls::new()); - ..append(&cascade! { - gtk4::Calendar::new(); - }); - })); - })); - }; - let box_ = cascade! { gtk4::CenterBox::new(); ..set_start_widget(Some(&cascade! { @@ -28,7 +13,7 @@ pub fn window(monitor: gdk::Monitor) -> gtk4::Window { ..append(>k4::Button::with_label("Workspaces")); ..append(>k4::Button::with_label("Applications")); })); - ..set_center_widget(Some(&time_button)); + ..set_center_widget(Some(&TimeButton::new())); }; let window = cascade! { @@ -38,23 +23,6 @@ pub fn window(monitor: gdk::Monitor) -> gtk4::Window { ..show(); }; - fn update_time(time_button: >k4::MenuButton) { - // TODO: Locale-based formatting? - let time = chrono::Local::now(); - time_button.set_label(&time.format("%b %-d %-I:%M %p").to_string()); - // time.format("%B %-d %Y") - } - - // TODO: better way to do this? - glib::timeout_add_seconds_local( - 1, - clone!(@weak time_button => @default-return glib::Continue(false), move || { - update_time(&time_button); - glib::Continue(true) - }), - ); - update_time(&time_button); - fn monitor_geometry_changed(window: >k4::Window, monitor: &gdk::Monitor) { let geometry = monitor.geometry(); window.set_size_request(geometry.width, 0);