[gnome-tour/bilelmoussaoui/video: 20/22] hide the video at start and animate it when the player starts
- From: Bilal Elmoussaoui <bilelmoussaoui src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-tour/bilelmoussaoui/video: 20/22] hide the video at start and animate it when the player starts
- Date: Tue, 18 Aug 2020 14:24:14 +0000 (UTC)
commit 1c3b344bdc5296e92545f920652afb6d2c0df3c7
Author: Bilal Elmoussaoui <bil elmoussaoui gmail com>
Date: Tue Aug 11 01:16:49 2020 +0200
hide the video at start and animate it when the player starts
data/resources/style.css | 9 +++
src/widgets/pages/welcome.rs | 152 +++++++++++++++++++++++++++++--------------
2 files changed, 111 insertions(+), 50 deletions(-)
---
diff --git a/data/resources/style.css b/data/resources/style.css
index 67eecca..5c1170c 100644
--- a/data/resources/style.css
+++ b/data/resources/style.css
@@ -11,6 +11,15 @@
font-weight: 400;
font-size: 12pt;
}
+.video {
+ opacity: 0;
+}
+.video.playing {
+ opacity: 1;
+ transition-property: opacity;
+ transition-duration: 250ms;
+ transition-timing-function: ease-in-out;
+}
.last-page {
background-color: #4a86cf; /*GNOME blue*/
diff --git a/src/widgets/pages/welcome.rs b/src/widgets/pages/welcome.rs
index faaf892..3b01029 100644
--- a/src/widgets/pages/welcome.rs
+++ b/src/widgets/pages/welcome.rs
@@ -3,67 +3,58 @@ use crate::config;
use gettextrs::gettext;
#[cfg(feature = "video")]
use gio::FileExt;
+#[cfg(feature = "video")]
+use glib::{Receiver, Sender};
use gtk::prelude::*;
+#[cfg(feature = "video")]
+use std::cell::RefCell;
+
+#[derive(PartialEq)]
+#[cfg(feature = "video")]
+pub enum Action {
+ VideoReady,
+}
pub struct WelcomePageWidget {
pub widget: libhandy::WindowHandle,
+ #[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 = libhandy::WindowHandle::new();
- let welcome_page = Self { widget };
+
+ #[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>()))
+ };
+ #[cfg(feature = "video")]
+ let (sender, r) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
+ #[cfg(feature = "video")]
+ let receiver = RefCell::new(Some(r));
+
+ let welcome_page = Self {
+ widget,
+ #[cfg(feature = "video")]
+ player,
+ #[cfg(feature = "video")]
+ sender,
+ #[cfg(feature = "video")]
+ receiver,
+ };
welcome_page.init();
welcome_page
}
- #[cfg(not(feature = "video"))]
- fn get_header_widget(&self) -> gtk::Widget {
- let icon = glib::get_os_info("LOGO").unwrap_or_else(|| "start-here-symbolic".into());
-
- let logo = gtk::Image::from_icon_name(Some(&icon), gtk::IconSize::Dialog);
- logo.set_pixel_size(196);
- logo.show();
-
- logo.upcast::<gtk::Widget>()
- }
-
- #[cfg(feature = "video")]
- fn get_header_widget(&self) -> gtk::Widget {
- 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();
- let player = gst_player::Player::new(Some(&renderer),
Some(&dispatcher.upcast::<gst_player::PlayerSignalDispatcher>()));
-
- let video_file = gio::File::new_for_path(config::VIDEO_PATH);
- player.set_uri(&video_file.get_uri());
-
- let video_widget = 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();
-
- video_widget.set_size_request(-1, 300);
- video_widget.set_property("ignore-alpha", &false).unwrap();
- video_widget.show();
-
- gtk::idle_add(clone!(@strong player => move || {
- player.play();
- glib::Continue(true)
- }));
-
- video_widget
- }
-
fn init(&self) {
let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
@@ -73,12 +64,73 @@ impl WelcomePageWidget {
container.set_margin_top(24);
container.set_margin_bottom(24);
- let name = glib::get_os_info("NAME").unwrap_or_else(|| "GNOME".into());
- let version = glib::get_os_info("VERSION").unwrap_or_else(|| "3.36".into());
+ #[cfg(not(feature = "video"))]
+ let header = {
+ let icon = glib::get_os_info("LOGO").unwrap_or_else(|| "start-here-symbolic".into());
+
+ let logo = gtk::Image::from_icon_name(Some(&icon), gtk::IconSize::Dialog);
+ logo.set_pixel_size(196);
+ logo.show();
+
+ logo.upcast::<gtk::Widget>()
+ };
+
+ #[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();
+
+ video_widget.set_size_request(-1, 360);
+ video_widget.set_property("ignore-alpha", &false).unwrap();
+ video_widget.show();
+ video_widget.get_style_context().add_class("video");
+ video_widget
+ };
- let header = self.get_header_widget();
container.add(&header);
+ #[cfg(feature = "video")]
+ {
+ let receiver = self.receiver.borrow_mut().take().unwrap();
+ receiver.attach(None, move |action| {
+ if action == Action::VideoReady {
+ header.get_style_context().add_class("playing");
+ }
+ glib::Continue(true)
+ });
+
+ let video_file = gio::File::new_for_path(config::VIDEO_PATH);
+ self.player.set_uri(&video_file.get_uri());
+
+ self.player.connect_state_changed(clone!(@strong self.sender as sender => move |_, state| {
+ if state == gst_player::PlayerState::Playing {
+ sender.send(Action::VideoReady).unwrap();
+ }
+ }));
+
+ gtk::timeout_add(
+ 500,
+ clone!(@strong self.player as player => move || {
+ player.play();
+ glib::Continue(true)
+ }),
+ );
+ };
+
+ let name = glib::get_os_info("NAME").unwrap_or_else(|| "GNOME".into());
+ let version = glib::get_os_info("VERSION").unwrap_or_else(|| "3.36".into());
+
let title = gtk::Label::new(Some(&gettext(format!("Welcome to {} {}", name, version))));
title.set_margin_top(36);
title.get_style_context().add_class("large-title");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]