mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
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.
This commit is contained in:
parent
0f3f0d54d2
commit
7814ec2eb5
@ -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);
|
||||
@ -4334,6 +4352,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;
|
||||
@ -4342,6 +4371,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;
|
||||
@ -4613,6 +4653,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;
|
||||
@ -4621,6 +4672,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;
|
||||
@ -5436,6 +5498,28 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
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:
|
||||
*
|
||||
@ -5474,6 +5558,27 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
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:
|
||||
*
|
||||
@ -8716,14 +8821,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -9139,6 +9259,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
|
||||
@ -9161,14 +9297,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -9614,6 +9783,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
|
||||
@ -12985,6 +13183,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;
|
||||
@ -12993,6 +13195,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;
|
||||
|
Loading…
Reference in New Issue
Block a user