summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/bacon-video-widget.c134
-rw-r--r--src/backend/bacon-video-widget.h1
2 files changed, 106 insertions, 29 deletions
diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c
index bbe8eae39..9a92fd325 100644
--- a/src/backend/bacon-video-widget.c
+++ b/src/backend/bacon-video-widget.c
@@ -100,6 +100,7 @@
#define DEFAULT_CONTROLS_WIDTH 600 /* In pixels */
#define LOGO_SIZE 256 /* Maximum size of the logo */
#define REWIND_OR_PREVIOUS 4000
+#define POPUP_HIDING_TIMEOUT 5
#define MAX_NETWORK_SPEED 10752
#define BUFFERING_LEFT_RATIO 1.1
@@ -162,7 +163,8 @@ enum
PROP_HUE,
PROP_AUDIO_OUTPUT_TYPE,
PROP_AV_OFFSET,
- PROP_SHOW_CURSOR
+ PROP_SHOW_CURSOR,
+ PROP_REVEAL_CONTROLS
};
static const gchar *video_props_str[4] = {
@@ -219,6 +221,10 @@ struct BaconVideoWidgetPrivate
GdkCursor *cursor;
+ /* Controls */
+ gboolean reveal_controls;
+ guint transition_timeout_id;
+
/* Visual effects */
GList *vis_plugins_list;
GHashTable *vis_plugins_ht;
@@ -315,7 +321,8 @@ static gboolean bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw,
GstSeekFlags flag,
GError **error);
static void set_controls_visibility (BaconVideoWidget *bvw,
- gboolean visible);
+ gboolean visible,
+ gboolean animate);
typedef struct {
GstTagList *tags;
@@ -627,7 +634,6 @@ bacon_video_widget_realize (GtkWidget * widget)
gtk_window_set_geometry_hints (GTK_WINDOW (toplevel), widget, NULL, 0);
} else {
bvw->priv->embedded = TRUE;
- set_controls_visibility (bvw, FALSE);
}
bacon_video_widget_gst_missing_plugins_setup (bvw);
@@ -683,48 +689,48 @@ set_current_actor (BaconVideoWidget *bvw)
clutter_actor_hide (CLUTTER_ACTOR (bvw->priv->logo_frame));
}
-/* need to use gstnavigation interface for these vmethods, to allow for the sink
- to map screen coordinates to video coordinates in the presence of e.g.
- hardware scaling */
+static void
+unschedule_hiding_popup (BaconVideoWidget *bvw)
+{
+ if (bvw->priv->transition_timeout_id > 0)
+ g_source_remove (bvw->priv->transition_timeout_id);
+ bvw->priv->transition_timeout_id = 0;
+}
static gboolean
-bacon_video_widget_motion_notify (GtkWidget *widget, GdkEventMotion *event)
+hide_popup_timeout_cb (BaconVideoWidget *bvw)
{
- gboolean res = FALSE;
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
-
- g_return_val_if_fail (bvw->priv->play != NULL, FALSE);
-
- if (bvw->priv->navigation && !bvw->priv->logo_mode)
- gst_navigation_send_mouse_event (bvw->priv->navigation, "mouse-move", 0, event->x, event->y);
-
- if (GTK_WIDGET_CLASS (parent_class)->motion_notify_event)
- res |= GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
+ set_controls_visibility (bvw, FALSE, TRUE);
+ unschedule_hiding_popup (bvw);
+ return G_SOURCE_REMOVE;
+}
- return res;
+static void
+schedule_hiding_popup (BaconVideoWidget *bvw)
+{
+ unschedule_hiding_popup (bvw);
+ bvw->priv->transition_timeout_id = g_timeout_add_seconds (POPUP_HIDING_TIMEOUT, (GSourceFunc) hide_popup_timeout_cb, bvw);
}
static void
set_controls_visibility (BaconVideoWidget *bvw,
- gboolean visible)
+ gboolean visible,
+ gboolean animate)
{
guint8 opacity = visible ? OVERLAY_OPACITY : 0;
/* FIXME:
* Using a show/hide seems to not trigger the
* controls to redraw, so let's change the opacity instead */
+ clutter_actor_set_easing_duration (bvw->priv->controls, animate ? 250 : 0);
clutter_actor_set_opacity (bvw->priv->controls, opacity);
-}
-static void
-toggle_controls (BaconVideoWidget *bvw)
-{
- gboolean value = TRUE;
+ bacon_video_widget_set_show_cursor (bvw, visible);
+ if (animate)
+ schedule_hiding_popup (bvw);
- if (clutter_actor_get_opacity (bvw->priv->controls) != 0)
- value = FALSE;
- set_controls_visibility (bvw, value);
- bacon_video_widget_set_show_cursor (bvw, value);
+ bvw->priv->reveal_controls = visible;
+ g_object_notify (G_OBJECT (bvw), "reveal-controls");
}
static void
@@ -762,6 +768,45 @@ ignore_event (BaconVideoWidget *bvw,
return FALSE;
}
+/* need to use gstnavigation interface for these vmethods, to allow for the sink
+ to map screen coordinates to video coordinates in the presence of e.g.
+ hardware scaling */
+
+static gboolean
+bacon_video_widget_motion_notify (GtkWidget *widget, GdkEventMotion *event)
+{
+ gboolean res = FALSE;
+ BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
+ GdkDevice *device;
+ int x, y;
+
+ g_return_val_if_fail (bvw->priv->play != NULL, FALSE);
+
+ if (bvw->priv->navigation && !bvw->priv->logo_mode)
+ gst_navigation_send_mouse_event (bvw->priv->navigation, "mouse-move", 0, event->x, event->y);
+
+ if (GTK_WIDGET_CLASS (parent_class)->motion_notify_event)
+ res |= GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
+
+ device = gdk_event_get_source_device ((GdkEvent *) event);
+ if (gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
+ return res;
+
+ if (!bvw->priv->reveal_controls) {
+ set_controls_visibility (bvw, TRUE, TRUE);
+ }
+
+ translate_coords (widget, event->window, event->x, event->y, &x, &y);
+ if (ignore_event (bvw, x, y)) {
+ /* Is the mouse on the popups? */
+ unschedule_hiding_popup (bvw);
+ } else {
+ schedule_hiding_popup (bvw);
+ }
+
+ return res;
+}
+
static gboolean
bacon_video_widget_button_press_or_release (GtkWidget *widget, GdkEventButton *event)
{
@@ -792,7 +837,11 @@ bacon_video_widget_button_press_or_release (GtkWidget *widget, GdkEventButton *e
* the button press
res = TRUE; */
} else if (event->type == GDK_BUTTON_RELEASE) {
- toggle_controls (bvw);
+ gboolean value = TRUE;
+
+ if (clutter_actor_get_opacity (bvw->priv->controls) != 0)
+ value = FALSE;
+ set_controls_visibility (bvw, value, FALSE);
}
bail:
@@ -1110,6 +1159,17 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+ /**
+ * BaconVideoWidget:reveal-controls:
+ *
+ * Whether to show or hide the controls.
+ **/
+ g_object_class_install_property (object_class, PROP_REVEAL_CONTROLS,
+ g_param_spec_boolean ("reveal-controls", "Reveal controls",
+ "Whether to show or hide the controls.", FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
/* Signals */
/**
* BaconVideoWidget::error:
@@ -2722,6 +2782,8 @@ bacon_video_widget_finalize (GObject * object)
g_type_class_unref (g_type_class_peek (BVW_TYPE_DVD_EVENT));
g_type_class_unref (g_type_class_peek (BVW_TYPE_ROTATION));
+ unschedule_hiding_popup (bvw);
+
if (bvw->priv->bus) {
/* make bus drop all messages to make sure none of our callbacks is ever
* called again (main loop might be run again to display error dialog) */
@@ -2903,6 +2965,9 @@ bacon_video_widget_get_property (GObject * object, guint property_id,
case PROP_SHOW_CURSOR:
g_value_set_boolean (value, bvw->priv->cursor_shown);
break;
+ case PROP_REVEAL_CONTROLS:
+ g_value_set_boolean (value, bvw->priv->reveal_controls);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -3486,6 +3551,15 @@ bacon_video_widget_popup_osd (BaconVideoWidget *bvw,
bacon_video_osd_actor_show_and_fade (BACON_VIDEO_OSD_ACTOR (bvw->priv->osd));
}
+void
+bacon_video_widget_show_popup (BaconVideoWidget *bvw)
+{
+ g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
+
+ set_controls_visibility (bvw, TRUE, FALSE);
+ schedule_hiding_popup (bvw);
+}
+
GObject *
bacon_video_widget_get_controls_object (BaconVideoWidget *bvw)
{
@@ -6184,6 +6258,8 @@ bacon_video_widget_initable_init (GInitable *initable,
layout,
bvw->priv->logo_frame);
+ clutter_actor_set_opacity (bvw->priv->controls, 0);
+
/* And tell playbin */
g_object_set (bvw->priv->play, "video-sink", video_sink, NULL);
diff --git a/src/backend/bacon-video-widget.h b/src/backend/bacon-video-widget.h
index 8ae53e149..c4679f85b 100644
--- a/src/backend/bacon-video-widget.h
+++ b/src/backend/bacon-video-widget.h
@@ -455,6 +455,7 @@ void bacon_video_widget_set_audio_output_type (BaconVideoWidget *bvw,
BvwAudioOutputType type);
/* OSD */
+void bacon_video_widget_show_popup (BaconVideoWidget *bvw);
void bacon_video_widget_popup_osd (BaconVideoWidget *bvw,
const char *icon_name);