[gnome-tour/bilelmoussaoui/fixes: 6/11] subclass adw::Application




commit 8f181ddc57847eec38908ff9e315ffce7dbae165
Author: Bilal Elmoussaoui <bil elmoussaoui gmail com>
Date:   Fri Dec 31 18:44:11 2021 +0100

    subclass adw::Application

 src/application.rs       | 171 ++++++++++++++++++++++++++---------------------
 src/main.rs              |   3 +-
 src/widgets/paginator.rs |   1 +
 src/widgets/window.rs    |   4 +-
 4 files changed, 98 insertions(+), 81 deletions(-)
---
diff --git a/src/application.rs b/src/application.rs
index b66ce23..c3e9674 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -1,107 +1,122 @@
 use crate::config;
 use crate::utils;
 use crate::widgets::Window;
-use gtk::gio::{self, prelude::*};
-use gtk::glib::{self, clone};
-use gtk::prelude::*;
+use adw::prelude::*;
+use gtk::{
+    gio,
+    glib::{self, clone},
+    subclass::prelude::*,
+};
 use log::info;
-use std::{cell::RefCell, rc::Rc};
 
-pub struct Application {
-    app: adw::Application,
-    window: RefCell<Rc<Option<Window>>>,
-}
-
-impl Application {
-    pub fn new() -> Rc<Self> {
-        let app = adw::Application::new(Some(config::APP_ID), gio::ApplicationFlags::FLAGS_NONE);
-        app.set_resource_base_path(Some("/org/gnome/Tour"));
+mod imp {
+    use super::*;
+    use adw::subclass::prelude::*;
+    use gtk::glib::{once_cell::sync::OnceCell, WeakRef};
 
-        let application = Rc::new(Self {
-            app,
-            window: RefCell::new(Rc::new(None)),
-        });
+    #[derive(Debug, Default)]
+    pub struct Application {
+        pub(super) window: OnceCell<Window>,
+    }
 
-        application.setup_signals(application.clone());
-        application
+    #[glib::object_subclass]
+    impl ObjectSubclass for Application {
+        const NAME: &'static str = "Application";
+        type ParentType = adw::Application;
+        type Type = super::Application;
     }
 
-    fn setup_gactions(&self, application: Rc<Self>) {
-        // Quit
-        utils::action(
-            &self.app,
-            "quit",
-            clone!(@strong self.app as app => move |_, _| {
-                app.quit();
-            }),
-        );
+    impl ObjectImpl for Application {}
+    impl ApplicationImpl for Application {
+        fn activate(&self, application: &Self::Type) {
+            let window = Window::new(&application);
+            application.add_window(&window.widget);
+            window.widget.present();
+            self.window.set(window);
+            self.parent_activate(application);
+        }
+        fn startup(&self, application: &Self::Type) {
+            // Quit
+            utils::action(
+                application,
+                "quit",
+                clone!(@weak application => move |_, _| {
+                    application.quit();
+                }),
+            );
 
-        // Start Tour
-        utils::action(
-            &self.app,
-            "start-tour",
-            clone!(@strong application => move |_, _| {
-                if let Some(window) = &*application.window.borrow().clone() {
-                    window.start_tour();
-                }
-            }),
-        );
+            // Start Tour
+            utils::action(
+                application,
+                "start-tour",
+                clone!(@weak application => move |_, _| {
+                    application.window().start_tour();
+                }),
+            );
 
-        // Skip Tour
-        utils::action(
-            &self.app,
-            "skip-tour",
-            clone!(@strong self.app as app => move |_, _| {
-                app.quit();
-            }),
-        );
+            // Skip Tour
+            utils::action(
+                application,
+                "skip-tour",
+                clone!(@weak application => move |_, _| {
+                    application.quit();
+                }),
+            );
 
-        utils::action(
-            &self.app,
-            "next-page",
-            clone!(@strong application => move |_, _| {
-                if let Some(window) = &*application.window.borrow().clone() {
+            utils::action(
+                application,
+                "next-page",
+                clone!(@weak application => move |_, _| {
+                    let window = application.window();
                     if window.paginator.borrow_mut().try_next().is_none() {
                         window.widget.close();
                     }
-                }
-            }),
-        );
+                }),
+            );
 
-        utils::action(
-            &self.app,
-            "previous-page",
-            clone!(@strong application => move |_, _| {
-                if let Some(window) = &*application.window.borrow().clone() {
+            utils::action(
+                application,
+                "previous-page",
+                clone!(@weak application => move |_, _| {
+                    let window = application.window();
                     if window.paginator.borrow_mut().try_previous().is_none() {
                         window.reset_tour();
                     }
-                }
-            }),
-        );
+                }),
+            );
+            application.set_accels_for_action("app.quit", &["<Control>q"]);
+            self.parent_startup(application);
+        }
+    }
+    impl GtkApplicationImpl for Application {}
+    impl AdwApplicationImpl for Application {}
+}
+
+glib::wrapper! {
+    pub struct Application(ObjectSubclass<imp::Application>)
+        @extends gio::Application, gtk::Application, adw::Application,
+        @implements gio::ActionMap, gio::ActionGroup;
+}
 
-        self.app.set_accels_for_action("app.quit", &["<primary>q"]);
+impl Application {
+    pub fn new() -> Self {
+        glib::Object::new(&[
+            ("application-id", &config::APP_ID),
+            ("resource-base-path", &Some("/org/gnome/Tour")),
+        ])
+        .unwrap()
     }
 
-    fn setup_signals(&self, app: Rc<Self>) {
-        self.app.connect_startup(clone!(@weak app => move |_| {
-            app.setup_gactions(app.clone());
-        }));
-        self.app
-            .connect_activate(clone!(@weak app => move |gtk_app| {
-               let window = Window::new(&gtk_app);
-                gtk_app.add_window(&window.widget);
-                window.widget.present();
-                window.widget.show();
-                app.window.replace(Rc::new(Some(window)));
-            }));
+    fn window(&self) -> &Window {
+        // and_then(|w| w.upgrade())
+        self.imp().window.get().unwrap()
     }
 
-    pub fn run(&self) {
+    pub fn run() {
         info!("GNOME Tour ({})", config::APP_ID);
         info!("Version: {} ({})", config::VERSION, config::PROFILE);
         info!("Datadir: {}", config::PKGDATADIR);
-
-        self.app.run();
+        let app = Self::new();
+        gtk::prelude::ApplicationExtManual::run(&app);
     }
 }
diff --git a/src/main.rs b/src/main.rs
index dbc9b75..d12cf44 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -32,6 +32,5 @@ fn main() {
 
     static_resources::init().expect("Failed to initialize the resource file.");
 
-    let app = Application::new();
-    app.run();
+    Application::run()
 }
diff --git a/src/widgets/paginator.rs b/src/widgets/paginator.rs
index c8835d3..6a1297e 100644
--- a/src/widgets/paginator.rs
+++ b/src/widgets/paginator.rs
@@ -4,6 +4,7 @@ use gtk::prelude::*;
 use std::cell::RefCell;
 use std::rc::Rc;
 
+#[derive(Debug)]
 pub struct PaginatorWidget {
     pub widget: gtk::Box,
     carousel: adw::Carousel,
diff --git a/src/widgets/window.rs b/src/widgets/window.rs
index c51b6f9..724ff86 100644
--- a/src/widgets/window.rs
+++ b/src/widgets/window.rs
@@ -6,14 +6,16 @@ use std::rc::Rc;
 use super::pages::{ImagePageWidget, WelcomePageWidget};
 use super::paginator::PaginatorWidget;
 use crate::config::{APP_ID, PROFILE};
+use crate::Application;
 
+#[derive(Debug)]
 pub struct Window {
     pub widget: adw::ApplicationWindow,
     pub paginator: RefCell<Rc<PaginatorWidget>>,
 }
 
 impl Window {
-    pub fn new(app: &adw::Application) -> Self {
+    pub fn new(app: &Application) -> Self {
         let widget = adw::ApplicationWindow::new(app);
 
         let paginator = RefCell::new(PaginatorWidget::new());


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]