3. Knowing when an actor's position or size changes
Prev | Chapter 2. Actors | Next

## 3. Knowing when an actor's position or size changes

### 3.1. Problem

You want to know when the position or the size, or both, of an actor change, for instance to update an unrelated actor or some internal state.

### 3.2. Solution

You can use the notify signal, detailed with the coordinate or the dimension you want to know has changed:

    g_signal_connect (actor, "notify::x",
                      G_CALLBACK (on_x_changed),
                      NULL);
    g_signal_connect (actor, "notify::height",
                      G_CALLBACK (on_height_changed),
                      NULL);
    g_signal_connect (actor, "notify::depth",
                      G_CALLBACK (on_depth_changed),
                      NULL);

If you want to know if any of the coordinates or dimensions of an actor have been changed, except for depth, you can use the allocation-changed signal:

    g_signal_connect (actor, "allocation-changed",
                      G_CALLBACK (on_allocation_changed),
                      NULL);

The signature for the handler of the "notify" signal is:

    void
    on_notify (GObject    *gobject,
               GParamSpec *pspec,
               gpointer    user_data);

While the signature for the handler of the "allocation-changed" signal is:

    void
    on_allocation_changed (ClutterActor           *actor,
                           const ClutterActorBox  *allocation,
                           ClutterAllocationFlags  flags,
                           gpointer                user_data);

### 3.3. Discussion

Any change the position and size of an actor will cause a change in the allocation of the actor itself. This will update the values of the x, y, width and height properties as well.

The first technique allows a greater deal of granularity, allowing you to know what exactly changed. Inside the callback for the signal you can query the value of the property:

    void
    on_x_changed (GObject    *gobject,
                  GParamSpec *pspec,
                  gpointer    user_data)
    {
      gint x_value = 0;

      /* Round the X coordinate to the nearest pixel */
      x_value = floorf (clutter_actor_get_x (CLUTTER_ACTOR (gobject))) + 0.5;

      g_print ("The new X coordinate is '%d' pixels\n", x_value);
    }

The second technique is more indicated if you want to get notification that any of the positional or dimensional attributes changed, except for the depth:

    void
    on_allocation_changed (ClutterActor           *actor,
                           const ClutterActorBox  *allocation,
                           ClutterAllocationFlags  flags,
                           gpointer                user_data)
    {
      g_print ("The bounding box is now: (%.2f, %.2f) (%.2f x %.2f)\n",
               clutter_actor_box_get_x (allocation),
               clutter_actor_box_get_y (allocation),
               clutter_actor_box_get_width (allocation),
               clutter_actor_box_get_height (allocation));
    }

All actors will update these properties when their size or position change.

Note that the stage, on the other hand, will not notify on position changes, so it is not possible to use the x and y properties to know that the platform-specific window embedding the stage has been moved — if the platform supports a windowing system. In order to achieve that you will have to use backend-specific API to extract the surface used by the stage and then platform-specific API to retrieve its coordinates.

Prev | Up | Next
2. Implementing a simple custom actor | Home | 4. Overriding the paint sequence