[gnome-photos] preview-view, preview-nav-buttons: Sliding transition between photos



commit fd5246fd0f4f57437cb30ca382e67527447a4a29
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Jul 18 12:12:15 2014 +0200

    preview-view, preview-nav-buttons: Sliding transition between photos
    
    Fixes: https://bugzilla.gnome.org/726505

 src/Makefile.am                  |    2 +
 src/photos-enums.c.template      |    1 +
 src/photos-preview-nav-buttons.c |   50 +++++++++++-
 src/photos-preview-nav-buttons.h |   14 +++-
 src/photos-preview-view.c        |  161 ++++++++++++++++++++++++++++++++------
 5 files changed, 202 insertions(+), 26 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 36cff24..1069b80 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -392,6 +392,7 @@ stamp-photos-enums.h: photos-enums.h.template
                ( glib-mkenums \
                        --template $(srcdir)/photos-enums.h.template \
                         $(srcdir)/photos-mode-controller.h \
+                        $(srcdir)/photos-preview-nav-buttons.h \
                 ) >> xgen-etbh \
                && ( cmp -s xgen-etbh photos-enums.h || cp xgen-etbh photos-enums.h ) \
                && rm -f xgen-etbh \
@@ -403,6 +404,7 @@ photos-enums.c: photos-enums.c.template
                ( glib-mkenums \
                        --template $(srcdir)/photos-enums.c.template \
                         $(srcdir)/photos-mode-controller.h \
+                        $(srcdir)/photos-preview-nav-buttons.h \
                 ) >> xgen-etbc \
                && ( cmp -s xgen-etbc photos-enums.c || cp xgen-etbc photos-enums.c ) \
                && rm -f xgen-etbc \
diff --git a/src/photos-enums.c.template b/src/photos-enums.c.template
index cf3c0a7..2033eca 100644
--- a/src/photos-enums.c.template
+++ b/src/photos-enums.c.template
@@ -4,6 +4,7 @@
 
 #include "photos-enums.h"
 #include "photos-mode-controller.h"
+#include "photos-preview-nav-buttons.h"
 
 /*** END file-header ***/
 
diff --git a/src/photos-preview-nav-buttons.c b/src/photos-preview-nav-buttons.c
index f3d33d5..4c195ab 100644
--- a/src/photos-preview-nav-buttons.c
+++ b/src/photos-preview-nav-buttons.c
@@ -29,6 +29,7 @@
 #include <glib/gi18n.h>
 #include <libgd/gd.h>
 
+#include "photos-enums.h"
 #include "photos-icons.h"
 #include "photos-item-manager.h"
 #include "photos-preview-model.h"
@@ -47,6 +48,7 @@ struct _PhotosPreviewNavButtonsPrivate
   GtkWidget *preview_view;
   GtkWidget *toolbar_widget;
   PhotosBaseManager *item_mngr;
+  PhotosPreviewAction action;
   gboolean hover;
   gboolean visible;
   guint auto_hide_id;
@@ -60,6 +62,14 @@ enum
   PROP_PREVIEW_VIEW
 };
 
+enum
+{
+  ACTIVATED,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
 
 G_DEFINE_TYPE_WITH_PRIVATE (PhotosPreviewNavButtons, photos_preview_nav_buttons, G_TYPE_OBJECT);
 
@@ -473,6 +483,8 @@ photos_preview_nav_buttons_init (PhotosPreviewNavButtons *self)
                             "active-changed",
                             G_CALLBACK (photos_preview_nav_buttons_active_changed),
                             self);
+
+  priv->action = PHOTOS_PREVIEW_ACTION_NONE;
 }
 
 
@@ -501,6 +513,17 @@ photos_preview_nav_buttons_class_init (PhotosPreviewNavButtonsClass *class)
                                                         "The widget used for showing the preview",
                                                         PHOTOS_TYPE_PREVIEW_VIEW,
                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+
+  signals[ACTIVATED] = g_signal_new ("activated",
+                                     G_TYPE_FROM_CLASS (class),
+                                     G_SIGNAL_RUN_LAST,
+                                     G_STRUCT_OFFSET (PhotosPreviewNavButtonsClass, activated),
+                                     NULL, /*accumulator */
+                                     NULL, /*accu_data */
+                                     g_cclosure_marshal_generic,
+                                     G_TYPE_NONE,
+                                     1,
+                                     PHOTOS_TYPE_PREVIEW_ACTION);
 }
 
 
