Ejemplo n.º 1
0
static void
mex_content_box_get_property (GObject    *object,
                              guint       property_id,
                              GValue     *value,
                              GParamSpec *pspec)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv;
  gint int_value;

  switch (property_id)
    {
    case PROP_OPEN:
      g_value_set_boolean (value, MEX_CONTENT_BOX (object)->priv->is_open);
      break;

    case PROP_IMPORTANT:
      g_value_set_boolean (value,
                           mex_content_box_get_important (MEX_CONTENT_BOX (object)));
      break;

    case PROP_THUMB_WIDTH:
      g_object_get (priv->tile, "thumb-width", &int_value, NULL);
      g_value_set_int (value, int_value);
      break;

    case PROP_ACTION_LIST_WIDTH:
      g_value_set_int (value, clutter_actor_get_width (priv->action_list));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    }
}
Ejemplo n.º 2
0
static void
mex_content_box_set_property (GObject      *object,
                              guint         property_id,
                              const GValue *value,
                              GParamSpec   *pspec)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv;
  gint int_value;

  switch (property_id)
    {
    case PROP_IMPORTANT:
      mex_content_box_set_important (MEX_CONTENT_BOX (object),
                                     g_value_get_boolean (value));
      break;

    case PROP_THUMB_WIDTH:
      int_value = g_value_get_int (value);
      if (int_value > 0)
        g_object_set (priv->tile,
                      "thumb-width", int_value,
                      "thumb-height", (int) (int_value * DEFAULT_THUMB_RATIO),
                      NULL);
      break;

    case PROP_ACTION_LIST_WIDTH:
      clutter_actor_set_width (priv->action_list, g_value_get_int (value));
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    }
}
Ejemplo n.º 3
0
static MxFocusable*
mex_content_box_move_focus (MxFocusable      *focusable,
                            MxFocusDirection  direction,
                            MxFocusable      *from)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (focusable)->priv;
  MxFocusable *result = NULL;

  if (priv->is_open)
    {
      if (direction == MX_FOCUS_DIRECTION_RIGHT &&
          (ClutterActor *) from != priv->action_list)
        result = mx_focusable_accept_focus (MX_FOCUSABLE (priv->action_list), 0);
      else if (direction == MX_FOCUS_DIRECTION_LEFT &&
               (ClutterActor *) from != priv->tile)
        result = mx_focusable_accept_focus (MX_FOCUSABLE (priv->tile), 0);

      if (result == NULL)
        {
          /* close the content box if it is open */
          if (priv->is_open && !priv->is_closing)
            mex_content_box_toggle_open (MEX_CONTENT_BOX (focusable));
        }
    }

  return result;
}
Ejemplo n.º 4
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;
    }
}
Ejemplo n.º 5
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;
    }
}
Ejemplo n.º 6
0
static void
mex_content_box_dispose (GObject *object)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv;
  GList *l;

  if (priv->bindings)
    {
      for (l = priv->bindings; l; l = l->next)
        g_object_unref (l->data);

      g_list_free (priv->bindings);
      priv->bindings = NULL;
    }

  if (priv->content)
    {
      g_object_unref (priv->content);
      priv->content = NULL;
    }

  if (priv->model)
    {
      g_object_unref (priv->model);
      priv->model = NULL;
    }

  G_OBJECT_CLASS (mex_content_box_parent_class)->dispose (object);
}
Ejemplo n.º 7
0
static void
mex_content_box_get_property (GObject    *object,
                              guint       property_id,
                              GValue     *value,
                              GParamSpec *pspec)
{
  MexContentBox *box = MEX_CONTENT_BOX (object);
  MexContentBoxPrivate *priv = box->priv;

  switch (property_id)
    {
    case PROP_MEDIA_URL:
      g_value_set_string (value, priv->media_url);
      break;

    case PROP_LOGO_URL:
      g_value_set_string (value, priv->logo_url);
      break;

    case PROP_THUMB_WIDTH:
      g_value_set_int (value, priv->thumb_width);
      break;

    case PROP_THUMB_HEIGHT:
      g_value_set_int (value, priv->thumb_height);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    }
}
Ejemplo n.º 8
0
static void
mex_content_box_paint (ClutterActor *actor)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv;
  gboolean clipped = FALSE;

  CLUTTER_ACTOR_CLASS (mex_content_box_parent_class)->paint (actor);

  if (G_UNLIKELY (priv->clip_to_allocation))
    {
      ClutterActorBox box;
      clutter_actor_get_allocation_box (actor, &box);
      cogl_clip_push_rectangle (0, 0, box.x2 - box.x1, box.y2 - box.y1);
      clipped = TRUE;
    }

  clutter_actor_paint (priv->tile);

  if (G_UNLIKELY (priv->extras_visible))
    {
      ClutterActorBox box;

      clutter_actor_paint (priv->action_list);
      clutter_actor_paint (priv->info_panel);

      /* separator */
      cogl_set_source_color4ub (255, 255, 255, 51);
      clutter_actor_get_allocation_box (priv->info_panel, &box);
      cogl_path_line (box.x1, box.y1, box.x2, box.y1);
      cogl_path_stroke ();
    }

  if (G_UNLIKELY (clipped))
    cogl_clip_pop ();
}
Ejemplo n.º 9
0
static MexModel*
mex_content_box_get_context (MexContentView *view)
{
  MexContentBox *box = MEX_CONTENT_BOX (view);
  MexContentBoxPrivate *priv = box->priv;

  return priv->context;
}
Ejemplo n.º 10
0
static gboolean
mex_content_box_key_press_event_cb (ClutterActor    *actor,
                                    ClutterKeyEvent *event,
                                    gpointer         user_data)
{
  MexActionManager *manager = mex_action_manager_get_default ();
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv;


  if (MEX_KEY_OK (event->keyval))
    {
      GList *actions;

      actions = mex_action_manager_get_actions_for_content (manager,
                                                            priv->content);
      /* find the first action and "activate" it */
      if (actions)
        {
          MxAction *action = actions->data;

          mex_action_set_context (action, priv->context);
          mex_action_set_content (action, priv->content);

          g_signal_emit_by_name (action, "activated", 0);

          g_list_free (actions);

          return TRUE;
        }
    }
  else if (MEX_KEY_INFO (event->keyval))
    {
      mex_content_box_toggle_open (MEX_CONTENT_BOX (actor));
    }
  else if (MEX_KEY_BACK (event->keyval))
    {
      /* close content box */
      if (priv->is_open)
        mex_content_box_toggle_open (MEX_CONTENT_BOX (actor));
    }

  return FALSE;
}
Ejemplo n.º 11
0
static void
mex_content_box_pick (ClutterActor       *actor,
                      const ClutterColor *color)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv;

  clutter_actor_paint (priv->tile);
  if (G_UNLIKELY (priv->extras_visible))
    clutter_actor_paint (priv->action_list);
}
Ejemplo n.º 12
0
static void
mex_content_box_paint (ClutterActor *actor)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv;

  if (MEX_IS_PROGRAM (priv->content))
    _mex_program_complete (MEX_PROGRAM (priv->content));

  CLUTTER_ACTOR_CLASS (mex_content_box_parent_class)->paint (actor);
}
Ejemplo n.º 13
0
/* MxFocusableIface */
static MxFocusable*
mex_content_box_accept_focus (MxFocusable *focusable,
                              MxFocusHint  hint)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (focusable)->priv;
  MxFocusable *focus = MX_FOCUSABLE (priv->tile);

  clutter_actor_grab_key_focus (CLUTTER_ACTOR (focusable));

  return mx_focusable_accept_focus (focus, hint);
}
Ejemplo n.º 14
0
static void
mex_content_box_finalize (GObject *object)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv;

  g_free (priv->thumb_url);
  g_free (priv->media_url);
  g_free (priv->logo_url);
  g_free (priv->description);

  G_OBJECT_CLASS (mex_content_box_parent_class)->finalize (object);
}
Ejemplo n.º 15
0
static void
mex_content_box_allocate (ClutterActor           *actor,
                          const ClutterActorBox  *box,
                          ClutterAllocationFlags  flags)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv;
  ClutterActorBox child_box;
  gfloat pref_w = 0, pref_h = 0, tile_w, tile_h;

  CLUTTER_ACTOR_CLASS (mex_content_box_parent_class)->allocate (actor, box,
                                                                flags);

  tile_w = box->x2 - box->x1;
  clutter_actor_get_preferred_width (priv->tile, -1, NULL, &tile_w);
  if (tile_w > box->x2 - box->x1)
    tile_w = box->x2 - box->x1;

  clutter_actor_get_preferred_height (priv->tile, tile_w, NULL, &tile_h);
  child_box.x1 = 0;
  child_box.x2 = child_box.x1 + tile_w;
  child_box.y1 = 0;
  child_box.y2 = child_box.y1 + tile_h;

  clutter_actor_allocate (priv->tile, &child_box, flags);

  if (G_UNLIKELY (priv->extras_visible))
    {
      /* action list */
      clutter_actor_get_preferred_width (priv->action_list, -1, NULL, &pref_w);
      clutter_actor_get_preferred_height (priv->info_panel, -1, NULL, &pref_h);

      child_box.x1 = tile_w;
      child_box.x2 = tile_w + pref_w;
      child_box.y1 = 0;
      child_box.y2 = tile_h;
      clutter_actor_allocate (priv->action_list, &child_box, flags);


      child_box.x1 = 0;
      child_box.x2 = tile_w + pref_w;
      child_box.y1 = tile_h;
      child_box.y2 = tile_h + pref_h;
      clutter_actor_allocate (priv->info_panel, &child_box, flags);
    }

  /* enable clip-to-allocation if the children will extend beyond the allocated
   * box */
  if ((tile_w + pref_w) > (box->x2 - box->x1)
      || (tile_h + pref_h) > (box->y2 - box->y1))
    priv->clip_to_allocation = TRUE;
  else
    priv->clip_to_allocation = FALSE;
}
Ejemplo n.º 16
0
static gboolean
mex_content_box_key_press_event_cb (ClutterActor    *actor,
                                    ClutterKeyEvent *event,
                                    MexExpanderBox  *drawer)
{
  gboolean open;

  MexActionManager *manager = mex_action_manager_get_default ();
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (drawer)->priv;

  if (event->keyval != MEX_KEY_OK &&
      event->keyval != MEX_KEY_INFO)
    {
      return FALSE;
    }

  if (event->keyval == MEX_KEY_OK)
    {
      GList *actions;

      actions = mex_action_manager_get_actions_for_content (manager,
                                                            priv->content);

      if (actions)
        {
          MxAction *action = actions->data;

          mex_action_set_content (action, priv->content);
          mex_action_set_context (action, priv->model);

          g_signal_emit_by_name (action, "activated", 0);

          g_list_free (actions);

          return TRUE;
        }
    }

  open = !mex_expander_box_get_open (drawer);

  /* We only want to expand the box if we have either more than one action,
   * or we have description metadata. We already track this when determining
   * if the info icon should be visible, so use that to determine whether
   * we should allow opening here.
   */
  if (open && !mex_tile_get_secondary_icon (MEX_TILE (priv->tile)))
    return FALSE;

  mex_expander_box_set_open (drawer, open);
  mex_expander_box_set_open (MEX_EXPANDER_BOX (priv->box), open);

  return TRUE;
}
Ejemplo n.º 17
0
static void
mex_content_box_dispose (GObject *object)
{
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv;

  if (priv->content)
    {
      g_object_unref (priv->content);
      priv->content = NULL;
    }

  if (priv->context)
    {
      g_object_unref (priv->context);
      priv->context = NULL;
    }

  if (priv->tile)
    {
      clutter_actor_destroy (priv->tile);
      priv->tile = NULL;
    }

  if (priv->action_list)
    {
      clutter_actor_destroy (priv->action_list);
      priv->action_list = NULL;
    }

  if (priv->info_panel)
    {
      clutter_actor_destroy (priv->info_panel);
      priv->info_panel = NULL;
    }

  if (priv->timeline)
    {
      g_object_unref (priv->timeline);
      priv->timeline = NULL;
    }

  if (priv->alpha)
    {
      g_object_unref (priv->alpha);
      priv->alpha = NULL;
    }

  G_OBJECT_CLASS (mex_content_box_parent_class)->dispose (object);
}
Ejemplo n.º 18
0
static gboolean
mex_content_box_tile_clicked_cb (ClutterActor       *tile,
                                 ClutterButtonEvent *event,
                                 MexContentBox      *self)
{
  /* Because key based interactions moving the focus involve
     opening/closing the content box, we have to be careful about the
     order in which we change focus and open/close the box with mouse
     interactions. */
  if (mex_content_box_get_open (self))
    {
      mex_content_box_toggle_open (MEX_CONTENT_BOX (self));

      mex_push_focus (MX_FOCUSABLE (tile));
    }
  else
    {
      mex_push_focus (MX_FOCUSABLE (tile));

      mex_content_box_toggle_open (MEX_CONTENT_BOX (self));
    }

  return TRUE;
}
Ejemplo n.º 19
0
static void
mex_content_box_set_context (MexContentView *view,
                             MexModel       *model)
{
  MexContentBox *box = MEX_CONTENT_BOX (view);
  MexContentBoxPrivate *priv = box->priv;

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

  if (priv->model)
    g_object_unref (priv->model);

  priv->model = g_object_ref (model);
  mex_content_view_set_context (MEX_CONTENT_VIEW (priv->action_list), model);
}
Ejemplo n.º 20
0
static void
mex_column_shrink_children (MexColumn *column)
{
  MexColumnPrivate *priv = column->priv;
  GList *l;

  if (priv->n_items < 1)
    return;

  clutter_timeline_stop (priv->expand_timeline);

  for (l = priv->children; l; l = g_list_next (l))
    {
      mex_column_shrink_child (l->data);
      mex_content_box_set_important (MEX_CONTENT_BOX (l->data), FALSE);
    }
}
Ejemplo n.º 21
0
static void
mex_content_box_notify_open_cb (MexExpanderBox *box,
                                GParamSpec     *pspec)
{
  GList *actions;

  ClutterStage *stage = CLUTTER_STAGE (
                          clutter_actor_get_stage (CLUTTER_ACTOR (box)));
  MxFocusManager *fmanager = mx_focus_manager_get_for_stage (stage);
  MexActionManager *manager = mex_action_manager_get_default ();
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (box)->priv;
  gboolean open = mex_expander_box_get_open (box);

  if (!open)
    {
      /* If the action list has focus, push it back onto the tile */
      if (mex_actor_has_focus (fmanager, priv->action_list))
        mx_focus_manager_push_focus (fmanager, MX_FOCUSABLE (priv->tile));
      return;
    }

  /* Refresh the info panel and the action list */
  mex_content_view_set_content (MEX_CONTENT_VIEW (priv->panel), priv->content);
  mex_action_list_refresh (MEX_ACTION_LIST (priv->action_list));

  /* See if we have any actions */
  actions = mex_action_manager_get_actions_for_content (manager,
                                                        priv->content);

  /* Push focus onto the action list if we have actions, otherwise onto
   * the tile.
   */
  if (actions)
    {
      clutter_actor_show (priv->action_list);
      mx_focus_manager_push_focus (fmanager,
                                   MX_FOCUSABLE (priv->action_list));
      g_list_free (actions);
    }
  else
    {
      clutter_actor_hide (priv->action_list);
      mx_focus_manager_push_focus (fmanager, MX_FOCUSABLE (priv->tile));
    }
}
Ejemplo n.º 22
0
static void
mex_content_box_set_content (MexContentView *view,
                             MexContent     *content)
{
  MexContentBox *box = MEX_CONTENT_BOX (view);
  MexContentBoxPrivate *priv = box->priv;

  if (priv->content)
    g_object_unref (priv->content);

  priv->content = g_object_ref (content);
  mex_content_view_set_content (MEX_CONTENT_VIEW (priv->tile), content);
  mex_content_view_set_content (MEX_CONTENT_VIEW (priv->info_panel), content);

  /* setting the content on action_list is delayed until the box is opened to
   * ensure any additional actions registered after set_content is called are
   * available */
}
Ejemplo n.º 23
0
static void
mex_content_box_set_context (MexContentView *view,
                             MexModel       *context)
{
  MexContentBox *box = MEX_CONTENT_BOX (view);
  MexContentBoxPrivate *priv = box->priv;

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

  if (priv->context)
    g_object_unref (priv->context);

  priv->context = g_object_ref (context);
  mex_content_view_set_context (MEX_CONTENT_VIEW (priv->action_list), context);
  mex_content_view_set_context (MEX_CONTENT_VIEW (priv->tile), context);
  mex_content_view_set_context (MEX_CONTENT_VIEW (priv->info_panel), context);
}
Ejemplo n.º 24
0
/**
 * mex_column_add_content:
 *
 * Add an item to the column for the specified content at the specified
 * position.
 */
