EggAnimation

Here is a nifty trick I’ve had up my sleeve since the Gtk 2.x days (wow, over half a decade ago!). I’ve used this on a bunch of projects over the years, and it always gets a few smiles. It has a very similar API to the early days of Clutter, where it’s inpsiration came from. I should preface this with: If you need very fast, GPU optimized graphics, this is not what you want. However, for automating property changes, it is very handy.

Let’s start simple by transitioning the opacity of a widget from 0 (transparent) to 1 (opaque).

gtk_widget_set_opacity (widget, 0.0);
egg_object_animate (widget,
                    EGG_ANIMATION_LINEAR,
                    1000, /* duration in msec */
                    NULL, /* frame clock, NULL for default */
                    "opacity", 1.0, /* key/value properties */
                    NULL);

This is fairly contrived, because you almost certainly want to do the above with CSS transitions.

Now consider scrolling to the bottom of a GtkScrolledWindow. The GtkAdjustment is not a widget, and therefore does not have a frame-clock. So we will pass the frame-clock of the scrolled window instead.

GdkFrameClock *frame_clock;
GtkAdjustment *v_adjustment;
gdouble upper;
gdouble page_size;
gdouble value;

frame_clock = gtk_widget_get_frame_clock (scroller);
v_adjustment = gtk_scrollable_get_vadjustment (scroller);
upper = gtk_adjustment_get_upper (v_adjustment);
page_size = gtk_adjustment_get_page_size (v_adjustment);
value = MAX (0.0, (upper - page_size));

egg_object_animate (v_adjustment,
                    EGG_ANIMATION_EASE_IN_OUT_QUAD,
                    1000,
                    frame_clock,
                    "value", value,
                    NULL);

egg_object_animate() returns a weak pointer to the EggAnimation. This is safe since the animation won’t start until the next iteration of the main loop. If you want to hold on to it, either use g_object_weak_ref() or g_object_ref. I prefer the weak ref (via g_object_add_weak_pointer()) so it is easy for me to cancel in-flight animations with egg_animation_stop().

Here is an example of how we use EggAnimation in Builder to make the “yank” operation in Vim mode more visible.

For many things, you’ll be able to just use CSS transitions. And you should definitely check if that is an option before using EggAnimation.

But that said, it’s used all over in Builder. If I did my job well, you barely even notice. And of course, for the animation hating crowed, GtkSettings:gtk-enable-animations is respected.