mirror of
https://github.com/brl/mutter.git
synced 2024-11-30 03:50:47 -05:00
d6d208da7d
With the recent change to internal floating point values, ClutterUnit has become a redundant type, defined to be a float. All integer entry points are being internally converted to floating point values to be passed to the GL pipeline with the least amount of conversion. ClutterUnit is thus exposed as just a "pixel with fractionary bits", and not -- as users might think -- as generic, resolution and device independent units. not that it was the case, but a definitive amount of people was convinced it did provide this "feature", and was flummoxed about the mere existence of this type. So, having ClutterUnit exposed in the public API doubles the entry points and has the following disadvantages: - we have to maintain twice the amount of entry points in ClutterActor - we still do an integer-to-float implicit conversion - we introduce a weird impedance between pixels and "pixels with fractionary bits" - language bindings will have to choose what to bind, and resort to manually overriding the API + *except* for language bindings based on GObject-Introspection, as they cannot do manual overrides, thus will replicate the entire set of entry points For these reason, we should coalesces every Actor entry point for pixels and for ClutterUnit into a single entry point taking a float, like: void clutter_actor_set_x (ClutterActor *self, gfloat x); void clutter_actor_get_size (ClutterActor *self, gfloat *width, gfloat *height); gfloat clutter_actor_get_height (ClutterActor *self); etc. The issues I have identified are: - we'll have a two cases of compiler warnings: - printf() format of the return values from %d to %f - clutter_actor_get_size() taking floats instead of unsigned ints - we'll have a problem with varargs when passing an integer instead of a floating point value, except on 64bit platforms where the size of a float is the same as the size of an int To be clear: the *intent* of the API should not change -- we still use pixels everywhere -- but: - we remove ambiguity in the API with regard to pixels and units - we remove entry points we get to maintain for the whole 1.0 version of the API - we make things simpler to bind for both manual language bindings and automatic (gobject-introspection based) ones - we have the simplest API possible while still exposing the capabilities of the underlying GL implementation
700 lines
26 KiB
C
700 lines
26 KiB
C
#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;
|
|
gfloat stage_width, stage_height;
|
|
gfloat 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_cmpfloat (clutter_actor_get_x (rect), ==, rect_x);
|
|
g_assert_cmpfloat (clutter_actor_get_y (rect), ==, rect_y);
|
|
g_assert_cmpfloat (clutter_actor_get_width (rect), ==, RECT_WIDTH);
|
|
g_assert_cmpfloat (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");
|
|
}
|
|
|