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
313 hildon_animation_actor_new (void)
315 HildonAnimationActor *newwindow = g_object_new (HILDON_TYPE_ANIMATION_ACTOR, NULL);
317 gtk_window_set_decorated (GTK_WINDOW (newwindow), FALSE);
319 return GTK_WIDGET (newwindow);
323 * An filter for GDK X11 events, waiting for PropertyNotify (window property
324 * changes) events, keeping track of animation actor ready atom.
325 * Having the ready atom set on the window by the window manager will trigger
326 * updates of actor parameters (position/rotation/etc...) to be sent off
327 * to the window manager for processing.
329 static GdkFilterReturn
330 hildon_animation_actor_event_filter (GdkXEvent *xevent,
334 HildonAnimationActor *self = HILDON_ANIMATION_ACTOR (data);
335 XAnyEvent *any = xevent;
337 if (any->type == PropertyNotify)
339 XPropertyEvent *property = xevent;
341 if (property->atom == ready_atom)
343 hildon_animation_actor_update_ready (self);
347 return GDK_FILTER_CONTINUE;
351 * Check for the ready atom on the animation actor X11 window.
352 * If present, send all pending animation actor messages to the
356 hildon_animation_actor_update_ready (HildonAnimationActor *self)
358 HildonAnimationActorPrivate
359 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
360 GtkWidget *widget = GTK_WIDGET (self);
361 Display *display = GDK_WINDOW_XDISPLAY (widget->window);
362 Window window = GDK_WINDOW_XID (widget->window);
369 unsigned long nitems, bytes_after;
370 unsigned char *prop = NULL;
372 /* Check for the "ready" property */
374 gdk_error_trap_push ();
375 status = XGetWindowProperty (display, window,
378 &actual_type, &actual_format,
379 &nitems, &bytes_after, &prop);
380 xerror = gdk_error_trap_pop();
384 /* We do not actually use the property value for anything,
385 * it is enough that the property is set. */
391 (status != Success) || (actual_type != XA_ATOM) ||
392 (actual_format != 32) || (nitems != 1))
400 /* The ready flag has been set once already. This means that
401 * the WM has restarted. Trigger re-mapping of the widget to
402 * update the texture actor first. Then push all animation
403 * actor settings anew. */
405 priv->map_event_cb_id =
406 g_signal_connect (G_OBJECT (self),
408 G_CALLBACK(hildon_animation_actor_map_event),
411 if (GTK_WIDGET_MAPPED (GTK_WIDGET (self)))
413 gtk_widget_unmap (GTK_WIDGET (self));
414 gtk_widget_map (GTK_WIDGET (self));
422 /* Send all pending messages */
424 hildon_animation_actor_send_pending_messages (self);
428 hildon_animation_actor_send_pending_messages (HildonAnimationActor *self)
430 HildonAnimationActorPrivate
431 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
433 if (priv->set_anchor)
435 if (priv->gravity == 0)
436 hildon_animation_actor_set_anchor (self,
440 hildon_animation_actor_set_anchor_from_gravity (self,
444 if (priv->set_position)
445 hildon_animation_actor_set_position_full (self,
450 if (priv->set_rotation & (1 << HILDON_AA_X_AXIS))
451 hildon_animation_actor_set_rotationx (self,
453 priv->x_rotation_angle,
458 if (priv->set_rotation & (1 << HILDON_AA_Y_AXIS))
459 hildon_animation_actor_set_rotationx (self,
461 priv->y_rotation_angle,
466 if (priv->set_rotation & (1 << HILDON_AA_Z_AXIS))
467 hildon_animation_actor_set_rotationx (self,
469 priv->z_rotation_angle,
475 hildon_animation_actor_set_scalex (self,
479 if (priv->set_parent)
480 hildon_animation_actor_set_parent (self,
484 hildon_animation_actor_set_show_full (self,
485 priv->show, priv->opacity);
489 hildon_animation_actor_send_all_messages (HildonAnimationActor *self)
491 HildonAnimationActorPrivate
492 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
494 priv->set_anchor = 1;
495 priv->set_position = 1;
496 priv->set_rotation = (1 << HILDON_AA_X_AXIS) |
497 (1 << HILDON_AA_Y_AXIS) |
498 (1 << HILDON_AA_Z_AXIS);
500 priv->set_parent = 1;
503 hildon_animation_actor_send_pending_messages (self);
506 /* ------------------------------------------------------------- */
509 * hildon_animation_actor_send_message:
510 * @self: A #HildonAnimationActor
511 * @message_type: Message id for the animation actor message.
512 * @l0: 1st animation actor message parameter.
513 * @l1: 2nd animation actor message parameter.
514 * @l2: 3rd animation actor message parameter.
515 * @l3: 4th animation actor message parameter.
516 * @l4: 5th animation actor message parameter.
518 * Sends an X11 ClientMessage event to the window manager with
519 * the specified parameters -- id (@message_type) and data (@l0,
520 * @l1, @l2, @l3, @l4).
522 * This is an internal utility function that application will
523 * not need to call directly.
526 hildon_animation_actor_send_message (HildonAnimationActor *self,
527 guint32 message_type,
534 GtkWidget *widget = GTK_WIDGET (self);
535 Display *display = GDK_WINDOW_XDISPLAY (widget->window);
536 Window window = GDK_WINDOW_XID (widget->window);
538 XClientMessageEvent event;
540 event.type = ClientMessage;
541 event.window = window;
542 event.message_type = (Atom)message_type;
544 event.data.l[0] = l0;
545 event.data.l[1] = l1;
546 event.data.l[2] = l2;
547 event.data.l[3] = l3;
548 event.data.l[4] = l4;
550 XEvent event = { 0 };
552 event.xclient.type = ClientMessage;
553 event.xclient.window = window;
554 event.xclient.message_type = (Atom)message_type;
555 event.xclient.format = 32;
556 event.xclient.data.l[0] = l0;
557 event.xclient.data.l[1] = l1;
558 event.xclient.data.l[2] = l2;
559 event.xclient.data.l[3] = l3;
560 event.xclient.data.l[4] = l4;
564 g_debug ("%lu (%lu %lu %lu %lu %lu) -> %lu\n",
570 XSendEvent (display, window, True,
576 * hildon_animation_actor_set_show_full:
577 * @self: A #HildonAnimationActor
578 * @show: A boolean flag setting the visibility of the animation actor.
579 * @opacity: Desired opacity setting
581 * Send a message to the window manager setting the visibility of
582 * the animation actor. This will only affect the visibility of
583 * the animation actor set by the compositing window manager in its own
584 * rendering pipeline, after X has drawn the window to the off-screen
585 * buffer. This setting, naturally, has no effect if the #HildonAnimationActor
586 * widget is not visible in X11 terms (i.e. realized and mapped).
588 * Furthermore, if a widget is parented, its final visibility will be
589 * affected by that of the parent window.
591 * The opacity setting ranges from zero (0), being completely transparent
592 * to 255 (0xff) being fully opaque.
594 * If the animation actor WM-counterpart is not ready, the show message
595 * will be queued until the WM is ready for it.
598 hildon_animation_actor_set_show_full (HildonAnimationActor *self,
602 HildonAnimationActorPrivate
603 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
604 GtkWidget *widget = GTK_WIDGET (self);
613 priv->opacity = opacity;
616 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
618 /* Defer show messages until the animation actor is parented
619 * and the parent window is mapped */
621 if (!priv->parent || !GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
624 hildon_animation_actor_send_message (self,
633 * hildon_animation_actor_set_show:
634 * @self: A #HildonAnimationActor
635 * @show: A boolean flag setting the visibility of the animation actor.
637 * This function is a shortcut for hildon_animation_actor_set_show_full(),
638 * setting the overall actor visibility without changing it's opacity
642 hildon_animation_actor_set_show (HildonAnimationActor *self,
645 HildonAnimationActorPrivate
646 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
648 hildon_animation_actor_set_show_full (self,
649 show, priv->opacity);
653 * hildon_animation_actor_set_opacity:
654 * @self: A #HildonAnimationActor
655 * @opacity: Desired opacity setting
657 * This function is a shortcut for hildon_animation_actor_set_show_full(),
658 * setting actor opacity without changing it's overall visibility.
660 * See hildon_animation_actor_set_show_full() for description of the range
661 * of values @opacity argument takes.
664 hildon_animation_actor_set_opacity (HildonAnimationActor *self,
667 HildonAnimationActorPrivate
668 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
670 hildon_animation_actor_set_show_full (self,
671 priv->show, opacity);
675 * hildon_animation_actor_set_position_full:
676 * @self: A #HildonAnimationActor
677 * @x: Desired X coordinate
678 * @y: Desired Y coordinate
679 * @depth: Desired window depth (Z coordinate)
681 * Send a message to the window manager setting the position of the
682 * animation actor. This will set the position of the animation
683 * actor off-screen bitmap as it is rendered to the screen. The
684 * position of the actor is relative to the parent window. The actor
685 * is also subject to the animation effects rendered by the compositing
686 * window manager on that window (like those by task switcher).
688 * The window depth affects the stacking of animation actors within
689 * a parent window and, more generally, the stacking of clutter actors
690 * within a stage/container. The default depth is 0 and a parent
691 * window's container will have it's window texture stacked at that level.
692 * The stacking at any depth level is sequential -- animation actor B
693 * created/parented after animation actor A will obscure the latter
696 * Animation actors with non-zero depth settings are subject to scaling as
697 * per the global scene perspective setup, which limits the depth setting
698 * as the primary parameter to control the stacking order. Since the
699 * stacking order follows the parenting order, it may be better to use
700 * hildon_animation_actor_set_parent() for setting the stacking.
702 * If the animation actor WM-counterpart is not ready, the show message
703 * will be queued until the WM is ready for it.
706 hildon_animation_actor_set_position_full (HildonAnimationActor *self,
711 HildonAnimationActorPrivate
712 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
713 GtkWidget *widget = GTK_WIDGET (self);
715 priv->position_x = x;
716 priv->position_y = y;
718 priv->set_position = 1;
720 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
722 hildon_animation_actor_send_message (self,
726 priv->set_position = 0;
731 * hildon_animation_actor_set_position:
732 * @self: A #HildonAnimationActor
733 * @x: Desired window X coordinate
734 * @y: Desired window Y coordinate
736 * A shortcut for hildon_animation_actor_set_position_full(),
737 * changing the window position, but preserving it's depth setting.
740 hildon_animation_actor_set_position (HildonAnimationActor *self,
744 HildonAnimationActorPrivate
745 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
747 hildon_animation_actor_set_position_full (self,
752 * hildon_animation_actor_set_depth:
753 * @self: A #HildonAnimationActor
754 * @depth: Desired window depth (Z coordinate)
756 * A shortcut for hildon_animation_actor_set_position_full(),
757 * changing the window depth, but preserving it's position.
760 hildon_animation_actor_set_depth (HildonAnimationActor *self,
763 HildonAnimationActorPrivate
764 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
766 hildon_animation_actor_set_position_full (self,
773 * hildon_animation_actor_set_scalex:
774 * @self: A #HildonAnimationActor
775 * @x_scale: Window's desired scale factor along the X-axis
776 * @y_scale: Window's desired scale factor along the Y-axis
778 * This function is just like hildon_animation_actor_set_scale(),
779 * but the scale factors are given as 16-bit fixed-point number.
782 hildon_animation_actor_set_scalex (HildonAnimationActor *self,
786 HildonAnimationActorPrivate
787 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
788 GtkWidget *widget = GTK_WIDGET (self);
790 priv->scale_x = x_scale;
791 priv->scale_y = y_scale;
794 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
796 hildon_animation_actor_send_message (self,
805 * hildon_animation_actor_set_scale:
806 * @self: A #HildonAnimationActor
807 * @x_scale: Window's desired scale factor along the X-axis
808 * @y_scale: Window's desired scale factor along the Y-axis
810 * Send a message to the window manager setting the scale factors of the
811 * animation actor. This will set the scale factors on the animation
812 * actor off-screen bitmap as it is rendered to the screen. If the
813 * animation actor is parented to another top-level window, the
814 * animation effects rendered by the compositing window manager
815 * on that top-level window (like those by task switcher) will
816 * also affect the animation actor.
818 * If the animation actor WM-counterpart is not ready, the show message
819 * will be queued until the WM is ready for it.
822 hildon_animation_actor_set_scale (HildonAnimationActor *self,
826 gint32 f_x_scale = x_scale * (1 << 16);
827 gint32 f_y_scale = y_scale * (1 << 16);
829 hildon_animation_actor_set_scalex (self, f_x_scale, f_y_scale);
833 * hildon_animation_actor_set_rotationx:
834 * @self: A #HildonAnimationActor
835 * @axis: The rotation axis.
836 * @degrees: The rotation angle in degrees.
837 * @x: Center of the rotation, X coordinate.
838 * @y: Center of the rotation, Y coordinate.
839 * @z: Center of the rotation, Z coordinate.
841 * This function is just like hildon_animation_actor_set_rotation(),
842 * but the rotation angle is given as 16-bit fixed-point number.
845 hildon_animation_actor_set_rotationx (HildonAnimationActor *self,
852 HildonAnimationActorPrivate
853 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
854 GtkWidget *widget = GTK_WIDGET (self);
860 case HILDON_AA_X_AXIS:
861 priv->x_rotation_angle = degrees;
862 priv->x_rotation_y = y;
863 priv->x_rotation_z = z;
864 mask = (1 << HILDON_AA_X_AXIS);
866 case HILDON_AA_Y_AXIS:
867 priv->y_rotation_angle = degrees;
868 priv->y_rotation_x = x;
869 priv->y_rotation_z = z;
870 mask = (1 << HILDON_AA_Y_AXIS);
872 case HILDON_AA_Z_AXIS:
873 priv->z_rotation_angle = degrees;
874 priv->z_rotation_x = x;
875 priv->z_rotation_y = y;
876 mask = (1 << HILDON_AA_Z_AXIS);
882 priv->set_rotation |= mask;
884 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
886 hildon_animation_actor_send_message (self,
888 axis, degrees, x, y, z);
889 priv->set_rotation &= ~mask;
894 * hildon_animation_actor_set_rotation:
895 * @self: A #HildonAnimationActor
896 * @axis: The rotation axis.
897 * @degrees: The rotation angle in degrees.
898 * @x: Center of the rotation, X coordinate.
899 * @y: Center of the rotation, Y coordinate.
900 * @z: Center of the rotation, Z coordinate.
902 * Send a message to the window manager setting the animation actor
903 * rotation around one of the three axes. The rotation center coordinates
904 * depend on the axis of rotation:
906 * * %HILDON_AA_X_AXIS requires @y and @z coordinates.
907 * * %HILDON_AA_Y_AXIS requires @x and @z coordinates.
908 * * %HILDON_AA_Z_AXIS requires @x and @y coordinates.
910 * If the animation actor WM-counterpart is not ready, the show message
911 * will be queued until the WM is ready for it.
914 hildon_animation_actor_set_rotation (HildonAnimationActor *self,
921 gint32 f_degrees = degrees * (1 << 16);
923 hildon_animation_actor_set_rotationx (self, axis, f_degrees, x, y, z);
927 * hildon_animation_actor_set_anchor:
928 * @self: A #HildonAnimationActor
929 * @x: The X coordinate of the anchor point.
930 * @y: The Y coordinate of the anchor point.
932 * Send a message to the window manager setting the anchor point for
933 * the animation actor. The anchor point is the point to which the
934 * actor position within its parent it is relative.
936 * If the animation actor WM-counterpart is not ready, the show message
937 * will be queued until the WM is ready for it.
940 hildon_animation_actor_set_anchor (HildonAnimationActor *self,
944 HildonAnimationActorPrivate
945 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
946 GtkWidget *widget = GTK_WIDGET (self);
951 priv->set_anchor = 1;
953 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
955 hildon_animation_actor_send_message (self,
959 priv->set_anchor = 0;
964 * hildon_animation_actor_set_anchor_from_gravity:
965 * @self: A #HildonAnimationActor
966 * @gravity: The gravity constant.
968 * Send a message to the window manager setting the anchor point for
969 * the animation actor. The anchor point is the point to which the
970 * actor position within its parent it is relative. Instead of being
971 * defined in (x, y)-coordinates, the anchor point is defined in the
972 * relative "gravity" constant as:
974 * * %HILDON_AA_N_GRAVITY translates to (width / 2, 0) coordinate
975 * * %HILDON_AA_NE_GRAVITY translates to (width, 0) coordinate
976 * * %HILDON_AA_E_GRAVITY translates to (width, height / 2) coordinate
977 * * %HILDON_AA_SE_GRAVITY translates to (width, height) coordinate
978 * * %HILDON_AA_S_GRAVITY translates to (width / 2, height) coordinate
979 * * %HILDON_AA_SW_GRAVITY translates to (0, height) coordinate
980 * * %HILDON_AA_W_GRAVITY translates to (0, height / 2) coordinate
981 * * %HILDON_AA_NW_GRAVITY translates to (0, 0) coordinate
982 * * %HILDON_AA_CENTER_GRAVITY translates to (width / 2, height / 2) coordinate
984 * If the animation actor WM-counterpart is not ready, the show message
985 * will be queued until the WM is ready for it.
988 hildon_animation_actor_set_anchor_from_gravity (HildonAnimationActor *self,
991 HildonAnimationActorPrivate
992 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
993 GtkWidget *widget = GTK_WIDGET (self);
995 priv->gravity = gravity;
996 priv->set_anchor = 1;
998 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
1000 hildon_animation_actor_send_message (self,
1004 priv->set_anchor = 0;
1009 * This callback will be triggered by the parent widget of
1010 * an animation actor when it is mapped. The compositing
1011 * window manager is now ready to parent the animation actor
1012 * into the target parent window.
1015 hildon_animation_actor_parent_map_event (GtkWidget *parent,
1019 hildon_animation_actor_set_parent (HILDON_ANIMATION_ACTOR (user_data),
1020 GTK_WINDOW (parent));
1025 * This callback will be triggered by the widget re-mapping
1026 * itself in case of WM restarting. The point is to push all
1027 * animation actor parameters anew to the WM.
1030 hildon_animation_actor_map_event (GtkWidget *widget,
1034 HildonAnimationActor
1035 *self = HILDON_ANIMATION_ACTOR (user_data);
1036 HildonAnimationActorPrivate
1037 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1039 hildon_animation_actor_send_all_messages (self);
1041 /* Disconnect the "map-event" handler after the "emergency resend all
1042 * actor parameters" drill is over. */
1044 if (priv->map_event_cb_id)
1046 g_signal_handler_disconnect (self,
1047 priv->map_event_cb_id);
1048 priv->map_event_cb_id = 0;
1055 * hildon_animation_actor_set_parent:
1056 * @self: A #HildonAnimationActor
1057 * @parent: A #GtkWindow that the actor will be parented to.
1059 * Send a message to the window manager setting the parent window
1060 * for the animation actor. Parenting an actor will not affect the
1061 * X window that the HildonAnimationActor represents, but it's off-screen
1062 * bitmap as it is handled by the compositing window manager.
1064 * Parenting an animation actor will affect its visibility as set
1065 * by the gtk_widget_show(), gtk_widget_hide() and
1066 * hildon_animation_actor_set_show(). The animation actor will only be
1067 * visible when the top-level window it is parented is visible.
1069 * Passing %NULL as a @parent argument will unparent the animation actor.
1070 * This will restore the actor's visibility if it was suppressed by
1071 * being unparented or parented to an unmapped window.
1073 * If the animation actor WM-counterpart is not ready, the show message
1074 * will be queued until the WM is ready for it.
1077 hildon_animation_actor_set_parent (HildonAnimationActor *self,
1080 HildonAnimationActorPrivate
1081 *priv = HILDON_ANIMATION_ACTOR_GET_PRIVATE (self);
1082 GtkWidget *widget = GTK_WIDGET (self);
1084 gtk_window_set_transient_for (GTK_WINDOW (self), parent);
1086 if (priv->parent != parent)
1088 /* Setting a new parent */
1092 if (priv->parent_map_event_cb_id)
1093 g_signal_handler_disconnect (priv->parent,
1094 priv->parent_map_event_cb_id);
1096 /* Might need a synchronized "parent(0)" or "parent(new parent)"
1097 * message here before we can safely decrease the reference count. */
1099 g_object_unref (priv->parent);
1102 priv->parent = parent;
1103 priv->set_parent = 1;
1107 /* The widget is being (re)parented, not unparented. */
1109 g_object_ref (parent);
1111 priv->parent_map_event_cb_id =
1112 g_signal_connect (G_OBJECT (priv->parent),
1114 G_CALLBACK(hildon_animation_actor_parent_map_event),
1119 priv->parent_map_event_cb_id = 0;
1123 if (GTK_WIDGET_MAPPED (widget) && priv->ready)
1127 /* If the animation actor is being unparented or parented to an
1128 * unmapped widget, force its visibility to "hidden". */
1130 if (!priv->parent || !GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
1132 hildon_animation_actor_send_message (self,
1138 /* If the widget is being parented (parent != 0), only proceed when
1139 * the parent widget is realized, since we need the X window id of
1140 * the parent. If the widget is being unparented (parent == 0), pass
1141 * the "special" window id of 0 in the message. */
1145 if (!GTK_WIDGET_MAPPED (GTK_WIDGET (priv->parent)))
1148 GdkWindow *gdk = GTK_WIDGET (parent)->window;
1149 win = GDK_WINDOW_XID (gdk);
1152 hildon_animation_actor_send_message (self,
1156 priv->set_parent = 0;
1158 /* Set animation actor visibility to desired value (in case it was
1159 * forced off when the actor was parented into an unmapped widget). */
1161 hildon_animation_actor_send_message (self,
1163 priv->show, priv->opacity,