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: Widget representing an animation actor for
28 * WM-assisted animation effects in the Hildon framework.
30 * The #HildonAnimationActor is a GTK+ widget which represents 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_class_init (HildonAnimationActorClass *klass)
282 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
284 widget_class->realize = hildon_animation_actor_realize;
285 widget_class->unrealize = hildon_animation_actor_unrealize;
286 widget_class->show = hildon_animation_actor_show;
287 widget_class->hide = hildon_animation_actor_hide;
289 g_type_class_add_private (klass, sizeof (HildonAnimationActorPrivate));
293 hildon_animation_actor_init (HildonAnimationActor *self)
295 HildonAnimationActorPrivate
296 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
298 /* Default non-zero values for the private variables */
300 priv->scale_x = 1 << 16;
301 priv->scale_y = 1 << 16;
302 priv->opacity = 0xff;
306 * hildon_animation_actor_new:
308 * Creates a new #HildonAnimationActor.
310 * Return value: A #HildonAnimationActor
315 hildon_animation_actor_new (void)
317 HildonAnimationActor *newwindow = g_object_new (HILDON_TYPE_ANIMATION_ACTOR, NULL);
319 gtk_window_set_decorated (GTK_WINDOW (newwindow), FALSE);
321 return GTK_WIDGET (newwindow);
325 * An filter for GDK X11 events, waiting for PropertyNotify (window property
326 * changes) events, keeping track of animation actor ready atom.
327 * Having the ready atom set on the window by the window manager will trigger
328 * updates of actor parameters (position/rotation/etc...) to be sent off
329 * to the window manager for processing.
331 static GdkFilterReturn
332 hildon_animation_actor_event_filter (GdkXEvent *xevent,
336 HildonAnimationActor *self = HILDON_ANIMATION_ACTOR (data);
337 XAnyEvent *any = xevent;
339 if (any->type == PropertyNotify)
341 XPropertyEvent *property = xevent;
343 if (property->atom == ready_atom)
345 hildon_animation_actor_update_ready (self);
349 return GDK_FILTER_CONTINUE;
353 * Check for the ready atom on the animation actor X11 window.
354 * If present, send all pending animation actor messages to the
358 hildon_animation_actor_update_ready (HildonAnimationActor *self)
360 HildonAnimationActorPrivate
361 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
362 GtkWidget *widget = GTK_WIDGET (self);
363 Display *display = GDK_WINDOW_XDISPLAY (widget->window);
364 Window window = GDK_WINDOW_XID (widget->window);
371 unsigned long nitems, bytes_after;
372 unsigned char *prop = NULL;
374 /* Check for the "ready" property */
376 gdk_error_trap_push ();
377 status = XGetWindowProperty (display, window,
380 &actual_type, &actual_format,
381 &nitems, &bytes_after, &prop);
382 xerror = gdk_error_trap_pop();
386 /* We do not actually use the property value for anything,
387 * it is enough that the property is set. */
393 (status != Success) || (actual_type != XA_ATOM) ||
394 (actual_format != 32) || (nitems != 1))
402 /* The ready flag has been set once already. This means that
403 * the WM has restarted. Trigger re-mapping of the widget to
404 * update the texture actor first. Then push all animation
405 * actor settings anew. */
407 priv->map_event_cb_id =
408 g_signal_connect (G_OBJECT (self),
410 G_CALLBACK(hildon_animation_actor_map_event),
413 if (GTK_WIDGET_MAPPED (GTK_WIDGET (self)))
415 gtk_widget_unmap (GTK_WIDGET (self));
416 gtk_widget_map (GTK_WIDGET (self));
424 /* Send all pending messages */
426 hildon_animation_actor_send_pending_messages (self);
430 hildon_animation_actor_send_pending_messages (HildonAnimationActor *self)
432 HildonAnimationActorPrivate
433 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
435 if (priv->set_anchor)
437 if (priv->gravity == 0)
438 hildon_animation_actor_set_anchor (self,
442 hildon_animation_actor_set_anchor_from_gravity (self,
446 if (priv->set_position)
447 hildon_animation_actor_set_position_full (self,
452 if (priv->set_rotation & (1 << HILDON_AA_X_AXIS))
453 hildon_animation_actor_set_rotationx (self,
455 priv->x_rotation_angle,
460 if (priv->set_rotation & (1 << HILDON_AA_Y_AXIS))
461 hildon_animation_actor_set_rotationx (self,
463 priv->y_rotation_angle,
468 if (priv->set_rotation & (1 << HILDON_AA_Z_AXIS))
469 hildon_animation_actor_set_rotationx (self,
471 priv->z_rotation_angle,
477 hildon_animation_actor_set_scalex (self,
481 if (priv->set_parent)
482 hildon_animation_actor_set_parent (self,
486 hildon_animation_actor_set_show_full (self,
487 priv->show, priv->opacity);
491 hildon_animation_actor_send_all_messages (HildonAnimationActor *self)
493 HildonAnimationActorPrivate
494 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
496 priv->set_anchor = 1;
497 priv->set_position = 1;
498 priv->set_rotation = (1 << HILDON_AA_X_AXIS) |
499 (1 << HILDON_AA_Y_AXIS) |
500 (1 << HILDON_AA_Z_AXIS);
502 priv->set_parent = 1;
505 hildon_animation_actor_send_pending_messages (self);
508 /* ------------------------------------------------------------- */
511 * hildon_animation_actor_send_message:
512 * @self: A #HildonAnimationActor
513 * @message_type: Message id for the animation actor message.
514 * @l0: 1st animation actor message parameter.
515 * @l1: 2nd animation actor message parameter.
516 * @l2: 3rd animation actor message parameter.
517 * @l3: 4th animation actor message parameter.
518 * @l4: 5th animation actor message parameter.
520 * Sends an X11 ClientMessage event to the window manager with
521 * the specified parameters -- id (@message_type) and data (@l0,
522 * @l1, @l2, @l3, @l4).
524 * This is an internal utility function that application will
525 * not need to call directly.
530 hildon_animation_actor_send_message (HildonAnimationActor *self,
531 guint32 message_type,
538 GtkWidget *widget = GTK_WIDGET (self);
539 Display *display = GDK_WINDOW_XDISPLAY (widget->window);
540 Window window = GDK_WINDOW_XID (widget->window);
542 XClientMessageEvent event;
544 event.type = ClientMessage;
545 event.window = window;
546 event.message_type = (Atom)message_type;
548 event.data.l[0] = l0;
549 event.data.l[1] = l1;
550 event.data.l[2] = l2;
551 event.data.l[3] = l3;
552 event.data.l[4] = l4;
554 XEvent event = { 0 };
556 event.xclient.type = ClientMessage;
557 event.xclient.window = window;
558 event.xclient.message_type = (Atom)message_type;
559 event.xclient.format = 32;
560 event.xclient.data.l[0] = l0;
561 event.xclient.data.l[1] = l1;
562 event.xclient.data.l[2] = l2;
563 event.xclient.data.l[3] = l3;
564 event.xclient.data.l[4] = l4;
568 g_debug ("%lu (%lu %lu %lu %lu %lu) -> %lu\n",
574 XSendEvent (display, window, True,
580 * hildon_animation_actor_set_show_full:
581 * @self: A #HildonAnimationActor
582 * @show: A boolean flag setting the visibility of the animation actor.
583 * @opacity: Desired opacity setting
585 * Send a message to the window manager setting the visibility of
586 * the animation actor. This will only affect the visibility of
587 * the animation actor set by the compositing window manager in its own
588 * rendering pipeline, after X has drawn the window to the off-screen
589 * buffer. This setting, naturally, has no effect if the #HildonAnimationActor
590 * widget is not visible in X11 terms (i.e. realized and mapped).
592 * Furthermore, if a widget is parented, its final visibility will be
593 * affected by that of the parent window.
595 * The opacity setting ranges from zero (0), being completely transparent
596 * to 255 (0xff) being fully opaque.
598 * If the animation actor WM-counterpart is not ready, the show message
599 * will be queued until the WM is ready for it.
604 hildon_animation_actor_set_show_full (HildonAnimationActor *self,
608 HildonAnimationActorPrivate
609 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
610 GtkWidget *widget = GTK_WIDGET (self);
619 priv->opacity = opacity;
622 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
624 /* Defer show messages until the animation actor is parented
625 * and the parent window is mapped */
627 if (!priv->parent || !GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
630 hildon_animation_actor_send_message (self,
639 * hildon_animation_actor_set_show:
640 * @self: A #HildonAnimationActor
641 * @show: A boolean flag setting the visibility of the animation actor.
643 * This function is a shortcut for hildon_animation_actor_set_show_full(),
644 * setting the overall actor visibility without changing it's opacity
650 hildon_animation_actor_set_show (HildonAnimationActor *self,
653 HildonAnimationActorPrivate
654 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
656 hildon_animation_actor_set_show_full (self,
657 show, priv->opacity);
661 * hildon_animation_actor_set_opacity:
662 * @self: A #HildonAnimationActor
663 * @opacity: Desired opacity setting
665 * This function is a shortcut for hildon_animation_actor_set_show_full(),
666 * setting actor opacity without changing it's overall visibility.
668 * See hildon_animation_actor_set_show_full() for description of the range
669 * of values @opacity argument takes.
674 hildon_animation_actor_set_opacity (HildonAnimationActor *self,
677 HildonAnimationActorPrivate
678 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
680 hildon_animation_actor_set_show_full (self,
681 priv->show, opacity);
685 * hildon_animation_actor_set_position_full:
686 * @self: A #HildonAnimationActor
687 * @x: Desired X coordinate
688 * @y: Desired Y coordinate
689 * @depth: Desired window depth (Z coordinate)
691 * Send a message to the window manager setting the position of the
692 * animation actor. This will set the position of the animation
693 * actor off-screen bitmap as it is rendered to the screen. The
694 * position of the actor is relative to the parent window. The actor
695 * is also subject to the animation effects rendered by the compositing
696 * window manager on that window (like those by task switcher).
698 * The window depth affects the stacking of animation actors within
699 * a parent window and, more generally, the stacking of clutter actors
700 * within a stage/container. The default depth is 0 and a parent
701 * window's container will have it's window texture stacked at that level.
702 * The stacking at any depth level is sequential -- animation actor B
703 * created/parented after animation actor A will obscure the latter
706 * Animation actors with non-zero depth settings are subject to scaling as
707 * per the global scene perspective setup, which limits the depth setting
708 * as the primary parameter to control the stacking order. Since the
709 * stacking order follows the parenting order, it may be better to use
710 * hildon_animation_actor_set_parent() for setting the stacking.
712 * If the animation actor WM-counterpart is not ready, the show message
713 * will be queued until the WM is ready for it.
718 hildon_animation_actor_set_position_full (HildonAnimationActor *self,
723 HildonAnimationActorPrivate
724 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
725 GtkWidget *widget = GTK_WIDGET (self);
727 priv->position_x = x;
728 priv->position_y = y;
730 priv->set_position = 1;
732 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
734 hildon_animation_actor_send_message (self,
738 priv->set_position = 0;
743 * hildon_animation_actor_set_position:
744 * @self: A #HildonAnimationActor
745 * @x: Desired window X coordinate
746 * @y: Desired window Y coordinate
748 * A shortcut for hildon_animation_actor_set_position_full(),
749 * changing the window position, but preserving it's depth setting.
754 hildon_animation_actor_set_position (HildonAnimationActor *self,
758 HildonAnimationActorPrivate
759 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
761 hildon_animation_actor_set_position_full (self,
766 * hildon_animation_actor_set_depth:
767 * @self: A #HildonAnimationActor
768 * @depth: Desired window depth (Z coordinate)
770 * A shortcut for hildon_animation_actor_set_position_full(),
771 * changing the window depth, but preserving it's position.
776 hildon_animation_actor_set_depth (HildonAnimationActor *self,
779 HildonAnimationActorPrivate
780 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
782 hildon_animation_actor_set_position_full (self,
789 * hildon_animation_actor_set_scalex:
790 * @self: A #HildonAnimationActor
791 * @x_scale: Window's desired scale factor along the X-axis
792 * @y_scale: Window's desired scale factor along the Y-axis
794 * This function is just like hildon_animation_actor_set_scale(),
795 * but the scale factors are given as 16-bit fixed-point number.
800 hildon_animation_actor_set_scalex (HildonAnimationActor *self,
804 HildonAnimationActorPrivate
805 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
806 GtkWidget *widget = GTK_WIDGET (self);
808 priv->scale_x = x_scale;
809 priv->scale_y = y_scale;
812 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
814 hildon_animation_actor_send_message (self,
823 * hildon_animation_actor_set_scale:
824 * @self: A #HildonAnimationActor
825 * @x_scale: Window's desired scale factor along the X-axis
826 * @y_scale: Window's desired scale factor along the Y-axis
828 * Send a message to the window manager setting the scale factors of the
829 * animation actor. This will set the scale factors on the animation
830 * actor off-screen bitmap as it is rendered to the screen. If the
831 * animation actor is parented to another top-level window, the
832 * animation effects rendered by the compositing window manager
833 * on that top-level window (like those by task switcher) will
834 * also affect the animation actor.
836 * If the animation actor WM-counterpart is not ready, the show message
837 * will be queued until the WM is ready for it.
842 hildon_animation_actor_set_scale (HildonAnimationActor *self,
846 gint32 f_x_scale = x_scale * (1 << 16);
847 gint32 f_y_scale = y_scale * (1 << 16);
849 hildon_animation_actor_set_scalex (self, f_x_scale, f_y_scale);
853 * hildon_animation_actor_set_rotationx:
854 * @self: A #HildonAnimationActor
855 * @axis: The rotation axis.
856 * @degrees: The rotation angle in degrees.
857 * @x: Center of the rotation, X coordinate.
858 * @y: Center of the rotation, Y coordinate.
859 * @z: Center of the rotation, Z coordinate.
861 * This function is just like hildon_animation_actor_set_rotation(),
862 * but the rotation angle is given as 16-bit fixed-point number.
867 hildon_animation_actor_set_rotationx (HildonAnimationActor *self,
874 HildonAnimationActorPrivate
875 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
876 GtkWidget *widget = GTK_WIDGET (self);
882 case HILDON_AA_X_AXIS:
883 priv->x_rotation_angle = degrees;
884 priv->x_rotation_y = y;
885 priv->x_rotation_z = z;
886 mask = (1 << HILDON_AA_X_AXIS);
888 case HILDON_AA_Y_AXIS:
889 priv->y_rotation_angle = degrees;
890 priv->y_rotation_x = x;
891 priv->y_rotation_z = z;
892 mask = (1 << HILDON_AA_Y_AXIS);
894 case HILDON_AA_Z_AXIS:
895 priv->z_rotation_angle = degrees;
896 priv->z_rotation_x = x;
897 priv->z_rotation_y = y;
898 mask = (1 << HILDON_AA_Z_AXIS);
904 priv->set_rotation |= mask;
906 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
908 hildon_animation_actor_send_message (self,
910 axis, degrees, x, y, z);
911 priv->set_rotation &= ~mask;
916 * hildon_animation_actor_set_rotation:
917 * @self: A #HildonAnimationActor
918 * @axis: The rotation axis.
919 * @degrees: The rotation angle in degrees.
920 * @x: Center of the rotation, X coordinate.
921 * @y: Center of the rotation, Y coordinate.
922 * @z: Center of the rotation, Z coordinate.
924 * Send a message to the window manager setting the animation actor
925 * rotation around one of the three axes. The rotation center coordinates
926 * depend on the axis of rotation:
928 * * %HILDON_AA_X_AXIS requires @y and @z coordinates.
929 * * %HILDON_AA_Y_AXIS requires @x and @z coordinates.
930 * * %HILDON_AA_Z_AXIS requires @x and @y coordinates.
932 * If the animation actor WM-counterpart is not ready, the show message
933 * will be queued until the WM is ready for it.
938 hildon_animation_actor_set_rotation (HildonAnimationActor *self,
945 gint32 f_degrees = degrees * (1 << 16);
947 hildon_animation_actor_set_rotationx (self, axis, f_degrees, x, y, z);
951 * hildon_animation_actor_set_anchor:
952 * @self: A #HildonAnimationActor
953 * @x: The X coordinate of the anchor point.
954 * @y: The Y coordinate of the anchor point.
956 * Send a message to the window manager setting the anchor point for
957 * the animation actor. The anchor point is the point to which the
958 * actor position within its parent it is relative.
960 * If the animation actor WM-counterpart is not ready, the show message
961 * will be queued until the WM is ready for it.
966 hildon_animation_actor_set_anchor (HildonAnimationActor *self,
970 HildonAnimationActorPrivate
971 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
972 GtkWidget *widget = GTK_WIDGET (self);
977 priv->set_anchor = 1;
979 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
981 hildon_animation_actor_send_message (self,
985 priv->set_anchor = 0;
990 * hildon_animation_actor_set_anchor_from_gravity:
991 * @self: A #HildonAnimationActor
992 * @gravity: The gravity constant.
994 * Send a message to the window manager setting the anchor point for
995 * the animation actor. The anchor point is the point to which the
996 * actor position within its parent it is relative. Instead of being
997 * defined in (x, y)-coordinates, the anchor point is defined in the
998 * relative "gravity" constant as:
1000 * * %HILDON_AA_N_GRAVITY translates to (width / 2, 0) coordinate
1001 * * %HILDON_AA_NE_GRAVITY translates to (width, 0) coordinate
1002 * * %HILDON_AA_E_GRAVITY translates to (width, height / 2) coordinate
1003 * * %HILDON_AA_SE_GRAVITY translates to (width, height) coordinate
1004 * * %HILDON_AA_S_GRAVITY translates to (width / 2, height) coordinate
1005 * * %HILDON_AA_SW_GRAVITY translates to (0, height) coordinate
1006 * * %HILDON_AA_W_GRAVITY translates to (0, height / 2) coordinate
1007 * * %HILDON_AA_NW_GRAVITY translates to (0, 0) coordinate
1008 * * %HILDON_AA_CENTER_GRAVITY translates to (width / 2, height / 2) coordinate
1010 * If the animation actor WM-counterpart is not ready, the show message
1011 * will be queued until the WM is ready for it.
1016 hildon_animation_actor_set_anchor_from_gravity (HildonAnimationActor *self,
1019 HildonAnimationActorPrivate
1020 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1021 GtkWidget *widget = GTK_WIDGET (self);
1023 priv->gravity = gravity;
1024 priv->set_anchor = 1;
1026 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
1028 hildon_animation_actor_send_message (self,
1032 priv->set_anchor = 0;
1037 * This callback will be triggered by the parent widget of
1038 * an animation actor when it is mapped. The compositing
1039 * window manager is now ready to parent the animation actor
1040 * into the target parent window.
1043 hildon_animation_actor_parent_map_event (GtkWidget *parent,
1047 hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (user_data),
1048 GTK_WINDOW (parent));
1053 * This callback will be triggered by the widget re-mapping
1054 * itself in case of WM restarting. The point is to push all
1055 * animation actor parameters anew to the WM.
1058 hildon_animation_actor_map_event (GtkWidget *widget,
1062 HildonAnimationActor
1063 *self = HILDON_ANIMATION_ACTOR (user_data);
1064 HildonAnimationActorPrivate
1065 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1067 hildon_animation_actor_send_all_messages (self);
1069 /* Disconnect the "map-event" handler after the "emergency resend all
1070 * actor parameters" drill is over. */
1072 if (priv->map_event_cb_id)
1074 g_signal_handler_disconnect (self,
1075 priv->map_event_cb_id);
1076 priv->map_event_cb_id = 0;
1083 * hildon_animation_actor_set_parent:
1084 * @self: A #HildonAnimationActor
1085 * @parent: A #GtkWindow that the actor will be parented to.
1087 * Send a message to the window manager setting the parent window
1088 * for the animation actor. Parenting an actor will not affect the
1089 * X window that the HildonAnimationActor represents, but it's off-screen
1090 * bitmap as it is handled by the compositing window manager.
1092 * Parenting an animation actor will affect its visibility as set
1093 * by the gtk_widget_show(), gtk_widget_hide() and
1094 * hildon_animation_actor_set_show(). The animation actor will only be
1095 * visible when the top-level window it is parented is visible.
1097 * Passing %NULL as a @parent argument will unparent the animation actor.
1098 * This will restore the actor's visibility if it was suppressed by
1099 * being unparented or parented to an unmapped window.
1101 * If the animation actor WM-counterpart is not ready, the show message
1102 * will be queued until the WM is ready for it.
1107 hildon_animation_actor_set_parent (HildonAnimationActor *self,
1110 HildonAnimationActorPrivate
1111 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1112 GtkWidget *widget = GTK_WIDGET (self);
1114 gtk_window_set_transient_for (GTK_WINDOW (self), parent);
1116 if (priv->parent != parent)
1118 /* Setting a new parent */
1122 if (priv->parent_map_event_cb_id)
1123 g_signal_handler_disconnect (priv->parent,
1124 priv->parent_map_event_cb_id);
1126 /* Might need a synchronized "parent(0)" or "parent(new parent)"
1127 * message here before we can safely decrease the reference count. */
1129 g_object_unref (priv->parent);
1132 priv->parent = parent;
1133 priv->set_parent = 1;
1137 /* The widget is being (re)parented, not unparented. */
1139 g_object_ref (parent);
1141 priv->parent_map_event_cb_id =
1142 g_signal_connect (G_OBJECT (priv->parent),
1144 G_CALLBACK(hildon_animation_actor_parent_map_event),
1149 priv->parent_map_event_cb_id = 0;
1153 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
1157 /* If the animation actor is being unparented or parented to an
1158 * unmapped widget, force its visibility to "hidden". */
1160 if (!priv->parent || !GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
1162 hildon_animation_actor_send_message (self,
1168 /* If the widget is being parented (parent != 0), only proceed when
1169 * the parent widget is realized, since we need the X window id of
1170 * the parent. If the widget is being unparented (parent == 0), pass
1171 * the "special" window id of 0 in the message. */
1175 if (!GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
1178 GdkWindow *gdk = GTK_WIDGET (parent)->window;
1179 win = GDK_WINDOW_XID (gdk);
1182 hildon_animation_actor_send_message (self,
1186 priv->set_parent = 0;
1188 /* Set animation actor visibility to desired value (in case it was
1189 * forced off when the actor was parented into an unmapped widget). */
1191 hildon_animation_actor_send_message (self,
1193 priv->show, priv->opacity,