[gnome-tour/bilelmoussaoui/fixes: 10/11] subclass the WelcomePageWidget




commit 59d6e0f06a550fdfd6fe426e76b901160becadbf
Author: Bilal Elmoussaoui <bil elmoussaoui gmail com>
Date:   Fri Dec 31 19:40:53 2021 +0100

    subclass the WelcomePageWidget

 src/widgets/pages/welcome.rs | 292 +++++++++++++++++++++++--------------------
 src/widgets/window.rs        |   2 +-
 2 files changed, 157 insertions(+), 137 deletions(-)
---
diff --git a/src/widgets/pages/welcome.rs b/src/widgets/pages/welcome.rs
index 617d6e2..d639b05 100644
--- a/src/widgets/pages/welcome.rs
+++ b/src/widgets/pages/welcome.rs
@@ -10,6 +10,7 @@ use gtk::glib::clone;
 #[cfg(feature = "video")]
 use gtk::glib::{Receiver, Sender};
 use gtk::prelude::*;
+use gtk::subclass::prelude::*;
 #[cfg(feature = "video")]
 use std::cell::RefCell;
 
@@ -20,158 +21,177 @@ pub enum Action {
     VideoUp,
 }
 
-pub struct WelcomePageWidget {
-    pub widget: gtk::Box,
-    #[cfg(feature = "video")]
-    player: gst_player::Player,
-    #[cfg(feature = "video")]
-    receiver: RefCell<Option<Receiver<Action>>>,
-    #[cfg(feature = "video")]
-    sender: Sender<Action>,
-}
-
-impl WelcomePageWidget {
-    pub fn new() -> Self {
-        let widget = gtk::Box::new(gtk::Orientation::Horizontal, 0);
+mod imp {
+    use super::*;
 
+    #[derive(Debug)]
+    pub struct WelcomePageWidget {
         #[cfg(feature = "video")]
-        let player = {
-            let dispatcher = gst_player::PlayerGMainContextSignalDispatcher::new(None);
-            let sink = gst::ElementFactory::make("gtksink", None)
-                .expect("Missing dependency: element gtksink is needed (usually, in gstreamer-plugins-good 
or in gst-plugin-gtk).");
-            let renderer = gst_player::PlayerVideoOverlayVideoRenderer::with_sink(&sink).upcast();
-            gst_player::Player::new(
-                Some(&renderer),
-                Some(&dispatcher.upcast::<gst_player::PlayerSignalDispatcher>()),
-            )
-        };
+        player: gst_player::Player,
         #[cfg(feature = "video")]
-        let (sender, r) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
+        receiver: RefCell<Option<Receiver<Action>>>,
         #[cfg(feature = "video")]
-        let receiver = RefCell::new(Some(r));
+        sender: Sender<Action>,
+    }
 
-        let welcome_page = Self {
-            widget,
+    impl Default for WelcomePageWidget {
+        fn default() -> Self {
             #[cfg(feature = "video")]
-            player,
+            let player = {
+                let dispatcher = gst_player::PlayerGMainContextSignalDispatcher::new(None);
+                let sink = gst::ElementFactory::make("gtksink", None)
+                .expect("Missing dependency: element gtksink is needed (usually, in gstreamer-plugins-good 
or in gst-plugin-gtk).");
+                let renderer =
+                    gst_player::PlayerVideoOverlayVideoRenderer::with_sink(&sink).upcast();
+                gst_player::Player::new(
+                    Some(&renderer),
+                    Some(&dispatcher.upcast::<gst_player::PlayerSignalDispatcher>()),
+                )
+            };
             #[cfg(feature = "video")]
-            sender,
+            let (sender, r) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
             #[cfg(feature = "video")]
-            receiver,
-        };
+            let receiver = RefCell::new(Some(r));
+
+            Self {
+                #[cfg(feature = "video")]
+                player,
+                #[cfg(feature = "video")]
+                sender,
+                #[cfg(feature = "video")]
+                receiver,
+            }
+        }
+    }
 
-        welcome_page.init();
-        welcome_page
+    #[glib::object_subclass]
+    impl ObjectSubclass for WelcomePageWidget {
+        const NAME: &'static str = "WelcomePageWidget";
+        type ParentType = gtk::Box;
+        type Type = super::WelcomePageWidget;
     }
 
-    fn init(&self) {
-        let container = gtk::Box::builder()
-            .orientation(gtk::Orientation::Vertical)
-            .spacing(0)
-            .hexpand(true)
-            .vexpand(true)
-            .valign(gtk::Align::Center)
-            .halign(gtk::Align::Center)
-            .margin_top(24)
-            .margin_bottom(24)
-            .build();
-        self.widget.add_css_class("page");
-        self.widget.add_css_class("welcome-page");
-
-        let clamp = adw::Clamp::new();
-        clamp.set_child(Some(&container));
-
-        #[cfg(not(feature = "video"))]
-        let header = {
-            let logo = gtk::Picture::builder()
-                .can_shrink(false)
-                .keep_aspect_ratio(true)
+    impl ObjectImpl for WelcomePageWidget {
+        fn constructed(&self, widget: &Self::Type) {
+            let layout_manager = widget
+                .layout_manager()
+                .map(|l| l.downcast::<gtk::BoxLayout>().unwrap())
+                .unwrap();
+            layout_manager.set_orientation(gtk::Orientation::Vertical);
+
+            let container = gtk::Box::builder()
+                .orientation(gtk::Orientation::Vertical)
+                .spacing(0)
+                .hexpand(true)
+                .vexpand(true)
+                .valign(gtk::Align::Center)
+                .halign(gtk::Align::Center)
+                .margin_top(24)
+                .margin_bottom(24)
                 .build();
-            logo.set_resource(Some("/org/gnome/Tour/welcome.svg"));
+            widget.add_css_class("page");
+            widget.add_css_class("welcome-page");
 
-            logo.upcast::<gtk::Widget>()
-        };
+            let clamp = adw::Clamp::new();
+            clamp.set_child(Some(&container));
 
-        #[cfg(feature = "video")]
-        let header = {
-            let video_widget = self
-                .player
-                .get_pipeline()
-                .get_property("video-sink")
-                .unwrap()
-                .get::<gst::Element>()
-                .expect("The player of a VideoPlayerWidget should not use the default sink.")
-                .unwrap()
-                .get_property("widget")
-                .unwrap()
-                .get::<gtk::Widget>()
-                .unwrap()
-                .unwrap();
+            #[cfg(not(feature = "video"))]
+            let header = {
+                let logo = gtk::Picture::builder()
+                    .can_shrink(false)
+                    .keep_aspect_ratio(true)
+                    .build();
+                logo.set_resource(Some("/org/gnome/Tour/welcome.svg"));
 
-            video_widget.set_size_request(-1, 360);
-            video_widget.set_property("ignore-alpha", &false).unwrap();
-            video_widget.show();
-            video_widget.add_css_class("video");
-            video_widget
-        };
+                logo.upcast::<gtk::Widget>()
+            };
 
-        container.append(&header);
+            #[cfg(feature = "video")]
+            let header = {
+                let video_widget = self
+                    .player
+                    .pipeline()
+                    .property::<gst::Element>("video-sink")
+                    .property::<gtk::Widget>("widget");
 
-        #[cfg(feature = "video")]
-        {
-            let receiver = self.receiver.borrow_mut().take().unwrap();
-            receiver.attach(
-                None,
-                clone!(@strong self.player as player => move |action| {
-                    match action {
-                        Action::VideoReady => player.play(),
-                        Action::VideoUp => header.add_css_class("playing"),
-                    };
-                    glib::Continue(true)
-                }),
-            );
-
-            self.player.connect_state_changed(
-                clone!(@strong self.sender as sender => move |_p,state| {
-                    if state == gst_player::PlayerState::Playing {
-                        sender.send(Action::VideoUp).unwrap();
-                    }
-                }),
-            );
-
-            self.player.connect_uri_loaded(
-                clone!(@strong self.sender as sender => move |_p, _uri| {
-                    sender.send(Action::VideoReady).unwrap();
-                }),
-            );
-            self.player.connect_end_of_stream(move |p| p.stop());
-
-            let video_file = gio::File::new_for_path(config::VIDEO_PATH);
-            gtk::timeout_add(
-                500,
-                clone!(@strong self.player as player => move || {
-                    player.set_uri(&video_file.get_uri());
-                    glib::Continue(false)
-                }),
-            );
-        };
-
-        let title = gtk::Label::new(Some(&gettext("Start the Tour")));
-        title.set_margin_top(36);
-        title.add_css_class("title-1");
-        container.append(&title);
-
-        let name = glib::os_info("NAME").unwrap_or_else(|| "GNOME".into());
-        let version = glib::os_info("VERSION").unwrap_or_else(|| "".into());
-        // Translators: The following string is formated as "Learn about new and essential features in GNOME 
3.36" for example
-        let text = gtk::Label::new(Some(&i18n_f(
-            "Learn about the key features in {} {}.",
-            &[&name, &version],
-        )));
-        text.add_css_class("body");
-        text.set_margin_top(12);
-        container.append(&text);
-
-        self.widget.append(&clamp);
+                video_widget.set_size_request(-1, 360);
+                video_widget.set_property("ignore-alpha", &false).unwrap();
+                video_widget.add_css_class("video");
+                video_widget
+            };
+
+            container.append(&header);
+
+            #[cfg(feature = "video")]
+            {
+                let receiver = self.receiver.borrow_mut().take().unwrap();
+                receiver.attach(
+                    None,
+                    clone!(@strong self.player as player => move |action| {
+                        match action {
+                            Action::VideoReady => player.play(),
+                            Action::VideoUp => header.add_css_class("playing"),
+                        };
+                        glib::Continue(true)
+                    }),
+                );
+
+                self.player.connect_state_changed(
+                    clone!(@strong self.sender as sender => move |_p,state| {
+                        if state == gst_player::PlayerState::Playing {
+                            sender.send(Action::VideoUp).unwrap();
+                        }
+                    }),
+                );
+
+                self.player.connect_uri_loaded(
+                    clone!(@strong self.sender as sender => move |_p, _uri| {
+                        sender.send(Action::VideoReady).unwrap();
+                    }),
+                );
+                self.player.connect_end_of_stream(move |p| p.stop());
+
+                let video_file = gio::File::new_for_path(config::VIDEO_PATH);
+                gtk::timeout_add(
+                    500,
+                    clone!(@strong self.player as player => move || {
+                        player.set_uri(&video_file.get_uri());
+                        glib::Continue(false)
+                    }),
+                );
+            };
+
+            let title = gtk::Label::new(Some(&gettext("Start the Tour")));
+            title.set_margin_top(36);
+            title.add_css_class("title-1");
+            container.append(&title);
+
+            let name = glib::os_info("NAME").unwrap_or_else(|| "GNOME".into());
+            let version = glib::os_info("VERSION").unwrap_or_else(|| "".into());
+            // Translators: The following string is formated as "Learn about new and essential features in 
GNOME 3.36" for example
+            let text = gtk::Label::new(Some(&i18n_f(
+                "Learn about the key features in {} {}.",
+                &[&name, &version],
+            )));
+            text.add_css_class("body");
+            text.set_margin_top(12);
+            container.append(&text);
+
+            widget.append(&clamp);
+            self.parent_constructed(widget);
+        }
+    }
+    impl WidgetImpl for WelcomePageWidget {}
+    impl BoxImpl for WelcomePageWidget {}
+}
+
+glib::wrapper! {
+    pub struct WelcomePageWidget(ObjectSubclass<imp::WelcomePageWidget>)
+        @extends gtk::Widget, gtk::Box;
+}
+
+impl WelcomePageWidget {
+    pub fn new() -> Self {
+        glib::Object::new(&[]).unwrap()
     }
 }
diff --git a/src/widgets/window.rs b/src/widgets/window.rs
index 81019d2..6255754 100644
--- a/src/widgets/window.rs
+++ b/src/widgets/window.rs
@@ -34,7 +34,7 @@ mod imp {
                 widget.add_css_class("devel");
             }
 
-            self.paginator.add_page(WelcomePageWidget::new().widget);
+            self.paginator.add_page(WelcomePageWidget::new());
             self.paginator.add_page(ImagePageWidget::new(
                 "/org/gnome/Tour/overview.svg",
                 gettext("Get an Overview"),


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