static void
mex_column_add_content (MexColumn  *column,
                        MexContent *content,
                        guint       position)
{
  MexColumnPrivate *priv = column->priv;
  ClutterActor *box;
  MexShadow *shadow;
  ClutterColor shadow_color = { 0, 0, 0, 128 };
  GList *sibling;

  box = mex_content_box_new ();
  mex_content_view_set_content (MEX_CONTENT_VIEW (box), content);
  mex_content_view_set_context (MEX_CONTENT_VIEW (box), priv->model);

  sibling = g_list_nth (priv->children, position);
  priv->children = g_list_insert_before (priv->children, sibling, box);
  priv->n_items ++;

  /* add shadow */
  shadow = mex_shadow_new ();
  mex_shadow_set_paint_flags (shadow,
                              MEX_TEXTURE_FRAME_TOP
                              | MEX_TEXTURE_FRAME_BOTTOM);
  mex_shadow_set_radius_y (shadow, 25);
  mex_shadow_set_color (shadow, &shadow_color);
  clutter_actor_add_effect_with_name (CLUTTER_ACTOR (box), "shadow",
                                      CLUTTER_EFFECT (shadow));
  clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (shadow), FALSE);

  g_signal_connect (box, "notify::open",
                    G_CALLBACK (content_box_open_notify), column);

  /* set important if the column has focus */
  mex_content_box_set_important (MEX_CONTENT_BOX (box), priv->has_focus);

  clutter_actor_set_parent (box, CLUTTER_ACTOR (column));
}
Ejemplo n.º 25
0
static void
mex_column_add (ClutterContainer *container,
                ClutterActor     *actor)
{
  MexColumn *self = MEX_COLUMN (container);
  MexColumnPrivate *priv = self->priv;

  if (priv->sort_func)
    priv->children =
      g_list_insert_sorted_with_data (priv->children, actor,
                                      (GCompareDataFunc)priv->sort_func,
                                      priv->sort_data);
  else
    priv->children = g_list_append (priv->children, actor);

  priv->n_items ++;

  /* Expand/collapse any drawer that gets added as appropriate */
  if (MEX_IS_EXPANDER_BOX (actor))
    {
      g_signal_connect (actor, "notify::open",
                        G_CALLBACK (expander_box_open_notify), container);

      mex_expander_box_set_important (MEX_EXPANDER_BOX (actor),
                                      priv->has_focus);

      if (MEX_IS_CONTENT_BOX (actor))
        {
          ClutterActor *tile =
            mex_content_box_get_tile (MEX_CONTENT_BOX (actor));
          mex_tile_set_important (MEX_TILE (tile), priv->has_focus);
        }
    }

  clutter_actor_set_parent (actor, CLUTTER_ACTOR (self));

  g_signal_emit_by_name (self, "actor-added", actor);
}
Ejemplo n.º 26
0
static void
mex_column_notify_focused_cb (MxFocusManager *manager,
                              GParamSpec     *pspec,
                              MexColumn      *self)
{
  GList *c;
  guint offset, increment;
  ClutterActor *focused, *focused_cell;
  gboolean cell_has_focus, has_focus, open, set_tile_important;

  MexColumnPrivate *priv = self->priv;

  focused = (ClutterActor *)mx_focus_manager_get_focused (manager);

  /* Check if we have focus, and what child is focused */
  focused_cell = NULL;
  set_tile_important = FALSE;
  cell_has_focus = has_focus = FALSE;

  if (focused)
    {
      gboolean contains_column = FALSE;
      ClutterActor *parent = clutter_actor_get_parent (focused);
      while (parent)
        {
          if (parent == (ClutterActor *)self)
            {
              has_focus = TRUE;

              if (!priv->has_focus)
                {
                  set_tile_important = TRUE;
                  priv->has_focus = TRUE;
                }

              if (focused != priv->header)
                {
                  cell_has_focus = TRUE;
                  focused_cell = focused;
                }

              break;
            }
          else if (MEX_IS_COLUMN (parent))
            {
              contains_column = TRUE;
            }

          focused = parent;
          parent = clutter_actor_get_parent (focused);
        }

      if (!contains_column)
        has_focus = TRUE;
    }

  if (!has_focus && priv->has_focus)
    {
      priv->has_focus = FALSE;
      set_tile_important = TRUE;
    }

  /* Scroll the adjustment to the top */
  if (!cell_has_focus && priv->adjustment)
    mx_adjustment_interpolate (priv->adjustment, 0, 250,
                               CLUTTER_EASE_OUT_CUBIC);

  /* Open/close boxes as appropriate */
  offset = 0;
  increment = 150;

  /* If we're changing the tile importance, initialise the state manager */
  if (set_tile_important && priv->n_items > 0)
    {
      if (priv->expand_timeline)
        g_object_unref (priv->expand_timeline);
      priv->expand_timeline =
        clutter_timeline_new (priv->n_items * increment);
      clutter_timeline_set_delay (priv->expand_timeline, 350);
    }

  /* Loop through children and set the expander box important/unimportant
   * as necessary, and if necessary, do the same for the tile inside the
   * expander-box.
   */
  open = has_focus && !cell_has_focus;
  for (c = priv->children; c; c = c->next)
    {
      gchar signal_name[32+16];
      ClutterActor *child = c->data;

      if ((!priv->collapse && priv->has_focus) || (child == focused_cell))
        open = TRUE;

      if (!MEX_IS_EXPANDER_BOX (child))
        continue;

      /* Note, 'marker-reached::' is 16 characters long */
      g_snprintf (signal_name, G_N_ELEMENTS (signal_name),
                  "marker-reached::%p", child);

      if (MEX_IS_CONTENT_BOX (child))
        {
          ClutterActor *tile =
            mex_content_box_get_tile (MEX_CONTENT_BOX (child));
          mex_tile_set_important (MEX_TILE (tile), priv->has_focus);
        }

      if (!open)
        {
          if (priv->expand_timeline)
            {
              if (clutter_timeline_has_marker (priv->expand_timeline,
                                               signal_name + 16))
                clutter_timeline_remove_marker (priv->expand_timeline,
                                                signal_name + 16);
              g_signal_handlers_disconnect_by_func (priv->expand_timeline,
                                                    mex_column_expand_drawer_cb,
                                                    child);
            }
          mex_expander_box_set_important (MEX_EXPANDER_BOX (child), FALSE);
        }
      else if (set_tile_important)
        {

          mex_expander_box_set_important (MEX_EXPANDER_BOX (child), FALSE);
          clutter_timeline_add_marker_at_time (priv->expand_timeline,
                                               signal_name + 16, offset);
          g_signal_connect_swapped (priv->expand_timeline, signal_name,
                                    G_CALLBACK (mex_column_expand_drawer_cb),
                                    child);

          offset += increment;
        }
      else
        mex_expander_box_set_important (MEX_EXPANDER_BOX (child), TRUE);
    }

  if (priv->expand_timeline && set_tile_important && (offset >= increment))
    clutter_timeline_start (priv->expand_timeline);
}
Ejemplo n.º 27
0
static void
mex_column_expand_children (MexColumn    *column,
                            ClutterActor *start_at)
{
  MexColumnPrivate *priv = column->priv;
  guint offset, increment;
  GList *c;
  gchar **markers;
  gint i;
  gboolean start;

  if (priv->n_items < 1)
    return;

  /* Open/close boxes as appropriate */
  offset = 0;
  increment = 150;

  clutter_timeline_set_duration (priv->expand_timeline,
                                 priv->n_items * increment);

  clutter_timeline_set_delay (priv->expand_timeline, 350);

  /* remove the previous markers */
  markers = clutter_timeline_list_markers (priv->expand_timeline, -1, NULL);
  if (markers)
    {
      for (i = 0; markers[i]; i++)
        {
          clutter_timeline_remove_marker (priv->expand_timeline,
                                          markers[i]);
        }
    }
  g_strfreev (markers);

  /* start is TRUE if start_at is NULL, otherwise it is set to TRUE when the
   * start_at item is found */
  start = (start_at == NULL);

  for (c = priv->children; c; c = g_list_next (c))
    {
      gchar signal_name[32+16];
      ClutterActor *child = c->data;

      if (!MEX_IS_CONTENT_BOX (child))
        continue;

      mex_content_box_set_important (MEX_CONTENT_BOX (child), TRUE);
      mex_column_expand_child (child);

      /* continue until the start item has been found */
      if (child == start_at)
        start = TRUE;

      if (!start)
        continue;

      /* Note, 'marker-reached::' is 16 characters long */
      g_snprintf (signal_name, G_N_ELEMENTS (signal_name),
                  "marker-reached::%p", child);

      /* stagger opening */
      clutter_timeline_add_marker_at_time (priv->expand_timeline,
                                           signal_name + 16, offset);
      g_signal_connect_swapped (priv->expand_timeline, signal_name,
                                G_CALLBACK (mex_column_expand_child),
                                child);

      offset += increment;

    }

    clutter_timeline_start (priv->expand_timeline);
}
Ejemplo n.º 28
0
static void
mex_content_box_set_property (GObject      *object,
                              guint         property_id,
                              const GValue *value,
                              GParamSpec   *pspec)
{
  MexContentBox *self = MEX_CONTENT_BOX (object);
  MexContentBoxPrivate *priv = self->priv;

  switch (property_id)
    {
    case PROP_MEDIA_URL:
      g_free (priv->media_url);
      priv->media_url = g_value_dup_string (value);
      break;

    case PROP_LOGO_URL:
      /* FIXME: We want the logo URL to be file:// to share the same
       * underlying texture. This should be handled by a generic "download
       * queue + texture cache" thingy that caches the same URL to a local
       * file and hands over a ClutterTexure (or a MagicTexture) with the
       * same underlying Cogl texture */
    {
      MxTextureCache *cache;
      ClutterActor *logo, *logo_frame;
      GFile *file;
      gchar *path;
      gint bw, bh;
      gfloat ratio;

      g_free (priv->logo_url);
      priv->logo_url = g_value_dup_string (value);

      if (priv->logo_url == NULL)
        break;

      file = g_file_new_for_uri (priv->logo_url);
      path = g_file_get_path (file);
      g_object_unref (file);
      if (G_UNLIKELY (path == NULL))
        {
          g_warning ("The logo URL provided is not local, refusing to load it");
          break;
        }

      cache = mx_texture_cache_get_default ();
      logo = mx_texture_cache_get_actor (cache, path);
      if (G_UNLIKELY (logo == NULL))
        {
          g_warning ("Could not retrieve texture for %s", path);
          break;
        }

      logo_frame = mex_aspect_frame_new ();
      /* FIXME, had to set the size (for now?) provides some GObject properties
       * to tune that? expose it in the CSS */
      clutter_actor_set_size (logo_frame, 60, 40);
      clutter_texture_get_base_size (CLUTTER_TEXTURE (logo), &bw, &bh);
      ratio = bh / 40.;
      mex_aspect_frame_set_ratio (MEX_ASPECT_FRAME (logo_frame), ratio);
      clutter_container_add_actor (CLUTTER_CONTAINER (logo_frame), logo);

      mex_tile_set_primary_icon (MEX_TILE (priv->tile), logo_frame);
    }
    break;

    case PROP_THUMB_WIDTH:
      priv->thumb_width = g_value_get_int (value);
      g_object_set (G_OBJECT (priv->tile),
                    "thumb-width",
                    priv->thumb_width,
                    NULL);
      break;

    case PROP_THUMB_HEIGHT:
      priv->thumb_height = g_value_get_int (value);
      g_object_set (G_OBJECT (priv->tile),
                    "thumb-height",
                    priv->thumb_height,
                    NULL);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    }
}
Ejemplo n.º 29
0
static MexContent *
mex_content_box_get_content (MexContentView *view)
{
  return MEX_CONTENT_BOX (view)->priv->content;
}