Esempio n. 1
0
static void
mx_expander_get_preferred_height (ClutterActor *actor,
                                  gfloat        for_width,
                                  gfloat       *min_height,
                                  gfloat       *pref_height)
{
  MxExpanderPrivate *priv = MX_EXPANDER (actor)->priv;
  ClutterActor *child;
  MxPadding padding;
  gfloat min_child_h, pref_child_h, min_label_h, pref_label_h, arrow_h;
  gfloat available_w;

  child = mx_bin_get_child (MX_BIN (actor));

  mx_widget_get_padding (MX_WIDGET (actor), &padding);
  available_w = for_width - padding.left - padding.right;

  if (child)
    {
      clutter_actor_get_preferred_height (child,
                                          available_w,
                                          &min_child_h,
                                          &pref_child_h);
      min_child_h += priv->spacing;
      pref_child_h += priv->spacing;

      /* allocate the space multiplied by the progress of the "expansion"
       * animation */
      min_child_h *= priv->progress;
      pref_child_h *= priv->progress;
    }
  else
    {
      min_child_h = 0;
      pref_child_h = 0;
    }

  clutter_actor_get_preferred_height (priv->label,
                                      available_w,
                                      &min_label_h,
                                      &pref_label_h);

  clutter_actor_get_preferred_height (priv->arrow, -1, NULL, &arrow_h);

  min_label_h = MAX (min_label_h, arrow_h);
  pref_label_h = MAX (pref_label_h, arrow_h);

  if (min_height)
    *min_height = padding.top
                  + min_child_h + min_label_h
                  + padding.bottom;

  if (pref_height)
    *pref_height = padding.top
                   + pref_child_h + pref_label_h
                   + padding.bottom;

}
Esempio n. 2
0
static void
mx_expander_foreach (ClutterContainer *container,
                     ClutterCallback   callback,
                     gpointer          user_data)
{
  ClutterActor *child;

  child = mx_bin_get_child (MX_BIN (container));

  if (child)
    callback (child, user_data);
}
Esempio n. 3
0
static void
tile_created_cb (MexProxy *proxy,
                 GObject  *content,
                 GObject  *object,
                 gpointer  controls)
{
    const gchar *mime_type;
    ClutterEffect *effect;
    ClutterColor color = { 0, 0, 0, 60 };

    /* filter out folders */
    mime_type = mex_content_get_metadata (MEX_CONTENT (content),
                                          MEX_CONTENT_METADATA_MIMETYPE);

    if (g_strcmp0 (mime_type, "x-grl/box") == 0)
    {
        g_signal_stop_emission_by_name (proxy, "object-created");
        return;
    }

    mex_tile_set_important (MEX_TILE (object), TRUE);
    clutter_actor_set_reactive (CLUTTER_ACTOR (object), TRUE);

    g_object_set (object, "thumb-height", 140, "thumb-width", 250, NULL);

    g_signal_connect (object, "key-press-event", G_CALLBACK (key_press_event_cb),
                      controls);
    g_signal_connect (object, "button-release-event",
                      G_CALLBACK (button_release_event_cb), controls);

    effect = g_object_new (MEX_TYPE_SHADOW,
                           "radius-x", 15,
                           "radius-y", 15,
                           "color", &color,
                           "enabled", FALSE,
                           NULL);
    clutter_actor_add_effect_with_name (CLUTTER_ACTOR (object), "shadow", effect);

    effect = g_object_new (MEX_TYPE_SHADOW,
                           "radius-x", 15,
                           "radius-y", 15,
                           "color", &color,
                           NULL);
    clutter_actor_add_effect_with_name (mx_bin_get_child (MX_BIN (object)),
                                        "shadow", effect);

    g_signal_connect (object, "focus-in", G_CALLBACK (tile_focus_in_cb), NULL);
    g_signal_connect (object, "focus-out", G_CALLBACK (tile_focus_out_cb), NULL);
    tile_focus_out_cb (MX_BIN (object));
}
Esempio n. 4
0
static void
tile_focus_in_cb (MxBin *actor)
{
    ClutterActorMeta *shadow;

    shadow = (ClutterActorMeta*) clutter_actor_get_effect (CLUTTER_ACTOR (actor),
             "shadow");
    clutter_actor_meta_set_enabled (shadow, TRUE);

    shadow =
        (ClutterActorMeta*) clutter_actor_get_effect (mx_bin_get_child (actor),
                "shadow");
    clutter_actor_meta_set_enabled (shadow, FALSE);
}
static void
update_playing (MxButton *button, gboolean playing)
{
    ClutterActor *child;

    child = mx_bin_get_child (MX_BIN (button));
    if (playing) {
        mx_stylable_set_style_class (MX_STYLABLE (button), "PauseButton");
        mx_icon_set_icon_name (MX_ICON (child), "media-playback-pause");
    } else {
        mx_stylable_set_style_class (MX_STYLABLE (button), "PlayButton");
        mx_icon_set_icon_name (MX_ICON (child), "media-playback-start");
    }
    /* stop button?  meh */
}
Esempio n. 6
0
static void
mx_expander_get_preferred_width (ClutterActor *actor,
                                 gfloat        for_height,
                                 gfloat       *min_width,
                                 gfloat       *pref_width)
{
  MxExpanderPrivate *priv = MX_EXPANDER (actor)->priv;
  ClutterActor *child;
  MxPadding padding;
  gfloat min_child_w, pref_child_w, min_label_w, pref_label_w, arrow_w;

  child = mx_bin_get_child (MX_BIN (actor));
  mx_widget_get_padding (MX_WIDGET (actor), &padding);

  if (child)
    {
      clutter_actor_get_preferred_width (child,
                                         -1,
                                         &min_child_w,
                                         &pref_child_w);
    }
  else
    {
      min_child_w = 0;
      pref_child_w = 0;
    }

  clutter_actor_get_preferred_width (priv->label,
                                     -1, &min_label_w, &pref_label_w);
  clutter_actor_get_preferred_width (priv->arrow,
                                     -1, NULL, &arrow_w);

  /* TODO: create a style property for this padding between arrow and label */
  if (arrow_w)
    arrow_w += 6.0f;

  if (min_width)
    *min_width = padding.left
                 + MAX (min_child_w, min_label_w + arrow_w)
                 + padding.right;

  if (pref_width)
    *pref_width = padding.left
                  + MAX (pref_child_w, pref_label_w + arrow_w)
                  + padding.right;
}
Esempio n. 7
0
static void
timeline_complete (ClutterTimeline *timeline,
                   ClutterActor    *expander)
{
  guchar opacity;
  ClutterActor *child;
  MxExpanderPrivate *priv = MX_EXPANDER (expander)->priv;

  g_signal_emit (expander, expander_signals[EXPAND_COMPLETE], 0);

  /* if the expander is now closed, update the style */
  if (!priv->expanded)
    {
      clutter_actor_set_name (priv->arrow, "mx-expander-arrow-closed");
      mx_stylable_set_style_class (MX_STYLABLE (expander), "closed-expander");

      clutter_actor_queue_relayout (expander);
    }

  child = mx_bin_get_child (MX_BIN (expander));

  if (!child)
    return;

  /* continue only if we are "opening" */
  if (!priv->expanded)
    return;

  /* we can't do an animation if there is already one in progress,
   * because we cannot get the actors original opacity */
  if (clutter_actor_get_animation (child))
    {
      clutter_actor_show (child);
      return;
    }

  opacity = clutter_actor_get_opacity (child);
  clutter_actor_set_opacity (child, 0);

  clutter_actor_show (child);
  clutter_actor_animate (child, CLUTTER_EASE_IN_SINE, 100,
                         "opacity", opacity,
                         NULL);
}
Esempio n. 8
0
static void
mx_expander_add (ClutterContainer *container,
                 ClutterActor     *actor)
{
  MxExpander *expander = MX_EXPANDER (container);
  MxExpanderPrivate *priv = expander->priv;

  /* Override the container add method so we can hide the actor if the
     expander is not expanded */

  /* chain up */
  container_parent_class->add (container, actor);

  if (!priv->expanded)
    {
      actor = mx_bin_get_child (MX_BIN (container));
      if (actor)
        clutter_actor_hide (actor);
    }
}
Esempio n. 9
0
static void
mx_expander_update (MxExpander *expander)
{
  MxExpanderPrivate *priv = expander->priv;
  ClutterActor *child;

  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 */

  child = mx_bin_get_child (MX_BIN (expander));

  if (!child)
    return;

  /* setup and start the expansion animation */
  if (!priv->expanded)
    {
      clutter_actor_hide (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);
}
Esempio n. 10
0
File: mx-button.c Progetto: danni/mx
static void
mx_button_update_contents (MxButton *self)
{
  MxButtonPrivate *priv = self->priv;
  ClutterActor *child;
  gboolean icon_visible, label_visible;
  const gchar *text;

  /* If the icon doesn't have a name set, treat it as
   * not-visible.
   */
  if (priv->icon_visible && mx_icon_get_icon_name (MX_ICON (priv->icon)))
    icon_visible = TRUE;
  else
    icon_visible = FALSE;

  text = clutter_text_get_text (CLUTTER_TEXT (priv->label));

  if (priv->label_visible && text && (strcmp (text, "") != 0))
    label_visible = TRUE;
  else
    label_visible = FALSE;

  /* replace any custom content */
  child = mx_bin_get_child (MX_BIN (self));

  if (child != priv->hbox)
    mx_bin_set_child (MX_BIN (self), priv->hbox);

  /* Handle the simple cases first */
  if (!icon_visible && !label_visible)
    {
      clutter_actor_hide (priv->hbox);
      return;
    }

  /* ensure the hbox is visible */
  clutter_actor_show (priv->hbox);

  if (icon_visible && !label_visible)
    {
      clutter_actor_show (priv->icon);
      clutter_actor_hide (priv->label);
      clutter_actor_set_child_below_sibling (priv->hbox, priv->icon, NULL);
      return;
    }

  if (!icon_visible && label_visible)
    {
      clutter_actor_hide (priv->icon);
      clutter_actor_show (priv->label);
      clutter_actor_set_child_below_sibling (priv->hbox, priv->label, NULL);
      return;
    }

  /* Both the icon and text are visible, handle this case */
  clutter_actor_show (priv->icon);
  clutter_actor_show (priv->label);

  switch (priv->icon_position)
    {
    case MX_POSITION_TOP:
      mx_box_layout_set_orientation (MX_BOX_LAYOUT (priv->hbox),
                                     MX_ORIENTATION_VERTICAL);
      clutter_actor_set_child_below_sibling (priv->hbox, priv->icon, NULL);

      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->label, "x-align", MX_ALIGN_MIDDLE,
                                   "y-align", MX_ALIGN_END, NULL);
      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->icon, "x-align", MX_ALIGN_MIDDLE,
                                   "y-align", MX_ALIGN_START, NULL);
      break;

    case MX_POSITION_RIGHT:
      mx_box_layout_set_orientation (MX_BOX_LAYOUT (priv->hbox),
                                     MX_ORIENTATION_HORIZONTAL);
      clutter_actor_set_child_above_sibling (priv->hbox, priv->icon, NULL);

      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->label, "x-align", MX_ALIGN_START,
                                   "y-align", MX_ALIGN_MIDDLE, NULL);
      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->icon, "x-align", MX_ALIGN_END,
                                   "y-align", MX_ALIGN_MIDDLE, NULL);
      break;

    case MX_POSITION_BOTTOM:
      mx_box_layout_set_orientation (MX_BOX_LAYOUT (priv->hbox),
                                     MX_ORIENTATION_VERTICAL);
      clutter_actor_set_child_above_sibling (priv->hbox, priv->icon, NULL);

      mx_box_layout_child_set_x_align (MX_BOX_LAYOUT (priv->hbox),
                                       priv->label, MX_ALIGN_MIDDLE);
      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->label, "x-align", MX_ALIGN_MIDDLE,
                                   "y-align", MX_ALIGN_START, NULL);
      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->icon, "x-align", MX_ALIGN_MIDDLE,
                                   "y-align", MX_ALIGN_END, NULL);
      break;

    case MX_POSITION_LEFT:
      mx_box_layout_set_orientation (MX_BOX_LAYOUT (priv->hbox),
                                     MX_ORIENTATION_HORIZONTAL);
      clutter_actor_set_child_below_sibling (priv->hbox, priv->icon, NULL);

      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->label, "x-align", MX_ALIGN_END,
                                   "y-align", MX_ALIGN_MIDDLE, NULL);
      clutter_container_child_set (CLUTTER_CONTAINER (priv->hbox),
                                   priv->icon, "x-align", MX_ALIGN_START,
                                   "y-align", MX_ALIGN_MIDDLE, NULL);
      break;
    }
}
static void
mx_viewport_allocate (ClutterActor          *self,
                      const ClutterActorBox *box,
                      ClutterAllocationFlags flags)
{
  MxViewportPrivate *priv = MX_VIEWPORT (self)->priv;
  MxPadding padding;
  ClutterActor *child;
  gfloat width, height;
  gfloat available_width, available_height;

  /* Chain up. */
  CLUTTER_ACTOR_CLASS (mx_viewport_parent_class)-> allocate (self, box, flags);

  mx_widget_get_padding (MX_WIDGET (self), &padding);
  available_width = box->x2 - box->x1 - padding.left - padding.right;
  available_height = box->y2 - box->y1 - padding.top - padding.bottom;

  child = mx_bin_get_child (MX_BIN (self));

  if (child)
    {
      gfloat natural_width, natural_height;
      ClutterActorBox child_box;
      MxAlign x_align, y_align;
      gboolean x_fill, y_fill;

      clutter_actor_get_preferred_size (child, NULL, NULL, &natural_width,
                                        &natural_height);
      mx_bin_get_fill (MX_BIN (self), &x_fill, &y_fill);

      if (x_fill && (available_width > natural_width))
        width = available_width;
      else
        width = natural_width;

      if (y_fill && (available_height > natural_height))
        height = available_height;
      else
        height = natural_height;

      mx_bin_get_alignment (MX_BIN (self), &x_align, &y_align);

      if (!x_fill && width < available_width)
        {
          switch (x_align)
            {
            case MX_ALIGN_START:
              child_box.x1 = padding.left;
              break;
            case MX_ALIGN_MIDDLE:
              child_box.x1 = padding.left + (available_width - width) / 2.f;
              break;
            case MX_ALIGN_END:
              child_box.x1 = box->x2 - box->x1 - padding.right - width;
              break;
            }
        }
      else
        child_box.x1 = padding.left;

      if (!y_fill && height < available_height)
        {
          switch (y_align)
            {
            case MX_ALIGN_START:
              child_box.y1 = padding.top;
              break;
            case MX_ALIGN_MIDDLE:
              child_box.y1 = padding.top + (available_height - height) / 2.f;
              break;
            case MX_ALIGN_END:
              child_box.y1 = box->y2 - box->y1 - padding.bottom - height;
              break;
            }
        }
      else
        child_box.y1 = padding.top;

      child_box.x2 = child_box.x1 + width;
      child_box.y2 = child_box.y1 + height;

      clutter_actor_allocate (child, &child_box, flags);
    }
  else
    {
      width = 0;
      height = 0;
    }



  /* Refresh adjustments */
  if (priv->sync_adjustments)
    {
      if (priv->hadjustment)
        {
          g_object_set (G_OBJECT (priv->hadjustment),
                        "lower", 0.0,
                        "page-size", available_width,
                        "upper", width,
                        "page-increment", available_width / 3,
                        "step-increment", available_width / 12,
                        NULL);
        }

      if (priv->vadjustment)
        {
          g_object_set (G_OBJECT (priv->vadjustment),
                        "lower", 0.0,
                        "page-size", available_height,
                        "upper", height,
                        "page-increment", available_height / 3,
                        "step-increment", available_height / 12,
                        NULL);
        }
    }
}
Esempio n. 12
0
static void
mex_media_controls_init (MexMediaControls *self)
{
    ClutterActor *actor;
    ClutterScript *script;
    GError *err = NULL;
    MxAdjustment *adjustment;
    ClutterActor *related_box;
    gchar *tmp;

    MexMediaControlsPrivate *priv = self->priv = MEDIA_CONTROLS_PRIVATE (self);

    priv->script = script = clutter_script_new ();

    tmp = g_build_filename (mex_get_data_dir (), "json", "media-controls.json",
                            NULL);
    clutter_script_load_from_file (script, tmp, &err);
    g_free (tmp);

    if (err)
        g_error ("Could not load media controls interface: %s", err->message);

    priv->vbox =
        (ClutterActor*) clutter_script_get_object (script, "media-controls");
    clutter_actor_set_parent (priv->vbox, CLUTTER_ACTOR (self));

    /* add shadow to media controls box */
    actor = (ClutterActor *) clutter_script_get_object (script,
            "media-controls-box");
    clutter_actor_add_effect (actor, CLUTTER_EFFECT (mex_shadow_new ()));


    /* vertical fade effect */
    priv->vertical_effect = mx_fade_effect_new ();
    clutter_actor_add_effect (priv->vbox, priv->vertical_effect);
    mx_scrollable_get_adjustments (MX_SCROLLABLE (mx_bin_get_child (MX_BIN (priv->vbox))),
                                   NULL, &adjustment);
    g_signal_connect (adjustment, "changed",
                      G_CALLBACK (notify_vertical_changed_cb), self);
    g_signal_connect (adjustment, "notify::value",
                      G_CALLBACK (notify_vertical_value_cb), self);

    /* horizontal fade effect */
    priv->horizontal_effect = mx_fade_effect_new ();
    related_box = (ClutterActor *) clutter_script_get_object (priv->script,
                  "related-box");
    clutter_actor_add_effect (related_box, priv->horizontal_effect);
    mx_scrollable_get_adjustments (MX_SCROLLABLE (related_box), &adjustment,
                                   NULL);
    g_signal_connect (adjustment, "changed",
                      G_CALLBACK (notify_horizontal_changed_cb), self);
    g_signal_connect (adjustment, "notify::value",
                      G_CALLBACK (notify_horizontal_value_cb), self);


    /* slider setup */
    priv->slider = (ClutterActor*) clutter_script_get_object (script, "slider");
    g_signal_connect (priv->slider, "notify::value",
                      G_CALLBACK (slider_value_changed_cb), self);
    g_signal_connect (priv->slider, "captured-event",
                      G_CALLBACK (slider_captured_event), self);

    priv->play_pause_action =
        (MxAction*) clutter_script_get_object (script, "play-pause-action");

    priv->stop_action =
        (MxAction*) clutter_script_get_object (script, "stop-action");

    priv->add_to_queue_action =
        (MxAction*) clutter_script_get_object (script, "add-to-queue-action");

    priv->queue_button =
        (ClutterActor *) clutter_script_get_object (script, "add-to-queue-button");

    g_signal_connect (priv->play_pause_action, "activated",
                      G_CALLBACK (mex_media_controls_play_cb), self);
    g_signal_connect (priv->stop_action, "activated",
                      G_CALLBACK (mex_media_controls_stop_cb), self);
#if 0
    g_signal_connect (priv->add_to_queue_action, "activated",
                      G_CALLBACK (mex_media_controls_add_to_queue_cb), self);
#endif

    /* proxy setup */

    priv->proxy_model = MEX_VIEW_MODEL (mex_view_model_new (NULL));
    /* FIXME: Set an arbitrary 200-item limit as we can't handle large
     *        amounts of actors without massive slow-down.
     */
    mex_view_model_set_limit (priv->proxy_model, 200);

    priv->proxy = mex_content_proxy_new (MEX_MODEL (priv->proxy_model),
                                         CLUTTER_CONTAINER (related_box),
                                         MEX_TYPE_CONTENT_TILE);

    g_signal_connect (priv->proxy, "object-created", G_CALLBACK (tile_created_cb),
                      self);

    priv->is_disabled = TRUE;
}
Esempio n. 13
0
static void
mx_expander_allocate (ClutterActor          *actor,
                      const ClutterActorBox *box,
                      ClutterAllocationFlags flags)
{
  ClutterActor *child;
  MxExpanderPrivate *priv = MX_EXPANDER (actor)->priv;
  ClutterActorBox child_box;
  MxPadding padding;
  gfloat label_w, label_h;
  gfloat available_w, available_h, min_w, min_h, arrow_h, arrow_w;
  MxAlign x_align, y_align;
  gboolean x_fill, y_fill;

  /* chain up to store allocation */
  CLUTTER_ACTOR_CLASS (mx_expander_parent_class)->allocate (actor, box, flags);

  mx_widget_get_padding (MX_WIDGET (actor), &padding);
  g_object_get (G_OBJECT (actor),
                "x-align", &x_align,
                "y-align", &y_align,
                "x-fill", &x_fill,
                "y-fill", &y_fill,
                NULL);

  available_w = (box->x2 - box->x1) - padding.left - padding.right;
  available_h = (box->y2 - box->y1) - padding.top - padding.bottom;

  /* arrow */
  clutter_actor_get_preferred_width (priv->arrow, -1, NULL, &arrow_w);
  arrow_w = MIN (arrow_w, available_w);

  clutter_actor_get_preferred_height (priv->arrow, -1, NULL, &arrow_h);
  arrow_h = MIN (arrow_h, available_h);

  child_box.x1 = padding.left;
  child_box.x2 = child_box.x1 + arrow_w;
  child_box.y1 = padding.top;
  child_box.y2 = child_box.y1 + arrow_h;
  clutter_actor_allocate (priv->arrow, &child_box, flags);

  /* label */
  min_h = 0;
  min_w = 0;

  clutter_actor_get_preferred_width (priv->label,
                                     available_h, &min_w, &label_w);
  label_w = CLAMP (label_w, min_w, available_w);

  clutter_actor_get_preferred_height (priv->label,
                                      label_w, &min_h, &label_h);
  label_h = CLAMP (label_h, min_h, available_h);

  /* TODO: make a style property for padding between arrow and label */
  child_box.x1 = padding.left + arrow_w + 6.0f;
  child_box.x2 = child_box.x1 + label_w;
  child_box.y1 = padding.top;
  child_box.y2 = child_box.y1 + MAX (label_h, arrow_h);
  mx_allocate_align_fill (priv->label, &child_box, MX_ALIGN_START,
                          MX_ALIGN_MIDDLE, FALSE, FALSE);
  clutter_actor_allocate (priv->label, &child_box, flags);

  /* remove label height and spacing for child calculations */
  available_h -= MAX (label_h, arrow_h) + priv->spacing;

  /* child */
  child = mx_bin_get_child (MX_BIN (actor));
  if (child && CLUTTER_ACTOR_IS_VISIBLE (child))
    {
      child_box.x1 = padding.left;
      child_box.x2 = child_box.x1 + available_w;
      child_box.y1 = padding.top + priv->spacing + MAX (label_h, arrow_h);
      child_box.y2 = child_box.y1 + available_h;

      mx_allocate_align_fill (child, &child_box,
                              x_align, y_align,
                              x_fill, y_fill);

      clutter_actor_allocate (child, &child_box, flags);
    }
}