GtkStack: add vertical slide transitions

We allow transitions that slide up or down.
This commit is contained in:
Matthias Clasen 2013-04-21 20:17:40 -04:00
parent 88cd26575d
commit c37b30f317
3 changed files with 57 additions and 25 deletions

View File

@ -52,15 +52,16 @@
* GtkStackTransitionType:
* @GTK_STACK_TRANSITION_TYPE_NONE: No transition
* @GTK_STACK_TRANSITION_TYPE_CROSSFADE: A cross-fade
* @GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT: Slight from left to right
* @GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT: Sligth from right to left
* @GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT: Slide from left to right
* @GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT: Slide from right to left
* @GTK_STACK_TRANSITION_TYPE_SLIDE_UP: Slide from bottom up
* @GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN: Slide from top down
*
* These enumeration values describe the possible transitions
* between pages in a #GtkStack widget.
*/
/* TODO:
* more transition types (slides)
* filter events out events to the last_child widget during transitions
*/
@ -166,6 +167,8 @@ static void gtk_stack_set_child_property (GtkContainer *contain
static void gtk_stack_unschedule_ticks (GtkStack *stack);
static gint get_bin_window_x (GtkStack *stack,
GtkAllocation *allocation);
static gint get_bin_window_y (GtkStack *stack,
GtkAllocation *allocation);
G_DEFINE_TYPE(GtkStack, gtk_stack, GTK_TYPE_CONTAINER);
@ -482,8 +485,7 @@ reorder_child (GtkStack *stack,
GtkStackChildInfo *info;
info = l->data;
/* Keep trying to find the current position and link location of the
child */
/* Keep trying to find the current position and link location of the child */
if (info->widget == child)
{
old_link = l;
@ -637,6 +639,24 @@ get_bin_window_x (GtkStack *stack,
return x;
}
static gint
get_bin_window_y (GtkStack *stack,
GtkAllocation *allocation)
{
GtkStackPrivate *priv = stack->priv;
int y = 0;
if (priv->transition_pos < 1.0)
{
if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP)
y = allocation->height * (1 - ease_out_cubic (priv->transition_pos));
if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN)
y = -allocation->height * (1 - ease_out_cubic (priv->transition_pos));
}
return y;
}
static gboolean
gtk_stack_set_transition_position (GtkStack *stack,
gdouble pos)
@ -649,12 +669,14 @@ gtk_stack_set_transition_position (GtkStack *stack,
if (priv->bin_window != NULL &&
(priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT ||
priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT))
priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT ||
priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP ||
priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN))
{
GtkAllocation allocation;
gtk_widget_get_allocation (GTK_WIDGET (stack), &allocation);
gdk_window_move (priv->bin_window,
get_bin_window_x (stack, &allocation), 0);
get_bin_window_x (stack, &allocation), get_bin_window_y (stack, &allocation));
}
done = pos >= 1.0;
@ -1364,21 +1386,29 @@ gtk_stack_draw_slide (GtkWidget *widget,
GtkStack *stack = GTK_STACK (widget);
GtkStackPrivate *priv = stack->priv;
GtkAllocation allocation;
int x = 0;
gint x = 0;
gint y = 0;
gtk_widget_get_allocation (widget, &allocation);
x = get_bin_window_x (stack, &allocation);
if (priv->transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT)
if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT)
x -= allocation.width;
if (priv->transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT)
if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT)
x += allocation.width;
y = get_bin_window_y (stack, &allocation);
if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_UP)
y -= allocation.height;
if (priv->active_transition_type == GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN)
y += allocation.height;
if (priv->last_visible_surface)
{
cairo_save (cr);
cairo_set_source_surface (cr, priv->last_visible_surface, x, 0);
cairo_set_source_surface (cr, priv->last_visible_surface, x, y);
cairo_paint (cr);
cairo_restore (cr);
}
@ -1425,6 +1455,8 @@ gtk_stack_draw (GtkWidget *widget,
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:
gtk_stack_draw_slide (widget, cr);
break;
default:
@ -1469,7 +1501,7 @@ gtk_stack_size_allocate (GtkWidget *widget,
allocation->x, allocation->y,
allocation->width, allocation->height);
gdk_window_move_resize (priv->bin_window,
get_bin_window_x (stack, allocation), 0,
get_bin_window_x (stack, allocation), get_bin_window_y (stack, allocation),
allocation->width, allocation->height);
}
}

View File

@ -42,7 +42,9 @@ typedef enum {
GTK_STACK_TRANSITION_TYPE_NONE,
GTK_STACK_TRANSITION_TYPE_CROSSFADE,
GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT,
GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT
GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT,
GTK_STACK_TRANSITION_TYPE_SLIDE_UP,
GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN
} GtkStackTransitionType;
struct _GtkStack {

View File

@ -50,7 +50,7 @@ on_back_button_clicked (GtkButton *button, GtkStack *stack)
for (i = 1; i < G_N_ELEMENTS (seq); i++)
{
if (g_str_equal (vis, seq[i]))
if (g_strcmp0 (vis, seq[i]) == 0)
{
gtk_stack_set_visible_child_full (stack, seq[i - 1], GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT);
break;
@ -69,7 +69,7 @@ on_forward_button_clicked (GtkButton *button, GtkStack *stack)
for (i = 0; i < G_N_ELEMENTS (seq) - 1; i++)
{
if (g_str_equal (vis, seq[i]))
if (g_strcmp0 (vis, seq[i]) == 0)
{
gtk_stack_set_visible_child_full (stack, seq[i + 1], GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT);
break;
@ -83,7 +83,7 @@ update_back_button_sensitivity (GtkStack *stack, GParamSpec *pspec, GtkWidget *b
const gchar *vis;
vis = gtk_stack_get_visible_child_name (stack);
gtk_widget_set_sensitive (button, ! g_str_equal (vis, "1"));
gtk_widget_set_sensitive (button, g_strcmp0 (vis, "1") != 0);
}
static void
@ -92,7 +92,7 @@ update_forward_button_sensitivity (GtkStack *stack, GParamSpec *pspec, GtkWidget
const gchar *vis;
vis = gtk_stack_get_visible_child_name (stack);
gtk_widget_set_sensitive (button, ! g_str_equal (vis, "3"));
gtk_widget_set_sensitive (button, g_strcmp0 (vis, "3") != 0);
}
gint
@ -209,14 +209,12 @@ main (gint argc,
gtk_container_add (GTK_CONTAINER (hbox), button);
combo = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo),
"NONE");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo),
"CROSSFADE");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo),
"SLIDE_RIGHT");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo),
"SLIDE_LEFT");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "NONE");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "CROSSFADE");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_RIGHT");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_LEFT");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_UP");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_DOWN");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
gtk_container_add (GTK_CONTAINER (hbox), combo);