[gtk+] GtkStack: Add more transition types



commit 98b78ed5da0c63df49a31f199b8147f45f40952b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Aug 31 12:00:47 2013 -0400

    GtkStack: Add more transition types
    
    This adds new 'over' and 'under' transitions which work by moving
    the new page over the previous one, or moving the previous page off
    to reveal the new one. We also add an over/under combination that
    is going to be used in GtkAboutDialog.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=707187

 gtk/gtkstack.c |  155 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 gtk/gtkstack.h |   11 ++++-
 2 files changed, 147 insertions(+), 19 deletions(-)
---
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index cee970a..de1ead8 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -58,9 +58,20 @@
  * @GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN: Slide from top down
  * @GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT: Slide from left or right according to the children order
  * @GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN: Slide from top down or bottom up according to the order
+ * @GTK_STACK_TRANSITION_TYPE_OVER_UP: Cover the old page by sliding up. Since 3.12
+ * @GTK_STACK_TRANSITION_TYPE_OVER_DOWN: Cover the old page by sliding down. Since: 3.12
+ * @GTK_STACK_TRANSITION_TYPE_OVER_LEFT: Cover the old page by sliding to the left. Since: 3.12
+ * @GTK_STACK_TRANSITION_TYPE_OVER_RIGHT: Cover the old page by sliding to the right. Since: 3.12
+ * @GTK_STACK_TRANSITION_TYPE_UNDER_UP: Uncover the new page by sliding up. Since 3.12
+ * @GTK_STACK_TRANSITION_TYPE_UNDER_DOWN: Uncover the new page by sliding down. Since: 3.12
+ * @GTK_STACK_TRANSITION_TYPE_UNDER_LEFT: Uncover the new page by sliding to the left. Since: 3.12
+ * @GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT: Uncover the new page by sliding to the right. Since: 3.12
+ * @GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN: Cover the old page or uncover the new page, according to order. 
Since: 3.12
  *
  * These enumeration values describe the possible transitions
  * between pages in a #GtkStack widget.
