[gnome-tour/bilelmoussaoui/fixes: 10/11] subclass the WelcomePageWidget
- From: Bilal Elmoussaoui <bilelmoussaoui src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-tour/bilelmoussaoui/fixes: 10/11] subclass the WelcomePageWidget
- Date: Fri, 31 Dec 2021 19:02:15 +0000 (UTC)
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]