diff options
Diffstat (limited to 'src/tests/clutter/interactive/test-layout.c')
-rw-r--r-- | src/tests/clutter/interactive/test-layout.c | 684 |
1 files changed, 0 insertions, 684 deletions
diff --git a/src/tests/clutter/interactive/test-layout.c b/src/tests/clutter/interactive/test-layout.c deleted file mode 100644 index ce8202cfd..000000000 --- a/src/tests/clutter/interactive/test-layout.c +++ /dev/null @@ -1,684 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include <gmodule.h> -#include <cogl/cogl.h> - -#include <clutter/clutter.h> -#include "test-utils.h" -#include "tests/clutter-test-utils.h" - -/* layout actor, by Lucas Rocha */ - -#define MY_TYPE_THING (my_thing_get_type ()) -#define MY_THING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_THING, MyThing)) -#define MY_IS_THING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_THING)) -#define MY_THING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_THING, MyThingClass)) -#define MY_IS_THING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_THING)) -#define MY_THING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_THING, MyThingClass)) - -typedef struct _MyThing MyThing; -typedef struct _MyThingPrivate MyThingPrivate; -typedef struct _MyThingClass MyThingClass; - -struct _MyThing -{ - ClutterActor parent_instance; - - MyThingPrivate *priv; -}; - -struct _MyThingClass -{ - ClutterActorClass parent_class; -}; - -enum -{ - PROP_0, - - PROP_SPACING, - PROP_PADDING, - PROP_USE_TRANSFORMED_BOX -}; - -struct _MyThingPrivate -{ - gfloat spacing; - gfloat padding; - - guint use_transformed_box : 1; -}; - -GType my_thing_get_type (void); - -int -test_layout_main (int argc, char *argv[]); - -const char * -test_layout_describe (void); - -G_DEFINE_TYPE_WITH_PRIVATE (MyThing, my_thing, CLUTTER_TYPE_ACTOR) - -#define MY_THING_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MY_TYPE_THING, MyThingPrivate)) - -static void -my_thing_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MyThingPrivate *priv = MY_THING (gobject)->priv; - gboolean needs_relayout = TRUE; - - switch (prop_id) - { - case PROP_SPACING: - priv->spacing = g_value_get_float (value); - break; - - case PROP_PADDING: - priv->padding = g_value_get_float (value); - break; - - case PROP_USE_TRANSFORMED_BOX: - priv->use_transformed_box = g_value_get_boolean (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - needs_relayout = FALSE; - break; - } - - /* setting spacing or padding queues a relayout - because they are supposed to change the internal - allocation of children */ - if (needs_relayout) - clutter_actor_queue_relayout (CLUTTER_ACTOR (gobject)); -} - -static void -my_thing_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MyThingPrivate *priv = MY_THING (gobject)->priv; - - switch (prop_id) - { - case PROP_SPACING: - g_value_set_float (value, priv->spacing); - break; - - case PROP_PADDING: - g_value_set_float (value, priv->padding); - break; - - case PROP_USE_TRANSFORMED_BOX: - g_value_set_boolean (value, priv->use_transformed_box); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -my_thing_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterActorIter iter; - ClutterActor *child; - gfloat min_left, min_right; - gfloat natural_left, natural_right; - - min_left = 0; - min_right = 0; - natural_left = 0; - natural_right = 0; - - clutter_actor_iter_init (&iter, self); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat child_x, child_min, child_natural; - - child_x = clutter_actor_get_x (child); - - clutter_actor_get_preferred_size (child, - &child_min, NULL, - &child_natural, NULL); - - if (child == clutter_actor_get_first_child (self)) - { - /* First child */ - min_left = child_x; - natural_left = child_x; - min_right = min_left + child_min; - natural_right = natural_left + child_natural; - } - else - { - /* Union of extents with previous children */ - if (child_x < min_left) - min_left = child_x; - - if (child_x < natural_left) - natural_left = child_x; - - if (child_x + child_min > min_right) - min_right = child_x + child_min; - - if (child_x + child_natural > natural_right) - natural_right = child_x + child_natural; - } - } - - if (min_left < 0) - min_left = 0; - - if (natural_left < 0) - natural_left = 0; - - if (min_right < 0) - min_right = 0; - - if (natural_right < 0) - natural_right = 0; - - g_assert (min_right >= min_left); - g_assert (natural_right >= natural_left); - - if (min_width_p) - *min_width_p = min_right - min_left; - - if (natural_width_p) - *natural_width_p = natural_right - min_left; -} - -static void -my_thing_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterActorIter iter; - ClutterActor *child; - gfloat min_top, min_bottom; - gfloat natural_top, natural_bottom; - - min_top = 0; - min_bottom = 0; - natural_top = 0; - natural_bottom = 0; - - clutter_actor_iter_init (&iter, self); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat child_y, child_min, child_natural; - - child_y = clutter_actor_get_y (child); - - clutter_actor_get_preferred_size (child, - NULL, &child_min, - NULL, &child_natural); - - if (child == clutter_actor_get_first_child (self)) - { - /* First child */ - min_top = child_y; - natural_top = child_y; - min_bottom = min_top + child_min; - natural_bottom = natural_top + child_natural; - } - else - { - /* Union of extents with previous children */ - if (child_y < min_top) - min_top = child_y; - - if (child_y < natural_top) - natural_top = child_y; - - if (child_y + child_min > min_bottom) - min_bottom = child_y + child_min; - - if (child_y + child_natural > natural_bottom) - natural_bottom = child_y + child_natural; - } - } - - if (min_top < 0) - min_top = 0; - - if (natural_top < 0) - natural_top = 0; - - if (min_bottom < 0) - min_bottom = 0; - - if (natural_bottom < 0) - natural_bottom = 0; - - g_assert (min_bottom >= min_top); - g_assert (natural_bottom >= natural_top); - - if (min_height_p) - *min_height_p = min_bottom - min_top; - - if (natural_height_p) - *natural_height_p = natural_bottom - min_top; -} - -static void -my_thing_allocate (ClutterActor *self, - const ClutterActorBox *box) -{ - MyThingPrivate *priv; - gfloat current_x, current_y, max_row_height; - ClutterActorIter iter; - ClutterActor *child; - - clutter_actor_set_allocation (self, box); - - priv = MY_THING (self)->priv; - - current_x = priv->padding; - current_y = priv->padding; - max_row_height = 0; - - /* The allocation logic here is to horizontally place children - * side-by-side and reflow into a new row when we run out of - * space - */ - clutter_actor_iter_init (&iter, self); - while (clutter_actor_iter_next (&iter, &child)) - { - gfloat natural_width, natural_height; - ClutterActorBox child_box; - - clutter_actor_get_preferred_size (child, - NULL, NULL, - &natural_width, - &natural_height); - - /* if it fits in the current row, keep it there; otherwise - * reflow into another row - */ - if (current_x + natural_width > box->x2 - box->x1 - priv->padding) - { - current_x = priv->padding; - current_y += max_row_height + priv->spacing; - max_row_height = 0; - } - - child_box.x1 = current_x; - child_box.y1 = current_y; - child_box.x2 = child_box.x1 + natural_width; - child_box.y2 = child_box.y1 + natural_height; - - clutter_actor_allocate (child, &child_box); - - /* if we take into account the transformation of the children - * then we first check if it's transformed; then we get the - * onscreen coordinates of the two points of the bounding box - * of the actor (origin(x, y) and (origin + size)(x,y)) and - * we update the coordinates and area given to the next child - */ - if (priv->use_transformed_box) - { - if (clutter_actor_is_scaled (child) || - clutter_actor_is_rotated (child)) - { - graphene_point3d_t v1 = { 0, }, v2 = { 0, }; - ClutterActorBox transformed_box = { 0, }; - - v1.x = box->x1; - v1.y = box->y1; - - clutter_actor_apply_transform_to_point (child, &v1, &v2); - transformed_box.x1 = v2.x; - transformed_box.y1 = v2.y; - - /* size */ - v1.x = natural_width; - v1.y = natural_height; - clutter_actor_apply_transform_to_point (child, &v1, &v2); - transformed_box.x2 = v2.x; - transformed_box.y2 = v2.y; - - natural_width = transformed_box.x2 - transformed_box.x1; - natural_height = transformed_box.y2 - transformed_box.y1; - } - } - - /* Record the maximum child height on current row to know - * what's the increment that should be used for the next - * row - */ - if (natural_height > max_row_height) - max_row_height = natural_height; - - current_x += natural_width + priv->spacing; - } -} - -#define MIN_SIZE 24 -#define MAX_SIZE 64 - -static void -my_thing_class_init (MyThingClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - gobject_class->set_property = my_thing_set_property; - gobject_class->get_property = my_thing_get_property; - - actor_class->get_preferred_width = my_thing_get_preferred_width; - actor_class->get_preferred_height = my_thing_get_preferred_height; - actor_class->allocate = my_thing_allocate; - - g_object_class_install_property (gobject_class, - PROP_SPACING, - g_param_spec_float ("spacing", - "Spacing", - "Spacing of the thing", - 0, G_MAXFLOAT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, - PROP_PADDING, - g_param_spec_float ("padding", - "Padding", - "Padding around the thing", - 0, G_MAXFLOAT, - 0, - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, - PROP_USE_TRANSFORMED_BOX, - g_param_spec_boolean ("use-transformed-box", - "Use Transformed Box", - "Use transformed box when allocating", - FALSE, - G_PARAM_READWRITE)); -} - -static void -my_thing_init (MyThing *thing) -{ - thing->priv = MY_THING_GET_PRIVATE (thing); -} - -static ClutterActor * -my_thing_new (gfloat padding, - gfloat spacing) -{ - return g_object_new (MY_TYPE_THING, - "padding", padding, - "spacing", spacing, - NULL); -} - -/* test code */ - -static ClutterActor *box = NULL; -static ClutterActor *icon = NULL; -static ClutterTimeline *main_timeline = NULL; - -static void -toggle_property_value (ClutterActor *actor, - const gchar *property_name) -{ - gboolean value; - - g_object_get (actor, property_name, &value, NULL); - - value = !value; - - g_object_set (box, property_name, value, NULL); -} - -static void -increase_property_value (ClutterActor *actor, - const char *property_name) -{ - gfloat value; - - g_object_get (actor, property_name, &value, NULL); - - value = value + 10.0; - - g_object_set (box, property_name, value, NULL); -} - -static void -decrease_property_value (ClutterActor *actor, - const char *property_name) -{ - gfloat value; - - g_object_get (actor, property_name, &value, NULL); - - value = MAX (0, value - 10.0); - - g_object_set (box, property_name, value, NULL); -} - -static ClutterActor * -create_item (void) -{ - ClutterActor *clone = clutter_clone_new (icon); - - gint32 size = g_random_int_range (MIN_SIZE, MAX_SIZE); - - clutter_actor_set_size (clone, size, size); - clutter_actor_animate_with_timeline (clone, CLUTTER_EASE_OUT_CUBIC, - main_timeline, - "scale-x", 2.0, - "scale-y", 2.0, - "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER, - NULL); - - return clone; -} - -static gboolean -keypress_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - switch (clutter_event_get_key_symbol (event)) - { - case CLUTTER_KEY_q: - clutter_test_quit (); - break; - - case CLUTTER_KEY_a: - { - if (icon != NULL) - { - ClutterActor *clone = create_item (); - - /* Add one item to container */ - clutter_actor_add_child (box, clone); - } - break; - } - - case CLUTTER_KEY_d: - { - ClutterActor *last_child; - - last_child = clutter_actor_get_last_child (box); - if (last_child != NULL) - { - /* Remove last item on container */ - clutter_actor_remove_child (box, last_child); - } - break; - } - - case CLUTTER_KEY_w: - { - decrease_property_value (box, "padding"); - break; - } - - case CLUTTER_KEY_e: - { - increase_property_value (box, "padding"); - break; - } - - case CLUTTER_KEY_r: - { - decrease_property_value (box, "spacing"); - break; - } - - case CLUTTER_KEY_s: - { - toggle_property_value (box, "use-transformed-box"); - break; - } - - case CLUTTER_KEY_t: - { - increase_property_value (box, "spacing"); - break; - } - - case CLUTTER_KEY_z: - { - if (clutter_timeline_is_playing (main_timeline)) - clutter_timeline_pause (main_timeline); - else - clutter_timeline_start (main_timeline); - - break; - } - - default: - break; - } - - return FALSE; -} - -static void -relayout_on_frame (ClutterTimeline *timeline) -{ - gboolean use_transformed_box; - - /* if we care about transformations updating the layout, we need to inform - * the layout that a transformation is happening; this is either done by - * attaching a notification on the transformation properties or by simply - * queuing a relayout on each frame of the timeline used to drive the - * behaviour. for simplicity's sake, we used the latter - */ - - g_object_get (G_OBJECT (box), - "use-transformed-box", &use_transformed_box, - NULL); - - if (use_transformed_box) - clutter_actor_queue_relayout (box); -} - -G_MODULE_EXPORT int -test_layout_main (int argc, char *argv[]) -{ - ClutterActor *stage, *instructions; - gint i, size; - GError *error = NULL; - - clutter_test_init (&argc, &argv); - - stage = clutter_test_get_stage (); - clutter_actor_set_size (stage, 800, 600); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Layout"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL); - - main_timeline = clutter_timeline_new_for_actor (stage, 2000); - clutter_timeline_set_repeat_count (main_timeline, -1); - clutter_timeline_set_auto_reverse (main_timeline, TRUE); - g_signal_connect (main_timeline, "new-frame", - G_CALLBACK (relayout_on_frame), - NULL); - - - box = my_thing_new (10, 10); - - clutter_actor_set_position (box, 20, 20); - clutter_actor_set_size (box, 350, -1); - - icon = clutter_test_utils_create_texture_from_file (TESTS_DATADIR - G_DIR_SEPARATOR_S - "redhand.png", - &error); - if (error) - g_error ("Unable to load 'redhand.png': %s", error->message); - - size = g_random_int_range (MIN_SIZE, MAX_SIZE); - clutter_actor_set_size (icon, size, size); - clutter_actor_add_child (box, icon); - clutter_actor_animate_with_timeline (icon, CLUTTER_EASE_OUT_CUBIC, - main_timeline, - "scale-x", 2.0, - "scale-y", 2.0, - "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER, - NULL); - - for (i = 1; i < 33; i++) - { - ClutterActor *clone = create_item (); - - clutter_actor_add_child (box, clone); - } - - clutter_actor_add_child (stage, box); - - instructions = clutter_text_new_with_text (NULL, - "<b>Instructions:</b>\n" - "a - add a new item\n" - "d - remove last item\n" - "z - start/pause behaviour\n" - "w - decrease padding\n" - "e - increase padding\n" - "r - decrease spacing\n" - "t - increase spacing\n" - "s - use transformed box\n" - "q - quit"); - - clutter_text_set_use_markup (CLUTTER_TEXT (instructions), TRUE); - clutter_actor_set_position (instructions, 450, 10); - clutter_actor_add_child (stage, instructions); - - g_signal_connect (stage, "key-release-event", - G_CALLBACK (keypress_cb), - NULL); - - clutter_timeline_stop (main_timeline); - - clutter_actor_show (stage); - - clutter_test_main (); - - g_object_unref (main_timeline); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_layout_describe (void) -{ - return "Container implementing a layout policy."; -} |