* clutter/clutter-actor.c:
* clutter/clutter-actor.h:
+ (clutter_actor_is_scaled):
+ (clutter_actor_is_rotated):
+ Convenience functions to test whether actor is scaled or rotated.
+
+ (clutter_actor_apply_relative_transform_to_point):
+ Removed unused variable.
+
+ * clutter/clutter-group.c:
+ (clutter_group_query_coords):
+ Use clutter_actor_get_relative_vertices() to calculate bounding
+ boxes of children that are scaled or rotated.
+
+2008-02-14 Tomas Frydrych <tf@openedhand.com>
+
+ * clutter/clutter-actor.c:
+ * clutter/clutter-actor.h:
(clutter_actor_get_relative_vertices):
(clutter_actor_apply_relative_transform_to_point):
Functions to calculate actor vertices in the plane of a given
ClutterVertex *point,
ClutterVertex *vertex)
{
- ClutterFixed mtx_p[16];
ClutterFixed v[4];
ClutterFixed w = CFX_ONE;
box->value = value;
g_hash_table_insert (shader_data->float1f_hash, g_strdup (param), box);
}
+
+/**
+ * clutter_actor_is_rotated:
+ * @self: a #ClutterActor
+ *
+ * Returns true if any rotation is applied to the actor.
+ *
+ * Since: 0.6
+ */
+gboolean
+clutter_actor_is_rotated (ClutterActor *self)
+{
+ ClutterActorPrivate *priv;
+
+ g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
+
+ priv = self->priv;
+
+ if (priv->rxang || priv->ryang || priv->rzang)
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * clutter_actor_is_scaled:
+ * @self: a #ClutterActor
+ *
+ * Returns true if the actor is scaled in either dimension.
+ *
+ * Since: 0.6
+ */
+gboolean
+clutter_actor_is_scaled (ClutterActor *self)
+{
+ ClutterActorPrivate *priv;
+
+ g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
+
+ priv = self->priv;
+
+ if (priv->scale_x != CFX_ONE || priv->scale_y != CFX_ONE)
+ return TRUE;
+
+ return FALSE;
+}
+
ClutterUnit y,
ClutterUnit *x_out,
ClutterUnit *y_out);
+gboolean clutter_actor_is_rotated (ClutterActor *self);
+gboolean clutter_actor_is_scaled (ClutterActor *self);
G_END_DECLS
}
static void
+clutter_group_get_box_from_vertices (ClutterActorBox *box,
+ ClutterVertex vtx[4])
+{
+ ClutterUnit x1, x2, y1, y2;
+
+ /* 4-way min/max */
+ x1 = vtx[0].x;
+ y1 = vtx[0].y;
+ if (vtx[1].x < x1)
+ x1 = vtx[1].x;
+ if (vtx[2].x < x1)
+ x1 = vtx[2].x;
+ if (vtx[3].x < x1)
+ x1 = vtx[3].x;
+ if (vtx[1].y < y1)
+ y1 = vtx[1].y;
+ if (vtx[2].y < y1)
+ y1 = vtx[2].y;
+ if (vtx[3].y < y1)
+ y1 = vtx[3].y;
+
+ x2 = vtx[0].x;
+ y2 = vtx[0].y;
+ if (vtx[1].x > x2)
+ x2 = vtx[1].x;
+ if (vtx[2].x > x2)
+ x2 = vtx[2].x;
+ if (vtx[3].x > x2)
+ x2 = vtx[3].x;
+ if (vtx[1].y > y2)
+ y2 = vtx[1].y;
+ if (vtx[2].y > y2)
+ y2 = vtx[2].y;
+ if (vtx[3].y > y2)
+ y2 = vtx[3].y;
+
+ box->x1 = x1;
+ box->x2 = x2;
+ box->y1 = y1;
+ box->y2 = y2;
+}
+
+static void
clutter_group_query_coords (ClutterActor *self,
ClutterActorBox *box)
{
{
do
{
- ClutterActor *child = CLUTTER_ACTOR(child_item->data);
+ ClutterActor *child = CLUTTER_ACTOR(child_item->data);
+ ClutterActorBox cbox;
- /* Once added we include in sizing - doesn't matter if visible */
- /* if (CLUTTER_ACTOR_IS_VISIBLE (child)) */
+ if (clutter_actor_is_scaled (child) ||
+ clutter_actor_is_rotated (child))
+ {
+ ClutterVertex vtx[4];
+
+ clutter_actor_get_relative_vertices (child, self, vtx);
+ clutter_group_get_box_from_vertices (&cbox, vtx);
+ }
+ else
{
- ClutterActorBox cbox;
gint anchor_x;
gint anchor_y;
cbox.x2 -= anchor_x;
cbox.y1 -= anchor_y;
cbox.y2 -= anchor_y;
-
- /* Ignore any children with offscreen ( negaive )
- * positions.
- *
- * Also x1 and x2 will be set by parent caller.
- *
- * FIXME: this assumes that children are not rotated in anyway.
- */
- if (box->x2 - box->x1 < cbox.x2)
- box->x2 = cbox.x2 + box->x1;
-
- if (box->y2 - box->y1 < cbox.y2)
- box->y2 = cbox.y2 + box->y1;
}
+
+ /* FIXME: now that we go into the trouble of working out the
+ * projected sizes, we should do better than this (probably resize
+ * the box in all direction as required).
+ *
+ * Ignore any children with offscreen ( negaive )
+ * positions.
+ *
+ * Also x1 and x2 will be set by parent caller.
+ */
+ if (box->x2 - box->x1 < cbox.x2)
+ box->x2 = cbox.x2 + box->x1;
+
+ if (box->y2 - box->y1 < cbox.y2)
+ box->y2 = cbox.y2 + box->y1;
}
while ((child_item = g_list_next(child_item)) != NULL);
}