static void
mex_telepathy_channel_create_busy_box (MexTelepathyChannel *self)
{
  MexTelepathyChannelPrivate *priv = MEX_TELEPATHY_CHANNEL (self)->priv;

  ClutterActor *calling_padding;
  ClutterActor *calling_box;
  ClutterActor *spinner;
  ClutterActor *stack;

  priv->busy_label = mx_label_new();
  mx_label_set_y_align (MX_LABEL (priv->busy_label), MX_ALIGN_MIDDLE);
  mx_label_set_x_align (MX_LABEL (priv->busy_label), MX_ALIGN_MIDDLE);

  spinner = mx_spinner_new ();

  calling_box = mx_box_layout_new ();

  mx_box_layout_add_actor_with_properties (MX_BOX_LAYOUT (calling_box),
                                           priv->busy_label,
                                           0,
                                           "expand",
                                           TRUE,
                                           "x-align",
                                           MX_ALIGN_START,
                                           "x-fill",
                                           TRUE,
                                           NULL);

  mx_box_layout_add_actor_with_properties (MX_BOX_LAYOUT (calling_box),
                                           spinner,
                                           1,
                                           "expand",
                                           TRUE,
                                           "x-align",
                                           MX_ALIGN_END,
                                           "x-fill",
                                           FALSE,
                                           NULL);

  priv->busy_box = mx_frame_new ();
  clutter_actor_set_width (CLUTTER_ACTOR (priv->busy_box), 475);
  mx_stylable_set_style_class (MX_STYLABLE (priv->busy_box),
                               "CallingFrameBorder");
  calling_padding = mx_frame_new ();
  mx_stylable_set_style_class (MX_STYLABLE (calling_padding),
                               "CallingFrame");
  mx_bin_set_child (MX_BIN (priv->busy_box), calling_padding);
  mx_bin_set_fill (MX_BIN (priv->busy_box), TRUE, TRUE);
  mx_bin_set_child (MX_BIN (calling_padding), calling_box);
  mx_bin_set_fill (MX_BIN (calling_padding), TRUE, TRUE);

  stack = mx_window_get_child (mex_get_main_window ());
  clutter_container_add (CLUTTER_CONTAINER (stack), priv->busy_box, NULL);
  mx_stack_child_set_x_fill (MX_STACK (stack), priv->busy_box, FALSE);
  mx_stack_child_set_y_fill (MX_STACK (stack), priv->busy_box, FALSE);
}
static void
mex_telepathy_channel_create_video_page (MexTelepathyChannel *self)
{
  MexTelepathyChannelPrivate *priv = MEX_TELEPATHY_CHANNEL (self)->priv;

  /* Create the widgets to place */
  mex_telepathy_channel_create_toolbar (self);
  mex_telepathy_channel_create_preview (self);
  mex_telepathy_channel_create_busy_box (self);
  mex_telepathy_channel_create_incoming_video (self);

  /* Top container */
  priv->video_call_page = mx_stack_new ();

  clutter_container_add (CLUTTER_CONTAINER (priv->video_call_page),
                         priv->full_frame,
                         priv->preview_area,
                         priv->toolbar_area,
                         NULL);

  /* Arrange the preview video area on the page */
  mx_stack_child_set_x_align (MX_STACK (priv->video_call_page),
                              priv->preview_area,
                              MX_ALIGN_END);

  mx_stack_child_set_y_align (MX_STACK (priv->video_call_page),
                              priv->preview_area,
                              MX_ALIGN_START);

  mx_stack_child_set_x_fill (MX_STACK (priv->video_call_page),
                             priv->preview_area,
                             FALSE);

  mx_stack_child_set_y_fill (MX_STACK (priv->video_call_page),
                             priv->preview_area,
                             FALSE);

  /* Arrange the incoming video area on the page */
  mx_stack_child_set_x_fill (MX_STACK (priv->video_call_page),
                             priv->full_frame,
                             FALSE);

  mx_stack_child_set_y_fill (MX_STACK (priv->video_call_page),
                             priv->full_frame,
                             FALSE);

  /* Arrange the toolbar area on the page */
  mx_stack_child_set_x_align (MX_STACK (priv->video_call_page),
                              priv->toolbar_area,
                              MX_ALIGN_MIDDLE);

  mx_stack_child_set_y_align (MX_STACK (priv->video_call_page),
                              priv->toolbar_area,
                              MX_ALIGN_END);

  mx_stack_child_set_x_fill (MX_STACK (priv->video_call_page),
                             priv->toolbar_area,
                             TRUE);

  mx_stack_child_set_y_fill (MX_STACK (priv->video_call_page),
                             priv->toolbar_area,
                             FALSE);

  /* Connect to hide signals. */
  g_signal_connect (priv->video_call_page,
                    "hide",
                    G_CALLBACK (mex_telepathy_channel_on_video_closed),
                    self);

  /* Connect to show signals. */
  g_signal_connect (priv->video_call_page,
                    "show",
                    G_CALLBACK (mex_telepathy_channel_on_video_shown),
                    self);

  if (priv->show_page)
    {
      g_signal_emit (self,
                     mex_telepathy_channel_signals[SHOW_ACTOR],
                     0,
                     g_object_ref (priv->video_call_page));
      clutter_actor_show (priv->busy_box);
      clutter_actor_raise_top (priv->busy_box);
      priv->show_page = FALSE;
    }
}
static void
_source_notification_added_cb (MexNotificationSource *source,
                               MexNotification       *notification,
                               MexNotificationArea   *area)
{
    MexNotificationAreaPrivate *priv = GET_PRIVATE (area);
    ClutterActor *actor;
    ClutterActor *last_top_actor;
    ClutterAnimation *animation;

    actor = _make_notification_actor (notification);

    g_hash_table_insert (priv->notification_to_actor,
                         notification,
                         actor);

    clutter_container_add_actor (CLUTTER_CONTAINER (area),
                                 actor);
    mx_stack_child_set_x_fill (MX_STACK (area), actor, FALSE);
    mx_stack_child_set_y_fill (MX_STACK (area), actor, FALSE);
    mx_stack_child_set_x_align (MX_STACK (area), actor, MX_ALIGN_MIDDLE);
    mx_stack_child_set_y_align (MX_STACK (area), actor, MX_ALIGN_MIDDLE);

    /* Get the last notification since we want to fade that out */
    last_top_actor = g_queue_peek_head (priv->stack);

    g_queue_push_head (priv->stack, actor);

    clutter_container_raise_child (CLUTTER_CONTAINER (area),
                                   actor,
                                   last_top_actor);



    /* Fade out old notification */
    if (last_top_actor)
    {
        clutter_actor_animate (last_top_actor,
                               CLUTTER_EASE_OUT_QUAD,
                               350,
                               "opacity", 0x00,
                               NULL);
    }

    clutter_actor_set_opacity (actor, 0);
    animation = clutter_actor_animate (actor,
                                       CLUTTER_EASE_OUT_QUAD,
                                       350,
                                       "opacity", 0xff,
                                       NULL);

    /* Delay new notification fade in if we had an old one */
    if (last_top_actor)
    {
        ClutterTimeline *timeline;

        timeline = clutter_animation_get_timeline (animation);

        clutter_timeline_set_delay (timeline, 450);
    }

    g_object_set_data (G_OBJECT (actor),
                       "notification-area",
                       area);
    g_object_set_data (G_OBJECT (actor),
                       "notification",
                       notification);

    if (notification->duration > 0)
    {
        guint timeout_id =
            g_timeout_add_seconds (notification->duration,
                                   (GSourceFunc)_notification_timeout_cb,
                                   actor);

        g_hash_table_insert (priv->notification_to_timeout_id,
                             notification,
                             GINT_TO_POINTER (timeout_id));
    }
}