static void mex_music_player_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MexMusicPlayerPrivate *priv = MEX_MUSIC_PLAYER (actor)->priv; ClutterActorBox child_box; ClutterActor *child; gfloat w, h; MxPadding padding; CLUTTER_ACTOR_CLASS (mex_music_player_parent_class)->allocate (actor, box, flags); mx_widget_get_padding (MX_WIDGET (actor), &padding); child = mex_script_get_actor (priv->script, "box"); clutter_actor_get_preferred_size (child, NULL, NULL, &w, &h); child_box.x1 = padding.left + (box->x2 - box->x1 - padding.left - padding.right) / 2 - w / 2; child_box.y1 = (box->y2 - box->y1 - padding.bottom) - h; child_box.x2 = child_box.x1 + w; child_box.y2 = child_box.y1 + h; clutter_actor_allocate (child, &child_box, flags); }
static ClutterUnit compute_row_height (GList *siblings, ClutterUnit best_yet, ClutterUnit current_a, TidyGridPrivate *priv) { GList *l; gboolean homogenous_a; gboolean homogenous_b; ClutterUnit gap; if (priv->column_major) { homogenous_b = priv->homogenous_columns; homogenous_a = priv->homogenous_rows; gap = priv->row_gap; } else { homogenous_a = priv->homogenous_columns; homogenous_b = priv->homogenous_rows; gap = priv->column_gap; } for (l = siblings; l != NULL; l = l->next) { ClutterActor *child = l->data; ClutterUnit natural_width, natural_height; /* each child will get as much space as they require */ clutter_actor_get_preferred_size (CLUTTER_ACTOR (child), NULL, NULL, &natural_width, &natural_height); if (priv->column_major) { ClutterUnit temp = natural_height; natural_height = natural_width; natural_width = temp; } /* if the primary axis is homogenous, each additional item is the same * width */ if (homogenous_a) natural_width = priv->max_extent_a; if (natural_height > best_yet) best_yet = natural_height; /* if the child is overflowing, we wrap to next line */ if (current_a + natural_width + gap > priv->a_wrap) { return best_yet; } current_a += natural_width + gap; } return best_yet; }
static void video_aspect_frame_allocate(ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { ClutterActor *container, *camera; ClutterActorBox container_box; gfloat frame_aspect, frame_box_width, frame_box_height, camera_aspect, camera_width, camera_height; CLUTTER_ACTOR_CLASS(video_aspect_frame_parent_class)->allocate(actor, box, flags); /* the first child in the frame is always the camera container */ container = clutter_actor_get_child_at_index(actor, 0); if (!container) return; /* the first child in the container is always the main camera that must fill the * container */ camera = clutter_actor_get_child_at_index(container, 0); if (!camera) return; /* retrieve the size allocated for the frame box */ frame_box_width = box->x2 - box->x1; frame_box_height = box->y2 - box->y1; /* retrieve the preferred size for the main camera in container box */ clutter_actor_get_preferred_size(camera, NULL, NULL, &camera_width, &camera_height); if (camera_width <= 0.0f || camera_height <= 0.0f) return; frame_aspect = frame_box_width / frame_box_height; camera_aspect = camera_width / camera_height; /* resize the camera actor to fit in the frame box without loosing * its aspect ratio */ if (frame_aspect < camera_aspect) { camera_width = frame_box_width; camera_height = frame_box_width / camera_aspect; } else { camera_height = frame_box_height; camera_width = frame_box_height * camera_aspect; } /* center the container box in the space left inside the frame box */ container_box.x1 = (frame_box_width - camera_width) / 2; container_box.y1 = (frame_box_height - camera_height) / 2; container_box.x2 = container_box.x1 + camera_width; container_box.y2 = container_box.y1 + camera_height; /* finally really allocate the container */ clutter_actor_allocate(container, &container_box, flags); }
static void mpl_entry_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MplEntryPrivate *priv = MPL_ENTRY (actor)->priv; MxPadding padding = { 0, 0, 0, 0 }; ClutterActorBox entry_box, button_box; gfloat entry_width, entry_height, button_width, button_height; CLUTTER_ACTOR_CLASS (mpl_entry_parent_class)-> allocate (actor, box, flags); mx_widget_get_padding (MX_WIDGET (actor), &padding); /* Button is right-aligned. */ clutter_actor_get_preferred_size (priv->table, NULL, NULL, &button_width, &button_height); button_box.x2 = (int) (box->x2 - box->x1 - padding.right); button_box.x1 = (int) (button_box.x2 - button_width); button_box.y1 = (int) (((box->y2 - box->y1) - button_height) / 2); button_box.y2 = (int) (button_box.y1 + button_height); /* Sanity check. */ button_box.x1 = (int) (MAX (padding.left, button_box.x1)); button_box.x2 = (int) (MAX (padding.left, button_box.x2)); /* Entry is left-aligned. */ clutter_actor_get_preferred_size (priv->entry, NULL, NULL, &entry_width, &entry_height); entry_box.x1 = (int) (padding.left); entry_box.x2 = (int) (button_box.x1); entry_box.y1 = (int) (((box->y2 - box->y1) - entry_height) / 2); entry_box.y2 = (int) (entry_box.y1 + entry_height); clutter_actor_allocate (priv->entry, &entry_box, flags); clutter_actor_allocate (priv->table, &button_box, flags); }
static void mex_column_view_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { gfloat header_pref_height, pref_h, pref_w; ClutterActorBox child_box; MxPadding padding; MexColumnView *column = MEX_COLUMN_VIEW (actor); MexColumnViewPrivate *priv = column->priv; CLUTTER_ACTOR_CLASS (mex_column_view_parent_class)->allocate (actor, box, flags); mx_widget_get_padding (MX_WIDGET (actor), &padding); /* Allocate header */ child_box.x1 = padding.left; child_box.x2 = box->x2 - box->x1 - padding.right; child_box.y1 = padding.top; clutter_actor_get_preferred_height (priv->header, child_box.x2 - child_box.x1, NULL, &header_pref_height); child_box.y2 = child_box.y1 + header_pref_height; clutter_actor_allocate (priv->header, &child_box, flags); /* Allocate placeholder/column actor */ child_box.y1 = padding.top + header_pref_height; /* scroll view */ child_box.y2 = box->y2 - box->y1 - padding.bottom; clutter_actor_allocate (priv->scroll, &child_box, flags); /* placeholder */ if (mex_column_is_empty (MEX_COLUMN (priv->column)) && priv->placeholder_actor) { /* keep the aspect ratio of the placeholder actor */ clutter_actor_get_preferred_size (priv->placeholder_actor, NULL, NULL, &pref_w, &pref_h); pref_h = pref_h * ((child_box.x2 - child_box.x1) / pref_w); child_box.y2 = child_box.y1 + pref_h; clutter_actor_allocate (priv->placeholder_actor, &child_box, flags); } }
static void mnb_zones_preview_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { gint n; GList *w; gfloat origin, bin_width; MnbZonesPreviewPrivate *priv = MNB_ZONES_PREVIEW (actor)->priv; CLUTTER_ACTOR_CLASS (mnb_zones_preview_parent_class)-> allocate (actor, box, flags); /* Figure out the origin */ bin_width = priv->width + priv->spacing; origin = - (priv->workspace * bin_width * priv->zoom); /* Make sure we zoom out from the centre */ origin += (bin_width - (bin_width * priv->zoom)) / 2.0; for (n = 0, w = priv->workspace_bins; w; w = w->next, n++) { ClutterActorBox child_box; gfloat width, height; MxPadding padding; ClutterActor *bin = CLUTTER_ACTOR (w->data); clutter_actor_get_preferred_size (bin, NULL, NULL, &width, &height); width *= priv->zoom; height *= priv->zoom; mx_widget_get_padding (MX_WIDGET (bin), &padding); /* We allocate the preferred size, but we make sure the padding is * 'outside' the target area. */ child_box.x1 = origin - padding.left; child_box.x2 = child_box.x1 + width; child_box.y1 = (((box->y2 - box->y1) - (height - padding.top - padding.bottom)) / 2.f) - padding.top; child_box.y2 = child_box.y1 + height; clutter_actor_allocate (bin, &child_box, flags); origin = (child_box.x2 - padding.right) + (priv->spacing * priv->zoom); } }
IO_METHOD(IoClutterActor, getPreferredSize) { float min_width = 0, min_height = 0, natural_width = 0, natural_height = 0; IoObject *p_size = IoObject_new(IOSTATE); clutter_actor_get_preferred_size( IOCACTOR(self), &min_width, &min_height, &natural_width, &natural_height ); IoObject_setSlot_to_(p_size, IOSYMBOL("minWidth"), IONUMBER(min_width)); IoObject_setSlot_to_(p_size, IOSYMBOL("minHeight"), IONUMBER(min_height)); IoObject_setSlot_to_(p_size, IOSYMBOL("naturalHeight"), IONUMBER(natural_width)); IoObject_setSlot_to_(p_size, IOSYMBOL("naturalHeight"), IONUMBER(natural_height)); return p_size; }
static void clutter_fixed_layout_get_preferred_width (ClutterLayoutManager *manager, ClutterContainer *container, gfloat for_height, gfloat *min_width_p, gfloat *nat_width_p) { ClutterActor *actor, *child; gdouble min_right; gdouble natural_right; min_right = 0; natural_right = 0; actor = CLUTTER_ACTOR (container); for (child = clutter_actor_get_first_child (actor); child != NULL; child = clutter_actor_get_next_sibling (child)) { gfloat child_x, child_min, child_natural; child_x = clutter_actor_get_x (child); clutter_actor_get_preferred_size (child, &child_min, NULL, &child_natural, NULL); if (child_x + child_min > min_right) min_right = child_x + child_min; if (child_x + child_natural > natural_right) natural_right = child_x + child_natural; } if (min_width_p) *min_width_p = min_right; if (nat_width_p) *nat_width_p = natural_right; }
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 clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager, ClutterContainer *container, gfloat for_width, gfloat *min_height_p, gfloat *nat_height_p) { ClutterActor *actor, *child; gdouble min_bottom; gdouble natural_bottom; min_bottom = 0; natural_bottom = 0; actor = CLUTTER_ACTOR (container); for (child = clutter_actor_get_first_child (actor); child != NULL; child = clutter_actor_get_next_sibling (child)) { gfloat child_y, child_min, child_natural; child_y = clutter_actor_get_y (child); clutter_actor_get_preferred_size (child, NULL, &child_min, NULL, &child_natural); if (child_y + child_min > min_bottom) min_bottom = child_y + child_min; if (child_y + child_natural > natural_bottom) natural_bottom = child_y + child_natural; } if (min_height_p) *min_height_p = min_bottom; if (nat_height_p) *nat_height_p = natural_bottom; }
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); } } }
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); } }
/* Allocate position and size of actor and its children */ static void _xfdashboard_viewpad_allocate(ClutterActor *self, const ClutterActorBox *inBox, ClutterAllocationFlags inFlags) { XfdashboardViewpadPrivate *priv=XFDASHBOARD_VIEWPAD(self)->priv; ClutterActorClass *actorClass=CLUTTER_ACTOR_CLASS(xfdashboard_viewpad_parent_class); gfloat viewWidth, viewHeight; gfloat vScrollbarWidth, vScrollbarHeight; gfloat hScrollbarWidth, hScrollbarHeight; gboolean hScrollbarVisible, vScrollbarVisible; ClutterActorBox *box; gfloat x, y, w, h; /* Chain up to store the allocation of the actor */ if(actorClass->allocate) actorClass->allocate(self, inBox, inFlags); /* Initialize largest possible allocation for view and determine * real size of view to show. The real size is used to determine * scroll bar visibility if policy is automatic */ viewWidth=clutter_actor_box_get_width(inBox); viewHeight=clutter_actor_box_get_height(inBox); /* Determine visibility of scroll bars */ hScrollbarVisible=FALSE; if(priv->hScrollbarPolicy==XFDASHBOARD_POLICY_ALWAYS || (priv->hScrollbarPolicy==XFDASHBOARD_POLICY_AUTOMATIC && xfdashboard_scrollbar_get_range(XFDASHBOARD_SCROLLBAR(priv->hScrollbar))>viewWidth)) { hScrollbarVisible=TRUE; } if(xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_HORIZONTAL || xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_BOTH) { hScrollbarVisible=FALSE; } vScrollbarVisible=FALSE; if(priv->vScrollbarPolicy==XFDASHBOARD_POLICY_ALWAYS || (priv->vScrollbarPolicy==XFDASHBOARD_POLICY_AUTOMATIC && xfdashboard_scrollbar_get_range(XFDASHBOARD_SCROLLBAR(priv->vScrollbar))>viewHeight)) { vScrollbarVisible=TRUE; } if(xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_VERTICAL || xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))==XFDASHBOARD_FIT_MODE_BOTH) { vScrollbarVisible=FALSE; } /* Set allocation for visible scroll bars */ vScrollbarWidth=0.0f; vScrollbarHeight=viewHeight; clutter_actor_get_preferred_width(priv->vScrollbar, -1, NULL, &vScrollbarWidth); hScrollbarWidth=viewWidth; hScrollbarHeight=0.0f; clutter_actor_get_preferred_height(priv->hScrollbar, -1, NULL, &hScrollbarHeight); if(hScrollbarVisible && vScrollbarVisible) { vScrollbarHeight-=hScrollbarHeight; hScrollbarWidth-=vScrollbarWidth; } if(vScrollbarVisible==FALSE) box=clutter_actor_box_new(0, 0, 0, 0); else box=clutter_actor_box_new(viewWidth-vScrollbarWidth, 0, viewWidth, vScrollbarHeight); clutter_actor_allocate(priv->vScrollbar, box, inFlags); clutter_actor_box_free(box); if(hScrollbarVisible==FALSE) box=clutter_actor_box_new(0, 0, 0, 0); else box=clutter_actor_box_new(0, viewHeight-hScrollbarHeight, hScrollbarWidth, viewHeight); clutter_actor_allocate(priv->hScrollbar, box, inFlags); clutter_actor_box_free(box); /* Reduce allocation for view by any visible scroll bar * and set allocation and clipping of view */ if(priv->activeView) { /* Set allocation */ if(vScrollbarVisible) viewWidth-=vScrollbarWidth; if(hScrollbarVisible) viewHeight-=hScrollbarHeight; x=y=0.0f; if(clutter_actor_has_clip(CLUTTER_ACTOR(priv->activeView))) { clutter_actor_get_clip(CLUTTER_ACTOR(priv->activeView), &x, &y, NULL, NULL); } switch(xfdashboard_view_get_fit_mode(XFDASHBOARD_VIEW(priv->activeView))) { case XFDASHBOARD_FIT_MODE_BOTH: w=viewWidth; h=viewHeight; break; case XFDASHBOARD_FIT_MODE_HORIZONTAL: w=viewWidth; clutter_actor_get_preferred_height(CLUTTER_ACTOR(priv->activeView), w, NULL, &h); break; case XFDASHBOARD_FIT_MODE_VERTICAL: h=viewHeight; clutter_actor_get_preferred_width(CLUTTER_ACTOR(priv->activeView), h, NULL, &w); break; default: clutter_actor_get_preferred_size(CLUTTER_ACTOR(priv->activeView), NULL, NULL, &w, &h); break; } box=clutter_actor_box_new(0, 0, w, h); clutter_actor_allocate(CLUTTER_ACTOR(priv->activeView), box, inFlags); clutter_actor_box_free(box); clutter_actor_set_clip(CLUTTER_ACTOR(priv->activeView), x, y, viewWidth, viewHeight); } /* Only set value if it changes */ if(priv->hScrollbarVisible!=hScrollbarVisible) { /* Set new value */ priv->hScrollbarVisible=hScrollbarVisible; /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_HSCROLLBAR_VISIBLE]); } if(priv->vScrollbarVisible!=vScrollbarVisible) { /* Set new value */ priv->vScrollbarVisible=vScrollbarVisible; /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_VSCROLLBAR_VISIBLE]); } }
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 tidy_grid_allocate (ClutterActor *self, const ClutterActorBox *box, gboolean absolute_origin_changed) { TidyGrid *layout = (TidyGrid *) self; TidyGridPrivate *priv = layout->priv; ClutterUnit current_a; ClutterUnit current_b; ClutterUnit next_b; ClutterUnit agap; ClutterUnit bgap; gboolean homogenous_a; gboolean homogenous_b; gdouble aalign; gdouble balign; current_a = current_b = next_b = 0; GList *iter; /* chain up to set actor->allocation */ CLUTTER_ACTOR_CLASS (tidy_grid_parent_class) ->allocate (self, box, absolute_origin_changed); priv->alloc_width = box->x2 - box->x1; priv->alloc_height = box->y2 - box->y1; priv->absolute_origin_changed = absolute_origin_changed; /* Make sure we have calculated the preferred size */ /* what does this do? */ clutter_actor_get_preferred_size (self, NULL, NULL, NULL, NULL); if (priv->column_major) { priv->a_wrap = priv->alloc_height; homogenous_b = priv->homogenous_columns; homogenous_a = priv->homogenous_rows; aalign = priv->valign; balign = priv->halign; agap = priv->row_gap; bgap = priv->column_gap; } else { priv->a_wrap = priv->alloc_width; homogenous_a = priv->homogenous_columns; homogenous_b = priv->homogenous_rows; aalign = priv->halign; balign = priv->valign; agap = priv->column_gap; bgap = priv->row_gap; } priv->max_extent_a = 0; priv->max_extent_b = 0; priv->first_of_batch = TRUE; if (homogenous_a || homogenous_b) { for (iter = priv->list; iter; iter = iter->next) { ClutterActor *child = iter->data; ClutterUnit natural_width; ClutterUnit natural_height; /* each child will get as much space as they require */ clutter_actor_get_preferred_size (CLUTTER_ACTOR (child), NULL, NULL, &natural_width, &natural_height); if (natural_width > priv->max_extent_a) priv->max_extent_a = natural_width; if (natural_height > priv->max_extent_b) priv->max_extent_b = natural_width; } } if (priv->column_major) { ClutterUnit temp = priv->max_extent_a; priv->max_extent_a = priv->max_extent_b; priv->max_extent_b = temp; } for (iter = priv->list; iter; iter=iter->next) { ClutterActor *child = iter->data; ClutterUnit natural_a; ClutterUnit natural_b; /* each child will get as much space as they require */ clutter_actor_get_preferred_size (CLUTTER_ACTOR (child), NULL, NULL, &natural_a, &natural_b); if (priv->column_major) /* swap axes around if column is major */ { ClutterUnit temp = natural_a; natural_a = natural_b; natural_b = temp; } /* if the child is overflowing, we wrap to next line */ if (current_a + natural_a > priv->a_wrap || (homogenous_a && current_a + priv->max_extent_a > priv->a_wrap)) { current_b = next_b + bgap; current_a = 0; next_b = current_b + bgap; priv->first_of_batch = TRUE; } if (priv->end_align && priv->first_of_batch) { current_a = compute_row_start (iter, current_a, priv); priv->first_of_batch = FALSE; } if (next_b-current_b < natural_b) next_b = current_b + natural_b; { ClutterUnit row_height; ClutterActorBox child_box; if (homogenous_b) { row_height = priv->max_extent_b; } else { row_height = compute_row_height (iter, next_b-current_b, current_a, priv); } if (homogenous_a) { child_box.x1 = current_a + (priv->max_extent_a-natural_a) * aalign; child_box.x2 = child_box.x1 + natural_a; } else { child_box.x1 = current_a; child_box.x2 = child_box.x1 + natural_a; } child_box.y1 = current_b + (row_height-natural_b) * balign; child_box.y2 = child_box.y1 + natural_b; if (priv->column_major) { ClutterUnit temp = child_box.x1; child_box.x1 = child_box.y1; child_box.y1 = temp; temp = child_box.x2; child_box.x2 = child_box.y2; child_box.y2 = temp; } /* update the allocation */ clutter_actor_allocate (CLUTTER_ACTOR (child), &child_box, absolute_origin_changed); if (homogenous_a) { current_a += priv->max_extent_a + agap; } else { current_a += natural_a + agap; } } } }
/* Get minimum and natural size of all visible children */ static void _xfdashboard_fill_box_layout_get_sizes_for_all(XfdashboardFillBoxLayout *self, ClutterContainer *inContainer, gfloat *outMinWidth, gfloat *outNaturalWidth, gfloat *outMinHeight, gfloat *outNaturalHeight) { XfdashboardFillBoxLayoutPrivate *priv; ClutterActor *child; ClutterActorIter iter; gint numberChildren; gfloat minWidth, naturalWidth; gfloat minHeight, naturalHeight; gfloat childMinWidth, childNaturalWidth; gfloat childMinHeight, childNaturalHeight; ClutterActor *parent; gfloat parentWidth, parentHeight; gfloat aspectRatio; g_return_if_fail(XFDASHBOARD_IS_FILL_BOX_LAYOUT(self)); g_return_if_fail(CLUTTER_IS_CONTAINER(inContainer)); g_return_if_fail(CLUTTER_IS_ACTOR(inContainer)); priv=self->priv; /* Initialize return values */ numberChildren=0; minWidth=naturalWidth=minHeight=naturalHeight=0.0f; /* If not homogeneous then iterate through all children and determine sizes ... */ if(priv->isHomogeneous==FALSE) { /* Iterate through children and calculate sizes */ clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inContainer)); while(clutter_actor_iter_next(&iter, &child)) { /* Only get sizes of visible children */ if(!clutter_actor_is_visible(child)) continue; /* Count visible children */ numberChildren++; /* Determine sizes of visible child */ clutter_actor_get_preferred_size(child, &childMinWidth, &childNaturalWidth, &childMinHeight, &childNaturalHeight); if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) { minWidth+=childMinWidth; naturalWidth+=childNaturalWidth; if(childMinHeight>minHeight) minHeight=childMinHeight; if(childNaturalHeight>naturalHeight) naturalHeight=childNaturalHeight; } else { minHeight+=childMinHeight; naturalHeight+=childNaturalHeight; if(childMinWidth>naturalWidth) minWidth=naturalWidth; if(childNaturalWidth>naturalHeight) naturalHeight=childNaturalWidth; } } } /* ... otherwise get largest minimum and natural size and add spacing */ else { /* Get number of visible children and also largest minimum * and natural size */ numberChildren=_xfdashboard_fill_box_layout_get_largest_sizes(self, inContainer, &childMinWidth, &childNaturalWidth, &childMinHeight, &childNaturalHeight); /* Multiply largest sizes with number visible children */ if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) { minWidth=(numberChildren*childMinWidth); naturalWidth=(numberChildren*childNaturalWidth); minHeight=childMinHeight; naturalHeight=childNaturalHeight; } else { minWidth=childMinWidth; naturalWidth=childNaturalWidth; minHeight=(numberChildren*childMinHeight); naturalHeight=(numberChildren*childNaturalHeight); } } /* Add spacing */ if(numberChildren>0) { numberChildren--; if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) { minWidth+=numberChildren*priv->spacing; naturalWidth+=numberChildren*priv->spacing; } else { minHeight+=numberChildren*priv->spacing; naturalHeight+=numberChildren*priv->spacing; } } /* Depending on orientation set sizes to fit into parent actor */ parent=clutter_actor_get_parent(CLUTTER_ACTOR(inContainer)); if(parent) { aspectRatio=1.0f; clutter_actor_get_size(CLUTTER_ACTOR(parent), &parentWidth, &parentHeight); if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) { if(priv->keepAspect==TRUE) { aspectRatio=minWidth/minHeight; minHeight=parentHeight; minWidth=minHeight*aspectRatio; aspectRatio=naturalWidth/naturalHeight; naturalHeight=parentHeight; naturalWidth=naturalHeight*aspectRatio; } else { minHeight=parentHeight; naturalHeight=parentHeight; } } else { if(priv->keepAspect==TRUE) { aspectRatio=minHeight/minWidth; minWidth=parentWidth; minHeight=minWidth*aspectRatio; aspectRatio=naturalHeight/naturalWidth; naturalWidth=parentWidth; naturalHeight=naturalWidth*aspectRatio; } else { minWidth=parentWidth; naturalWidth=parentWidth; } } } /* Set return values */ if(outMinWidth) *outMinWidth=minWidth; if(outNaturalWidth) *outNaturalWidth=naturalWidth; if(outMinHeight) *outMinHeight=minHeight; if(outNaturalHeight) *outNaturalHeight=naturalHeight; }
/* Get largest minimum and natural size of all visible children * for calculation of one child and returns the number of visible ones */ static gint _xfdashboard_fill_box_layout_get_largest_sizes(XfdashboardFillBoxLayout *self, ClutterContainer *inContainer, gfloat *outMinWidth, gfloat *outNaturalWidth, gfloat *outMinHeight, gfloat *outNaturalHeight) { XfdashboardFillBoxLayoutPrivate *priv; ClutterActor *child; ClutterActorIter iter; gint numberChildren; gfloat largestMinWidth, largestNaturalWidth; gfloat largestMinHeight, largestNaturalHeight; gfloat childMinWidth, childNaturalWidth; gfloat childMinHeight, childNaturalHeight; ClutterActor *parent; gfloat parentWidth, parentHeight; gfloat aspectRatio; g_return_val_if_fail(XFDASHBOARD_IS_FILL_BOX_LAYOUT(self), 0); g_return_val_if_fail(CLUTTER_IS_CONTAINER(inContainer), 0); g_return_val_if_fail(CLUTTER_IS_ACTOR(inContainer), 0); priv=self->priv; /* Iterate through all children and determine sizes */ numberChildren=0; largestMinWidth=largestNaturalWidth=largestMinHeight=largestNaturalHeight=0.0f; clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inContainer)); while(clutter_actor_iter_next(&iter, &child)) { /* Only check visible children */ if(!clutter_actor_is_visible(child)) continue; /* Check for largest size */ clutter_actor_get_preferred_size(child, &childMinWidth, &childNaturalWidth, &childMinHeight, &childNaturalHeight); if(childMinWidth>largestMinWidth) largestMinWidth=childMinWidth; if(childNaturalWidth>largestNaturalWidth) largestNaturalWidth=childNaturalWidth; if(childMinHeight>largestMinHeight) largestMinHeight=childMinHeight; if(childNaturalHeight>largestNaturalHeight) largestNaturalHeight=childNaturalHeight; /* Count visible children */ numberChildren++; } /* Depending on orientation set sizes to fit into parent actor */ parent=clutter_actor_get_parent(CLUTTER_ACTOR(inContainer)); if(parent) { aspectRatio=1.0f; clutter_actor_get_size(CLUTTER_ACTOR(parent), &parentWidth, &parentHeight); if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) { if(priv->keepAspect==TRUE) { aspectRatio=largestMinWidth/largestMinHeight; largestMinHeight=parentHeight; largestMinWidth=largestMinHeight*aspectRatio; aspectRatio=largestNaturalWidth/largestNaturalHeight; largestNaturalHeight=parentHeight; largestNaturalWidth=largestNaturalHeight*aspectRatio; } else { largestMinHeight=parentHeight; largestNaturalHeight=parentHeight; } } else { if(priv->keepAspect==TRUE) { aspectRatio=largestMinHeight/largestMinWidth; largestMinWidth=parentWidth; largestMinHeight=largestMinWidth*aspectRatio; aspectRatio=largestNaturalHeight/largestNaturalWidth; largestNaturalWidth=parentWidth; largestNaturalHeight=largestNaturalWidth*aspectRatio; } else { largestMinWidth=parentWidth; largestNaturalWidth=parentWidth; } } } /* Set return values */ if(outMinWidth) *outMinWidth=largestMinWidth; if(outNaturalWidth) *outNaturalWidth=largestNaturalWidth; if(outMinHeight) *outMinHeight=largestMinHeight; if(outNaturalHeight) *outNaturalHeight=largestNaturalHeight; /* Return number of visible children */ return(numberChildren); }
/* Allocate position and size of actor and its children */ static void _xfdashboard_text_box_allocate(ClutterActor *self, const ClutterActorBox *inBox, ClutterAllocationFlags inFlags) { XfdashboardTextBoxPrivate *priv=XFDASHBOARD_TEXT_BOX(self)->priv; ClutterActorBox *box=NULL; gfloat left, right, top, bottom; gfloat iconWidth, iconHeight; /* Chain up to store the allocation of the actor */ CLUTTER_ACTOR_CLASS(xfdashboard_text_box_parent_class)->allocate(self, inBox, inFlags); /* Initialize bounding box of allocation used in actors */ left=top=priv->padding; right=clutter_actor_box_get_width(inBox)-priv->padding; bottom=clutter_actor_box_get_height(inBox)-priv->padding; /* Set allocation of primary icon if visible */ if(CLUTTER_ACTOR_IS_VISIBLE(priv->actorPrimaryIcon)) { gfloat childRight; /* Get scale size of primary icon */ iconWidth=iconHeight=0.0f; clutter_actor_get_size(priv->actorPrimaryIcon, &iconWidth, &iconHeight); if(iconHeight>0.0f) iconWidth=(bottom-top)*(iconWidth/iconHeight); /* Set allocation */ childRight=left+iconWidth; box=clutter_actor_box_new(floor(left), floor(top), floor(childRight), floor(bottom)); clutter_actor_allocate(CLUTTER_ACTOR(priv->actorPrimaryIcon), box, inFlags); clutter_actor_box_free(box); /* Adjust bounding box for next actor */ left=childRight+priv->spacing; } /* Set allocation of secondary icon if visible */ if(CLUTTER_ACTOR_IS_VISIBLE(priv->actorSecondaryIcon)) { gfloat childLeft; /* Get scale size of secondary icon */ iconWidth=0.0f; clutter_actor_get_size(priv->actorSecondaryIcon, &iconWidth, &iconHeight); if(iconHeight>0.0f) iconWidth=(bottom-top)*(iconWidth/iconHeight); /* Set allocation */ childLeft=right-iconWidth; box=clutter_actor_box_new(floor(childLeft), floor(top), floor(right), floor(bottom)); clutter_actor_allocate(CLUTTER_ACTOR(priv->actorSecondaryIcon), box, inFlags); clutter_actor_box_free(box); /* Adjust bounding box for next actor */ right=childLeft-priv->spacing; } /* Set allocation of editable text box if visible */ if(CLUTTER_ACTOR_IS_VISIBLE(priv->actorTextBox)) { gfloat textHeight; /* Get height of text */ clutter_actor_get_preferred_size(CLUTTER_ACTOR(priv->actorTextBox), NULL, NULL, NULL, &textHeight); /* Set allocation */ box=clutter_actor_box_new(floor(left), floor(bottom-textHeight), floor(right), floor(bottom)); clutter_actor_allocate(CLUTTER_ACTOR(priv->actorTextBox), box, inFlags); clutter_actor_box_free(box); } /* Set allocation of hint label if visible */ if(CLUTTER_ACTOR_IS_VISIBLE(priv->actorHintLabel)) { gfloat textHeight; /* Get height of label */ clutter_actor_get_preferred_size(CLUTTER_ACTOR(priv->actorHintLabel), NULL, NULL, NULL, &textHeight); /* Set allocation */ box=clutter_actor_box_new(floor(left), floor(bottom-textHeight), floor(right), floor(bottom)); clutter_actor_allocate(CLUTTER_ACTOR(priv->actorHintLabel), box, inFlags); clutter_actor_box_free(box); } }
/* Re-layout and allocate children of container we manage */ static void _xfdashboard_scaled_table_layout_allocate(ClutterLayoutManager *self, ClutterContainer *inContainer, const ClutterActorBox *inAllocation, ClutterAllocationFlags inFlags) { XfdashboardScaledTableLayoutPrivate *priv; gint row, col; ClutterActor *child; ClutterActorIter iter; gfloat cellWidth, cellHeight; gfloat childWidth, childHeight; gfloat scaledChildWidth, scaledChildHeight; gfloat largestWidth, largestHeight; gfloat scaleWidth, scaleHeight; gfloat aspectRatio; gfloat x, y; ClutterActorBox childAllocation; g_return_if_fail(XFDASHBOARD_IS_SCALED_TABLE_LAYOUT(self)); g_return_if_fail(CLUTTER_IS_CONTAINER(inContainer)); priv=XFDASHBOARD_SCALED_TABLE_LAYOUT(self)->priv; /* Get size of container holding children to layout and * determine size of a cell */ clutter_actor_get_size(CLUTTER_ACTOR(inContainer), &childWidth, &childHeight); cellWidth=childWidth-((priv->columns-1)*priv->columnSpacing); cellWidth=floor(cellWidth/priv->columns); cellHeight=childHeight-((priv->rows-1)*priv->rowSpacing); cellHeight=floor(cellHeight/priv->rows); /* Iterate through children and find largest one * if relative scale was set */ largestWidth=largestHeight=0.0f; if(priv->relativeScale==TRUE) { gfloat w, h; clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inContainer)); while(clutter_actor_iter_next(&iter, &child)) { if(!CLUTTER_ACTOR_IS_VISIBLE(child)) continue; clutter_actor_get_preferred_size(child, NULL, NULL, &w, &h); if(w>largestWidth) largestWidth=w; if(h>largestHeight) largestHeight=h; } } /* Iterate through child actors and set their new allocation */ row=col=0; x=y=0.0f; clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inContainer)); while(clutter_actor_iter_next(&iter, &child)) { if(!CLUTTER_ACTOR_IS_VISIBLE(child)) continue; /* Get natural size of actor */ clutter_actor_get_preferred_size(child, NULL, NULL, &childWidth, &childHeight); /* If either width or height is 0 then it is visually hidden and we * skip expensive calculation. This also has the nice effect that * do not perform invalid divisions by zero ;) */ if(childWidth>0.0f && childHeight>0.0f) { /* Get scale factor needed to apply to width and height. * If no relative scaling should be performed the scale is always 1.0 * otherwise it is the scale factor for this actor to the largest one. */ if(priv->relativeScale==TRUE) { /* Get scale factors */ scaleWidth=childWidth/largestWidth; scaleHeight=childHeight/largestHeight; } else scaleWidth=scaleHeight=1.0f; /* Get aspect ratio factor */ aspectRatio=childHeight/childWidth; /* Calculate new size of child */ scaledChildWidth=cellWidth*scaleWidth; scaledChildHeight=scaledChildWidth*aspectRatio; if(scaledChildHeight>cellHeight) { scaledChildHeight=cellHeight*scaleHeight; scaledChildWidth=scaledChildHeight/aspectRatio; } /* If upscaling should be prevent check if we are upscaling now */ if(priv->preventUpscaling) { if(scaledChildWidth>childWidth) { scaledChildWidth=childWidth; scaledChildHeight=childWidth*aspectRatio; } if(scaledChildHeight>childHeight) { scaledChildHeight=childHeight; scaledChildWidth=childHeight/aspectRatio; } } } else { /* Visually hidden so do not allocate any space */ scaledChildWidth=0.0f; scaledChildHeight=0.0f; } /* Set new allocation of child */ childAllocation.x1=ceil(x+((cellWidth-scaledChildWidth)/2.0f)); childAllocation.y1=ceil(y+((cellHeight-scaledChildHeight)/2.0f)); childAllocation.x2=ceil(childAllocation.x1+scaledChildWidth); childAllocation.y2=ceil(childAllocation.y1+scaledChildHeight); clutter_actor_allocate(child, &childAllocation, inFlags); /* Set up for next child */ col=(col+1) % priv->columns; if(col==0) row++; x=col*(cellWidth+priv->columnSpacing); y=row*(cellHeight+priv->rowSpacing); } }
static void clutter_flow_layout_allocate (ClutterLayoutManager *manager, ClutterContainer *container, const ClutterActorBox *allocation, ClutterAllocationFlags flags) { ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv; ClutterActor *actor, *child; ClutterActorIter iter; gfloat x_off, y_off; gfloat avail_width, avail_height; gfloat item_x, item_y; gint line_item_count; gint items_per_line; gint line_index; actor = CLUTTER_ACTOR (container); if (clutter_actor_get_n_children (actor) == 0) return; clutter_actor_box_get_origin (allocation, &x_off, &y_off); clutter_actor_box_get_size (allocation, &avail_width, &avail_height); /* blow the cached preferred size and re-compute with the given * available size in case the FlowLayout wasn't given the exact * size it requested */ if ((priv->req_width >= 0 && avail_width != priv->req_width) || (priv->req_height >= 0 && avail_height != priv->req_height)) { clutter_flow_layout_get_preferred_width (manager, container, avail_height, NULL, NULL); clutter_flow_layout_get_preferred_height (manager, container, avail_width, NULL, NULL); } items_per_line = compute_lines (CLUTTER_FLOW_LAYOUT (manager), avail_width, avail_height); item_x = x_off; item_y = y_off; line_item_count = 0; line_index = 0; clutter_actor_iter_init (&iter, actor); while (clutter_actor_iter_next (&iter, &child)) { ClutterActorBox child_alloc; gfloat item_width, item_height; gfloat new_x, new_y; gfloat child_min, child_natural; if (!CLUTTER_ACTOR_IS_VISIBLE (child)) continue; new_x = new_y = 0; if (!priv->snap_to_grid) clutter_actor_get_preferred_size (child, NULL, NULL, &item_width, &item_height); if (priv->orientation == CLUTTER_FLOW_HORIZONTAL) { if ((priv->snap_to_grid && line_item_count == items_per_line && line_item_count > 0) || (!priv->snap_to_grid && item_x + item_width > avail_width)) { item_y += g_array_index (priv->line_natural, gfloat, line_index); if (line_index >= 0) item_y += priv->row_spacing; line_item_count = 0; line_index += 1; item_x = x_off; } if (priv->snap_to_grid) { new_x = x_off + ((line_item_count + 1) * (avail_width + priv->col_spacing)) / items_per_line; item_width = new_x - item_x - priv->col_spacing; } else { new_x = item_x + item_width + priv->col_spacing; } item_height = g_array_index (priv->line_natural, gfloat, line_index); } else { if ((priv->snap_to_grid && line_item_count == items_per_line && line_item_count > 0) || (!priv->snap_to_grid && item_y + item_height > avail_height)) { item_x += g_array_index (priv->line_natural, gfloat, line_index); if (line_index >= 0) item_x += priv->col_spacing; line_item_count = 0; line_index += 1; item_y = y_off; } if (priv->snap_to_grid) { new_y = y_off + ((line_item_count + 1) * (avail_height + priv->row_spacing)) / items_per_line; item_height = new_y - item_y - priv->row_spacing; } else { new_y = item_y + item_height + priv->row_spacing; } item_width = g_array_index (priv->line_natural, gfloat, line_index); } if (!priv->is_homogeneous && !clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL)) { clutter_actor_get_preferred_width (child, item_height, &child_min, &child_natural); item_width = MIN (item_width, child_natural); } if (!priv->is_homogeneous && !clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL)) { clutter_actor_get_preferred_height (child, item_width, &child_min, &child_natural); item_height = MIN (item_height, child_natural); } CLUTTER_NOTE (LAYOUT, "flow[line:%d, item:%d/%d] =" "{ %.2f, %.2f, %.2f, %.2f }", line_index, line_item_count + 1, items_per_line, item_x, item_y, item_width, item_height); child_alloc.x1 = ceil (item_x); child_alloc.y1 = ceil (item_y); child_alloc.x2 = ceil (child_alloc.x1 + item_width); child_alloc.y2 = ceil (child_alloc.y1 + item_height); clutter_actor_allocate (child, &child_alloc, flags); if (priv->orientation == CLUTTER_FLOW_HORIZONTAL) item_x = new_x; else item_y = new_y; line_item_count += 1; } }
static void mex_column_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { gfloat header_pref_height, pref_h, pref_w; ClutterActorBox child_box; MxPadding padding; gdouble value; GList *c; MexColumn *column = MEX_COLUMN (actor); MexColumnPrivate *priv = column->priv; CLUTTER_ACTOR_CLASS (mex_column_parent_class)->allocate (actor, box, flags); mx_widget_get_padding (MX_WIDGET (actor), &padding); /* Allocate header */ if (priv->adjustment) value = mx_adjustment_get_value (priv->adjustment); else value = 0.0; child_box.x1 = padding.left; child_box.x2 = box->x2 - box->x1 - padding.right; child_box.y1 = padding.top + value; clutter_actor_get_preferred_height (priv->header, child_box.x2 - child_box.x1, NULL, &header_pref_height); child_box.y2 = child_box.y1 + header_pref_height; clutter_actor_allocate (priv->header, &child_box, flags); /* Allocate placeholder actor */ child_box.y1 = padding.top + header_pref_height; /* keep the aspect ratio of the palceholder actor */ clutter_actor_get_preferred_size (priv->placeholder_actor, NULL, NULL, &pref_w, &pref_h); pref_h = pref_h * ((child_box.x2 - child_box.x1) / pref_w); child_box.y2 = child_box.y1 + pref_h; clutter_actor_allocate (priv->placeholder_actor, &child_box, flags); child_box.y2 = box->y2 - box->y1 - padding.bottom; if (priv->n_items) { /* Calculate child height multiplier */ gfloat width, pref_height, avail_height, ratio, remainder; if (!priv->adjustment) { /* Find out the height available for each actor as a ratio of * their preferred height. */ clutter_actor_get_preferred_height (actor, box->x2 - box->x1, NULL, &pref_height); pref_height -= padding.top + padding.bottom + header_pref_height; avail_height = child_box.y2 - child_box.y1; ratio = avail_height / pref_height; } else ratio = 1; /* Allocate children */ remainder = 0; width = child_box.x2 - child_box.x1; for (c = priv->children; c; c = c->next) { gfloat min_height, nat_height, height; ClutterActor *child = c->data; clutter_actor_get_preferred_height (child, width, &min_height, &nat_height); /* Calculate the allocatable height and keep an accumulator so * when we round to a pixel, we don't end up with a lot of * empty space at the end of the actor. */ height = MAX (min_height, nat_height / ratio); remainder += (height - (gint)height); height = (gint)height; while (remainder >= 1.f) { height += 1.f; remainder -= 1.f; } /* Allocate the child */ child_box.y2 = child_box.y1 + height; clutter_actor_allocate (child, &child_box, flags); /* Set the top position of the next child box */ child_box.y1 = child_box.y2; } } /* Make sure the adjustment reflects the column's allocation */ if (priv->adjustment) { gdouble page_size = box->y2 - box->y1 - padding.top - padding.bottom; g_object_set (G_OBJECT (priv->adjustment), "lower", 0.0, "upper", child_box.y2 - padding.top, "page-size", page_size, "step-increment", 1.0, "page-increment", page_size, NULL); } }