diff --git a/src/lib/clapper-gtk/clapper-gtk-video-placeholder-private.h b/src/lib/clapper-gtk/clapper-gtk-video-placeholder-private.h new file mode 100644 index 000000000..794a881d0 --- /dev/null +++ b/src/lib/clapper-gtk/clapper-gtk-video-placeholder-private.h @@ -0,0 +1,38 @@ +/* Clapper GTK Integration Library + * Copyright (C) 2024 Rafał Dzięgiel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include +#include + +#include "clapper-gtk-container.h" + +G_BEGIN_DECLS + +#define CLAPPER_GTK_TYPE_VIDEO_PLACEHOLDER (clapper_gtk_video_placeholder_get_type()) +#define CLAPPER_GTK_VIDEO_PLACEHOLDER_CAST(obj) ((ClapperGtkVideoPlaceholder *)(obj)) + +G_DECLARE_FINAL_TYPE (ClapperGtkVideoPlaceholder, clapper_gtk_video_placeholder, CLAPPER_GTK, VIDEO_PLACEHOLDER, ClapperGtkContainer) + +G_GNUC_INTERNAL +GtkWidget * clapper_gtk_video_placeholder_new (void); + +G_END_DECLS diff --git a/src/lib/clapper-gtk/clapper-gtk-video-placeholder.c b/src/lib/clapper-gtk/clapper-gtk-video-placeholder.c new file mode 100644 index 000000000..99001672d --- /dev/null +++ b/src/lib/clapper-gtk/clapper-gtk-video-placeholder.c @@ -0,0 +1,145 @@ +/* Clapper GTK Integration Library + * Copyright (C) 2024 Rafał Dzięgiel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include +#include + +#include "clapper-gtk-video-placeholder-private.h" +#include "clapper-gtk-utils-private.h" + +#define NORMAL_SPACING 16 +#define ADAPT_SPACING 8 + +#define GST_CAT_DEFAULT clapper_gtk_video_placeholder_debug +GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); + +struct _ClapperGtkVideoPlaceholder +{ + ClapperGtkContainer parent; + + GtkWidget *box; + GtkWidget *title_label; + + ClapperPlayer *player; +}; + +#define parent_class clapper_gtk_video_placeholder_parent_class +G_DEFINE_TYPE (ClapperGtkVideoPlaceholder, clapper_gtk_video_placeholder, CLAPPER_GTK_TYPE_CONTAINER) + +static void +adapt_cb (ClapperGtkContainer *container, gboolean adapt, + ClapperGtkVideoPlaceholder *self) +{ + GST_DEBUG_OBJECT (self, "Adapted: %s", (adapt) ? "yes" : "no"); + + gtk_box_set_spacing (GTK_BOX (self->box), (adapt) ? ADAPT_SPACING : NORMAL_SPACING); + + if (adapt) { + gtk_widget_add_css_class (GTK_WIDGET (self), "adapted"); + gtk_widget_add_css_class (GTK_WIDGET (self->title_label), "title-2"); + } else { + gtk_widget_remove_css_class (GTK_WIDGET (self), "adapted"); + gtk_widget_remove_css_class (GTK_WIDGET (self->title_label), "title-2"); + } +} + +static void +_player_state_changed_cb (ClapperPlayer *player, + GParamSpec *pspec G_GNUC_UNUSED, ClapperGtkVideoPlaceholder *self) +{ + gtk_widget_set_visible (self->box, + clapper_player_get_state (player) > CLAPPER_PLAYER_STATE_STOPPED); +} + +GtkWidget * +clapper_gtk_video_placeholder_new (void) +{ + return g_object_new (CLAPPER_GTK_TYPE_VIDEO_PLACEHOLDER, NULL); +} + +static void +clapper_gtk_video_placeholder_map (GtkWidget *widget) +{ + ClapperGtkVideoPlaceholder *self = CLAPPER_GTK_VIDEO_PLACEHOLDER_CAST (widget); + + if ((self->player = clapper_gtk_get_player_from_ancestor (widget))) { + g_signal_connect (self->player, "notify::state", + G_CALLBACK (_player_state_changed_cb), self); + _player_state_changed_cb (self->player, NULL, self); + } + + GTK_WIDGET_CLASS (parent_class)->map (widget); +} + +static void +clapper_gtk_video_placeholder_unmap (GtkWidget *widget) +{ + ClapperGtkVideoPlaceholder *self = CLAPPER_GTK_VIDEO_PLACEHOLDER_CAST (widget); + + if (self->player) { + g_signal_handlers_disconnect_by_func (self->player, _player_state_changed_cb, self); + self->player = NULL; + } + + GTK_WIDGET_CLASS (parent_class)->unmap (widget); +} + +static void +clapper_gtk_video_placeholder_init (ClapperGtkVideoPlaceholder *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); + + gtk_box_set_spacing (GTK_BOX (self->box), NORMAL_SPACING); +} + +static void +clapper_gtk_video_placeholder_dispose (GObject *object) +{ + gtk_widget_dispose_template (GTK_WIDGET (object), CLAPPER_GTK_TYPE_VIDEO_PLACEHOLDER); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +clapper_gtk_video_placeholder_class_init (ClapperGtkVideoPlaceholderClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; + + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappergtkvideoplaceholder", 0, + "Clapper GTK Video Placeholder"); + clapper_gtk_init_translations (); + + gobject_class->dispose = clapper_gtk_video_placeholder_dispose; + + widget_class->map = clapper_gtk_video_placeholder_map; + widget_class->unmap = clapper_gtk_video_placeholder_unmap; + + gtk_widget_class_set_template_from_resource (widget_class, + CLAPPER_GTK_RESOURCE_PREFIX "/ui/clapper-gtk-video-placeholder.ui"); + + gtk_widget_class_bind_template_child (widget_class, ClapperGtkVideoPlaceholder, box); + gtk_widget_class_bind_template_child (widget_class, ClapperGtkVideoPlaceholder, title_label); + + gtk_widget_class_bind_template_callback (widget_class, adapt_cb); + + gtk_widget_class_set_css_name (widget_class, "clapper-gtk-video-placeholder"); +} diff --git a/src/lib/clapper-gtk/clapper-gtk-video.c b/src/lib/clapper-gtk/clapper-gtk-video.c index 5cd252afa..2ca532794 100644 --- a/src/lib/clapper-gtk/clapper-gtk-video.c +++ b/src/lib/clapper-gtk/clapper-gtk-video.c @@ -101,6 +101,7 @@ #include "clapper-gtk-lead-container.h" #include "clapper-gtk-status-private.h" #include "clapper-gtk-buffering-animation-private.h" +#include "clapper-gtk-video-placeholder-private.h" #define PERCENTAGE_ROUND(a) (round ((gdouble) a / 0.01) * 0.01) @@ -1032,10 +1033,8 @@ _video_sink_changed_cb (ClapperPlayer *player, } if (!widget) { - /* FIXME: Create some default widget to show */ - widget = g_object_ref_sink (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); - GST_DEBUG_OBJECT (self, "No widget from video sink, using placeholder"); + widget = g_object_ref_sink (clapper_gtk_video_placeholder_new ()); } gtk_overlay_set_child (GTK_OVERLAY (self->overlay), widget); diff --git a/src/lib/clapper-gtk/clapper-gtk.gresources.xml b/src/lib/clapper-gtk/clapper-gtk.gresources.xml index c25bb2f60..b625109a6 100644 --- a/src/lib/clapper-gtk/clapper-gtk.gresources.xml +++ b/src/lib/clapper-gtk/clapper-gtk.gresources.xml @@ -9,6 +9,7 @@ ui/clapper-gtk-stream-list-item.ui ui/clapper-gtk-title-header.ui ui/clapper-gtk-video.ui + ui/clapper-gtk-video-placeholder.ui css/styles.css diff --git a/src/lib/clapper-gtk/css/styles.css b/src/lib/clapper-gtk/css/styles.css index f567a0609..0c67f446f 100644 --- a/src/lib/clapper-gtk/css/styles.css +++ b/src/lib/clapper-gtk/css/styles.css @@ -25,15 +25,21 @@ clapper-gtk-video clapper-gtk-status.osd { background-color: transparent; } -clapper-gtk-status box { +clapper-gtk-video-placeholder { + background-color: black; +} +clapper-gtk-status box, +clapper-gtk-video-placeholder box { padding-left: 6px; padding-right: 6px; } -clapper-gtk-status box image { +clapper-gtk-status box image, +clapper-gtk-video-placeholder box image { -gtk-icon-size: 128px; -gtk-icon-filter: opacity(0.6); } -clapper-gtk-status.adapted box image { +clapper-gtk-status.adapted box image, +clapper-gtk-video-placeholder.adapted box image { -gtk-icon-size: 96px; } diff --git a/src/lib/clapper-gtk/meson.build b/src/lib/clapper-gtk/meson.build index 84d8b17ac..f2dacb82d 100644 --- a/src/lib/clapper-gtk/meson.build +++ b/src/lib/clapper-gtk/meson.build @@ -128,6 +128,7 @@ clappergtk_sources = [ 'clapper-gtk-toggle-play-button.c', 'clapper-gtk-utils.c', 'clapper-gtk-video.c', + 'clapper-gtk-video-placeholder.c', clappergtk_resources, ] clappergtk_c_args = [ diff --git a/src/lib/clapper-gtk/po/POTFILES b/src/lib/clapper-gtk/po/POTFILES index 1fbd4c32d..332385af7 100644 --- a/src/lib/clapper-gtk/po/POTFILES +++ b/src/lib/clapper-gtk/po/POTFILES @@ -1,4 +1,5 @@ src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui +src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c src/lib/clapper-gtk/clapper-gtk-status.c diff --git a/src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui b/src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui new file mode 100644 index 000000000..3096adfab --- /dev/null +++ b/src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui @@ -0,0 +1,46 @@ + + + +