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

View File

@ -42,7 +42,9 @@ typedef enum {
GTK_STACK_TRANSITION_TYPE_NONE, GTK_STACK_TRANSITION_TYPE_NONE,
GTK_STACK_TRANSITION_TYPE_CROSSFADE, GTK_STACK_TRANSITION_TYPE_CROSSFADE,
GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT, 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; } GtkStackTransitionType;
struct _GtkStack { 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++) 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); gtk_stack_set_visible_child_full (stack, seq[i - 1], GTK_STACK_TRANSITION_TYPE_SLIDE_RIGHT);
break; break;
@ -69,7 +69,7 @@ on_forward_button_clicked (GtkButton *button, GtkStack *stack)
for (i = 0; i < G_N_ELEMENTS (seq) - 1; i++) 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); gtk_stack_set_visible_child_full (stack, seq[i + 1], GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT);
break; break;
@ -83,7 +83,7 @@ update_back_button_sensitivity (GtkStack *stack, GParamSpec *pspec, GtkWidget *b
const gchar *vis; const gchar *vis;
vis = gtk_stack_get_visible_child_name (stack); 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 static void
@ -92,7 +92,7 @@ update_forward_button_sensitivity (GtkStack *stack, GParamSpec *pspec, GtkWidget
const gchar *vis; const gchar *vis;
vis = gtk_stack_get_visible_child_name (stack); 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 gint
@ -209,14 +209,12 @@ main (gint argc,
gtk_container_add (GTK_CONTAINER (hbox), button); gtk_container_add (GTK_CONTAINER (hbox), button);
combo = gtk_combo_box_text_new (); combo = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "NONE");
"NONE"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "CROSSFADE");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_RIGHT");
"CROSSFADE"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_LEFT");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_UP");
"SLIDE_RIGHT"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "SLIDE_DOWN");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo),
"SLIDE_LEFT");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
gtk_container_add (GTK_CONTAINER (hbox), combo); gtk_container_add (GTK_CONTAINER (hbox), combo);