static void shell_generic_container_get_preferred_height (ClutterActor *actor, gfloat for_width, gfloat *min_height_p, gfloat *natural_height_p) { ShellGenericContainerAllocation *alloc = g_slice_new0 (ShellGenericContainerAllocation); StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); st_theme_node_adjust_for_width (theme_node, &for_width); alloc->_refcount = 1; g_signal_emit (G_OBJECT (actor), shell_generic_container_signals[GET_PREFERRED_HEIGHT], 0, for_width, alloc); if (min_height_p) *min_height_p = alloc->min_size; if (natural_height_p) *natural_height_p = alloc->natural_size; shell_generic_container_allocation_unref (alloc); st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p); }
static void st_scroll_bar_get_preferred_height (ClutterActor *self, gfloat for_width, gfloat *min_height_p, gfloat *natural_height_p) { StScrollBar *bar = ST_SCROLL_BAR (self); StScrollBarPrivate *priv = bar->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self)); gfloat trough_min_height, trough_natural_height; gfloat handle_min_height, handle_natural_height; st_theme_node_adjust_for_width (theme_node, &for_width); _st_actor_get_preferred_height (priv->trough, for_width, TRUE, &trough_min_height, &trough_natural_height); _st_actor_get_preferred_height (priv->handle, for_width, TRUE, &handle_min_height, &handle_natural_height); if (priv->vertical) { if (min_height_p) *min_height_p = trough_min_height + handle_min_height; if (natural_height_p) *natural_height_p = trough_natural_height + handle_natural_height; } else { if (min_height_p) *min_height_p = MAX (trough_min_height, handle_min_height); if (natural_height_p) *natural_height_p = MAX (trough_natural_height, handle_natural_height); } st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p); }
static void st_scroll_view_get_preferred_height (ClutterActor *actor, gfloat for_width, gfloat *min_height_p, gfloat *natural_height_p) { StScrollViewPrivate *priv = ST_SCROLL_VIEW (actor)->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); gboolean account_for_hscrollbar = FALSE; gfloat min_height = 0, natural_height; gfloat child_min_height, child_natural_height; gfloat child_min_width; gfloat sb_width; if (!priv->child) return; st_theme_node_adjust_for_width (theme_node, &for_width); clutter_actor_get_preferred_width (priv->child, -1, &child_min_width, NULL); if (min_height_p) *min_height_p = 0; sb_width = get_scrollbar_width (ST_SCROLL_VIEW (actor), -1); switch (priv->vscrollbar_policy) { case GTK_POLICY_NEVER: break; case GTK_POLICY_ALWAYS: case GTK_POLICY_AUTOMATIC: /* We've requested space for the scrollbar, subtract it back out */ for_width -= sb_width; break; } switch (priv->hscrollbar_policy) { case GTK_POLICY_NEVER: account_for_hscrollbar = FALSE; break; case GTK_POLICY_ALWAYS: account_for_hscrollbar = TRUE; break; case GTK_POLICY_AUTOMATIC: account_for_hscrollbar = for_width < child_min_width; break; } clutter_actor_get_preferred_height (priv->child, for_width, &child_min_height, &child_natural_height); natural_height = child_natural_height; switch (priv->vscrollbar_policy) { case GTK_POLICY_NEVER: min_height = child_min_height; break; case GTK_POLICY_ALWAYS: case GTK_POLICY_AUTOMATIC: /* Should theoretically use the min height of the vscrollbar, * but that's not cleanly defined at the moment */ min_height = 0; break; } if (account_for_hscrollbar) { float sb_height = get_scrollbar_height (ST_SCROLL_VIEW (actor), for_width); min_height += sb_height; natural_height += sb_height; } if (min_height_p) *min_height_p = min_height; if (natural_height_p) *natural_height_p = natural_height; st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p); }
static void st_table_get_preferred_height (ClutterActor *self, gfloat for_width, gfloat *min_height_p, gfloat *natural_height_p) { gint *min_heights, *pref_heights; gfloat total_min_height, total_pref_height; StTablePrivate *priv = ST_TABLE (self)->priv; StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self)); gint i; gint *min_widths; ClutterActor *child; /* We only support height-for-width allocation. So if we are called * width-for-height, calculate heights based on our natural width */ if (for_width < 0) { float natural_width; clutter_actor_get_preferred_width (self, -1, NULL, &natural_width); for_width = natural_width; } if (priv->n_rows < 1) { *min_height_p = 0; *natural_height_p = 0; return; } st_theme_node_adjust_for_width (theme_node, &for_width); /* Setting size to zero and then what we want it to be causes a clear if * clear flag is set (which it should be.) */ g_array_set_size (priv->min_heights, 0); g_array_set_size (priv->pref_heights, 0); g_array_set_size (priv->min_heights, priv->n_rows); g_array_set_size (priv->pref_heights, priv->n_rows); /* use min_widths to help allocation of height-for-width widgets */ min_widths = st_table_calculate_col_widths (ST_TABLE (self), for_width); min_heights = (gint *) priv->min_heights->data; pref_heights = (gint *) priv->pref_heights->data; /* calculate minimum row heights */ for (child = clutter_actor_get_first_child (self); child != NULL; child = clutter_actor_get_next_sibling (child)) { gint row, col, col_span, cell_width, row_span; gfloat min, pref; StTableChild *meta; meta = (StTableChild *) clutter_container_get_child_meta (CLUTTER_CONTAINER (self), child); if (!meta->allocate_hidden && !CLUTTER_ACTOR_IS_VISIBLE (child)) continue; /* get child properties */ row = meta->row; col = meta->col; col_span = meta->col_span; row_span = meta->row_span; cell_width = 0; for (i = 0; i < col_span && col + i < priv->n_cols; i++) cell_width += min_widths[col + i]; _st_actor_get_preferred_height (child, (float) cell_width, meta->x_fill, &min, &pref); if (row_span == 1 && min > min_heights[row]) min_heights[row] = min; if (row_span == 1 && pref > pref_heights[row]) pref_heights[row] = pref; } /* start off with row spacing */ total_min_height = (priv->n_rows - 1) * (float) (priv->row_spacing); total_pref_height = total_min_height; for (i = 0; i < priv->n_rows; i++) { total_min_height += min_heights[i]; total_pref_height += pref_heights[i]; } if (min_height_p) *min_height_p = total_min_height; if (natural_height_p) *natural_height_p = total_pref_height; st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p); }