@@ -511,31 +534,51 @@ photos_preview_nav_buttons_new (PhotosPreviewView *preview_view, GtkOverlay *ove
 }
 
 
+PhotosPreviewAction
+photos_preview_nav_buttons_get_action (PhotosPreviewNavButtons *self)
+{
+  return self->priv->action;
+}
+
+
 void
 photos_preview_nav_buttons_hide (PhotosPreviewNavButtons *self)
 {
   PhotosPreviewNavButtonsPrivate *priv = self->priv;
 
+  priv->action = PHOTOS_PREVIEW_ACTION_NONE;
   priv->visible = FALSE;
   photos_preview_nav_buttons_fade_out_button (self, priv->prev_widget);
   photos_preview_nav_buttons_fade_out_button (self, priv->next_widget);
   photos_preview_nav_buttons_fade_out_button (self, priv->toolbar_widget);
+
+  g_signal_emit (self, signals[ACTIVATED], 0, priv->action);
 }
 
 
 void
 photos_preview_nav_buttons_next (PhotosPreviewNavButtons *self)
 {
-  gtk_tree_path_next (self->priv->current_path);
+  PhotosPreviewNavButtonsPrivate *priv = self->priv;
+
+  priv->action = PHOTOS_PREVIEW_ACTION_NEXT;
+  gtk_tree_path_next (priv->current_path);
   photos_preview_nav_buttons_set_active_path (self);
+
+  g_signal_emit (self, signals[ACTIVATED], 0, priv->action);
 }
 
 
 void
 photos_preview_nav_buttons_previous (PhotosPreviewNavButtons *self)
 {
-  gtk_tree_path_prev (self->priv->current_path);
+  PhotosPreviewNavButtonsPrivate *priv = self->priv;
+
+  priv->action = PHOTOS_PREVIEW_ACTION_PREVIOUS;
+  gtk_tree_path_prev (priv->current_path);
   photos_preview_nav_buttons_set_active_path (self);
+
+  g_signal_emit (self, signals[ACTIVATED], 0, priv->action);
 }
 
 
@@ -564,6 +607,9 @@ photos_preview_nav_buttons_show (PhotosPreviewNavButtons *self)
 {
   PhotosPreviewNavButtonsPrivate *priv = self->priv;
 
+  priv->action = PHOTOS_PREVIEW_ACTION_NONE;
   priv->visible = TRUE;
   photos_preview_nav_buttons_update_visibility (self);
+
+  g_signal_emit (self, signals[ACTIVATED], 0, priv->action);
 }
diff --git a/src/photos-preview-nav-buttons.h b/src/photos-preview-nav-buttons.h
index c4a5538..fbc2a8d 100644
--- a/src/photos-preview-nav-buttons.h
+++ b/src/photos-preview-nav-buttons.h
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2013 Red Hat, Inc.
+ * Copyright © 2013, 2014 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -54,6 +54,13 @@ G_BEGIN_DECLS
   (G_TYPE_INSTANCE_GET_CLASS ((obj), \
    PHOTOS_TYPE_PREVIEW_VIEW, PhotosPreviewNavButtonsClass))
 
+typedef enum
+{
+  PHOTOS_PREVIEW_ACTION_NONE,
+  PHOTOS_PREVIEW_ACTION_NEXT,
+  PHOTOS_PREVIEW_ACTION_PREVIOUS
+} PhotosPreviewAction;
+
 typedef struct _PhotosPreviewNavButtons        PhotosPreviewNavButtons;
 typedef struct _PhotosPreviewNavButtonsClass   PhotosPreviewNavButtonsClass;
 typedef struct _PhotosPreviewNavButtonsPrivate PhotosPreviewNavButtonsPrivate;
@@ -67,6 +74,9 @@ struct _PhotosPreviewNavButtons
 struct _PhotosPreviewNavButtonsClass
 {
   GObjectClass parent_class;
+
+  /* signals */
+  void (*activated) (PhotosPreviewNavButtons *self, PhotosPreviewAction action);
 };
 
 GType                       photos_preview_nav_buttons_get_type           (void) G_GNUC_CONST;
@@ -74,6 +84,8 @@ GType                       photos_preview_nav_buttons_get_type           (void)
 PhotosPreviewNavButtons    *photos_preview_nav_buttons_new                (PhotosPreviewView *preview_view,
                                                                            GtkOverlay *overlay);
 
