[totem] main: Handle scroll events inside the video widget



commit b0762f5f159936f6274f4dc1ebe81b5d6beed693
Author: Bastien Nocera <hadess hadess net>
Date:   Tue Feb 11 13:33:15 2014 +0100

    main: Handle scroll events inside the video widget
    
    And pass the "requests" to the player itself. That will allow
    us to use gestures to control those in the future.

 data/totem.ui                    |    1 -
 src/backend/bacon-video-widget.c |   88 ++++++++++++++++++++++++++++++++++---
 src/totem-object.c               |   59 +++++++++----------------
 3 files changed, 102 insertions(+), 46 deletions(-)
---
diff --git a/data/totem.ui b/data/totem.ui
index 5f08b25..3655369 100644
--- a/data/totem.ui
+++ b/data/totem.ui
@@ -219,7 +219,6 @@
                   <object class="GtkVBox" id="tmw_main_vbox">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <signal name="scroll-event" handler="window_scroll_event_cb" swapped="no"/>
                     <child>
                       <object class="GtkOverlay" id="tmw_bvw_box">
                         <property name="visible">True</property>
diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c
index 9983f6a..bd276bd 100644
--- a/src/backend/bacon-video-widget.c
+++ b/src/backend/bacon-video-widget.c
@@ -133,6 +133,8 @@ enum
   SIGNAL_BUFFERING,
   SIGNAL_MISSING_PLUGINS,
   SIGNAL_DOWNLOAD_BUFFERING,
+  SIGNAL_SEEK_REQUESTED,
+  SIGNAL_VOLUME_CHANGE_REQUESTED,
   LAST_SIGNAL
 };
 
@@ -863,20 +865,53 @@ bacon_video_widget_tap (ClutterTapAction *action,
 }
 
 static gboolean
-bacon_video_widget_scroll (GtkWidget *widget, GdkEventScroll *event)
+bacon_video_widget_handle_scroll (GtkWidget        *widget,
+                                 GdkEventScroll   *event,
+                                 BaconVideoWidget *bvw)
 {
-  BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
   int x, y;
+  GdkScrollDirection direction;
+  gboolean forward;
 
   g_return_val_if_fail (bvw->priv->play != NULL, FALSE);
 
-  translate_coords (widget, event->window, event->x, event->y, &x, &y);
-  if (ignore_event (bvw, x, y))
-    return GDK_EVENT_STOP;
+  if (widget == (gpointer) bvw) {
+    translate_coords (widget, event->window, event->x, event->y, &x, &y);
+    if (ignore_event (bvw, x, y))
+      return GDK_EVENT_STOP;
+  }
+
+  direction = event->direction;
+  if (direction == GDK_SCROLL_SMOOTH) {
+    gdouble y;
+    gdk_event_get_scroll_deltas ((GdkEvent *) event, NULL, &y);
+    direction = y >= 0.0 ? GDK_SCROLL_DOWN : GDK_SCROLL_UP;
+  }
 
-  if (GTK_WIDGET_CLASS (parent_class)->scroll_event)
-    return GTK_WIDGET_CLASS (parent_class)->scroll_event (widget, event);
-  return GDK_EVENT_PROPAGATE;
+  switch (direction) {
+  case GDK_SCROLL_UP:
+    forward = TRUE;
+    break;
+  case GDK_SCROLL_DOWN:
+    forward = FALSE;
+    break;
+  default:
+    return GDK_EVENT_PROPAGATE;
+  }
+
+  if (widget == (gpointer) bvw ||
+      widget == g_object_get_data (G_OBJECT (bvw->priv->controls), "seek_scale"))
+    g_signal_emit (G_OBJECT (bvw), bvw_signals[SIGNAL_SEEK_REQUESTED], 0, forward);
+  else if (widget == g_object_get_data (G_OBJECT (bvw->priv->controls), "volume_button"))
+    g_signal_emit (G_OBJECT (bvw), bvw_signals[SIGNAL_VOLUME_CHANGE_REQUESTED], 0, forward);
+
+  return GDK_EVENT_STOP;
+}
+
+static gboolean
+bacon_video_widget_scroll (GtkWidget *widget, GdkEventScroll *event)
+{
+  return bacon_video_widget_handle_scroll (widget, event, BACON_VIDEO_WIDGET (widget));
 }
 
 static void
@@ -1324,6 +1359,35 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
                   G_STRUCT_OFFSET (BaconVideoWidgetClass, download_buffering),
                   NULL, NULL,
                   g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE);
