summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2019-03-05 20:44:45 +0100
committerMatthias Clasen <mclasen@redhat.com>2019-03-29 10:03:18 -0400
commit9d0a42dc143daabe02c90b447bdff42e7f39e1b8 (patch)
treee3ec7502516ca8a4f79f878d83a119b999832618
parentec9be217710b98f6fd24e03e58ac3306e45aa933 (diff)
downloadgtk+-9d0a42dc143daabe02c90b447bdff42e7f39e1b8.tar.gz
stack: Add a cube spin transition
Add a transition to GtkStack that pretends pages are the sides or a cube, and switch them by rotating the cube. Use this transition in widget-factory.
-rw-r--r--demos/widget-factory/widget-factory.c2
-rw-r--r--demos/widget-factory/widget-factory.ui2
-rw-r--r--gtk/gtkstack.c109
-rw-r--r--gtk/gtkstack.h5
4 files changed, 113 insertions, 5 deletions
diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c
index dcd4760e97..08f9d5efb4 100644
--- a/demos/widget-factory/widget-factory.c
+++ b/demos/widget-factory/widget-factory.c
@@ -48,7 +48,7 @@ change_transition_state (GSimpleAction *action,
GtkStackTransitionType transition;
if (g_variant_get_boolean (state))
- transition = GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT;
+ transition = GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT;
else
transition = GTK_STACK_TRANSITION_TYPE_NONE;
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index 67377698e7..8c3a7f6a50 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -426,7 +426,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="margin">10</property>
<child>
<object class="GtkStack" id="toplevel_stack">
- <property name="transition-duration">30000</property>
+ <property name="transition-duration">1000</property>
<child>
<object class="GtkStackPage">
<property name="name">page1</property>
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index d7222f9e5e..d329d7b6e3 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -104,6 +104,9 @@
* @GTK_STACK_TRANSITION_TYPE_OVER_DOWN_UP: Cover the old page sliding down or uncover the new page sliding up, according to order
* @GTK_STACK_TRANSITION_TYPE_OVER_LEFT_RIGHT: Cover the old page sliding left or uncover the new page sliding right, according to order
* @GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT: Cover the old page sliding right or uncover the new page sliding left, according to order
+ * @GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT: Pretend the pages are sides of a cube and rotate that cube to the left
+ * @GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT: Pretend the pages are sides of a cube and rotate that cube to the right
+ * @GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT: Pretend the pages are sides of a cube and rotate that cube to the left or right according to the children order
*
* These enumeration values describe the possible transitions
* between pages in a #GtkStack widget.
@@ -873,7 +876,8 @@ is_direction_dependent_transition (GtkStackTransitionType transition_type)
transition_type == GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN ||
transition_type == GTK_STACK_TRANSITION_TYPE_OVER_DOWN_UP ||
transition_type == GTK_STACK_TRANSITION_TYPE_OVER_LEFT_RIGHT ||
- transition_type == GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT);
+ transition_type == GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT ||
+ transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT);
}
/* Returns simple transition type for a direction dependent transition, given
@@ -887,6 +891,8 @@ get_simple_transition_type (gboolean new_child_first,
{
case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT:
return new_child_first ? GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT : GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT;
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT:
+ return new_child_first ? GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT : GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT;
case GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN:
return new_child_first ? GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN : GTK_STACK_TRANSITION_TYPE_SLIDE_UP;
case GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN:
@@ -911,6 +917,8 @@ get_simple_transition_type (gboolean new_child_first,
case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
case GTK_STACK_TRANSITION_TYPE_CROSSFADE:
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT:
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT:
default:
return transition_type;
}
@@ -1049,6 +1057,10 @@ effective_transition_type (GtkStack *stack,
return GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT;
case GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT:
return GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT;
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT:
+ return GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT;
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT:
+ return GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT;
case GTK_STACK_TRANSITION_TYPE_OVER_LEFT:
return GTK_STACK_TRANSITION_TYPE_OVER_RIGHT;
case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT:
@@ -1071,6 +1083,7 @@ effective_transition_type (GtkStack *stack,
case GTK_STACK_TRANSITION_TYPE_OVER_LEFT_RIGHT:
case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT:
case GTK_STACK_TRANSITION_TYPE_CROSSFADE:
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT:
default:
return transition_type;
}
@@ -2045,7 +2058,6 @@ gtk_stack_forall (GtkContainer *container,
}
}
-#include <gsk/gskrendernodeprivate.h>
static void
gtk_stack_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
@@ -2168,6 +2180,94 @@ gtk_stack_snapshot_under (GtkWidget *widget,
}
static void
+gtk_stack_snapshot_cube (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ GtkStack *stack = GTK_STACK (widget);
+ GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
+ double progress = gtk_progress_tracker_get_progress (&priv->tracker, FALSE);
+
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT)
+ progress = 1 - progress;
+
+ if (priv->last_visible_node && progress > 0.5)
+ {
+ gtk_snapshot_save (snapshot);
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ gtk_widget_get_width (widget) / 2.f,
+ gtk_widget_get_height (widget) / 2.f,
+ 0));
+ gtk_snapshot_perspective (snapshot, 2 * gtk_widget_get_width (widget) / 1.f);
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ 0, 0,
+ - gtk_widget_get_width (widget) / 2.f));
+ gtk_snapshot_rotate_3d (snapshot, -90 * progress, graphene_vec3_y_axis());
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ - gtk_widget_get_width (widget) / 2.f,
+ - gtk_widget_get_height (widget) / 2.f,
+ gtk_widget_get_width (widget) / 2.f));
+ gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (
+ priv->last_visible_surface_allocation.x,
+ priv->last_visible_surface_allocation.y));
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT)
+ gtk_snapshot_append_node (snapshot, priv->last_visible_node);
+ else
+ gtk_widget_snapshot_child (widget, priv->visible_child->widget, snapshot);
+ gtk_snapshot_restore (snapshot);
+ }
+
+ gtk_snapshot_save (snapshot);
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ gtk_widget_get_width (widget) / 2.f,
+ gtk_widget_get_height (widget) / 2.f,
+ 0));
+ gtk_snapshot_perspective (snapshot, 2 * gtk_widget_get_width (widget) / 1.f);
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ 0, 0,
+ - gtk_widget_get_width (widget) / 2.f));
+ gtk_snapshot_rotate_3d (snapshot, 90 * (1.0 - progress), graphene_vec3_y_axis());
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ - gtk_widget_get_width (widget) / 2.f,
+ - gtk_widget_get_height (widget) / 2.f,
+ gtk_widget_get_width (widget) / 2.f));
+ gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (
+ priv->last_visible_surface_allocation.x,
+ priv->last_visible_surface_allocation.y));
+
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT)
+ gtk_widget_snapshot_child (widget, priv->visible_child->widget, snapshot);
+ else
+ gtk_snapshot_append_node (snapshot, priv->last_visible_node);
+ gtk_snapshot_restore (snapshot);
+
+ if (priv->last_visible_node && progress <= 0.5)
+ {
+ gtk_snapshot_save (snapshot);
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ gtk_widget_get_width (widget) / 2.f,
+ gtk_widget_get_height (widget) / 2.f,
+ 0));
+ gtk_snapshot_perspective (snapshot, 2 * gtk_widget_get_width (widget) / 1.f);
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ 0, 0,
+ - gtk_widget_get_width (widget) / 2.f));
+ gtk_snapshot_rotate_3d (snapshot, -90 * progress, graphene_vec3_y_axis());
+ gtk_snapshot_translate_3d (snapshot, &GRAPHENE_POINT3D_INIT (
+ - gtk_widget_get_width (widget) / 2.f,
+ - gtk_widget_get_height (widget) / 2.f,
+ gtk_widget_get_width (widget) / 2.f));
+ gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (
+ priv->last_visible_surface_allocation.x,
+ priv->last_visible_surface_allocation.y));
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT)
+ gtk_snapshot_append_node (snapshot, priv->last_visible_node);
+ else
+ gtk_widget_snapshot_child (widget, priv->visible_child->widget, snapshot);
+ gtk_snapshot_restore (snapshot);
+ }
+}
+
+static void
gtk_stack_snapshot_slide (GtkWidget *widget,
GtkSnapshot *snapshot)
{
@@ -2283,6 +2383,10 @@ gtk_stack_snapshot (GtkWidget *widget,
case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
gtk_stack_snapshot_under (widget, snapshot);
break;
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT:
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT:
+ gtk_stack_snapshot_cube (widget, snapshot);
+ break;
case GTK_STACK_TRANSITION_TYPE_NONE:
case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT:
case GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN:
@@ -2290,6 +2394,7 @@ gtk_stack_snapshot (GtkWidget *widget,
case GTK_STACK_TRANSITION_TYPE_OVER_DOWN_UP:
case GTK_STACK_TRANSITION_TYPE_OVER_LEFT_RIGHT:
case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT:
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT:
default:
g_assert_not_reached ();
}
diff --git a/gtk/gtkstack.h b/gtk/gtkstack.h
index 658ef8bb6a..8f67b889c2 100644
--- a/gtk/gtkstack.h
+++ b/gtk/gtkstack.h
@@ -72,7 +72,10 @@ typedef enum {
GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN,
GTK_STACK_TRANSITION_TYPE_OVER_DOWN_UP,
GTK_STACK_TRANSITION_TYPE_OVER_LEFT_RIGHT,
- GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT
+ GTK_STACK_TRANSITION_TYPE_OVER_RIGHT_LEFT,
+ GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT,
+ GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT,
+ GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT
} GtkStackTransitionType;
struct _GtkStack {