static void mex_tile_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MxPadding padding; ClutterActorBox child_box; gfloat available_width, available_height; ClutterEffect *fade; MexTilePrivate *priv = MEX_TILE (actor)->priv; CLUTTER_ACTOR_CLASS (mex_tile_parent_class)->allocate (actor, box, flags); mx_widget_get_padding (MX_WIDGET (actor), &padding); available_width = box->x2 - box->x1 - padding.left - padding.right; available_height = box->y2 - box->y1 - padding.top - padding.bottom; if (priv->child) { gfloat child_width, full_width, full_height; clutter_actor_get_preferred_size (priv->child, NULL, NULL, &full_width, &full_height); child_box.y1 = padding.top; if (clutter_alpha_get_alpha (priv->important_alpha) < 0.5) { child_width = full_width * (available_height / full_height); if (child_width > available_width) child_width = available_width; child_box.y2 = child_box.y1 + available_height; /* When we're in unimportant state, make sure the label * doesn't overlap the image. */ if (available_height < full_height) available_width -= child_width * ((0.5 - clutter_alpha_get_alpha (priv->important_alpha)) * 2); } else { child_width = available_width; clutter_actor_set_clip_to_allocation ( actor, (full_height > available_height)); child_box.y2 = child_box.y1 + full_height; } child_box.x2 = box->x2 - box->x1 - padding.right; child_box.x1 = child_box.x2 - child_width; mx_allocate_align_fill (priv->child, &child_box, MX_ALIGN_MIDDLE, MX_ALIGN_MIDDLE, FALSE, FALSE); clutter_actor_allocate (priv->child, &child_box, flags); } /* Allocate Header */ if (priv->header_visible) { gfloat icon1_w, icon1_h, icon2_w, icon2_h, label_h, label_w, header_h; gfloat middle_w; if (priv->header_padding) { padding.top += priv->header_padding->top; padding.right += priv->header_padding->right; padding.bottom += priv->header_padding->bottom; padding.left += priv->header_padding->left; } clutter_actor_get_preferred_size (priv->box_layout, NULL, NULL, &label_w, &label_h); if (priv->icon1) clutter_actor_get_preferred_size (priv->icon1, NULL, NULL, &icon1_w, &icon1_h); else icon1_h = icon1_w = 0; if (priv->icon2) clutter_actor_get_preferred_size (priv->icon2, NULL, NULL, &icon2_w, &icon2_h); else icon2_h = icon2_w = 0; header_h = MAX (icon1_h, MAX (icon2_h, label_h)); /* primary icon */ if (priv->icon1) { child_box.y1 = padding.top + (header_h / 2.0) - (icon1_h / 2.0); child_box.x1 = padding.left; child_box.y2 = child_box.y1 + icon1_h; child_box.x2 = child_box.x1 + icon1_w; clutter_actor_allocate (priv->icon1, &child_box, flags); child_box.x1 += icon1_w + 8; } else child_box.x1 = padding.left; /* label */ child_box.x2 = child_box.x1 + label_w; child_box.y1 = (int) (padding.top + (header_h / 2.0) - (label_h / 2.0)); child_box.y2 = child_box.y1 + label_h; fade = clutter_actor_get_effect (priv->box_layout, "fade"); middle_w = available_width - icon1_w - icon2_w; if (priv->header_padding) middle_w -= priv->header_padding->left + priv->header_padding->right; clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (fade), !(middle_w > label_w)); mx_fade_effect_set_bounds (MX_FADE_EFFECT (fade), 0, 0, middle_w, 0); clutter_actor_allocate (priv->box_layout, &child_box, flags); /* secondary icon */ if (priv->icon2) { child_box.x2 = (box->x2 - box->x1) - padding.right; child_box.x1 = child_box.x2 - icon2_w; child_box.y1 = padding.top + (header_h / 2.0) - (icon2_h / 2.0); child_box.y2 = child_box.y1 + icon2_h; clutter_actor_allocate (priv->icon2, &child_box, flags); } priv->header_height = header_h; if (priv->header_padding) priv->header_height += priv->header_padding->top + priv->header_padding->bottom; } }
static void mx_label_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MxLabelPrivate *priv = MX_LABEL (actor)->priv; gboolean label_did_fade = priv->label_should_fade; ClutterActorClass *parent_class; ClutterActorBox child_box; gboolean x_fill, y_fill; gfloat avail_width; parent_class = CLUTTER_ACTOR_CLASS (mx_label_parent_class); parent_class->allocate (actor, box, flags); mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box); avail_width = child_box.x2 - child_box.x1; /* The default behaviour of ClutterText is to align to the * top-left when it gets more space than is needed. Because * of this behaviour, if we're aligning to the left, we can * assign all our horizontal space to the label without * measuring it (i.e. x-fill), and the same applies for * aligning to the top and vertical space. */ x_fill = (priv->x_align == MX_ALIGN_START) ? TRUE : FALSE; y_fill = (priv->y_align == MX_ALIGN_START) ? TRUE : FALSE; mx_allocate_align_fill (priv->label, &child_box, priv->x_align, priv->y_align, x_fill, y_fill); priv->label_should_fade = FALSE; if (priv->fade_out) { /* If we're fading out, make sure the label has its full width * allocated. This ensures that the offscreen effect has the full * label inside its texture. */ gfloat label_width; clutter_actor_get_preferred_width (priv->label, -1, NULL, &label_width); if (label_width > avail_width) { priv->label_should_fade = TRUE; child_box.x2 = child_box.x1 + label_width; } mx_fade_effect_set_bounds (MX_FADE_EFFECT (priv->fade_effect), 0, 0, MIN (label_width, avail_width), 0); } /* Allocate the label */ clutter_actor_allocate (priv->label, &child_box, flags); if (priv->show_tooltip) { PangoLayout *layout; const gchar *text; layout = clutter_text_get_layout (CLUTTER_TEXT (priv->label)); if (pango_layout_is_ellipsized (layout)) text = clutter_text_get_text (CLUTTER_TEXT (priv->label)); else text = NULL; mx_widget_set_tooltip_text (MX_WIDGET (actor), text); } /* Animate in/out the faded end of the label */ if (label_did_fade != priv->label_should_fade) { /* Begin/reverse the fading timeline when necessary */ if (priv->label_should_fade) clutter_timeline_set_direction (priv->fade_timeline, CLUTTER_TIMELINE_FORWARD); else clutter_timeline_set_direction (priv->fade_timeline, CLUTTER_TIMELINE_BACKWARD); if (!clutter_timeline_is_playing (priv->fade_timeline)) clutter_timeline_rewind (priv->fade_timeline); clutter_timeline_start (priv->fade_timeline); } }