[clutter] actor: Adjust the preferred size too
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter] actor: Adjust the preferred size too
- Date: Mon, 16 Jan 2012 23:52:57 +0000 (UTC)
commit 37d46649ce56ec55aaf23f7b745ae25224cf170a
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Mon Nov 28 15:30:52 2011 +0000
actor: Adjust the preferred size too
Don't adjust just the allocation: we need to adjust the preferred size
of the actor to account for the margin.
clutter/clutter-actor.c | 346 +++++++++++++++++++++++++++++++----------------
clutter/clutter-actor.h | 1 +
clutter/clutter-types.h | 4 +-
3 files changed, 230 insertions(+), 121 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 63751a2..62f1307 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -6239,6 +6239,178 @@ clutter_actor_get_preferred_size (ClutterActor *self,
*natural_height_p = natural_height;
}
+/*< private >
+ * effective_align:
+ * @align: a #ClutterActorAlign
+ * @direction: a #ClutterTextDirection
+ *
+ * Retrieves the correct alignment depending on the text direction
+ *
+ * Return value: the effective alignment
+ */
+static ClutterActorAlign
+effective_align (ClutterActorAlign align,
+ ClutterTextDirection direction)
+{
+ ClutterActorAlign res;
+
+ switch (align)
+ {
+ case CLUTTER_ACTOR_ALIGN_START:
+ res = (direction == CLUTTER_TEXT_DIRECTION_RTL)
+ ? CLUTTER_ACTOR_ALIGN_END
+ : CLUTTER_ACTOR_ALIGN_START;
+ break;
+
+ case CLUTTER_ACTOR_ALIGN_END:
+ res = (direction == CLUTTER_TEXT_DIRECTION_RTL)
+ ? CLUTTER_ACTOR_ALIGN_START
+ : CLUTTER_ACTOR_ALIGN_END;
+ break;
+
+ default:
+ res = align;
+ break;
+ }
+
+ return res;
+}
+
+static inline void
+adjust_for_margin (float margin_start,
+ float margin_end,
+ float *minimum_size,
+ float *natural_size,
+ float *allocated_start,
+ float *allocated_end)
+{
+ *minimum_size -= (margin_start + margin_end);
+ *natural_size -= (margin_start + margin_end);
+ *allocated_start += margin_start;
+ *allocated_end -= margin_end;
+}
+
+static inline void
+adjust_for_alignment (ClutterActorAlign alignment,
+ float natural_size,
+ float *allocated_start,
+ float *allocated_end)
+{
+ float allocated_size = *allocated_end - *allocated_start;
+
+ switch (alignment)
+ {
+ case CLUTTER_ACTOR_ALIGN_FILL:
+ /* do nothing */
+ break;
+
+ case CLUTTER_ACTOR_ALIGN_START:
+ /* keep start */
+ *allocated_end = *allocated_start + MIN (natural_size, allocated_size);
+ break;
+
+ case CLUTTER_ACTOR_ALIGN_END:
+ if (allocated_size > natural_size)
+ {
+ *allocated_start += (allocated_size - natural_size);
+ *allocated_end = *allocated_start + natural_size;
+ }
+ break;
+
+ case CLUTTER_ACTOR_ALIGN_CENTER:
+ if (allocated_size > natural_size)
+ {
+ *allocated_start += ceilf ((allocated_size - natural_size) / 2);
+ *allocated_end = *allocated_start + MIN (allocated_size, natural_size);
+ }
+ break;
+ }
+}
+
+/*< private >
+ * clutter_actor_adjust_width:
+ * @self: a #ClutterActor
+ * @minimum_width: (inout): the actor's preferred minimum width, which
+ * will be adjusted depending on the margin
+ * @natural_width: (inout): the actor's preferred natural width, which
+ * will be adjusted depending on the margin
+ * @adjusted_x1: (out): the adjusted x1 for the actor's bounding box
+ * @adjusted_x2: (out): the adjusted x2 for the actor's bounding box
+ *
+ * Adjusts the preferred and allocated position and size of an actor,
+ * depending on the margin and alignment properties.
+ */
+static void
+clutter_actor_adjust_width (ClutterActor *self,
+ gfloat *minimum_width,
+ gfloat *natural_width,
+ gfloat *adjusted_x1,
+ gfloat *adjusted_x2)
+{
+ ClutterTextDirection text_dir;
+ const ClutterLayoutInfo *info;
+
+ info = _clutter_actor_get_layout_info_or_defaults (self);
+ text_dir = clutter_actor_get_text_direction (self);
+
+ CLUTTER_NOTE (LAYOUT, "Adjusting allocated X and width");
+
+ /* this will tweak natural_width to remove the margin, so that
+ * adjust_for_alignment() will use the correct size
+ */
+ adjust_for_margin (info->margin.left, info->margin.right,
+ minimum_width, natural_width,
+ adjusted_x1, adjusted_x2);
+
+ adjust_for_alignment (effective_align (info->x_align, text_dir),
+ *natural_width,
+ adjusted_x1, adjusted_x2);
+}
+
+/*< private >
+ * clutter_actor_adjust_height:
+ * @self: a #ClutterActor
+ * @minimum_height: (inout): the actor's preferred minimum height, which
+ * will be adjusted depending on the margin
+ * @natural_height: (inout): the actor's preferred natural height, which
+ * will be adjusted depending on the margin
+ * @adjusted_y1: (out): the adjusted y1 for the actor's bounding box
+ * @adjusted_y2: (out): the adjusted y2 for the actor's bounding box
+ *
+ * Adjusts the preferred and allocated position and size of an actor,
+ * depending on the margin and alignment properties.
+ */
+static void
+clutter_actor_adjust_height (ClutterActor *self,
+ gfloat *minimum_height,
+ gfloat *natural_height,
+ gfloat *adjusted_y1,
+ gfloat *adjusted_y2)
+{
+ const ClutterLayoutInfo *info;
+
+ info = _clutter_actor_get_layout_info_or_defaults (self);
+
+ CLUTTER_NOTE (LAYOUT, "Adjusting allocated Y and height");
+
+ /* this will tweak natural_height to remove the margin, so that
+ * adjust_for_alignment() will use the correct size
+ */
+ adjust_for_margin (info->margin.top, info->margin.bottom,
+ minimum_height, natural_height,
+ adjusted_y1,
+ adjusted_y2);
+
+ /* we don't use effective_align() here, because text direction
+ * only affects the horizontal axis
+ */
+ adjust_for_alignment (info->y_align,
+ *natural_height,
+ adjusted_y1,
+ adjusted_y2);
+
+}
+
/* looks for a cached size request for this for_size. If not
* found, returns the oldest entry so it can be overwritten */
static gboolean
@@ -6318,10 +6490,10 @@ clutter_actor_get_preferred_width (ClutterActor *self,
if (priv->min_width_set && priv->natural_width_set)
{
if (min_width_p != NULL)
- *min_width_p = info->min_width;
+ *min_width_p = info->min_width + (info->margin.left + info->margin.right);
if (natural_width_p != NULL)
- *natural_width_p = info->natural_width;
+ *natural_width_p = info->natural_width + (info->margin.left + info->margin.right);
return;
}
@@ -6352,25 +6524,37 @@ clutter_actor_get_preferred_width (ClutterActor *self,
if (!found_in_cache)
{
- gfloat min_width, natural_width;
+ gfloat minimum_width, natural_width;
ClutterActorClass *klass;
- min_width = natural_width = 0;
+ minimum_width = natural_width = 0;
+
+ /* adjust for the margin */
+ if (for_height >= 0)
+ {
+ for_height -= (info->margin.top + info->margin.bottom);
+ if (for_height < 0)
+ for_height = 0;
+ }
CLUTTER_NOTE (LAYOUT, "Width request for %.2f px", for_height);
klass = CLUTTER_ACTOR_GET_CLASS (self);
klass->get_preferred_width (self, for_height,
- &min_width,
+ &minimum_width,
&natural_width);
+ /* adjust for the margin */
+ minimum_width += (info->margin.left + info->margin.right);
+ natural_width += (info->margin.left + info->margin.right);
+
/* Due to accumulated float errors, it's better not to warn
* on this, but just fix it.
*/
- if (natural_width < min_width)
- natural_width = min_width;
+ if (natural_width < minimum_width)
+ natural_width = minimum_width;
- cached_size_request->min_size = min_width;
+ cached_size_request->min_size = minimum_width;
cached_size_request->natural_size = natural_width;
cached_size_request->for_size = for_height;
cached_size_request->age = priv->cached_width_age;
@@ -6439,10 +6623,10 @@ clutter_actor_get_preferred_height (ClutterActor *self,
if (priv->min_height_set && priv->natural_height_set)
{
if (min_height_p != NULL)
- *min_height_p = info->min_height;
+ *min_height_p = info->min_height + (info->margin.top + info->margin.bottom);
if (natural_height_p != NULL)
- *natural_height_p = info->natural_height;
+ *natural_height_p = info->natural_height + (info->margin.top + info->margin.bottom);
return;
}
@@ -6472,25 +6656,37 @@ clutter_actor_get_preferred_height (ClutterActor *self,
if (!found_in_cache)
{
- gfloat min_height, natural_height;
+ gfloat minimum_height, natural_height;
ClutterActorClass *klass;
- min_height = natural_height = 0;
+ minimum_height = natural_height = 0;
CLUTTER_NOTE (LAYOUT, "Height request for %.2f px", for_width);
+ /* adjust for margin */
+ if (for_width >= 0)
+ {
+ for_width -= (info->margin.left + info->margin.right);
+ if (for_width < 0)
+ for_width = 0;
+ }
+
klass = CLUTTER_ACTOR_GET_CLASS (self);
klass->get_preferred_height (self, for_width,
- &min_height,
+ &minimum_height,
&natural_height);
+ /* adjust for margin */
+ minimum_height += (info->margin.top + info->margin.bottom);
+ natural_height += (info->margin.top + info->margin.bottom);
+
/* Due to accumulated float errors, it's better not to warn
* on this, but just fix it.
*/
- if (natural_height < min_height)
- natural_height = min_height;
+ if (natural_height < minimum_height)
+ natural_height = minimum_height;
- cached_size_request->min_size = min_height;
+ cached_size_request->min_size = minimum_height;
cached_size_request->natural_size = natural_height;
cached_size_request->for_size = for_width;
cached_size_request->age = priv->cached_height_age;
@@ -6601,85 +6797,6 @@ clutter_actor_get_allocation_geometry (ClutterActor *self,
geom->height = CLUTTER_NEARBYINT (clutter_actor_box_get_height (&box));
}
-static ClutterActorAlign
-effective_align (ClutterActorAlign align,
- ClutterTextDirection direction)
-{
- ClutterActorAlign res;
-
- switch (align)
- {
- case CLUTTER_ACTOR_ALIGN_START:
- res = (direction == CLUTTER_TEXT_DIRECTION_RTL)
- ? CLUTTER_ACTOR_ALIGN_END
- : CLUTTER_ACTOR_ALIGN_START;
- break;
-
- case CLUTTER_ACTOR_ALIGN_END:
- res = (direction == CLUTTER_TEXT_DIRECTION_RTL)
- ? CLUTTER_ACTOR_ALIGN_START
- : CLUTTER_ACTOR_ALIGN_END;
- break;
-
- default:
- res = align;
- break;
- }
-
- return res;
-}
-
-static inline void
-adjust_for_margin (float margin_start,
- float margin_end,
- float *minimum_size,
- float *natural_size,
- float *allocated_start,
- float *allocated_end)
-{
- *minimum_size -= (margin_start + margin_end);
- *natural_size -= (margin_start + margin_end);
- *allocated_start += margin_start;
- *allocated_end -= margin_end;
-}
-
-static inline void
-adjust_for_alignment (ClutterActorAlign alignment,
- float natural_size,
- float *allocated_start,
- float *allocated_end)
-{
- float allocated_size = *allocated_end - *allocated_start;
-
- switch (alignment)
- {
- case CLUTTER_ACTOR_ALIGN_FILL:
- /* do nothing */
- break;
-
- case CLUTTER_ACTOR_ALIGN_START:
- /* keep start */
- *allocated_end = *allocated_start + MIN (natural_size, allocated_size);
- break;
-
- case CLUTTER_ACTOR_ALIGN_END:
- if (allocated_size > natural_size)
- {
- *allocated_start += (allocated_size - natural_size);
- *allocated_end = *allocated_start + natural_size;
- }
- break;
-
- case CLUTTER_ACTOR_ALIGN_CENTER:
- if (allocated_size > natural_size)
- {
- *allocated_start += ceilf ((allocated_size - natural_size) / 2);
- *allocated_end = *allocated_start + MIN (allocated_size, natural_size);
- }
- break;
- }
-}
-
/*< private >
* clutter_actor_adjust_allocation:
* @self: a #ClutterActor
@@ -6697,8 +6814,6 @@ clutter_actor_adjust_allocation (ClutterActor *self,
float min_width, min_height;
float nat_width, nat_height;
ClutterRequestMode req_mode;
- ClutterTextDirection text_dir;
- const ClutterLayoutInfo *info;
adj_allocation = *allocation;
@@ -6744,24 +6859,17 @@ clutter_actor_adjust_allocation (ClutterActor *self,
}
#endif
- info = _clutter_actor_get_layout_info_or_defaults (self);
- text_dir = clutter_actor_get_text_direction (self);
+ clutter_actor_adjust_width (self,
+ &min_width,
+ &nat_width,
+ &adj_allocation.x1,
+ &adj_allocation.x2);
- CLUTTER_NOTE (LAYOUT, "Adjusting allocated X and width");
- adjust_for_margin (info->margin.left, info->margin.right,
- &min_width, &nat_width,
- &adj_allocation.x1, &adj_allocation.x2);
- adjust_for_alignment (effective_align (info->x_align, text_dir),
- nat_width,
- &adj_allocation.x1, &adj_allocation.x2);
-
- CLUTTER_NOTE (LAYOUT, "Adjusting allocated Y and height");
- adjust_for_margin (info->margin.top, info->margin.bottom,
- &min_height, &nat_height,
- &adj_allocation.y1, &adj_allocation.y2);
- adjust_for_alignment (info->y_align,
- nat_height,
- &adj_allocation.y1, &adj_allocation.y2);
+ clutter_actor_adjust_height (self,
+ &min_height,
+ &nat_height,
+ &adj_allocation.y1,
+ &adj_allocation.y2);
/* we maintain the invariant that an allocation cannot be adjusted
* to be outside the parent-given box
@@ -8880,7 +8988,7 @@ clutter_actor_insert_child (ClutterActor *self,
ClutterActor *child)
{
ClutterActorPrivate *priv = self->priv;
- GList *l, *prev;
+ GList *l, *prev = NULL;
/* Find the right place to insert the child so that it will still be
sorted and the child will be after all of the actors at the same
@@ -13884,7 +13992,7 @@ clutter_actor_needs_y_expand (ClutterActor *self)
return self->priv->y_expand_effective;
}
-/*< private >
+/**
* clutter_actor_queue_compute_expand:
* @self: a #ClutterActor
*
@@ -13895,7 +14003,7 @@ clutter_actor_needs_y_expand (ClutterActor *self)
*
* Since: 1.10
*/
-static void
+void
clutter_actor_queue_compute_expand (ClutterActor *self)
{
ClutterActor *parent_actor;
@@ -13993,7 +14101,7 @@ clutter_actor_get_x_expand (ClutterActor *self)
/**
* clutter_actor_set_y_expand:
* @self: a #ClutterActor
- * @x_expand: whether the actor should expand
+ * @y_expand: whether the actor should expand
*
* Sets whether a #ClutterActor should receive extra space when possible,
* during the allocation.
@@ -14114,7 +14222,7 @@ clutter_actor_get_x_align (ClutterActor *self)
/**
* clutter_actor_set_y_align:
* @self: a #ClutterActor
- * @x_align: the vertical alignment policy
+ * @y_align: the vertical alignment policy
*
* Sets the vertical alignment policy of a #ClutterActor, in case the
* actor received extra vertical space.
diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h
index bbe2a61..c72f808 100644
--- a/clutter/clutter-actor.h
+++ b/clutter/clutter-actor.h
@@ -375,6 +375,7 @@ void clutter_actor_set_y_expand (ClutterActor
gboolean clutter_actor_get_y_expand (ClutterActor *self);
gboolean clutter_actor_needs_x_expand (ClutterActor *self);
gboolean clutter_actor_needs_y_expand (ClutterActor *self);
+void clutter_actor_queue_compute_expand (ClutterActor *self);
void clutter_actor_set_x_align (ClutterActor *self,
ClutterActorAlign x_align);
diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h
index c04e9a6..f9c109e 100644
--- a/clutter/clutter-types.h
+++ b/clutter/clutter-types.h
@@ -289,8 +289,8 @@ struct _ClutterMargin
GType clutter_margin_get_type (void) G_GNUC_CONST;
ClutterMargin * clutter_margin_new (void) G_GNUC_MALLOC;
-ClutterMargin * clutter_margin_copy (const ClutterMargin *margin);
-void clutter_margin_free (ClutterMargin *margin);
+ClutterMargin * clutter_margin_copy (const ClutterMargin *margin_);
+void clutter_margin_free (ClutterMargin *margin_);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]