diff options
author | Benjamin Otte <otte@redhat.com> | 2017-01-12 22:00:38 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-01-13 03:38:36 +0100 |
commit | d9b0685b495926af602990e709feaad5822d5724 (patch) | |
tree | faa60a95b5eb64d64926b7542301813bb8038ef9 | |
parent | 670ae58cc9c69cb295822e8e41abd9497171404e (diff) | |
download | gtk+-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.txt | 1 | ||||
-rw-r--r-- | gtk/gtkcssimagecrossfade.c | 63 | ||||
-rw-r--r-- | gtk/gtksnapshot.c | 122 | ||||
-rw-r--r-- | gtk/gtksnapshot.h | 5 | ||||
-rw-r--r-- | gtk/gtksnapshotprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkstack.c | 33 |
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 |