[clutter/wip/base-types: 5/6] actor: Add position and size animatable properties
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/base-types: 5/6] actor: Add position and size animatable properties
- Date: Wed, 11 Apr 2012 17:33:49 +0000 (UTC)
commit 9a52a70eeab1d0966c1065af6b83277fa6f7ca7f
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Sun Apr 1 17:32:59 2012 +0100
actor: Add position and size animatable properties
Using a compound type property for position and size has various
advantages: it reduces the amount of checks; it reduces the amount
of notify signals to connect to; it reduces the amount of transitions
generated.
clutter/clutter-actor.c | 230 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 218 insertions(+), 12 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index e5f6109..34711e8 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -788,6 +788,9 @@ enum
PROP_WIDTH,
PROP_HEIGHT,
+ PROP_POSITION,
+ PROP_SIZE,
+
/* Then the rest of these size-related properties are the "actual"
* underlying properties set or gotten by X, Y, WIDTH, HEIGHT
*/
@@ -2165,13 +2168,16 @@ clutter_actor_notify_if_geometry_changed (ClutterActor *self,
{
g_object_notify_by_pspec (obj, obj_props[PROP_X]);
g_object_notify_by_pspec (obj, obj_props[PROP_Y]);
+ g_object_notify_by_pspec (obj, obj_props[PROP_POSITION]);
g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]);
g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]);
+ g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]);
}
else if (priv->needs_width_request || priv->needs_height_request)
{
g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]);
g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]);
+ g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]);
}
else
{
@@ -2184,16 +2190,28 @@ clutter_actor_notify_if_geometry_changed (ClutterActor *self,
height = priv->allocation.y2 - priv->allocation.y1;
if (x != old->x1)
- g_object_notify_by_pspec (obj, obj_props[PROP_X]);
+ {
+ g_object_notify_by_pspec (obj, obj_props[PROP_X]);
+ g_object_notify_by_pspec (obj, obj_props[PROP_POSITION]);
+ }
if (y != old->y1)
- g_object_notify_by_pspec (obj, obj_props[PROP_Y]);
+ {
+ g_object_notify_by_pspec (obj, obj_props[PROP_Y]);
+ g_object_notify_by_pspec (obj, obj_props[PROP_POSITION]);
+ }
if (width != (old->x2 - old->x1))
- g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]);
+ {
+ g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]);
+ g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]);
+ }
if (height != (old->y2 - old->y1))
- g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]);
+ {
+ g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]);
+ g_object_notify_by_pspec (obj, obj_props[PROP_SIZE]);
+ }
}
g_object_thaw_notify (obj);
@@ -4331,6 +4349,17 @@ clutter_actor_set_property (GObject *object,
clutter_actor_set_y (actor, g_value_get_float (value));
break;
+ case PROP_POSITION:
+ {
+ const ClutterPoint *pos = g_value_get_boxed (value);
+
+ if (pos != NULL)
+ clutter_actor_set_position (actor, pos->x, pos->y);
+ else
+ clutter_actor_set_fixed_position_set (actor, FALSE);
+ }
+ break;
+
case PROP_WIDTH:
clutter_actor_set_width (actor, g_value_get_float (value));
break;
@@ -4339,6 +4368,17 @@ clutter_actor_set_property (GObject *object,
clutter_actor_set_height (actor, g_value_get_float (value));
break;
+ case PROP_SIZE:
+ {
+ const ClutterSize *size = g_value_get_boxed (value);
+
+ if (size != NULL)
+ clutter_actor_set_size (actor, size->width, size->height);
+ else
+ clutter_actor_set_size (actor, -1, -1);
+ }
+ break;
+
case PROP_FIXED_X:
clutter_actor_set_x (actor, g_value_get_float (value));
break;
@@ -4610,6 +4650,17 @@ clutter_actor_get_property (GObject *object,
g_value_set_float (value, clutter_actor_get_y (actor));
break;
+ case PROP_POSITION:
+ {
+ ClutterPoint position;
+
+ clutter_point_init (&position,
+ clutter_actor_get_x (actor),
+ clutter_actor_get_y (actor));
+ g_value_set_boxed (value, &position);
+ }
+ break;
+
case PROP_WIDTH:
g_value_set_float (value, clutter_actor_get_width (actor));
break;
@@ -4618,6 +4669,17 @@ clutter_actor_get_property (GObject *object,
g_value_set_float (value, clutter_actor_get_height (actor));
break;
+ case PROP_SIZE:
+ {
+ ClutterSize size;
+
+ clutter_size_init (&size,
+ clutter_actor_get_width (actor),
+ clutter_actor_get_height (actor));
+ g_value_set_boxed (value, &size);
+ }
+ break;
+
case PROP_FIXED_X:
{
const ClutterLayoutInfo *info;
@@ -5428,6 +5490,28 @@ clutter_actor_class_init (ClutterActorClass *klass)
CLUTTER_PARAM_ANIMATABLE);
/**
+ * ClutterActor:position:
+ *
+ * The position of the origin of the actor.
+ *
+ * This property is a shorthand for setting and getting the
+ * #ClutterActor:x and #ClutterActor:y properties at the same
+ * time.
+ *
+ * The #ClutterActor:position property is animatable.
+ *
+ * Since: 1.12
+ */
+ obj_props[PROP_POSITION] =
+ g_param_spec_boxed ("position",
+ P_("Position"),
+ P_("The position of the origin of the actor"),
+ CLUTTER_TYPE_POINT,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ CLUTTER_PARAM_ANIMATABLE);
+
+ /**
* ClutterActor:width:
*
* Width of the actor (in pixels). If written, forces the minimum and
@@ -5466,6 +5550,27 @@ clutter_actor_class_init (ClutterActorClass *klass)
CLUTTER_PARAM_ANIMATABLE);
/**
+ * ClutterActor:size:
+ *
+ * The size of the actor.
+ *
+ * This property is a shorthand for setting and getting the
+ * #ClutterActor:width and #ClutterActor:height at the same time.
+ *
+ * The #ClutterActor:size property is animatable.
+ *
+ * Since: 1.12
+ */
+ obj_props[PROP_SIZE] =
+ g_param_spec_boxed ("size",
+ P_("Size"),
+ P_("The size of the actor"),
+ CLUTTER_TYPE_SIZE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS |
+ CLUTTER_PARAM_ANIMATABLE);
+
+ /**
* ClutterActor:fixed-x:
*
* The fixed X position of the actor in pixels.
@@ -8707,14 +8812,29 @@ clutter_actor_set_position (ClutterActor *self,
gfloat x,
gfloat y)
{
+ ClutterPoint new_position;
+
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- g_object_freeze_notify (G_OBJECT (self));
+ clutter_point_init (&new_position, x, y);
- clutter_actor_set_x (self, x);
- clutter_actor_set_y (self, y);
+ if (_clutter_actor_get_transition (self, obj_props[PROP_POSITION]) == NULL)
+ {
+ ClutterPoint cur_position;
- g_object_thaw_notify (G_OBJECT (self));
+ cur_position.x = clutter_actor_get_x (self);
+ cur_position.y = clutter_actor_get_y (self);
+
+ _clutter_actor_create_transition (self, obj_props[PROP_POSITION],
+ &cur_position,
+ &new_position);
+ }
+ else
+ _clutter_actor_update_transition (self,
+ obj_props[PROP_POSITION],
+ &new_position);
+
+ clutter_actor_queue_relayout (self);
}
/**
@@ -9130,6 +9250,22 @@ clutter_actor_set_height_internal (ClutterActor *self,
}
}
+static void
+clutter_actor_set_size_internal (ClutterActor *self,
+ const ClutterSize *size)
+{
+ if (size != NULL)
+ {
+ clutter_actor_set_width_internal (self, size->width);
+ clutter_actor_set_height_internal (self, size->height);
+ }
+ else
+ {
+ clutter_actor_set_width_internal (self, -1);
+ clutter_actor_set_height_internal (self, -1);
+ }
+}
+
/**
* clutter_actor_set_size:
* @self: A #ClutterActor
@@ -9152,14 +9288,47 @@ clutter_actor_set_size (ClutterActor *self,
gfloat width,
gfloat height)
{
+ ClutterSize new_size;
+
g_return_if_fail (CLUTTER_IS_ACTOR (self));
- g_object_freeze_notify (G_OBJECT (self));
+ clutter_size_init (&new_size, width, height);
- clutter_actor_set_width (self, width);
- clutter_actor_set_height (self, height);
+ if (_clutter_actor_get_transition (self, obj_props[PROP_SIZE]) == NULL)
+ {
+ /* minor optimization: if we don't have a duration then we can
+ * skip the get_size() below, to avoid the chance of going through
+ * get_preferred_width() and get_preferred_height() just to jump to
+ * a new desired size
+ */
+ if (clutter_actor_get_easing_duration (self) == 0)
+ {
+ g_object_freeze_notify (G_OBJECT (self));
- g_object_thaw_notify (G_OBJECT (self));
+ clutter_actor_set_size_internal (self, &new_size);
+
+ g_object_thaw_notify (G_OBJECT (self));
+
+ return;
+ }
+ else
+ {
+ ClutterSize cur_size;
+
+ clutter_size_init (&cur_size,
+ clutter_actor_get_width (self),
+ clutter_actor_get_height (self));
+
+ _clutter_actor_create_transition (self,
+ obj_props[PROP_SIZE],
+ &cur_size,
+ &new_size);
+ }
+ }
+ else
+ _clutter_actor_update_transition (self, obj_props[PROP_SIZE], &new_size);
+
+ clutter_actor_queue_relayout (self);
}
/**
@@ -9605,6 +9774,35 @@ clutter_actor_set_y_internal (ClutterActor *self,
clutter_actor_queue_relayout (self);
}
+static void
+clutter_actor_set_position_internal (ClutterActor *self,
+ const ClutterPoint *position)
+{
+ ClutterActorPrivate *priv = self->priv;
+ ClutterLayoutInfo *linfo;
+ ClutterActorBox old = { 0, };
+
+ linfo = _clutter_actor_get_layout_info (self);
+
+ if (priv->position_set &&
+ clutter_point_equals (position, &linfo->fixed_pos))
+ return;
+
+ clutter_actor_store_old_geometry (self, &old);
+
+ if (position != NULL)
+ {
+ linfo->fixed_pos = *position;
+ clutter_actor_set_fixed_position_set (self, TRUE);
+ }
+ else
+ clutter_actor_set_fixed_position_set (self, FALSE);
+
+ clutter_actor_notify_if_geometry_changed (self, &old);
+
+ clutter_actor_queue_relayout (self);
+}
+
/**
* clutter_actor_set_x:
* @self: a #ClutterActor
@@ -12971,6 +13169,10 @@ clutter_actor_set_animatable_property (ClutterActor *actor,
clutter_actor_set_y_internal (actor, g_value_get_float (value));
break;
+ case PROP_POSITION:
+ clutter_actor_set_position_internal (actor, g_value_get_boxed (value));
+ break;
+
case PROP_WIDTH:
clutter_actor_set_width_internal (actor, g_value_get_float (value));
break;
@@ -12979,6 +13181,10 @@ clutter_actor_set_animatable_property (ClutterActor *actor,
clutter_actor_set_height_internal (actor, g_value_get_float (value));
break;
+ case PROP_SIZE:
+ clutter_actor_set_size_internal (actor, g_value_get_boxed (value));
+ break;
+
case PROP_DEPTH:
clutter_actor_set_depth_internal (actor, g_value_get_float (value));
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]