static void mex_grid_view_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MexGridViewPrivate *priv = MEX_GRID_VIEW (actor)->priv; gfloat menu_min_width, menu_width, grid_width; ClutterActorBox child_box; CLUTTER_ACTOR_CLASS (mex_grid_view_parent_class)->allocate (actor, box, flags); /* menu */ clutter_actor_get_preferred_width (priv->menu_layout, -1, &menu_min_width, &menu_width); mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box); child_box.x2 = child_box.x1 + MAX (MENU_MIN_WIDTH, menu_width); if (priv->state == STATE_CLOSING_STAGE2) clutter_actor_box_interpolate (&child_box, &priv->target_box, clutter_alpha_get_alpha (priv->alpha), &child_box); clutter_actor_allocate (priv->menu_layout, &child_box, flags); /* grid */ mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box); child_box.y1 += GRID_TOP_PADDING; child_box.x1 = child_box.x1 + MENU_MIN_WIDTH; grid_width = child_box.x2 - child_box.x1; if (priv->state == STATE_OPENING) child_box.x2 = child_box.x1 + grid_width * clutter_alpha_get_alpha (priv->alpha); else if (priv->state == STATE_CLOSING_STAGE1) child_box.x2 = child_box.x1 + grid_width * (1 - clutter_alpha_get_alpha (priv->alpha)); else if (priv->state == STATE_CLOSED || priv->state == STATE_CLOSING_STAGE2) child_box.x2 = child_box.x1; clutter_actor_allocate (priv->grid_layout, &child_box, flags); }
static void mex_info_bar_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { ClutterActorBox child_box; MexInfoBarPrivate *priv = MEX_INFO_BAR (actor)->priv; CLUTTER_ACTOR_CLASS (mex_info_bar_parent_class)-> allocate (actor, box, flags); mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box); clutter_actor_allocate (priv->group, &child_box, flags); }
static void mex_media_controls_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { ClutterActorBox child_box; MexMediaControlsPrivate *priv = MEX_MEDIA_CONTROLS (actor)->priv; CLUTTER_ACTOR_CLASS (mex_media_controls_parent_class)-> allocate (actor, box, flags); mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box); clutter_actor_allocate (priv->vbox, &child_box, flags); }
static void mx_frame_allocate (ClutterActor *self, const ClutterActorBox *box, ClutterAllocationFlags flags) { MxFramePrivate *priv = ((MxFrame *) self)->priv; ClutterActorBox childbox; CLUTTER_ACTOR_CLASS (mx_frame_parent_class)->allocate (self, box, flags); if (priv->child) { mx_widget_get_available_area (MX_WIDGET (self), box, &childbox); clutter_actor_allocate (priv->child, &childbox, flags); } }
static void mex_clock_bin_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { ClutterActorBox childbox; MexClockBinPrivate *priv = MEX_CLOCK_BIN (actor)->priv; CLUTTER_ACTOR_CLASS (mex_clock_bin_parent_class)-> allocate (actor, box, flags); if (priv->child) { mx_widget_get_available_area (MX_WIDGET (actor), box, &childbox); clutter_actor_allocate (priv->child, &childbox, flags); } }
static void mx_toggle_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MxTogglePrivate *priv = MX_TOGGLE (actor)->priv; ClutterActorBox handle_box, child_box; CoglHandle background; gfloat handle_w; gfloat toggle_pos; CLUTTER_ACTOR_CLASS (mx_toggle_parent_class)->allocate (actor, box, flags); mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box); /* background-image don't get stretched, so adjust the child box so that the * handle appears in the correct place. */ background = mx_widget_get_background_texture (MX_WIDGET (actor)); if (background) { gfloat width; MxPadding padding; mx_widget_get_padding (MX_WIDGET (actor), &padding); width = cogl_texture_get_width (background); width -= padding.left + padding.right; child_box.x1 += (child_box.x2 - child_box.x1) / 2.f; child_box.x1 -= width / 2.f; child_box.x2 = child_box.x1 + width; } clutter_actor_get_preferred_width (priv->handle, -1, NULL, &handle_w); toggle_pos = child_box.x2 - handle_w - child_box.x1; priv->slide_length = toggle_pos; toggle_pos = toggle_pos * priv->position; handle_box.x1 = (gint) (child_box.x1 + toggle_pos); handle_box.y1 = child_box.y1; handle_box.x2 = handle_box.x1 + handle_w; handle_box.y2 = child_box.y2; clutter_actor_allocate (priv->handle, &handle_box, flags); }
static void mx_toolbar_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MxToolbarPrivate *priv = MX_TOOLBAR (actor)->priv; ClutterActorBox childbox, avail; gfloat close_w; CLUTTER_ACTOR_CLASS (mx_toolbar_parent_class)->allocate (actor, box, flags); mx_widget_get_available_area (MX_WIDGET (actor), box, &avail); if (priv->close_button) { gfloat pref_h; clutter_actor_get_preferred_size (priv->close_button, NULL, NULL, &close_w, &pref_h); childbox.x1 = avail.x2 - close_w; childbox.y1 = avail.y1; childbox.x2 = avail.x2; childbox.y2 = avail.y2; clutter_actor_allocate (priv->close_button, &childbox, flags); } else { close_w = 0; } if (priv->child) { childbox.x1 = avail.x1; childbox.y1 = avail.y1; childbox.x2 = MAX (childbox.x1, avail.x2 - close_w - SPACING); childbox.y2 = MAX (childbox.y1, avail.y2); clutter_actor_allocate (priv->child, &childbox, flags); } }
static void mx_stack_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { GList *c; ClutterActorBox avail_space; MxStackPrivate *priv = MX_STACK (actor)->priv; CLUTTER_ACTOR_CLASS (mx_stack_parent_class)->allocate (actor, box, flags); mx_widget_get_available_area (MX_WIDGET (actor), box, &avail_space); memcpy (&priv->allocation, box, sizeof (priv->allocation)); for (c = priv->children; c; c = c->next) { gboolean x_fill, y_fill, fit, crop; MxAlign x_align, y_align; ClutterActor *child = c->data; ClutterActorBox child_box = avail_space; if (!CLUTTER_ACTOR_IS_VISIBLE (child)) continue; clutter_container_child_get (CLUTTER_CONTAINER (actor), child, "x-fill", &x_fill, "y-fill", &y_fill, "x-align", &x_align, "y-align", &y_align, "fit", &fit, "crop", &crop, NULL); /* when "crop" is set, fit and fill properties are ignored */ if (crop) { gfloat available_height, available_width; gfloat natural_width, natural_height; gfloat ratio_width, ratio_height, ratio_child; available_width = avail_space.x2 - avail_space.x1; available_height = avail_space.y2 - avail_space.y1; clutter_actor_get_preferred_size (child, NULL, NULL, &natural_width, &natural_height); ratio_child = natural_width / natural_height; ratio_width = available_width / natural_width; ratio_height = available_height / natural_height; if (ratio_width > ratio_height) { natural_width = available_width; natural_height = natural_width / ratio_child; } else { natural_height = available_height; natural_width = ratio_child * natural_height; } child_box.x1 = (available_width - natural_width) / 2; child_box.y1 = (available_height - natural_height) / 2; child_box.x2 = natural_width; child_box.y2 = natural_height; clutter_actor_allocate (child, &child_box, flags); continue; } /* when "fit" is set, fill properties are ignored */ if (fit) { gfloat available_height, available_width, width, height; gfloat min_width, natural_width, min_height, natural_height; ClutterRequestMode request_mode; available_height = avail_space.y2 - avail_space.y1; available_width = avail_space.x2 - avail_space.x1; request_mode = clutter_actor_get_request_mode (child); if (request_mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH) { clutter_actor_get_preferred_width (child, available_height, &min_width, &natural_width); width = CLAMP (natural_width, min_width, available_width); clutter_actor_get_preferred_height (child, width, &min_height, &natural_height); height = CLAMP (natural_height, min_height, available_height); } else { clutter_actor_get_preferred_height (child, available_width, &min_height, &natural_height); height = CLAMP (natural_height, min_height, available_height); clutter_actor_get_preferred_width (child, height, &min_width, &natural_width); width = CLAMP (natural_width, min_width, available_width); } child_box.x1 = 0; child_box.y1 = 0; switch (x_align) { case MX_ALIGN_START: break; case MX_ALIGN_MIDDLE: child_box.x1 += (gint)(available_width / 2 - width / 2); break; case MX_ALIGN_END: child_box.x1 = avail_space.x2 - width; break; } switch (y_align) { case MX_ALIGN_START: break; case MX_ALIGN_MIDDLE: child_box.y1 += (gint)(available_height / 2 - height / 2); break; case MX_ALIGN_END: child_box.y1 = avail_space.y2 - height; break; } child_box.x2 = child_box.x1 + width; child_box.y2 = child_box.y1 + height; clutter_actor_allocate (child, &child_box, flags); continue; } /* Adjust the available space when not filling, otherwise * actors that support width-for-height or height-for-width * allocation won't shrink correctly. */ if (!x_fill) { gfloat width; clutter_actor_get_preferred_width (child, -1, NULL, &width); switch (x_align) { case MX_ALIGN_START: break; case MX_ALIGN_MIDDLE: child_box.x1 += (gint)((avail_space.x2 - avail_space.x1) / 2 - width / 2); break; case MX_ALIGN_END: child_box.x1 = avail_space.x2 - width; break; } child_box.x2 = child_box.x1 + width; if (child_box.x2 > avail_space.x2) child_box.x2 = avail_space.x2; if (child_box.x1 < avail_space.x1) child_box.x1 = avail_space.x1; } if (!y_fill) { gfloat height; clutter_actor_get_preferred_height (child, -1, NULL, &height); switch (y_align) { case MX_ALIGN_START: break; case MX_ALIGN_MIDDLE: child_box.y1 += (gint)((avail_space.y2 - avail_space.y1) / 2 - height / 2); break; case MX_ALIGN_END: child_box.y1 = avail_space.y2 - height; break; } child_box.y2 = child_box.y1 + height; if (child_box.y2 > avail_space.y2) child_box.y2 = avail_space.y2; if (child_box.y1 < avail_space.y1) child_box.y1 = avail_space.y1; } mx_allocate_align_fill (child, &child_box, x_align, y_align, x_fill, y_fill); clutter_actor_allocate (child, &child_box, flags); } }
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); } }