示例#1
0
/*
 * The Nature of Maximize operation is such that it is difficult to do a visual
 * effect that would work well. Scaling, the obvious effect, does not work that
 * well, because at the end of the effect we end up with window content bigger
 * and differently laid out than in the real window; this is a proof concept.
 *
 * (Something like a sound would be more appropriate.)
 */
static void
maximize (MetaPlugin *plugin,
          MetaWindowActor *window_actor,
          gint end_x, gint end_y, gint end_width, gint end_height)
{
  MetaWindowType type;
  ClutterActor *actor = CLUTTER_ACTOR (window_actor);
  MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);

  gdouble  scale_x    = 1.0;
  gdouble  scale_y    = 1.0;
  gfloat   anchor_x   = 0;
  gfloat   anchor_y   = 0;

  type = meta_window_get_window_type (meta_window);

  if (type == META_WINDOW_NORMAL)
    {
      ClutterAnimation *animation;
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
      ActorPrivate *apriv = get_actor_private (window_actor);
      gfloat width, height;
      gfloat x, y;

      apriv->is_maximized = TRUE;

      clutter_actor_get_size (actor, &width, &height);
      clutter_actor_get_position (actor, &x, &y);

      /*
       * Work out the scale and anchor point so that the window is expanding
       * smoothly into the target size.
       */
      scale_x = (gdouble)end_width / (gdouble) width;
      scale_y = (gdouble)end_height / (gdouble) height;

      anchor_x = (gdouble)(x - end_x)*(gdouble)width /
        ((gdouble)(end_width - width));
      anchor_y = (gdouble)(y - end_y)*(gdouble)height /
        ((gdouble)(end_height - height));

      clutter_actor_move_anchor_point (actor, anchor_x, anchor_y);

      animation = clutter_actor_animate (actor,
                                         CLUTTER_EASE_IN_SINE,
                                         MAXIMIZE_TIMEOUT,
                                         "scale-x", scale_x,
                                         "scale-y", scale_y,
                                         NULL);
      apriv->tml_maximize = clutter_animation_get_timeline (animation);
      data->plugin = plugin;
      data->actor = actor;
      g_signal_connect (apriv->tml_maximize, "completed",
                        G_CALLBACK (on_maximize_effect_complete),
                        data);
      return;
    }

  meta_plugin_maximize_completed (plugin, window_actor);
}
示例#2
0
static void
stepper_move_on (StScrollBarPrivate *priv,
                 gint                mode)
{
  ClutterAnimation *a;
  ClutterTimeline *t;
  GValue v = { 0, };
  double value, inc;

  a = g_object_new (CLUTTER_TYPE_ANIMATION,
                    "object", priv->adjustment,
                    "duration", (guint)(PAGING_SUBSEQUENT_REPEAT_TIMEOUT * st_slow_down_factor),
                    "mode", mode,
                    NULL);

  g_signal_connect (a, "completed", G_CALLBACK (stepper_animation_completed_cb),
                    NULL);

  g_object_get (priv->adjustment,
                "step-increment", &inc,
                "value", &value,
                NULL);

  if (priv->stepper_forward)
    value = value + inc;
  else
    value = value - inc;

  g_value_init (&v, G_TYPE_DOUBLE);
  g_value_set_double (&v, value);
  clutter_animation_bind (a, "value", &v);

  t = clutter_animation_get_timeline (a);
  clutter_timeline_start (t);
}
示例#3
0
/*
 * Simple TV-out like effect.
 */