+ *
+ * New values may be added to this enumeration over time.
  */
 
 /* TODO:
@@ -668,9 +679,12 @@ get_bin_window_x (GtkStack      *stack,
 
   if (priv->transition_pos < 1.0)
     {
-      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT)
+      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT ||
+          priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_LEFT)
         x = allocation->width * (1 - ease_out_cubic (priv->transition_pos));
-      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT)
+      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT ||
+          priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_RIGHT)
+
         x = -allocation->width * (1 - ease_out_cubic (priv->transition_pos));
     }
 
@@ -686,9 +700,11 @@ get_bin_window_y (GtkStack      *stack,
 
   if (priv->transition_pos < 1.0)
     {
-      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP)
+      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP ||
+          priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_UP)
         y = allocation->height * (1 - ease_out_cubic (priv->transition_pos));
-      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN)
+      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN ||
+          priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_DOWN)
         y = -allocation->height * (1 - ease_out_cubic (priv->transition_pos));
     }
 
@@ -709,7 +725,11 @@ gtk_stack_set_transition_position (GtkStack *stack,
       (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT ||
        priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT ||
        priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP ||
-       priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN))
+       priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN ||
+       priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_UP ||
+       priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_DOWN ||
+       priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_LEFT ||
+       priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_OVER_RIGHT))
     {
       GtkAllocation allocation;
       gtk_widget_get_allocation (GTK_WIDGET (stack), &allocation);
@@ -806,6 +826,14 @@ effective_transition_type (GtkStack               *stack,
         return GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT;
       else if (transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT)
         return GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT;
+      else if (transition_type == GTK_STACK_TRANSITION_TYPE_OVER_LEFT)
+        return GTK_STACK_TRANSITION_TYPE_OVER_RIGHT;
+      else if (transition_type == GTK_STACK_TRANSITION_TYPE_OVER_RIGHT)
+        return GTK_STACK_TRANSITION_TYPE_OVER_LEFT;
+      else if (transition_type == GTK_STACK_TRANSITION_TYPE_UNDER_LEFT)
+        return GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT;
+      else if (transition_type == GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT)
+        return GTK_STACK_TRANSITION_TYPE_UNDER_LEFT;
     }
 
   return transition_type;
@@ -895,12 +923,14 @@ set_visible_child (GtkStack               *stack,
 
   if ((child_info == NULL || priv->last_visible_child == NULL) &&
       (transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT ||
-       transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN))
+       transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN ||
+       transition_type == GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN))
     {
       transition_type = GTK_STACK_TRANSITION_TYPE_NONE;
     }
   else if (transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT ||
-          transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN)
+          transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN ||
+          transition_type == GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN)
     {
       gboolean i_first = FALSE;
       for (l = priv->children; l != NULL; l = g_list_next (l))
@@ -918,10 +948,14 @@ set_visible_child (GtkStack               *stack,
        {
          transition_type = i_first ? GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT : 
GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT;
        }
-      if (transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN)
+      else if (transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN)
        {
          transition_type = i_first ? GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN : 
GTK_STACK_TRANSITION_TYPE_SLIDE_UP;
        }
+      else if (transition_type == GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN)
+       {
+         transition_type = i_first ? GTK_STACK_TRANSITION_TYPE_UNDER_DOWN : 
GTK_STACK_TRANSITION_TYPE_OVER_UP;
+       }
     }
 
   gtk_widget_queue_resize (GTK_WIDGET (stack));
@@ -1467,6 +1501,64 @@ gtk_stack_draw_crossfade (GtkWidget *widget,
 }
 
 static void
+gtk_stack_draw_under (GtkWidget *widget,
+                      cairo_t   *cr)
+{
+  GtkStack *stack = GTK_STACK (widget);
+  GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
+  GtkAllocation allocation;
+  gint x, y, width, height, pos_x, pos_y;
+
+  gtk_widget_get_allocation (widget, &allocation);
+  x = y = 0;
+  width = allocation.width;
+  height = allocation.height;
+  pos_x = pos_y = 0;
+
+  switch (priv->active_transition_type)
+    {
+    case GTK_STACK_TRANSITION_TYPE_UNDER_DOWN:
+      y = 0;
+      height = allocation.height * (ease_out_cubic (priv->transition_pos));
+      pos_y = height;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_UNDER_UP:
+      y = allocation.height * (1 - ease_out_cubic (priv->transition_pos));
+      height = allocation.height - y;
+      pos_y = y - allocation.height;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
+      x = allocation.width * (1 - ease_out_cubic (priv->transition_pos));
+      width = allocation.width - x;
+      pos_x = x - allocation.width;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
+      x = 0;
+      width = allocation.width * (ease_out_cubic (priv->transition_pos));
+      pos_x = width;
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+
+  cairo_save (cr);
+  cairo_rectangle (cr, x, y, width, height);
+  cairo_clip (cr);
+
+  gtk_container_propagate_draw (GTK_CONTAINER (stack),
+                                priv->visible_child->widget,
+                                cr);
+
+  cairo_restore (cr);
+
+  if (priv->last_visible_surface)
+    {
+      cairo_set_source_surface (cr, priv->last_visible_surface, pos_x, pos_y);
+      cairo_paint (cr);
+    }
+}
+
+static void
 gtk_stack_draw_slide (GtkWidget *widget,
                       cairo_t   *cr)
 {
@@ -1479,18 +1571,34 @@ gtk_stack_draw_slide (GtkWidget *widget,
   gtk_widget_get_allocation (widget, &allocation);
 
   x = get_bin_window_x (stack, &allocation);
-
-  if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT)
-    x -= allocation.width;
-  if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT)
-    x += allocation.width;
-
   y = get_bin_window_y (stack, &allocation);
 
-  if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP)
-    y -= allocation.height;
-  if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN)
-    y += allocation.height;
+  switch (priv->active_transition_type)
+    {
+    case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT:
+      x -= allocation.width;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT:
+      x += allocation.width;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_SLIDE_UP:
+      y -= allocation.height;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN:
+      y += allocation.height;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_OVER_UP:
+    case GTK_STACK_TRANSITION_TYPE_OVER_DOWN:
+      y = 0;
+      break;
+    case GTK_STACK_TRANSITION_TYPE_OVER_LEFT:
+    case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT:
+      x = 0;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
 
   if (priv->last_visible_surface &&
       gtk_cairo_should_draw_window (cr, priv->view_window))
@@ -1548,8 +1656,19 @@ gtk_stack_draw (GtkWidget *widget,
             case GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT:
             case GTK_STACK_TRANSITION_TYPE_SLIDE_UP:
             case GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN:
+            case GTK_STACK_TRANSITION_TYPE_OVER_UP:
+            case GTK_STACK_TRANSITION_TYPE_OVER_DOWN:
+            case GTK_STACK_TRANSITION_TYPE_OVER_LEFT:
+            case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT:
               gtk_stack_draw_slide (widget, cr);
               break;
+            case GTK_STACK_TRANSITION_TYPE_UNDER_UP:
+            case GTK_STACK_TRANSITION_TYPE_UNDER_DOWN:
+            case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
+            case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
+             if (gtk_cairo_should_draw_window (cr, priv->bin_window))
+               gtk_stack_draw_under (widget, cr);
+              break;
             default:
               g_assert_not_reached ();
             }
diff --git a/gtk/gtkstack.h b/gtk/gtkstack.h
index 77d7337..2c967aa 100644
--- a/gtk/gtkstack.h
+++ b/gtk/gtkstack.h
@@ -45,7 +45,16 @@ typedef enum {
   GTK_STACK_TRANSITION_TYPE_SLIDE_UP,
   GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN,
   GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT,
-  GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN
+  GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN,
+  GTK_STACK_TRANSITION_TYPE_OVER_UP,
+  GTK_STACK_TRANSITION_TYPE_OVER_DOWN,
+  GTK_STACK_TRANSITION_TYPE_OVER_LEFT,
+  GTK_STACK_TRANSITION_TYPE_OVER_RIGHT,
+  GTK_STACK_TRANSITION_TYPE_UNDER_UP,
+  GTK_STACK_TRANSITION_TYPE_UNDER_DOWN,
+  GTK_STACK_TRANSITION_TYPE_UNDER_LEFT,
+  GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT,
+  GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN
 } GtkStackTransitionType;
 
 struct _GtkStack {


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