summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2017-01-12 22:00:38 +0100
committerBenjamin Otte <otte@redhat.com>2017-01-13 03:38:36 +0100
commitd9b0685b495926af602990e709feaad5822d5724 (patch)
treefaa60a95b5eb64d64926b7542301813bb8038ef9
parent670ae58cc9c69cb295822e8e41abd9497171404e (diff)
downloadgtk+-d9b0685b495926af602990e709feaad5822d5724.tar.gz
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.
-rw-r--r--docs/reference/gtk/gtk4-sections.txt1
-rw-r--r--gtk/gtkcssimagecrossfade.c63
-rw-r--r--gtk/gtksnapshot.c122
-rw-r--r--gtk/gtksnapshot.h5
-rw-r--r--gtk/gtksnapshotprivate.h4
-rw-r--r--gtk/gtkstack.c33
6 files changed, 145 insertions, 83 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index b34f82d1aa..13a4b0d30b 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 2b9aab1271..7f80248c2b 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 08db8c5b63..d79f9039c1 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 0b691c3486..7ac7a43481 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 91d1b66ef6..3989bc5fde 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 d1f4767ed8..b1448f28b7 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