static void
destroy (MetaPlugin *plugin, MetaWindowActor *window_actor)
{
  MetaWindowType type;
  ClutterActor *actor = CLUTTER_ACTOR (window_actor);
  MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);

  type = meta_window_get_window_type (meta_window);

  if (type == META_WINDOW_NORMAL)
    {
      ClutterAnimation *animation;
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
      ActorPrivate *apriv = get_actor_private (window_actor);

      animation = clutter_actor_animate (actor,
                                         CLUTTER_EASE_OUT_QUAD,
                                         DESTROY_TIMEOUT,
                                         "opacity", 0,
                                         "scale-x", 0.8,
                                         "scale-y", 0.8,
                                         NULL);
      apriv->tml_destroy = clutter_animation_get_timeline (animation);
      data->plugin = plugin;
      data->actor = actor;
      g_signal_connect (apriv->tml_destroy, "completed",
                        G_CALLBACK (on_destroy_effect_complete),
                        data);
    }
  else
    meta_plugin_destroy_completed (plugin, window_actor);
}
示例#4
0
/*
 * Simple minimize handler: it applies a scale effect (which must be reversed on
 * completion).
 */
static void
minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
{
  MetaWindowType type;
  MetaRectangle icon_geometry;
  MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);
  ClutterActor *actor  = CLUTTER_ACTOR (window_actor);


  type = meta_window_get_window_type (meta_window);

  if (!meta_window_get_icon_geometry(meta_window, &icon_geometry))
    {
      icon_geometry.x = 0;
      icon_geometry.y = 0;
    }

  if (type == META_WINDOW_NORMAL)
    {
      ClutterAnimation *animation;
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
      ActorPrivate *apriv = get_actor_private (window_actor);

      apriv->is_minimized = TRUE;

      clutter_actor_move_anchor_point_from_gravity (actor,
                                                    CLUTTER_GRAVITY_CENTER);

      animation = clutter_actor_animate (actor,
                                         CLUTTER_EASE_IN_SINE,
                                         MINIMIZE_TIMEOUT,
                                         "scale-x", 0.0,
                                         "scale-y", 0.0,
                                         "x", (double)icon_geometry.x,
                                         "y", (double)icon_geometry.y,
                                         NULL);
      apriv->tml_minimize = clutter_animation_get_timeline (animation);
      data->plugin = plugin;
      data->actor = actor;
      g_signal_connect (apriv->tml_minimize, "completed",
                        G_CALLBACK (on_minimize_effect_complete),
                        data);

    }
  else
    meta_plugin_minimize_completed (plugin, window_actor);
}
static void
_expire_notification (MexNotificationArea *area,
                      MexNotification     *notification,
                      ClutterActor        *actor)
{
    MexNotificationAreaPrivate *priv = GET_PRIVATE (area);
    ClutterAnimation *animation;
    ClutterActor *last_top_actor;

    g_hash_table_remove (priv->notification_to_timeout_id, notification);
    g_hash_table_remove (priv->notification_to_actor, notification);

    g_queue_remove_all (priv->stack, actor);

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

    g_signal_connect_after (animation,
                            "completed",
                            (GCallback)_animation_completed_cb,
                            actor);

    /* Check if there is already something else in the stack. If so fade that
     * back in ... */
    last_top_actor = g_queue_peek_head (priv->stack);

    if (last_top_actor)
    {
        ClutterTimeline *timeline;

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

        timeline = clutter_animation_get_timeline (animation);

        clutter_timeline_set_delay (timeline, 450);
    }
}
示例#6
0
/*
 * Simple map handler: it applies a scale effect which must be reversed on
 * completion).
 */
