Commit 117ebe90 authored by Bilal Elmoussaoui's avatar Bilal Elmoussaoui

Merge branch 'bilelmoussaoui/video' into 'master'

Add a configurable welcome video thing See merge request GNOME/gnome-tour!16
parents 298f0bfa b70e4f16
...@@ -53,6 +53,12 @@ dependencies = [ ...@@ -53,6 +53,12 @@ dependencies = [
] ]
[[package]] [[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bitflags" name = "bitflags"
version = "1.2.1" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
...@@ -381,6 +387,8 @@ dependencies = [ ...@@ -381,6 +387,8 @@ dependencies = [
"gettext-rs", "gettext-rs",
"gio", "gio",
"glib", "glib",
"gstreamer",
"gstreamer-player",
"gtk", "gtk",
"libhandy", "libhandy",
"log", "log",
...@@ -399,6 +407,137 @@ dependencies = [ ...@@ -399,6 +407,137 @@ dependencies = [
] ]
[[package]] [[package]]
name = "gstreamer"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce4ce1ba28d3293b8cb8c3d33f50e6da2e5cfeefa59a0d10d922ab8015791609"
dependencies = [
"bitflags",
"cfg-if",
"futures-channel",
"futures-core",
"futures-util",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer-sys",
"libc",
"muldiv",
"num-rational",
"once_cell",
"paste",
"pretty-hex",
"thiserror",
]
[[package]]
name = "gstreamer-base"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "872893487ce8876f18c63730402822804c5762869f631d8e3e6b18aafc8399f0"
dependencies = [
"bitflags",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer",
"gstreamer-base-sys",
"gstreamer-sys",
"libc",
]
[[package]]
name = "gstreamer-base-sys"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fd5a77d39b47568fba01274dfcb28dc32382513c697009f80b89ef63fd32fd"
dependencies = [
"glib-sys",
"gobject-sys",
"gstreamer-sys",
"libc",
"system-deps",
]
[[package]]
name = "gstreamer-player"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e8a850be21b18fb21f21fa16394bfc176013f7fffdc6719db0ea23b3c99a2b"
dependencies = [
"bitflags",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer",
"gstreamer-player-sys",
"gstreamer-sys",
"gstreamer-video",
"libc",
]
[[package]]
name = "gstreamer-player-sys"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f0cd125febba8f9b3cae13881c0d845a77a4e4797b9552aa4058330c23e958"
dependencies = [
"glib-sys",
"gobject-sys",
"gstreamer-sys",
"gstreamer-video-sys",
"libc",
"system-deps",
]
[[package]]
name = "gstreamer-sys"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1321f34d53bb5f60ab1aaf581e29b664b8d41601714ee1bb7dbea490b5b9ff60"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "gstreamer-video"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a52c141d83113e6dd080347ca49ef9be296e7900e081f2b67eaad6a3d5ef26"
dependencies = [
"bitflags",
"futures-channel",
"futures-util",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer",
"gstreamer-base",
"gstreamer-base-sys",
"gstreamer-sys",
"gstreamer-video-sys",
"libc",
"once_cell",
]
[[package]]
name = "gstreamer-video-sys"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6f105143a7676d2032c386c10b2d376106b5562b7a11b694b634113456f1935"
dependencies = [
"glib-sys",
"gobject-sys",
"gstreamer-base-sys",
"gstreamer-sys",
"libc",
"system-deps",
]
[[package]]
name = "gtk" name = "gtk"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
...@@ -561,10 +700,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" ...@@ -561,10 +700,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]] [[package]]
name = "muldiv"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204"
[[package]]
name = "num-integer"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell" name = "once_cell"
version = "1.4.0" version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
[[package]] [[package]]
name = "pango" name = "pango"
...@@ -594,6 +769,25 @@ dependencies = [ ...@@ -594,6 +769,25 @@ dependencies = [
] ]
[[package]] [[package]]
name = "paste"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
dependencies = [
"paste-impl",
"proc-macro-hack",
]
[[package]]
name = "paste-impl"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
dependencies = [
"proc-macro-hack",
]
[[package]]
name = "pin-project" name = "pin-project"
version = "0.4.23" version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
...@@ -626,6 +820,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" ...@@ -626,6 +820,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
[[package]] [[package]]
name = "pretty-hex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be91bcc43e73799dc46a6c194a55e7aae1d86cc867c860fd4a436019af21bd8c"
[[package]]
name = "pretty_env_logger" name = "pretty_env_logger"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
......
...@@ -4,6 +4,9 @@ version = "0.0.1" ...@@ -4,6 +4,9 @@ version = "0.0.1"
authors = ["Bilal Elmoussaoui <bil.elmoussaoui@gmail.com>"] authors = ["Bilal Elmoussaoui <bil.elmoussaoui@gmail.com>"]
edition = "2018" edition = "2018"
[features]
video = ["gst_player", "gst"]
[dependencies] [dependencies]
glib = { version = "0.10", features = ["v2_64"] } glib = { version = "0.10", features = ["v2_64"] }
gdk = "0.13" gdk = "0.13"
...@@ -14,3 +17,13 @@ gettext-rs = { version = "0.4", features = ["gettext-system"] } ...@@ -14,3 +17,13 @@ gettext-rs = { version = "0.4", features = ["gettext-system"] }
libhandy = "1.0.0-alpha" libhandy = "1.0.0-alpha"
pretty_env_logger = "0.4" pretty_env_logger = "0.4"
anyhow = "1.0" anyhow = "1.0"
[dependencies.gst_player]
version = "0.16"
package = "gstreamer-player"
optional = true
[dependencies.gst]
version = "0.16"
package = "gstreamer"
optional = true
# GNOME Greeter & Tour # Tour
<img src="https://gitlab.gnome.org/GNOME/gnome-tour/raw/master/data/icons/org.gnome.Tour.svg" width="128" height="128" />
<p>GNOME's Tour & Greeter.</p>
## Screenshots
<div align="center">
![screenshot](data/resources/screenshots/screenshot1.png)
</div>
### Video Feature
Tour uses by default the logo of the distribution based on the info from `/etc/os-release`. The application comes with a feature to replace the logo with a welcome video shipped by the distribution.
To enable the feature, you need to build the application with
```bash
meson _builddir -Dvideo_path=/absolute/path/to/the/video.mp4
```
If you're testing the application using Builder, make sure to change the `config-opts` accordinagly & give the application filesystem access so it can play the video file.
Example:
This needs to be added to the `gnome-tour` module
```json
"config-opts" : [
"-Dvideo_path=/home/username/to/the/video.mp4"
]
```
along with `--filesystem=home` in `finish-args`
...@@ -4,17 +4,18 @@ export MESON_BUILD_ROOT="$1" ...@@ -4,17 +4,18 @@ export MESON_BUILD_ROOT="$1"
export MESON_SOURCE_ROOT="$2" export MESON_SOURCE_ROOT="$2"
export CARGO_TARGET_DIR="$MESON_BUILD_ROOT"/target export CARGO_TARGET_DIR="$MESON_BUILD_ROOT"/target
export CARGO_HOME="$CARGO_TARGET_DIR"/cargo-home export CARGO_HOME="$CARGO_TARGET_DIR"/cargo-home
FEATURES="$6"
if [[ $4 = "Devel" ]] if [[ $4 = "Devel" ]]
then then
echo "DEBUG MODE" echo "DEBUG MODE"
cargo build --manifest-path \ cargo build --manifest-path \
"$MESON_SOURCE_ROOT"/Cargo.toml --verbose && \ "$MESON_SOURCE_ROOT"/Cargo.toml $FEATURES && \
cp "$CARGO_TARGET_DIR"/debug/$5 $3 cp "$CARGO_TARGET_DIR"/debug/$5 $3
else else
echo "RELEASE MODE" echo "RELEASE MODE"
cargo build --manifest-path \ cargo build --manifest-path \
"$MESON_SOURCE_ROOT"/Cargo.toml --release && \ "$MESON_SOURCE_ROOT"/Cargo.toml $FEATURES --release && \
cp "$CARGO_TARGET_DIR"/release/$5 $3 cp "$CARGO_TARGET_DIR"/release/$5 $3
fi fi
...@@ -14,11 +14,7 @@ ...@@ -14,11 +14,7 @@
"--share=ipc", "--share=ipc",
"--socket=fallback-x11", "--socket=fallback-x11",
"--socket=wayland", "--socket=wayland",
"--device=dri", "--device=dri"
"--filesystem=xdg-run/dconf",
"--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf",
"--env=DCONF_USER_CONFIG_DIR=.config/dconf"
], ],
"build-options" : { "build-options" : {
"append-path" : "/usr/lib/sdk/rust-stable/bin", "append-path" : "/usr/lib/sdk/rust-stable/bin",
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<id>@app-id@</id> <id>@app-id@</id>
<metadata_license>CC0</metadata_license> <metadata_license>CC0</metadata_license>
<project_license>GPL-3.0+</project_license> <project_license>GPL-3.0+</project_license>
<name>GNOME Tour</name> <name>Tour</name>
<summary>GNOME Tour and Greeter.</summary> <summary>GNOME Tour and Greeter.</summary>
<description> <description>
<p>A guided tour and greeter for GNOME.</p> <p>A guided tour and greeter for GNOME.</p>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -11,6 +11,15 @@ ...@@ -11,6 +11,15 @@
font-weight: 400; font-weight: 400;
font-size: 12pt; font-size: 12pt;
} }
.video {
opacity: 0;
}
.video.playing {
opacity: 1;
transition-property: opacity;
transition-duration: 250ms;
transition-timing-function: ease-in-out;
}
.last-page { .last-page {
background-color: #4a86cf; /*GNOME blue*/ background-color: #4a86cf; /*GNOME blue*/
......
...@@ -13,6 +13,11 @@ dependency('gio-2.0', version: '>= 2.56') ...@@ -13,6 +13,11 @@ dependency('gio-2.0', version: '>= 2.56')
dependency('gdk-pixbuf-2.0') dependency('gdk-pixbuf-2.0')
dependency('gtk+-3.0', version: '>= 3.16') dependency('gtk+-3.0', version: '>= 3.16')
if get_option('video_path') != ''
dependency('gstreamer-1.0', version: '>= 1.12')
dependency('gstreamer-video-1.0', version: '>= 1.12')
dependency('gstreamer-player-1.0', version: '>= 1.12')
endif
glib_compile_resources = find_program('glib-compile-resources', required: true) glib_compile_resources = find_program('glib-compile-resources', required: true)
desktop_file_validate = find_program('desktop-file-validate', required: false) desktop_file_validate = find_program('desktop-file-validate', required: false)
......
...@@ -9,3 +9,9 @@ option ( ...@@ -9,3 +9,9 @@ option (
description: 'The build profile for GNOME Tour. One of "default" or "development".' description: 'The build profile for GNOME Tour. One of "default" or "development".'
) )
option(
'video_path',
type : 'string',
value: '',
description : 'Sets the absolute path of a welcome video'
)
...@@ -5,3 +5,5 @@ pub static NAME_SUFFIX: &str = @NAME_SUFFIX@; ...@@ -5,3 +5,5 @@ pub static NAME_SUFFIX: &str = @NAME_SUFFIX@;
pub static VERSION: &str = @VERSION@; pub static VERSION: &str = @VERSION@;
pub static GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@; pub static GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@;
pub static LOCALEDIR: &str = @LOCALEDIR@; pub static LOCALEDIR: &str = @LOCALEDIR@;
#[cfg(feature = "video")]
pub static VIDEO_PATH: &str = @VIDEO_PATH@;
...@@ -20,6 +20,8 @@ fn main() { ...@@ -20,6 +20,8 @@ fn main() {
glib::set_prgname(Some("Tour")); glib::set_prgname(Some("Tour"));
gtk::init().expect("Unable to start GTK3"); gtk::init().expect("Unable to start GTK3");
#[cfg(feature = "video")]
gst::init().expect("Unable to start gst");
static_resources::init().expect("Failed to initialize the resource file."); static_resources::init().expect("Failed to initialize the resource file.");
......
...@@ -6,6 +6,7 @@ global_conf.set_quoted('NAME_SUFFIX', name_suffix) ...@@ -6,6 +6,7 @@ global_conf.set_quoted('NAME_SUFFIX', name_suffix)
global_conf.set_quoted('VERSION', version + version_suffix) global_conf.set_quoted('VERSION', version + version_suffix)
global_conf.set_quoted('GETTEXT_PACKAGE', gettext_package) global_conf.set_quoted('GETTEXT_PACKAGE', gettext_package)
global_conf.set_quoted('LOCALEDIR', localedir) global_conf.set_quoted('LOCALEDIR', localedir)
global_conf.set_quoted('VIDEO_PATH', get_option('video_path'))
config = configure_file( config = configure_file(
input: 'config.rs.in', input: 'config.rs.in',
output: 'config.rs', output: 'config.rs',
...@@ -49,6 +50,10 @@ sources = files( ...@@ -49,6 +50,10 @@ sources = files(
'utils.rs', 'utils.rs',
) )
features = ''
if get_option('video_path') != ''
features = '--features video'
endif
custom_target( custom_target(
'cargo-build', 'cargo-build',
build_by_default: true, build_by_default: true,
...@@ -65,6 +70,7 @@ custom_target( ...@@ -65,6 +70,7 @@ custom_target(
'@OUTPUT@', '@OUTPUT@',
profile, profile,
meson.project_name(), meson.project_name(),
features
] ]
) )
use super::page::Pageable;
use gtk::prelude::*; use gtk::prelude::*;
pub struct ImagePageWidget { pub struct ImagePageWidget {
pub widget: gtk::Box, pub widget: gtk::Box,
pub title: String,
}
impl Pageable for ImagePageWidget {
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast::<gtk::Widget>()
}
fn get_title(&self) -> String {
self.title.clone()
}
} }
impl ImagePageWidget { impl ImagePageWidget {
pub fn new(resource_uri: &str, title: String, head: String, body: String) -> Self { pub fn new(resource_uri: &str, head: String, body: String) -> Self {
let widget = gtk::Box::new(gtk::Orientation::Vertical, 0); let widget = gtk::Box::new(gtk::Orientation::Vertical, 0);
let image_page = Self { widget, title }; let image_page = Self { widget };
image_page.init(resource_uri, head, body); image_page.init(resource_uri, head, body);
image_page image_page
...@@ -34,6 +22,7 @@ impl ImagePageWidget { ...@@ -34,6 +22,7 @@ impl ImagePageWidget {
let container = gtk::Box::new(gtk::Orientation::Vertical, 12); let container = gtk::Box::new(gtk::Orientation::Vertical, 12);
container.set_halign(gtk::Align::Center); container.set_halign(gtk::Align::Center);
container.set_valign(gtk::Align::Center); container.set_valign(gtk::Align::Center);
container.set_vexpand(true);
container.set_margin_bottom(48); container.set_margin_bottom(48);
container.set_margin_top(12); container.set_margin_top(12);
container.set_margin_start(12); container.set_margin_start(12);
......
mod image; mod image;
mod page;
mod welcome; mod welcome;
pub use image::ImagePageWidget; pub use image::ImagePageWidget;
pub use page::Pageable;
pub use welcome::WelcomePageWidget; pub use welcome::WelcomePageWidget;
pub trait Pageable {
fn get_widget(&self) -> gtk::Widget;
fn get_title(&self) -> String;
}
use super::page::Pageable; #[cfg(feature = "video")]
use crate::config;
use gettextrs::gettext; use gettextrs::gettext;
#[cfg(feature = "video")]
use gio::FileExt;
#[cfg(feature = "video")]
use glib::clone;
#[cfg(feature = "video")]
use glib::{Receiver, Sender};
use gtk::prelude::*; use gtk::prelude::*;
#[cfg(feature = "video")]
use std::cell::RefCell;
pub struct WelcomePageWidget { #[derive(PartialEq)]
pub widget: gtk::Box, #[cfg(feature = "video")]
pub title: String, pub enum Action {
VideoReady,
VideoUp,
} }
impl Pageable for WelcomePageWidget { pub struct WelcomePageWidget {
fn get_widget(&self) -> gtk::Widget { pub widget: libhandy::WindowHandle,
self.widget.clone().upcast::<gtk::Widget>() #[cfg(feature = "video")]
} player: gst_player::Player,
#[cfg(feature = "video")]
fn get_title(&self) -> String { receiver: RefCell<Option<Receiver<Action>>>,
self.title.clone() #[cfg(feature = "video")]
} sender: Sender<Action>,
} }
impl WelcomePageWidget { impl WelcomePageWidget {
pub fn new() -> Self { pub fn new() -> Self {
let widget = gtk::Box::new(gtk::Orientation::Vertical, 0); let widget = libhandy::WindowHandle::new();
#[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 { let welcome_page = Self {
widget, widget,
title: gettext("Welcome Tour"), #[cfg(feature = "video")]
player,
#[cfg(feature = "video")]
sender,
#[cfg(feature = "video")]
receiver,
}; };
welcome_page.init(); welcome_page.init();
...@@ -30,32 +59,99 @@ impl WelcomePageWidget { ...@@ -30,32 +59,99 @@ impl WelcomePageWidget {
} }
fn init(&self) { fn init(&self) {
self.widget.set_property_expand(true); let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
self.widget.set_valign(gtk::Align::Center);
self.widget.set_halign(gtk::Align::Center);
self.widget.set_margin_top(24);
self.widget.set_margin_bottom(24);
let name = glib::get_os_info("NAME").unwrap_or_else(|| "GNOME".into()); container.set_property_expand(true);
let version = glib::get_os_info("VERSION").unwrap_or_else(|| "3.36".into()); container.set_valign(gtk::Align::Center);
container.set_halign(gtk::Align::Center);
container.set_margin_top(24);
container.set_margin_bottom(24);
#[cfg(not(feature = "video"))]
let header = {
let icon = glib::get_os_info("LOGO").unwrap_or_else(|| "start-here-symbolic".into()); 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); let logo = gtk::Image::from_icon_name(Some(&icon), gtk::IconSize::Dialog);
logo.set_pixel_size(196); logo.set_pixel_size(196);
logo.show(); logo.show();
self.widget.add(&logo);
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
};
container.add(&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.get_style_context().add_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 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)))); let title = gtk::Label::new(Some(&gettext(format!("Welcome to {} {}", name, version))));
title.set_margin_top(36); title.set_margin_top(36);
title.get_style_context().add_class("large-title"); title.get_style_context().add_class("large-title");
title.show(); title.show();
self.widget.add(&title); container.add(&title);
let text = gtk::Label::new(Some(&gettext("Hi there! Take the tour to learn your way around and discover essential features."))); let text = gtk::Label::new(Some(&gettext("Hi there! Take the tour to learn your way around and discover essential features.")));
text.get_style_context().add_class("body"); text.get_style_context().add_class("body");
text.set_margin_top(12); text.set_margin_top(12);
text.show(); text.show();
self.widget.add(&text); container.add(&text);
let actions_container = gtk::Box::new(gtk::Orientation::Horizontal, 12); let actions_container = gtk::Box::new(gtk::Orientation::Horizontal, 12);
actions_container.set_halign(gtk::Align::Center); actions_container.set_halign(gtk::Align::Center);
...@@ -81,7 +177,10 @@ impl WelcomePageWidget { ...@@ -81,7 +177,10 @@ impl WelcomePageWidget {
actions_container.show(); actions_container.show();
self.widget.add(&actions_container); container.add(&actions_container);
container.show();
self.widget.add(&container);
self.widget.show(); self.widget.show();
} }
} }
...@@ -5,7 +5,6 @@ use gtk::prelude::*; ...@@ -5,7 +5,6 @@ use gtk::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use super::pages::Pageable;
use libhandy::prelude::{CarouselExt, CarouselIndicatorDotsExt, HeaderBarExt}; use libhandy::prelude::{CarouselExt, CarouselIndicatorDotsExt, HeaderBarExt};
pub struct PaginatorWidget { pub struct PaginatorWidget {
...@@ -13,7 +12,7 @@ pub struct PaginatorWidget { ...@@ -13,7 +12,7 @@ pub struct PaginatorWidget {
carousel: libhandy::Carousel, carousel: libhandy::Carousel,
carousel_dots: libhandy::CarouselIndicatorDots, carousel_dots: libhandy::CarouselIndicatorDots,
headerbar: libhandy::HeaderBar, headerbar: libhandy::HeaderBar,
pages: RefCell<Vec<Box<dyn Pageable>>>, pages: RefCell<Vec<gtk::Widget>>,
current_page: RefCell<u32>, current_page: RefCell<u32>,
next_btn: gtk::Button, next_btn: gtk::Button,
close_btn: gtk::Button, close_btn: gtk::Button,
...@@ -57,9 +56,9 @@ impl PaginatorWidget { ...@@ -57,9 +56,9 @@ impl PaginatorWidget {
Ok(()) Ok(())
} }
pub fn add_page(&self, page: Box<dyn Pageable>) { pub fn add_page(&self, page: gtk::Widget) {
let page_nr = self.pages.borrow().len(); let page_nr = self.pages.borrow().len();
self.carousel.insert(&page.get_widget(), page_nr as i32); self.carousel.insert(&page, page_nr as i32);
self.pages.borrow_mut().push(page); self.pages.borrow_mut().push(page);
self.update_position(); self.update_position();
...@@ -135,7 +134,7 @@ impl PaginatorWidget { ...@@ -135,7 +134,7 @@ impl PaginatorWidget {
if page_nr < self.carousel.get_n_pages() { if page_nr < self.carousel.get_n_pages() {
let pages = &self.pages.borrow(); let pages = &self.pages.borrow();
let page = pages.get(page_nr as usize).unwrap(); let page = pages.get(page_nr as usize).unwrap();
self.carousel.scroll_to(&page.get_widget()); self.carousel.scroll_to(page);
} }
} }
} }
...@@ -35,59 +35,73 @@ impl Window { ...@@ -35,59 +35,73 @@ impl Window {
} }
fn init(&mut self) { fn init(&mut self) {
self.widget.set_default_size(720, 500); self.widget.set_default_size(960, 720);
self.widget.set_icon_name(Some(APP_ID)); self.widget.set_icon_name(Some(APP_ID));
// Devel Profile // Devel Profile
if PROFILE == "Devel" { if PROFILE == "Devel" {
self.widget.get_style_context().add_class("devel"); self.widget.get_style_context().add_class("devel");
} }
self.paginator.borrow_mut().add_page(Box::new(WelcomePageWidget::new())); self.paginator.borrow_mut().add_page(WelcomePageWidget::new().widget.upcast::<gtk::Widget>());
self.paginator.borrow_mut().add_page(Box::new(ImagePageWidget::new( self.paginator.borrow_mut().add_page(
ImagePageWidget::new(
"/org/gnome/Tour/activities.svg", "/org/gnome/Tour/activities.svg",
gettext("Activities Overview"),
gettext("Open Activities to launch apps"), gettext("Open Activities to launch apps"),
gettext("The activities view can also be used to switch windows and search."), gettext("The activities view can also be used to switch windows and search."),
))); )
.widget
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(Box::new(ImagePageWidget::new( self.paginator.borrow_mut().add_page(
ImagePageWidget::new(
"/org/gnome/Tour/search.svg", "/org/gnome/Tour/search.svg",
gettext("Search"),
gettext("Just type to search"), gettext("Just type to search"),
gettext("In the activities view, just start typing to search for apps, settings and more."), gettext("In the activities view, just start typing to search for apps, settings and more."),
))); )
.widget
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(Box::new(ImagePageWidget::new( self.paginator.borrow_mut().add_page(
ImagePageWidget::new(
"/org/gnome/Tour/calendar.svg", "/org/gnome/Tour/calendar.svg",
gettext("Date & Time"),
gettext("Click the time to see notifications"), gettext("Click the time to see notifications"),
gettext("The notifications popover also includes personal planning tools."), gettext("The notifications popover also includes personal planning tools."),
))); )
.widget
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(Box::new(ImagePageWidget::new( self.paginator.borrow_mut().add_page(
ImagePageWidget::new(
"/org/gnome/Tour/status-menu.svg", "/org/gnome/Tour/status-menu.svg",
gettext("System Menu"),
gettext("View system information and settings"), gettext("View system information and settings"),
gettext("Get an overview of the system status and quickly change settings."), gettext("Get an overview of the system status and quickly change settings."),
))); )
.widget
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(Box::new(ImagePageWidget::new( self.paginator.borrow_mut().add_page(
ImagePageWidget::new(
"/org/gnome/Tour/software.svg", "/org/gnome/Tour/software.svg",
gettext("Software"),
gettext("Use Software to find and install apps"), gettext("Use Software to find and install apps"),
gettext("Discover great apps through search, browsing and our recommendations."), gettext("Discover great apps through search, browsing and our recommendations."),
))); )
.widget
.upcast::<gtk::Widget>(),
);
let name = glib::get_os_info("NAME").unwrap_or_else(|| "GNOME".into()); let name = glib::get_os_info("NAME").unwrap_or_else(|| "GNOME".into());
let last_page = ImagePageWidget::new( let last_page = ImagePageWidget::new(
"/org/gnome/Tour/ready-to-go.svg", "/org/gnome/Tour/ready-to-go.svg",
gettext("Tour Completed"),
utils::i18n_f("That's it! We hope that you enjoy {}.", &[&name]), utils::i18n_f("That's it! We hope that you enjoy {}.", &[&name]),
gettext("To get more advice and tips, see the Help app."), gettext("To get more advice and tips, see the Help app."),
); );
last_page.widget.get_style_context().add_class("last-page"); last_page.widget.get_style_context().add_class("last-page");
self.paginator.borrow_mut().add_page(Box::new(last_page)); self.paginator.borrow_mut().add_page(last_page.widget.upcast::<gtk::Widget>());
self.widget.add(&self.paginator.borrow().widget); self.widget.add(&self.paginator.borrow().widget);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment