use adw::subclass::prelude::*; use gtk::prelude::*; use gtk::subclass::prelude::*; use gtk::{gio, glib}; use crate::application::MutinyApp; use crate::config::{APP_ID, PROFILE}; mod imp { use super::*; use gtk::CompositeTemplate; #[derive(Debug, CompositeTemplate)] #[template(resource = "/chat/revolt/Mutiny/ui/window.ui")] pub struct MutinyAppWindow { #[template_child] pub headerbar: TemplateChild, pub settings: gio::Settings, } impl Default for MutinyAppWindow { fn default() -> Self { Self { headerbar: TemplateChild::default(), settings: gio::Settings::new(APP_ID), } } } #[glib::object_subclass] impl ObjectSubclass for MutinyAppWindow { const NAME: &'static str = "MutinyAppWindow"; type Type = super::MutinyAppWindow; type ParentType = adw::ApplicationWindow; fn class_init(klass: &mut Self::Class) { Self::bind_template(klass); } // You must call `Widget`'s `init_template()` within `instance_init()`. fn instance_init(obj: &glib::subclass::InitializingObject) { obj.init_template(); } } impl ObjectImpl for MutinyAppWindow { fn constructed(&self, obj: &Self::Type) { self.parent_constructed(obj); // Devel Profile if PROFILE == "Devel" { obj.add_css_class("devel"); } // Load latest window state obj.load_window_size(); } } impl WidgetImpl for MutinyAppWindow {} impl WindowImpl for MutinyAppWindow { // Save window state on delete event fn close_request(&self, window: &Self::Type) -> gtk::Inhibit { if let Err(err) = window.save_window_size() { log::warn!("Failed to save window state, {}", &err); } // Pass close request on to the parent self.parent_close_request(window) } } impl ApplicationWindowImpl for MutinyAppWindow {} impl AdwApplicationWindowImpl for MutinyAppWindow {} } glib::wrapper! { pub struct MutinyAppWindow(ObjectSubclass) @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, @implements gio::ActionMap, gio::ActionGroup, gtk::Root; } impl MutinyAppWindow { pub fn new(app: &MutinyApp) -> Self { glib::Object::new(&[("application", app)]).expect("Failed to create MutinyAppWindow") } fn save_window_size(&self) -> Result<(), glib::BoolError> { let imp = self.imp(); let (width, height) = self.default_size(); imp.settings.set_int("window-width", width)?; imp.settings.set_int("window-height", height)?; imp.settings .set_boolean("is-maximized", self.is_maximized())?; Ok(()) } fn load_window_size(&self) { let imp = self.imp(); let width = imp.settings.int("window-width"); let height = imp.settings.int("window-height"); let is_maximized = imp.settings.boolean("is-maximized"); self.set_default_size(width, height); if is_maximized { self.maximize(); } } }