static void
mex_content_box_toggle_open (MexContentBox *box)
{
  MexContentBoxPrivate *priv = box->priv;
  gboolean close_notified, next_is_open;
  const gchar *mimetype;

  /* search history items should not appear in the "open" state */
  mimetype = mex_content_get_metadata (priv->content,
                                       MEX_CONTENT_METADATA_MIMETYPE);
  if (!g_strcmp0 (mimetype, "x-mex/search"))
    return;


  /* if the close animation was cancelled then no notify for the closed state
   * will have been sent, therefore notify for the opened state does not need
   * to be emitted */
  close_notified = (!priv->is_open
                    && !clutter_timeline_is_playing (priv->timeline));

  next_is_open = !priv->is_open;

  if (next_is_open)
    {
      /* opening */
      clutter_timeline_set_direction (priv->timeline,
                                      CLUTTER_TIMELINE_FORWARD);
      mx_stylable_set_style_class (MX_STYLABLE (box), "open");

      /* refresh the action list */
      mex_content_view_set_content (MEX_CONTENT_VIEW (priv->action_list),
                                    priv->content);

      priv->extras_visible = TRUE;
      if (close_notified)
        g_object_notify_by_pspec (G_OBJECT (box), properties[PROP_OPEN]);

      mex_push_focus (MX_FOCUSABLE (priv->action_list));
    }
  else
    {
      priv->is_closing = TRUE;

      /* closing */
      mex_push_focus (MX_FOCUSABLE (priv->tile));
      clutter_timeline_set_direction (priv->timeline,
                                      CLUTTER_TIMELINE_BACKWARD);

      priv->is_closing = FALSE;
      priv->extras_visible = TRUE;
    }

  if (!clutter_timeline_is_playing (priv->timeline))
    clutter_timeline_rewind (priv->timeline);

  clutter_timeline_start (priv->timeline);

  priv->is_open = next_is_open;
}
static gboolean
move_actors (ClutterActor *actor,
             ClutterEvent *event,
             gpointer      user_data)
{
  State *state = user_data;
  ClutterActor *child;

  /* do nothing if the animator is already running */
  if (clutter_timeline_is_playing (clutter_animator_get_timeline (state->animator)))
    return TRUE;

  /* remove all keys from the animator */
  clutter_animator_remove_key (state->animator, NULL, NULL, -1);

  /* add keys for all actors in the group */
  for (child = clutter_actor_get_first_child (state->group);
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    {
      add_keys_for_actor (child, state->animator);
    }

  /* start the animation */
  clutter_animator_start (state->animator);

  return TRUE;
}
Beispiel #3
0
void
astro_appview_advance (AstroAppview *view,
                       gint          n)
{
  AstroAppviewPrivate *priv;
  static ClutterTimeline *move_time = NULL;
  gint new_active;

  g_return_if_fail (ASTRO_IS_APPVIEW (view));
  priv = view->priv;

  new_active = priv->active + n;
  if (new_active < 0 || new_active >= g_list_length (priv->apps))
    return;
  priv->active = new_active;

  if (CLUTTER_IS_TIMELINE (move_time) &&clutter_timeline_is_playing (move_time))
    {
      clutter_timeline_stop (move_time);
      g_object_unref (move_time);
    }
 
  move_time = clutter_effect_move (priv->move_temp,
                                   CLUTTER_ACTOR (view),
                          (CSW()/2)- (priv->active * ASTRO_APPICON_SPACING ()),
                                    clutter_actor_get_y (CLUTTER_ACTOR (view)),
                                    NULL, NULL);

  g_signal_connect (move_time, "new-frame",
                    G_CALLBACK (on_move_timeline_new_frame), view);
}
Beispiel #4
0
static void
astro_appview_hide (ClutterActor *view)
{
  AstroAppviewPrivate *priv;
  static ClutterTimeline *hide_time = NULL;
  
  g_return_if_fail (ASTRO_IS_APPVIEW (view));
  priv = ASTRO_APPVIEW (view)->priv;

  if (CLUTTER_IS_TIMELINE (hide_time) &&clutter_timeline_is_playing (hide_time))
    {
      clutter_timeline_stop (hide_time);
      g_object_unref (hide_time);
    }
  
  hide_time = clutter_effect_move (priv->hide_temp,
                                   CLUTTER_ACTOR (view),
                                   -1 * clutter_actor_get_width (view),
                                   clutter_actor_get_y (CLUTTER_ACTOR (view)),
                                   NULL, NULL);

  g_signal_connect (hide_time, "new-frame",
                    G_CALLBACK (on_move_timeline_new_frame), view); 
  g_signal_connect (hide_time, "completed",
                    G_CALLBACK (on_hide_timeline_completed), view);
}
Beispiel #5
0
static void
astro_appview_show (ClutterActor *view)
{
  AstroAppviewPrivate *priv;
  static ClutterTimeline *show_time = NULL;
  
  g_return_if_fail (ASTRO_IS_APPVIEW (view));
  priv = ASTRO_APPVIEW (view)->priv;

  if (CLUTTER_IS_TIMELINE (show_time) &&clutter_timeline_is_playing (show_time))
    {
      clutter_timeline_stop (show_time);
      g_object_unref (show_time);
    }

  clutter_actor_set_x (view, -1* clutter_actor_get_width (view));
  CLUTTER_ACTOR_CLASS (astro_appview_parent_class)->show (view);

  show_time = clutter_effect_move (priv->show_temp,
                                   CLUTTER_ACTOR (view),
                            (CSW()/2)- (priv->active * ASTRO_APPICON_SPACING()),
                             clutter_actor_get_y (CLUTTER_ACTOR (view)),
                                   NULL, NULL);

  g_signal_connect (show_time, "new-frame",
                    G_CALLBACK (on_move_timeline_new_frame), view); 
}
Beispiel #6
0
static gboolean
on_input (ClutterActor *stage,
	  ClutterEvent *event,
	  gpointer      user_data)
{
  App *app = user_data;

  if (event->type == CLUTTER_KEY_RELEASE)
    {
      if (clutter_timeline_is_playing(app->timeline))
	return FALSE;

      switch (clutter_event_get_key_symbol (event))
	{
	case CLUTTER_Left:
	  rotate_items (app, -1);
	  break;
	case CLUTTER_Right:
	  rotate_items (app, 1);
	  break;
	case CLUTTER_Return:
	  break;
	case CLUTTER_q:
	  clutter_main_quit();
	  break;
	default:
	  break;
	}
    }

  return FALSE;
}
Beispiel #7
0
static void
start_entry (ClutterScoreEntry *entry)
{
  ClutterScorePrivate *priv = entry->score->priv;

  /* timelines attached to a marker might already be playing when we
   * end up here from the ::completed handler, so we need to perform
   * this check to avoid restarting those timelines
   */
  if (clutter_timeline_is_playing (entry->timeline))
    return;

  entry->complete_id = g_signal_connect (entry->timeline,
                                         "completed",
                                         G_CALLBACK (on_timeline_completed),
                                         entry);

  CLUTTER_NOTE (SCHEDULER, "timeline [%p] ('%lu') started",
                entry->timeline,
                entry->id);

  if (G_UNLIKELY (priv->running_timelines == NULL))
    priv->running_timelines = g_hash_table_new (NULL, NULL);

  g_hash_table_insert (priv->running_timelines,
                       GUINT_TO_POINTER (entry->id),
                       entry);

  clutter_timeline_start (entry->timeline);

  g_signal_emit (entry->score, score_signals[TIMELINE_STARTED], 0,
                 entry->timeline);
}
Beispiel #8
0
gboolean
gb_player_show_controls (GbPlayer *self)
{
	ClutterEffectTemplate *effect_template;
	gint x, y;
	ClutterKnot t_knot[2];
	ClutterKnot b_knot[2];
	ClutterKnot c_knot[2];
	if ((!self->priv->playing) || (clutter_timeline_is_playing (self->priv->show_hide_timeline)))
		return FALSE;
	
	clutter_timeline_start(self->priv->show_hide_timeline);
	effect_template = clutter_effect_template_new (self->priv->show_hide_timeline, &on_alpha);
	clutter_actor_get_position (self->priv->title_group, &x, &y);
	t_knot[0].x = x;
	t_knot[0].y = y;
	t_knot[1].x= -20;
	t_knot[1].y= 20;
	clutter_actor_get_position (self->priv->window_buttons_group, &x, &y);
	b_knot[0].x = x;
	b_knot[0].y = y;
	b_knot[1].x=  640 - 200;
	b_knot[1].y=  20;
	clutter_actor_get_position (self->priv->window_buttons_group, &x, &y);
	c_knot[0].x = x;
	c_knot[0].y = y;
	c_knot[1].x=  ((640 / 2) - (400 / 2));
	c_knot[1].y=  480 - 70 - 30;
 
	clutter_effect_fade (effect_template, self->priv->title_group, 0xff, NULL, NULL);
	clutter_effect_fade (effect_template, self->priv->window_buttons_group, 0xff, NULL, NULL);
	clutter_effect_fade (effect_template, self->priv->controls_group, 0xff, NULL, NULL);
	g_object_unref (effect_template);
	return FALSE;
}
Beispiel #9
0
static void
mex_shell_paint (ClutterActor *actor)
{
  GList *c;
  MexShellPrivate *priv = MEX_SHELL (actor)->priv;

  CLUTTER_ACTOR_CLASS (mex_shell_parent_class)->paint (actor);

  for (c = priv->children; c; c = c->next)
    {
      gboolean do_paint;
      MexShellChildData *data = c->data;

      if (data->child == priv->presented)
        do_paint = TRUE;
      else if (data->start_animator)
        do_paint = TRUE;
      else if (clutter_timeline_is_playing (
                 clutter_animator_get_timeline (data->animator)))
        do_paint = TRUE;
      else
        do_paint = FALSE;

      if (do_paint)
        clutter_actor_paint (((MexShellChildData *)c->data)->child);

      if (data->start_animator)
        {
          clutter_animator_start (data->animator);
          data->start_animator = FALSE;
        }
    }
}
Beispiel #10
0
static void
mex_content_box_get_preferred_height (ClutterActor *actor,
                                      gfloat        for_width,
                                      gfloat       *min_height,
                                      gfloat       *pref_height)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv;
  gfloat info_h;

  clutter_actor_get_preferred_height (priv->tile, for_width, min_height,
                                      pref_height);

  if (!priv->extras_visible)
    return;

  if (pref_height)
    {
      clutter_actor_get_preferred_height (priv->info_panel, for_width, NULL,
                                          &info_h);
      if (clutter_timeline_is_playing (priv->timeline))
        *pref_height = *pref_height +
          (info_h * clutter_alpha_get_alpha (priv->alpha));
      else
        *pref_height = *pref_height + info_h;
    }
}
Beispiel #11
0
static void
layout_manager_real_end_animation (ClutterLayoutManager *manager)
{
    ClutterTimeline *timeline;
    ClutterAlpha *alpha;

    alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
    if (alpha == NULL)
        return;

    timeline = clutter_alpha_get_timeline (alpha);
    g_assert (timeline != NULL);

    if (clutter_timeline_is_playing (timeline))
        clutter_timeline_stop (timeline);

    g_signal_handlers_disconnect_by_func (timeline,
                                          G_CALLBACK (clutter_layout_manager_end_animation),
                                          manager);
    g_signal_handlers_disconnect_by_func (timeline,
                                          G_CALLBACK (clutter_layout_manager_layout_changed),
                                          manager);

    g_object_set_qdata (G_OBJECT (manager), quark_layout_alpha, NULL);

    clutter_layout_manager_layout_changed (manager);
}
Beispiel #12
0
static void
mx_expander_update (MxExpander *expander)
{
  MxExpanderPrivate *priv = expander->priv;

  if (priv->expanded)
    {
      clutter_actor_set_name (priv->arrow, "mx-expander-arrow-open");
      mx_stylable_set_style_class (MX_STYLABLE (expander), "open-expander");
    }
  /* closed state is set when animation is finished */

  if (!priv->child)
    return;

  /* setup and start the expansion animation */
  if (!priv->expanded)
    {
      clutter_actor_hide (priv->child);
      clutter_timeline_set_direction (priv->timeline,
                                      CLUTTER_TIMELINE_BACKWARD);
    }
  else
    {
      clutter_timeline_set_direction (priv->timeline,
                                      CLUTTER_TIMELINE_FORWARD);
    }


  if (!clutter_timeline_is_playing (priv->timeline))
    clutter_timeline_rewind (priv->timeline);

  clutter_timeline_start (priv->timeline);
}
Beispiel #13
0
static void
mex_content_box_get_preferred_width (ClutterActor *actor,
                                     gfloat        for_height,
                                     gfloat       *min_width,
                                     gfloat       *pref_width)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv;
  gfloat list_w;

  clutter_actor_get_preferred_width (priv->tile, for_height, min_width,
                                     pref_width);
  if (!priv->extras_visible)
    return;

  if (pref_width)
    {
      clutter_actor_get_preferred_width (priv->action_list, for_height, NULL,
                                         &list_w);

      if (clutter_timeline_is_playing (priv->timeline))
        *pref_width = *pref_width +
          (list_w * clutter_alpha_get_alpha (priv->alpha));
      else
        *pref_width = *pref_width + list_w;
    }
}
Beispiel #14
0
static gboolean
im_spinning_around (ClutterTimeline *time)
{
    if (!clutter_timeline_is_playing (timeline))
        clutter_timeline_start (timeline);
    return TRUE;
}
Beispiel #15
0
void
mx_toggle_set_active (MxToggle *toggle,
                      gboolean  active)
{
  MxTogglePrivate *priv;

  g_return_if_fail (MX_IS_TOGGLE (toggle));

  priv = toggle->priv;

  if (priv->active != active
      || (priv->position > 0 && priv->position < 1))
    {
      ClutterTimeline *timeline;

      priv->active = active;

      if (active)
        mx_stylable_set_style_pseudo_class (MX_STYLABLE (toggle), "checked");
      else
        mx_stylable_set_style_pseudo_class (MX_STYLABLE (toggle), NULL);

      g_object_notify (G_OBJECT (toggle), "active");


      /* don't run an animation if the actor is not mapped */
      if (!CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (toggle)))
        {
          priv->position = (active) ? 1 : 0;
          return;
        }

      timeline = clutter_alpha_get_timeline (priv->alpha);

      if (active)
        clutter_timeline_set_direction (timeline, CLUTTER_TIMELINE_FORWARD);
      else
        clutter_timeline_set_direction (timeline, CLUTTER_TIMELINE_BACKWARD);

      if (clutter_timeline_is_playing (timeline))
        return;

      clutter_timeline_rewind (timeline);

      if (priv->drag_offset > -1)
        {
          clutter_alpha_set_mode (priv->alpha, CLUTTER_LINEAR);
          clutter_timeline_advance (timeline, priv->position * 300);
        }
      else
        {
          clutter_alpha_set_mode (priv->alpha, CLUTTER_EASE_IN_OUT_CUBIC);
        }

      clutter_timeline_start (timeline);
    }
}
Beispiel #16
0
/**
 * clutter_timeline_get_delta:
 * @timeline: a #ClutterTimeline
 *
 * Retrieves the amount of time elapsed since the last
 * ClutterTimeline::new-frame signal.
 *
 * This function is only useful inside handlers for the ::new-frame
 * signal, and its behaviour is undefined if the timeline is not
 * playing.
 *
 * Return value: the amount of time in milliseconds elapsed since the
 * last frame
 *
 * Since: 0.6
 */