+
+  /**
+   * BaconVideoWidget::seek-requested:
+   * @forward: whether the seek requested is a forward or backward seek.
+   *
+   * Emitted when a gesture, our mouse movement that should seek is made.
+   **/
+  bvw_signals[SIGNAL_SEEK_REQUESTED] =
+    g_signal_new ("seek-requested",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+  /**
+   * BaconVideoWidget::volume-change-requested:
+   * @increase: whether the volume change requested is an increase or decrease.
+   *
+   * Emitted when a gesture, our mouse movement that should change the volume
+   * is emitted.
+   **/
+  bvw_signals[SIGNAL_VOLUME_CHANGE_REQUESTED] =
+    g_signal_new ("volume-change-requested",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 }
 
 static void
@@ -6161,6 +6225,7 @@ bacon_video_widget_initable_init (GInitable     *initable,
   GstElement *audio_bin, *audio_converter;
   GstPad *audio_pad;
   ClutterAction *action;
+  GObject *item;
 
   bvw = BACON_VIDEO_WIDGET (initable);
 
@@ -6299,6 +6364,13 @@ bacon_video_widget_initable_init (GInitable     *initable,
 
   clutter_actor_set_opacity (bvw->priv->controls, 0);
 
+  item = g_object_get_data (G_OBJECT (bvw->priv->controls), "seek_scale");
+  g_signal_connect (item, "scroll-event",
+                   G_CALLBACK (bacon_video_widget_handle_scroll), bvw);
+  item = g_object_get_data (G_OBJECT (bvw->priv->controls), "volume_button");
+  g_signal_connect (item, "scroll-event",
+                   G_CALLBACK (bacon_video_widget_handle_scroll), bvw);
+
   /* And tell playbin */
   g_object_set (bvw->priv->play, "video-sink", video_sink, NULL);
 
diff --git a/src/totem-object.c b/src/totem-object.c
index 139d29c..ddf00fa 100644
--- a/src/totem-object.c
+++ b/src/totem-object.c
@@ -105,7 +105,6 @@ G_MODULE_EXPORT gboolean seek_slider_pressed_cb (GtkWidget *widget, GdkEventButt
 G_MODULE_EXPORT void seek_slider_changed_cb (GtkAdjustment *adj, TotemObject *totem);
 G_MODULE_EXPORT gboolean seek_slider_released_cb (GtkWidget *widget, GdkEventButton *event, TotemObject 
*totem);
 G_MODULE_EXPORT gboolean window_key_press_event_cb (GtkWidget *win, GdkEventKey *event, TotemObject *totem);
-G_MODULE_EXPORT int window_scroll_event_cb (GtkWidget *win, GdkEvent *event, TotemObject *totem);
 
 enum {
        PROP_0,
@@ -3339,37 +3338,23 @@ totem_object_handle_key_press (TotemObject *totem, GdkEventKey *event)
        return retval;
 }
 
-static gboolean
-totem_object_handle_scroll (TotemObject    *totem,
-                           const GdkEvent *event)
+static void
+on_seek_requested_event (BaconVideoWidget *bvw,
+                        gboolean          forward,
+                        TotemObject      *totem)
 {
-       gboolean retval = TRUE;
-       GdkEventScroll *sevent = (GdkEventScroll *) event;
-       GdkScrollDirection direction;
-
-       direction = sevent->direction;
+       gint64 offset;
 
-       if (direction == GDK_SCROLL_SMOOTH) {
-               gdouble y;
-               gdk_event_get_scroll_deltas (event, NULL, &y);
-               direction = y >= 0.0 ? GDK_SCROLL_DOWN : GDK_SCROLL_UP;
-       }
-
-       switch (direction) {
-       case GDK_SCROLL_UP:
-               totem_object_seek_relative (totem, SEEK_FORWARD_SHORT_OFFSET * 1000, FALSE);
-               break;
-       case GDK_SCROLL_DOWN:
-               totem_object_seek_relative (totem, SEEK_BACKWARD_SHORT_OFFSET * 1000, FALSE);
-               break;
-       case GDK_SCROLL_LEFT:
-       case GDK_SCROLL_RIGHT:
-       case GDK_SCROLL_SMOOTH:
-       default:
-               retval = FALSE;
-       }
+       offset = forward ? SEEK_FORWARD_SHORT_OFFSET * 1000 : SEEK_BACKWARD_SHORT_OFFSET * 1000;
+       totem_object_seek_relative (totem, offset, FALSE);
+}
 
-       return retval;
+static void
+on_volume_change_requested_event (BaconVideoWidget *bvw,
+                                 gboolean          increase,
+                                 TotemObject      *totem)
+{
+       totem_object_set_volume_relative (totem, increase ? VOLUME_UP_OFFSET : VOLUME_DOWN_OFFSET);
 }
 
 gboolean
@@ -3440,12 +3425,6 @@ window_key_press_event_cb (GtkWidget *win, GdkEventKey *event, TotemObject *tote
        return FALSE;
 }
 
-gboolean
-window_scroll_event_cb (GtkWidget *win, GdkEvent *event, TotemObject *totem)
-{
-       return totem_object_handle_scroll (totem, event);
-}
-
 static void
 update_media_menu_items (TotemObject *totem)
 {
@@ -3668,8 +3647,6 @@ totem_callback_connect (TotemObject *totem)
                          G_CALLBACK (seek_slider_pressed_cb), totem);
        g_signal_connect (totem->seek, "button-release-event",
                          G_CALLBACK (seek_slider_released_cb), totem);
-       g_signal_connect (totem->seek, "scroll-event",
-                         G_CALLBACK (window_scroll_event_cb), totem);
        g_signal_connect (totem->seekadj, "value-changed",
                          G_CALLBACK (seek_slider_changed_cb), totem);
 
@@ -3887,6 +3864,14 @@ video_widget_create (TotemObject *totem)
                          "notify::reveal-controls",
                          G_CALLBACK (on_reveal_controls_changed),
                          totem);
+       g_signal_connect (G_OBJECT (totem->bvw),
+                         "seek-requested",
+                         G_CALLBACK (on_seek_requested_event),
+                         totem);
+       g_signal_connect (G_OBJECT (totem->bvw),
+                         "volume-change-requested",
+                         G_CALLBACK (on_volume_change_requested_event),
+                         totem);
 
        container = GTK_CONTAINER (gtk_builder_get_object (totem->xml, "tmw_bvw_box"));
        gtk_container_add (container,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]