[gtk+] Add gtk_snapshot_push_cross_fade()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Add gtk_snapshot_push_cross_fade()
- Date: Fri, 13 Jan 2017 02:38:48 +0000 (UTC)
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]