예제 #1
0
/*
 * _clutter_input_device_set_actor:
 * @device: a #ClutterInputDevice
 * @actor: a #ClutterActor
 *
 * Sets the actor under the pointer coordinates of @device
 *
 * This function is called by _clutter_input_device_update()
 * and it will:
 *
 *   - queue a %CLUTTER_LEAVE event on the previous pointer actor
 *     of @device, if any
 *   - set to %FALSE the :has-pointer property of the previous
 *     pointer actor of @device, if any
 *   - queue a %CLUTTER_ENTER event on the new pointer actor
 *   - set to %TRUE the :has-pointer property of the new pointer
 *     actor
 */
void
_clutter_input_device_set_actor (ClutterInputDevice *device,
                                 ClutterActor       *actor)
{
  ClutterActor *old_actor;
  ClutterEvent cev;

  g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));

  if (actor == device->cursor_actor)
    return;

  old_actor = device->cursor_actor;
  if (old_actor != NULL)
    {
      cev.crossing.type = CLUTTER_LEAVE;
      cev.crossing.time = device->current_time;
      cev.crossing.flags = 0;
      cev.crossing.stage = device->stage;
      cev.crossing.source = device->cursor_actor;
      cev.crossing.x = device->current_x;
      cev.crossing.y = device->current_y;
      cev.crossing.device = device;
      cev.crossing.related = actor;

      /* we need to make sure that this event is processed before
       * any other event we might have queued up until now, so we
       * go on and synthesize the event emission
       */
      _clutter_process_event (&cev);

      _clutter_actor_set_has_pointer (device->cursor_actor, FALSE);
      g_object_weak_unref (G_OBJECT (device->cursor_actor),
                           cursor_weak_unref,
                           device);

      device->cursor_actor = NULL;
    }

  if (actor != NULL)
    {
      cev.crossing.type = CLUTTER_ENTER;
      cev.crossing.time = device->current_time;
      cev.crossing.flags = 0;
      cev.crossing.stage = device->stage;
      cev.crossing.x = device->current_x;
      cev.crossing.y = device->current_y;
      cev.crossing.device = device;

      CLUTTER_NOTE (EVENT, "Device '%s' entering '%s' at %d, %d",
                    device->device_name,
                    clutter_actor_get_name (actor) != NULL
                      ? clutter_actor_get_name (actor)
                      : G_OBJECT_TYPE_NAME (actor),
                    device->current_x,
                    device->current_y);

      /* if there is an actor overlapping the Stage boundary and we
       * don't do this check then we'll emit an ENTER event only on
       * the actor instead of emitting it on the Stage *and* the
       * actor
       */
      if (old_actor == NULL && actor != CLUTTER_ACTOR (device->stage))
        {
          cev.crossing.source = CLUTTER_ACTOR (device->stage);
          cev.crossing.related = NULL;

          CLUTTER_NOTE (EVENT, "Adding Crossing[Enter] event for Stage");

          _clutter_process_event (&cev);

          cev.crossing.source = actor;
          cev.crossing.related = CLUTTER_ACTOR (device->stage);
        }
      else
        {
          cev.crossing.source = actor;
          cev.crossing.related = old_actor;
        }

      /* as above: we need to make sure that this event is processed
       * before any other event we might have queued up until now, so
       * we go on and synthesize the event emission
       */
      _clutter_process_event (&cev);
    }

  device->cursor_actor = actor;

  if (device->cursor_actor != NULL)
    {
      g_object_weak_ref (G_OBJECT (device->cursor_actor),
                         cursor_weak_unref,
                         device);
      _clutter_actor_set_has_pointer (device->cursor_actor, TRUE);
    }
}
예제 #2
0
/*< private >
 * clutter_input_device_set_actor:
 * @device: a #ClutterInputDevice
 * @actor: a #ClutterActor
 * @emit_crossing: %TRUE to emit crossing events
 *
 * Sets the actor under the pointer coordinates of @device
 *
 * This function is called by _clutter_input_device_update()
 * and it will:
 *
 *   - queue a %CLUTTER_LEAVE event on the previous pointer actor
 *     of @device, if any
 *   - set to %FALSE the :has-pointer property of the previous
 *     pointer actor of @device, if any
 *   - queue a %CLUTTER_ENTER event on the new pointer actor
 *   - set to %TRUE the :has-pointer property of the new pointer
 *     actor
 */
void
_clutter_input_device_set_actor (ClutterInputDevice *device,
                                 ClutterActor       *actor,
                                 gboolean            emit_crossing)
{
  ClutterActor *old_actor;

  if (device->cursor_actor == actor)
    return;

  old_actor = device->cursor_actor;

  if (old_actor != NULL)
    {
      if (emit_crossing)
        {
          ClutterEvent *event;

          event = clutter_event_new (CLUTTER_LEAVE);
          event->crossing.time = device->current_time;
          event->crossing.flags = 0;
          event->crossing.stage = device->stage;
          event->crossing.source = device->cursor_actor;
          event->crossing.x = device->current_x;
          event->crossing.y = device->current_y;
          event->crossing.related = actor;
          clutter_event_set_device (event, device);

          /* we need to make sure that this event is processed
           * before any other event we might have queued up until
           * now, so we go on, and synthesize the event emission
           * ourselves
           */
          _clutter_process_event (event);

          clutter_event_free (event);
        }

      /* processing the event might have destroyed the actor */
      if (device->cursor_actor != NULL)
        {
          _clutter_actor_set_has_pointer (device->cursor_actor, FALSE);
          g_object_weak_unref (G_OBJECT (device->cursor_actor),
                               cursor_weak_unref,
                               device);

          device->cursor_actor = NULL;
        }
    }

  if (actor != NULL)
    {
      if (emit_crossing)
        {
          ClutterEvent *event;

          event = clutter_event_new (CLUTTER_ENTER);
          event->crossing.time = device->current_time;
          event->crossing.flags = 0;
          event->crossing.stage = device->stage;
          event->crossing.x = device->current_x;
          event->crossing.y = device->current_y;
          event->crossing.source = actor;
          event->crossing.related = old_actor;
          clutter_event_set_device (event, device);

          /* see above */
          _clutter_process_event (event);

          clutter_event_free (event);
        }
    }

  device->cursor_actor = actor;
  if (device->cursor_actor != NULL)
    {
      g_object_weak_ref (G_OBJECT (device->cursor_actor),
                         cursor_weak_unref,
                         device);
      _clutter_actor_set_has_pointer (device->cursor_actor, TRUE);
    }
}