2 * This file is a part of hildon
4 * Copyright (C) 2008 Nokia Corporation, all rights reserved.
6 * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * SECTION:hildon-animation-window
27 * @short_description: Animation actor for
28 * WM-assisted animation effects in the Hildon framework.
30 * The #HildonAnimationActor is an
31 * animation actor for WM-assisted animation effects in the Hildon
32 * framework. It derives from #GtkWindow and can host any widgets much
33 * like a normal window. The special features available to the
34 * animation actor is the ability to set its position, scale factor
35 * and rotation. These parameters are interpreted by Hildon's
36 * compositing window manager to alter the on-screen representation of
37 * the animation actor window. Bear in mind, however, that by design
38 * decision, animation actors are not reactive -- the widgets placed
39 * in such window will not receive keyboard, motion or button
40 * events. Animation actors are input-transparent -- the input events
41 * will be sent to the underlying real windows and widgets.
43 * The animation actors may exist in a parented or an unparented
44 * state. To be displayed, animations actors must be parented to
45 * another top-level window widget. Animation actors display on top
46 * (in front) of the standard window contents unless the position
47 * (depth, z-coordinate) is specifically adjusted. Animation actors in
48 * an unparented state do not display at all.
50 * Parented animation actors are placed in the coordinate space of the
51 * parent window and visually become a part of the parent window
52 * iteslf -- they inherit the transformations and effects enforced by
53 * the window manager on the parent window (task switcher animations,
54 * minimize events, etc.).
56 * All animation actor settings (position, scale, rotation, opacity,
57 * depth) can be applied to unparented actors, but will only take
58 * effect as the actor is parented to a top-level window and that
59 * window is shown. All settings are preserved during
60 * unparenting/reparenting.
62 * The #HildonAnimationActor API closely follows the #ClutterActor
63 * API. Please take a look at the #ClutterActor description for the
64 * modelview transformations order that applies to
65 * HildonAnimationActor and ClutterActor alike.
67 * Animation actor widget controls the animation actor as it is
68 * transformed by the window manager using ClientMessage X11
69 * events. It tries to minimize the amount of such events and couples
70 * conceptually related parameters (visibility and opacity, position
71 * and depth) to the same message. The API, however, offers
72 * convenience functions for the programmer to be able to modify every
73 * parameter individually.
76 * <title>Basic HildonAnimationActor example</title>
79 * animation_cb (void *obj)
81 * HildonAnimationActor *actor = HILDON_ANIMATION_ACTOR (obj);
83 * static int x_inc = 1;
84 * static int y_inc = 1;
89 * if (((x_inc > 0) && (x > 800)) ||
90 * ((x_inc < 0) && (x < 1)))
92 * if (((y_inc > 0) && (y > 480)) ||
93 * ((y_inc < 0) && (y < 1)))
100 * // Set animation actor position and rotation
101 * hildon_animation_actor_set_position (actor, x, y);
102 * hildon_animation_actor_set_rotation (actor,
109 * main (int argc, char **argv)
115 * gtk_init (&argc, &argv);
117 * // ... set up a normal window
118 * win = hildon_window_new ();
119 * g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
120 * gtk_widget_show_all (win);
122 * // ... load an image
123 * image = gtk_image_new_from_file ("image.jpg");
125 * actor = hildon_animation_actor_new();
126 * gtk_container_add (GTK_CONTAINER (actor), image);
128 * // Parent the animation actor
129 * hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (actor), win);
131 * // Set anchor point to the actor center
132 * hildon_animation_actor_set_anchor_from_gravity (HILDON_ANIMATION_ACTOR (actor),
133 HILDON_AA_CENTER_GRAVITY);
135 * gtk_widget_show_all (actor);
137 * // Set up animation
138 * g_timeout_add (100, (GSourceFunc)animation_cb, actor);
148 #include <gdk/gdkx.h>
149 #include <X11/Xatom.h>
151 #include "hildon-animation-actor.h"
152 #include "hildon-animation-actor-private.h"
154 G_DEFINE_TYPE (HildonAnimationActor, hildon_animation_actor, GTK_TYPE_WINDOW);
156 static GdkFilterReturn
157 hildon_animation_actor_event_filter (GdkXEvent *xevent,
161 hildon_animation_actor_update_ready (HildonAnimationActor *self);
163 hildon_animation_actor_send_pending_messages (HildonAnimationActor *self);
165 hildon_animation_actor_send_all_messages (HildonAnimationActor *self);
167 hildon_animation_actor_parent_map_event (GtkWidget *parent,
171 hildon_animation_actor_map_event (GtkWidget *widget,
175 static guint32 show_atom;
176 static guint32 position_atom;
177 static guint32 rotation_atom;
178 static guint32 scale_atom;
179 static guint32 anchor_atom;
180 static guint32 parent_atom;
181 static guint32 ready_atom;
183 static gboolean atoms_initialized = FALSE;
186 hildon_animation_actor_realize (GtkWidget *widget)
189 Atom wm_type, applet_type;
191 GTK_WIDGET_CLASS (hildon_animation_actor_parent_class)->realize (widget);
193 /* Set animation actor window type. */
195 display = gdk_drawable_get_display (widget->window);
197 wm_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE");
198 applet_type = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_WM_WINDOW_TYPE_ANIMATION_ACTOR");
200 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (widget->window), wm_type,
201 XA_ATOM, 32, PropModeReplace,
202 (unsigned char *) &applet_type, 1);
204 /* This is a bit of a hack, but for the sake of speed (it is assumed that
205 * once HildonAnimationActor is created, a lot of ClientMessages will
206 * follow), we cache all ClientMessages atoms in static variables. */
208 if (!atoms_initialized)
211 gdk_x11_get_xatom_by_name_for_display
212 (display, "_HILDON_ANIMATION_CLIENT_MESSAGE_SHOW");
214 gdk_x11_get_xatom_by_name_for_display
215 (display, "_HILDON_ANIMATION_CLIENT_MESSAGE_POSITION");
217 gdk_x11_get_xatom_by_name_for_display
218 (display, "_HILDON_ANIMATION_CLIENT_MESSAGE_ROTATION");
220 gdk_x11_get_xatom_by_name_for_display
221 (display, "_HILDON_ANIMATION_CLIENT_MESSAGE_SCALE");
223 gdk_x11_get_xatom_by_name_for_display
224 (display, "_HILDON_ANIMATION_CLIENT_MESSAGE_ANCHOR");
226 gdk_x11_get_xatom_by_name_for_display
227 (display, "_HILDON_ANIMATION_CLIENT_MESSAGE_PARENT");
229 gdk_x11_get_xatom_by_name_for_display
230 (display, "_HILDON_ANIMATION_CLIENT_READY");
232 g_debug ("show atom = %lu\n", show_atom);
233 g_debug ("position atom = %lu\n", position_atom);
234 g_debug ("rotation atom = %lu\n", rotation_atom);
235 g_debug ("scale atom = %lu\n", scale_atom);
236 g_debug ("anchor atom = %lu\n", anchor_atom);
237 g_debug ("parent atom = %lu\n", parent_atom);
238 g_debug ("ready atom = %lu\n", ready_atom);
241 atoms_initialized = TRUE;
244 /* Wait for a ready message */
246 gdk_window_add_filter (widget->window,
247 hildon_animation_actor_event_filter,
252 hildon_animation_actor_unrealize (GtkWidget *widget)
254 gdk_window_remove_filter (widget->window,
255 hildon_animation_actor_event_filter,
258 GTK_WIDGET_CLASS (hildon_animation_actor_parent_class)->unrealize (widget);
262 hildon_animation_actor_show (GtkWidget *widget)
264 HildonAnimationActor *self = HILDON_ANIMATION_ACTOR (widget);
266 GTK_WIDGET_CLASS (hildon_animation_actor_parent_class)->show (widget);
267 hildon_animation_actor_set_show (self, 1);
271 hildon_animation_actor_hide (GtkWidget *widget)
273 HildonAnimationActor *self = HILDON_ANIMATION_ACTOR (widget);
275 hildon_animation_actor_set_show (self, 0);
276 GTK_WIDGET_CLASS (hildon_animation_actor_parent_class)->hide (widget);
280 hildon_animation_actor_finalize (GObject *object)
282 HildonAnimationActor *self = HILDON_ANIMATION_ACTOR (object);
283 HildonAnimationActorPrivate
284 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
288 if (priv->parent_map_event_cb_id)
289 g_signal_handler_disconnect (priv->parent,
290 priv->parent_map_event_cb_id);
292 g_object_unref (priv->parent);
297 hildon_animation_actor_class_init (HildonAnimationActorClass *klass)
299 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
300 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
302 gobject_class->finalize = hildon_animation_actor_finalize;
304 widget_class->realize = hildon_animation_actor_realize;
305 widget_class->unrealize = hildon_animation_actor_unrealize;
306 widget_class->show = hildon_animation_actor_show;
307 widget_class->hide = hildon_animation_actor_hide;
309 g_type_class_add_private (klass, sizeof (HildonAnimationActorPrivate));
313 hildon_animation_actor_init (HildonAnimationActor *self)
315 HildonAnimationActorPrivate
316 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
318 /* Default non-zero values for the private variables */
320 priv->scale_x = 1 << 16;
321 priv->scale_y = 1 << 16;
322 priv->opacity = 0xff;
326 * hildon_animation_actor_new:
328 * Creates a new #HildonAnimationActor.
330 * Return value: A #HildonAnimationActor
335 hildon_animation_actor_new (void)
337 HildonAnimationActor *newwindow = g_object_new (HILDON_TYPE_ANIMATION_ACTOR, NULL);
339 gtk_window_set_decorated (GTK_WINDOW (newwindow), FALSE);
341 return GTK_WIDGET (newwindow);
345 * An filter for GDK X11 events, waiting for PropertyNotify (window property
346 * changes) events, keeping track of animation actor ready atom.
347 * Having the ready atom set on the window by the window manager will trigger
348 * updates of actor parameters (position/rotation/etc...) to be sent off
349 * to the window manager for processing.
351 static GdkFilterReturn
352 hildon_animation_actor_event_filter (GdkXEvent *xevent,
356 HildonAnimationActor *self = HILDON_ANIMATION_ACTOR (data);
357 XAnyEvent *any = xevent;
359 if (any->type == PropertyNotify)
361 XPropertyEvent *property = xevent;
363 if (property->atom == ready_atom)
365 hildon_animation_actor_update_ready (self);
369 return GDK_FILTER_CONTINUE;
373 * Check for the ready atom on the animation actor X11 window.
374 * If present, send all pending animation actor messages to the
378 hildon_animation_actor_update_ready (HildonAnimationActor *self)
380 HildonAnimationActorPrivate
381 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
382 GtkWidget *widget = GTK_WIDGET (self);
383 Display *display = GDK_WINDOW_XDISPLAY (widget->window);
384 Window window = GDK_WINDOW_XID (widget->window);
391 unsigned long nitems, bytes_after;
392 unsigned char *prop = NULL;
394 /* Check for the "ready" property */
396 gdk_error_trap_push ();
397 status = XGetWindowProperty (display, window,
400 &actual_type, &actual_format,
401 &nitems, &bytes_after, &prop);
402 xerror = gdk_error_trap_pop();
406 /* We do not actually use the property value for anything,
407 * it is enough that the property is set. */
413 (status != Success) || (actual_type != XA_ATOM) ||
414 (actual_format != 32) || (nitems != 1))
422 /* The ready flag has been set once already. This means that
423 * the WM has restarted. Trigger re-mapping of the widget to
424 * update the texture actor first. Then push all animation
425 * actor settings anew. */
427 priv->map_event_cb_id =
428 g_signal_connect (G_OBJECT (self),
430 G_CALLBACK(hildon_animation_actor_map_event),
433 if (GTK_WIDGET_MAPPED (GTK_WIDGET (self)))
435 gtk_widget_unmap (GTK_WIDGET (self));
436 gtk_widget_map (GTK_WIDGET (self));
444 /* Send all pending messages */
446 hildon_animation_actor_send_pending_messages (self);
450 hildon_animation_actor_send_pending_messages (HildonAnimationActor *self)
452 HildonAnimationActorPrivate
453 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
455 if (priv->set_anchor)
457 if (priv->gravity == 0)
458 hildon_animation_actor_set_anchor (self,
462 hildon_animation_actor_set_anchor_from_gravity (self,
466 if (priv->set_position)
467 hildon_animation_actor_set_position_full (self,
472 if (priv->set_rotation & (1 << HILDON_AA_X_AXIS))
473 hildon_animation_actor_set_rotationx (self,
475 priv->x_rotation_angle,
480 if (priv->set_rotation & (1 << HILDON_AA_Y_AXIS))
481 hildon_animation_actor_set_rotationx (self,
483 priv->y_rotation_angle,
488 if (priv->set_rotation & (1 << HILDON_AA_Z_AXIS))
489 hildon_animation_actor_set_rotationx (self,
491 priv->z_rotation_angle,
497 hildon_animation_actor_set_scalex (self,
501 if (priv->set_parent)
502 hildon_animation_actor_set_parent (self,
506 hildon_animation_actor_set_show_full (self,
507 priv->show, priv->opacity);
511 hildon_animation_actor_send_all_messages (HildonAnimationActor *self)
513 HildonAnimationActorPrivate
514 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
516 priv->set_anchor = 1;
517 priv->set_position = 1;
518 priv->set_rotation = (1 << HILDON_AA_X_AXIS) |
519 (1 << HILDON_AA_Y_AXIS) |
520 (1 << HILDON_AA_Z_AXIS);
522 priv->set_parent = 1;
525 hildon_animation_actor_send_pending_messages (self);
528 /* ------------------------------------------------------------- */
531 * hildon_animation_actor_send_message:
532 * @self: A #HildonAnimationActor
533 * @message_type: Message id for the animation actor message.
534 * @l0: 1st animation actor message parameter.
535 * @l1: 2nd animation actor message parameter.
536 * @l2: 3rd animation actor message parameter.
537 * @l3: 4th animation actor message parameter.
538 * @l4: 5th animation actor message parameter.
540 * Sends an X11 ClientMessage event to the window manager with
541 * the specified parameters -- id (@message_type) and data (@l0,
542 * @l1, @l2, @l3, @l4).
544 * This is an internal utility function that application will
545 * not need to call directly.
550 hildon_animation_actor_send_message (HildonAnimationActor *self,
551 guint32 message_type,
558 GtkWidget *widget = GTK_WIDGET (self);
559 Display *display = GDK_WINDOW_XDISPLAY (widget->window);
560 Window window = GDK_WINDOW_XID (widget->window);
562 XClientMessageEvent event;
564 event.type = ClientMessage;
565 event.window = window;
566 event.message_type = (Atom)message_type;
568 event.data.l[0] = l0;
569 event.data.l[1] = l1;
570 event.data.l[2] = l2;
571 event.data.l[3] = l3;
572 event.data.l[4] = l4;
574 XEvent event = { 0 };
576 event.xclient.type = ClientMessage;
577 event.xclient.window = window;
578 event.xclient.message_type = (Atom)message_type;
579 event.xclient.format = 32;
580 event.xclient.data.l[0] = l0;
581 event.xclient.data.l[1] = l1;
582 event.xclient.data.l[2] = l2;
583 event.xclient.data.l[3] = l3;
584 event.xclient.data.l[4] = l4;
588 g_debug ("%lu (%lu %lu %lu %lu %lu) -> %lu\n",
594 XSendEvent (display, window, True,
600 * hildon_animation_actor_set_show_full:
601 * @self: A #HildonAnimationActor
602 * @show: A boolean flag setting the visibility of the animation actor.
603 * @opacity: Desired opacity setting
605 * Send a message to the window manager setting the visibility of
606 * the animation actor. This will only affect the visibility of
607 * the animation actor set by the compositing window manager in its own
608 * rendering pipeline, after X has drawn the window to the off-screen
609 * buffer. This setting, naturally, has no effect if the #HildonAnimationActor
610 * widget is not visible in X11 terms (i.e. realized and mapped).
612 * Furthermore, if a widget is parented, its final visibility will be
613 * affected by that of the parent window.
615 * The opacity setting ranges from zero (0), being completely transparent
616 * to 255 (0xff) being fully opaque.
618 * If the animation actor WM-counterpart is not ready, the show message
619 * will be queued until the WM is ready for it.
624 hildon_animation_actor_set_show_full (HildonAnimationActor *self,
628 HildonAnimationActorPrivate
629 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
630 GtkWidget *widget = GTK_WIDGET (self);
639 priv->opacity = opacity;
642 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
644 /* Defer show messages until the animation actor is parented
645 * and the parent window is mapped */
647 if (!priv->parent || !GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
650 hildon_animation_actor_send_message (self,
659 * hildon_animation_actor_set_show:
660 * @self: A #HildonAnimationActor
661 * @show: A boolean flag setting the visibility of the animation actor.
663 * This function is a shortcut for hildon_animation_actor_set_show_full(),
664 * setting the overall actor visibility without changing it's opacity
670 hildon_animation_actor_set_show (HildonAnimationActor *self,
673 HildonAnimationActorPrivate
674 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
676 hildon_animation_actor_set_show_full (self,
677 show, priv->opacity);
681 * hildon_animation_actor_set_opacity:
682 * @self: A #HildonAnimationActor
683 * @opacity: Desired opacity setting
685 * This function is a shortcut for hildon_animation_actor_set_show_full(),
686 * setting actor opacity without changing it's overall visibility.
688 * See hildon_animation_actor_set_show_full() for description of the range
689 * of values @opacity argument takes.
694 hildon_animation_actor_set_opacity (HildonAnimationActor *self,
697 HildonAnimationActorPrivate
698 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
700 hildon_animation_actor_set_show_full (self,
701 priv->show, opacity);
705 * hildon_animation_actor_set_position_full:
706 * @self: A #HildonAnimationActor
707 * @x: Desired X coordinate
708 * @y: Desired Y coordinate
709 * @depth: Desired window depth (Z coordinate)
711 * Send a message to the window manager setting the position of the
712 * animation actor. This will set the position of the animation
713 * actor off-screen bitmap as it is rendered to the screen. The
714 * position of the actor is relative to the parent window. The actor
715 * is also subject to the animation effects rendered by the compositing
716 * window manager on that window (like those by task switcher).
718 * The window depth affects the stacking of animation actors within
719 * a parent window and, more generally, the stacking of clutter actors
720 * within a stage/container. The default depth is 0 and a parent
721 * window's container will have it's window texture stacked at that level.
722 * The stacking at any depth level is sequential -- animation actor B
723 * created/parented after animation actor A will obscure the latter
726 * Animation actors with non-zero depth settings are subject to scaling as
727 * per the global scene perspective setup, which limits the depth setting
728 * as the primary parameter to control the stacking order. Since the
729 * stacking order follows the parenting order, it may be better to use
730 * hildon_animation_actor_set_parent() for setting the stacking.
732 * If the animation actor WM-counterpart is not ready, the show message
733 * will be queued until the WM is ready for it.
738 hildon_animation_actor_set_position_full (HildonAnimationActor *self,
743 HildonAnimationActorPrivate
744 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
745 GtkWidget *widget = GTK_WIDGET (self);
747 priv->position_x = x;
748 priv->position_y = y;
750 priv->set_position = 1;
752 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
754 hildon_animation_actor_send_message (self,
758 priv->set_position = 0;
763 * hildon_animation_actor_set_position:
764 * @self: A #HildonAnimationActor
765 * @x: Desired window X coordinate
766 * @y: Desired window Y coordinate
768 * A shortcut for hildon_animation_actor_set_position_full(),
769 * changing the window position, but preserving it's depth setting.
774 hildon_animation_actor_set_position (HildonAnimationActor *self,
778 HildonAnimationActorPrivate
779 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
781 hildon_animation_actor_set_position_full (self,
786 * hildon_animation_actor_set_depth:
787 * @self: A #HildonAnimationActor
788 * @depth: Desired window depth (Z coordinate)
790 * A shortcut for hildon_animation_actor_set_position_full(),
791 * changing the window depth, but preserving it's position.
796 hildon_animation_actor_set_depth (HildonAnimationActor *self,
799 HildonAnimationActorPrivate
800 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
802 hildon_animation_actor_set_position_full (self,
809 * hildon_animation_actor_set_scalex:
810 * @self: A #HildonAnimationActor
811 * @x_scale: Window's desired scale factor along the X-axis
812 * @y_scale: Window's desired scale factor along the Y-axis
814 * This function is just like hildon_animation_actor_set_scale(),
815 * but the scale factors are given as 16-bit fixed-point number.
820 hildon_animation_actor_set_scalex (HildonAnimationActor *self,
824 HildonAnimationActorPrivate
825 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
826 GtkWidget *widget = GTK_WIDGET (self);
828 priv->scale_x = x_scale;
829 priv->scale_y = y_scale;
832 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
834 hildon_animation_actor_send_message (self,
843 * hildon_animation_actor_set_scale:
844 * @self: A #HildonAnimationActor
845 * @x_scale: Window's desired scale factor along the X-axis
846 * @y_scale: Window's desired scale factor along the Y-axis
848 * Send a message to the window manager setting the scale factors of the
849 * animation actor. This will set the scale factors on the animation
850 * actor off-screen bitmap as it is rendered to the screen. If the
851 * animation actor is parented to another top-level window, the
852 * animation effects rendered by the compositing window manager
853 * on that top-level window (like those by task switcher) will
854 * also affect the animation actor.
856 * If the animation actor WM-counterpart is not ready, the show message
857 * will be queued until the WM is ready for it.
862 hildon_animation_actor_set_scale (HildonAnimationActor *self,
866 gint32 f_x_scale = x_scale * (1 << 16);
867 gint32 f_y_scale = y_scale * (1 << 16);
869 hildon_animation_actor_set_scalex (self, f_x_scale, f_y_scale);
873 * hildon_animation_actor_set_rotationx:
874 * @self: A #HildonAnimationActor
875 * @axis: The rotation axis.
876 * @degrees: The rotation angle in degrees.
877 * @x: Center of the rotation, X coordinate.
878 * @y: Center of the rotation, Y coordinate.
879 * @z: Center of the rotation, Z coordinate.
881 * This function is just like hildon_animation_actor_set_rotation(),
882 * but the rotation angle is given as 16-bit fixed-point number.
887 hildon_animation_actor_set_rotationx (HildonAnimationActor *self,
894 HildonAnimationActorPrivate
895 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
896 GtkWidget *widget = GTK_WIDGET (self);
902 case HILDON_AA_X_AXIS:
903 priv->x_rotation_angle = degrees;
904 priv->x_rotation_y = y;
905 priv->x_rotation_z = z;
906 mask = (1 << HILDON_AA_X_AXIS);
908 case HILDON_AA_Y_AXIS:
909 priv->y_rotation_angle = degrees;
910 priv->y_rotation_x = x;
911 priv->y_rotation_z = z;
912 mask = (1 << HILDON_AA_Y_AXIS);
914 case HILDON_AA_Z_AXIS:
915 priv->z_rotation_angle = degrees;
916 priv->z_rotation_x = x;
917 priv->z_rotation_y = y;
918 mask = (1 << HILDON_AA_Z_AXIS);
924 priv->set_rotation |= mask;
926 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
928 hildon_animation_actor_send_message (self,
930 axis, degrees, x, y, z);
931 priv->set_rotation &= ~mask;
936 * hildon_animation_actor_set_rotation:
937 * @self: A #HildonAnimationActor
938 * @axis: The rotation axis.
939 * @degrees: The rotation angle in degrees.
940 * @x: Center of the rotation, X coordinate.
941 * @y: Center of the rotation, Y coordinate.
942 * @z: Center of the rotation, Z coordinate.
944 * Send a message to the window manager setting the animation actor
945 * rotation around one of the three axes. The rotation center coordinates
946 * depend on the axis of rotation:
948 * * %HILDON_AA_X_AXIS requires @y and @z coordinates.
949 * * %HILDON_AA_Y_AXIS requires @x and @z coordinates.
950 * * %HILDON_AA_Z_AXIS requires @x and @y coordinates.
952 * If the animation actor WM-counterpart is not ready, the show message
953 * will be queued until the WM is ready for it.
958 hildon_animation_actor_set_rotation (HildonAnimationActor *self,
965 gint32 f_degrees = degrees * (1 << 16);
967 hildon_animation_actor_set_rotationx (self, axis, f_degrees, x, y, z);
971 * hildon_animation_actor_set_anchor:
972 * @self: A #HildonAnimationActor
973 * @x: The X coordinate of the anchor point.
974 * @y: The Y coordinate of the anchor point.
976 * Send a message to the window manager setting the anchor point for
977 * the animation actor. The anchor point is the point to which the
978 * actor position within its parent it is relative.
980 * If the animation actor WM-counterpart is not ready, the show message
981 * will be queued until the WM is ready for it.
986 hildon_animation_actor_set_anchor (HildonAnimationActor *self,
990 HildonAnimationActorPrivate
991 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
992 GtkWidget *widget = GTK_WIDGET (self);
997 priv->set_anchor = 1;
999 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
1001 hildon_animation_actor_send_message (self,
1005 priv->set_anchor = 0;
1010 * hildon_animation_actor_set_anchor_from_gravity:
1011 * @self: A #HildonAnimationActor
1012 * @gravity: The gravity constant.
1014 * Send a message to the window manager setting the anchor point for
1015 * the animation actor. The anchor point is the point to which the
1016 * actor position within its parent it is relative. Instead of being
1017 * defined in (x, y)-coordinates, the anchor point is defined in the
1018 * relative "gravity" constant as:
1020 * * %HILDON_AA_N_GRAVITY translates to (width / 2, 0) coordinate
1021 * * %HILDON_AA_NE_GRAVITY translates to (width, 0) coordinate
1022 * * %HILDON_AA_E_GRAVITY translates to (width, height / 2) coordinate
1023 * * %HILDON_AA_SE_GRAVITY translates to (width, height) coordinate
1024 * * %HILDON_AA_S_GRAVITY translates to (width / 2, height) coordinate
1025 * * %HILDON_AA_SW_GRAVITY translates to (0, height) coordinate
1026 * * %HILDON_AA_W_GRAVITY translates to (0, height / 2) coordinate
1027 * * %HILDON_AA_NW_GRAVITY translates to (0, 0) coordinate
1028 * * %HILDON_AA_CENTER_GRAVITY translates to (width / 2, height / 2) coordinate
1030 * If the animation actor WM-counterpart is not ready, the show message
1031 * will be queued until the WM is ready for it.
1036 hildon_animation_actor_set_anchor_from_gravity (HildonAnimationActor *self,
1039 HildonAnimationActorPrivate
1040 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1041 GtkWidget *widget = GTK_WIDGET (self);
1043 priv->gravity = gravity;
1044 priv->set_anchor = 1;
1046 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
1048 hildon_animation_actor_send_message (self,
1052 priv->set_anchor = 0;
1057 * This callback will be triggered by the parent widget of
1058 * an animation actor when it is mapped. The compositing
1059 * window manager is now ready to parent the animation actor
1060 * into the target parent window.
1063 hildon_animation_actor_parent_map_event (GtkWidget *parent,
1067 hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (user_data),
1068 GTK_WINDOW (parent));
1073 * This callback will be triggered by the widget re-mapping
1074 * itself in case of WM restarting. The point is to push all
1075 * animation actor parameters anew to the WM.
1078 hildon_animation_actor_map_event (GtkWidget *widget,
1082 HildonAnimationActor
1083 *self = HILDON_ANIMATION_ACTOR (user_data);
1084 HildonAnimationActorPrivate
1085 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1087 hildon_animation_actor_send_all_messages (self);
1089 /* Disconnect the "map-event" handler after the "emergency resend all
1090 * actor parameters" drill is over. */
1092 if (priv->map_event_cb_id)
1094 g_signal_handler_disconnect (self,
1095 priv->map_event_cb_id);
1096 priv->map_event_cb_id = 0;
1103 * hildon_animation_actor_set_parent:
1104 * @self: A #HildonAnimationActor
1105 * @parent: A #GtkWindow that the actor will be parented to.
1107 * Send a message to the window manager setting the parent window
1108 * for the animation actor. Parenting an actor will not affect the
1109 * X window that the HildonAnimationActor represents, but it's off-screen
1110 * bitmap as it is handled by the compositing window manager.
1112 * Parenting an animation actor will affect its visibility as set
1113 * by the gtk_widget_show(), gtk_widget_hide() and
1114 * hildon_animation_actor_set_show(). The animation actor will only be
1115 * visible when the top-level window it is parented is visible.
1117 * Passing %NULL as a @parent argument will unparent the animation actor.
1118 * This will restore the actor's visibility if it was suppressed by
1119 * being unparented or parented to an unmapped window.
1121 * If the animation actor WM-counterpart is not ready, the show message
1122 * will be queued until the WM is ready for it.
1127 hildon_animation_actor_set_parent (HildonAnimationActor *self,
1130 HildonAnimationActorPrivate
1131 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1132 GtkWidget *widget = GTK_WIDGET (self);
1134 gtk_window_set_transient_for (GTK_WINDOW (self), parent);
1136 if (priv->parent != parent)
1138 /* Setting a new parent */
1142 if (priv->parent_map_event_cb_id)
1143 g_signal_handler_disconnect (priv->parent,
1144 priv->parent_map_event_cb_id);
1146 /* Might need a synchronized "parent(0)" or "parent(new parent)"
1147 * message here before we can safely decrease the reference count. */
1149 g_object_unref (priv->parent);
1152 priv->parent = parent;
1153 priv->set_parent = 1;
1157 /* The widget is being (re)parented, not unparented. */
1159 g_object_ref (parent);
1161 priv->parent_map_event_cb_id =
1162 g_signal_connect (G_OBJECT (priv->parent),
1164 G_CALLBACK(hildon_animation_actor_parent_map_event),
1169 priv->parent_map_event_cb_id = 0;
1173 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
1177 /* If the animation actor is being unparented or parented to an
1178 * unmapped widget, force its visibility to "hidden". */
1180 if (!priv->parent || !GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
1182 hildon_animation_actor_send_message (self,
1188 /* If the widget is being parented (parent != 0), only proceed when
1189 * the parent widget is realized, since we need the X window id of
1190 * the parent. If the widget is being unparented (parent == 0), pass
1191 * the "special" window id of 0 in the message. */
1195 if (!GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
1198 GdkWindow *gdk = GTK_WIDGET (parent)->window;
1199 win = GDK_WINDOW_XID (gdk);
1202 hildon_animation_actor_send_message (self,
1206 priv->set_parent = 0;
1208 /* Set animation actor visibility to desired value (in case it was
1209 * forced off when the actor was parented into an unmapped widget). */
1211 hildon_animation_actor_send_message (self,
1213 priv->show, priv->opacity,