[gtk+] Add gtk_snapshot_push_cross_fade()



commit d9b0685b495926af602990e709feaad5822d5724
Author: Benjamin Otte <otte redhat com>
Date:   Thu Jan 12 22:00:38 2017 +0100

    Add gtk_snapshot_push_cross_fade()
    
    ... and use it.
    
    The function is a bit awkward because it requires 2 calls to
    gtk_snapshot_pop(), but once you accept that, it's very convenient to
    use, as can be seen by the 2 implementations.

 docs/reference/gtk/gtk4-sections.txt |    1 +
 gtk/gtkcssimagecrossfade.c           |   67 +++----------------
 gtk/gtksnapshot.c                    |  122 +++++++++++++++++++++++++++++++++-
 gtk/gtksnapshot.h                    |    5 ++
 gtk/gtksnapshotprivate.h             |    4 +
 gtk/gtkstack.c                       |   33 ++-------
 6 files changed, 147 insertions(+), 85 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index b34f82d..13a4b0d 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4458,6 +4458,7 @@ gtk_snapshot_push_color_matrix
 gtk_snapshot_push_repeat
 gtk_snapshot_push_clip
 gtk_snapshot_push_rounded_clip
+gtk_snapshot_push_cross_fade
 gtk_snapshot_pop
 gtk_snapshot_pop_and_append
 gtk_snapshot_set_transform