static void
map (MetaPlugin *plugin, MetaWindowActor *window_actor)
{
  MetaWindowType type;
  ClutterActor *actor = CLUTTER_ACTOR (window_actor);
  MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);

  type = meta_window_get_window_type (meta_window);

  if (type == META_WINDOW_NORMAL)
    {
      ClutterAnimation *animation;
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
      ActorPrivate *apriv = get_actor_private (window_actor);

      clutter_actor_set_pivot_point (actor, 0.5, 0.5);
      clutter_actor_set_opacity (actor, 0);
      clutter_actor_set_scale (actor, 0.5, 0.5);
      clutter_actor_show (actor);

      animation = clutter_actor_animate (actor,
                                         CLUTTER_EASE_OUT_QUAD,
                                         MAP_TIMEOUT,
                                         "opacity", 255,
                                         "scale-x", 1.0,
                                         "scale-y", 1.0,
                                         NULL);
      apriv->tml_map = clutter_animation_get_timeline (animation);
      data->actor = actor;
      data->plugin = plugin;
      g_signal_connect (apriv->tml_map, "completed",
                        G_CALLBACK (on_map_effect_complete),
                        data);
    }
  else
    meta_plugin_map_completed (plugin, window_actor);
}
示例#7
0
/*
 * Simple TV-out like effect.
 */
static void
destroy (MetaPlugin *plugin, MetaWindowActor *window_actor)
{
  MetaWindowType type;
  ClutterActor *actor = CLUTTER_ACTOR (window_actor);
  MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);

  type = meta_window_get_window_type (meta_window);

  if (type == META_WINDOW_NORMAL || type == META_WINDOW_DIALOG ||
      type == META_WINDOW_MODAL_DIALOG)
  {
      ClutterAnimation *animation;
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
      ActorPrivate *apriv = get_actor_private (window_actor);

      clutter_actor_move_anchor_point_from_gravity (actor,
                                                    CLUTTER_GRAVITY_CENTER);

      animation = clutter_actor_animate (actor,
                                         CLUTTER_EASE_IN_SINE,
                                         DESTROY_TIMEOUT,
                                         "scale-x", DESTROY_SCALE,
                                         "scale-y", DESTROY_SCALE,
                                         "opacity", 0,
                                         NULL);
      apriv->tml_destroy = clutter_animation_get_timeline (animation);
      data->plugin = plugin;
      data->actor = actor;
      g_signal_connect (apriv->tml_destroy, "completed",
                        G_CALLBACK (on_destroy_effect_complete),
                        data);
    }
  else
    meta_plugin_destroy_completed (plugin, window_actor);
}
示例#8
0
static gboolean
trough_paging_cb (StScrollBar *self)
{
  gfloat handle_pos, event_pos, tx, ty;
  gdouble value;
  gdouble page_increment;
  gboolean ret;

  gulong mode;
  ClutterAnimation *a;
  GValue v = { 0, };
  ClutterTimeline *t;

  if (self->priv->paging_event_no == 0)
    {
      /* Scroll on after initial timeout. */
      mode = CLUTTER_EASE_OUT_CUBIC;
      ret = FALSE;
      self->priv->paging_event_no = 1;
      self->priv->paging_source_id = g_timeout_add (
        PAGING_INITIAL_REPEAT_TIMEOUT,
        (GSourceFunc) trough_paging_cb,
        self);
    }
  else if (self->priv->paging_event_no == 1)
    {
      /* Scroll on after subsequent timeout. */
      ret = FALSE;
      mode = CLUTTER_EASE_IN_CUBIC;
      self->priv->paging_event_no = 2;
      self->priv->paging_source_id = g_timeout_add (
        PAGING_SUBSEQUENT_REPEAT_TIMEOUT,
        (GSourceFunc) trough_paging_cb,
        self);
    }
  else
    {
      /* Keep scrolling. */
      ret = TRUE;
      mode = CLUTTER_LINEAR;
      self->priv->paging_event_no++;
    }

  /* Do the scrolling */
  st_adjustment_get_values (self->priv->adjustment,
                            &value, NULL, NULL,
                            NULL, &page_increment, NULL);

  if (self->priv->vertical)
    handle_pos = clutter_actor_get_y (self->priv->handle);
  else
    handle_pos = clutter_actor_get_x (self->priv->handle);

  clutter_actor_transform_stage_point (CLUTTER_ACTOR (self->priv->trough),
                                       self->priv->move_x,
                                       self->priv->move_y,
                                       &tx, &ty);

  if (self->priv->vertical)
    event_pos = ty;
  else
    event_pos = tx;

  if (event_pos > handle_pos)
    {
      if (self->priv->paging_direction == NONE)
        {
          /* Remember direction. */
          self->priv->paging_direction = DOWN;
        }
      if (self->priv->paging_direction == UP)
        {
          /* Scrolled far enough. */
          return FALSE;
        }
      value += page_increment;
    }
  else
    {
      if (self->priv->paging_direction == NONE)
        {
          /* Remember direction. */
          self->priv->paging_direction = UP;
        }
      if (self->priv->paging_direction == DOWN)
        {
          /* Scrolled far enough. */
          return FALSE;
        }
      value -= page_increment;
    }

  if (self->priv->paging_animation)
    {
      clutter_animation_completed (self->priv->paging_animation);
    }

  /* FIXME: Creating a new animation for each scroll is probably not the best
  * idea, but it's a lot less involved than extenind the current animation */
  a = self->priv->paging_animation = g_object_new (CLUTTER_TYPE_ANIMATION,
                                                   "object", self->priv->adjustment,
                                                   "duration", (guint)(PAGING_SUBSEQUENT_REPEAT_TIMEOUT * st_slow_down_factor),
                                                   "mode", mode,
                                                   NULL);
  g_value_init (&v, G_TYPE_DOUBLE);
  g_value_set_double (&v, value);
  clutter_animation_bind (self->priv->paging_animation, "value", &v);
  t = clutter_animation_get_timeline (self->priv->paging_animation);
  g_signal_connect (a, "completed", G_CALLBACK (animation_completed_cb),
                    self->priv);
  clutter_timeline_start (t);

  return ret;
}
示例#9
0
/*
 * Simple map handler: it applies a scale effect which must be reversed on
 * completion).
 */