+PhotosPreviewAction         photos_preview_nav_buttons_get_action         (PhotosPreviewNavButtons *self);
+
 void                        photos_preview_nav_buttons_hide               (PhotosPreviewNavButtons *self);
 
 void                        photos_preview_nav_buttons_next               (PhotosPreviewNavButtons *self);
diff --git a/src/photos-preview-view.c b/src/photos-preview-view.c
index b509646..5ff9330 100644
--- a/src/photos-preview-view.c
+++ b/src/photos-preview-view.c
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2013 Red Hat, Inc.
+ * Copyright © 2013, 2014 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -39,6 +39,7 @@ struct _PhotosPreviewViewPrivate
 {
   GeglNode *node;
   GtkWidget *overlay;
+  GtkWidget *stack;
   GtkWidget *view;
   PhotosModeController *mode_cntrlr;
   PhotosPreviewNavButtons *nav_buttons;
@@ -54,6 +55,9 @@ enum
 G_DEFINE_TYPE_WITH_PRIVATE (PhotosPreviewView, photos_preview_view, GTK_TYPE_SCROLLED_WINDOW);
 
 
+static GtkWidget *photos_preview_view_create_view (PhotosPreviewView *self);
+
+
 static void
 photos_preview_view_draw_background (PhotosPreviewView *self, cairo_t *cr, GdkRectangle *rect, gpointer 
user_data)
 {
@@ -70,6 +74,90 @@ photos_preview_view_draw_background (PhotosPreviewView *self, cairo_t *cr, GdkRe
 }
 
 
+static GtkWidget *
+photos_preview_view_get_invisible_view (PhotosPreviewView *self)
+{
+  PhotosPreviewViewPrivate *priv = self->priv;
+  GList *children;
+  GList *l;
+  GtkWidget *current_view;
+  GtkWidget *next_view = NULL;
+
+  current_view = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
+  children = gtk_container_get_children (GTK_CONTAINER (priv->stack));
+  for (l = children; l != NULL; l = l->next)
+    {
+      GtkWidget *view = GTK_WIDGET (l->data);
+
+      if (current_view != view)
+        {
+          next_view = view;
+          break;
+        }
+    }
+
+  g_list_free (children);
+  return next_view;
+}
+
+
+static void
+photos_preview_view_nav_buttons_activated (PhotosPreviewView *self, PhotosPreviewAction action)
+{
+  PhotosPreviewViewPrivate *priv = self->priv;
+  GtkStackTransitionType transition;
+  GtkWidget *current_view;
+  GtkWidget *next_view;
+  gint position;
+
+  if (action == PHOTOS_PREVIEW_ACTION_NONE)
+    return;
+
+  switch (action)
+    {
+    case PHOTOS_PREVIEW_ACTION_NEXT:
+      position = 0;
+      transition = GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT;
+      break;
+
+    case PHOTOS_PREVIEW_ACTION_PREVIOUS:
+      position = -1;
+      transition = GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT;
+      break;
+
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  current_view = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
+  gtk_container_child_set (GTK_CONTAINER (priv->stack), current_view, "position", position, NULL);
+
+  gtk_stack_set_transition_type (GTK_STACK (priv->stack), transition);
+
+  next_view = photos_preview_view_get_invisible_view (self);
+  gtk_stack_set_visible_child (GTK_STACK (priv->stack), next_view);
+}
+
+
+static void
+photos_preview_view_notify_transition_running (PhotosPreviewView *self)
+{
+  PhotosPreviewViewPrivate *priv = self->priv;
+  GtkWidget *old_view;
+  GtkWidget *new_view;
+
+  if (gtk_stack_get_transition_running (GTK_STACK (priv->stack)))
+    return;
+
+  old_view = photos_preview_view_get_invisible_view (self);
+  gtk_container_remove (GTK_CONTAINER (priv->stack), old_view);
+
+  new_view = photos_preview_view_create_view (self);
+  gtk_container_add (GTK_CONTAINER (priv->stack), new_view);
+}
+
+
 static void
 photos_preview_view_scale_and_align_image (PhotosPreviewView *self, GtkWidget *view)
 {
@@ -127,6 +215,27 @@ photos_preview_view_size_allocate (PhotosPreviewView *self, GdkRectangle *alloca
 }
 
 
+static GtkWidget *
+photos_preview_view_create_view (PhotosPreviewView *self)
+{
+  GtkStyleContext *context;
+  GtkWidget *view;
+
+  view = GTK_WIDGET (gegl_gtk_view_new ());
+  gtk_widget_add_events (view, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
+  context = gtk_widget_get_style_context (view);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
+  gtk_style_context_add_class (context, "content-view");
+  g_signal_connect_swapped (view, "size-allocate", G_CALLBACK (photos_preview_view_size_allocate), self);
+  g_signal_connect_swapped (view, "draw-background", G_CALLBACK (photos_preview_view_draw_background), self);
+
+  /* It has to be visible to become the visible child of priv->stack. */
+  gtk_widget_show (view);
+
+  return view;
+}
+
+
 static void
 photos_preview_view_window_mode_changed (PhotosPreviewView *self, PhotosWindowMode mode, PhotosWindowMode 
old_mode)
 {
@@ -156,12 +265,16 @@ photos_preview_view_constructed (GObject *object)
 
   G_OBJECT_CLASS (photos_preview_view_parent_class)->constructed (object);
 
-  /* Add the view to the scrolled window after the default
+  /* Add the stack to the scrolled window after the default
    * adjustments have been created.
    */
-  gtk_container_add (GTK_CONTAINER (self), priv->view);
+  gtk_container_add (GTK_CONTAINER (self), priv->stack);
 
   priv->nav_buttons = photos_preview_nav_buttons_new (self, GTK_OVERLAY (priv->overlay));
+  g_signal_connect_swapped (priv->nav_buttons,
+                            "activated",
+                            G_CALLBACK (photos_preview_view_nav_buttons_activated),
+                            self);
 
   gtk_widget_show_all (GTK_WIDGET (self));
 }
@@ -191,6 +304,7 @@ photos_preview_view_init (PhotosPreviewView *self)
 {
   PhotosPreviewViewPrivate *priv;
   GtkStyleContext *context;
+  GtkWidget *view;
 
   self->priv = photos_preview_view_get_instance_private (self);
   priv = self->priv;
@@ -207,19 +321,19 @@ photos_preview_view_init (PhotosPreviewView *self)
   context = gtk_widget_get_style_context (GTK_WIDGET (self));
   gtk_style_context_add_class (context, "documents-scrolledwin");
 
-  priv->view = GTK_WIDGET (gegl_gtk_view_new ());
-  gtk_widget_add_events (priv->view, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
-  context = gtk_widget_get_style_context (priv->view);
-  gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
-  gtk_style_context_add_class (context, "content-view");
-  g_signal_connect_swapped (priv->view,
-                            "size-allocate",
-                            G_CALLBACK (photos_preview_view_size_allocate),
-                            self);
-  g_signal_connect_swapped (priv->view,
-                            "draw-background",
-                            G_CALLBACK (photos_preview_view_draw_background),
+  priv->stack = gtk_stack_new ();
+  gtk_stack_set_transition_duration (GTK_STACK (priv->stack), 400);
+  g_signal_connect_swapped (priv->stack,
+                            "notify::transition-running",
+                            G_CALLBACK (photos_preview_view_notify_transition_running),
                             self);
+
+  view = photos_preview_view_create_view (self);
+  gtk_container_add (GTK_CONTAINER (priv->stack), view);
+  gtk_stack_set_visible_child (GTK_STACK (priv->stack), view);
+
+  view = photos_preview_view_create_view (self);
+  gtk_container_add (GTK_CONTAINER (priv->stack), view);
 }
 
 
@@ -274,21 +388,22 @@ void
 photos_preview_view_set_node (PhotosPreviewView *self, GeglNode *node)
 {
   PhotosPreviewViewPrivate *priv = self->priv;
+  GtkWidget *view;
+
+  photos_preview_nav_buttons_show (priv->nav_buttons);
 
   if (priv->node == node)
-    goto out;
+    return;
 
   g_clear_object (&priv->node);
   if (node == NULL)
-    goto out;
+    return;
 
   priv->node = g_object_ref (node);
-  photos_preview_view_scale_and_align_image (self, priv->view);
+  view = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
+  photos_preview_view_scale_and_align_image (self, view);
 
   /* Steals the reference to the GeglNode. */
-  gegl_gtk_view_set_node (GEGL_GTK_VIEW (priv->view), g_object_ref (priv->node));
-  gtk_widget_queue_draw (priv->view);
-
- out:
-  photos_preview_nav_buttons_show (priv->nav_buttons);
+  gegl_gtk_view_set_node (GEGL_GTK_VIEW (view), g_object_ref (priv->node));
+  gtk_widget_queue_draw (view);
 }


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