mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
Merge branch 'scale-center'
Bug 1349 - Using the anchor point to set the scale center is messy The branch adds an extra center point for scaling which can be used for example to set a scale about the center without affecting the position of the actor. The scale center can be specified as a unit offset from the origin or as a gravity. If specified as a gravity it will be stored as a fraction of the actor's size so that the position will track when the actor changes size. The anchor point and rotation centers have been modified so they can be set with a gravity in the same way. However, only the Z rotation exposes a property to set using a gravity because the other two require a Z coordinate which doesn't make sense to interpret as a fraction of the actor's width or height. Conflicts: clutter/clutter-actor.c
This commit is contained in:
commit
3e68b23ea8
File diff suppressed because it is too large
Load Diff
@ -390,33 +390,26 @@ void clutter_actor_set_rotation (ClutterActor
|
||||
gint x,
|
||||
gint y,
|
||||
gint z);
|
||||
void clutter_actor_set_rotationx (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
ClutterFixed angle,
|
||||
gint x,
|
||||
gint y,
|
||||
gint z);
|
||||
void clutter_actor_set_rotationu (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gdouble angle,
|
||||
ClutterUnit x,
|
||||
ClutterUnit y,
|
||||
ClutterUnit z);
|
||||
void clutter_actor_set_z_rotation_from_gravity (ClutterActor *self,
|
||||
gdouble angle,
|
||||
ClutterGravity gravity);
|
||||
gdouble clutter_actor_get_rotation (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *z);
|
||||
ClutterFixed clutter_actor_get_rotationx (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *z);
|
||||
gdouble clutter_actor_get_rotationu (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
ClutterUnit *x,
|
||||
ClutterUnit *y,
|
||||
ClutterUnit *z);
|
||||
ClutterGravity clutter_actor_get_z_rotation_gravity (ClutterActor *self);
|
||||
|
||||
void clutter_actor_set_opacity (ClutterActor *self,
|
||||
guint8 opacity);
|
||||
@ -474,18 +467,33 @@ void clutter_actor_set_depthu (ClutterActor
|
||||
ClutterUnit depth);
|
||||
ClutterUnit clutter_actor_get_depthu (ClutterActor *self);
|
||||
|
||||
void clutter_actor_set_scalex (ClutterActor *self,
|
||||
ClutterFixed scale_x,
|
||||
ClutterFixed scale_y);
|
||||
void clutter_actor_set_scale (ClutterActor *self,
|
||||
gdouble scale_x,
|
||||
gdouble scale_y);
|
||||
void clutter_actor_get_scalex (ClutterActor *self,
|
||||
ClutterFixed *scale_x,
|
||||
ClutterFixed *scale_y);
|
||||
void clutter_actor_set_scale_full (ClutterActor *self,
|
||||
gdouble scale_x,
|
||||
gdouble scale_y,
|
||||
int center_x,
|
||||
int center_y);
|
||||
void clutter_actor_set_scale_fullu (ClutterActor *self,
|
||||
gdouble scale_x,
|
||||
gdouble scale_y,
|
||||
ClutterUnit center_x,
|
||||
ClutterUnit center_y);
|
||||
void clutter_actor_set_scale_with_gravity (ClutterActor *self,
|
||||
gdouble scale_x,
|
||||
gdouble scale_y,
|
||||
ClutterGravity gravity);
|
||||
void clutter_actor_get_scale (ClutterActor *self,
|
||||
gdouble *scale_x,
|
||||
gdouble *scale_y);
|
||||
void clutter_actor_get_scale_center (ClutterActor *self,
|
||||
gint *center_x,
|
||||
gint *center_y);
|
||||
void clutter_actor_get_scale_centeru (ClutterActor *self,
|
||||
ClutterUnit *center_x,
|
||||
ClutterUnit *center_y);
|
||||
ClutterGravity clutter_actor_get_scale_gravity (ClutterActor *self);
|
||||
|
||||
void clutter_actor_move_by (ClutterActor *self,
|
||||
gint dx,
|
||||
@ -526,6 +534,7 @@ void clutter_actor_move_anchor_point (ClutterActor *self,
|
||||
void clutter_actor_get_anchor_point (ClutterActor *self,
|
||||
gint *anchor_x,
|
||||
gint *anchor_y);
|
||||
ClutterGravity clutter_actor_get_anchor_point_gravity (ClutterActor *self);
|
||||
void clutter_actor_set_anchor_pointu (ClutterActor *self,
|
||||
ClutterUnit anchor_x,
|
||||
ClutterUnit anchor_y);
|
||||
|
@ -95,11 +95,11 @@ alpha_notify_foreach (ClutterBehaviour *behaviour,
|
||||
rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour);
|
||||
priv = rotate_behaviour->priv;
|
||||
|
||||
clutter_actor_set_rotationx (actor, priv->axis,
|
||||
angle,
|
||||
priv->center_x,
|
||||
priv->center_y,
|
||||
priv->center_z);
|
||||
clutter_actor_set_rotation (actor, priv->axis,
|
||||
CLUTTER_FIXED_TO_DOUBLE (angle),
|
||||
priv->center_x,
|
||||
priv->center_y,
|
||||
priv->center_z);
|
||||
}
|
||||
|
||||
static inline
|
||||
|
@ -85,7 +85,9 @@ scale_frame_foreach (ClutterBehaviour *behaviour,
|
||||
{
|
||||
ScaleFrameClosure *closure = data;
|
||||
|
||||
clutter_actor_set_scalex (actor, closure->scale_x, closure->scale_y);
|
||||
clutter_actor_set_scale (actor,
|
||||
CLUTTER_FIXED_TO_DOUBLE (closure->scale_x),
|
||||
CLUTTER_FIXED_TO_DOUBLE (closure->scale_y));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -352,7 +352,9 @@ clutter_actor_set_y
|
||||
clutter_actor_get_y
|
||||
clutter_actor_move_by
|
||||
clutter_actor_set_rotation
|
||||
clutter_actor_set_z_rotation_from_gravity
|
||||
clutter_actor_get_rotation
|
||||
clutter_actor_get_z_rotation_gravity
|
||||
clutter_actor_is_rotated
|
||||
clutter_actor_set_opacity
|
||||
clutter_actor_get_opacity
|
||||
@ -381,7 +383,11 @@ clutter_actor_get_stage
|
||||
clutter_actor_set_depth
|
||||
clutter_actor_get_depth
|
||||
clutter_actor_set_scale
|
||||
clutter_actor_set_scale_full
|
||||
clutter_actor_set_scale_with_gravity
|
||||
clutter_actor_get_scale
|
||||
clutter_actor_get_scale_center
|
||||
clutter_actor_get_scale_gravity
|
||||
clutter_actor_is_scaled
|
||||
clutter_actor_apply_transform_to_point
|
||||
clutter_actor_transform_stage_point
|
||||
@ -400,6 +406,7 @@ clutter_actor_box_get_from_vertices
|
||||
clutter_actor_set_anchor_point
|
||||
clutter_actor_get_anchor_point
|
||||
clutter_actor_set_anchor_point_from_gravity
|
||||
clutter_actor_get_anchor_point_gravity
|
||||
clutter_actor_move_anchor_point
|
||||
clutter_actor_move_anchor_point_from_gravity
|
||||
|
||||
@ -427,6 +434,8 @@ clutter_actor_set_positionu
|
||||
clutter_actor_get_positionu
|
||||
clutter_actor_set_sizeu
|
||||
clutter_actor_get_sizeu
|
||||
clutter_actor_set_scale_fullu
|
||||
clutter_actor_get_scale_centeru
|
||||
clutter_actor_set_anchor_pointu
|
||||
clutter_actor_get_anchor_pointu
|
||||
clutter_actor_move_anchor_pointu
|
||||
@ -438,12 +447,6 @@ clutter_actor_move_byu
|
||||
clutter_actor_get_transformed_positionu
|
||||
clutter_actor_get_transformed_sizeu
|
||||
|
||||
<SUBSECTION>
|
||||
clutter_actor_set_scalex
|
||||
clutter_actor_get_scalex
|
||||
clutter_actor_set_rotationx
|
||||
clutter_actor_get_rotationx
|
||||
|
||||
<SUBSECTION>
|
||||
clutter_actor_grab_key_focus
|
||||
clutter_actor_get_pango_context
|
||||
|
@ -25,6 +25,7 @@ test_conformance_SOURCES = \
|
||||
test-binding-pool.c \
|
||||
test-clutter-text.c \
|
||||
test-text-cache.c \
|
||||
test-anchors.c \
|
||||
$(NULL)
|
||||
|
||||
# For convenience, this provides a way to easily run individual unit tests:
|
||||
|
698
tests/conform/test-anchors.c
Normal file
698
tests/conform/test-anchors.c
Normal file
@ -0,0 +1,698 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
#define NOTIFY_ANCHOR_X (1 << 0)
|
||||
#define NOTIFY_ANCHOR_Y (1 << 1)
|
||||
#define NOTIFY_ANCHOR_GRAVITY (1 << 2)
|
||||
#define NOTIFY_SCALE_X (1 << 3)
|
||||
#define NOTIFY_SCALE_Y (1 << 4)
|
||||
#define NOTIFY_SCALE_CENTER_X (1 << 5)
|
||||
#define NOTIFY_SCALE_CENTER_Y (1 << 6)
|
||||
#define NOTIFY_SCALE_GRAVITY (1 << 7)
|
||||
#define NOTIFY_ROTATION_ANGLE_X (1 << 8)
|
||||
#define NOTIFY_ROTATION_ANGLE_Y (1 << 9)
|
||||
#define NOTIFY_ROTATION_ANGLE_Z (1 << 10)
|
||||
#define NOTIFY_ROTATION_CENTER_X (1 << 11)
|
||||
#define NOTIFY_ROTATION_CENTER_Y (1 << 12)
|
||||
#define NOTIFY_ROTATION_CENTER_Z (1 << 13)
|
||||
#define NOTIFY_ROTATION_CENTER_Z_GRAVITY (1 << 14)
|
||||
|
||||
#define RECT_WIDTH 100
|
||||
#define RECT_HEIGHT 80
|
||||
|
||||
/* Allow the transformed position by off by a certain number of
|
||||
pixels */
|
||||
#define POSITION_TOLERANCE 2
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
gulong notifications;
|
||||
ClutterActor *rect;
|
||||
} TestState;
|
||||
|
||||
static const struct
|
||||
{
|
||||
ClutterGravity gravity;
|
||||
gint x_pos, y_pos;
|
||||
} gravities[] =
|
||||
{
|
||||
{ CLUTTER_GRAVITY_NORTH, RECT_WIDTH / 2, 0 },
|
||||
{ CLUTTER_GRAVITY_NORTH_EAST, RECT_WIDTH, 0 },
|
||||
{ CLUTTER_GRAVITY_EAST, RECT_WIDTH, RECT_HEIGHT / 2 },
|
||||
{ CLUTTER_GRAVITY_SOUTH_EAST, RECT_WIDTH, RECT_HEIGHT },
|
||||
{ CLUTTER_GRAVITY_SOUTH, RECT_WIDTH / 2, RECT_HEIGHT },
|
||||
{ CLUTTER_GRAVITY_SOUTH_WEST, 0, RECT_HEIGHT },
|
||||
{ CLUTTER_GRAVITY_WEST, 0, RECT_HEIGHT / 2 },
|
||||
{ CLUTTER_GRAVITY_NORTH_WEST, 0, 0 },
|
||||
{ CLUTTER_GRAVITY_CENTER, RECT_WIDTH / 2, RECT_HEIGHT / 2 }
|
||||
};
|
||||
|
||||
static const char * const
|
||||
properties[] =
|
||||
{ "anchor-x",
|
||||
"anchor-y",
|
||||
"anchor-gravity",
|
||||
"scale-x",
|
||||
"scale-y",
|
||||
"scale-center-x",
|
||||
"scale-center-y",
|
||||
"scale-gravity",
|
||||
"rotation-angle-x",
|
||||
"rotation-angle-y",
|
||||
"rotation-angle-z",
|
||||
"rotation-center-x",
|
||||
"rotation-center-y",
|
||||
"rotation-center-z",
|
||||
"rotation-center-z-gravity" };
|
||||
|
||||
static void
|
||||
notify_cb (GObject *object, GParamSpec *pspec, TestState *state)
|
||||
{
|
||||
int i;
|
||||
int new_flags = 0;
|
||||
int flag = 1;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (properties); i++)
|
||||
{
|
||||
if (!strcmp (properties[i], pspec->name))
|
||||
new_flags |= flag;
|
||||
flag <<= 1;
|
||||
}
|
||||
|
||||
g_assert ((new_flags & state->notifications) == 0);
|
||||
|
||||
state->notifications |= new_flags;
|
||||
}
|
||||
|
||||
#define assert_notifications(flags) \
|
||||
do \
|
||||
{ \
|
||||
g_assert (state->notifications == (flags)); \
|
||||
state->notifications = 0; \
|
||||
} while (0)
|
||||
|
||||
/* Helper macro to assert the transformed position. This needs to be a
|
||||
macro so that the assertion failure will report the right line
|
||||
number */
|
||||
#define assert_coords(state, x_1, y_1, x_2, y_2) \
|
||||
do \
|
||||
{ \
|
||||
ClutterVertex verts[4]; \
|
||||
clutter_actor_get_abs_allocation_vertices ((state)->rect, verts); \
|
||||
check_coords ((state), (x_1), (y_1), (x_2), (y_2), verts); \
|
||||
g_assert (approx_equal ((x_1), \
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[0].x))); \
|
||||
g_assert (approx_equal ((y_1), \
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[0].y))); \
|
||||
g_assert (approx_equal ((x_2), \
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[3].x))); \
|
||||
g_assert (approx_equal ((y_2), \
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[3].y))); \
|
||||
} while (0)
|
||||
|
||||
#define assert_position(state, x, y) \
|
||||
assert_coords((state), (x), (y), (x) + RECT_WIDTH, (y) + RECT_HEIGHT)
|
||||
|
||||
#define assert_vertex_and_free(v, xc, yc, zc) \
|
||||
do \
|
||||
{ \
|
||||
g_assert (approx_equal (CLUTTER_UNITS_TO_DEVICE (v->x), xc) \
|
||||
&& approx_equal (CLUTTER_UNITS_TO_DEVICE (v->y), yc) \
|
||||
&& approx_equal (CLUTTER_UNITS_TO_DEVICE (v->z), zc)); \
|
||||
g_boxed_free (CLUTTER_TYPE_VERTEX, v); \
|
||||
} while (0)
|
||||
|
||||
static inline gboolean
|
||||
approx_equal (int a, int b)
|
||||
{
|
||||
return abs (a - b) <= POSITION_TOLERANCE;
|
||||
}
|
||||
|
||||
static void
|
||||
check_coords (TestState *state,
|
||||
gint x_1, gint y_1, gint x_2, gint y_2,
|
||||
const ClutterVertex *verts)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking that (%i,%i,%i,%i) \xe2\x89\x88 (%i,%i,%i,%i): %s\n",
|
||||
x_1, y_1, x_2, y_2,
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[0].x),
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[0].y),
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[3].x),
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[3].y),
|
||||
approx_equal (x_1, CLUTTER_UNITS_TO_DEVICE (verts[0].x))
|
||||
&& approx_equal (y_1, CLUTTER_UNITS_TO_DEVICE (verts[0].y))
|
||||
&& approx_equal (x_2, CLUTTER_UNITS_TO_DEVICE (verts[3].x))
|
||||
&& approx_equal (y_2, CLUTTER_UNITS_TO_DEVICE (verts[3].y))
|
||||
? "yes" : "NO");
|
||||
}
|
||||
|
||||
static void
|
||||
test_anchor_point (TestState *state)
|
||||
{
|
||||
ClutterActor *rect = state->rect;
|
||||
gint anchor_x, anchor_y;
|
||||
ClutterGravity anchor_gravity;
|
||||
int i;
|
||||
|
||||
/* Assert the default settings */
|
||||
g_assert (clutter_actor_get_x (rect) == 100);
|
||||
g_assert (clutter_actor_get_y (rect) == 200);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"anchor-x", &anchor_x, "anchor-y", &anchor_y,
|
||||
"anchor-gravity", &anchor_gravity,
|
||||
NULL);
|
||||
g_assert (anchor_x == 0);
|
||||
g_assert (anchor_y == 0);
|
||||
g_assert (anchor_gravity == CLUTTER_GRAVITY_NONE);
|
||||
|
||||
/* Change the anchor point */
|
||||
clutter_actor_set_anchor_point (rect, 20, 30);
|
||||
g_object_get (rect,
|
||||
"anchor-x", &anchor_x, "anchor-y", &anchor_y,
|
||||
"anchor-gravity", &anchor_gravity,
|
||||
NULL);
|
||||
g_assert (anchor_x == 20);
|
||||
g_assert (anchor_y == 30);
|
||||
g_assert (anchor_gravity == CLUTTER_GRAVITY_NONE);
|
||||
assert_position (state, 80, 170);
|
||||
assert_notifications (NOTIFY_ANCHOR_X | NOTIFY_ANCHOR_Y);
|
||||
|
||||
/* Move the anchor point */
|
||||
clutter_actor_move_anchor_point (rect, 40, 50);
|
||||
g_object_get (rect,
|
||||
"anchor-x", &anchor_x, "anchor-y", &anchor_y,
|
||||
"anchor-gravity", &anchor_gravity,
|
||||
NULL);
|
||||
g_assert (anchor_x == 40);
|
||||
g_assert (anchor_y == 50);
|
||||
g_assert (anchor_gravity == CLUTTER_GRAVITY_NONE);
|
||||
assert_position (state, 80, 170);
|
||||
assert_notifications (NOTIFY_ANCHOR_X | NOTIFY_ANCHOR_Y);
|
||||
|
||||
/* Put the actor back to its default position */
|
||||
clutter_actor_set_position (rect, 100, 200);
|
||||
|
||||
/* Change the anchor point with each of the gravities */
|
||||
for (i = 0; i < G_N_ELEMENTS (gravities); i++)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
GEnumClass *gravity_class = g_type_class_ref (CLUTTER_TYPE_GRAVITY);
|
||||
GEnumValue *value = g_enum_get_value (gravity_class,
|
||||
gravities[i].gravity);
|
||||
g_print ("Setting gravity to %s\n",
|
||||
value ? value->value_name : "?");
|
||||
g_type_class_unref (gravity_class);
|
||||
}
|
||||
|
||||
g_object_set (rect, "anchor-gravity", gravities[i].gravity, NULL);
|
||||
|
||||
g_object_get (rect,
|
||||
"anchor-x", &anchor_x, "anchor-y", &anchor_y,
|
||||
"anchor-gravity", &anchor_gravity,
|
||||
NULL);
|
||||
g_assert (anchor_x == gravities[i].x_pos);
|
||||
g_assert (anchor_y == gravities[i].y_pos);
|
||||
g_assert (anchor_gravity == gravities[i].gravity);
|
||||
assert_position (state,
|
||||
100 - gravities[i].x_pos,
|
||||
200 - gravities[i].y_pos);
|
||||
|
||||
assert_notifications (NOTIFY_ANCHOR_X | NOTIFY_ANCHOR_Y
|
||||
| NOTIFY_ANCHOR_GRAVITY);
|
||||
}
|
||||
|
||||
/* Verify that the anchor point moves if the actor changes size when
|
||||
it is set from the gravity */
|
||||
clutter_actor_set_size (rect, RECT_WIDTH * 2, RECT_HEIGHT * 2);
|
||||
g_object_get (rect,
|
||||
"anchor-x", &anchor_x, "anchor-y", &anchor_y,
|
||||
"anchor-gravity", &anchor_gravity,
|
||||
NULL);
|
||||
g_assert (anchor_x == RECT_WIDTH);
|
||||
g_assert (anchor_y == RECT_HEIGHT);
|
||||
g_assert (anchor_gravity == CLUTTER_GRAVITY_CENTER);
|
||||
assert_coords (state, 100 - RECT_WIDTH, 200 - RECT_HEIGHT,
|
||||
100 + RECT_WIDTH, 200 + RECT_HEIGHT);
|
||||
assert_notifications (0);
|
||||
clutter_actor_set_size (rect, RECT_WIDTH, RECT_HEIGHT);
|
||||
|
||||
/* Change the anchor point using units again to assert that the
|
||||
gravity property changes */
|
||||
clutter_actor_set_anchor_point (rect, 20, 30);
|
||||
g_object_get (rect,
|
||||
"anchor-x", &anchor_x, "anchor-y", &anchor_y,
|
||||
"anchor-gravity", &anchor_gravity,
|
||||
NULL);
|
||||
g_assert (anchor_x == 20);
|
||||
g_assert (anchor_y == 30);
|
||||
g_assert (anchor_gravity == CLUTTER_GRAVITY_NONE);
|
||||
assert_position (state, 80, 170);
|
||||
assert_notifications (NOTIFY_ANCHOR_X | NOTIFY_ANCHOR_Y
|
||||
| NOTIFY_ANCHOR_GRAVITY);
|
||||
|
||||
/* Verify that the anchor point doesn't move if the actor changes
|
||||
size when it is set from units */
|
||||
clutter_actor_set_size (rect, RECT_WIDTH * 2, RECT_HEIGHT * 2);
|
||||
g_object_get (rect,
|
||||
"anchor-x", &anchor_x, "anchor-y", &anchor_y,
|
||||
"anchor-gravity", &anchor_gravity,
|
||||
NULL);
|
||||
g_assert (anchor_x == 20);
|
||||
g_assert (anchor_y == 30);
|
||||
g_assert (anchor_gravity == CLUTTER_GRAVITY_NONE);
|
||||
assert_coords (state, 80, 170, 80 + RECT_WIDTH * 2, 170 + RECT_HEIGHT * 2);
|
||||
assert_notifications (0);
|
||||
clutter_actor_set_size (rect, RECT_WIDTH, RECT_HEIGHT);
|
||||
|
||||
/* Put the anchor back */
|
||||
clutter_actor_set_anchor_point_from_gravity (rect, CLUTTER_GRAVITY_NONE);
|
||||
assert_notifications (NOTIFY_ANCHOR_X | NOTIFY_ANCHOR_Y);
|
||||
}
|
||||
|
||||
static void
|
||||
test_scale_center (TestState *state)
|
||||
{
|
||||
ClutterActor *rect = state->rect;
|
||||
gdouble scale_x, scale_y;
|
||||
gint center_x, center_y;
|
||||
ClutterGravity gravity;
|
||||
int i;
|
||||
|
||||
/* Assert the default settings */
|
||||
g_assert (clutter_actor_get_x (rect) == 100);
|
||||
g_assert (clutter_actor_get_y (rect) == 200);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"scale-center-x", ¢er_x, "scale-center-y", ¢er_y,
|
||||
"scale-x", &scale_x, "scale-y", &scale_y,
|
||||
"scale-gravity", &gravity,
|
||||
NULL);
|
||||
g_assert (center_x == 0);
|
||||
g_assert (center_y == 0);
|
||||
g_assert (scale_x == 1.0);
|
||||
g_assert (scale_y == 1.0);
|
||||
g_assert (gravity == CLUTTER_GRAVITY_NONE);
|
||||
|
||||
/* Try changing the scale without affecting the center */
|
||||
g_object_set (rect, "scale-x", 2.0, "scale-y", 3.0, NULL);
|
||||
g_assert (clutter_actor_get_x (rect) == 100);
|
||||
g_assert (clutter_actor_get_y (rect) == 200);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"scale-center-x", ¢er_x, "scale-center-y", ¢er_y,
|
||||
"scale-x", &scale_x, "scale-y", &scale_y,
|
||||
"scale-gravity", &gravity,
|
||||
NULL);
|
||||
g_assert (center_x == 0);
|
||||
g_assert (center_y == 0);
|
||||
g_assert (scale_x == 2.0);
|
||||
g_assert (scale_y == 3.0);
|
||||
g_assert (gravity == CLUTTER_GRAVITY_NONE);
|
||||
assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y);
|
||||
assert_coords (state, 100, 200, 100 + RECT_WIDTH * 2, 200 + RECT_HEIGHT * 3);
|
||||
|
||||
/* Change the scale and center */
|
||||
g_object_set (rect, "scale-x", 4.0, "scale-y", 2.0,
|
||||
"scale-center-x", 10, "scale-center-y", 20, NULL);
|
||||
g_assert (clutter_actor_get_x (rect) == 100);
|
||||
g_assert (clutter_actor_get_y (rect) == 200);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"scale-center-x", ¢er_x, "scale-center-y", ¢er_y,
|
||||
"scale-x", &scale_x, "scale-y", &scale_y,
|
||||
"scale-gravity", &gravity,
|
||||
NULL);
|
||||
g_assert (center_x == 10);
|
||||
g_assert (center_y == 20);
|
||||
g_assert (scale_x == 4.0);
|
||||
g_assert (scale_y == 2.0);
|
||||
g_assert (gravity == CLUTTER_GRAVITY_NONE);
|
||||
assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y
|
||||
| NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y);
|
||||
assert_coords (state, 100 + 10 - 10 * 4, 200 + 20 - 20 * 2,
|
||||
100 + 10 + (RECT_WIDTH - 10) * 4,
|
||||
200 + 20 + (RECT_HEIGHT - 20) * 2);
|
||||
|
||||
/* Change the anchor point with each of the gravities */
|
||||
for (i = 0; i < G_N_ELEMENTS (gravities); i++)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
GEnumClass *gravity_class = g_type_class_ref (CLUTTER_TYPE_GRAVITY);
|
||||
GEnumValue *value = g_enum_get_value (gravity_class,
|
||||
gravities[i].gravity);
|
||||
g_print ("Setting scale center to %s\n",
|
||||
value ? value->value_name : "?");
|
||||
g_type_class_unref (gravity_class);
|
||||
}
|
||||
|
||||
g_object_set (rect, "scale-gravity", gravities[i].gravity, NULL);
|
||||
|
||||
g_assert (clutter_actor_get_x (rect) == 100);
|
||||
g_assert (clutter_actor_get_y (rect) == 200);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"scale-center-x", ¢er_x, "scale-center-y", ¢er_y,
|
||||
"scale-x", &scale_x, "scale-y", &scale_y,
|
||||
"scale-gravity", &gravity,
|
||||
NULL);
|
||||
g_assert (center_x == gravities[i].x_pos);
|
||||
g_assert (center_y == gravities[i].y_pos);
|
||||
g_assert (scale_x == 4.0);
|
||||
g_assert (scale_y == 2.0);
|
||||
g_assert (gravity == gravities[i].gravity);
|
||||
assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y
|
||||
| NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y
|
||||
| NOTIFY_SCALE_GRAVITY);
|
||||
assert_coords (state,
|
||||
100 - gravities[i].x_pos * 3,
|
||||
200 - gravities[i].y_pos,
|
||||
100 + (gravities[i].x_pos
|
||||
+ (RECT_WIDTH - gravities[i].x_pos) * 4),
|
||||
200 + (gravities[i].y_pos
|
||||
+ (RECT_HEIGHT - gravities[i].y_pos) * 2));
|
||||
}
|
||||
|
||||
/* Change the scale center using units again to assert that the
|
||||
gravity property changes */
|
||||
clutter_actor_set_scale_full (rect, 4, 2, 10, 20);
|
||||
g_object_get (rect,
|
||||
"scale-center-x", ¢er_x, "scale-center-y", ¢er_y,
|
||||
"scale-x", &scale_x, "scale-y", &scale_y,
|
||||
"scale-gravity", &gravity,
|
||||
NULL);
|
||||
g_assert (center_x == 10);
|
||||
g_assert (center_y == 20);
|
||||
g_assert (scale_x == 4.0);
|
||||
g_assert (scale_y == 2.0);
|
||||
g_assert (gravity == CLUTTER_GRAVITY_NONE);
|
||||
assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y
|
||||
| NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y
|
||||
| NOTIFY_SCALE_GRAVITY);
|
||||
assert_coords (state, 100 + 10 - 10 * 4, 200 + 20 - 20 * 2,
|
||||
100 + 10 + (RECT_WIDTH - 10) * 4,
|
||||
200 + 20 + (RECT_HEIGHT - 20) * 2);
|
||||
|
||||
/* Put the scale back to normal */
|
||||
clutter_actor_set_scale_full (rect, 1, 1, 0, 0);
|
||||
assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y
|
||||
| NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rotate_center (TestState *state)
|
||||
{
|
||||
ClutterActor *rect = state->rect;
|
||||
gdouble angle_x, angle_y, angle_z;
|
||||
ClutterVertex *center_x, *center_y, *center_z;
|
||||
ClutterGravity z_center_gravity;
|
||||
guint stage_width, stage_height;
|
||||
gint rect_x, rect_y;
|
||||
int i;
|
||||
|
||||
/* Position the rectangle at the center of the stage so that
|
||||
rotations by 90° along the X or Y axis will cause the actor to be
|
||||
appear as a flat line. This makes verifying the transformations
|
||||
easier */
|
||||
clutter_actor_get_size (clutter_actor_get_stage (rect),
|
||||
&stage_width, &stage_height);
|
||||
rect_x = stage_width / 2;
|
||||
rect_y = stage_height / 2;
|
||||
clutter_actor_set_position (rect, rect_x, rect_y);
|
||||
|
||||
/* Assert the default settings */
|
||||
g_assert (clutter_actor_get_x (rect) == rect_x);
|
||||
g_assert (clutter_actor_get_y (rect) == rect_y);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"rotation-angle-x", &angle_x,
|
||||
"rotation-angle-y", &angle_y,
|
||||
"rotation-angle-z", &angle_z,
|
||||
"rotation-center-x", ¢er_x,
|
||||
"rotation-center-y", ¢er_y,
|
||||
"rotation-center-z", ¢er_z,
|
||||
"rotation-center-z-gravity", &z_center_gravity,
|
||||
NULL);
|
||||
g_assert (angle_x == 0.0);
|
||||
g_assert (angle_y == 0.0);
|
||||
g_assert (angle_z == 0.0);
|
||||
assert_vertex_and_free (center_x, 0, 0, 0);
|
||||
assert_vertex_and_free (center_y, 0, 0, 0);
|
||||
assert_vertex_and_free (center_z, 0, 0, 0);
|
||||
g_assert (z_center_gravity == CLUTTER_GRAVITY_NONE);
|
||||
|
||||
/* Change each of the rotation angles without affecting the center
|
||||
point */
|
||||
for (i = CLUTTER_X_AXIS; i <= CLUTTER_Z_AXIS; i++)
|
||||
{
|
||||
char prop_name[] = "rotation-angle- ";
|
||||
prop_name[sizeof (prop_name) - 2] = i - CLUTTER_X_AXIS + 'x';
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Setting %s to 90 degrees\n", prop_name);
|
||||
|
||||
g_object_set (rect, prop_name, 90.0, NULL);
|
||||
assert_notifications (NOTIFY_ROTATION_ANGLE_X << (i - CLUTTER_X_AXIS));
|
||||
|
||||
g_assert (clutter_actor_get_x (rect) == rect_x);
|
||||
g_assert (clutter_actor_get_y (rect) == rect_y);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"rotation-angle-x", &angle_x,
|
||||
"rotation-angle-y", &angle_y,
|
||||
"rotation-angle-z", &angle_z,
|
||||
"rotation-center-x", ¢er_x,
|
||||
"rotation-center-y", ¢er_y,
|
||||
"rotation-center-z", ¢er_z,
|
||||
"rotation-center-z-gravity", &z_center_gravity,
|
||||
NULL);
|
||||
if (i == CLUTTER_X_AXIS)
|
||||
{
|
||||
g_assert (angle_x == 90.0);
|
||||
assert_coords (state, rect_x, rect_y,
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[3].x), rect_y);
|
||||
}
|
||||
else
|
||||
g_assert (angle_x == 0.0);
|
||||
if (i == CLUTTER_Y_AXIS)
|
||||
{
|
||||
g_assert (angle_y == 90.0);
|
||||
assert_coords (state, rect_x, rect_y,
|
||||
rect_x, CLUTTER_UNITS_TO_DEVICE (verts[3].y));
|
||||
}
|
||||
else
|
||||
g_assert (angle_y == 0.0);
|
||||
if (i == CLUTTER_Z_AXIS)
|
||||
{
|
||||
g_assert (angle_z == 90.0);
|
||||
assert_coords (state, rect_x, rect_y,
|
||||
rect_x - RECT_HEIGHT, rect_y + RECT_WIDTH);
|
||||
}
|
||||
else
|
||||
g_assert (angle_z == 0.0);
|
||||
assert_vertex_and_free (center_x, 0, 0, 0);
|
||||
assert_vertex_and_free (center_y, 0, 0, 0);
|
||||
assert_vertex_and_free (center_z, 0, 0, 0);
|
||||
g_assert (z_center_gravity == CLUTTER_GRAVITY_NONE);
|
||||
|
||||
g_object_set (rect, prop_name, 0.0, NULL);
|
||||
assert_notifications (NOTIFY_ROTATION_ANGLE_X << (i - CLUTTER_X_AXIS));
|
||||
}
|
||||
|
||||
clutter_actor_set_position (rect, rect_x -= 10, rect_y -= 20);
|
||||
|
||||
/* Same test but also change the center position */
|
||||
for (i = CLUTTER_X_AXIS; i <= CLUTTER_Z_AXIS; i++)
|
||||
{
|
||||
char prop_name[] = "rotation-angle- ";
|
||||
prop_name[sizeof (prop_name) - 2] = i - CLUTTER_X_AXIS + 'x';
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Setting %s to 90 degrees with center 10,20,0\n", prop_name);
|
||||
|
||||
clutter_actor_set_rotation (rect, i, 90.0, 10, 20, 0);
|
||||
assert_notifications ((NOTIFY_ROTATION_ANGLE_X << (i - CLUTTER_X_AXIS))
|
||||
| (NOTIFY_ROTATION_CENTER_X
|
||||
<< (i - CLUTTER_X_AXIS)));
|
||||
|
||||
g_assert (clutter_actor_get_x (rect) == rect_x);
|
||||
g_assert (clutter_actor_get_y (rect) == rect_y);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"rotation-angle-x", &angle_x,
|
||||
"rotation-angle-y", &angle_y,
|
||||
"rotation-angle-z", &angle_z,
|
||||
"rotation-center-x", ¢er_x,
|
||||
"rotation-center-y", ¢er_y,
|
||||
"rotation-center-z", ¢er_z,
|
||||
"rotation-center-z-gravity", &z_center_gravity,
|
||||
NULL);
|
||||
if (i == CLUTTER_X_AXIS)
|
||||
{
|
||||
g_assert (angle_x == 90.0);
|
||||
assert_coords (state,
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[0].x), rect_y + 20,
|
||||
CLUTTER_UNITS_TO_DEVICE (verts[3].x), rect_y + 20);
|
||||
assert_vertex_and_free (center_x, 10, 20, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (angle_x == 0.0);
|
||||
assert_vertex_and_free (center_x, 0, 0, 0);
|
||||
}
|
||||
if (i == CLUTTER_Y_AXIS)
|
||||
{
|
||||
g_assert (angle_y == 90.0);
|
||||
assert_coords (state,
|
||||
rect_x + 10, CLUTTER_UNITS_TO_DEVICE (verts[0].y),
|
||||
rect_x + 10, CLUTTER_UNITS_TO_DEVICE (verts[3].y));
|
||||
assert_vertex_and_free (center_y, 10, 20, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (angle_y == 0.0);
|
||||
assert_vertex_and_free (center_y, 0, 0, 0);
|
||||
}
|
||||
if (i == CLUTTER_Z_AXIS)
|
||||
{
|
||||
g_assert (angle_z == 90.0);
|
||||
assert_coords (state,
|
||||
rect_x + 10 + 20,
|
||||
rect_y + 20 - 10,
|
||||
rect_x + 10 + 20 - RECT_HEIGHT,
|
||||
rect_y + 20 + RECT_WIDTH - 10);
|
||||
assert_vertex_and_free (center_z, 10, 20, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (angle_z == 0.0);
|
||||
assert_vertex_and_free (center_z, 0, 0, 0);
|
||||
}
|
||||
g_assert (z_center_gravity == CLUTTER_GRAVITY_NONE);
|
||||
|
||||
clutter_actor_set_rotation (rect, i, 0, 0, 0, 0);
|
||||
assert_notifications ((NOTIFY_ROTATION_ANGLE_X << (i - CLUTTER_X_AXIS))
|
||||
| (NOTIFY_ROTATION_CENTER_X
|
||||
<< (i - CLUTTER_X_AXIS)));
|
||||
|
||||
}
|
||||
|
||||
/* Try rotating the z with all of the gravities */
|
||||
for (i = 0; i < G_N_ELEMENTS (gravities); i++)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
GEnumClass *gravity_class = g_type_class_ref (CLUTTER_TYPE_GRAVITY);
|
||||
GEnumValue *value = g_enum_get_value (gravity_class,
|
||||
gravities[i].gravity);
|
||||
g_print ("Setting z rotation to 90 degrees with center at %s\n",
|
||||
value ? value->value_name : "?");
|
||||
g_type_class_unref (gravity_class);
|
||||
}
|
||||
|
||||
clutter_actor_set_z_rotation_from_gravity (rect, 90,
|
||||
gravities[i].gravity);
|
||||
assert_notifications (NOTIFY_ROTATION_ANGLE_Z
|
||||
| NOTIFY_ROTATION_CENTER_Z
|
||||
| NOTIFY_ROTATION_CENTER_Z_GRAVITY);
|
||||
|
||||
g_assert (clutter_actor_get_x (rect) == rect_x);
|
||||
g_assert (clutter_actor_get_y (rect) == rect_y);
|
||||
g_assert (clutter_actor_get_width (rect) == RECT_WIDTH);
|
||||
g_assert (clutter_actor_get_height (rect) == RECT_HEIGHT);
|
||||
g_object_get (rect,
|
||||
"rotation-angle-x", &angle_x,
|
||||
"rotation-angle-y", &angle_y,
|
||||
"rotation-angle-z", &angle_z,
|
||||
"rotation-center-x", ¢er_x,
|
||||
"rotation-center-y", ¢er_y,
|
||||
"rotation-center-z", ¢er_z,
|
||||
"rotation-center-z-gravity", &z_center_gravity,
|
||||
NULL);
|
||||
g_assert (angle_x == 0.0);
|
||||
g_assert (angle_y == 0.0);
|
||||
g_assert (angle_z == 90.0);
|
||||
assert_vertex_and_free (center_x, 0, 0, 0);
|
||||
assert_vertex_and_free (center_y, 0, 0, 0);
|
||||
assert_vertex_and_free (center_z,
|
||||
gravities[i].x_pos, gravities[i].y_pos, 0);
|
||||
assert_coords (state,
|
||||
rect_x + gravities[i].x_pos + gravities[i].y_pos,
|
||||
rect_y + gravities[i].y_pos - gravities[i].x_pos,
|
||||
rect_x + gravities[i].x_pos + gravities[i].y_pos
|
||||
- RECT_HEIGHT,
|
||||
rect_y + gravities[i].y_pos + RECT_WIDTH
|
||||
- gravities[i].x_pos);
|
||||
g_assert (z_center_gravity == gravities[i].gravity);
|
||||
g_assert (clutter_actor_get_z_rotation_gravity (rect)
|
||||
== gravities[i].gravity);
|
||||
|
||||
/* Put the rotation back */
|
||||
clutter_actor_set_z_rotation_from_gravity (rect, 0, CLUTTER_GRAVITY_NONE);
|
||||
assert_notifications (NOTIFY_ROTATION_ANGLE_Z
|
||||
| NOTIFY_ROTATION_CENTER_Z
|
||||
| NOTIFY_ROTATION_CENTER_Z_GRAVITY);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_cb (gpointer data)
|
||||
{
|
||||
test_anchor_point (data);
|
||||
test_scale_center (data);
|
||||
test_rotate_center (data);
|
||||
|
||||
clutter_main_quit ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
test_anchors (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
state.rect = clutter_rectangle_new ();
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), state.rect, NULL);
|
||||
clutter_actor_set_position (state.rect, 100, 200);
|
||||
clutter_actor_set_size (state.rect, RECT_WIDTH, RECT_HEIGHT);
|
||||
|
||||
/* Record notifications on the actor properties */
|
||||
state.notifications = 0;
|
||||
g_signal_connect (state.rect, "notify",
|
||||
G_CALLBACK (notify_cb), &state);
|
||||
|
||||
/* Run the tests in a low priority idle function so that we can be
|
||||
sure the stage is correctly setup */
|
||||
g_idle_add_full (G_PRIORITY_LOW, idle_cb, &state, NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_idle_remove_by_data (&state);
|
||||
|
||||
clutter_actor_destroy (state.rect);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
||||
|
@ -108,5 +108,7 @@ main (int argc, char **argv)
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/binding-pool", test_binding_pool);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/actor", test_anchors);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user