static void
map (MetaPlugin *plugin, MetaWindowActor *window_actor)
{
  MetaWindowType type;
  ClutterActor *actor = CLUTTER_ACTOR (window_actor);
  MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);

  type = meta_window_get_window_type (meta_window);

  if (type == META_WINDOW_NORMAL || type == META_WINDOW_DIALOG ||
      type == META_WINDOW_MODAL_DIALOG)
  {
      ClutterAnimation *animation;
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
      ActorPrivate *apriv = get_actor_private (window_actor);

      clutter_actor_move_anchor_point_from_gravity (actor,
                                                    CLUTTER_GRAVITY_CENTER);
      clutter_actor_set_scale (actor, MAP_SCALE, MAP_SCALE);
      clutter_actor_set_opacity (actor, 0);
      clutter_actor_show (actor);

      animation = clutter_actor_animate (actor,
                                         CLUTTER_EASE_IN_SINE,
                                         MAP_TIMEOUT,
                                         "scale-x", 1.0,
                                         "scale-y", 1.0,
                                         "opacity", 255,
                                         NULL);
      apriv->tml_map = clutter_animation_get_timeline (animation);
      data->actor = actor;
      data->plugin = plugin;
      g_signal_connect (apriv->tml_map, "completed",
                        G_CALLBACK (on_map_effect_complete),
                        data);

      apriv->is_minimized = FALSE;

  } else if (type == META_WINDOW_DOCK)
  {
      /* For context menus (popup/dropdown) we fade the menu in */
      ClutterAnimation *animation;
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
      ActorPrivate *apriv = get_actor_private (window_actor);

      clutter_actor_set_opacity (actor, 0);
      clutter_actor_show (actor);

      animation = clutter_actor_animate (actor,
                                         CLUTTER_EASE_IN_SINE,
                                         MAP_TIMEOUT,
                                         "opacity", 255,
                                         NULL);
      apriv->tml_map = clutter_animation_get_timeline (animation);
      data->actor = actor;
      data->plugin = plugin;
      g_signal_connect (apriv->tml_map, "completed",
                        G_CALLBACK (on_map_effect_complete),
                        data);

      apriv->is_minimized = FALSE;
  } else
    meta_plugin_map_completed (plugin, window_actor);
}
示例#10
0
static void
switch_workspace (MetaPlugin *plugin,
                  gint from, gint to,
                  MetaMotionDirection direction)
{
  MetaScreen *screen;
  MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
  GList        *l;
  ClutterActor *workspace0  = clutter_group_new ();
  ClutterActor *workspace1  = clutter_group_new ();
  ClutterActor *stage;
  int           screen_width, screen_height;
  ClutterAnimation *animation;

  screen = meta_plugin_get_screen (plugin);
  stage = meta_get_stage_for_screen (screen);

  meta_screen_get_size (screen,
                        &screen_width,
                        &screen_height);

  clutter_actor_set_anchor_point (workspace1,
                                  screen_width,
                                  screen_height);
  clutter_actor_set_position (workspace1,
                              screen_width,
                              screen_height);

  clutter_actor_set_scale (workspace1, 0.0, 0.0);

  clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace1);
  clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace0);

  if (from == to)
    {
      meta_plugin_switch_workspace_completed (plugin);
      return;
    }

  l = g_list_last (meta_get_window_actors (screen));

  while (l)
    {
      MetaWindowActor *window_actor = l->data;
      MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
      MetaWorkspace   *workspace;
      ActorPrivate    *apriv	    = get_actor_private (window_actor);
      ClutterActor    *actor	    = CLUTTER_ACTOR (window_actor);
      gint             win_workspace;

      workspace = meta_window_get_workspace (window);
      win_workspace = meta_workspace_index (workspace);

      if (win_workspace == to || win_workspace == from)
        {
          apriv->orig_parent = clutter_actor_get_parent (actor);

          clutter_actor_reparent (actor,
				  win_workspace == to ? workspace1 : workspace0);
          clutter_actor_show_all (actor);
          clutter_actor_raise_top (actor);
        }
      else if (win_workspace < 0)
        {
          /* Sticky window */
          apriv->orig_parent = NULL;
        }
      else
        {
          /* Window on some other desktop */
          clutter_actor_hide (actor);
          apriv->orig_parent = NULL;
        }

      l = l->prev;
    }

  priv->desktop1 = workspace0;
  priv->desktop2 = workspace1;

  animation = clutter_actor_animate (workspace0, CLUTTER_EASE_IN_SINE,
                                     SWITCH_TIMEOUT,
                                     "scale-x", 1.0,
                                     "scale-y", 1.0,
                                     NULL);
  priv->tml_switch_workspace1 = clutter_animation_get_timeline (animation);
  g_signal_connect (priv->tml_switch_workspace1,
                    "completed",
                    G_CALLBACK (on_switch_workspace_effect_complete),
                    plugin);

  animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
                                     SWITCH_TIMEOUT,
                                     "scale-x", 0.0,
                                     "scale-y", 0.0,
                                     NULL);
  priv->tml_switch_workspace2 = clutter_animation_get_timeline (animation);
}
示例#11
0
  g_object_get (adjustment,
                "page-increment", &step,
                "value", &value,
                NULL);
  clutter_animation_set_object (priv->animation,
                                G_OBJECT (adjustment));

  if (event->direction % 2)
    /* up, left (1, 3) */
    final = value + step;
  else
    /* down, right (2, 4) */
    final = value - step;

  timeline = clutter_animation_get_timeline (priv->animation);
  interval = clutter_animation_get_interval (priv->animation, "value");

  if (!interval)
    {
      interval = clutter_interval_new (G_TYPE_DOUBLE, value, final);
      clutter_animation_bind_interval (priv->animation, "value",
                                       interval);
      clutter_timeline_start (timeline);

    }
  else
    {
      GValue *end, *start;

      end = clutter_interval_peek_final_value (interval);
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));
    }
}