2008-02-14 Tomas Frydrych <tf@openedhand.com>
authorTomas Frydrych <tf@openedhand.com>
Fri, 15 Feb 2008 09:13:50 +0000 (09:13 +0000)
committerTomas Frydrych <tf@openedhand.com>
Fri, 15 Feb 2008 09:13:50 +0000 (09:13 +0000)
* 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.

ChangeLog
clutter/clutter-actor.c
clutter/clutter-actor.h
clutter/clutter-group.c

index 3534119..4905d66 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,22 @@
 
        * 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
index ab07d96..06ca83e 100644 (file)
@@ -660,7 +660,6 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor  *self,
                                                 ClutterVertex *point,
                                                 ClutterVertex *vertex)
 {
-  ClutterFixed  mtx_p[16];
   ClutterFixed  v[4];
   ClutterFixed  w = CFX_ONE;
 
@@ -5516,3 +5515,50 @@ clutter_actor_set_shader_param (ClutterActor *self,
   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;
+}
+
index d963103..5a855d9 100644 (file)
@@ -458,6 +458,8 @@ gboolean clutter_actor_transform_stage_point          (ClutterActor   *self,
                                                        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
 
index 5461bfe..adc44e7 100644 (file)
@@ -149,6 +149,49 @@ clutter_group_request_coords (ClutterActor    *self,
 }
 
 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)
 {
@@ -167,12 +210,19 @@ clutter_group_query_coords (ClutterActor        *self,
     {
       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;
 
@@ -188,20 +238,22 @@ clutter_group_query_coords (ClutterActor        *self,
              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);
     }