[gtk+/stack] Add a way to specify transition types on the fly



commit 6a7620173ea4fd56b3c89ddef4e78b20eee28bed
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Apr 21 14:22:35 2013 -0400

    Add a way to specify transition types on the fly
    
    Add a gtk_stack_set_visible_child_full that takes a
    transition type.

 gtk/gtkstack.c    | 63 ++++++++++++++++++++++++++++++++++++++++---------------
 gtk/gtkstack.h    |  3 +++
 tests/teststack.c |  6 ++----
 3 files changed, 51 insertions(+), 21 deletions(-)
---
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index 4d18923..e97f0e0 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -111,6 +111,8 @@ struct _GtkStackPrivate {
   guint tick_id;
   gint64 start_time;
   gint64 end_time;
+
+  GtkStackTransitionType active_transition_type;
 };
 
 static void     gtk_stack_add                            (GtkContainer  *widget,
@@ -626,9 +628,9 @@ get_bin_window_x (GtkStack      *stack,
 
   if (priv->transition_pos < 1.0)
     {
-      if (priv->transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT)
+      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT)
         x = allocation->width * (1 - ease_out_cubic (priv->transition_pos));
-      if (priv->transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT)
+      if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT)
         x = -allocation->width * (1 - ease_out_cubic (priv->transition_pos));
     }
 
@@ -646,8 +648,8 @@ gtk_stack_set_transition_position (GtkStack *stack,
   gtk_widget_queue_draw (GTK_WIDGET (stack));
 
   if (priv->bin_window != NULL &&
-      (priv->transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT ||
-       priv->transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT))
+      (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT ||
+       priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT))
     {
       GtkAllocation allocation;
       gtk_widget_get_allocation (GTK_WIDGET (stack), &allocation);
@@ -735,7 +737,9 @@ gtk_stack_unschedule_ticks (GtkStack *stack)
 }
 
 static void
-gtk_stack_start_transition (GtkStack *stack)
+gtk_stack_start_transition (GtkStack               *stack,
+                            GtkStackTransitionType  transition_type,
+                            guint                   transition_duration)
 {
   GtkStackPrivate *priv = stack->priv;
   GtkWidget *widget = GTK_WIDGET (stack);
@@ -747,26 +751,31 @@ gtk_stack_start_transition (GtkStack *stack)
 
   if (gtk_widget_get_mapped (widget) &&
       animations_enabled &&
-      priv->transition_type != GTK_STACK_TRANSITION_TYPE_NONE &&
+      transition_type != GTK_STACK_TRANSITION_TYPE_NONE &&
+      transition_duration != 0 &&
       priv->last_visible_child != NULL)
     {
       gtk_widget_set_opacity (widget, 0.999);
 
       priv->transition_pos = 0.0;
       priv->start_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
-      priv->end_time = priv->start_time + (priv->transition_duration * 1000);
+      priv->end_time = priv->start_time + (transition_duration * 1000);
+      priv->active_transition_type = transition_type;
       gtk_stack_schedule_ticks (stack);
     }
   else
     {
       gtk_stack_unschedule_ticks (stack);
+      priv->active_transition_type = GTK_STACK_TRANSITION_TYPE_NONE;
       gtk_stack_set_transition_position (stack, 1.0);
     }
 }
 
 static void
