[gtk/wip/baedert/for-master: 2/2] stack: Apply transitions in size-allocate
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/baedert/for-master: 2/2] stack: Apply transitions in size-allocate
- Date: Fri, 12 Jun 2020 14:45:07 +0000 (UTC)
commit 952df968bfec0d0f59d21629cac722508dea0e51
Author: Timm Bäder <mail baedert org>
Date: Fri Jun 12 16:10:03 2020 +0200
stack: Apply transitions in size-allocate
Fixes #2678
gtk/gtkstack.c | 637 ++++++++++++++++++++++++---------------------------------
1 file changed, 270 insertions(+), 367 deletions(-)
---
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index 303059643e..5f88479bd6 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -138,8 +138,6 @@ typedef struct {
guint transition_duration;
GtkStackPage *last_visible_child;
- GskRenderNode *last_visible_node;
- GtkAllocation last_visible_surface_allocation;
guint tick_id;
GtkProgressTracker tracker;
gboolean first_frame_skipped;
@@ -645,8 +643,6 @@ gtk_stack_finalize (GObject *obj)
gtk_stack_unschedule_ticks (stack);
- g_clear_pointer (&priv->last_visible_node, gsk_render_node_unref);
-
G_OBJECT_CLASS (gtk_stack_parent_class)->finalize (obj);
}
@@ -859,7 +855,8 @@ static inline gboolean
is_down_transition (GtkStackTransitionType transition_type)
{
return (transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN ||
- transition_type == GTK_STACK_TRANSITION_TYPE_OVER_DOWN);
+ transition_type == GTK_STACK_TRANSITION_TYPE_OVER_DOWN ||
+ transition_type == GTK_STACK_TRANSITION_TYPE_UNDER_DOWN);
}
/* Transitions that cause the bin window to move */
@@ -873,7 +870,11 @@ is_window_moving_transition (GtkStackTransitionType transition_type)
transition_type == GTK_STACK_TRANSITION_TYPE_OVER_UP ||
transition_type == GTK_STACK_TRANSITION_TYPE_OVER_DOWN ||
transition_type == GTK_STACK_TRANSITION_TYPE_OVER_LEFT ||
- transition_type == GTK_STACK_TRANSITION_TYPE_OVER_RIGHT);
+ transition_type == GTK_STACK_TRANSITION_TYPE_OVER_RIGHT ||
+ transition_type == GTK_STACK_TRANSITION_TYPE_UNDER_UP ||
+ transition_type == GTK_STACK_TRANSITION_TYPE_UNDER_DOWN ||
+ transition_type == GTK_STACK_TRANSITION_TYPE_UNDER_LEFT ||
+ transition_type == GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT);
}
/* Transitions that change direction depending on the relative order of the
@@ -934,44 +935,15 @@ get_simple_transition_type (gboolean new_child_first,
}
}
-static gint
-get_bin_window_x (GtkStack *stack)
+static double
+get_transition_progress (GtkStack *stack)
{
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- int width;
- int x = 0;
-
- width = gtk_widget_get_width (GTK_WIDGET (stack));
-
- if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER)
- {
- if (is_left_transition (priv->active_transition_type))
- x = width * (1 - gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- if (is_right_transition (priv->active_transition_type))
- x = -width * (1 - gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- }
-
- return x;
-}
-
-static gint
-get_bin_window_y (GtkStack *stack)
-{
- GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- int height;
- int y = 0;
-
- height = gtk_widget_get_height (GTK_WIDGET (stack));
- if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER)
- {
- if (is_up_transition (priv->active_transition_type))
- y = height * (1 - gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- if (is_down_transition(priv->active_transition_type))
- y = -height * (1 - gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- }
+ if (gtk_progress_tracker_get_state (&priv->tracker) == GTK_PROGRESS_STATE_AFTER)
+ return 0;
- return y;
+ return gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE);
}
static void
@@ -981,20 +953,16 @@ gtk_stack_progress_updated (GtkStack *stack)
if (!priv->vhomogeneous || !priv->hhomogeneous)
gtk_widget_queue_resize (GTK_WIDGET (stack));
- else if (is_window_moving_transition (priv->active_transition_type))
- gtk_widget_queue_allocate (GTK_WIDGET (stack));
- else
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_CROSSFADE)
gtk_widget_queue_draw (GTK_WIDGET (stack));
+ else
+ gtk_widget_queue_allocate (GTK_WIDGET (stack));
- if (gtk_progress_tracker_get_state (&priv->tracker) == GTK_PROGRESS_STATE_AFTER)
+ if (gtk_progress_tracker_get_state (&priv->tracker) == GTK_PROGRESS_STATE_AFTER &&
+ priv->last_visible_child)
{
- g_clear_pointer (&priv->last_visible_node, gsk_render_node_unref);
-
- if (priv->last_visible_child != NULL)
- {
- gtk_widget_set_child_visible (priv->last_visible_child->widget, FALSE);
- priv->last_visible_child = NULL;
- }
+ gtk_widget_set_child_visible (priv->last_visible_child->widget, FALSE);
+ priv->last_visible_child = NULL;
}
}
@@ -1104,6 +1072,26 @@ effective_transition_type (GtkStack *stack,
}
}
+static void
+gtk_stack_get_child_size (GtkStack *stack,
+ GtkWidget *child,
+ int *out_width,
+ int *out_height)
+{
+ GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
+ const int width = gtk_widget_get_width (GTK_WIDGET (stack));
+ const int height = gtk_widget_get_height (GTK_WIDGET (stack));
+ int min_width, min_height;
+
+ gtk_widget_measure (priv->visible_child->widget, GTK_ORIENTATION_HORIZONTAL,
+ height, &min_width, NULL, NULL, NULL);
+ *out_width = MAX (width, min_width);
+
+ gtk_widget_measure (priv->visible_child->widget, GTK_ORIENTATION_VERTICAL,
+ *out_width, &min_height, NULL, NULL, NULL);
+ *out_height = MAX (height, min_height);
+}
+
static void
gtk_stack_start_transition (GtkStack *stack,
GtkStackTransitionType transition_type,
@@ -1210,15 +1198,13 @@ set_visible_child (GtkStack *stack,
gtk_widget_set_child_visible (priv->last_visible_child->widget, FALSE);
priv->last_visible_child = NULL;
- g_clear_pointer (&priv->last_visible_node, gsk_render_node_unref);
-
if (priv->visible_child && priv->visible_child->widget)
{
if (gtk_widget_is_visible (widget))
{
priv->last_visible_child = priv->visible_child;
- priv->last_visible_widget_width = gtk_widget_get_allocated_width
(priv->last_visible_child->widget);
- priv->last_visible_widget_height = gtk_widget_get_allocated_height
(priv->last_visible_child->widget);
+ priv->last_visible_widget_width = gtk_widget_get_width (widget);
+ priv->last_visible_widget_height = gtk_widget_get_height (widget);
}
else
{
@@ -1709,6 +1695,7 @@ gtk_stack_set_transition_duration (GtkStack *stack,
return;
priv->transition_duration = duration;
+
g_object_notify_by_pspec (G_OBJECT (stack),
stack_props[PROP_TRANSITION_DURATION]);
}
@@ -2059,312 +2046,251 @@ 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);
+ const gdouble progress = gtk_progress_tracker_get_progress (&priv->tracker, FALSE);
gtk_snapshot_push_cross_fade (snapshot, progress);
-
- if (priv->last_visible_node)
- {
- gtk_snapshot_save (snapshot);
- gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (
- priv->last_visible_surface_allocation.x,
- priv->last_visible_surface_allocation.y));
- gtk_snapshot_append_node (snapshot, priv->last_visible_node);
- gtk_snapshot_restore (snapshot);
- }
+ gtk_widget_snapshot_child (widget, priv->last_visible_child->widget, snapshot);
gtk_snapshot_pop (snapshot);
-
- gtk_widget_snapshot_child (widget,
- priv->visible_child->widget,
- snapshot);
+ gtk_widget_snapshot_child (widget, priv->visible_child->widget, snapshot);
gtk_snapshot_pop (snapshot);
}
static void
-gtk_stack_snapshot_under (GtkWidget *widget,
- GtkSnapshot *snapshot)
+gtk_stack_allocate_cube (GtkStack *stack)
{
- GtkStack *stack = GTK_STACK (widget);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- int widget_width, widget_height;
- gint x, y, width, height, pos_x, pos_y;
+ GtkWidget *widget = GTK_WIDGET (stack);
+ const int width = gtk_widget_get_width (widget);
+ const int height = gtk_widget_get_height (widget);
+ double progress = gtk_progress_tracker_get_progress (&priv->tracker, FALSE);
+ int last_widget_width, last_widget_height;
+ int visible_widget_width, visible_widget_height;
+ GskTransform *t;
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT)
+ progress = 1 - progress;
- x = y = 0;
- width = widget_width = gtk_widget_get_width (widget);
- height = widget_height = gtk_widget_get_height (widget);
+ gtk_stack_get_child_size (stack, priv->last_visible_child->widget,
+ &last_widget_width, &last_widget_height);
- pos_x = pos_y = 0;
+ gtk_stack_get_child_size (stack, priv->visible_child->widget,
+ &visible_widget_width, &visible_widget_height);
- switch ((guint) priv->active_transition_type)
+ if (progress > 0.5)
{
- case GTK_STACK_TRANSITION_TYPE_UNDER_DOWN:
- y = 0;
- height = widget_height * (gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- pos_y = height;
- break;
- case GTK_STACK_TRANSITION_TYPE_UNDER_UP:
- y = widget_height * (1 - gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- height = widget_height - y;
- pos_y = y - widget_height;
- break;
- case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
- x = widget_width * (1 - gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- width = widget_width - x;
- pos_x = x - widget_width;
- break;
- case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
- x = 0;
- width = widget_width * (gtk_progress_tracker_get_ease_out_cubic (&priv->tracker, FALSE));
- pos_x = width;
- break;
- default:
- g_assert_not_reached ();
- }
+ t = gsk_transform_translate_3d (NULL, &GRAPHENE_POINT3D_INIT (width / 2.0f, height / 2.0f, 0));
+ t = gsk_transform_perspective (t, 2 * width / 1.0f);
+ t = gsk_transform_translate_3d (t, &GRAPHENE_POINT3D_INIT (0, 0, - width / 2.0f));
+ t = gsk_transform_rotate_3d (t, -90.0f * progress, graphene_vec3_y_axis ());
+ t = gsk_transform_translate_3d (t, &GRAPHENE_POINT3D_INIT (- width / 2.0f,
+ - height / 2.0f,
+ width / 2.0f));
- gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT(x, y, width, height));
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT)
+ gtk_widget_allocate (priv->last_visible_child->widget,
+ last_widget_width, last_widget_height, -1, t);
+ else
+ gtk_widget_allocate (priv->visible_child->widget,
+ visible_widget_width, visible_widget_height, -1, t);
+ }
- gtk_widget_snapshot_child (widget,
- priv->visible_child->widget,
- snapshot);
+ t = gsk_transform_translate_3d (NULL, &GRAPHENE_POINT3D_INIT (width / 2.0f, height / 2.0f, 0));
+ t = gsk_transform_perspective (t, 2 * width / 1.0f);
+ t = gsk_transform_translate_3d (t, &GRAPHENE_POINT3D_INIT (0, 0, -width / 2.0f));
+ t = gsk_transform_rotate_3d (t, 90 * (1.0 - progress), graphene_vec3_y_axis ());
+ t = gsk_transform_translate_3d (t, &GRAPHENE_POINT3D_INIT (- width / 2.0f, - height / 2.0f, width / 2.0f));
- gtk_snapshot_pop (snapshot);
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT)
+ gtk_widget_allocate (priv->visible_child->widget,
+ visible_widget_width, visible_widget_height, -1, t);
+ else
+ gtk_widget_allocate (priv->last_visible_child->widget,
+ last_widget_width, last_widget_height, -1, t);
- if (priv->last_visible_node)
+ if (progress <= 0.5)
{
- gtk_snapshot_save (snapshot);
- gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (pos_x, pos_y));
- gtk_snapshot_append_node (snapshot, priv->last_visible_node);
- gtk_snapshot_restore (snapshot);
+ t = gsk_transform_translate_3d (NULL, &GRAPHENE_POINT3D_INIT (width / 2.0f, height / 2.0f, 0));
+ t = gsk_transform_perspective (t, 2 * width / 1.0f);
+ t = gsk_transform_translate_3d (t, &GRAPHENE_POINT3D_INIT (0, 0, - width / 2.0f));
+ t = gsk_transform_rotate_3d (t, -90 * progress, graphene_vec3_y_axis ());
+ t = gsk_transform_translate_3d (t, &GRAPHENE_POINT3D_INIT (- width / 2.0f, - height / 2.0, width /
2.0f));
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT)
+ gtk_widget_allocate (priv->last_visible_child->widget,
+ last_widget_width, last_widget_height, -1, t);
+ else
+ gtk_widget_allocate (priv->visible_child->widget,
+ visible_widget_width, visible_widget_height, -1, t);
}
}
static void
-gtk_stack_snapshot_cube (GtkWidget *widget,
- GtkSnapshot *snapshot)
+gtk_stack_allocate_slide (GtkStack *stack)
{
- 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;
+ GtkWidget *widget = GTK_WIDGET (stack);
+ const int width = gtk_widget_get_width (widget);
+ const int height = gtk_widget_get_height (widget);
+ const double progress = get_transition_progress (stack);
+ int new_x, new_y;
+ int old_x, old_y;
+ GtkAllocation child_allocation;
- if (priv->last_visible_node && progress > 0.5)
+ switch ((guint) priv->active_transition_type)
{
- 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);
+ case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT:
+ old_x = - width * progress;
+ old_y = 0;
+ new_x = width - (width * progress);
+ new_y = 0;
+ break;
+ case GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT:
+ old_x = width * progress;
+ old_y = 0;
+ new_x = - width + (width * progress);
+ new_y = 0;
+ break;
+ case GTK_STACK_TRANSITION_TYPE_OVER_LEFT:
+ old_x = 0;
+ old_y = 0;
+ new_x = width - (width * progress);
+ new_y = 0;
+ break;
+ case GTK_STACK_TRANSITION_TYPE_SLIDE_UP:
+ old_x = 0;
+ old_y = - height * progress;
+ new_x = 0;
+ new_y = height - (height * progress);
+ break;
+ case GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN:
+ old_x = 0;
+ old_y = height * progress;
+ new_x = 0;
+ new_y = - height + (height * progress);
+ break;
+ case GTK_STACK_TRANSITION_TYPE_UNDER_UP:
+ new_x = 0;
+ new_y = 0;
+ old_x = 0;
+ old_y = - height * progress;
+ break;
+ case GTK_STACK_TRANSITION_TYPE_UNDER_DOWN:
+ old_x = 0;
+ old_y = progress * height;
+ new_x = 0;
+ new_y = 0;
+ break;
+ case GTK_STACK_TRANSITION_TYPE_OVER_DOWN:
+ old_x = 0;
+ old_y = 0;
+ new_x = 0;
+ new_y = - height + (height * progress);
+ break;
+ case GTK_STACK_TRANSITION_TYPE_OVER_UP:
+ old_x = 0;
+ old_y = 0;
+ new_x = 0;
+ new_y = height - (height * progress);
+ break;
+ case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
+ old_x = width * progress;
+ old_y = 0;
+ new_x = 0;
+ new_y = 0;
+ break;
+ case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT:
+ old_x = 0;
+ old_y = 0;
+ new_x = - width + (width * progress);
+ new_y = 0;
+ break;
+ case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
+ new_x = 0;
+ new_y = 0;
+ old_x = - width * progress;
+ old_y = 0;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
}
- 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));
+ gtk_stack_get_child_size (stack, priv->visible_child->widget,
+ &child_allocation.width, &child_allocation.height);
+ child_allocation.x = new_x;
+ child_allocation.y = new_y;
+ gtk_widget_size_allocate (priv->visible_child->widget, &child_allocation, -1);
- 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);
- }
+ gtk_stack_get_child_size (stack, priv->last_visible_child->widget,
+ &child_allocation.width, &child_allocation.height);
+ child_allocation.x = old_x;
+ child_allocation.y = old_y;
+ gtk_widget_size_allocate (priv->last_visible_child->widget, &child_allocation, -1);
}
static void
-gtk_stack_snapshot_slide (GtkWidget *widget,
- GtkSnapshot *snapshot)
+gtk_stack_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GtkStack *stack = GTK_STACK (widget);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- if (priv->last_visible_node)
- {
- int x, y;
- int width, height;
-
- width = gtk_widget_get_width (widget);
- height = gtk_widget_get_height (widget);
-
- x = get_bin_window_x (stack);
- y = get_bin_window_y (stack);
+ if (!priv->visible_child)
+ return;
- switch ((guint) priv->active_transition_type)
+ if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER &&
+ priv->last_visible_child)
+ {
+ gtk_snapshot_push_clip (snapshot,
+ &GRAPHENE_RECT_INIT(
+ 0, 0,
+ gtk_widget_get_width (widget),
+ gtk_widget_get_height (widget)
+ ));
+
+ switch (priv->active_transition_type)
{
- case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT:
- x -= width;
+ case GTK_STACK_TRANSITION_TYPE_CROSSFADE:
+ gtk_stack_snapshot_crossfade (widget, snapshot);
break;
+ case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT:
case GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT:
- x += width;
- break;
case GTK_STACK_TRANSITION_TYPE_SLIDE_UP:
- y -= height;
- break;
case GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN:
- y += height;
- break;
case GTK_STACK_TRANSITION_TYPE_OVER_UP:
- case GTK_STACK_TRANSITION_TYPE_OVER_DOWN:
- y = 0;
- break;
case GTK_STACK_TRANSITION_TYPE_OVER_LEFT:
case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT:
- x = 0;
+ case GTK_STACK_TRANSITION_TYPE_OVER_DOWN:
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT:
+ case GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT:
+ case GTK_STACK_TRANSITION_TYPE_NONE:
+ case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT:
+ case GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN:
+ case GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN:
+ 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:
+ gtk_widget_snapshot_child (widget, priv->last_visible_child->widget, snapshot);
+ gtk_widget_snapshot_child (widget, priv->visible_child->widget, snapshot);
+ break;
+ case GTK_STACK_TRANSITION_TYPE_UNDER_DOWN:
+ case GTK_STACK_TRANSITION_TYPE_UNDER_RIGHT:
+ case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
+ case GTK_STACK_TRANSITION_TYPE_UNDER_UP:
+ gtk_widget_snapshot_child (widget, priv->visible_child->widget, snapshot);
+ gtk_widget_snapshot_child (widget, priv->last_visible_child->widget, snapshot);
break;
default:
g_assert_not_reached ();
- break;
}
- if (priv->last_visible_child != NULL)
- {
- if (gtk_widget_get_valign (priv->last_visible_child->widget) == GTK_ALIGN_END &&
- priv->last_visible_widget_height > height)
- y -= priv->last_visible_widget_height - height;
- else if (gtk_widget_get_valign (priv->last_visible_child->widget) == GTK_ALIGN_CENTER)
- y -= (priv->last_visible_widget_height - height) / 2;
- }
-
- gtk_snapshot_save (snapshot);
- gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
- gtk_snapshot_append_node (snapshot, priv->last_visible_node);
- gtk_snapshot_restore (snapshot);
- }
-
- gtk_widget_snapshot_child (widget,
- priv->visible_child->widget,
- snapshot);
-}
-
-static void
-gtk_stack_snapshot (GtkWidget *widget,
- GtkSnapshot *snapshot)
-{
- GtkStack *stack = GTK_STACK (widget);
- GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
-
- if (priv->visible_child)
+ gtk_snapshot_pop (snapshot);
+ }
+ else
{
- if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER)
- {
- if (priv->last_visible_node == NULL &&
- priv->last_visible_child != NULL)
- {
- GtkSnapshot *last_visible_snapshot;
-
- gtk_widget_get_allocation (priv->last_visible_child->widget,
- &priv->last_visible_surface_allocation);
- last_visible_snapshot = gtk_snapshot_new ();
- gtk_widget_snapshot (priv->last_visible_child->widget, last_visible_snapshot);
- priv->last_visible_node = gtk_snapshot_free_to_node (last_visible_snapshot);
- }
-
- gtk_snapshot_push_clip (snapshot,
- &GRAPHENE_RECT_INIT(
- 0, 0,
- gtk_widget_get_width (widget),
- gtk_widget_get_height (widget)
- ));
-
- switch (priv->active_transition_type)
- {
- case GTK_STACK_TRANSITION_TYPE_CROSSFADE:
- gtk_stack_snapshot_crossfade (widget, snapshot);
- break;
- case GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT:
- case GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT:
- case GTK_STACK_TRANSITION_TYPE_SLIDE_UP:
- case GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN:
- case GTK_STACK_TRANSITION_TYPE_OVER_UP:
- case GTK_STACK_TRANSITION_TYPE_OVER_DOWN:
- case GTK_STACK_TRANSITION_TYPE_OVER_LEFT:
- case GTK_STACK_TRANSITION_TYPE_OVER_RIGHT:
- gtk_stack_snapshot_slide (widget, snapshot);
- break;
- case GTK_STACK_TRANSITION_TYPE_UNDER_UP:
- case GTK_STACK_TRANSITION_TYPE_UNDER_DOWN:
- case GTK_STACK_TRANSITION_TYPE_UNDER_LEFT:
- 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:
- case GTK_STACK_TRANSITION_TYPE_OVER_UP_DOWN:
- 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 ();
- }
-
- gtk_snapshot_pop (snapshot);
- }
- else
- gtk_widget_snapshot_child (widget,
- priv->visible_child->widget,
- snapshot);
+ gtk_widget_snapshot_child (widget,
+ priv->visible_child->widget,
+ snapshot);
}
}
@@ -2376,71 +2302,51 @@ gtk_stack_size_allocate (GtkWidget *widget,
{
GtkStack *stack = GTK_STACK (widget);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkAllocation child_allocation;
-
- child_allocation.x = get_bin_window_x (stack);
- child_allocation.y = get_bin_window_y (stack);
-
- if (priv->last_visible_child)
- {
- int min, nat;
-
- gtk_widget_measure (priv->last_visible_child->widget, GTK_ORIENTATION_HORIZONTAL,
- -1,
- &min, &nat, NULL, NULL);
- child_allocation.width = MAX (min, width);
- gtk_widget_measure (priv->last_visible_child->widget, GTK_ORIENTATION_VERTICAL,
- child_allocation.width,
- &min, &nat, NULL, NULL);
- child_allocation.height = MAX (min, height);
- gtk_widget_size_allocate (priv->last_visible_child->widget, &child_allocation, -1);
-
- if (!gdk_rectangle_equal (&priv->last_visible_surface_allocation,
- &child_allocation))
- {
- g_clear_pointer (&priv->last_visible_node, gsk_render_node_unref);
- }
- }
-
- child_allocation.width = width;
- child_allocation.height = height;
+ if (!priv->visible_child)
+ return;
- if (priv->visible_child)
+ if (gtk_progress_tracker_get_state (&priv->tracker) != GTK_PROGRESS_STATE_AFTER &&
+ priv->last_visible_child)
{
int min_width;
int min_height;
- gtk_widget_measure (priv->visible_child->widget, GTK_ORIENTATION_HORIZONTAL,
- height, &min_width, NULL, NULL, NULL);
- child_allocation.width = MAX (child_allocation.width, min_width);
-
- gtk_widget_measure (priv->visible_child->widget, GTK_ORIENTATION_VERTICAL,
- child_allocation.width, &min_height, NULL, NULL, NULL);
- child_allocation.height = MAX (child_allocation.height, min_height);
-
- if (child_allocation.width > width)
+ if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_CROSSFADE)
{
- GtkAlign halign = gtk_widget_get_halign (priv->visible_child->widget);
+ /* Last visible child */
+ gtk_stack_get_child_size (stack, priv->last_visible_child->widget, &min_width, &min_height);
+ gtk_widget_allocate (priv->last_visible_child->widget, min_width, min_height, -1, NULL);
- if (halign == GTK_ALIGN_CENTER || halign == GTK_ALIGN_FILL)
- child_allocation.x = (width - child_allocation.width) / 2;
- else if (halign == GTK_ALIGN_END)
- child_allocation.x = (width - child_allocation.width);
+ /* visible child */
+ gtk_stack_get_child_size (stack, priv->visible_child->widget, &min_width, &min_height);
+ gtk_widget_allocate (priv->visible_child->widget, min_width, min_height, -1, NULL);
}
-
- if (child_allocation.height > height)
+ else if (is_window_moving_transition (priv->active_transition_type))
{
- GtkAlign valign = gtk_widget_get_valign (priv->visible_child->widget);
-
- if (valign == GTK_ALIGN_CENTER || valign == GTK_ALIGN_FILL)
- child_allocation.y = (height - child_allocation.height) / 2;
- else if (valign == GTK_ALIGN_END)
- child_allocation.y = (height - child_allocation.height);
+ gtk_stack_allocate_slide (stack);
+ }
+ else if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_RIGHT ||
+ priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT ||
+ priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT)
+ {
+ gtk_stack_allocate_cube (stack);
}
+ else
+ {
+ g_assert_not_reached ();
+ }
+
+ }
+ else
+ {
+ int min_width;
+ int min_height;
- gtk_widget_size_allocate (priv->visible_child->widget, &child_allocation, -1);
+ gtk_stack_get_child_size (stack, priv->visible_child->widget, &min_width, &min_height);
+ gtk_widget_allocate (priv->visible_child->widget, min_width, min_height, -1, NULL);
}
+
}
#define LERP(a, b, t) ((a) + (((b) - (a)) * (1.0 - (t))))
@@ -2457,12 +2363,9 @@ gtk_stack_measure (GtkWidget *widget,
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
GtkStackPage *child_info;
GtkWidget *child;
- gint child_min, child_nat;
+ int child_min, child_nat;
GList *l;
- *minimum = 0;
- *natural = 0;
-
for (l = priv->children; l != NULL; l = l->next)
{
child_info = l->data;
@@ -2486,13 +2389,13 @@ gtk_stack_measure (GtkWidget *widget,
{
if (orientation == GTK_ORIENTATION_VERTICAL && !priv->vhomogeneous)
{
- gdouble t = priv->interpolate_size ? gtk_progress_tracker_get_ease_out_cubic (&priv->tracker,
FALSE) : 1.0;
+ double t = priv->interpolate_size ? gtk_progress_tracker_get_ease_out_cubic (&priv->tracker,
FALSE) : 1.0;
*minimum = LERP (*minimum, priv->last_visible_widget_height, t);
*natural = LERP (*natural, priv->last_visible_widget_height, t);
}
if (orientation == GTK_ORIENTATION_HORIZONTAL && !priv->hhomogeneous)
{
- gdouble t = priv->interpolate_size ? gtk_progress_tracker_get_ease_out_cubic (&priv->tracker,
FALSE) : 1.0;
+ double t = priv->interpolate_size ? gtk_progress_tracker_get_ease_out_cubic (&priv->tracker,
FALSE) : 1.0;
*minimum = LERP (*minimum, priv->last_visible_widget_width, t);
*natural = LERP (*natural, priv->last_visible_widget_width, t);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]