diff --git a/gtk/gtkcssimagecrossfade.c b/gtk/gtkcssimagecrossfade.c
index 2b9aab1..7f80248 100644
--- a/gtk/gtkcssimagecrossfade.c
+++ b/gtk/gtkcssimagecrossfade.c
@@ -106,64 +106,15 @@ gtk_css_image_cross_fade_snapshot (GtkCssImage *image,
 {
   GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
 
-  if (cross_fade->progress <= 0.0)
-    {
-      if (cross_fade->start)
-        gtk_css_image_snapshot (cross_fade->start, snapshot, width, height);
-    }
-  else if (cross_fade->progress >= 1.0)
-    {
-      if (cross_fade->end)
-        gtk_css_image_snapshot (cross_fade->end, snapshot, width, height);
-    }
-  else
-    {
-      GskRenderNode *start_node, *end_node;
-      if (cross_fade->start)
-        {
-          gtk_snapshot_push (snapshot, TRUE, "CrossFadeStart");
-          gtk_css_image_snapshot (cross_fade->start, snapshot, width, height);
-          start_node = gtk_snapshot_pop (snapshot);
-        }
-      else
-        start_node = NULL;
-
-      if (cross_fade->end)
-        {
-          gtk_snapshot_push (snapshot, TRUE, "CrossFadeStart");
-          gtk_css_image_snapshot (cross_fade->end, snapshot, width, height);
-          end_node = gtk_snapshot_pop (snapshot);
-        }
-      else
-        end_node = NULL;
+  gtk_snapshot_push_cross_fade (snapshot, cross_fade->progress, "CrossFadeImage<%g>", cross_fade->progress);
 
-      if (start_node && end_node)
-        {
-          GskRenderNode *node = gsk_cross_fade_node_new (start_node, end_node, cross_fade->progress);
-
-          if (snapshot->record_names)
-            gsk_render_node_set_name (node, "CrossFade");
-          gtk_snapshot_append_node (snapshot, node);
+  if (cross_fade->start)
+    gtk_css_image_snapshot (cross_fade->start, snapshot, width, height);
+  gtk_snapshot_pop_and_append (snapshot);
 
-          gsk_render_node_unref (node);
-          gsk_render_node_unref (start_node);
-          gsk_render_node_unref (end_node);
-        }
-      else if (start_node)
-        {
-          gtk_snapshot_push_opacity (snapshot, 1.0 - cross_fade->progress, "CrossFadeStart");
-          gtk_snapshot_append_node (snapshot, start_node);
-          gtk_snapshot_pop_and_append (snapshot);
-          gsk_render_node_unref (start_node);
-        }
-      else if (end_node)
-        {
-          gtk_snapshot_push_opacity (snapshot, cross_fade->progress, "CrossFadeEnd");
-          gtk_snapshot_append_node (snapshot, end_node);
-          gtk_snapshot_pop_and_append (snapshot);
-          gsk_render_node_unref (end_node);
-        }
-    }
+  if (cross_fade->end)
+    gtk_css_image_snapshot (cross_fade->end, snapshot, width, height);
+  gtk_snapshot_pop_and_append (snapshot);
 }
 
 static gboolean
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 08db8c5..d79f903 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -647,7 +647,6 @@ gtk_snapshot_push_shadow (GtkSnapshot            *snapshot,
   GtkSnapshotState *state;
   char *str;
 
-
   if (name && snapshot->record_names)
     {
       va_list args;
@@ -676,6 +675,127 @@ gtk_snapshot_push_shadow (GtkSnapshot            *snapshot,
   snapshot->state = state;
 }
 
+static GskRenderNode *
+gtk_snapshot_collect_cross_fade_end (GtkSnapshotState *state,
+                                     GskRenderNode   **nodes,
+                                     guint             n_nodes,
+                                     const char       *name)
+{
+  GskRenderNode *start_node, *end_node, *node;
+
+  end_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+  start_node = state->data.cross_fade.start_node;
+
+  if (state->data.cross_fade.progress <= 0.0)
+    {
+      node = start_node;
+
+      if (end_node)
+        gsk_render_node_unref (end_node);
+    }
+  else if (state->data.cross_fade.progress >= 1.0)
+    {
+      node = end_node;
+
+      if (start_node)
+        gsk_render_node_unref (start_node);
+    }
+  else if (start_node && end_node)
+    {
+      node = gsk_cross_fade_node_new (start_node, end_node, state->data.cross_fade.progress);
+      gsk_render_node_set_name (node, name);
+
+      gsk_render_node_unref (start_node);
+      gsk_render_node_unref (end_node);
+    }
+  else if (start_node)
+    {
+      node = gsk_opacity_node_new (start_node, 1.0 - state->data.cross_fade.progress);
+      gsk_render_node_set_name (node, name);
+
+      gsk_render_node_unref (start_node);
+    }
+  else if (end_node)
+    {
+      node = gsk_opacity_node_new (end_node, state->data.cross_fade.progress);
+      gsk_render_node_set_name (node, name);
+
+      gsk_render_node_unref (end_node);
+    }
+  else
+    {
+      node = NULL;
+    }
+
+  return node;
+}
+
+static GskRenderNode *
+gtk_snapshot_collect_cross_fade_start (GtkSnapshotState *state,
+                                       GskRenderNode   **nodes,
+                                       guint             n_nodes,
+                                       const char       *name)
+{
+  state->parent->data.cross_fade.start_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+  
+  return NULL;
+}
+
+/**
+ * gtk_snapshot_push_cross_fade:
+ * @snapshot: a #GtkSnapshot
+ * @progress: progress between 0.0 and 1.0
+ * @name: printf format string for name of the pushed node
+ * @...: printf-style arguments for the @name string
+ *
+ * Snapshots a cross-fade operation between two images with the
+ * given @progress.
+ *
+ * Until the first call to gtk_snapshot_pop(), the start image
+ * will be snapshot. After that call, the end image will be recorded
+ * until the second call to gtk_snapshot_pop().
+ *
+ * Calling this function requires 2 calls to gtk_snapshot_pop().
+ **/
+void
+gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
+                              double       progress,
+                              const char  *name,
+                              ...)
+{
+  GtkSnapshotState *state;
+  char *str;
+
+  if (name && snapshot->record_names)
+    {
+      va_list args;
+
+      va_start (args, name);
+      str = g_strdup_vprintf (name, args);
+      va_end (args);
+    }
+  else
+    str = NULL;
+
+  state = gtk_snapshot_state_new (snapshot->state,
+                                  str,
+                                  snapshot->state->clip_region,
+                                  snapshot->state->translate_x,
+                                  snapshot->state->translate_y,
+                                  gtk_snapshot_collect_cross_fade_end);
+  state->data.cross_fade.progress = progress;
+  state->data.cross_fade.start_node = NULL;
+
+  state = gtk_snapshot_state_new (state,
+                                  str,
+                                  state->clip_region,
+                                  state->translate_x,
+                                  state->translate_y,
+                                  gtk_snapshot_collect_cross_fade_start);
+
+  snapshot->state = state;
+}
+
 /**
  * gtk_snapshot_pop:
  * @snapshot: a #GtkSnapshot
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index 0b691c3..7ac7a43 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -80,6 +80,11 @@ void            gtk_snapshot_push_shadow                (GtkSnapshot
                                                          const char             *name,
                                                          ...) G_GNUC_PRINTF (4, 5);
 GDK_AVAILABLE_IN_3_90
+void            gtk_snapshot_push_cross_fade            (GtkSnapshot            *snapshot,
+                                                         double                  progress,
+                                                         const char             *name,
+                                                         ...) G_GNUC_PRINTF (3, 4);
+GDK_AVAILABLE_IN_3_90
 GskRenderNode * gtk_snapshot_pop                        (GtkSnapshot            *snapshot) 
G_GNUC_WARN_UNUSED_RESULT;
 GDK_AVAILABLE_IN_3_90
 void            gtk_snapshot_pop_and_append             (GtkSnapshot            *snapshot);
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index 91d1b66..3989bc5 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -67,6 +67,10 @@ struct _GtkSnapshotState {
       GskShadow *shadows;
       GskShadow a_shadow; /* Used if n_shadows == 1 */
     } shadow;
+    struct {
+      double progress;
+      GskRenderNode *start_node;
+    } cross_fade;
   } data;
 };
 
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index d1f4767..b1448f2 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -1914,44 +1914,25 @@ gtk_stack_snapshot_crossfade (GtkWidget   *widget,
   GtkStack *stack = GTK_STACK (widget);
   GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
   gdouble progress = gtk_progress_tracker_get_progress (&priv->tracker, FALSE);
-  GskRenderNode *end_node, *node;
-  char *name;
 
-  gtk_snapshot_push (snapshot, TRUE, "GtkStackCrossFadeEnd");
-  gtk_widget_snapshot_child (widget,
-                             priv->visible_child->widget,
-                             snapshot);
-  end_node = gtk_snapshot_pop (snapshot);
+  gtk_snapshot_push_cross_fade (snapshot, progress, "CrossFade<%g>", progress);
 
   if (priv->last_visible_node)
     {
       graphene_matrix_t identity;
-      GskRenderNode *start_node;
 
       graphene_matrix_init_identity (&identity);
 
       gtk_snapshot_push_transform (snapshot, &identity, "CrossFadeStart");
       gtk_snapshot_append_node (snapshot, priv->last_visible_node);
-      start_node = gtk_snapshot_pop (snapshot);
-      node = gsk_cross_fade_node_new (start_node, end_node, progress);
-      gsk_render_node_unref (start_node);
-    }
-  else
-    {
-      node = gsk_opacity_node_new (end_node, 1.0 - progress);
-    }
-
-  if (snapshot->record_names)
-    {
-      name = g_strdup_printf ("CrossFade<%g>", progress);
-      gsk_render_node_set_name (node, name);
-      g_free (name);
+      gtk_snapshot_pop_and_append (snapshot);
     }
+  gtk_snapshot_pop_and_append (snapshot);
 
-  gtk_snapshot_append_node (snapshot, node);
-
-  gsk_render_node_unref (node);
-  gsk_render_node_unref (end_node);
+  gtk_widget_snapshot_child (widget,
+                             priv->visible_child->widget,
+                             snapshot);
+  gtk_snapshot_pop_and_append (snapshot);
 }
 
 static void


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