[evince] ev-media: Make EvMediaPlayer a self contained widget to show the video and the controls
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] ev-media: Make EvMediaPlayer a self contained widget to show the video and the controls
- Date: Fri, 5 Jun 2015 10:36:07 +0000 (UTC)
commit 1f31e0815e2c40c8983d2c9fd759220134050642
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Fri Jun 5 10:09:02 2015 +0200
ev-media: Make EvMediaPlayer a self contained widget to show the video and the controls
Using the EvView window with gst_video_overlay_set_render_rectangle()
to paint the videos seems to cause issues in some cases where the video
is not correctly positioned, or uses the whole view area. To avoid that,
we use now a specific widget (a GtkDrawingArea) to render the video
instead. EvMediaPlayer is not a GtkBox containing the drawing area and
the media controls. This simplifies the code a lot and requires less
code in EvView which will also make easier to add support for videos
in presentation view.
libview/Makefile.am | 2 -
libview/ev-media-controls.c | 179 -------------------
libview/ev-media-controls.h | 45 -----
libview/ev-media-player.c | 410 ++++++++++++++++++++++---------------------
libview/ev-media-player.h | 17 +--
libview/ev-view.c | 174 ++++---------------
6 files changed, 246 insertions(+), 581 deletions(-)
---
diff --git a/libview/Makefile.am b/libview/Makefile.am
index 3ffabeb..52e48e1 100644
--- a/libview/Makefile.am
+++ b/libview/Makefile.am
@@ -57,8 +57,6 @@ libevview3_la_SOURCES = \
if ENABLE_MULTIMEDIA
libevview3_la_SOURCES += \
- ev-media-controls.h \
- ev-media-controls.c \
ev-media-player.h \
ev-media-player.c
endif
diff --git a/libview/ev-media-player.c b/libview/ev-media-player.c
index acde3d7..1c7f1a2 100644
--- a/libview/ev-media-player.c
+++ b/libview/ev-media-player.c
@@ -24,30 +24,30 @@
#include <gst/video/videooverlay.h>
+#if defined (GDK_WINDOWING_X11)
+#include <gdk/gdkx.h>
+#elif defined (GDK_WINDOWING_WIN32)
+#include <gdk/gdkwin32.h>
+#endif
+
enum {
PROP_0,
PROP_MEDIA,
- PROP_WINDOW_ID,
- PROP_RENDER_AREA,
- PROP_DURATION,
- PROP_POSITION
-};
-
-enum {
- STATE_CHANGED,
- N_SIGNALS
};
struct _EvMediaPlayer {
- GObject parent;
+ GtkBox parent;
EvMedia *media;
- guint64 window_id;
- GdkRectangle render_area;
+ GtkWidget *drawing_area;
+ GtkWidget *controls;
+ GtkWidget *play_button;
+ GtkWidget *slider;
GstElement *pipeline;
GstBus *bus;
GstVideoOverlay *overlay;
+ guint64 window_handle;
gboolean is_playing;
gboolean is_seeking;
gdouble duration;
@@ -57,38 +57,48 @@ struct _EvMediaPlayer {
};
struct _EvMediaPlayerClass {
- GObjectClass parent_class;
+ GtkBoxClass parent_class;
};
-static guint signals[N_SIGNALS];
+G_DEFINE_TYPE (EvMediaPlayer, ev_media_player, GTK_TYPE_BOX)
+
+static void
+ev_media_player_update_position (EvMediaPlayer *player)
+{
+ if (!ev_media_get_show_controls (player->media))
+ return;
-G_DEFINE_TYPE (EvMediaPlayer, ev_media_player, G_TYPE_OBJECT)
+ gtk_range_set_value (GTK_RANGE (player->slider), player->position);
+}
static gboolean
-update_position_cb (EvMediaPlayer *player)
+query_position_cb (EvMediaPlayer *player)
{
gint64 position;
gst_element_query_position (player->pipeline, GST_FORMAT_TIME, &position);
player->position = (gdouble)position / GST_SECOND;
- g_object_notify (G_OBJECT (player), "position");
+ ev_media_player_update_position (player);
return G_SOURCE_CONTINUE;
}
static void
-ev_media_player_update_position_start (EvMediaPlayer *player)
+ev_media_player_query_position_start (EvMediaPlayer *player)
{
if (player->position_timeout_id > 0)
return;
+ if (!ev_media_get_show_controls (player->media))
+ return;
+
player->position_timeout_id = g_timeout_add (1000 / 15,
- (GSourceFunc)update_position_cb,
+ (GSourceFunc)query_position_cb,
player);
}
static void
-ev_media_player_update_position_stop (EvMediaPlayer *player)
+ev_media_player_query_position_stop (EvMediaPlayer *player)
{
if (player->position_timeout_id > 0) {
g_source_remove (player->position_timeout_id);
@@ -97,16 +107,30 @@ ev_media_player_update_position_stop (EvMediaPlayer *player)
}
static void
-ev_media_player_update_position (EvMediaPlayer *player)
+ev_media_player_query_position (EvMediaPlayer *player)
{
+ if (!ev_media_get_show_controls (player->media))
+ return;
+
if (player->duration <= 0)
return;
if (player->is_playing)
- ev_media_player_update_position_start (player);
+ ev_media_player_query_position_start (player);
else
- ev_media_player_update_position_stop (player);
- update_position_cb (player);
+ ev_media_player_query_position_stop (player);
+ query_position_cb (player);
+}
+
+static void
+ev_media_player_update_play_button (EvMediaPlayer *player)
+{
+ if (!ev_media_get_show_controls (player->media))
+ return;
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (gtk_button_get_image (GTK_BUTTON (player->play_button))),
+ player->is_playing ? "media-playback-pause-symbolic" :
"media-playback-start-symbolic",
+ GTK_ICON_SIZE_MENU);
}
static void
@@ -121,8 +145,8 @@ ev_media_player_update_state (EvMediaPlayer *player,
is_playing = state == GST_STATE_PLAYING;
if (is_playing != player->is_playing) {
player->is_playing = is_playing;
- g_signal_emit (player, signals[STATE_CHANGED], 0, player->is_playing ?
EV_MEDIA_PLAYER_STATE_PLAY : EV_MEDIA_PLAYER_STATE_PAUSE);
- ev_media_player_update_position (player);
+ ev_media_player_update_play_button (player);
+ ev_media_player_query_position (player);
}
if (new_state)
@@ -130,12 +154,53 @@ ev_media_player_update_state (EvMediaPlayer *player,
}
static void
+ev_media_player_toggle_state (EvMediaPlayer *player)
+{
+ GstState current, pending, new_state;
+
+ if (!player->pipeline)
+ return;
+
+ gst_element_get_state (player->pipeline, ¤t, &pending, 0);
+ new_state = current == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
+ if (pending != new_state)
+ gst_element_set_state (player->pipeline, new_state);
+}
+
+static void
+ev_media_player_seek (EvMediaPlayer *player,
+ GtkScrollType scroll,
+ gdouble position)
+{
+ if (!player->pipeline)
+ return;
+
+ position = CLAMP (position, 0, player->duration);
+ if (gst_element_seek_simple (player->pipeline,
+ GST_FORMAT_TIME,
+ GST_SEEK_FLAG_FLUSH,
+ (gint64)(position * GST_SECOND))) {
+ player->is_seeking = TRUE;
+ ev_media_player_query_position_stop (player);
+ player->position = position;
+ ev_media_player_update_position (player);
+ }
+}
+
+
+static void
ev_media_player_notify_eos (EvMediaPlayer *player)
{
- g_signal_emit (player, signals[STATE_CHANGED], 0, EV_MEDIA_PLAYER_STATE_PAUSE);
- ev_media_player_update_position_stop (player);
+ if (!ev_media_get_show_controls (player->media)) {
+ /* A media without controls can't be played again */
+ gtk_widget_destroy (GTK_WIDGET (player));
+ return;
+ }
+
+ ev_media_player_update_play_button (player);
+ ev_media_player_query_position_stop (player);
player->position = 0;
- g_object_notify (G_OBJECT (player), "position");
+ ev_media_player_update_position (player);
gst_element_set_state (player->pipeline, GST_STATE_READY);
}
@@ -150,12 +215,7 @@ bus_sync_handle (GstBus *bus,
return GST_BUS_PASS;
overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
- gst_video_overlay_set_window_handle (overlay, (guintptr)player->window_id);
- gst_video_overlay_set_render_rectangle (overlay,
- player->render_area.x,
- player->render_area.y,
- player->render_area.width,
- player->render_area.height);
+ gst_video_overlay_set_window_handle (overlay, (guintptr)player->window_handle);
gst_video_overlay_expose (overlay);
player->overlay = overlay;
@@ -195,10 +255,13 @@ bus_message_handle (GstBus *bus,
if (GST_MESSAGE_SRC (message) != (GstObject *)player->pipeline)
return;
+ if (!ev_media_get_show_controls (player->media))
+ return;
+
if (player->is_seeking) {
player->is_seeking = FALSE;
if (player->is_playing)
- ev_media_player_update_position_start (player);
+ ev_media_player_query_position_start (player);
} else {
ev_media_player_update_state (player, &state);
@@ -207,7 +270,7 @@ bus_message_handle (GstBus *bus,
gst_element_query_duration (player->pipeline, GST_FORMAT_TIME, &duration);
player->duration = (gdouble)duration / GST_SECOND;
- g_object_notify (G_OBJECT (player), "duration");
+ gtk_range_set_range (GTK_RANGE (player->slider), 0, player->duration);
}
}
@@ -224,11 +287,51 @@ bus_message_handle (GstBus *bus,
}
static void
+drawing_area_realize_cb (GtkWidget *widget,
+ EvMediaPlayer *player)
+{
+#if defined (GDK_WINDOWING_X11)
+ player->window_handle = (guint64)GDK_WINDOW_XID (gtk_widget_get_window (widget));
+#elif defined (GDK_WINDOWING_WIN32)
+ player->window_handle = (guint64)GDK_WINDOW_HWND (gtk_widget_get_window (widget));
+#else
+ g_assert_not_reached ();
+#endif
+}
+
+static void
+ev_media_player_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EvMediaPlayer *player = EV_MEDIA_PLAYER (widget);
+ GdkRectangle controls_allocation;
+
+ GTK_WIDGET_CLASS (ev_media_player_parent_class)->size_allocate (widget, allocation);
+
+ if (!ev_media_get_show_controls (player->media))
+ return;
+
+ /* Give all the allocated size to the drawing area */
+ gtk_widget_size_allocate (player->drawing_area, allocation);
+
+ /* And give space for the controls below */
+ controls_allocation.x = allocation->x;
+ controls_allocation.y = allocation->y + allocation->height;
+ controls_allocation.width = allocation->width;
+ controls_allocation.height = gtk_widget_get_allocated_height (player->controls);
+ gtk_widget_size_allocate (player->controls, &controls_allocation);
+
+ allocation->height += controls_allocation.height;
+
+ gtk_widget_set_allocation (widget, allocation);
+}
+
+static void
ev_media_player_dispose (GObject *object)
{
EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
- ev_media_player_update_position_stop (player);
+ ev_media_player_query_position_stop (player);
if (player->bus) {
gst_bus_remove_signal_watch (player->bus);
@@ -248,26 +351,6 @@ ev_media_player_dispose (GObject *object)
}
static void
-ev_media_player_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
-
- switch (prop_id) {
- case PROP_DURATION:
- g_value_set_double (value, player->duration);
- break;
- case PROP_POSITION:
- g_value_set_double (value, player->position);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
ev_media_player_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -279,12 +362,6 @@ ev_media_player_set_property (GObject *object,
case PROP_MEDIA:
player->media = EV_MEDIA (g_value_dup_object (value));
break;
- case PROP_WINDOW_ID:
- player->window_id = g_value_get_uint64 (value);
- break;
- case PROP_RENDER_AREA:
- ev_media_player_set_render_area (player, (GdkRectangle *)g_value_get_boxed (value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -293,12 +370,21 @@ ev_media_player_set_property (GObject *object,
static void
ev_media_player_init (EvMediaPlayer *player)
{
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (player), GTK_ORIENTATION_VERTICAL);
+
player->pipeline = gst_element_factory_make ("playbin", NULL);
if (!player->pipeline) {
g_warning ("Failed to create playbin\n");
return;
}
+ player->drawing_area = gtk_drawing_area_new ();
+ g_signal_connect (player->drawing_area, "realize",
+ G_CALLBACK (drawing_area_realize_cb),
+ player);
+ gtk_box_pack_start (GTK_BOX (player), player->drawing_area, TRUE, TRUE, 0);
+ gtk_widget_show (player->drawing_area);
+
player->bus = gst_pipeline_get_bus (GST_PIPELINE (player->pipeline));
gst_bus_set_sync_handler (player->bus, (GstBusSyncHandler)bus_sync_handle, player, NULL);
gst_bus_add_signal_watch (player->bus);
@@ -308,12 +394,62 @@ ev_media_player_init (EvMediaPlayer *player)
}
static void
+ev_media_player_setup_media_controls (EvMediaPlayer *player)
+{
+ GtkAdjustment *adjustment;
+ GtkCssProvider *provider;
+
+ player->controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+ gtk_style_context_add_class (gtk_widget_get_style_context (player->controls), GTK_STYLE_CLASS_OSD);
+
+ player->play_button = gtk_button_new ();
+ g_signal_connect_swapped (player->play_button, "clicked",
+ G_CALLBACK (ev_media_player_toggle_state),
+ player);
+ gtk_widget_set_name (player->play_button, "ev-media-player-play-button");
+ gtk_widget_set_valign (player->play_button, GTK_ALIGN_CENTER);
+ gtk_button_set_relief (GTK_BUTTON (player->play_button), GTK_RELIEF_NONE);
+ gtk_button_set_image (GTK_BUTTON (player->play_button),
+ gtk_image_new_from_icon_name ("media-playback-start-symbolic",
+ GTK_ICON_SIZE_MENU));
+ gtk_button_set_label(GTK_BUTTON (player->play_button), NULL);
+ gtk_button_set_focus_on_click (GTK_BUTTON (player->play_button), FALSE);
+
+ provider = gtk_css_provider_new ();
+ gtk_css_provider_load_from_data (provider, "#ev-media-player-play-button { padding: 0px 8px 0px 8px;
}", -1, NULL);
+ gtk_style_context_add_provider (gtk_widget_get_style_context (player->play_button),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_USER);
+ g_object_unref (provider);
+
+ gtk_box_pack_start (GTK_BOX (player->controls), player->play_button, FALSE, TRUE, 0);
+ gtk_widget_show (player->play_button);
+
+ adjustment = gtk_adjustment_new (0, 0, 1, 0.1, 0.10, 0);
+ player->slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
+ g_signal_connect_swapped (player->slider, "change-value",
+ G_CALLBACK (ev_media_player_seek),
+ player);
+ gtk_widget_set_hexpand (player->slider, TRUE);
+ gtk_scale_set_draw_value (GTK_SCALE (player->slider), FALSE);
+ gtk_box_pack_start (GTK_BOX (player->controls), player->slider, FALSE, TRUE, 0);
+ gtk_widget_show (player->slider);
+
+ gtk_box_pack_start (GTK_BOX (player), player->controls, FALSE, FALSE, 0);
+ gtk_widget_show (player->controls);
+}
+
+static void
ev_media_player_constructed (GObject *object)
{
EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
G_OBJECT_CLASS (ev_media_player_parent_class)->constructed (object);
+ if (ev_media_get_show_controls (player->media))
+ ev_media_player_setup_media_controls (player);
+
if (!player->pipeline)
return;
@@ -324,7 +460,8 @@ ev_media_player_constructed (GObject *object)
static void
ev_media_player_class_init (EvMediaPlayerClass *klass)
{
- GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
if (!gst_is_initialized ()) {
GError *error = NULL;
@@ -337,8 +474,8 @@ ev_media_player_class_init (EvMediaPlayerClass *klass)
g_object_class->constructed = ev_media_player_constructed;
g_object_class->dispose = ev_media_player_dispose;
- g_object_class->get_property = ev_media_player_get_property;
g_object_class->set_property = ev_media_player_set_property;
+ widget_class->size_allocate = ev_media_player_size_allocate;
g_object_class_install_property (g_object_class,
PROP_MEDIA,
@@ -349,147 +486,20 @@ ev_media_player_class_init (EvMediaPlayerClass *klass)
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (g_object_class,
- PROP_WINDOW_ID,
- g_param_spec_uint64 ("window-id",
- "Window ID",
- "The identifier of the window where the media
will be rendered",
- 0, G_MAXUINT64, 0,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (g_object_class,
- PROP_RENDER_AREA,
- g_param_spec_boxed ("render-area",
- "Render area",
- "The area of the window where the media will be
rendered",
- GDK_TYPE_RECTANGLE,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (g_object_class,
- PROP_DURATION,
- g_param_spec_double ("duration",
- "Duration",
- "Duration of the media",
- 0, G_MAXDOUBLE, 0,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (g_object_class,
- PROP_POSITION,
- g_param_spec_double ("position",
- "Position",
- "Current position of the media",
- 0, G_MAXDOUBLE, 0,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
-
- signals[STATE_CHANGED] =
- g_signal_new ("state-changed",
- G_TYPE_FROM_CLASS (g_object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
}
-EvMediaPlayer *
-ev_media_player_new (EvMedia *media,
- guint64 window_id,
- GdkRectangle *area)
+GtkWidget *
+ev_media_player_new (EvMedia *media)
{
g_return_val_if_fail (EV_IS_MEDIA (media), NULL);
- g_return_val_if_fail (window_id > 0, NULL);
- g_return_val_if_fail (area != NULL, NULL);
-
- return EV_MEDIA_PLAYER (g_object_new (EV_TYPE_MEDIA_PLAYER,
- "media", media,
- "window-id", window_id,
- "render-area", area,
- NULL));
-}
-void
-ev_media_player_set_render_area (EvMediaPlayer *player,
- GdkRectangle *area)
-{
- g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
- g_return_if_fail (area != NULL);
-
- if (player->render_area.x == area->x &&
- player->render_area.y == area->y &&
- player->render_area.width == area->width &&
- player->render_area.height == area->height)
- return;
-
- player->render_area = *area;
- if (!player->overlay)
- return;
-
- gst_video_overlay_set_render_rectangle (player->overlay, area->x, area->y, area->width,
area->height);
- gst_video_overlay_expose (player->overlay);
+ return GTK_WIDGET (g_object_new (EV_TYPE_MEDIA_PLAYER, "media", media, NULL));
}
-void
-ev_media_player_expose (EvMediaPlayer *player)
+EvMedia *
+ev_media_player_get_media (EvMediaPlayer *player)
{
- g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
-
- if (!player->overlay)
- return;
+ g_return_val_if_fail (EV_IS_MEDIA_PLAYER (player), NULL);
- gst_video_overlay_expose (player->overlay);
-}
-
-gdouble
-ev_media_player_get_duration (EvMediaPlayer *player)
-{
- g_return_val_if_fail (EV_IS_MEDIA_PLAYER (player), 0);
-
- return player->duration;
-}
-
-gdouble
-ev_media_player_get_position (EvMediaPlayer *player)
-{
- g_return_val_if_fail (EV_IS_MEDIA_PLAYER (player), 0);
-
- return player->position;
-}
-
-void
-ev_media_player_toggle_state (EvMediaPlayer *player)
-{
- GstState current, pending, new_state;
-
- g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
-
- if (!player->pipeline)
- return;
-
- gst_element_get_state (player->pipeline, ¤t, &pending, 0);
- new_state = current == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
- if (pending != new_state)
- gst_element_set_state (player->pipeline, new_state);
-}
-
-void
-ev_media_player_seek (EvMediaPlayer *player,
- gdouble position)
-{
- g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
-
- if (!player->pipeline)
- return;
-
- position = CLAMP (position, 0, player->duration);
- if (gst_element_seek_simple (player->pipeline,
- GST_FORMAT_TIME,
- GST_SEEK_FLAG_FLUSH,
- (gint64)(position * GST_SECOND))) {
- player->is_seeking = TRUE;
- ev_media_player_update_position_stop (player);
- player->position = position;
- g_object_notify (G_OBJECT (player), "position");
- }
+ return player->media;
}
diff --git a/libview/ev-media-player.h b/libview/ev-media-player.h
index 083df1e..ef7b686 100644
--- a/libview/ev-media-player.h
+++ b/libview/ev-media-player.h
@@ -22,7 +22,7 @@
#define EV_MEDIA_PLAYER_H
#include <glib-object.h>
-#include <gdk/gdk.h>
+#include <gtk/gtk.h>
#include "ev-media.h"
G_BEGIN_DECLS
@@ -42,18 +42,9 @@ typedef enum {
typedef struct _EvMediaPlayer EvMediaPlayer;
typedef struct _EvMediaPlayerClass EvMediaPlayerClass;
-GType ev_media_player_get_type (void) G_GNUC_CONST;
-EvMediaPlayer *ev_media_player_new (EvMedia *media,
- guint64 window_id,
- GdkRectangle *area);
-void ev_media_player_set_render_area (EvMediaPlayer *player,
- GdkRectangle *area);
-void ev_media_player_expose (EvMediaPlayer *player);
-gdouble ev_media_player_get_duration (EvMediaPlayer *player);
-gdouble ev_media_player_get_position (EvMediaPlayer *player);
-void ev_media_player_toggle_state (EvMediaPlayer *player);
-void ev_media_player_seek (EvMediaPlayer *player,
- gdouble position);
+GType ev_media_player_get_type (void) G_GNUC_CONST;
+GtkWidget *ev_media_player_new (EvMedia *media);
+EvMedia *ev_media_player_get_media (EvMediaPlayer *player);
G_END_DECLS
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 9a99954..0ddf1a1 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -47,14 +47,7 @@
#include "ev-debug.h"
#ifdef ENABLE_MULTIMEDIA
-#if defined (GDK_WINDOWING_X11)
-#include <gdk/gdkx.h>
-#elif defined (GDK_WINDOWING_WIN32)
-#include <gdk/gdkwin32.h>
-#endif
-
#include "ev-media-player.h"
-#include "ev-media-controls.h"
#endif
enum {
@@ -154,6 +147,8 @@ static EvFormField *ev_view_get_form_field_at_location (EvView
static EvMedia *ev_view_get_media_at_location (EvView *view,
gdouble x,
gdouble y);
+static gboolean ev_view_find_player_for_media (EvView *view,
+ EvMedia *media);
/*** Annotations ***/
static EvAnnotation *ev_view_get_annotation_at_location (EvView *view,
gdouble x,
@@ -2132,7 +2127,7 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
}
} else if ((media = ev_view_get_media_at_location (view, x, y))) {
- if (!g_object_get_data (G_OBJECT (media), "view-player"))
+ if (!ev_view_find_player_for_media (view, media))
ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
else
ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
@@ -2818,154 +2813,57 @@ ev_view_get_media_at_location (EvView *view,
return media_mapping ? media_mapping->data : NULL;
}
-#ifdef ENABLE_MULTIMEDIA
-static void
-media_player_state_changed (EvMediaPlayer *player,
- guint state,
- EvMedia *media)
+static gboolean
+ev_view_find_player_for_media (EvView *view,
+ EvMedia *media)
{
- /* A media without controls can't be played again */
- if (state == EV_MEDIA_PLAYER_STATE_PAUSE)
- g_object_set_data (G_OBJECT (media), "view-player", NULL);
-}
+#ifdef ENABLE_MULTIMEDIA
+ GList *l;
+
+ for (l = view->children; l; l = g_list_next (l)) {
+ EvViewChild *child = (EvViewChild *)l->data;
+
+ if (!EV_IS_MEDIA_PLAYER (child->widget))
+ continue;
+
+ if (ev_media_player_get_media (EV_MEDIA_PLAYER (child->widget)) == media)
+ return TRUE;
+ }
#endif
+ return FALSE;
+}
+
static void
ev_view_handle_media (EvView *view,
EvMedia *media)
{
#ifdef ENABLE_MULTIMEDIA
- EvMediaPlayer *player;
+ GtkWidget *player;
EvMappingList *media_mapping;
+ EvMapping *mapping;
GdkRectangle render_area;
guint page;
- guint64 window_handle;
page = ev_media_get_page_index (media);
media_mapping = ev_page_cache_get_media_mapping (view->page_cache, page);
/* TODO: focus? */
- player = g_object_get_data (G_OBJECT (media), "view-player");
- if (player)
+ if (ev_view_find_player_for_media (view, media))
return;
-#if defined (GDK_WINDOWING_X11)
- window_handle = (guint64)GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (view)));
-#elif defined (GDK_WINDOWING_WIN32)
- window_handle = (guint64)GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET (view)));
-#else
- g_assert_not_reached ();
-#endif
-
- ev_view_get_area_from_mapping (view, page, media_mapping, media, &render_area);
- player = ev_media_player_new (media, window_handle, &render_area);
- g_object_set_data_full (G_OBJECT (media), "view-player", player, g_object_unref);
-
- if (ev_media_get_show_controls (media)) {
- GtkWidget *controls;
- EvMapping *mapping;
- EvRectangle doc_rect;
-
- mapping = ev_mapping_list_find (media_mapping, media);
- doc_rect.x1 = mapping->area.x1;
- doc_rect.x2 = mapping->area.x2;
- doc_rect.y1 = mapping->area.y2;
- doc_rect.y2 = doc_rect.y1 + 16;
-
- controls = ev_media_controls_new (player);
- ev_view_put (view, controls,
- render_area.x,
- render_area.y + render_area.height,
- page, &doc_rect);
- gtk_widget_show (controls);
- } else {
- /* A media without controls will be paused when reaching EOS */
- g_signal_connect (player, "state-changed",
- G_CALLBACK (media_player_state_changed),
- media);
- }
-#endif /* ENABLE_MULTIMEDIA */
-}
-
-static void
-ev_view_update_media_render_area (EvView *view)
-{
-#ifdef ENABLE_MULTIMEDIA
- guint i;
-
- for (i = view->start_page; i >= 0 && i <= view->end_page; i++) {
- EvMappingList *media_mapping;
- GList *l;
-
- media_mapping = ev_page_cache_get_media_mapping (view->page_cache, i);
- if (!media_mapping)
- continue;
-
- for (l = ev_mapping_list_get_list (media_mapping); l; l = g_list_next (l)) {
- EvMapping *mapping = (EvMapping *)l->data;
- EvMedia *media = (EvMedia *)mapping->data;
- EvMediaPlayer *player;
- GdkRectangle render_area;
-
- player = g_object_get_data (G_OBJECT (media), "view-player");
- if (!player)
- continue;
-
- _ev_view_transform_doc_rect_to_view_rect (view, i,
- &mapping->area,
- &render_area);
- render_area.x -= view->scroll_x;
- render_area.y -= view->scroll_y;
- ev_media_player_set_render_area (player, &render_area);
- }
- }
-#endif
-}
-
-#ifdef ENABLE_MULTIMEDIA
-static void
-draw_media (EvView *view,
- cairo_t *cr,
- gint page,
- GdkRectangle *clip)
-{
- EvMappingList *media_mapping;
- GList *l;
-
- media_mapping = ev_page_cache_get_media_mapping (view->page_cache, page);
-
- for (l = ev_mapping_list_get_list (media_mapping); l; l = g_list_next (l)) {
- EvMapping *mapping = (EvMapping *)l->data;
- EvMediaPlayer *player;
- GdkRectangle media_rect;
- GdkRectangle intersect;
+ player = ev_media_player_new (media);
- player = g_object_get_data (G_OBJECT (mapping->data), "view-player");
- if (!player)
- continue;
+ mapping = ev_mapping_list_find (media_mapping, media);
+ _ev_view_transform_doc_rect_to_view_rect (view, page, &mapping->area, &render_area);
+ render_area.x -= view->scroll_x;
+ render_area.y -= view->scroll_y;
- _ev_view_transform_doc_rect_to_view_rect (view, page,
- &mapping->area,
- &media_rect);
- media_rect.x -= view->scroll_x;
- media_rect.y -= view->scroll_y;
-
- /* Draw a black background to avoid showing the builtin poster */
- if (gdk_rectangle_intersect (&media_rect, clip, &intersect)) {
- cairo_save (cr);
- cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
- cairo_rectangle (cr,
- intersect.x, intersect.y,
- intersect.width, intersect.height);
- cairo_fill (cr);
- cairo_restore (cr);
-
- ev_media_player_expose (player);
- }
- }
+ ev_view_put (view, player, render_area.x, render_area.y, page, &mapping->area);
+ gtk_widget_show (player);
+#endif /* ENABLE_MULTIMEDIA */
}
-#endif
/* Annotations */
static EvViewWindowChild *
@@ -4194,8 +4092,6 @@ ev_view_size_allocate (GtkWidget *widget,
ev_view_window_child_move (view, child, view_rect.x + root_x, view_rect.y + root_y);
}
}
-
- ev_view_update_media_render_area (view);
}
static gboolean
@@ -4663,10 +4559,6 @@ ev_view_draw (GtkWidget *widget,
draw_focus (view, cr, i, &clip_rect);
if (page_ready && view->synctex_result)
highlight_forward_search_results (view, cr, i);
-#ifdef ENABLE_MULTIMEDIA
- if (page_ready && EV_IS_DOCUMENT_MEDIA (view->document))
- draw_media (view, cr, i, &clip_rect);
-#endif
#ifdef EV_ENABLE_DEBUG
if (page_ready)
draw_debug_borders (view, cr, i, &clip_rect);
@@ -7649,8 +7541,6 @@ on_adjustment_value_changed (GtkAdjustment *adjustment,
if (view->document)
view_update_range_and_current_page (view);
-
- ev_view_update_media_render_area (view);
}
GtkWidget*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]