-set_visible_child (GtkStack          *stack,
-                   GtkStackChildInfo *child_info)
+set_visible_child (GtkStack               *stack,
+                   GtkStackChildInfo      *child_info,
+                   GtkStackTransitionType  transition_type,
+                   guint                   transition_duration)
 {
   GtkStackPrivate *priv = stack->priv;
   GtkStackChildInfo *info;
@@ -817,7 +826,7 @@ set_visible_child (GtkStack          *stack,
   g_object_notify (G_OBJECT (stack), "visible-child");
   g_object_notify (G_OBJECT (stack), "visible-child-name");
 
-  gtk_stack_start_transition (stack);
+  gtk_stack_start_transition (stack, transition_type, transition_duration);
 }
 
 static void
@@ -834,10 +843,10 @@ stack_child_visibility_notify_cb (GObject    *obj,
 
   if (priv->visible_child == NULL &&
       gtk_widget_get_visible (child))
-    set_visible_child (stack, child_info);
+    set_visible_child (stack, child_info, priv->transition_type, priv->transition_duration);
   else if (priv->visible_child == child_info &&
            !gtk_widget_get_visible (child))
-    set_visible_child (stack, NULL);
+    set_visible_child (stack, NULL, priv->transition_type, priv->transition_duration);
 
   if (child_info == priv->last_visible_child)
     {
@@ -929,7 +938,7 @@ gtk_stack_add (GtkContainer *container,
 
   if (priv->visible_child == NULL &&
       gtk_widget_get_visible (child))
-    set_visible_child (stack, child_info);
+    set_visible_child (stack, child_info, priv->transition_type, priv->transition_duration);
   else
     gtk_widget_set_child_visible (child, FALSE);
 
@@ -961,7 +970,7 @@ gtk_stack_remove (GtkContainer *container,
   child_info->widget = NULL;
 
   if (priv->visible_child == child_info)
-    set_visible_child (stack, NULL);
+    set_visible_child (stack, NULL, priv->transition_type, priv->transition_duration);
 
   if (priv->last_visible_child == child_info)
     priv->last_visible_child = NULL;
@@ -1185,7 +1194,9 @@ gtk_stack_set_visible_child (GtkStack  *stack,
     return;
 
   if (gtk_widget_get_visible (child_info->widget))
-    set_visible_child (stack, child_info);
+    set_visible_child (stack, child_info,
+                       stack->priv->transition_type,
+                       stack->priv->transition_duration);
 }
 
 /**
@@ -1206,6 +1217,24 @@ void
 gtk_stack_set_visible_child_name (GtkStack   *stack,
                                  const gchar *name)
 {
+  gtk_stack_set_visible_child_full (stack, name, stack->priv->transition_type);
+}
+
+/**
+ * gtk_stack_set_visible_child_name:
+ * @stack: a #GtkStack
+ * @name: the name of the child to make visible
+ * @transition_type: the transition type to use
+ *
+ * Makes the child with the given name visible.
+ *
+ * Since: 3.10
+ */
+void
+gtk_stack_set_visible_child_full (GtkStack               *stack,
+                                  const gchar            *name,
+                                  GtkStackTransitionType  transition_type)
+{
   GtkStackPrivate *priv;
   GtkStackChildInfo *child_info, *info;
   GList *l;
@@ -1228,7 +1257,7 @@ gtk_stack_set_visible_child_name (GtkStack   *stack,
     }
 
   if (child_info != NULL && gtk_widget_get_visible (child_info->widget))
-    set_visible_child (stack, child_info);
+    set_visible_child (stack, child_info, transition_type, priv->transition_duration);
 }
 
 static void
@@ -1373,7 +1402,7 @@ gtk_stack_draw (GtkWidget *widget,
               cairo_destroy (pattern_cr);
             }
 
-          switch (priv->transition_type)
+          switch (priv->active_transition_type)
             {
             case GTK_STACK_TRANSITION_TYPE_CROSSFADE:
               gtk_stack_draw_crossfade (widget, cr);
diff --git a/gtk/gtkstack.h b/gtk/gtkstack.h
index 4634b3a..a9bb373 100644
--- a/gtk/gtkstack.h
+++ b/gtk/gtkstack.h
@@ -70,6 +70,9 @@ GtkWidget *            gtk_stack_get_visible_child       (GtkStack
 void                   gtk_stack_set_visible_child_name  (GtkStack               *stack,
                                                           const gchar            *name);
 const gchar *          gtk_stack_get_visible_child_name  (GtkStack               *stack);
+void                   gtk_stack_set_visible_child_full  (GtkStack               *stack,
+                                                          const gchar            *name,
+                                                          GtkStackTransitionType  transition_type);
 void                   gtk_stack_set_homogeneous         (GtkStack               *stack,
                                                           gboolean                homogeneous);
 gboolean               gtk_stack_get_homogeneous         (GtkStack               *stack);
diff --git a/tests/teststack.c b/tests/teststack.c
index 30837c6..5a6a8cf 100644
--- a/tests/teststack.c
+++ b/tests/teststack.c
@@ -52,8 +52,7 @@ on_back_button_clicked (GtkButton *button, GtkStack *stack)
     {
       if (g_str_equal (vis, seq[i]))
         {
-          gtk_stack_set_transition_type (stack, GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT);
-          gtk_stack_set_visible_child_name (stack, seq[i - 1]);
+          gtk_stack_set_visible_child_full (stack, seq[i - 1], GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT);
           break;
         }
     }
@@ -72,8 +71,7 @@ on_forward_button_clicked (GtkButton *button, GtkStack *stack)
     {
       if (g_str_equal (vis, seq[i]))
         {
-          gtk_stack_set_transition_type (stack, GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT);
-          gtk_stack_set_visible_child_name (stack, seq[i + 1]);
+          gtk_stack_set_visible_child_full (stack, seq[i + 1], GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT);
           break;
         }
     }


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