guint
clutter_timeline_get_delta (ClutterTimeline *timeline)
{
  g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0);

  if (!clutter_timeline_is_playing (timeline))
    return 0;

  return timeline->priv->msecs_delta;
}
static gboolean
key_pressed_cb (ClutterActor *actor,
                ClutterEvent *event,
                gpointer      user_data)
{
  ClutterState *transitions = CLUTTER_STATE (user_data);

  if (!clutter_timeline_is_playing (clutter_state_get_timeline (transitions)))
    next_state (transitions, NULL);

  return TRUE;
}
Beispiel #18
0
static void
mex_shell_child_data_free (MexShell *self, MexShellChildData *data)
{
  ClutterTimeline *timeline = clutter_animator_get_timeline (data->animator);

  if (clutter_timeline_is_playing (timeline))
    mex_shell_timeline_completed_cb (timeline, self);

  clutter_animator_remove_key (data->animator, NULL, NULL, -1);
  g_object_unref (data->animator);
  g_slice_free (MexShellChildData, data);
}
static gboolean
key_pressed_cb (ClutterActor *actor,
                ClutterEvent *event,
                gpointer      user_data)
{
  ClutterTimeline *timeline = CLUTTER_TIMELINE (user_data);

  if (!clutter_timeline_is_playing (timeline))
    clutter_timeline_start (timeline);

  return TRUE;
}
Beispiel #20
0
void
fluttr_viewer_show (FluttrViewer *viewer, gboolean show)
{
        FluttrViewerPrivate *priv;
        
        g_return_if_fail (FLUTTR_IS_VIEWER (viewer));
        priv = FLUTTR_VIEWER_GET_PRIVATE(viewer);
        
        priv->popping = show;
        if (show == TRUE)
        	clutter_actor_set_opacity (priv->texture, 0);
        if (!clutter_timeline_is_playing (priv->timeline))
        	clutter_timeline_start (priv->timeline);
}	
Beispiel #21
0
/* a key press either starts the timeline or reverses it */
static gboolean
key_pressed_cb (ClutterActor *actor,
                ClutterEvent *event,
                gpointer      user_data)
{
  State *state = (State *) user_data;

  if (clutter_timeline_is_playing (state->timeline))
    reverse_timeline (state->timeline);
  else
    clutter_timeline_start (state->timeline);

  return TRUE;
}
Beispiel #22
0
/* Public Functions */
static void
on_active_completed (ClutterActor *actor, gpointer data)
{
  AstroContactRowPrivate *priv;

  g_return_if_fail (ASTRO_IS_CONTACT_ROW (data));
  priv = ASTRO_CONTACT_ROW_GET_PRIVATE (data);

  if (clutter_timeline_is_playing (priv->bar_time))
    return;

   priv->bar_time = clutter_effect_fade (priv->bar_temp,
                       priv->bar,
                       255,
                       NULL, NULL);
}
static gboolean
red_button_press (ClutterActor *actor,
                  ClutterButtonEvent *event,
                  gpointer            data)
{
  GObject *timeline;

  g_print ("[*] Pressed `%s'\n", clutter_get_script_id (G_OBJECT (actor)));

  timeline = clutter_script_get_object (script, "main-timeline");
  g_assert (CLUTTER_IS_TIMELINE (timeline));

  if (!clutter_timeline_is_playing (CLUTTER_TIMELINE (timeline)))
    clutter_timeline_start (CLUTTER_TIMELINE (timeline));
  else
    clutter_timeline_pause (CLUTTER_TIMELINE (timeline));

  return TRUE;
}
/*
 * start the animation when a key is pressed;
 * see the signals recipe in the Script chapter for more details
 */
