[gnome-shell] [St] Make allocation handling more consistent
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] [St] Make allocation handling more consistent
- Date: Tue, 16 Feb 2010 19:08:02 +0000 (UTC)
commit 5331d3e360d08a109c98a1f6f072c12787eb4088
Author: Dan Winship <danw gnome org>
Date: Sat Feb 13 11:24:25 2010 -0500
[St] Make allocation handling more consistent
In StBin, StBoxLayout, and StTable, if a child has a potential
allocation that is larger than its preferred size, we give it its
preferred size instead. However, the corresponding
get_preferred_height/width methods were not making the same
assumption, which meant that if we had more width than the widget
wanted, we would allocate it its preferred width, but with the height
that corresponded to the larger width.
Fix this by defining new helpers _st_actor_get_preferred_width() and
_st_actor_get_preferred_height() and using them everywhere. Also, make
StBin and StTable use _st_allocate_fill() rather than having
nearly-identical duplicate copies of the code.
https://bugzilla.gnome.org/show_bug.cgi?id=609848
src/shell-slicer.c | 23 +++--
src/st/st-bin.c | 158 +++------------------------------
src/st/st-box-layout.c | 66 +++++++++-----
src/st/st-private.c | 231 +++++++++++++++++++++++++++++++++++++++--------
src/st/st-private.h | 22 ++++-
src/st/st-table.c | 133 +++-------------------------
6 files changed, 291 insertions(+), 342 deletions(-)
---
diff --git a/src/shell-slicer.c b/src/shell-slicer.c
index db59df8..bcc27de 100644
--- a/src/shell-slicer.c
+++ b/src/shell-slicer.c
@@ -37,9 +37,9 @@ shell_slicer_get_preferred_width (ClutterActor *self,
}
else
{
- clutter_actor_get_preferred_width (child, for_height,
- NULL,
- natural_width_p);
+ _st_actor_get_preferred_width (child, for_height, FALSE,
+ NULL,
+ natural_width_p);
}
st_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
@@ -66,9 +66,9 @@ shell_slicer_get_preferred_height (ClutterActor *self,
}
else
{
- clutter_actor_get_preferred_height (child, for_width,
- NULL,
- natural_height_p);
+ _st_actor_get_preferred_height (child, for_width, FALSE,
+ NULL,
+ natural_height_p);
}
st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
@@ -97,14 +97,17 @@ shell_slicer_paint_child (ShellSlicer *self)
ClutterActorBox self_box;
ClutterActorBox child_box;
float width, height, child_width, child_height;
- double x_align, y_align;
+ StAlign x_align, y_align;
+ double x_align_factor, y_align_factor;
child = st_bin_get_child (ST_BIN (self));
if (!child)
return;
- _st_bin_get_align_factors (ST_BIN (self), &x_align, &y_align);
+ st_bin_get_alignment (ST_BIN (self), &x_align, &y_align);
+ _st_get_align_factors (ST_WIDGET (self), x_align, y_align,
+ &x_align_factor, &y_align_factor);
clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &self_box);
clutter_actor_get_allocation_box (child, &child_box);
@@ -117,8 +120,8 @@ shell_slicer_paint_child (ShellSlicer *self)
cogl_push_matrix ();
cogl_clip_push (0, 0, width, height);
- cogl_translate ((int)(0.5 + x_align * (width - child_width)),
- (int)(0.5 + y_align * (height - child_height)),
+ cogl_translate ((int)(0.5 + x_align_factor * (width - child_width)),
+ (int)(0.5 + y_align_factor * (height - child_height)),
0);
clutter_actor_paint (child);
diff --git a/src/st/st-bin.c b/src/st/st-bin.c
index 48347b6..3039297 100644
--- a/src/st/st-bin.c
+++ b/src/st/st-bin.c
@@ -71,59 +71,6 @@ G_DEFINE_TYPE_WITH_CODE (StBin, st_bin, ST_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
clutter_container_iface_init));
-void
-_st_bin_get_align_factors (StBin *bin,
- gdouble *x_align,
- gdouble *y_align)
-{
- StBinPrivate *priv = bin->priv;
- gdouble factor;
-
- switch (priv->x_align)
- {
- case ST_ALIGN_START:
- factor = 0.0;
- break;
-
- case ST_ALIGN_MIDDLE:
- factor = 0.5;
- break;
-
- case ST_ALIGN_END:
- factor = 1.0;
- break;
-
- default:
- factor = 0.0;
- break;
- }
-
- if (x_align)
- *x_align = factor;
-
- switch (priv->y_align)
- {
- case ST_ALIGN_START:
- factor = 0.0;
- break;
-
- case ST_ALIGN_MIDDLE:
- factor = 0.5;
- break;
-
- case ST_ALIGN_END:
- factor = 1.0;
- break;
-
- default:
- factor = 0.0;
- break;
- }
-
- if (y_align)
- *y_align = factor;
-}
-
static void
st_bin_add (ClutterContainer *container,
ClutterActor *actor)
@@ -199,92 +146,13 @@ st_bin_allocate (ClutterActor *self,
if (priv->child)
{
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self));
- gfloat natural_width, natural_height;
- gfloat min_width, min_height;
- gfloat child_width, child_height;
- gfloat available_width, available_height;
- ClutterRequestMode request;
- ClutterActorBox content_box;
- ClutterActorBox allocation = { 0, };
- gdouble x_align, y_align;
-
- st_theme_node_get_content_box (theme_node, box, &content_box);
-
- _st_bin_get_align_factors (ST_BIN (self), &x_align, &y_align);
-
- available_width = content_box.x2 - content_box.x1;
- available_height = content_box.y2 - content_box.y1;
-
- if (available_width < 0)
- available_width = 0;
-
- if (available_height < 0)
- available_height = 0;
-
- if (priv->x_fill)
- {
- allocation.x1 = (int) content_box.x1;
- allocation.x2 = (int) content_box.x2;
- }
-
- if (priv->y_fill)
- {
- allocation.y1 = (int) content_box.y1;
- allocation.y2 = (int) content_box.y2;
- }
-
- /* if we are filling horizontally and vertically then we're done */
- if (priv->x_fill && priv->y_fill)
- {
- clutter_actor_allocate (priv->child, &allocation, flags);
- return;
- }
-
- request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
- g_object_get (G_OBJECT (priv->child), "request-mode", &request, NULL);
-
- if (request == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
- {
- clutter_actor_get_preferred_width (priv->child, available_height,
- &min_width,
- &natural_width);
-
- child_width = CLAMP (natural_width, min_width, available_width);
-
- clutter_actor_get_preferred_height (priv->child, child_width,
- &min_height,
- &natural_height);
-
- child_height = CLAMP (natural_height, min_height, available_height);
- }
- else
- {
- clutter_actor_get_preferred_height (priv->child, available_width,
- &min_height,
- &natural_height);
-
- child_height = CLAMP (natural_height, min_height, available_height);
-
- clutter_actor_get_preferred_width (priv->child, child_height,
- &min_width,
- &natural_width);
-
- child_width = CLAMP (natural_width, min_width, available_width);
- }
-
- if (!priv->x_fill)
- {
- allocation.x1 = content_box.x1 + (int) ((available_width - child_width) * x_align);
- allocation.x2 = allocation.x1 + child_width;
- }
-
- if (!priv->y_fill)
- {
- allocation.y1 = content_box.y1 + (int) ((available_height - child_height) * y_align);
- allocation.y2 = allocation.y1 + child_height;
- }
-
- clutter_actor_allocate (priv->child, &allocation, flags);
+ ClutterActorBox childbox;
+
+ st_theme_node_get_content_box (theme_node, box, &childbox);
+ _st_allocate_fill (ST_WIDGET (self), priv->child, &childbox,
+ priv->x_align, priv->y_align,
+ priv->x_fill, priv->y_fill);
+ clutter_actor_allocate (priv->child, &childbox, flags);
}
}
@@ -309,9 +177,9 @@ st_bin_get_preferred_width (ClutterActor *self,
}
else
{
- clutter_actor_get_preferred_width (priv->child, for_height,
- min_width_p,
- natural_width_p);
+ _st_actor_get_preferred_width (priv->child, for_height, priv->y_fill,
+ min_width_p,
+ natural_width_p);
}
st_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
@@ -338,9 +206,9 @@ st_bin_get_preferred_height (ClutterActor *self,
}
else
{
- clutter_actor_get_preferred_height (priv->child, for_width,
- min_height_p,
- natural_height_p);
+ _st_actor_get_preferred_height (priv->child, for_width, priv->x_fill,
+ min_height_p,
+ natural_height_p);
}
st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
diff --git a/src/st/st-box-layout.c b/src/st/st-box-layout.c
index d23226a..5062c07 100644
--- a/src/st/st-box-layout.c
+++ b/src/st/st-box-layout.c
@@ -528,6 +528,7 @@ get_content_preferred_width (StBoxLayout *self,
{
ClutterActor *child = l->data;
gfloat child_min = 0, child_nat = 0;
+ gboolean child_fill;
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
continue;
@@ -540,18 +541,20 @@ get_content_preferred_width (StBoxLayout *self,
continue;
}
- clutter_actor_get_preferred_width (child,
- (!priv->is_vertical) ? for_height : -1,
- &child_min,
- &child_nat);
-
if (priv->is_vertical)
{
+ _st_actor_get_preferred_width (child, -1, FALSE,
+ &child_min, &child_nat);
min_width = MAX (child_min, min_width);
natural_width = MAX (child_nat, natural_width);
}
else
{
+ clutter_container_child_get ((ClutterContainer*) self, child,
+ "y-fill", &child_fill,
+ NULL);
+ _st_actor_get_preferred_width (child, for_height, child_fill,
+ &child_min, &child_nat);
min_width += child_min;
natural_width += child_nat;
}
@@ -606,6 +609,7 @@ get_content_preferred_height (StBoxLayout *self,
{
ClutterActor *child = l->data;
gfloat child_min = 0, child_nat = 0;
+ gboolean child_fill = FALSE;
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
continue;
@@ -618,10 +622,17 @@ get_content_preferred_height (StBoxLayout *self,
continue;
}
- clutter_actor_get_preferred_height (child,
- (priv->is_vertical) ? for_width : -1,
- &child_min,
- &child_nat);
+ if (priv->is_vertical)
+ {
+ clutter_container_child_get ((ClutterContainer*) self, child,
+ "x-fill", &child_fill,
+ NULL);
+ }
+ _st_actor_get_preferred_height (child,
+ (priv->is_vertical) ? for_width : -1,
+ child_fill,
+ &child_min,
+ &child_nat);
if (!priv->is_vertical)
{
@@ -713,6 +724,7 @@ compute_shrinks (StBoxLayout *self,
{
ClutterActor *child = l->data;
gfloat child_min, child_nat;
+ gboolean child_fill;
gboolean fixed;
child = (ClutterActor*) l->data;
@@ -722,13 +734,23 @@ compute_shrinks (StBoxLayout *self,
if (CLUTTER_ACTOR_IS_VISIBLE (child) && !fixed)
{
if (priv->is_vertical)
- clutter_actor_get_preferred_height (child,
- for_length,
- &child_min, &child_nat);
+ {
+ clutter_container_child_get ((ClutterContainer*) self, child,
+ "x-fill", &child_fill,
+ NULL);
+ _st_actor_get_preferred_height (child,
+ for_length, child_fill,
+ &child_min, &child_nat);
+ }
else
- clutter_actor_get_preferred_width (child,
- for_length,
- &child_min, &child_nat);
+ {
+ clutter_container_child_get ((ClutterContainer*) self, child,
+ "y-fill", &child_fill,
+ NULL);
+ _st_actor_get_preferred_width (child,
+ for_length, child_fill,
+ &child_min, &child_nat);
+ }
shrinks[i].shrink_amount = MAX (0., child_nat - child_min);
n_possible_shrink_children++;
@@ -943,13 +965,13 @@ st_box_layout_allocate (ClutterActor *actor,
if (priv->is_vertical)
{
- clutter_actor_get_preferred_height (child, avail_width,
- &child_min, &child_nat);
+ _st_actor_get_preferred_height (child, avail_width, xfill,
+ &child_min, &child_nat);
}
else
{
- clutter_actor_get_preferred_width (child, avail_height,
- &child_min, &child_nat);
+ _st_actor_get_preferred_width (child, avail_height, yfill,
+ &child_min, &child_nat);
}
child_allocated = child_nat;
@@ -973,7 +995,8 @@ st_box_layout_allocate (ClutterActor *actor,
else
child_box.x2 = content_box.x2;
- _st_allocate_fill (child, &child_box, xalign, yalign, xfill, yfill);
+ _st_allocate_fill (ST_WIDGET (actor), child, &child_box,
+ xalign, yalign, xfill, yfill);
clutter_actor_allocate (child, &child_box, flags);
}
@@ -996,7 +1019,8 @@ st_box_layout_allocate (ClutterActor *actor,
else
child_box.y2 = content_box.y2;
- _st_allocate_fill (child, &child_box, xalign, yalign, xfill, yfill);
+ _st_allocate_fill (ST_WIDGET (actor), child, &child_box,
+ xalign, yalign, xfill, yfill);
clutter_actor_allocate (child, &child_box, flags);
}
diff --git a/src/st/st-private.c b/src/st/st-private.c
index 182e36d..7586e2b 100644
--- a/src/st/st-private.c
+++ b/src/st/st-private.c
@@ -1,12 +1,114 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include "st-private.h"
-/* Utility function to modify a child allocation box with respect to the
- * x/y-fill child properties. Expects childbox to contain the available
- * allocation space.
+/**
+ * _st_actor_get_preferred_width:
+ * @actor: a #ClutterActor
+ * @for_height: as with clutter_actor_get_preferred_width()
+ * @y_fill: %TRUE if @actor will fill its allocation vertically
+ * @min_width_p: as with clutter_actor_get_preferred_width()
+ * @natural_width_p: as with clutter_actor_get_preferred_width()
+ *
+ * Like clutter_actor_get_preferred_width(), but if @y_fill is %FALSE,
+ * then it will compute a width request based on the assumption that
+ * @actor will be given an allocation no taller than its natural
+ * height.
*/
void
-_st_allocate_fill (ClutterActor *child,
+_st_actor_get_preferred_width (ClutterActor *actor,
+ gfloat for_height,
+ gboolean y_fill,
+ gfloat *min_width_p,
+ gfloat *natural_width_p)
+{
+ if (!y_fill && for_height != -1)
+ {
+ ClutterRequestMode mode;
+ gfloat natural_height;
+
+ g_object_get (G_OBJECT (actor), "request-mode", &mode, NULL);
+ if (mode == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT)
+ {
+ clutter_actor_get_preferred_height (actor, -1, NULL, &natural_height);
+ if (for_height > natural_height)
+ for_height = natural_height;
+ }
+ }
+
+ clutter_actor_get_preferred_width (actor, for_height, min_width_p, natural_width_p);
+}
+
+/**
+ * _st_actor_get_preferred_height:
+ * @actor: a #ClutterActor
+ * @for_width: as with clutter_actor_get_preferred_height()
+ * @x_fill: %TRUE if @actor will fill its allocation horizontally
+ * @min_height_p: as with clutter_actor_get_preferred_height()
+ * @natural_height_p: as with clutter_actor_get_preferred_height()
+ *
+ * Like clutter_actor_get_preferred_height(), but if @x_fill is
+ * %FALSE, then it will compute a height request based on the
+ * assumption that @actor will be given an allocation no wider than
+ * its natural width.
+ */
+void
+_st_actor_get_preferred_height (ClutterActor *actor,
+ gfloat for_width,
+ gboolean x_fill,
+ gfloat *min_height_p,
+ gfloat *natural_height_p)
+{
+ if (!x_fill && for_width != -1)
+ {
+ ClutterRequestMode mode;
+ gfloat natural_width;
+
+ g_object_get (G_OBJECT (actor), "request-mode", &mode, NULL);
+ if (mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
+ {
+ clutter_actor_get_preferred_width (actor, -1, NULL, &natural_width);
+ if (for_width > natural_width)
+ for_width = natural_width;
+ }
+ }
+
+ clutter_actor_get_preferred_height (actor, for_width, min_height_p, natural_height_p);
+}
+
+/**
+ * _st_allocate_fill:
+ * @parent: the parent #StWidget
+ * @child: the child (not necessarily an #StWidget)
+ * @childbox: total space that could be allocated to @child
+ * @x_alignment: horizontal alignment within @childbox
+ * @y_alignment: vertical alignment within @childbox
+ * @x_fill: whether or not to fill @childbox horizontally
+ * @y_fill: whether or not to fill @childbox vertically
+ *
+ * Given @childbox, containing the initial allocation of @child, this
+ * adjusts the horizontal allocation if @x_fill is %FALSE, and the
+ * vertical allocation if @y_fill is %FALSE, by:
+ *
+ * - reducing the allocation if it is larger than @child's natural
+ * size.
+ *
+ * - adjusting the position of the child within the allocation
+ * according to @x_alignment/@y_alignment (and flipping
+ * @x_alignment if @parent has %ST_TEXT_DIRECTION_RTL)
+ *
+ * If @x_fill and @y_fill are both %TRUE, or if @child's natural size
+ * is larger than the initial allocation in @childbox, then @childbox
+ * will be unchanged.
+ *
+ * If you are allocating children with _st_allocate_fill(), you should
+ * determine their preferred sizes using
+ * _st_actor_get_preferred_width() and
+ * _st_actor_get_preferred_height(), not with the corresponding
+ * Clutter methods.
+ */
+void
+_st_allocate_fill (StWidget *parent,
+ ClutterActor *child,
ClutterActorBox *childbox,
StAlign x_alignment,
StAlign y_alignment,
@@ -18,51 +120,36 @@ _st_allocate_fill (ClutterActor *child,
gfloat child_width, child_height;
gfloat available_width, available_height;
ClutterRequestMode request;
- ClutterActorBox allocation = { 0, };
gdouble x_align, y_align;
- if (x_alignment == ST_ALIGN_START)
- x_align = 0.0;
- else if (x_alignment == ST_ALIGN_MIDDLE)
- x_align = 0.5;
- else
- x_align = 1.0;
-
- if (y_alignment == ST_ALIGN_START)
- y_align = 0.0;
- else if (y_alignment == ST_ALIGN_MIDDLE)
- y_align = 0.5;
- else
- y_align = 1.0;
-
available_width = childbox->x2 - childbox->x1;
available_height = childbox->y2 - childbox->y1;
if (available_width < 0)
- available_width = 0;
-
- if (available_height < 0)
- available_height = 0;
-
- if (x_fill)
{
- allocation.x1 = childbox->x1;
- allocation.x2 = (int)(allocation.x1 + available_width);
+ available_width = 0;
+ childbox->x2 = childbox->x1;
}
- if (y_fill)
+ if (available_height < 0)
{
- allocation.y1 = childbox->y1;
- allocation.y2 = (int)(allocation.y1 + available_height);
+ available_height = 0;
+ childbox->y2 = childbox->y1;
}
- /* if we are filling horizontally and vertically then we're done */
+ /* If we are filling both horizontally and vertically then we don't
+ * need to do anything else.
+ */
if (x_fill && y_fill)
- {
- *childbox = allocation;
- return;
- }
+ return;
+ _st_get_align_factors (parent, x_alignment, y_alignment,
+ &x_align, &y_align);
+
+ /* The following is based on clutter_actor_get_preferred_size(), but
+ * modified to cope with the fact that the available size may be
+ * less than the preferred size.
+ */
request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
g_object_get (G_OBJECT (child), "request-mode", &request, NULL);
@@ -97,18 +184,82 @@ _st_allocate_fill (ClutterActor *child,
if (!x_fill)
{
- allocation.x1 = childbox->x1 + (int)((available_width - child_width) * x_align);
- allocation.x2 = allocation.x1 + (int) child_width;
+ childbox->x1 += (int)((available_width - child_width) * x_align);
+ childbox->x2 = childbox->x1 + (int) child_width;
}
if (!y_fill)
{
- allocation.y1 = childbox->y1 + (int)((available_height - child_height) * y_align);
- allocation.y2 = allocation.y1 + (int) child_height;
+ childbox->y1 += (int)((available_height - child_height) * y_align);
+ childbox->y2 = childbox->y1 + (int) child_height;
}
+}
- *childbox = allocation;
+/**
+ * _st_get_align_factors:
+ * @widget: an #StWidget
+ * @x_align: an #StAlign
+ * @y_align: an #StAlign
+ * @x_align_out: (out) (allow-none): @x_align as a #gdouble
+ * @y_align_out: (out) (allow-none): @y_align as a #gdouble
+ *
+ * Converts @x_align and @y_align to #gdouble values. If @widget has
+ * %ST_TEXT_DIRECTION_RTL, the @x_align_out value will be flipped
+ * relative to @x_align.
+ */
+void
+_st_get_align_factors (StWidget *widget,
+ StAlign x_align,
+ StAlign y_align,
+ gdouble *x_align_out,
+ gdouble *y_align_out)
+{
+ if (x_align_out)
+ {
+ switch (x_align)
+ {
+ case ST_ALIGN_START:
+ *x_align_out = 0.0;
+ break;
+
+ case ST_ALIGN_MIDDLE:
+ *x_align_out = 0.5;
+ break;
+
+ case ST_ALIGN_END:
+ *x_align_out = 1.0;
+ break;
+
+ default:
+ g_warn_if_reached ();
+ break;
+ }
+ if (st_widget_get_direction (widget) == ST_TEXT_DIRECTION_RTL)
+ *x_align_out = 1.0 - *x_align_out;
+ }
+
+ if (y_align_out)
+ {
+ switch (y_align)
+ {
+ case ST_ALIGN_START:
+ *y_align_out = 0.0;
+ break;
+
+ case ST_ALIGN_MIDDLE:
+ *y_align_out = 0.5;
+ break;
+
+ case ST_ALIGN_END:
+ *y_align_out = 1.0;
+ break;
+
+ default:
+ g_warn_if_reached ();
+ break;
+ }
+ }
}
/**
diff --git a/src/st/st-private.h b/src/st/st-private.h
index 42ac824..8368665 100644
--- a/src/st/st-private.h
+++ b/src/st/st-private.h
@@ -44,11 +44,25 @@ G_END_DECLS
ClutterActor *_st_widget_get_dnd_clone (StWidget *widget);
-void _st_bin_get_align_factors (StBin *bin,
- gdouble *x_align,
- gdouble *y_align);
+void _st_get_align_factors (StWidget *widget,
+ StAlign x_align,
+ StAlign y_align,
+ gdouble *x_align_out,
+ gdouble *y_align_out);
-void _st_allocate_fill (ClutterActor *child,
+void _st_actor_get_preferred_width (ClutterActor *actor,
+ gfloat for_height,
+ gboolean y_fill,
+ gfloat *min_width_p,
+ gfloat *natural_width_p);
+void _st_actor_get_preferred_height (ClutterActor *actor,
+ gfloat for_width,
+ gboolean x_fill,
+ gfloat *min_height_p,
+ gfloat *natural_height_p);
+
+void _st_allocate_fill (StWidget *parent,
+ ClutterActor *child,
ClutterActorBox *childbox,
StAlign x_align,
StAlign y_align,
diff --git a/src/st/st-table.c b/src/st/st-table.c
index a2c16a4..878af0f 100644
--- a/src/st/st-table.c
+++ b/src/st/st-table.c
@@ -278,120 +278,6 @@ st_table_dispose (GObject *gobject)
G_OBJECT_CLASS (st_table_parent_class)->dispose (gobject);
}
-#define CLAMP_TO_PIXEL(x) ((float)((int)(x)))
-
-/* Utility function to modify a child allocation box with respect to the
- * x/y-fill child properties. Expects childbox to contain the available
- * allocation space.
- */
-static void
-st_table_allocate_fill (ClutterActor *child,
- ClutterActorBox *childbox,
- gdouble x_align,
- gdouble y_align,
- gboolean x_fill,
- gboolean y_fill,
- gboolean ltr)
-{
- gfloat natural_width, natural_height;
- gfloat min_width, min_height;
- gfloat child_width, child_height;
- gfloat available_width, available_height;
- ClutterRequestMode request;
- ClutterActorBox allocation = { 0, };
-
- available_width = childbox->x2 - childbox->x1;
- available_height = childbox->y2 - childbox->y1;
-
- if (available_width < 0)
- available_width = 0;
-
- if (available_height < 0)
- available_height = 0;
-
- if (x_fill)
- {
- if (ltr)
- {
- allocation.x1 = childbox->x1;
- allocation.x2 = (int)(allocation.x1 + available_width);
- }
- else
- {
- allocation.x2 = childbox->x2;
- allocation.x1 = (int)(allocation.x2 - available_width);
- }
- }
-
- if (y_fill)
- {
- allocation.y1 = childbox->y1;
- allocation.y2 = (int)(allocation.y1 + available_height);
- }
-
- /* if we are filling horizontally and vertically then we're done */
- if (x_fill && y_fill)
- {
- *childbox = allocation;
- return;
- }
-
- request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
- g_object_get (G_OBJECT (child), "request-mode", &request, NULL);
-
- if (request == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
- {
- clutter_actor_get_preferred_width (child, available_height,
- &min_width,
- &natural_width);
-
- child_width = CLAMP (natural_width, min_width, available_width);
-
- clutter_actor_get_preferred_height (child, child_width,
- &min_height,
- &natural_height);
-
- child_height = CLAMP (natural_height, min_height, available_height);
- }
- else
- {
- clutter_actor_get_preferred_height (child, available_width,
- &min_height,
- &natural_height);
-
- child_height = CLAMP (natural_height, min_height, available_height);
-
- clutter_actor_get_preferred_width (child, child_height,
- &min_width,
- &natural_width);
-
- child_width = CLAMP (natural_width, min_width, available_width);
- }
-
- if (!x_fill)
- {
- if (ltr)
- {
- allocation.x1 = childbox->x1 + (int)((available_width - child_width) * x_align);
- allocation.x2 = allocation.x1 + (int) child_width;
- }
- else
- {
- allocation.x2 = childbox->x2 - (int)((available_width - child_width) * x_align);
- allocation.x1 = allocation.x2 - (int) child_width;
- }
- }
-
- if (!y_fill)
- {
- allocation.y1 = childbox->y1 + (int)((available_height - child_height) * y_align);
- allocation.y2 = allocation.y1 + (int) child_height;
- }
-
- *childbox = allocation;
-
-}
-
static void
st_table_homogeneous_allocate (ClutterActor *self,
const ClutterActorBox *content_box,
@@ -453,7 +339,8 @@ st_table_homogeneous_allocate (ClutterActor *self,
childbox.y1 = content_box->y1 + (row_height + row_spacing) * row;
childbox.y2 = childbox.y1 + (row_height * row_span) + (row_spacing * (row_span - 1));
- st_table_allocate_fill (child, &childbox, x_align, y_align, x_fill, y_fill, ltr);
+ _st_allocate_fill (ST_WIDGET (self), child, &childbox,
+ x_align, y_align, x_fill, y_fill);
clutter_actor_allocate (child, &childbox, flags);
}
@@ -510,7 +397,7 @@ st_table_calculate_col_widths (StTable *table,
if (x_expand)
is_expand_col[col] = TRUE;
- clutter_actor_get_preferred_width (child, -1, &w_min, &w_pref);
+ _st_actor_get_preferred_width (child, -1, meta->y_fill, &w_min, &w_pref);
if (col_span == 1 && w_pref > pref_widths[col])
{
pref_widths[col] = w_pref;
@@ -630,11 +517,12 @@ st_table_calculate_row_heights (StTable *table,
if (!meta->x_fill)
{
gfloat width;
- clutter_actor_get_preferred_width (child, -1, NULL, &width);
+ _st_actor_get_preferred_width (child, -1, meta->y_fill, NULL, &width);
cell_width = MIN (cell_width, width);
}
- clutter_actor_get_preferred_height (child, cell_width, &h_min, &h_pref);
+ _st_actor_get_preferred_height (child, cell_width, meta->x_fill,
+ &h_min, &h_pref);
if (row_span == 1 && h_pref > pref_heights[row])
{
@@ -874,7 +762,8 @@ st_table_preferred_allocate (ClutterActor *self,
childbox.y2 = (float) MAX (0, child_y + row_height);
- st_table_allocate_fill (child, &childbox, x_align, y_align, x_fill, y_fill, ltr);
+ _st_allocate_fill (ST_WIDGET (self), child, &childbox,
+ x_align, y_align, x_fill, y_fill);
clutter_actor_allocate (child, &childbox, flags);
}
@@ -954,7 +843,7 @@ st_table_get_preferred_width (ClutterActor *self,
col = meta->col;
col_span = meta->col_span;
- clutter_actor_get_preferred_width (child, -1, &w_min, &w_pref);
+ _st_actor_get_preferred_width (child, -1, meta->y_fill, &w_min, &w_pref);
if (col_span == 1 && w_min > min_widths[col])
min_widths[col] = w_min;
@@ -1041,8 +930,8 @@ st_table_get_preferred_height (ClutterActor *self,
for (i = 0; i < col_span && col + i < priv->n_cols; i++)
cell_width += min_widths[col + i];
- clutter_actor_get_preferred_height (child,
- (float) cell_width, &min, &pref);
+ _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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]