gboolean
foo_key_pressed_cb (ClutterActor *actor,
                    ClutterEvent *event,
                    gpointer      user_data)
{
  ClutterScript *script = CLUTTER_SCRIPT (user_data);

  ClutterAnimator *animator;
  clutter_script_get_objects (script,
                              "animator", &animator,
                              NULL);

  if (clutter_timeline_is_playing (clutter_animator_get_timeline (animator)))
    return FALSE;

  clutter_animator_start (animator);

  return TRUE;
}
static gboolean
mouse_moved(CurrentCallView *self)
{
    g_return_val_if_fail(IS_CURRENT_CALL_VIEW(self), FALSE);
    auto priv = CURRENT_CALL_VIEW_GET_PRIVATE(self);

    priv->time_last_mouse_motion = g_get_monotonic_time();

    // since the mouse moved, make sure the controls are shown
    if (clutter_timeline_get_direction(CLUTTER_TIMELINE(priv->fade_info)) == CLUTTER_TIMELINE_FORWARD) {
        clutter_timeline_set_direction(CLUTTER_TIMELINE(priv->fade_info), CLUTTER_TIMELINE_BACKWARD);
        clutter_timeline_set_direction(CLUTTER_TIMELINE(priv->fade_controls), CLUTTER_TIMELINE_BACKWARD);
        if (!clutter_timeline_is_playing(CLUTTER_TIMELINE(priv->fade_info))) {
            clutter_timeline_rewind(CLUTTER_TIMELINE(priv->fade_info));
            clutter_timeline_rewind(CLUTTER_TIMELINE(priv->fade_controls));
            clutter_timeline_start(CLUTTER_TIMELINE(priv->fade_info));
            clutter_timeline_start(CLUTTER_TIMELINE(priv->fade_controls));
        }
    }

    return FALSE; // propogate event
}
Beispiel #26
0
static gboolean                 
on_thread_ok_idle (FluttrViewer *viewer)
{
        FluttrViewerPrivate *priv;
        GdkPixbuf *pixbuf;
        
        g_return_val_if_fail (FLUTTR_IS_VIEWER (viewer), FALSE);
        priv = FLUTTR_VIEWER_GET_PRIVATE(viewer);
        
        close_message_window (viewer);
        
        /* Get pixbuf from worker */
        g_object_get (G_OBJECT (priv->worker), "pixbuf", &pixbuf, NULL);
        priv->pixbuf = pixbuf;        
        
	if (!clutter_timeline_is_playing (priv->swap_time))
        	clutter_timeline_start (priv->swap_time);
        
        g_signal_emit (viewer, _viewer_signals[SUCCESSFUL], 0, priv->worker);
        
        return FALSE;
}
Beispiel #27
0
void            
astro_contact_row_set_active (AstroContactRow *row,
                              gboolean         active)
{
  AstroContactRowPrivate *priv;
  static ClutterTimeline *active_time = NULL;
 
  g_return_if_fail (ASTRO_IS_CONTACT_ROW (row));
  priv = row->priv;

  if (priv->active == active)
    return;
   
  priv->active = active;

  if (active)
    {
      active_time = clutter_effect_fade (priv->active_temp,
                                         priv->bg,
                                         255,
                                         on_active_completed, row);
      clutter_timeline_start (priv->active_time);    
    }
  else
    {
      active_time = clutter_effect_fade (priv->active_temp,
                                         priv->bg,
                                         0,
                                         on_inactive_completed, row);
      if (clutter_timeline_is_playing (priv->bar_time))
        clutter_timeline_stop (priv->bar_time);

      priv->bar_time = clutter_effect_fade (priv->active_temp,
                                     priv->bar,
                                     0,
                                     NULL, NULL);
    }
}
Beispiel #28
0
void
mex_tile_set_important (MexTile  *tile,
                        gboolean  important)
{
  MexTilePrivate *priv;

  g_return_if_fail (MEX_IS_TILE (tile));

  priv = tile->priv;
  if (priv->important != important)
    {
      priv->important = important;

      g_object_notify (G_OBJECT (tile), "important");

      mx_stylable_set_style_class (MX_STYLABLE (tile),
                                   important ? "Important" : NULL);

      if (clutter_timeline_is_playing (priv->timeline))
        clutter_timeline_set_direction (priv->timeline, important ?
                                        CLUTTER_TIMELINE_FORWARD :
                                        CLUTTER_TIMELINE_BACKWARD);
      else
        {
          if (CLUTTER_ACTOR_IS_MAPPED (tile))
            {
              clutter_timeline_rewind (priv->timeline);
              clutter_timeline_start (priv->timeline);
            }
          else
            {
              clutter_timeline_advance (priv->timeline, DURATION);
              mex_tile_important_new_frame_cb (priv->timeline, 0, tile);
              mex_tile_timeline_completed_cb (priv->timeline, tile);
            }
        }
    }
}
Beispiel #29
0
static void
on_key_release_event (ClutterStage *stage,
                      ClutterEvent *event,
                      gpointer      null)
{
    static gint i = 0;

    switch (clutter_key_event_symbol ((ClutterKeyEvent*)event))
    {
    case CLUTTER_Escape:
        clutter_main_quit ();
        break;
    case CLUTTER_Left:
        i--;
        if (i == 0)
            i = 359;
        clutter_actor_set_rotation (CLUTTER_ACTOR (stage), CLUTTER_Y_AXIS, i,
                                    CLUTTER_STAGE_WIDTH ()/2,
                                    0,
                                    CLUTTER_STAGE_HEIGHT ());
        break;
    case CLUTTER_Right:
        i++;
        if (i == 360)
            i = 0;
        clutter_actor_set_rotation (CLUTTER_ACTOR (stage), CLUTTER_Y_AXIS, i,
                                    CLUTTER_STAGE_WIDTH ()/2,
                                    0,
                                    CLUTTER_STAGE_HEIGHT ());
        break;
    case CLUTTER_Up:
        if (!clutter_timeline_is_playing (timeline))
            clutter_timeline_start (timeline);
        break;
    default:
        break;
    }
}
static gboolean
timeout_check_last_motion_event(CurrentCallView *self)
{
    g_return_val_if_fail(IS_CURRENT_CALL_VIEW(self), G_SOURCE_REMOVE);
    auto priv = CURRENT_CALL_VIEW_GET_PRIVATE(self);

    auto current_time = g_get_monotonic_time();
    if (current_time - priv->time_last_mouse_motion >= CONTROLS_FADE_TIMEOUT) {
        // timeout has passed, hide the controls
        if (clutter_timeline_get_direction(CLUTTER_TIMELINE(priv->fade_info)) == CLUTTER_TIMELINE_BACKWARD) {
            clutter_timeline_set_direction(CLUTTER_TIMELINE(priv->fade_info), CLUTTER_TIMELINE_FORWARD);
            clutter_timeline_set_direction(CLUTTER_TIMELINE(priv->fade_controls), CLUTTER_TIMELINE_FORWARD);
            if (!clutter_timeline_is_playing(CLUTTER_TIMELINE(priv->fade_info))) {
                clutter_timeline_rewind(CLUTTER_TIMELINE(priv->fade_info));
                clutter_timeline_rewind(CLUTTER_TIMELINE(priv->fade_controls));
                clutter_timeline_start(CLUTTER_TIMELINE(priv->fade_info));
                clutter_timeline_start(CLUTTER_TIMELINE(priv->fade_controls));
            }
        }
    }

    return G_SOURCE_CONTINUE;
}