mirror of
https://github.com/brl/mutter.git
synced 2025-06-13 16:59:30 +00:00
Bug 1162 - Re-works the tests/ to use the glib-2.16 unit testing
framework * configure.ac: * tests/*: The tests have been reorganised into different categories: conformance, interactive and micro benchmarks. - conformance tests can be run as part of automated tests - interactive tests are basically all the existing tests - micro benchmarks focus on a single performance metric I converted the timeline tests to conformance tests and also added some tests from Neil Roberts and Ebassi. Note: currently only the conformance tests use the glib test APIs, though the micro benchmarks should too. The other change is to make the unit tests link into monolithic binaries which makes the build time for unit tests considerably faster. To deal with the extra complexity this adds to debugging individual tests I have added some sugar to the makefiles so all the tests can be run directly via a symlink and when an individual test is run this way, then a note is printed to the terminal explaining exactly how that test may be debugged using GDB. There is a convenience make rule: 'make test-report', that will run all the conformance tests and hopefully even open the results in your web browser. It skips some of the slower timeline tests, but you can run those using 'make full-report'
This commit is contained in:
69
tests/interactive/Makefile.am
Normal file
69
tests/interactive/Makefile.am
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
UNIT_TESTS = \
|
||||
test-textures.c \
|
||||
test-events.c \
|
||||
test-offscreen.c \
|
||||
test-scale.c \
|
||||
test-actors.c \
|
||||
test-behave.c \
|
||||
test-entry.c \
|
||||
test-project.c \
|
||||
test-perspective.c \
|
||||
test-rotate.c \
|
||||
test-depth.c \
|
||||
test-threads.c \
|
||||
test-score.c \
|
||||
test-script.c \
|
||||
test-model.c \
|
||||
test-grab.c \
|
||||
test-effects.c \
|
||||
test-fullscreen.c \
|
||||
test-shader.c \
|
||||
test-unproject.c \
|
||||
test-viewport test-fbo.c \
|
||||
test-opacity.c \
|
||||
test-multistage.c \
|
||||
test-cogl-primitives.c \
|
||||
test-cogl-tex-tile.c \
|
||||
test-cogl-tex-convert.c \
|
||||
test-cogl-tex-foreign.c \
|
||||
test-cogl-tex-getset.c \
|
||||
test-cogl-offscreen.c \
|
||||
test-cogl-tex-polygon.c \
|
||||
test-stage-read-pixels.c \
|
||||
test-random-text.c \
|
||||
test-clip.c \
|
||||
test-paint-wrapper.c \
|
||||
test-texture-quality.c \
|
||||
test-entry-auto.c \
|
||||
test-layout.c \
|
||||
test-invariants.c
|
||||
|
||||
#FIXME - this is is a bit of a yukky way of ensuring the tests find our data:
|
||||
test-script.json:
|
||||
ln -sf $(top_srcdir)/tests/data/test-script.json
|
||||
redhand.png:
|
||||
ln -sf $(top_srcdir)/tests/data/redhand.png
|
||||
|
||||
# For convenience, this provides a way to easily run individual unit tests:
|
||||
.PHONY: wrappers
|
||||
wrappers: test-interactive
|
||||
for i in $(UNIT_TESTS); \
|
||||
do \
|
||||
ln -sf $(top_srcdir)/tests/interactive/wrapper.sh $${i%*.c}; \
|
||||
done
|
||||
# NB: BUILT_SOURCES here a misnomer. We aren't building source, just inserting
|
||||
# a phony rule that will generate symlink scripts for running individual tests
|
||||
BUILT_SOURCES = wrappers redhand.png test-script.json
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/ -I$(top_srcdir)/clutter -I$(top_builddir)/clutter
|
||||
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
|
||||
AM_CFLAGS = $(CLUTTER_CFLAGS)
|
||||
AM_LDFLAGS = $(CLUTTER_LIBS)
|
||||
|
||||
noinst_PROGRAMS = test-interactive
|
||||
|
||||
test_interactive_SOURCES = \
|
||||
test-main.c \
|
||||
$(UNIT_TESTS)
|
||||
test_interactive_LDFLAGS = -export-dynamic
|
256
tests/interactive/test-actors.c
Normal file
256
tests/interactive/test-actors.c
Normal file
@ -0,0 +1,256 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#if defined (_MSC_VER) && !defined (_USE_MATH_DEFINES)
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#define TRAILS 0
|
||||
#define NHANDS 6
|
||||
#define RADIUS ((CLUTTER_STAGE_WIDTH()+CLUTTER_STAGE_HEIGHT())/NHANDS)
|
||||
|
||||
typedef struct SuperOH
|
||||
{
|
||||
ClutterActor **hand, *bgtex;
|
||||
ClutterActor *group;
|
||||
|
||||
} SuperOH;
|
||||
|
||||
static gint n_hands = NHANDS;
|
||||
|
||||
static GOptionEntry super_oh_entries[] = {
|
||||
{
|
||||
"num-hands", 'n',
|
||||
0,
|
||||
G_OPTION_ARG_INT, &n_hands,
|
||||
"Number of hands", "HANDS"
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* input handler */
|
||||
static gboolean
|
||||
input_cb (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
SuperOH *oh = data;
|
||||
|
||||
if (event->type == CLUTTER_BUTTON_PRESS)
|
||||
{
|
||||
ClutterButtonEvent *button_event;
|
||||
ClutterActor *e;
|
||||
gint x, y;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
button_event = (ClutterButtonEvent *) event;
|
||||
g_print ("*** button press event (button:%d) ***\n",
|
||||
button_event->button);
|
||||
|
||||
e = clutter_stage_get_actor_at_pos (CLUTTER_STAGE (stage), x, y);
|
||||
|
||||
if (e && (CLUTTER_IS_TEXTURE (e) || CLUTTER_IS_CLONE_TEXTURE (e)))
|
||||
{
|
||||
clutter_actor_hide (e);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (event->type == CLUTTER_KEY_RELEASE)
|
||||
{
|
||||
ClutterKeyEvent *kev = (ClutterKeyEvent *) event;
|
||||
|
||||
g_print ("*** key press event (key:%c) ***\n",
|
||||
clutter_key_event_symbol (kev));
|
||||
|
||||
if (clutter_key_event_symbol (kev) == CLUTTER_q)
|
||||
{
|
||||
clutter_main_quit ();
|
||||
return TRUE;
|
||||
}
|
||||
else if (clutter_key_event_symbol (kev) == CLUTTER_r)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_hands; i++)
|
||||
clutter_actor_show (oh->hand[i]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Timeline handler */
|
||||
static void
|
||||
frame_cb (ClutterTimeline *timeline,
|
||||
gint frame_num,
|
||||
gpointer data)
|
||||
{
|
||||
SuperOH *oh = data;
|
||||
gint i;
|
||||
|
||||
/* Rotate everything clockwise about stage center*/
|
||||
|
||||
clutter_actor_set_rotation (CLUTTER_ACTOR (oh->group),
|
||||
CLUTTER_Z_AXIS,
|
||||
frame_num,
|
||||
CLUTTER_STAGE_WIDTH () / 2,
|
||||
CLUTTER_STAGE_HEIGHT () / 2,
|
||||
0);
|
||||
|
||||
for (i = 0; i < n_hands; i++)
|
||||
{
|
||||
gdouble scale_x, scale_y;
|
||||
|
||||
clutter_actor_get_scale (oh->hand[i], &scale_x, &scale_y);
|
||||
|
||||
/* Rotate each hand around there centers - to get this we need
|
||||
* to take into account any scaling.
|
||||
*
|
||||
* FIXME: scaling causes drift so disabled for now. Need rotation
|
||||
* unit based functions to fix.
|
||||
*/
|
||||
clutter_actor_set_rotation (oh->hand[i], CLUTTER_Z_AXIS,
|
||||
- 6.0 * frame_num, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_actors_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *scaler_1, *scaler_2;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
|
||||
SuperOH *oh;
|
||||
gint i;
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
|
||||
clutter_init_with_args (&argc, &argv,
|
||||
NULL,
|
||||
super_oh_entries,
|
||||
NULL,
|
||||
&error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Unable to initialise Clutter:\n%s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 800, 600);
|
||||
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Actors Test");
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage),
|
||||
&stage_color);
|
||||
|
||||
oh = g_new(SuperOH, 1);
|
||||
|
||||
/* Create a timeline to manage animation */
|
||||
timeline = clutter_timeline_new (360, 60); /* num frames, fps */
|
||||
g_object_set (timeline, "loop", TRUE, NULL); /* have it loop */
|
||||
|
||||
/* fire a callback for frame change */
|
||||
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh);
|
||||
|
||||
/* Set up some behaviours to handle scaling */
|
||||
alpha = clutter_alpha_new_full (timeline, CLUTTER_ALPHA_SINE, NULL, NULL);
|
||||
|
||||
scaler_1 = clutter_behaviour_scale_new (alpha,
|
||||
0.5, 0.5,
|
||||
1.0, 1.0);
|
||||
|
||||
scaler_2 = clutter_behaviour_scale_new (alpha,
|
||||
1.0, 1.0,
|
||||
0.5, 0.5);
|
||||
|
||||
/* create a new group to hold multiple actors in a group */
|
||||
oh->group = clutter_group_new();
|
||||
|
||||
oh->hand = g_new (ClutterActor*, n_hands);
|
||||
for (i = 0; i < n_hands; i++)
|
||||
{
|
||||
gint x, y, w, h;
|
||||
|
||||
/* Create a texture from file, then clone in to same resources */
|
||||
if (i == 0)
|
||||
{
|
||||
if ((oh->hand[i] = clutter_texture_new_from_file ("redhand.png",
|
||||
&error)) == NULL)
|
||||
{
|
||||
g_error ("image load failed: %s", error->message);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
oh->hand[i] = clutter_clone_texture_new (CLUTTER_TEXTURE(oh->hand[0]));
|
||||
|
||||
/* Place around a circle */
|
||||
w = clutter_actor_get_width (oh->hand[0]);
|
||||
h = clutter_actor_get_height (oh->hand[0]);
|
||||
|
||||
x = CLUTTER_STAGE_WIDTH () / 2
|
||||
+ RADIUS
|
||||
* cos (i * M_PI / (n_hands / 2))
|
||||
- w / 2;
|
||||
|
||||
y = CLUTTER_STAGE_HEIGHT () / 2
|
||||
+ RADIUS
|
||||
* sin (i * M_PI / (n_hands / 2))
|
||||
- h / 2;
|
||||
|
||||
clutter_actor_set_position (oh->hand[i], x, y);
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (oh->hand[i],
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
/* Add to our group group */
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (oh->group), oh->hand[i]);
|
||||
|
||||
#if 1 /* FIXME: disabled as causes drift? - see comment above */
|
||||
if (i % 2)
|
||||
clutter_behaviour_apply (scaler_1, oh->hand[i]);
|
||||
else
|
||||
clutter_behaviour_apply (scaler_2, oh->hand[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add the group to the stage */
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage),
|
||||
CLUTTER_ACTOR (oh->group));
|
||||
|
||||
/* Show everying ( and map window ) */
|
||||
clutter_actor_show (stage);
|
||||
|
||||
|
||||
g_signal_connect (stage, "button-press-event",
|
||||
G_CALLBACK (input_cb),
|
||||
oh);
|
||||
g_signal_connect (stage, "key-release-event",
|
||||
G_CALLBACK (input_cb),
|
||||
oh);
|
||||
|
||||
/* and start it */
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_free (oh->hand);
|
||||
g_free (oh);
|
||||
|
||||
return 0;
|
||||
}
|
233
tests/interactive/test-behave.c
Normal file
233
tests/interactive/test-behave.c
Normal file
@ -0,0 +1,233 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static gboolean
|
||||
button_press_cb (ClutterStage *stage,
|
||||
ClutterButtonEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *click_type;
|
||||
|
||||
switch (event->click_count)
|
||||
{
|
||||
case 2:
|
||||
click_type = "double";
|
||||
break;
|
||||
case 3:
|
||||
click_type = "triple";
|
||||
break;
|
||||
default:
|
||||
click_type = "single";
|
||||
break;
|
||||
}
|
||||
|
||||
g_print ("%s button press event\n", click_type);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
scroll_event_cb (ClutterStage *stage,
|
||||
ClutterScrollEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
g_print ("scroll direction: %s\n",
|
||||
event->direction == CLUTTER_SCROLL_UP ? "up"
|
||||
: "down");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
timeline_completed (ClutterTimeline *timeline)
|
||||
{
|
||||
ClutterTimelineDirection direction;
|
||||
|
||||
direction = clutter_timeline_get_direction (timeline);
|
||||
|
||||
if (direction == CLUTTER_TIMELINE_FORWARD)
|
||||
direction = CLUTTER_TIMELINE_BACKWARD;
|
||||
else
|
||||
direction = CLUTTER_TIMELINE_FORWARD;
|
||||
|
||||
clutter_timeline_set_direction (timeline, direction);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
PATH_POLY,
|
||||
PATH_ELLIPSE,
|
||||
PATH_BSPLINE
|
||||
} path_t;
|
||||
|
||||
#define MAGIC 0.551784
|
||||
#define RADIUS 200
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_behave_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *o_behave, *p_behave;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group, *rect, *hand;
|
||||
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||
ClutterColor rect_bg_color = { 0x33, 0x22, 0x22, 0xff };
|
||||
ClutterColor rect_border_color = { 0, 0, 0, 0 };
|
||||
int i;
|
||||
path_t path_type = PATH_POLY;
|
||||
|
||||
ClutterKnot knots_poly[] = {{ 0, 0 }, { 0, 300 }, { 300, 300 },
|
||||
{ 300, 0 }, {0, 0 }};
|
||||
|
||||
ClutterKnot origin = { 200, 200 };
|
||||
|
||||
ClutterKnot knots_bspline[] = {{ -RADIUS, 0 },
|
||||
{ -RADIUS, RADIUS*MAGIC },
|
||||
{ -RADIUS*MAGIC, RADIUS },
|
||||
{ 0, RADIUS },
|
||||
{ RADIUS*MAGIC, RADIUS },
|
||||
{ RADIUS, RADIUS*MAGIC },
|
||||
{ RADIUS, 0 },
|
||||
{ RADIUS, -RADIUS*MAGIC },
|
||||
{ RADIUS*MAGIC, -RADIUS },
|
||||
{ 0, -RADIUS },
|
||||
{ -RADIUS*MAGIC, -RADIUS },
|
||||
{ -RADIUS, -RADIUS*MAGIC },
|
||||
{ -RADIUS, 0}};
|
||||
|
||||
for (i = 0; i < argc; ++i)
|
||||
{
|
||||
if (!strncmp (argv[i], "--path", 6))
|
||||
{
|
||||
if (!strncmp (argv[i] + 7, "poly", 4))
|
||||
path_type = PATH_POLY;
|
||||
else if (!strncmp (argv[i] + 7, "bspline", 7))
|
||||
path_type = PATH_BSPLINE;
|
||||
else if (!strncmp (argv[i] + 7, "ellipse", 7))
|
||||
path_type = PATH_ELLIPSE;
|
||||
}
|
||||
else if (!strncmp (argv[i], "--help", 6))
|
||||
{
|
||||
printf ("behave [--path=poly|ellipse|bspline]\n");
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_hide_cursor (CLUTTER_STAGE (stage));
|
||||
|
||||
g_signal_connect (stage, "button-press-event",
|
||||
G_CALLBACK (button_press_cb),
|
||||
NULL);
|
||||
g_signal_connect (stage, "scroll-event",
|
||||
G_CALLBACK (scroll_event_cb),
|
||||
NULL);
|
||||
g_signal_connect (stage, "key-press-event",
|
||||
G_CALLBACK (clutter_main_quit),
|
||||
NULL);
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage),
|
||||
&stage_color);
|
||||
|
||||
/* Make a hand */
|
||||
group = clutter_group_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
|
||||
clutter_actor_show (group);
|
||||
|
||||
hand = clutter_texture_new_from_file ("redhand.png", NULL);
|
||||
if (hand == NULL)
|
||||
{
|
||||
g_error("pixbuf load failed");
|
||||
return 1;
|
||||
}
|
||||
clutter_actor_set_position (hand, 0, 0);
|
||||
clutter_actor_show (hand);
|
||||
|
||||
rect = clutter_rectangle_new ();
|
||||
clutter_actor_set_position (rect, 0, 0);
|
||||
clutter_actor_set_size (rect,
|
||||
clutter_actor_get_width (hand),
|
||||
clutter_actor_get_height (hand));
|
||||
clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect),
|
||||
&rect_bg_color);
|
||||
clutter_rectangle_set_border_width (CLUTTER_RECTANGLE (rect), 10);
|
||||
clutter_color_parse ("DarkSlateGray", &rect_border_color);
|
||||
clutter_rectangle_set_border_color (CLUTTER_RECTANGLE (rect),
|
||||
&rect_border_color);
|
||||
clutter_actor_show (rect);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), rect, hand, NULL);
|
||||
|
||||
/* Make a timeline */
|
||||
timeline = clutter_timeline_new_for_duration (4000); /* num frames, fps */
|
||||
clutter_timeline_set_loop (timeline, TRUE);
|
||||
g_signal_connect (timeline,
|
||||
"completed", G_CALLBACK (timeline_completed),
|
||||
NULL);
|
||||
|
||||
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
|
||||
alpha = clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL);
|
||||
|
||||
/* Create a behaviour for that alpha */
|
||||
o_behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff);
|
||||
|
||||
/* Apply it to our actor */
|
||||
clutter_behaviour_apply (o_behave, group);
|
||||
|
||||
/* Make a path behaviour and apply that too */
|
||||
switch (path_type)
|
||||
{
|
||||
case PATH_POLY:
|
||||
p_behave = clutter_behaviour_path_new (alpha, knots_poly, 5);
|
||||
break;
|
||||
case PATH_ELLIPSE:
|
||||
p_behave =
|
||||
clutter_behaviour_ellipse_new (alpha, 200, 200, 400, 300,
|
||||
CLUTTER_ROTATE_CW,
|
||||
0.0, 360.0);
|
||||
|
||||
clutter_behaviour_ellipse_set_angle_tilt (CLUTTER_BEHAVIOUR_ELLIPSE (p_behave),
|
||||
CLUTTER_X_AXIS,
|
||||
45.0);
|
||||
clutter_behaviour_ellipse_set_angle_tilt (CLUTTER_BEHAVIOUR_ELLIPSE (p_behave),
|
||||
CLUTTER_Z_AXIS,
|
||||
45.0);
|
||||
break;
|
||||
|
||||
case PATH_BSPLINE:
|
||||
origin.x = 0;
|
||||
origin.y = RADIUS;
|
||||
p_behave =
|
||||
clutter_behaviour_bspline_new (alpha, knots_bspline,
|
||||
sizeof (knots_bspline)/sizeof(ClutterKnot));
|
||||
|
||||
clutter_behaviour_bspline_set_origin (
|
||||
CLUTTER_BEHAVIOUR_BSPLINE (p_behave),
|
||||
&origin);
|
||||
break;
|
||||
}
|
||||
|
||||
clutter_behaviour_apply (p_behave, group);
|
||||
|
||||
/* start the timeline and thus the animations */
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main();
|
||||
|
||||
g_object_unref (o_behave);
|
||||
g_object_unref (p_behave);
|
||||
|
||||
return 0;
|
||||
}
|
128
tests/interactive/test-clip.c
Normal file
128
tests/interactive/test-clip.c
Normal file
@ -0,0 +1,128 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#define TL_SCALE 5.0f
|
||||
|
||||
typedef struct _CallbackData CallbackData;
|
||||
|
||||
struct _CallbackData
|
||||
{
|
||||
ClutterActor *stage, *group, *rect, *hand;
|
||||
};
|
||||
|
||||
static void
|
||||
on_new_frame (ClutterTimeline *tl, int frame_num, CallbackData *data)
|
||||
{
|
||||
int i;
|
||||
int stage_width = clutter_actor_get_width (data->stage);
|
||||
int stage_height = clutter_actor_get_height (data->stage);
|
||||
gdouble progress = clutter_timeline_get_progress (tl);
|
||||
gdouble angle = progress * 2 * M_PI * TL_SCALE;
|
||||
gdouble rotation[3];
|
||||
|
||||
gdouble xpos = stage_width * 0.45 * sin (angle) + stage_width / 8;
|
||||
gdouble ypos = stage_height * 0.45 * sin (angle) + stage_height / 8;
|
||||
gdouble zpos = stage_width * cos (angle) - stage_width / 2;
|
||||
|
||||
clutter_actor_set_position (data->hand, xpos, ypos);
|
||||
clutter_actor_set_depth (data->hand, zpos);
|
||||
clutter_actor_set_rotation (data->hand, CLUTTER_Y_AXIS,
|
||||
angle / M_PI * 180.0 * 3,
|
||||
clutter_actor_get_width (data->hand) / 2,
|
||||
clutter_actor_get_height (data->hand) / 2,
|
||||
0);
|
||||
|
||||
memset (rotation, 0, sizeof (rotation));
|
||||
|
||||
if (progress < 1 / 3.0)
|
||||
rotation[2] = 360 * progress * 3;
|
||||
else if (progress < 2 / 3.0)
|
||||
rotation[1] = 360 * progress * 3;
|
||||
else
|
||||
rotation[0] = 360 * progress * 3;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
clutter_actor_set_rotation (data->group, i,
|
||||
rotation[i],
|
||||
clutter_actor_get_width (data->rect) / 2,
|
||||
clutter_actor_get_height (data->rect) / 2,
|
||||
0);
|
||||
clutter_actor_set_rotation (data->rect, i,
|
||||
rotation[i],
|
||||
clutter_actor_get_width (data->rect) / 2,
|
||||
clutter_actor_get_height (data->rect) / 2,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_clip_main (int argc, char **argv)
|
||||
{
|
||||
ClutterGeometry geom;
|
||||
ClutterTimeline *tl;
|
||||
ClutterColor blue = { 0x40, 0x40, 0xff, 0xff };
|
||||
CallbackData data;
|
||||
ClutterActor *other_hand;
|
||||
int x, y;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
data.stage = clutter_stage_get_default ();
|
||||
|
||||
data.group = clutter_group_new ();
|
||||
|
||||
clutter_actor_get_geometry (data.stage, &geom);
|
||||
geom.x = geom.width / 4;
|
||||
geom.y = geom.height / 4;
|
||||
geom.width /= 2;
|
||||
geom.height /= 2;
|
||||
clutter_actor_set_geometry (data.group, &geom);
|
||||
|
||||
data.rect = clutter_rectangle_new_with_color (&blue);
|
||||
clutter_actor_set_geometry (data.rect, &geom);
|
||||
clutter_container_add (CLUTTER_CONTAINER (data.stage), data.rect, NULL);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (data.stage), data.group, NULL);
|
||||
|
||||
clutter_actor_set_clip (data.group, 0, 0, geom.width, geom.height);
|
||||
|
||||
data.hand = clutter_texture_new_from_file ("redhand.png", NULL);
|
||||
if (data.hand == NULL)
|
||||
{
|
||||
g_critical ("pixbuf loading failed");
|
||||
exit (1);
|
||||
}
|
||||
clutter_container_add (CLUTTER_CONTAINER (data.group), data.hand, NULL);
|
||||
|
||||
/* Add a hand at each of the four corners of the group */
|
||||
for (y = 0; y < 2; y++)
|
||||
for (x = 0; x < 2; x++)
|
||||
{
|
||||
other_hand = clutter_clone_texture_new (CLUTTER_TEXTURE (data.hand));
|
||||
clutter_actor_set_anchor_point_from_gravity
|
||||
(other_hand, CLUTTER_GRAVITY_CENTER);
|
||||
clutter_actor_set_position (other_hand,
|
||||
x * geom.width,
|
||||
y * geom.height);
|
||||
clutter_container_add (CLUTTER_CONTAINER (data.group),
|
||||
other_hand, NULL);
|
||||
}
|
||||
|
||||
clutter_actor_raise_top (data.hand);
|
||||
|
||||
tl = clutter_timeline_new (360 * TL_SCALE, 60);
|
||||
clutter_timeline_start (tl);
|
||||
clutter_timeline_set_loop (tl, TRUE);
|
||||
|
||||
g_signal_connect (tl, "new-frame", G_CALLBACK (on_new_frame), &data);
|
||||
|
||||
clutter_actor_show (data.stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
218
tests/interactive/test-cogl-offscreen.c
Normal file
218
tests/interactive/test-cogl-offscreen.c
Normal file
@ -0,0 +1,218 @@
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
CoglHandle texhand_id;
|
||||
CoglHandle texture_id;
|
||||
CoglHandle offscreen_id;
|
||||
};
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
test_coglbox_paint(ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
CoglColor color;
|
||||
ClutterFixed texcoords[4] = {
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f)
|
||||
};
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
cogl_color_set_from_4ub (&color, 0x66, 0x66, 0xdd, 0xff);
|
||||
cogl_color (&color);
|
||||
cogl_rectangle (0,0,400,400);
|
||||
|
||||
cogl_color_set_from_4ub (&color, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_color (&color);
|
||||
cogl_texture_rectangle (priv->texhand_id,
|
||||
0,0,
|
||||
CLUTTER_INT_TO_FIXED (400),
|
||||
CLUTTER_INT_TO_FIXED (400),
|
||||
0,0,
|
||||
CLUTTER_INT_TO_FIXED (6),
|
||||
CLUTTER_INT_TO_FIXED (6));
|
||||
|
||||
cogl_draw_buffer (COGL_OFFSCREEN_BUFFER, priv->offscreen_id);
|
||||
|
||||
cogl_color_set_from_4ub (&color, 0xff, 0, 0, 0xff);
|
||||
cogl_color (&color);
|
||||
cogl_rectangle (20,20,100,100);
|
||||
|
||||
cogl_color_set_from_4ub (&color, 0, 0xff, 0, 0xff);
|
||||
cogl_color (&color);
|
||||
cogl_rectangle (80,80,100,100);
|
||||
|
||||
cogl_draw_buffer (COGL_WINDOW_BUFFER, 0);
|
||||
|
||||
cogl_color_set_from_4ub (&color, 0xff, 0xff, 0xff, 0x88);
|
||||
cogl_color (&color);
|
||||
cogl_texture_rectangle (priv->texture_id,
|
||||
CLUTTER_INT_TO_FIXED (100),
|
||||
CLUTTER_INT_TO_FIXED (100),
|
||||
CLUTTER_INT_TO_FIXED (300),
|
||||
CLUTTER_INT_TO_FIXED (300),
|
||||
texcoords[0],
|
||||
texcoords[1],
|
||||
texcoords[2],
|
||||
texcoords[3]);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
|
||||
cogl_texture_unref (priv->texture_id);
|
||||
cogl_offscreen_unref (priv->offscreen_id);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
||||
|
||||
printf ("Loading redhand.png\n");
|
||||
priv->texhand_id = cogl_texture_new_from_file ("redhand.png", 0, FALSE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
NULL);
|
||||
|
||||
printf ("Creating texture with size\n");
|
||||
priv->texture_id = cogl_texture_new_with_size (200,200,0, FALSE,
|
||||
COGL_PIXEL_FORMAT_RGB_888);
|
||||
|
||||
if (priv->texture_id == COGL_INVALID_HANDLE)
|
||||
printf ("Failed creating texture with size!\n");
|
||||
|
||||
printf ("Creating offscreen\n");
|
||||
priv->offscreen_id = cogl_offscreen_new_to_texture (priv->texture_id);
|
||||
|
||||
if (priv->offscreen_id == COGL_INVALID_HANDLE)
|
||||
printf ("Failed creating offscreen to texture!\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_offscreen_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
|
||||
clutter_init(&argc, &argv);
|
||||
|
||||
/* Stage */
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 400, 400);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
||||
|
||||
/* Cogl Box */
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
298
tests/interactive/test-cogl-primitives.c
Normal file
298
tests/interactive/test-cogl-primitives.c
Normal file
@ -0,0 +1,298 @@
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
void (*_test_coglbox_priv1) (void);
|
||||
};
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
typedef void (*PaintFunc) (void);
|
||||
|
||||
static void
|
||||
test_paint_line ()
|
||||
{
|
||||
cogl_path_line (CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (-25),
|
||||
CLUTTER_INT_TO_FIXED (50),
|
||||
CLUTTER_INT_TO_FIXED (25));
|
||||
}
|
||||
|
||||
static void
|
||||
test_paint_rect ()
|
||||
{
|
||||
cogl_path_rectangle (CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (-25),
|
||||
CLUTTER_INT_TO_FIXED (100),
|
||||
CLUTTER_INT_TO_FIXED (50));
|
||||
}
|
||||
|
||||
static void
|
||||
test_paint_rndrect()
|
||||
{
|
||||
cogl_path_round_rectangle (CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (-25),
|
||||
CLUTTER_INT_TO_FIXED (100),
|
||||
CLUTTER_INT_TO_FIXED (50),
|
||||
CLUTTER_INT_TO_FIXED (10),
|
||||
5);
|
||||
}
|
||||
|
||||
static void
|
||||
test_paint_polyl ()
|
||||
{
|
||||
ClutterFixed poly_coords[] = {
|
||||
CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (+50),
|
||||
CLUTTER_INT_TO_FIXED (-30),
|
||||
CLUTTER_INT_TO_FIXED (+30),
|
||||
CLUTTER_INT_TO_FIXED (+30),
|
||||
CLUTTER_INT_TO_FIXED (-30),
|
||||
CLUTTER_INT_TO_FIXED (+40)
|
||||
};
|
||||
|
||||
cogl_path_polyline (poly_coords, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
test_paint_polyg ()
|
||||
{
|
||||
gint poly_coords[] = {
|
||||
CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (+50),
|
||||
CLUTTER_INT_TO_FIXED (-30),
|
||||
CLUTTER_INT_TO_FIXED (+30),
|
||||
CLUTTER_INT_TO_FIXED (+30),
|
||||
CLUTTER_INT_TO_FIXED (-30),
|
||||
CLUTTER_INT_TO_FIXED (+40)
|
||||
};
|
||||
|
||||
cogl_path_polygon (poly_coords, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
test_paint_elp ()
|
||||
{
|
||||
cogl_path_ellipse (0, 0,
|
||||
CLUTTER_INT_TO_FIXED (60),
|
||||
CLUTTER_INT_TO_FIXED (40));
|
||||
}
|
||||
|
||||
static void
|
||||
test_paint_curve ()
|
||||
{
|
||||
cogl_path_move_to (CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (+50));
|
||||
|
||||
cogl_path_curve_to (CLUTTER_INT_TO_FIXED (+100),
|
||||
CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (-100),
|
||||
CLUTTER_INT_TO_FIXED (-50),
|
||||
CLUTTER_INT_TO_FIXED (+50),
|
||||
CLUTTER_INT_TO_FIXED (+50));
|
||||
}
|
||||
|
||||
static PaintFunc paint_func []=
|
||||
{
|
||||
test_paint_line,
|
||||
test_paint_rect,
|
||||
test_paint_rndrect,
|
||||
test_paint_polyl,
|
||||
test_paint_polyg,
|
||||
test_paint_elp,
|
||||
test_paint_curve
|
||||
};
|
||||
|
||||
static void
|
||||
test_coglbox_paint(ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
CoglColor cfill;
|
||||
CoglColor cstroke;
|
||||
|
||||
static GTimer *timer = NULL;
|
||||
static gint paint_index = 0;
|
||||
|
||||
gint NUM_PAINT_FUNCS;
|
||||
|
||||
NUM_PAINT_FUNCS = G_N_ELEMENTS (paint_func);
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
|
||||
if (!timer)
|
||||
{
|
||||
timer = g_timer_new ();
|
||||
g_timer_start (timer);
|
||||
}
|
||||
|
||||
if (g_timer_elapsed (timer, NULL) >= 1)
|
||||
{
|
||||
paint_index += 1;
|
||||
paint_index = paint_index % NUM_PAINT_FUNCS;
|
||||
g_timer_start (timer);
|
||||
}
|
||||
|
||||
cogl_color_set_from_4ub (&cfill, 0, 160, 0, 255);
|
||||
cogl_color_set_from_4ub (&cstroke, 200, 0, 0, 255);
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
paint_func[paint_index] ();
|
||||
|
||||
cogl_translate (100,100,0);
|
||||
cogl_color (&cstroke);
|
||||
cogl_path_stroke ();
|
||||
|
||||
cogl_translate (150,0,0);
|
||||
cogl_color (&cfill);
|
||||
cogl_path_fill ();
|
||||
|
||||
cogl_pop_matrix();
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
#define SPIN() while (g_main_context_pending (NULL)) \
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_primitives_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
|
||||
clutter_init(&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 400, 400);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
||||
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
clutter_actor_set_rotation (coglbox, CLUTTER_Y_AXIS, -30, 200, 0, 0);
|
||||
clutter_actor_set_position (coglbox, 0, 100);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
while (1)
|
||||
{
|
||||
clutter_actor_hide (coglbox);
|
||||
clutter_actor_show (coglbox);
|
||||
SPIN();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
224
tests/interactive/test-cogl-tex-convert.c
Normal file
224
tests/interactive/test-cogl-tex-convert.c
Normal file
@ -0,0 +1,224 @@
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
CoglHandle cogl_tex_id[4];
|
||||
gint frame;
|
||||
};
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
test_coglbox_paint(ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
CoglColor cback;
|
||||
CoglColor cwhite;
|
||||
|
||||
ClutterFixed texcoords[4] = {
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f)
|
||||
};
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
cogl_color_set_from_4ub (&cback, 0x66, 0x66, 0xdd, 0xff);
|
||||
cogl_color (&cback);
|
||||
cogl_rectangle (0,0,400,400);
|
||||
|
||||
cogl_color_set_from_4ub (&cwhite, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_color (&cwhite);
|
||||
|
||||
cogl_push_matrix ();
|
||||
cogl_texture_rectangle (priv->cogl_tex_id[0],
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
CLUTTER_INT_TO_FIXED (213),
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (200,0,0);
|
||||
cogl_texture_rectangle (priv->cogl_tex_id[1],
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
CLUTTER_INT_TO_FIXED (213),
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (0,200,0);
|
||||
cogl_texture_rectangle (priv->cogl_tex_id[2],
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
CLUTTER_INT_TO_FIXED (213),
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (200,200,0);
|
||||
cogl_texture_rectangle (priv->cogl_tex_id[3],
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
CLUTTER_INT_TO_FIXED (213),
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
cogl_texture_unref (priv->cogl_tex_id);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
||||
|
||||
priv->cogl_tex_id[0] =
|
||||
cogl_texture_new_from_file ("redhand.png", 0, FALSE,
|
||||
COGL_PIXEL_FORMAT_ANY, NULL);
|
||||
|
||||
priv->cogl_tex_id[1] =
|
||||
cogl_texture_new_from_file ("redhand.png", 0, FALSE,
|
||||
COGL_PIXEL_FORMAT_BGRA_8888, NULL);
|
||||
|
||||
priv->cogl_tex_id[2] =
|
||||
cogl_texture_new_from_file ("redhand.png", 0, FALSE,
|
||||
COGL_PIXEL_FORMAT_ARGB_8888, NULL);
|
||||
|
||||
priv->cogl_tex_id[3] =
|
||||
cogl_texture_new_from_file ("redhand.png", 0, FALSE,
|
||||
COGL_PIXEL_FORMAT_G_8, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_tex_convert_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
|
||||
clutter_init(&argc, &argv);
|
||||
|
||||
/* Stage */
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 400, 400);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
||||
|
||||
/* Cogl Box */
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
214
tests/interactive/test-cogl-tex-foreign.c
Normal file
214
tests/interactive/test-cogl-tex-foreign.c
Normal file
@ -0,0 +1,214 @@
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
GLuint gl_handle;
|
||||
CoglHandle cogl_handle;
|
||||
};
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
test_coglbox_paint(ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
CoglColor cback;
|
||||
CoglColor cwhite;
|
||||
ClutterFixed texcoords[4] = {
|
||||
CLUTTER_FLOAT_TO_FIXED (0.3f),
|
||||
CLUTTER_FLOAT_TO_FIXED (0.3f),
|
||||
CLUTTER_FLOAT_TO_FIXED (0.7f),
|
||||
CLUTTER_FLOAT_TO_FIXED (0.7f)
|
||||
};
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
cogl_color_set_from_4ub (&cback, 0x66, 0x66, 0xdd, 0xff);
|
||||
cogl_color (&cback);
|
||||
cogl_rectangle (0,0,400,400);
|
||||
|
||||
cogl_color_set_from_4ub (&cwhite, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_color (&cwhite);
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
cogl_translate (100,100,0);
|
||||
cogl_texture_rectangle (priv->cogl_handle,
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
|
||||
cogl_texture_unref (priv->cogl_handle);
|
||||
glDeleteTextures (1, &priv->gl_handle);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
guchar data[12];
|
||||
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
||||
|
||||
/* Prepare a 2x2 pixels texture */
|
||||
|
||||
data[0] = 255; data[1] = 0; data[2] = 0;
|
||||
data[3] = 0; data[4] = 255; data[5] = 0;
|
||||
data[6] = 0; data[7] = 0; data[8] = 255;
|
||||
data[9] = 0; data[10] = 0; data[11] = 0;
|
||||
|
||||
glGenTextures (1, &priv->gl_handle);
|
||||
glBindTexture (GL_TEXTURE_2D, priv->gl_handle);
|
||||
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
|
||||
2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
/* Create texture from foreign */
|
||||
|
||||
priv->cogl_handle =
|
||||
cogl_texture_new_from_foreign (priv->gl_handle,
|
||||
GL_TEXTURE_2D,
|
||||
2, 2, 0, 0,
|
||||
COGL_PIXEL_FORMAT_RGB_888);
|
||||
|
||||
if (priv->cogl_handle == COGL_INVALID_HANDLE)
|
||||
{
|
||||
printf ("Failed creating texture from foreign!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_tex_foreign_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
|
||||
clutter_init(&argc, &argv);
|
||||
|
||||
/* Stage */
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 400, 400);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
||||
|
||||
/* Cogl Box */
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
272
tests/interactive/test-cogl-tex-getset.c
Normal file
272
tests/interactive/test-cogl-tex-getset.c
Normal file
@ -0,0 +1,272 @@
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
CoglHandle cogl_tex_id[4];
|
||||
};
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
test_coglbox_paint(ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
CoglColor cback;
|
||||
CoglColor cwhite;
|
||||
ClutterFixed texcoords[4] = {
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f)
|
||||
};
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
cogl_color_set_from_4ub (&cback, 0x66, 0x66, 0xdd, 0xff);
|
||||
cogl_color (&cback);
|
||||
cogl_rectangle (0,0,400,400);
|
||||
|
||||
cogl_color_set_from_4ub (&cwhite, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_color (&cwhite);
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
cogl_translate (100,100,0);
|
||||
cogl_texture_rectangle (priv->cogl_tex_id[1],
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
CLUTTER_INT_TO_FIXED (213),
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
cogl_texture_unref (priv->cogl_tex_id);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
guint width;
|
||||
guint height;
|
||||
guint rowstride;
|
||||
CoglPixelFormat format;
|
||||
gint size;
|
||||
guchar *data;
|
||||
gint x,y,t;
|
||||
guchar *pixel;
|
||||
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
||||
|
||||
/* Load image from file */
|
||||
|
||||
priv->cogl_tex_id[0] =
|
||||
cogl_texture_new_from_file ("redhand.png", 40, FALSE,
|
||||
COGL_PIXEL_FORMAT_ANY, NULL);
|
||||
|
||||
if (priv->cogl_tex_id[0] == COGL_INVALID_HANDLE)
|
||||
{
|
||||
printf ("Failed loading redhand.png image!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Texture loaded from file.\n");
|
||||
|
||||
/* Obtain pixel data */
|
||||
|
||||
format = cogl_texture_get_format (priv->cogl_tex_id[0]);
|
||||
g_assert(format == COGL_PIXEL_FORMAT_RGBA_8888 ||
|
||||
format == COGL_PIXEL_FORMAT_ARGB_8888);
|
||||
|
||||
width = cogl_texture_get_width (priv->cogl_tex_id[0]);
|
||||
height = cogl_texture_get_height (priv->cogl_tex_id[0]);
|
||||
size = cogl_texture_get_data (priv->cogl_tex_id[0],
|
||||
format, 0, NULL);
|
||||
|
||||
printf("size: %dx%d\n", width, height);
|
||||
printf("format: 0x%x\n", format);
|
||||
printf("bytesize: %d\n", size);
|
||||
|
||||
data = (guchar*) g_malloc (sizeof(guchar) * size);
|
||||
|
||||
cogl_texture_get_data (priv->cogl_tex_id[0],
|
||||
format, 0, data);
|
||||
rowstride = cogl_texture_get_rowstride (priv->cogl_tex_id[0]);
|
||||
|
||||
/* Create new texture from modified data */
|
||||
|
||||
priv->cogl_tex_id[1] =
|
||||
cogl_texture_new_from_data (width, height, 0, FALSE,
|
||||
format, format,
|
||||
rowstride, data);
|
||||
|
||||
if (priv->cogl_tex_id[1] == COGL_INVALID_HANDLE)
|
||||
{
|
||||
printf ("Failed creating image from data!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("Texture created from data.\n");
|
||||
|
||||
/* Modify data (swap red and green) */
|
||||
|
||||
for (y=0; y<height; ++y)
|
||||
{
|
||||
for (x=0; x<width; ++x)
|
||||
{
|
||||
pixel = data + y * rowstride + x * 4;
|
||||
if (format == COGL_PIXEL_FORMAT_RGBA_8888)
|
||||
{
|
||||
t = pixel[0];
|
||||
pixel[0] = pixel[1];
|
||||
pixel[1] = t;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = pixel[1];
|
||||
pixel[1] = pixel[2];
|
||||
pixel[2] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cogl_texture_set_region (priv->cogl_tex_id[1],
|
||||
0, 0, 0, 0,
|
||||
100, 100, width, height,
|
||||
format, 0, data);
|
||||
|
||||
cogl_texture_set_region (priv->cogl_tex_id[1],
|
||||
100, 100, 100, 100,
|
||||
100, 100, width, height,
|
||||
format, 0, data);
|
||||
|
||||
printf ("Subregion data updated.\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_tex_getset_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
|
||||
clutter_init(&argc, &argv);
|
||||
|
||||
/* Stage */
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 400, 400);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
||||
|
||||
/* Cogl Box */
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
398
tests/interactive/test-cogl-tex-polygon.c
Normal file
398
tests/interactive/test-cogl-tex-polygon.c
Normal file
@ -0,0 +1,398 @@
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
CoglHandle sliced_tex, not_sliced_tex;
|
||||
gint frame;
|
||||
gboolean use_sliced;
|
||||
gboolean use_linear_filtering;
|
||||
};
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
test_coglbox_fade_texture (CoglHandle tex_id,
|
||||
ClutterFixed x1,
|
||||
ClutterFixed y1,
|
||||
ClutterFixed x2,
|
||||
ClutterFixed y2,
|
||||
ClutterFixed tx1,
|
||||
ClutterFixed ty1,
|
||||
ClutterFixed tx2,
|
||||
ClutterFixed ty2)
|
||||
{
|
||||
CoglTextureVertex vertices[4];
|
||||
CoglColor white;
|
||||
int i;
|
||||
|
||||
vertices[0].x = x1;
|
||||
vertices[0].y = y1;
|
||||
vertices[0].z = 0;
|
||||
vertices[0].tx = tx1;
|
||||
vertices[0].ty = ty1;
|
||||
vertices[1].x = x1;
|
||||
vertices[1].y = y2;
|
||||
vertices[1].z = 0;
|
||||
vertices[1].tx = tx1;
|
||||
vertices[1].ty = ty2;
|
||||
vertices[2].x = x2;
|
||||
vertices[2].y = y2;
|
||||
vertices[2].z = 0;
|
||||
vertices[2].tx = tx2;
|
||||
vertices[2].ty = ty2;
|
||||
vertices[3].x = x2;
|
||||
vertices[3].y = y1;
|
||||
vertices[3].z = 0;
|
||||
vertices[3].tx = tx2;
|
||||
vertices[3].ty = ty1;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
cogl_color_set_from_4ub (&(vertices[i].color),
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
((i ^ (i >> 1)) & 1) ? 0 : 128);
|
||||
}
|
||||
|
||||
cogl_texture_polygon (tex_id, 4, vertices, TRUE);
|
||||
|
||||
cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_color (&white);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_triangle_texture (CoglHandle tex_id,
|
||||
ClutterFixed x,
|
||||
ClutterFixed y,
|
||||
ClutterFixed tx1,
|
||||
ClutterFixed ty1,
|
||||
ClutterFixed tx2,
|
||||
ClutterFixed ty2,
|
||||
ClutterFixed tx3,
|
||||
ClutterFixed ty3)
|
||||
{
|
||||
CoglTextureVertex vertices[3];
|
||||
int tex_width = cogl_texture_get_width (tex_id);
|
||||
int tex_height = cogl_texture_get_height (tex_id);
|
||||
|
||||
vertices[0].x = x + tx1 * tex_width;
|
||||
vertices[0].y = y + ty1 * tex_height;
|
||||
vertices[0].z = 0;
|
||||
vertices[0].tx = tx1;
|
||||
vertices[0].ty = ty1;
|
||||
|
||||
vertices[1].x = x + tx2 * tex_width;
|
||||
vertices[1].y = y + ty2 * tex_height;
|
||||
vertices[1].z = 0;
|
||||
vertices[1].tx = tx2;
|
||||
vertices[1].ty = ty2;
|
||||
|
||||
vertices[2].x = x + tx3 * tex_width;
|
||||
vertices[2].y = y + ty3 * tex_height;
|
||||
vertices[2].z = 0;
|
||||
vertices[2].tx = tx3;
|
||||
vertices[2].ty = ty3;
|
||||
|
||||
cogl_texture_polygon (tex_id, 3, vertices, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_paint (ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
CoglHandle tex_handle = priv->use_sliced ? priv->sliced_tex
|
||||
: priv->not_sliced_tex;
|
||||
CoglColor white;
|
||||
int tex_width = cogl_texture_get_width (tex_handle);
|
||||
int tex_height = cogl_texture_get_height (tex_handle);
|
||||
|
||||
cogl_color_set_from_4ub (&white, 255, 255, 255, 255);
|
||||
cogl_color (&white);
|
||||
|
||||
cogl_texture_set_filters (tex_handle,
|
||||
priv->use_linear_filtering
|
||||
? CGL_LINEAR : CGL_NEAREST,
|
||||
priv->use_linear_filtering
|
||||
? CGL_LINEAR : CGL_NEAREST);
|
||||
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (tex_width / 2, 0, 0);
|
||||
cogl_rotate (priv->frame, 0, 1, 0);
|
||||
cogl_translate (-tex_width / 2, 0, 0);
|
||||
|
||||
/* Draw a hand and refect it */
|
||||
cogl_texture_rectangle (tex_handle,
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (tex_width),
|
||||
CLUTTER_INT_TO_FIXED (tex_height),
|
||||
0, 0, CFX_ONE, CFX_ONE);
|
||||
test_coglbox_fade_texture (tex_handle,
|
||||
0, CLUTTER_INT_TO_FIXED (tex_height),
|
||||
CLUTTER_INT_TO_FIXED (tex_width),
|
||||
CLUTTER_INT_TO_FIXED (tex_height * 3 / 2),
|
||||
0, CFX_ONE,
|
||||
CFX_ONE, CFX_ONE / 2);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (tex_width * 3 / 2 + 60, 0, 0);
|
||||
cogl_rotate (priv->frame, 0, 1, 0);
|
||||
cogl_translate (-tex_width / 2 - 10, 0, 0);
|
||||
|
||||
/* Draw the texture split into two triangles */
|
||||
test_coglbox_triangle_texture (tex_handle,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, CFX_ONE,
|
||||
CFX_ONE, CFX_ONE);
|
||||
test_coglbox_triangle_texture (tex_handle,
|
||||
CLUTTER_INT_TO_FIXED (20), 0,
|
||||
0, 0,
|
||||
CFX_ONE, 0,
|
||||
CFX_ONE, CFX_ONE);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
cogl_texture_unref (priv->not_sliced_tex);
|
||||
cogl_texture_unref (priv->sliced_tex);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
GError *error = NULL;
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
priv->use_linear_filtering = FALSE;
|
||||
priv->use_sliced = FALSE;
|
||||
|
||||
priv->sliced_tex = cogl_texture_new_from_file
|
||||
("redhand.png", 10, FALSE, COGL_PIXEL_FORMAT_ANY, &error);
|
||||
if (priv->sliced_tex == NULL)
|
||||
{
|
||||
g_warning ("Texture loading failed: %s", error->message);
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
|
||||
priv->not_sliced_tex = cogl_texture_new_from_file
|
||||
("redhand.png", -1, FALSE, COGL_PIXEL_FORMAT_ANY, &error);
|
||||
if (priv->not_sliced_tex == NULL)
|
||||
{
|
||||
g_warning ("Texture loading failed: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
frame_cb (ClutterTimeline *timeline,
|
||||
gint frame_num,
|
||||
gpointer data)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (data);
|
||||
|
||||
priv->frame = frame_num;
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
|
||||
}
|
||||
|
||||
static void
|
||||
update_toggle_text (ClutterLabel *button, gboolean val)
|
||||
{
|
||||
clutter_label_set_text (button, val ? "Enabled" : "Disabled");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_toggle_click (ClutterActor *button, ClutterEvent *event,
|
||||
gboolean *toggle_val)
|
||||
{
|
||||
update_toggle_text (CLUTTER_LABEL (button), *toggle_val = !*toggle_val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
make_toggle (const char *label_text, gboolean *toggle_val)
|
||||
{
|
||||
ClutterActor *group = clutter_group_new ();
|
||||
ClutterActor *label = clutter_label_new_with_text ("Sans 14", label_text);
|
||||
ClutterActor *button = clutter_label_new_with_text ("Sans 14", "");
|
||||
|
||||
clutter_actor_set_reactive (button, TRUE);
|
||||
|
||||
update_toggle_text (CLUTTER_LABEL (button), *toggle_val);
|
||||
|
||||
clutter_actor_set_position (button, clutter_actor_get_width (label) + 10, 0);
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), label, button, NULL);
|
||||
|
||||
g_signal_connect (button, "button-press-event", G_CALLBACK (on_toggle_click),
|
||||
toggle_val);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_tex_polygon_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
ClutterActor *filtering_toggle;
|
||||
ClutterActor *slicing_toggle;
|
||||
ClutterActor *note;
|
||||
ClutterTimeline *timeline;
|
||||
ClutterColor blue = { 0x30, 0x30, 0xff, 0xff };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
/* Stage */
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &blue);
|
||||
clutter_actor_set_size (stage, 640, 480);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
||||
|
||||
/* Cogl Box */
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
/* Timeline for animation */
|
||||
timeline = clutter_timeline_new (360, 60); /* num frames, fps */
|
||||
g_object_set (timeline, "loop", TRUE, NULL); /* have it loop */
|
||||
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), coglbox);
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
/* Labels for toggling settings */
|
||||
slicing_toggle = make_toggle ("Texture slicing: ",
|
||||
&(TEST_COGLBOX_GET_PRIVATE (coglbox)
|
||||
->use_sliced));
|
||||
clutter_actor_set_position (slicing_toggle, 0,
|
||||
clutter_actor_get_height (stage)
|
||||
- clutter_actor_get_height (slicing_toggle));
|
||||
filtering_toggle = make_toggle ("Linear filtering: ",
|
||||
&(TEST_COGLBOX_GET_PRIVATE (coglbox)
|
||||
->use_linear_filtering));
|
||||
clutter_actor_set_position (filtering_toggle, 0,
|
||||
clutter_actor_get_y (slicing_toggle)
|
||||
- clutter_actor_get_height (filtering_toggle));
|
||||
note = clutter_label_new_with_text ("Sans 10", "<- Click to change");
|
||||
clutter_actor_set_position (note,
|
||||
clutter_actor_get_width (filtering_toggle) + 10,
|
||||
(clutter_actor_get_height (stage)
|
||||
+ clutter_actor_get_y (filtering_toggle)) / 2
|
||||
- clutter_actor_get_height (note) / 2);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage),
|
||||
slicing_toggle,
|
||||
filtering_toggle,
|
||||
note,
|
||||
NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
227
tests/interactive/test-cogl-tex-tile.c
Normal file
227
tests/interactive/test-cogl-tex-tile.c
Normal file
@ -0,0 +1,227 @@
|
||||
#include <config.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
CoglHandle cogl_tex_id;
|
||||
gint frame;
|
||||
};
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
test_coglbox_paint(ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
CoglColor cback = {0x66, 0x66, 0xDD, 0xFF};
|
||||
CoglColor cwhite = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
ClutterFixed texcoords[4] = {
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (0.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f),
|
||||
CLUTTER_FLOAT_TO_FIXED (1.0f)
|
||||
};
|
||||
|
||||
gint pingpong_frame;
|
||||
ClutterFixed sin_frame, cos_frame;
|
||||
ClutterFixed frac_frame;
|
||||
gint t;
|
||||
|
||||
sin_frame = clutter_sini (CLUTTER_ANGLE_FROM_DEG (priv->frame));
|
||||
cos_frame = clutter_cosi (CLUTTER_ANGLE_FROM_DEG (priv->frame));
|
||||
|
||||
pingpong_frame = (priv->frame <= 180 ? priv->frame : 360 - priv->frame);
|
||||
frac_frame = COGL_FIXED_DIV (CLUTTER_INT_TO_FIXED (pingpong_frame),
|
||||
CLUTTER_INT_TO_FIXED (180));
|
||||
frac_frame += (COGL_FIXED_1 >> 1);
|
||||
frac_frame <<= 1;
|
||||
|
||||
for (t=0; t<4; t+=2)
|
||||
{
|
||||
texcoords[t] += cos_frame;
|
||||
texcoords[t+1] += sin_frame;
|
||||
|
||||
texcoords[t] = COGL_FIXED_MUL (texcoords[t], frac_frame);
|
||||
texcoords[t+1] = COGL_FIXED_MUL (texcoords[t+1], frac_frame);
|
||||
}
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
cogl_color_set_from_4ub (&cback, 0x66, 0x66, 0xdd, 0xff);
|
||||
cogl_color (&cback);
|
||||
cogl_rectangle (0,0,400,400);
|
||||
|
||||
cogl_color_set_from_4ub (&cwhite, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_color (&cwhite);
|
||||
cogl_translate (100,100,0);
|
||||
cogl_texture_rectangle (priv->cogl_tex_id,
|
||||
0, 0,
|
||||
CLUTTER_INT_TO_FIXED (200),
|
||||
CLUTTER_INT_TO_FIXED (213),
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
cogl_texture_unref (priv->cogl_tex_id);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
||||
|
||||
priv->cogl_tex_id = cogl_texture_new_from_file ("redhand.png", 0, FALSE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
NULL);
|
||||
|
||||
cogl_texture_set_filters (priv->cogl_tex_id,
|
||||
CGL_LINEAR, CGL_LINEAR);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
frame_cb (ClutterTimeline *timeline,
|
||||
gint frame_num,
|
||||
gpointer data)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (data);
|
||||
|
||||
priv->frame = frame_num;
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_tex_tile_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
ClutterTimeline *timeline;
|
||||
|
||||
clutter_init(&argc, &argv);
|
||||
|
||||
/* Stage */
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 400, 400);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
||||
|
||||
/* Cogl Box */
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
/* Timeline for animation */
|
||||
timeline = clutter_timeline_new (360, 60); /* num frames, fps */
|
||||
g_object_set (timeline, "loop", TRUE, NULL); /* have it loop */
|
||||
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), coglbox);
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
213
tests/interactive/test-depth.c
Normal file
213
tests/interactive/test-depth.c
Normal file
@ -0,0 +1,213 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
/* each time the timeline animating the label completes, swap the direction */
|
||||
static void
|
||||
timeline_completed (ClutterTimeline *timeline,
|
||||
gpointer user_data)
|
||||
{
|
||||
clutter_timeline_set_direction (timeline,
|
||||
!clutter_timeline_get_direction (timeline));
|
||||
clutter_timeline_start (timeline);
|
||||
}
|
||||
|
||||
static ClutterActor *raise_actor[2];
|
||||
static gboolean raise_no = 0;
|
||||
|
||||
static gboolean
|
||||
raise_top (gpointer ignored)
|
||||
{
|
||||
clutter_actor_raise_top (raise_actor[raise_no]);
|
||||
raise_no = !raise_no;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
clone_box (ClutterTexture *original)
|
||||
{
|
||||
guint width, height;
|
||||
ClutterActor *group;
|
||||
ClutterActor *clone;
|
||||
|
||||
clutter_actor_get_size (CLUTTER_ACTOR (original), &width, &height);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clone = clutter_clone_texture_new (original);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (group), clone);
|
||||
clutter_actor_set_depth (clone, width/2);
|
||||
|
||||
clone = clutter_clone_texture_new (original);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (group), clone);
|
||||
clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 180, width/2, 0, 0);
|
||||
clutter_actor_set_depth (clone, -width/2);
|
||||
|
||||
clone = clutter_clone_texture_new (original);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (group), clone);
|
||||
clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 90, 0, 0, 0);
|
||||
clutter_actor_set_depth (clone, width/2);
|
||||
clutter_actor_set_position (clone, 0, 0);
|
||||
|
||||
clone = clutter_clone_texture_new (original);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (group), clone);
|
||||
clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 90, 0, 0, 0);
|
||||
clutter_actor_set_depth (clone, width/2);
|
||||
clutter_actor_set_position (clone, width, 0);
|
||||
|
||||
clone = clutter_clone_texture_new (original);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (group), clone);
|
||||
clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0);
|
||||
clutter_actor_set_depth (clone, -width/2);
|
||||
clutter_actor_set_position (clone, 0, height);
|
||||
|
||||
clone = clutter_clone_texture_new (original);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (group), clone);
|
||||
clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0);
|
||||
clutter_actor_set_depth (clone, -width/2);
|
||||
clutter_actor_set_position (clone, 0, 0);
|
||||
|
||||
clutter_actor_show_all (group);
|
||||
return group;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
janus_group (const gchar *front_text,
|
||||
const gchar *back_text)
|
||||
{
|
||||
ClutterColor slide_color = {0x00, 0x00, 0x00, 0xff};
|
||||
ClutterColor red = {0xff, 0x00, 0x00, 0xff};
|
||||
ClutterColor green = {0x00, 0xff, 0x00, 0xff};
|
||||
ClutterActor *group, *rectangle, *front, *back;
|
||||
guint width, height;
|
||||
guint width2, height2;
|
||||
|
||||
group = clutter_group_new ();
|
||||
rectangle = clutter_rectangle_new_with_color (&slide_color);
|
||||
front = clutter_label_new_with_text ("Sans 50px", front_text);
|
||||
back = clutter_label_new_with_text ("Sans 50px", back_text);
|
||||
clutter_label_set_color (CLUTTER_LABEL (front), &red);
|
||||
clutter_label_set_color (CLUTTER_LABEL (back), &green);
|
||||
|
||||
clutter_actor_get_size (front, &width, &height);
|
||||
clutter_actor_get_size (back, &width2, &height2);
|
||||
|
||||
if (width2 > width)
|
||||
width = width2;
|
||||
if (height2 > height)
|
||||
height = height2;
|
||||
|
||||
clutter_actor_set_size (rectangle, width, height);
|
||||
clutter_actor_set_rotation (back, CLUTTER_Y_AXIS, 180, width/2, 0, 0);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (group),
|
||||
back, rectangle, front, NULL);
|
||||
|
||||
clutter_actor_show_all (group);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
G_MODULE_EXPORT gint
|
||||
test_depth_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterBehaviour *d_behave;
|
||||
ClutterBehaviour *r_behave;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group, *hand, *label, *rect, *janus, *box;
|
||||
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||
ClutterColor rect_color = { 0, 0, 0, 0x88 };
|
||||
GError *error;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE);
|
||||
clutter_stage_set_fog (CLUTTER_STAGE (stage), 1.0, 10, -50);
|
||||
|
||||
g_signal_connect (stage,
|
||||
"button-press-event", G_CALLBACK (clutter_main_quit),
|
||||
NULL);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clutter_stage_add (stage, group);
|
||||
clutter_actor_show (group);
|
||||
|
||||
label = clutter_label_new_with_text ("Mono 26", "Clutter");
|
||||
clutter_actor_set_position (label, 120, 200);
|
||||
clutter_actor_show (label);
|
||||
|
||||
error = NULL;
|
||||
hand = clutter_texture_new_from_file ("redhand.png", &error);
|
||||
if (error)
|
||||
g_error ("Unable to load redhand.png: %s", error->message);
|
||||
clutter_actor_set_position (hand, 240, 100);
|
||||
clutter_actor_show (hand);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_actor_set_position (rect, 340, 100);
|
||||
clutter_actor_set_size (rect, 200, 200);
|
||||
clutter_actor_show (rect);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), hand, rect, NULL);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
|
||||
|
||||
/* 3 seconds, at 60 fps */
|
||||
timeline = clutter_timeline_new (180, 60);
|
||||
g_signal_connect (timeline,
|
||||
"completed", G_CALLBACK (timeline_completed),
|
||||
NULL);
|
||||
|
||||
d_behave = clutter_behaviour_depth_new (clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL),
|
||||
-100, 100);
|
||||
clutter_behaviour_apply (d_behave, label);
|
||||
|
||||
/* add two faced actor */
|
||||
janus = janus_group ("GREEN", "RED");
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), janus);
|
||||
clutter_actor_set_position (janus, 300, 350);
|
||||
|
||||
r_behave = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL),
|
||||
CLUTTER_Y_AXIS,
|
||||
CLUTTER_ROTATE_CW,
|
||||
0, 360);
|
||||
clutter_behaviour_apply (r_behave, janus);
|
||||
|
||||
|
||||
/* add hand box */
|
||||
box = clone_box (CLUTTER_TEXTURE (hand));
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
||||
clutter_actor_set_position (box, 200, 250);
|
||||
clutter_actor_set_scale (box, 0.5, 0.5);
|
||||
clutter_actor_set_rotation (box, CLUTTER_X_AXIS, 45, 0, 0, 0);
|
||||
clutter_actor_set_opacity (box, 0x44);
|
||||
|
||||
r_behave = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL),
|
||||
CLUTTER_Y_AXIS,
|
||||
CLUTTER_ROTATE_CW,
|
||||
0, 360);
|
||||
clutter_behaviour_apply (r_behave, box);
|
||||
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
raise_actor[0] = rect;
|
||||
raise_actor[1] = hand;
|
||||
g_timeout_add (2000, raise_top, NULL);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (d_behave);
|
||||
g_object_unref (timeline);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
83
tests/interactive/test-devices.c
Normal file
83
tests/interactive/test-devices.c
Normal file
@ -0,0 +1,83 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
typedef struct {
|
||||
|
||||
GHashTable *devices;
|
||||
|
||||
} TestDevicesApp;
|
||||
|
||||
|
||||
|
||||
static gboolean
|
||||
stage_motion_event_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer userdata)
|
||||
{
|
||||
TestDevicesApp *app = (TestDevicesApp *)userdata;
|
||||
ClutterActor *hand = NULL;
|
||||
ClutterMotionEvent *mev = (ClutterMotionEvent *)event;
|
||||
|
||||
hand = g_hash_table_lookup (app->devices, mev->device);
|
||||
clutter_actor_set_position (hand, mev->x, mev->y);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_devices_main (int argc, char **argv)
|
||||
{
|
||||
ClutterActor *stage = NULL;
|
||||
GSList *stage_devices = NULL;
|
||||
TestDevicesApp *app = NULL;
|
||||
ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
|
||||
|
||||
clutter_x11_enable_xinput ();
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
app = g_new0 (TestDevicesApp, 1);
|
||||
app->devices = g_hash_table_new (g_direct_hash, g_direct_equal) ;
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
//clutter_stage_fullscreen (CLUTTER_STAGE (stage));
|
||||
|
||||
g_signal_connect (stage,
|
||||
"motion-event",
|
||||
G_CALLBACK(stage_motion_event_cb),
|
||||
app);
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
stage_devices = clutter_x11_get_input_devices ();
|
||||
|
||||
if (stage_devices == NULL)
|
||||
g_error ("No extended input devices found.");
|
||||
|
||||
do
|
||||
{
|
||||
if (stage_devices)
|
||||
{
|
||||
ClutterX11XInputDevice *device = NULL;
|
||||
ClutterActor *hand = NULL;
|
||||
|
||||
device = (ClutterX11XInputDevice *)stage_devices->data;
|
||||
|
||||
if (clutter_x11_get_input_device_type (device)
|
||||
== CLUTTER_X11_XINPUT_POINTER_DEVICE)
|
||||
{
|
||||
|
||||
g_debug("got a pointer device...\n");
|
||||
|
||||
hand = clutter_texture_new_from_file ("redhand.png", NULL);
|
||||
g_hash_table_insert (app->devices, device, hand);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), hand);
|
||||
}
|
||||
|
||||
}
|
||||
} while ((stage_devices = stage_devices->next) != NULL);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
95
tests/interactive/test-effects.c
Normal file
95
tests/interactive/test-effects.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static ClutterEffectTemplate *tmpl = NULL;
|
||||
static ClutterTimeline *timeline = NULL;
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_effects_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage, *actor;
|
||||
ClutterContainer *container;
|
||||
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||
ClutterColor rect_color = { 0, 0, 0, 0xdd };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
timeline = clutter_timeline_new_for_duration (5000);
|
||||
clutter_timeline_set_loop (timeline, TRUE);
|
||||
tmpl =
|
||||
clutter_effect_template_new (timeline, CLUTTER_ALPHA_RAMP_INC);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
container = CLUTTER_CONTAINER (stage);
|
||||
g_signal_connect (stage,
|
||||
"button-press-event", G_CALLBACK (clutter_main_quit),
|
||||
NULL);
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE);
|
||||
clutter_actor_set_size (stage, 800, 600);
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_container_add_actor (container, actor);
|
||||
clutter_actor_set_size (actor, 50, 50);
|
||||
clutter_actor_set_position (actor, 50, 10);
|
||||
clutter_effect_fade (tmpl, actor, 0x22, NULL, NULL);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_container_add_actor (container, actor);
|
||||
clutter_actor_set_size (actor, 50, 50);
|
||||
clutter_actor_set_position (actor, 750, 70);
|
||||
clutter_effect_depth (tmpl, actor, -500, NULL, NULL);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_container_add_actor (container, actor);
|
||||
clutter_actor_set_size (actor, 50, 50);
|
||||
clutter_actor_set_position (actor, 50, 140);
|
||||
clutter_effect_move (tmpl, actor, 750, 140, NULL, NULL);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_container_add_actor (container, actor);
|
||||
clutter_actor_set_size (actor, 50, 50);
|
||||
clutter_actor_set_position (actor, 750, 210);
|
||||
{
|
||||
ClutterKnot knots[2];
|
||||
|
||||
knots[0].x = 750; knots[0].y = 210;
|
||||
knots[1].x = 350; knots[1].y = 210;
|
||||
|
||||
clutter_effect_path (tmpl, actor, knots, 2, NULL, NULL);
|
||||
}
|
||||
clutter_actor_show (actor);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_container_add_actor (container, actor);
|
||||
clutter_actor_set_size (actor, 50, 50);
|
||||
clutter_actor_set_position (actor, 50, 280);
|
||||
clutter_actor_set_anchor_point_from_gravity (actor, CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
clutter_effect_scale (tmpl, actor, 2.0, 2.0, NULL, NULL);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_container_add_actor (container, actor);
|
||||
clutter_actor_set_size (actor, 50, 50);
|
||||
clutter_actor_set_position (actor, 750, 350);
|
||||
clutter_effect_rotate (tmpl, actor,
|
||||
CLUTTER_Z_AXIS, 180.0,
|
||||
25, 25, 0,
|
||||
CLUTTER_ROTATE_CW,
|
||||
NULL, NULL);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (tmpl);
|
||||
g_object_unref (timeline);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
301
tests/interactive/test-entry-auto.c
Normal file
301
tests/interactive/test-entry-auto.c
Normal file
@ -0,0 +1,301 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef g_assert_cmpint
|
||||
# define g_assert_cmpint(x,y,z) g_assert((x) y (z))
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
gunichar unichar;
|
||||
const char bytes[6];
|
||||
gint nbytes;
|
||||
} TestData;
|
||||
|
||||
const TestData
|
||||
test_data[] = {
|
||||
{ 0xe4, "\xc3\xa4", 2 }, /* LATIN SMALL LETTER A WITH DIAERESIS */
|
||||
{ 0x2665, "\xe2\x99\xa5", 3 } /* BLACK HEART SUIT */
|
||||
};
|
||||
|
||||
static void
|
||||
selfcheck (const TestData *t)
|
||||
{
|
||||
gunichar unichar;
|
||||
char bytes[6];
|
||||
int nbytes;
|
||||
|
||||
g_assert (g_unichar_validate (t->unichar));
|
||||
|
||||
nbytes = g_unichar_to_utf8 (t->unichar, bytes);
|
||||
bytes[nbytes] = '\0';
|
||||
g_assert (nbytes == t->nbytes);
|
||||
g_assert (memcmp (t->bytes, bytes, nbytes) == 0);
|
||||
|
||||
unichar = g_utf8_get_char_validated (bytes, nbytes);
|
||||
g_assert (unichar == t->unichar);
|
||||
}
|
||||
|
||||
static int
|
||||
get_nbytes (ClutterEntry *entry)
|
||||
{
|
||||
const char *s = clutter_entry_get_text (entry);
|
||||
return strlen (s);
|
||||
}
|
||||
|
||||
static int
|
||||
get_nchars (ClutterEntry *entry)
|
||||
{
|
||||
const char *s = clutter_entry_get_text (entry);
|
||||
g_assert (g_utf8_validate (s, -1, NULL));
|
||||
return g_utf8_strlen (s, -1);
|
||||
}
|
||||
|
||||
#define DONT_MOVE_CURSOR (-2)
|
||||
|
||||
static void
|
||||
insert_unichar (ClutterEntry *entry, gunichar unichar, int position)
|
||||
{
|
||||
if (position > DONT_MOVE_CURSOR)
|
||||
{
|
||||
clutter_entry_set_cursor_position (entry, position);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, position);
|
||||
}
|
||||
|
||||
clutter_entry_insert_unichar (entry, unichar);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty (ClutterEntry *entry, const TestData *unused)
|
||||
{
|
||||
g_assert (clutter_entry_get_text (entry) == NULL);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_empty (ClutterEntry *entry, const TestData *unused)
|
||||
{
|
||||
/* annoyingly slightly different from initially empty */
|
||||
clutter_entry_set_text (entry, "");
|
||||
g_assert_cmpint (get_nchars (entry), ==, 0);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 0);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_text (ClutterEntry *entry, const TestData *unused)
|
||||
{
|
||||
clutter_entry_set_text (entry, "abcdef");
|
||||
g_assert_cmpint (get_nchars (entry), ==, 6);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 6);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
|
||||
clutter_entry_set_cursor_position (entry, 5);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 5);
|
||||
|
||||
clutter_entry_set_text (entry, "");
|
||||
/* FIXME: cursor position should be -1?
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
test_insert (ClutterEntry *entry, const TestData *t)
|
||||
{
|
||||
clutter_entry_insert_unichar (entry, t->unichar);
|
||||
clutter_entry_insert_unichar (entry, t->unichar);
|
||||
|
||||
insert_unichar (entry, t->unichar, 1);
|
||||
g_assert_cmpint (get_nchars (entry), ==, 3);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_append_some (ClutterEntry *entry, const TestData *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= 4; i++)
|
||||
{
|
||||
insert_unichar (entry, t->unichar, DONT_MOVE_CURSOR);
|
||||
g_assert_cmpint (get_nchars (entry), ==, i);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, i * t->nbytes);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_prepend_some (ClutterEntry *entry, const TestData *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
clutter_entry_insert_unichar (entry, t->unichar);
|
||||
g_assert_cmpint (get_nchars (entry), ==, 1);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
|
||||
for (i = 2; i <= 4; i++)
|
||||
{
|
||||
insert_unichar (entry, t->unichar, 0);
|
||||
g_assert_cmpint (get_nchars (entry), ==, i);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, i * t->nbytes);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_delete_chars (ClutterEntry *entry, const TestData *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
clutter_entry_insert_unichar (entry, t->unichar);
|
||||
|
||||
clutter_entry_set_cursor_position (entry, 2);
|
||||
clutter_entry_delete_chars (entry, 1);
|
||||
g_assert_cmpint (get_nchars (entry), ==, 3);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
|
||||
|
||||
clutter_entry_set_cursor_position (entry, 2);
|
||||
clutter_entry_delete_chars (entry, 1);
|
||||
g_assert_cmpint (get_nchars (entry), ==, 2);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_delete_text (ClutterEntry *entry, const TestData *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
clutter_entry_insert_unichar (entry, t->unichar);
|
||||
|
||||
clutter_entry_set_cursor_position (entry, 3);
|
||||
clutter_entry_delete_text (entry, 2, 4);
|
||||
g_assert_cmpint (get_nchars (entry), ==, 2);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes);
|
||||
/* FIXME: cursor position should be -1?
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
init_event (ClutterKeyEvent *event)
|
||||
{
|
||||
event->type = CLUTTER_KEY_PRESS;
|
||||
event->time = 0; /* not needed */
|
||||
event->flags = CLUTTER_EVENT_FLAG_SYNTHETIC;
|
||||
event->stage = NULL; /* not needed */
|
||||
event->source = NULL; /* not needed */
|
||||
event->modifier_state = 0;
|
||||
event->hardware_keycode = 0; /* not needed */
|
||||
}
|
||||
|
||||
static void
|
||||
send_keyval (ClutterEntry *entry, int keyval)
|
||||
{
|
||||
ClutterKeyEvent event;
|
||||
|
||||
init_event (&event);
|
||||
event.keyval = keyval;
|
||||
event.unicode_value = 0; /* should be ignored for cursor keys etc. */
|
||||
|
||||
clutter_entry_handle_key_event (entry, &event);
|
||||
}
|
||||
|
||||
static void
|
||||
send_unichar (ClutterEntry *entry, gunichar unichar)
|
||||
{
|
||||
ClutterKeyEvent event;
|
||||
|
||||
init_event (&event);
|
||||
event.keyval = 0; /* should be ignored for printable characters */
|
||||
event.unicode_value = unichar;
|
||||
|
||||
clutter_entry_handle_key_event (entry, &event);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cursor (ClutterEntry *entry, const TestData *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
clutter_entry_insert_unichar (entry, t->unichar);
|
||||
clutter_entry_set_cursor_position (entry, 2);
|
||||
|
||||
/* test cursor moves and is clamped */
|
||||
send_keyval (entry, CLUTTER_Left);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
|
||||
|
||||
send_keyval (entry, CLUTTER_Left);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0);
|
||||
|
||||
send_keyval (entry, CLUTTER_Left);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0);
|
||||
|
||||
/* delete text containing the cursor */
|
||||
clutter_entry_set_cursor_position (entry, 3);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 3);
|
||||
|
||||
clutter_entry_delete_text (entry, 2, 4);
|
||||
send_keyval (entry, CLUTTER_Left);
|
||||
/* FIXME: cursor position should be -1?
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
test_event (ClutterEntry *entry, const TestData *t)
|
||||
{
|
||||
send_unichar (entry, t->unichar);
|
||||
g_assert_cmpint (get_nchars (entry), ==, 1);
|
||||
g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes);
|
||||
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
run (void (*test_func)(ClutterEntry *, const TestData *), const TestData *t)
|
||||
{
|
||||
ClutterActor *entry;
|
||||
|
||||
entry = clutter_entry_new ();
|
||||
test_func (CLUTTER_ENTRY (entry), t);
|
||||
clutter_actor_destroy (entry);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_entry_auto_main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_data); ++i)
|
||||
selfcheck (&test_data[i]);
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
run (test_empty, NULL);
|
||||
run (test_set_empty, NULL);
|
||||
run (test_set_text, NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_data); ++i)
|
||||
{
|
||||
const TestData *t = &test_data[i];
|
||||
|
||||
run (test_append_some, t);
|
||||
run (test_prepend_some, t);
|
||||
run (test_insert, t);
|
||||
run (test_delete_chars, t);
|
||||
run (test_delete_text, t);
|
||||
run (test_cursor, t);
|
||||
run (test_event, t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
47
tests/interactive/test-entry.c
Normal file
47
tests/interactive/test-entry.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static void
|
||||
on_entry_activated (ClutterEntry *entry, gpointer null)
|
||||
{
|
||||
g_print ("Activated: %s\n", clutter_entry_get_text (entry));
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_entry_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *entry;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
|
||||
ClutterColor entry_color = { 0x33, 0xdd, 0xff, 0xff };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_actor_set_size (stage, 800, 600);
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "ClutterEntry Test");
|
||||
|
||||
entry = clutter_entry_new_with_text ("Sans 14",
|
||||
"Type something, be sure to use the "
|
||||
"left/right arrow keys to move the "
|
||||
"cursor position.");
|
||||
clutter_entry_set_color (CLUTTER_ENTRY (entry), &entry_color);
|
||||
clutter_actor_set_size (entry, 600, 50);
|
||||
clutter_actor_set_position (entry, 100, 100);
|
||||
/*clutter_entry_set_visibility (CLUTTER_ENTRY (entry), FALSE);*/
|
||||
/*clutter_entry_set_max_length (CLUTTER_ENTRY (entry), 50);*/
|
||||
|
||||
clutter_group_add (CLUTTER_GROUP (stage), entry);
|
||||
clutter_stage_set_key_focus (CLUTTER_STAGE (stage), entry);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
g_signal_connect (entry, "activate",
|
||||
G_CALLBACK (on_entry_activated), NULL);
|
||||
|
||||
clutter_main();
|
||||
|
||||
return 0;
|
||||
}
|
304
tests/interactive/test-events.c
Normal file
304
tests/interactive/test-events.c
Normal file
@ -0,0 +1,304 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
gboolean IsFullScreen = FALSE, IsMotion = TRUE;
|
||||
|
||||
static void
|
||||
stage_state_cb (ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *detail = (gchar*)data;
|
||||
|
||||
printf("[stage signal] %s\n", detail);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
blue_button_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
if (IsFullScreen)
|
||||
IsFullScreen = FALSE;
|
||||
else
|
||||
IsFullScreen = TRUE;
|
||||
|
||||
g_object_set (stage, "fullscreen", IsFullScreen, NULL);
|
||||
|
||||
g_print ("*** Fullscreen %s ***\n",
|
||||
IsFullScreen ? "enabled" : "disabled");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
red_button_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
|
||||
if (IsMotion)
|
||||
IsMotion = FALSE;
|
||||
else
|
||||
IsMotion = TRUE;
|
||||
|
||||
clutter_set_motion_events_enabled (IsMotion);
|
||||
|
||||
g_print ("*** Per actor motion events %s ***\n",
|
||||
IsMotion ? "enabled" : "disabled");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
capture_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
g_print ("* captured event for type '%s' *\n",
|
||||
G_OBJECT_TYPE_NAME (actor));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
key_focus_in_cb (ClutterActor *actor,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterActor *focus_box = CLUTTER_ACTOR(data);
|
||||
|
||||
if (actor == clutter_stage_get_default ())
|
||||
clutter_actor_hide (focus_box);
|
||||
else
|
||||
{
|
||||
clutter_actor_set_position (focus_box,
|
||||
clutter_actor_get_x (actor) - 5,
|
||||
clutter_actor_get_y (actor) - 5);
|
||||
|
||||
clutter_actor_set_size (focus_box,
|
||||
clutter_actor_get_width (actor) + 10,
|
||||
clutter_actor_get_height (actor) + 10);
|
||||
clutter_actor_show (focus_box);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fill_keybuf (char *keybuf, ClutterKeyEvent *event)
|
||||
{
|
||||
char utf8[6];
|
||||
int len;
|
||||
|
||||
/* printable character, if any (ß, ∑) */
|
||||
len = g_unichar_to_utf8 (event->unicode_value, utf8);
|
||||
utf8[len] = '\0';
|
||||
sprintf(keybuf, "'%s' ", utf8);
|
||||
|
||||
/* key combination (<Mod1>s, <Shift><Mod1>S, <Ctrl><Mod1>Delete) */
|
||||
len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->keyval),
|
||||
utf8);
|
||||
utf8[len] = '\0';
|
||||
|
||||
if (event->modifier_state & CLUTTER_SHIFT_MASK)
|
||||
strcat (keybuf, "<Shift>");
|
||||
if (event->modifier_state & CLUTTER_LOCK_MASK)
|
||||
strcat (keybuf, "<Lock>");
|
||||
if (event->modifier_state & CLUTTER_CONTROL_MASK)
|
||||
strcat (keybuf, "<Control>");
|
||||
if (event->modifier_state & CLUTTER_MOD1_MASK)
|
||||
strcat (keybuf, "<Mod1>");
|
||||
if (event->modifier_state & CLUTTER_MOD2_MASK)
|
||||
strcat (keybuf, "<Mod2>");
|
||||
if (event->modifier_state & CLUTTER_MOD3_MASK)
|
||||
strcat (keybuf, "<Mod3>");
|
||||
if (event->modifier_state & CLUTTER_MOD4_MASK)
|
||||
strcat (keybuf, "<Mod4>");
|
||||
if (event->modifier_state & CLUTTER_MOD5_MASK)
|
||||
strcat (keybuf, "<Mod5>");
|
||||
strcat (keybuf, utf8);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
input_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterStage *stage = CLUTTER_STAGE (clutter_stage_get_default ());
|
||||
gchar keybuf[128], *source = (gchar*)data;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_KEY_PRESS:
|
||||
fill_keybuf (keybuf, &event->key);
|
||||
printf ("[%s] KEY PRESS %s", source, keybuf);
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
fill_keybuf (keybuf, &event->key);
|
||||
printf ("[%s] KEY RELEASE %s", source, keybuf);
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
g_print ("[%s] MOTION", source);
|
||||
break;
|
||||
case CLUTTER_ENTER:
|
||||
g_print ("[%s] ENTER", source);
|
||||
break;
|
||||
case CLUTTER_LEAVE:
|
||||
g_print ("[%s] LEAVE", source);
|
||||
break;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
g_print ("[%s] BUTTON PRESS (click count:%i)",
|
||||
source, event->button.click_count);
|
||||
break;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
g_print ("[%s] BUTTON RELEASE (click count:%i)",
|
||||
source, event->button.click_count);
|
||||
|
||||
if (clutter_event_get_source (event) == CLUTTER_ACTOR (stage))
|
||||
clutter_stage_set_key_focus (stage, NULL);
|
||||
else if (clutter_event_get_source (event) == actor
|
||||
&& clutter_actor_get_parent (actor) == CLUTTER_ACTOR (stage))
|
||||
clutter_stage_set_key_focus (stage, actor);
|
||||
break;
|
||||
case CLUTTER_SCROLL:
|
||||
g_print ("[%s] BUTTON SCROLL (click count:%i)",
|
||||
source, event->button.click_count);
|
||||
break;
|
||||
case CLUTTER_STAGE_STATE:
|
||||
g_print ("[%s] STAGE STATE", source);
|
||||
break;
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
g_print ("[%s] DESTROY NOTIFY", source);
|
||||
break;
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
g_print ("[%s] CLIENT MESSAGE", source);
|
||||
break;
|
||||
case CLUTTER_DELETE:
|
||||
g_print ("[%s] DELETE", source);
|
||||
break;
|
||||
case CLUTTER_NOTHING:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (clutter_event_get_source (event) == actor)
|
||||
g_print (" *source*");
|
||||
|
||||
g_print ("\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_events_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage, *actor, *focus_box, *group;
|
||||
ClutterColor rcol = { 0xff, 0, 0, 0xff},
|
||||
bcol = { 0, 0, 0xff, 0xff },
|
||||
gcol = { 0, 0xff, 0, 0xff },
|
||||
ycol = { 0xff, 0xff, 0, 0xff },
|
||||
ncol = { 0, 0, 0, 0xff };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
g_signal_connect (stage, "event", G_CALLBACK (input_cb), "stage");
|
||||
|
||||
g_signal_connect (stage, "fullscreen",
|
||||
G_CALLBACK (stage_state_cb), "fullscreen");
|
||||
g_signal_connect (stage, "unfullscreen",
|
||||
G_CALLBACK (stage_state_cb), "unfullscreen");
|
||||
g_signal_connect (stage, "activate",
|
||||
G_CALLBACK (stage_state_cb), "activate");
|
||||
g_signal_connect (stage, "deactivate",
|
||||
G_CALLBACK (stage_state_cb), "deactivate");
|
||||
|
||||
g_signal_connect (stage, "captured-event", G_CALLBACK (capture_cb), NULL);
|
||||
|
||||
focus_box = clutter_rectangle_new_with_color (&ncol);
|
||||
clutter_container_add (CLUTTER_CONTAINER(stage), focus_box, NULL);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rcol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 100, 100);
|
||||
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
|
||||
|
||||
g_signal_connect (actor, "event", G_CALLBACK (input_cb), "red box");
|
||||
g_signal_connect (actor, "focus-in", G_CALLBACK (key_focus_in_cb),
|
||||
focus_box);
|
||||
|
||||
/* Toggle motion - enter/leave capture */
|
||||
g_signal_connect (actor, "button-press-event",
|
||||
G_CALLBACK (red_button_cb), NULL);
|
||||
|
||||
clutter_stage_set_key_focus (CLUTTER_STAGE (stage), actor);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&gcol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 250, 100);
|
||||
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
|
||||
|
||||
g_signal_connect (actor, "event", G_CALLBACK (input_cb), "green box");
|
||||
g_signal_connect (actor, "focus-in", G_CALLBACK (key_focus_in_cb),
|
||||
focus_box);
|
||||
|
||||
g_signal_connect (actor, "captured-event", G_CALLBACK (capture_cb), NULL);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&bcol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 400, 100);
|
||||
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER(stage), actor, NULL);
|
||||
|
||||
g_signal_connect (actor, "event", G_CALLBACK (input_cb), "blue box");
|
||||
g_signal_connect (actor, "focus-in", G_CALLBACK (key_focus_in_cb),
|
||||
focus_box);
|
||||
/* Fullscreen */
|
||||
g_signal_connect (actor, "button-press-event",
|
||||
G_CALLBACK (blue_button_cb), NULL);
|
||||
|
||||
/* non reactive */
|
||||
actor = clutter_rectangle_new_with_color (&ncol);
|
||||
clutter_actor_set_size (actor, 400, 50);
|
||||
clutter_actor_set_position (actor, 100, 250);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER(stage), actor, NULL);
|
||||
|
||||
g_signal_connect (actor, "event", G_CALLBACK (input_cb), "blue box");
|
||||
g_signal_connect (actor, "focus-in", G_CALLBACK (key_focus_in_cb),
|
||||
focus_box);
|
||||
|
||||
g_signal_connect (stage, "focus-in", G_CALLBACK (key_focus_in_cb),
|
||||
focus_box);
|
||||
|
||||
/* non reactive group, with reactive child */
|
||||
actor = clutter_rectangle_new_with_color (&ycol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
g_signal_connect (actor, "event", G_CALLBACK (input_cb), "yellow box");
|
||||
|
||||
/* note group not reactive */
|
||||
group = clutter_group_new ();
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), actor, NULL);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), group, NULL);
|
||||
clutter_actor_set_position (group, 100, 350);
|
||||
clutter_actor_show_all (group);
|
||||
|
||||
clutter_actor_show_all (CLUTTER_ACTOR (stage));
|
||||
|
||||
clutter_main();
|
||||
|
||||
return 0;
|
||||
}
|
219
tests/interactive/test-fbo.c
Normal file
219
tests/interactive/test-fbo.c
Normal file
@ -0,0 +1,219 @@
|
||||
#include "../config.h"
|
||||
|
||||
/*#define TEST_GROUP */
|
||||
|
||||
/* These variables are used instead of the standard GLSL variables on
|
||||
GLES 2 */
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
#define GLES2_VARS \
|
||||
"precision mediump float;\n" \
|
||||
"varying vec2 tex_coord;\n" \
|
||||
"varying vec4 frag_color;\n"
|
||||
#define TEX_COORD "tex_coord"
|
||||
#define COLOR_VAR "frag_color"
|
||||
|
||||
#else /* HAVE_COGL_GLES2 */
|
||||
|
||||
#define GLES2_VARS ""
|
||||
#define TEX_COORD "gl_TexCoord[0]"
|
||||
#define COLOR_VAR "gl_Color"
|
||||
|
||||
#endif /* HAVE_COGL_GLES2 */
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
ClutterActor*
|
||||
make_source(void)
|
||||
{
|
||||
ClutterActor *source, *actor;
|
||||
GError *error = NULL;
|
||||
|
||||
ClutterColor yellow = {0xff, 0xff, 0x00, 0xff};
|
||||
|
||||
source = clutter_group_new();
|
||||
actor = clutter_texture_new_from_file ("redhand.png", &error);
|
||||
if (!actor)
|
||||
g_error("pixbuf load failed: %s", error ? error->message : "Unknown");
|
||||
|
||||
clutter_group_add (source, actor);
|
||||
|
||||
actor = clutter_label_new_with_text ("Sans Bold 50px", "Clutter");
|
||||
|
||||
clutter_label_set_color (CLUTTER_LABEL (actor), &yellow);
|
||||
clutter_actor_set_y (actor, clutter_actor_get_height(source) + 5);
|
||||
clutter_group_add (source, actor);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
ClutterShader*
|
||||
make_shader(void)
|
||||
{
|
||||
ClutterShader *shader;
|
||||
GError *error = NULL;
|
||||
|
||||
shader = clutter_shader_new ();
|
||||
clutter_shader_set_fragment_source (shader,
|
||||
|
||||
GLES2_VARS
|
||||
"uniform float radius ;"
|
||||
"uniform sampler2D rectTexture;"
|
||||
"uniform float x_step, y_step;"
|
||||
""
|
||||
"void main()"
|
||||
"{"
|
||||
" vec4 color = texture2D(rectTexture, " TEX_COORD ".st);"
|
||||
" float u;"
|
||||
" float v;"
|
||||
" int count = 1;"
|
||||
" for (u=-radius;u<radius;u++)"
|
||||
" for (v=-radius;v<radius;v++)"
|
||||
" {"
|
||||
" color += texture2D(rectTexture, "
|
||||
" vec2(" TEX_COORD ".s + u"
|
||||
" * 2.0 * x_step,"
|
||||
" " TEX_COORD ".t + v"
|
||||
" * 2.0 * y_step));"
|
||||
" count ++;"
|
||||
" }"
|
||||
""
|
||||
" gl_FragColor = color / float(count);"
|
||||
" gl_FragColor = gl_FragColor * " COLOR_VAR ";"
|
||||
"}",
|
||||
-1
|
||||
);
|
||||
|
||||
if (!clutter_shader_compile (shader, &error))
|
||||
{
|
||||
fprintf (stderr, "shader compilation failed:\n%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT gint
|
||||
test_fbo_main (gint argc, gchar *argv[])
|
||||
{
|
||||
ClutterColor blue = {0x33, 0x44, 0x55, 0xff};
|
||||
|
||||
ClutterActor *fbo;
|
||||
ClutterActor *onscreen_source, *offscreen_source, *trans_source;
|
||||
ClutterActor *foo_source;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *clone;
|
||||
ClutterShader *shader;
|
||||
gint padx, pady;
|
||||
gint fbo_width, fbo_height;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_OFFSCREEN) == FALSE)
|
||||
g_error("This test requires CLUTTER_FEATURE_OFFSCREEN");
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &blue);
|
||||
|
||||
/* Create the first source */
|
||||
onscreen_source = make_source();
|
||||
clutter_actor_show_all (onscreen_source);
|
||||
clutter_group_add (stage, onscreen_source);
|
||||
|
||||
/* Basic sizing for alignment */
|
||||
fbo_width = clutter_actor_get_width (onscreen_source);
|
||||
fbo_height = clutter_actor_get_height (onscreen_source);
|
||||
padx = fbo_width + 10;
|
||||
pady = fbo_height + 10;
|
||||
clutter_actor_set_size (stage, padx*4, pady*2);
|
||||
|
||||
/* Second hand from fbo onscreen */
|
||||
if ((fbo = clutter_texture_new_from_actor (onscreen_source)) == NULL)
|
||||
g_error("onscreen fbo creation failed");
|
||||
|
||||
clutter_actor_set_position (fbo, padx, 0);
|
||||
clutter_group_add (stage, fbo);
|
||||
|
||||
/* apply a shader to it */
|
||||
shader = make_shader();
|
||||
clutter_actor_set_shader (fbo, shader);
|
||||
clutter_actor_set_shader_param (fbo, "radius", 2.0);
|
||||
clutter_actor_set_shader_param (fbo, "x_step",
|
||||
1.0f / clutter_util_next_p2 (fbo_width));
|
||||
clutter_actor_set_shader_param (fbo, "y_step",
|
||||
1.0f / clutter_util_next_p2 (fbo_height));
|
||||
|
||||
/* Third from cloning the fbo texture */
|
||||
clone = clutter_clone_texture_new (CLUTTER_TEXTURE(fbo));
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), clone);
|
||||
clutter_actor_set_position (clone, padx*2, 0);
|
||||
|
||||
|
||||
/* Forth - an offscreen source */
|
||||
offscreen_source = make_source();
|
||||
clutter_actor_show_all (offscreen_source); /* need to show() offscreen */
|
||||
if ((fbo = clutter_texture_new_from_actor (offscreen_source)) == NULL)
|
||||
g_error("offscreen fbo creation failed");
|
||||
|
||||
clutter_actor_set_position (fbo, padx*3, 0);
|
||||
clutter_group_add (stage, fbo);
|
||||
|
||||
|
||||
/* 5th transformed */
|
||||
trans_source = make_source();
|
||||
clutter_actor_show_all (trans_source); /* need to show() offscreen */
|
||||
|
||||
clutter_actor_set_scale (trans_source, 2.5, 2.5);
|
||||
|
||||
if ((fbo = clutter_texture_new_from_actor (trans_source)) == NULL)
|
||||
g_error("transformed fbo creation failed");
|
||||
|
||||
clutter_actor_set_position (fbo, 0, pady);
|
||||
clutter_group_add (stage, fbo);
|
||||
|
||||
|
||||
/* 6th resized bigger, but after fbo creation */
|
||||
trans_source = make_source();
|
||||
clutter_actor_show_all (trans_source); /* need to show() offscreen */
|
||||
|
||||
if ((fbo = clutter_texture_new_from_actor (trans_source)) == NULL)
|
||||
g_error("transformed fbo creation failed");
|
||||
|
||||
/* rotate after */
|
||||
clutter_actor_move_anchor_point_from_gravity (trans_source,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
clutter_actor_set_rotation (trans_source, CLUTTER_Z_AXIS, 90.0, 0, 0, 0);
|
||||
|
||||
clutter_actor_set_position (fbo, padx, pady);
|
||||
clutter_group_add (stage, fbo);
|
||||
|
||||
|
||||
/* non visual breaks */
|
||||
foo_source = make_source();
|
||||
g_object_ref_sink (foo_source);
|
||||
|
||||
clutter_actor_show_all (foo_source);
|
||||
if ((fbo = clutter_texture_new_from_actor (foo_source)) == NULL)
|
||||
g_error("foo fbo creation failed");
|
||||
|
||||
g_object_unref (foo_source); /* fbo should keep it around */
|
||||
|
||||
clutter_actor_set_position (fbo, padx*3, pady);
|
||||
clutter_group_add (stage, fbo);
|
||||
|
||||
/* TODO:
|
||||
* Check realize/unrealize
|
||||
* get_pixbuf()
|
||||
* set_rgba on fbo texture.
|
||||
*/
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
98
tests/interactive/test-fullscreen.c
Normal file
98
tests/interactive/test-fullscreen.c
Normal file
@ -0,0 +1,98 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
enum
|
||||
{
|
||||
START,
|
||||
HIDE,
|
||||
SHOW,
|
||||
DONE
|
||||
};
|
||||
|
||||
static int state = START;
|
||||
|
||||
static void
|
||||
on_fullscreen (ClutterStage *stage)
|
||||
{
|
||||
g_debug ("fullscreen set, size: %dx%d, mapped: %s",
|
||||
clutter_actor_get_width (CLUTTER_ACTOR (stage)),
|
||||
clutter_actor_get_height (CLUTTER_ACTOR (stage)),
|
||||
CLUTTER_ACTOR_IS_MAPPED (stage) ? "true" : "false");
|
||||
}
|
||||
|
||||
static void
|
||||
on_unfullscreen (ClutterStage *stage)
|
||||
{
|
||||
g_debug ("fullscreen unset, size: %dx%d, mapped: %s",
|
||||
clutter_actor_get_width (CLUTTER_ACTOR (stage)),
|
||||
clutter_actor_get_height (CLUTTER_ACTOR (stage)),
|
||||
CLUTTER_ACTOR_IS_MAPPED (stage) ? "true" : "false");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toggle_fullscreen (gpointer dummy)
|
||||
{
|
||||
ClutterActor *stage = clutter_stage_get_default ();
|
||||
gboolean is_fullscreen = FALSE;
|
||||
|
||||
g_object_get (G_OBJECT (stage), "fullscreen", &is_fullscreen, NULL);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case START:
|
||||
g_debug ("start: is_fullscreen := %s", is_fullscreen ? "true" : "false");
|
||||
clutter_actor_hide (stage);
|
||||
state = HIDE;
|
||||
return TRUE;
|
||||
|
||||
case HIDE:
|
||||
g_debug ("hide: is_fullscreen := %s", is_fullscreen ? "true" : "false");
|
||||
clutter_actor_show (stage);
|
||||
state = SHOW;
|
||||
return TRUE;
|
||||
|
||||
case SHOW:
|
||||
g_debug ("show: is_fullscreen := %s", is_fullscreen ? "true" : "false");
|
||||
clutter_stage_unfullscreen (CLUTTER_STAGE (stage));
|
||||
state = DONE;
|
||||
return TRUE;
|
||||
|
||||
case DONE:
|
||||
g_debug ("done: is_fullscreen := %s", is_fullscreen ? "true" : "false");
|
||||
clutter_main_quit ();
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_fullscreen_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
g_signal_connect (stage,
|
||||
"fullscreen", G_CALLBACK (on_fullscreen),
|
||||
NULL);
|
||||
g_signal_connect (stage,
|
||||
"unfullscreen", G_CALLBACK (on_unfullscreen),
|
||||
NULL);
|
||||
|
||||
clutter_stage_fullscreen (CLUTTER_STAGE (stage));
|
||||
clutter_actor_show (stage);
|
||||
|
||||
g_debug ("stage size: %dx%d, mapped: %s",
|
||||
clutter_actor_get_width (stage),
|
||||
clutter_actor_get_height (stage),
|
||||
CLUTTER_ACTOR_IS_MAPPED (stage) ? "true" : "false");
|
||||
|
||||
g_timeout_add (1000, toggle_fullscreen, NULL);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
236
tests/interactive/test-grab.c
Normal file
236
tests/interactive/test-grab.c
Normal file
@ -0,0 +1,236 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static void
|
||||
stage_state_cb (ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *detail = (gchar*)data;
|
||||
|
||||
printf("[stage signal] %s\n", detail);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
debug_event_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
gchar keybuf[9], *source = (gchar*)data;
|
||||
int len = 0;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_KEY_PRESS:
|
||||
len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->key.keyval),
|
||||
keybuf);
|
||||
keybuf[len] = '\0';
|
||||
printf ("[%s] KEY PRESS '%s'", source, keybuf);
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->key.keyval),
|
||||
keybuf);
|
||||
keybuf[len] = '\0';
|
||||
printf ("[%s] KEY RELEASE '%s'", source, keybuf);
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
printf("[%s] MOTION", source);
|
||||
break;
|
||||
case CLUTTER_ENTER:
|
||||
printf("[%s] ENTER", source);
|
||||
break;
|
||||
case CLUTTER_LEAVE:
|
||||
printf("[%s] LEAVE", source);
|
||||
break;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
printf("[%s] BUTTON PRESS (click count:%i)",
|
||||
source, event->button.click_count);
|
||||
break;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
printf("[%s] BUTTON RELEASE", source);
|
||||
break;
|
||||
case CLUTTER_SCROLL:
|
||||
printf("[%s] BUTTON SCROLL", source);
|
||||
break;
|
||||
case CLUTTER_STAGE_STATE:
|
||||
printf("[%s] STAGE STATE", source);
|
||||
break;
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
printf("[%s] DESTROY NOTIFY", source);
|
||||
break;
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
printf("[%s] CLIENT MESSAGE\n", source);
|
||||
break;
|
||||
case CLUTTER_DELETE:
|
||||
printf("[%s] DELETE", source);
|
||||
break;
|
||||
case CLUTTER_NOTHING:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (clutter_event_get_source (event) == actor)
|
||||
printf(" *source*");
|
||||
|
||||
printf("\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
grab_pointer_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
clutter_grab_pointer (actor);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
red_release_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
clutter_ungrab_pointer ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
blue_release_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
clutter_actor_destroy (actor);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
green_press_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
clutter_set_motion_events_enabled (!clutter_get_motion_events_enabled ());
|
||||
|
||||
g_print ("per actor motion events are now %s\n",
|
||||
clutter_get_motion_events_enabled () ? "enabled" : "disabled");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toggle_grab_pointer_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
/* we only deal with the event if the source is ourself */
|
||||
if (event->button.source == actor)
|
||||
{
|
||||
if (clutter_get_pointer_grab () != NULL)
|
||||
clutter_ungrab_pointer ();
|
||||
else
|
||||
clutter_grab_pointer (actor);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cyan_press_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (clutter_get_keyboard_grab () != NULL)
|
||||
clutter_ungrab_keyboard ();
|
||||
else
|
||||
clutter_grab_keyboard (actor);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_grab_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage, *actor;
|
||||
ClutterColor rcol = { 0xff, 0, 0, 0xff},
|
||||
bcol = { 0, 0, 0xff, 0xff },
|
||||
gcol = { 0, 0xff, 0, 0xff },
|
||||
ccol = { 0, 0xff, 0xff, 0xff },
|
||||
ycol = { 0xff, 0xff, 0, 0xff };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
g_print ("Red box: aquire grab on press, releases it on next button release\n");
|
||||
g_print ("Blue box: aquire grab on press, destroys the blue box actor on release\n");
|
||||
g_print ("Yellow box: aquire grab on press, releases grab on next press on yellow box\n");
|
||||
g_print ("Green box: toggle per actor motion events.\n\n");
|
||||
g_print ("Cyan box: toggle grab (from cyan box) for keyboard events.\n\n");
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
g_signal_connect (stage, "event", G_CALLBACK (debug_event_cb), "stage");
|
||||
|
||||
g_signal_connect (stage, "fullscreen",
|
||||
G_CALLBACK (stage_state_cb), "fullscreen");
|
||||
g_signal_connect (stage, "unfullscreen",
|
||||
G_CALLBACK (stage_state_cb), "unfullscreen");
|
||||
g_signal_connect (stage, "activate",
|
||||
G_CALLBACK (stage_state_cb), "activate");
|
||||
g_signal_connect (stage, "deactivate",
|
||||
G_CALLBACK (stage_state_cb), "deactivate");
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&rcol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 100, 100);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
|
||||
g_signal_connect (actor, "event", G_CALLBACK (debug_event_cb), "red box");
|
||||
g_signal_connect (actor, "button-press-event",
|
||||
G_CALLBACK (grab_pointer_cb), NULL);
|
||||
g_signal_connect (actor, "button-release-event",
|
||||
G_CALLBACK (red_release_cb), NULL);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&ycol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 100, 300);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
|
||||
g_signal_connect (actor, "event", G_CALLBACK (debug_event_cb), "yellow box");
|
||||
g_signal_connect (actor, "button-press-event",
|
||||
G_CALLBACK (toggle_grab_pointer_cb), NULL);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&bcol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 300, 100);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
|
||||
g_signal_connect (actor, "event",
|
||||
G_CALLBACK (debug_event_cb), "blue box");
|
||||
g_signal_connect (actor, "button-press-event",
|
||||
G_CALLBACK (grab_pointer_cb), NULL);
|
||||
g_signal_connect (actor, "button-release-event",
|
||||
G_CALLBACK (blue_release_cb), NULL);
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&gcol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 300, 300);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
|
||||
g_signal_connect (actor, "event",
|
||||
G_CALLBACK (debug_event_cb), "green box");
|
||||
g_signal_connect (actor, "button-press-event",
|
||||
G_CALLBACK (green_press_cb), NULL);
|
||||
|
||||
|
||||
actor = clutter_rectangle_new_with_color (&ccol);
|
||||
clutter_actor_set_size (actor, 100, 100);
|
||||
clutter_actor_set_position (actor, 500, 100);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL);
|
||||
g_signal_connect (actor, "event",
|
||||
G_CALLBACK (debug_event_cb), "cyan box");
|
||||
g_signal_connect (actor, "button-press-event",
|
||||
G_CALLBACK (cyan_press_cb), NULL);
|
||||
|
||||
clutter_actor_show_all (CLUTTER_ACTOR (stage));
|
||||
|
||||
clutter_main();
|
||||
|
||||
return 0;
|
||||
}
|
188
tests/interactive/test-invariants.c
Normal file
188
tests/interactive/test-invariants.c
Normal file
@ -0,0 +1,188 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
/* dummy unit testing API; to be replaced by GTest in 1.0 */
|
||||
typedef void (* test_func) (void);
|
||||
|
||||
typedef struct _TestUnit TestUnit;
|
||||
|
||||
struct _TestUnit
|
||||
{
|
||||
gchar *name;
|
||||
test_func func;
|
||||
};
|
||||
|
||||
static GSList *units = NULL;
|
||||
|
||||
static void
|
||||
test_init (gint *argc,
|
||||
gchar ***argv)
|
||||
{
|
||||
g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
g_assert (clutter_init (argc, argv) == CLUTTER_INIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
test_add_func (const gchar *name,
|
||||
test_func func)
|
||||
{
|
||||
TestUnit *unit;
|
||||
|
||||
unit = g_slice_new (TestUnit);
|
||||
unit->name = g_strdup (name);
|
||||
unit->func = func;
|
||||
|
||||
units = g_slist_prepend (units, unit);
|
||||
}
|
||||
|
||||
static int
|
||||
test_run (void)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
units = g_slist_reverse (units);
|
||||
|
||||
for (l = units; l != NULL; l = l->next)
|
||||
{
|
||||
TestUnit *u = l->data;
|
||||
GString *test_name = g_string_sized_new (75);
|
||||
gsize len, i;
|
||||
|
||||
g_string_append (test_name, "Testing: ");
|
||||
g_string_append (test_name, u->name);
|
||||
len = 75 - test_name->len;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
g_string_append_c (test_name, '.');
|
||||
|
||||
g_print ("%s", test_name->str);
|
||||
|
||||
u->func ();
|
||||
|
||||
g_print ("OK\n");
|
||||
}
|
||||
|
||||
for (l = units; l != NULL; l = l->next)
|
||||
{
|
||||
TestUnit *u = l->data;
|
||||
|
||||
g_free (u->name);
|
||||
g_slice_free (TestUnit, u);
|
||||
}
|
||||
|
||||
g_slist_free (units);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* test units */
|
||||
static void
|
||||
test_initial_state (void)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_rectangle_new ();
|
||||
|
||||
g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
|
||||
g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
|
||||
g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
|
||||
|
||||
clutter_actor_destroy (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
test_realized (void)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_rectangle_new ();
|
||||
|
||||
g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
|
||||
|
||||
clutter_actor_realize (actor);
|
||||
|
||||
g_assert (CLUTTER_ACTOR_IS_REALIZED (actor));
|
||||
|
||||
g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
|
||||
g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
|
||||
|
||||
clutter_actor_destroy (actor);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_mapped (void)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_rectangle_new ();
|
||||
|
||||
g_assert (!(CLUTTER_ACTOR_IS_REALIZED (actor)));
|
||||
g_assert (!(CLUTTER_ACTOR_IS_MAPPED (actor)));
|
||||
|
||||
clutter_actor_show (actor);
|
||||
|
||||
g_assert (CLUTTER_ACTOR_IS_REALIZED (actor));
|
||||
g_assert (CLUTTER_ACTOR_IS_MAPPED (actor));
|
||||
|
||||
g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
|
||||
|
||||
clutter_actor_destroy (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
test_show_on_set_parent (void)
|
||||
{
|
||||
ClutterActor *actor, *group;
|
||||
gboolean show_on_set_parent;
|
||||
|
||||
group = clutter_group_new ();
|
||||
|
||||
g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (group)));
|
||||
|
||||
actor = clutter_rectangle_new ();
|
||||
g_object_get (G_OBJECT (actor),
|
||||
"show-on-set-parent", &show_on_set_parent,
|
||||
NULL);
|
||||
|
||||
g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
|
||||
g_assert (show_on_set_parent == TRUE);
|
||||
|
||||
clutter_group_add (group, actor);
|
||||
g_object_get (G_OBJECT (actor),
|
||||
"show-on-set-parent", &show_on_set_parent,
|
||||
NULL);
|
||||
|
||||
g_assert (CLUTTER_ACTOR_IS_VISIBLE (actor));
|
||||
g_assert (show_on_set_parent == TRUE);
|
||||
|
||||
g_object_ref (actor);
|
||||
clutter_actor_unparent (actor);
|
||||
g_object_get (G_OBJECT (actor),
|
||||
"show-on-set-parent", &show_on_set_parent,
|
||||
NULL);
|
||||
|
||||
g_assert (CLUTTER_ACTOR_IS_REALIZED (actor));
|
||||
g_assert (!(CLUTTER_ACTOR_IS_VISIBLE (actor)));
|
||||
g_assert (show_on_set_parent == TRUE);
|
||||
|
||||
clutter_actor_destroy (actor);
|
||||
clutter_actor_destroy (group);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_invariants_main (int argc, char *argv[])
|
||||
{
|
||||
test_init (&argc, &argv);
|
||||
|
||||
test_add_func ("/invariants/initial-state", test_initial_state);
|
||||
test_add_func ("/invariants/realized", test_realized);
|
||||
test_add_func ("/invariants/mapped", test_mapped);
|
||||
test_add_func ("/invariants/show-on-set-parent", test_show_on_set_parent);
|
||||
|
||||
return test_run ();
|
||||
}
|
818
tests/interactive/test-layout.c
Normal file
818
tests/interactive/test-layout.c
Normal file
@ -0,0 +1,818 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <clutter/clutter.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
|
||||
};
|
||||
|
||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MyThing,
|
||||
my_thing,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
|
||||
clutter_container_iface_init));
|
||||
|
||||
#define MY_THING_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MY_TYPE_THING, MyThingPrivate))
|
||||
|
||||
struct _MyThingPrivate
|
||||
{
|
||||
GList *children;
|
||||
|
||||
ClutterUnit spacing;
|
||||
ClutterUnit padding;
|
||||
|
||||
guint use_transformed_box : 1;
|
||||
};
|
||||
|
||||
/* Add, remove, foreach, copied from ClutterGroup code. */
|
||||
|
||||
static void
|
||||
my_thing_real_add (ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
MyThing *group = MY_THING (container);
|
||||
MyThingPrivate *priv = group->priv;
|
||||
|
||||
g_object_ref (actor);
|
||||
|
||||
priv->children = g_list_append (priv->children, actor);
|
||||
clutter_actor_set_parent (actor, CLUTTER_ACTOR (group));
|
||||
|
||||
g_signal_emit_by_name (container, "actor-added", actor);
|
||||
|
||||
/* queue relayout to allocate new item */
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (group));
|
||||
|
||||
g_object_unref (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_real_remove (ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
MyThing *group = MY_THING (container);
|
||||
MyThingPrivate *priv = group->priv;
|
||||
|
||||
g_object_ref (actor);
|
||||
|
||||
priv->children = g_list_remove (priv->children, actor);
|
||||
clutter_actor_unparent (actor);
|
||||
|
||||
/* At this point, the actor passed to the "actor-removed" signal
|
||||
* handlers is not parented anymore to the container but since we
|
||||
* are holding a reference on it, it's still valid
|
||||
*/
|
||||
g_signal_emit_by_name (container, "actor-removed", actor);
|
||||
|
||||
/* queue relayout to re-allocate children without the
|
||||
removed item */
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (group));
|
||||
|
||||
g_object_unref (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_real_foreach (ClutterContainer *container,
|
||||
ClutterCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MyThingPrivate *priv = MY_THING (container)->priv;
|
||||
GList *l;
|
||||
|
||||
for (l = priv->children; l; l = l->next)
|
||||
(* callback) (CLUTTER_ACTOR (l->data), user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_container_iface_init (ClutterContainerIface *iface)
|
||||
{
|
||||
iface->add = my_thing_real_add;
|
||||
iface->remove = my_thing_real_remove;
|
||||
iface->foreach = my_thing_real_foreach;
|
||||
}
|
||||
|
||||
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 = clutter_value_get_unit (value);
|
||||
break;
|
||||
|
||||
case PROP_PADDING:
|
||||
priv->padding = clutter_value_get_unit (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:
|
||||
clutter_value_set_unit (value, priv->spacing);
|
||||
break;
|
||||
|
||||
case PROP_PADDING:
|
||||
clutter_value_set_unit (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_finalize (GObject *gobject)
|
||||
{
|
||||
G_OBJECT_CLASS (my_thing_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_dispose (GObject *gobject)
|
||||
{
|
||||
MyThing *self = MY_THING (gobject);
|
||||
MyThingPrivate *priv = self->priv;
|
||||
|
||||
if (priv->children)
|
||||
{
|
||||
g_list_foreach (priv->children, (GFunc) clutter_actor_destroy, NULL);
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (my_thing_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
MyThingPrivate *priv;
|
||||
GList *l;
|
||||
ClutterUnit min_left, min_right;
|
||||
ClutterUnit natural_left, natural_right;
|
||||
|
||||
priv = MY_THING (self)->priv;
|
||||
|
||||
min_left = 0;
|
||||
min_right = 0;
|
||||
natural_left = 0;
|
||||
natural_right = 0;
|
||||
|
||||
for (l = priv->children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child;
|
||||
ClutterUnit child_x, child_min, child_natural;
|
||||
|
||||
child = l->data;
|
||||
|
||||
child_x = clutter_actor_get_xu (child);
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
&child_min, NULL,
|
||||
&child_natural, NULL);
|
||||
|
||||
if (l == priv->children)
|
||||
{
|
||||
/* 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,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
MyThingPrivate *priv;
|
||||
GList *l;
|
||||
ClutterUnit min_top, min_bottom;
|
||||
ClutterUnit natural_top, natural_bottom;
|
||||
|
||||
priv = MY_THING (self)->priv;
|
||||
|
||||
min_top = 0;
|
||||
min_bottom = 0;
|
||||
natural_top = 0;
|
||||
natural_bottom = 0;
|
||||
|
||||
for (l = priv->children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child;
|
||||
ClutterUnit child_y, child_min, child_natural;
|
||||
|
||||
child = l->data;
|
||||
|
||||
child_y = clutter_actor_get_yu (child);
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
NULL, &child_min,
|
||||
NULL, &child_natural);
|
||||
|
||||
if (l == priv->children)
|
||||
{
|
||||
/* 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,
|
||||
gboolean origin_changed)
|
||||
{
|
||||
MyThingPrivate *priv;
|
||||
ClutterUnit current_x, current_y, max_row_height;
|
||||
GList *l;
|
||||
|
||||
/* chain up to set actor->allocation */
|
||||
CLUTTER_ACTOR_CLASS (my_thing_parent_class)->allocate (self, box,
|
||||
origin_changed);
|
||||
|
||||
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
|
||||
*/
|
||||
for (l = priv->children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child;
|
||||
ClutterUnit natural_width, natural_height;
|
||||
ClutterActorBox child_box;
|
||||
|
||||
child = l->data;
|
||||
|
||||
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, origin_changed);
|
||||
|
||||
/* 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))
|
||||
{
|
||||
ClutterVertex v1 = { 0, }, v2 = { 0, };
|
||||
ClutterActorBox transformed_box = { 0, };
|
||||
|
||||
/* origin */
|
||||
if (!origin_changed)
|
||||
{
|
||||
v1.x = 0;
|
||||
v1.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_paint (ClutterActor *actor)
|
||||
{
|
||||
MyThing *self = MY_THING (actor);
|
||||
GList *c;
|
||||
|
||||
cogl_push_matrix();
|
||||
|
||||
/* paint all visible children */
|
||||
for (c = self->priv->children;
|
||||
c != NULL;
|
||||
c = c->next)
|
||||
{
|
||||
ClutterActor *child = c->data;
|
||||
|
||||
g_assert (child != NULL);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (child))
|
||||
clutter_actor_paint (child);
|
||||
}
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
#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;
|
||||
gobject_class->dispose = my_thing_dispose;
|
||||
gobject_class->finalize = my_thing_finalize;
|
||||
|
||||
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;
|
||||
actor_class->paint = my_thing_paint;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SPACING,
|
||||
clutter_param_spec_unit ("spacing",
|
||||
"Spacing",
|
||||
"Spacing of the thing",
|
||||
0, CLUTTER_MAXUNIT,
|
||||
0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PADDING,
|
||||
clutter_param_spec_unit ("padding",
|
||||
"Padding",
|
||||
"Padding around the thing",
|
||||
0, CLUTTER_MAXUNIT,
|
||||
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));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MyThingPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
my_thing_init (MyThing *thing)
|
||||
{
|
||||
thing->priv = MY_THING_GET_PRIVATE (thing);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
my_thing_new (gint padding,
|
||||
gint spacing)
|
||||
{
|
||||
return g_object_new (MY_TYPE_THING,
|
||||
"padding", CLUTTER_UNITS_FROM_DEVICE (padding),
|
||||
"spacing", CLUTTER_UNITS_FROM_DEVICE (spacing),
|
||||
NULL);
|
||||
|
||||
}
|
||||
|
||||
/* test code */
|
||||
|
||||
static ClutterActor *box = NULL;
|
||||
static ClutterActor *icon = NULL;
|
||||
static ClutterTimeline *main_timeline = NULL;
|
||||
static ClutterBehaviour *behaviour = NULL;
|
||||
|
||||
static ClutterColor bg_color;
|
||||
|
||||
static void
|
||||
toggle_property_value (ClutterActor *actor,
|
||||
const gchar *property_name)
|
||||
{
|
||||
gboolean value;
|
||||
|
||||
g_object_get (G_OBJECT (actor),
|
||||
property_name, &value,
|
||||
NULL);
|
||||
|
||||
value = !value;
|
||||
|
||||
g_object_set (G_OBJECT (box),
|
||||
property_name, value,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
increase_property_value (ClutterActor *actor,
|
||||
const char *property_name)
|
||||
{
|
||||
ClutterUnit value;
|
||||
|
||||
g_object_get (G_OBJECT (actor),
|
||||
property_name, &value,
|
||||
NULL);
|
||||
|
||||
value = value + CLUTTER_UNITS_FROM_DEVICE (10);
|
||||
|
||||
g_object_set (G_OBJECT (box),
|
||||
property_name, value,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decrease_property_value (ClutterActor *actor,
|
||||
const char *property_name)
|
||||
{
|
||||
ClutterUnit value;
|
||||
|
||||
g_object_get (G_OBJECT (actor),
|
||||
property_name, &value,
|
||||
NULL);
|
||||
|
||||
value = MAX (0, value - CLUTTER_UNITS_FROM_DEVICE (10));
|
||||
|
||||
g_object_set (G_OBJECT (box),
|
||||
property_name, value,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
create_item (void)
|
||||
{
|
||||
ClutterActor *clone =
|
||||
clutter_clone_texture_new (CLUTTER_TEXTURE (icon));
|
||||
|
||||
gint32 size = g_random_int_range (MIN_SIZE, MAX_SIZE);
|
||||
|
||||
clutter_actor_set_size (clone, size, size);
|
||||
|
||||
clutter_behaviour_apply (behaviour, clone);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
keypress_cb (ClutterActor *actor,
|
||||
ClutterKeyEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
switch (clutter_key_event_symbol (event))
|
||||
{
|
||||
case CLUTTER_q:
|
||||
{
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
case CLUTTER_a:
|
||||
{
|
||||
if (icon != NULL)
|
||||
{
|
||||
ClutterActor *clone = create_item ();
|
||||
|
||||
/* Add one item to container */
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (box), clone);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_d:
|
||||
{
|
||||
GList *children =
|
||||
clutter_container_get_children (CLUTTER_CONTAINER (box));
|
||||
|
||||
if (children)
|
||||
{
|
||||
GList *last = g_list_last (children);
|
||||
|
||||
/* Remove last item on container */
|
||||
clutter_container_remove_actor (CLUTTER_CONTAINER (box),
|
||||
CLUTTER_ACTOR (last->data));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_w:
|
||||
{
|
||||
decrease_property_value (box, "padding");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_e:
|
||||
{
|
||||
increase_property_value (box, "padding");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_r:
|
||||
{
|
||||
decrease_property_value (box, "spacing");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_s:
|
||||
{
|
||||
toggle_property_value (box, "use-transformed-box");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_t:
|
||||
{
|
||||
increase_property_value (box, "spacing");
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_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;
|
||||
GError *error = NULL;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 800, 600);
|
||||
|
||||
clutter_color_parse ("Red", &bg_color);
|
||||
|
||||
main_timeline = clutter_timeline_new_for_duration (2000);
|
||||
clutter_timeline_set_loop (main_timeline, TRUE);
|
||||
g_signal_connect (main_timeline, "new-frame",
|
||||
G_CALLBACK (relayout_on_frame),
|
||||
NULL);
|
||||
|
||||
behaviour = clutter_behaviour_scale_new (clutter_alpha_new_full (main_timeline,
|
||||
CLUTTER_ALPHA_SINE,
|
||||
NULL, NULL),
|
||||
1.0, 1.0, 2.0, 2.0);
|
||||
|
||||
box = my_thing_new (10, 10);
|
||||
|
||||
clutter_actor_set_position (box, 20, 20);
|
||||
clutter_actor_set_size (box, 350, -1);
|
||||
|
||||
icon = clutter_texture_new_from_file ("redhand.png", &error);
|
||||
if (error)
|
||||
g_error ("Unable to load 'redhand.png': %s", error->message);
|
||||
|
||||
for (i = 0; i < 33; i++)
|
||||
{
|
||||
ClutterActor *clone = create_item ();
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (box), clone);
|
||||
}
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
||||
|
||||
instructions = clutter_label_new_with_text ("Sans 14",
|
||||
"<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_label_set_use_markup (CLUTTER_LABEL (instructions), TRUE);
|
||||
clutter_actor_set_position (instructions, 450, 10);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), instructions);
|
||||
|
||||
g_signal_connect (stage, "key-release-event",
|
||||
G_CALLBACK (keypress_cb),
|
||||
NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (main_timeline);
|
||||
g_object_unref (behaviour);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
37
tests/interactive/test-main.c
Normal file
37
tests/interactive/test-main.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GModule *module;
|
||||
char *unit_test;
|
||||
char *main_symbol_name;
|
||||
int (*unit_test_main) (int argc, char **argv);
|
||||
int ret;
|
||||
|
||||
if (argc != 2)
|
||||
g_error ("Usage: %s unit_test");
|
||||
|
||||
module = g_module_open (NULL, 0);
|
||||
if (!module)
|
||||
g_error ("Failed to open self for symbol lookup");
|
||||
|
||||
unit_test = g_path_get_basename (argv[1]);
|
||||
|
||||
main_symbol_name = g_strdup_printf ("%s_main", unit_test);
|
||||
main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
|
||||
|
||||
if (!g_module_symbol (module, main_symbol_name, &unit_test_main))
|
||||
g_error ("Failed to look up main symbol for the test: %s", unit_test);
|
||||
|
||||
ret = unit_test_main (argc - 1, argv + 1);
|
||||
|
||||
g_free (unit_test);
|
||||
g_free (main_symbol_name);
|
||||
g_module_close (module);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
236
tests/interactive/test-model.c
Normal file
236
tests/interactive/test-model.c
Normal file
@ -0,0 +1,236 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
enum
|
||||
{
|
||||
COLUMN_FOO,
|
||||
COLUMN_BAR,
|
||||
|
||||
N_COLUMNS
|
||||
};
|
||||
|
||||
static void
|
||||
print_iter (ClutterModelIter *iter,
|
||||
const gchar *text)
|
||||
{
|
||||
ClutterModel *model;
|
||||
gint i;
|
||||
gchar *string;
|
||||
|
||||
model = clutter_model_iter_get_model (iter);
|
||||
|
||||
clutter_model_iter_get (iter, COLUMN_FOO, &i, COLUMN_BAR, &string, -1);
|
||||
|
||||
g_print ("[row:%02d]: %s: (%s: %d), (%s: %s)\n",
|
||||
clutter_model_iter_get_row (iter),
|
||||
text,
|
||||
clutter_model_get_column_name (model, COLUMN_FOO), i,
|
||||
clutter_model_get_column_name (model, COLUMN_BAR), string);
|
||||
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
foreach_func (ClutterModel *model,
|
||||
ClutterModelIter *iter,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint i;
|
||||
gchar *string;
|
||||
|
||||
clutter_model_iter_get (iter, COLUMN_FOO, &i, COLUMN_BAR, &string, -1);
|
||||
|
||||
g_print ("[row:%02d]: Foreach: %d, %s\n",
|
||||
clutter_model_iter_get_row (iter),
|
||||
i, string);
|
||||
|
||||
g_free (string);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
filter_func (ClutterModel *model,
|
||||
ClutterModelIter *iter,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint i = 0;
|
||||
|
||||
clutter_model_iter_get (iter, COLUMN_FOO, &i, -1);
|
||||
|
||||
return !(i % 2);
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_func (ClutterModel *model,
|
||||
const GValue *a,
|
||||
const GValue *b,
|
||||
gpointer dummy)
|
||||
{
|
||||
return -1 * strcmp (g_value_get_string (a), g_value_get_string (b));
|
||||
}
|
||||
|
||||
static void
|
||||
on_row_changed (ClutterModel *model,
|
||||
ClutterModelIter *iter)
|
||||
{
|
||||
print_iter (iter, "Changed");
|
||||
}
|
||||
|
||||
static void
|
||||
filter_model (ClutterModel *model)
|
||||
{
|
||||
ClutterModelIter *iter;
|
||||
|
||||
g_print ("\n* Filter function: even rows\n");
|
||||
clutter_model_set_filter (model, filter_func, NULL, NULL);
|
||||
|
||||
iter = clutter_model_get_first_iter (model);
|
||||
while (!clutter_model_iter_is_last (iter))
|
||||
{
|
||||
print_iter (iter, "Filtered Forward Iteration");
|
||||
|
||||
iter = clutter_model_iter_next (iter);
|
||||
}
|
||||
g_object_unref (iter);
|
||||
|
||||
g_print ("\n* Sorting function: reverse alpha\n");
|
||||
clutter_model_set_sort (model, COLUMN_BAR, sort_func, NULL, NULL);
|
||||
|
||||
g_signal_connect (model, "row-changed", G_CALLBACK (on_row_changed), NULL);
|
||||
|
||||
iter = clutter_model_get_iter_at_row (model, 0);
|
||||
clutter_model_iter_set (iter, COLUMN_BAR, "Changed string of 0th row, "
|
||||
"automatically gets sorted",
|
||||
-1);
|
||||
g_object_unref (iter);
|
||||
|
||||
clutter_model_foreach (model, foreach_func, NULL);
|
||||
|
||||
g_print ("\n* Unset filter\n");
|
||||
clutter_model_set_filter (model, NULL, NULL, NULL);
|
||||
|
||||
while (clutter_model_get_n_rows (model))
|
||||
clutter_model_remove (model, 0);
|
||||
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
iterate (ClutterModel *model)
|
||||
{
|
||||
ClutterModelIter *iter;
|
||||
|
||||
iter = clutter_model_get_first_iter (model);
|
||||
|
||||
while (!clutter_model_iter_is_last (iter))
|
||||
{
|
||||
print_iter (iter, "Forward Iteration");
|
||||
iter = clutter_model_iter_next (iter);
|
||||
}
|
||||
g_object_unref (iter);
|
||||
|
||||
iter = clutter_model_get_last_iter (model);
|
||||
do
|
||||
{
|
||||
print_iter (iter, "Reverse Iteration");
|
||||
iter = clutter_model_iter_prev (iter);
|
||||
}
|
||||
while (!clutter_model_iter_is_first (iter));
|
||||
|
||||
print_iter (iter, "Reverse Iteration");
|
||||
g_object_unref (iter);
|
||||
|
||||
filter_model (model);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
populate_model (ClutterModel *model)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
gchar *string = g_strdup_printf ("String %d", i);
|
||||
|
||||
clutter_model_append (model,
|
||||
COLUMN_FOO, i,
|
||||
COLUMN_BAR, string,
|
||||
-1);
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
clutter_model_foreach (model, foreach_func, NULL);
|
||||
iterate (model);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_row_added (ClutterModel *model,
|
||||
ClutterModelIter *iter,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint i;
|
||||
gchar *string;
|
||||
|
||||
clutter_model_iter_get (iter, COLUMN_FOO, &i, COLUMN_BAR, &string, -1);
|
||||
|
||||
g_print ("[row:%02d]: Added: %d, %s\n",
|
||||
clutter_model_iter_get_row (iter),
|
||||
i, string);
|
||||
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
static void
|
||||
on_row_removed (ClutterModel *model,
|
||||
ClutterModelIter *iter,
|
||||
gpointer dummy)
|
||||
{
|
||||
print_iter (iter, "Removed");
|
||||
}
|
||||
|
||||
static void
|
||||
on_sort_changed (ClutterModel *model)
|
||||
{
|
||||
g_print ("*** Sort Changed ***\n\n");
|
||||
clutter_model_foreach (model, foreach_func, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_filter_changed (ClutterModel *model)
|
||||
{
|
||||
g_print ("*** Filter Changed ***\n\n");
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_model_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterModel *model;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
model = clutter_list_model_new (N_COLUMNS,
|
||||
G_TYPE_INT, "Foo",
|
||||
G_TYPE_STRING, "Bar");
|
||||
|
||||
g_timeout_add (1000, (GSourceFunc) populate_model, model);
|
||||
|
||||
g_signal_connect (model, "row-added",
|
||||
G_CALLBACK (on_row_added), NULL);
|
||||
g_signal_connect (model, "row-removed",
|
||||
G_CALLBACK (on_row_removed), NULL);
|
||||
g_signal_connect (model, "sort-changed",
|
||||
G_CALLBACK (on_sort_changed), NULL);
|
||||
g_signal_connect (model, "filter-changed",
|
||||
G_CALLBACK (on_filter_changed), NULL);
|
||||
|
||||
clutter_main();
|
||||
|
||||
g_object_unref (model);
|
||||
|
||||
return 0;
|
||||
}
|
134
tests/interactive/test-multistage.c
Normal file
134
tests/interactive/test-multistage.c
Normal file
@ -0,0 +1,134 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static gint n_stages = 1;
|
||||
|
||||
static gboolean
|
||||
tex_button_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
clutter_actor_hide (actor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_button_press (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterActor *new_stage;
|
||||
ClutterActor *label, *tex;
|
||||
gint width, height;
|
||||
gchar *stage_label, *win_title;
|
||||
ClutterColor color = { 0xdd, 0x33, 0xdd, 0xff };
|
||||
ClutterColor white = { 0x99, 0x99, 0x99, 0xff };
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *r_behave;
|
||||
|
||||
new_stage = clutter_stage_new ();
|
||||
if (!new_stage)
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: below should really be automatic */
|
||||
/* clutter_stage_ensure_cogl_context (CLUTTER_STAGE(new_stage)); */
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (new_stage), &color);
|
||||
clutter_actor_set_size (new_stage, 320, 240);
|
||||
|
||||
tex = clutter_texture_new_from_file ("redhand.png", NULL);
|
||||
|
||||
if (!tex)
|
||||
g_error ("pixbuf load failed");
|
||||
|
||||
clutter_actor_set_reactive (tex, TRUE);
|
||||
g_signal_connect (tex, "button-press-event",
|
||||
G_CALLBACK (tex_button_cb), NULL);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (new_stage), tex);
|
||||
|
||||
stage_label = g_strdup_printf ("<b>Stage: %d</b>", ++n_stages);
|
||||
label = clutter_label_new_with_text ("Mono 12", stage_label);
|
||||
|
||||
clutter_label_set_color (CLUTTER_LABEL (label), &white);
|
||||
clutter_label_set_use_markup (CLUTTER_LABEL (label), TRUE);
|
||||
width = (clutter_actor_get_width (new_stage)
|
||||
- clutter_actor_get_width (label)) / 2;
|
||||
height = (clutter_actor_get_height (new_stage)
|
||||
- clutter_actor_get_height (label)) / 2;
|
||||
clutter_actor_set_position (label, width, height);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (new_stage), label);
|
||||
clutter_actor_show (label);
|
||||
g_free (stage_label);
|
||||
|
||||
/*
|
||||
g_signal_connect (new_stage, "button-press-event",
|
||||
G_CALLBACK (clutter_actor_destroy),
|
||||
NULL);
|
||||
*/
|
||||
|
||||
win_title = g_strdup_printf ("Stage:%p", new_stage);
|
||||
clutter_stage_set_title (CLUTTER_STAGE(new_stage), win_title);
|
||||
|
||||
timeline = clutter_timeline_new_for_duration (2000);
|
||||
g_object_set (timeline, "loop", TRUE, NULL);
|
||||
|
||||
alpha = clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL);
|
||||
|
||||
r_behave = clutter_behaviour_rotate_new (alpha,
|
||||
CLUTTER_Y_AXIS,
|
||||
CLUTTER_ROTATE_CW,
|
||||
0.0, 360.0);
|
||||
|
||||
clutter_behaviour_rotate_set_center (CLUTTER_BEHAVIOUR_ROTATE (r_behave),
|
||||
clutter_actor_get_width (label)/2,
|
||||
0,
|
||||
0);
|
||||
|
||||
clutter_behaviour_apply (r_behave, label);
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_actor_show_all (new_stage);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_multistage_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage_default;
|
||||
ClutterActor *label;
|
||||
gint width, height;
|
||||
gchar *win_title;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage_default = clutter_stage_get_default ();
|
||||
g_signal_connect (stage_default, "button-press-event",
|
||||
G_CALLBACK (on_button_press),
|
||||
NULL);
|
||||
|
||||
label = clutter_label_new_with_text ("Mono 16", "Default stage");
|
||||
width = (clutter_actor_get_width (stage_default)
|
||||
- clutter_actor_get_width (label))
|
||||
/ 2;
|
||||
height = (clutter_actor_get_height (stage_default)
|
||||
- clutter_actor_get_height (label))
|
||||
/ 2;
|
||||
clutter_actor_set_position (label, width, height);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage_default), label);
|
||||
clutter_actor_show (label);
|
||||
|
||||
win_title = g_strdup_printf ("Stage:%p", stage_default);
|
||||
clutter_stage_set_title (CLUTTER_STAGE(stage_default), win_title);
|
||||
|
||||
clutter_actor_show (stage_default);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
32
tests/interactive/test-offscreen.c
Normal file
32
tests/interactive/test-offscreen.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
/* Very simple test just to see what happens setting up offscreen rendering */
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_offscreen_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
gboolean offscreen;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
/* Attempt to set up rendering offscreen */
|
||||
g_object_set (stage, "offscreen", TRUE, NULL);
|
||||
|
||||
/* See if it worked */
|
||||
g_object_get (stage, "offscreen", &offscreen, NULL);
|
||||
|
||||
if (offscreen == FALSE)
|
||||
printf ("FAIL: Unable to setup offscreen rendering\n.");
|
||||
else
|
||||
printf ("SUCCESS: Able to setup offscreen rendering\n.");
|
||||
|
||||
clutter_actor_show_all (CLUTTER_ACTOR (stage));
|
||||
|
||||
clutter_main();
|
||||
|
||||
return 0;
|
||||
}
|
116
tests/interactive/test-opacity.c
Normal file
116
tests/interactive/test-opacity.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_opacity_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage, *group1, *group2, *label, *rect;
|
||||
ClutterColor label_color = { 255, 0, 0, 128 };
|
||||
ClutterColor rect_color = { 0, 0, 255, 255 };
|
||||
ClutterColor color_check = { 0, };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
label = clutter_label_new_with_text ("Sans 18px", "Label, 50% opacity");
|
||||
clutter_label_set_color (CLUTTER_LABEL (label), &label_color);
|
||||
|
||||
g_print ("label 50%%.get_color()/1\n");
|
||||
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL);
|
||||
clutter_actor_set_position (label, 10, 10);
|
||||
|
||||
g_print ("label 50%%.get_color()/2\n");
|
||||
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
g_print ("label 50%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (label));
|
||||
g_assert (clutter_actor_get_paint_opacity (label) == 128);
|
||||
|
||||
clutter_actor_show (label);
|
||||
|
||||
group1 = clutter_group_new ();
|
||||
clutter_actor_set_opacity (group1, 128);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), group1, NULL);
|
||||
clutter_actor_set_position (group1, 10, 30);
|
||||
clutter_actor_show (group1);
|
||||
|
||||
label = clutter_label_new_with_text ("Sans 18px", "Label+Group, 25% opacity");
|
||||
|
||||
clutter_label_set_color (CLUTTER_LABEL (label), &label_color);
|
||||
|
||||
g_print ("label 50%% + group 50%%.get_color()/1\n");
|
||||
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (group1), label, NULL);
|
||||
|
||||
g_print ("label 50%% + group 50%%.get_color()/2\n");
|
||||
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
g_print ("label 50%% + group 50%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (label));
|
||||
g_assert (clutter_actor_get_paint_opacity (label) == 64);
|
||||
|
||||
clutter_actor_show (label);
|
||||
|
||||
group2 = clutter_group_new ();
|
||||
clutter_container_add (CLUTTER_CONTAINER (group1), group2, NULL);
|
||||
clutter_actor_set_position (group2, 10, 60);
|
||||
clutter_actor_show (group2);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_actor_set_size (rect, 128, 128);
|
||||
|
||||
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/1\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (group2), rect, NULL);
|
||||
|
||||
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/2\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
g_print ("rect 100%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (rect));
|
||||
g_assert (clutter_actor_get_paint_opacity (rect) == 128);
|
||||
|
||||
clutter_actor_show (rect);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_actor_set_size (rect, 128, 128);
|
||||
clutter_actor_set_position (rect, 150, 90);
|
||||
|
||||
g_print ("rect 100%%.get_color()/1\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), rect, NULL);
|
||||
|
||||
g_print ("rect 100%%.get_color()/2\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
g_print ("rect 100%%.get_paint_opacity() = %d\n",
|
||||
clutter_actor_get_paint_opacity (rect));
|
||||
g_assert (clutter_actor_get_paint_opacity (rect) == 255);
|
||||
|
||||
clutter_actor_show (rect);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
300
tests/interactive/test-paint-wrapper.c
Normal file
300
tests/interactive/test-paint-wrapper.c
Normal file
@ -0,0 +1,300 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#if defined (_MSC_VER) && !defined (_USE_MATH_DEFINES)
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define TRAILS 0
|
||||
#define NHANDS 6
|
||||
#define RADIUS ((CLUTTER_STAGE_WIDTH()+CLUTTER_STAGE_HEIGHT())/NHANDS)
|
||||
|
||||
typedef struct SuperOH
|
||||
{
|
||||
ClutterActor **hand, *bgtex;
|
||||
ClutterActor *group;
|
||||
|
||||
} SuperOH;
|
||||
|
||||
static gint n_hands = NHANDS;
|
||||
|
||||
static GOptionEntry super_oh_entries[] = {
|
||||
{
|
||||
"num-hands", 'n',
|
||||
0,
|
||||
G_OPTION_ARG_INT, &n_hands,
|
||||
"Number of hands", "HANDS"
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static gint
|
||||
get_radius (void)
|
||||
{
|
||||
return (CLUTTER_STAGE_HEIGHT() + CLUTTER_STAGE_HEIGHT()) / n_hands ;
|
||||
}
|
||||
|
||||
/* input handler */
|
||||
static gboolean
|
||||
input_cb (ClutterStage *stage,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (event->type == CLUTTER_BUTTON_PRESS)
|
||||
{
|
||||
ClutterButtonEvent *button_event;
|
||||
ClutterActor *e;
|
||||
gint x, y;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
button_event = (ClutterButtonEvent *) event;
|
||||
g_print ("*** button press event (button:%d) ***\n",
|
||||
button_event->button);
|
||||
|
||||
e = clutter_stage_get_actor_at_pos (stage, x, y);
|
||||
|
||||
if (e && (CLUTTER_IS_TEXTURE (e) || CLUTTER_IS_CLONE_TEXTURE (e)))
|
||||
{
|
||||
clutter_actor_hide (e);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (event->type == CLUTTER_KEY_RELEASE)
|
||||
{
|
||||
ClutterKeyEvent *kev = (ClutterKeyEvent *) event;
|
||||
|
||||
g_print ("*** key press event (key:%c) ***\n",
|
||||
clutter_key_event_symbol (kev));
|
||||
|
||||
if (clutter_key_event_symbol (kev) == CLUTTER_q)
|
||||
{
|
||||
clutter_main_quit ();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Timeline handler */
|
||||
static void
|
||||
frame_cb (ClutterTimeline *timeline,
|
||||
gint frame_num,
|
||||
gpointer data)
|
||||
{
|
||||
SuperOH *oh = (SuperOH *)data;
|
||||
gint i;
|
||||
|
||||
/* Rotate everything clockwise about stage center*/
|
||||
|
||||
clutter_actor_set_rotation (CLUTTER_ACTOR (oh->group),
|
||||
CLUTTER_Z_AXIS,
|
||||
frame_num,
|
||||
CLUTTER_STAGE_WIDTH () / 2,
|
||||
CLUTTER_STAGE_HEIGHT () / 2,
|
||||
0);
|
||||
|
||||
for (i = 0; i < n_hands; i++)
|
||||
{
|
||||
gdouble scale_x, scale_y;
|
||||
|
||||
clutter_actor_get_scale (oh->hand[i], &scale_x, &scale_y);
|
||||
|
||||
/* Rotate each hand around there centers - to get this we need
|
||||
* to take into account any scaling.
|
||||
*
|
||||
* FIXME: scaling causes drift so disabled for now. Need rotation
|
||||
* unit based functions to fix.
|
||||
*/
|
||||
clutter_actor_set_rotation (oh->hand[i], CLUTTER_Z_AXIS,
|
||||
- 6.0 * frame_num, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean hand_pre_paint_guard = FALSE;
|
||||
|
||||
static void
|
||||
hand_pre_paint (ClutterActor *actor,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglColor red;
|
||||
guint w, h;
|
||||
|
||||
g_assert (hand_pre_paint_guard == FALSE);
|
||||
|
||||
clutter_actor_get_size (actor, &w, &h);
|
||||
|
||||
cogl_color_set_from_4ub (&red, 255, 0, 0, 128);
|
||||
cogl_color (&red);
|
||||
cogl_rectangle (0, 0, w / 2, h / 2);
|
||||
|
||||
hand_pre_paint_guard = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
hand_post_paint (ClutterActor *actor,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglColor green;
|
||||
guint w, h;
|
||||
|
||||
g_assert (hand_pre_paint_guard == TRUE);
|
||||
|
||||
clutter_actor_get_size (actor, &w, &h);
|
||||
|
||||
cogl_color_set_from_4ub (&green, 0, 255, 0, 128);
|
||||
cogl_color (&green);
|
||||
cogl_rectangle (w / 2, h / 2, w / 2, h / 2);
|
||||
|
||||
hand_pre_paint_guard = FALSE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_paint_wrapper_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *scaler_1, *scaler_2;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
|
||||
SuperOH *oh;
|
||||
gint i;
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
|
||||
clutter_init_with_args (&argc, &argv,
|
||||
NULL,
|
||||
super_oh_entries,
|
||||
NULL,
|
||||
&error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Unable to initialise Clutter:\n%s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 800, 600);
|
||||
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Actors Test");
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage),
|
||||
&stage_color);
|
||||
|
||||
oh = g_new(SuperOH, 1);
|
||||
|
||||
/* Create a timeline to manage animation */
|
||||
timeline = clutter_timeline_new (360, 60); /* num frames, fps */
|
||||
g_object_set (timeline, "loop", TRUE, NULL); /* have it loop */
|
||||
|
||||
/* fire a callback for frame change */
|
||||
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh);
|
||||
|
||||
/* Set up some behaviours to handle scaling */
|
||||
alpha = clutter_alpha_new_full (timeline, CLUTTER_ALPHA_SINE, NULL, NULL);
|
||||
|
||||
scaler_1 = clutter_behaviour_scale_new (alpha,
|
||||
0.5, 0.5,
|
||||
1.0, 1.0);
|
||||
|
||||
scaler_2 = clutter_behaviour_scale_new (alpha,
|
||||
1.0, 1.0,
|
||||
0.5, 0.5);
|
||||
|
||||
/* create a new group to hold multiple actors in a group */
|
||||
oh->group = clutter_group_new();
|
||||
|
||||
oh->hand = g_new (ClutterActor*, n_hands);
|
||||
for (i = 0; i < n_hands; i++)
|
||||
{
|
||||
gint x, y, w, h;
|
||||
gint radius = get_radius ();
|
||||
|
||||
/* Create a texture from file, then clone in to same resources */
|
||||
if (i == 0)
|
||||
{
|
||||
if ((oh->hand[i] = clutter_texture_new_from_file ("redhand.png",
|
||||
&error)) == NULL)
|
||||
{
|
||||
g_error ("image load failed: %s", error->message);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
oh->hand[i] = clutter_clone_texture_new (CLUTTER_TEXTURE(oh->hand[0]));
|
||||
|
||||
/* paint something before each hand */
|
||||
g_signal_connect (oh->hand[i],
|
||||
"paint", G_CALLBACK (hand_pre_paint),
|
||||
NULL);
|
||||
|
||||
/* paint something after each hand */
|
||||
g_signal_connect_after (oh->hand[i],
|
||||
"paint", G_CALLBACK (hand_post_paint),
|
||||
NULL);
|
||||
|
||||
/* Place around a circle */
|
||||
w = clutter_actor_get_width (oh->hand[0]);
|
||||
h = clutter_actor_get_height (oh->hand[0]);
|
||||
|
||||
x = CLUTTER_STAGE_WIDTH () / 2
|
||||
+ radius
|
||||
* cos (i * M_PI / (n_hands / 2))
|
||||
- w / 2;
|
||||
|
||||
y = CLUTTER_STAGE_HEIGHT () / 2
|
||||
+ radius
|
||||
* sin (i * M_PI / (n_hands / 2))
|
||||
- h / 2;
|
||||
|
||||
clutter_actor_set_position (oh->hand[i], x, y);
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (oh->hand[i],
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
/* Add to our group group */
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (oh->group), oh->hand[i]);
|
||||
|
||||
#if 1 /* FIXME: disabled as causes drift? - see comment above */
|
||||
if (i % 2)
|
||||
clutter_behaviour_apply (scaler_1, oh->hand[i]);
|
||||
else
|
||||
clutter_behaviour_apply (scaler_2, oh->hand[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add the group to the stage */
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage),
|
||||
CLUTTER_ACTOR (oh->group));
|
||||
|
||||
/* Show everying ( and map window ) */
|
||||
clutter_actor_show (stage);
|
||||
|
||||
|
||||
g_signal_connect (stage, "button-press-event",
|
||||
G_CALLBACK (input_cb),
|
||||
oh);
|
||||
g_signal_connect (stage, "key-release-event",
|
||||
G_CALLBACK (input_cb),
|
||||
oh);
|
||||
|
||||
/* and start it */
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_free (oh->hand);
|
||||
g_free (oh);
|
||||
|
||||
return 0;
|
||||
}
|
52
tests/interactive/test-perspective.c
Normal file
52
tests/interactive/test-perspective.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_perspective_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *rect;
|
||||
ClutterActor *stage;
|
||||
ClutterColor red = {0xff, 0, 0, 0xff}, white = {0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
g_object_set (stage, "fullscreen", TRUE, NULL);
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &red);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&white);
|
||||
clutter_actor_set_size (rect,
|
||||
clutter_actor_get_width(stage),
|
||||
clutter_actor_get_height(stage));
|
||||
clutter_actor_set_position (rect, 0, 0);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&red);
|
||||
clutter_actor_set_size (rect, 2, 2);
|
||||
clutter_actor_set_position (rect, 1, 1);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&red);
|
||||
clutter_actor_set_size (rect, 2, 2);
|
||||
clutter_actor_set_position (rect, clutter_actor_get_width(stage)-3, 1);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&red);
|
||||
clutter_actor_set_size (rect, 2, 2);
|
||||
clutter_actor_set_position (rect, 1, clutter_actor_get_height(stage)-3);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&red);
|
||||
clutter_actor_set_size (rect, 2, 2);
|
||||
clutter_actor_set_position (rect,
|
||||
clutter_actor_get_width(stage)-3,
|
||||
clutter_actor_get_height(stage)-3);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
clutter_actor_show_all (CLUTTER_ACTOR (stage));
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
263
tests/interactive/test-pixmap.c
Normal file
263
tests/interactive/test-pixmap.c
Normal file
@ -0,0 +1,263 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#if HAVE_CLUTTER_GLX
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <clutter/x11/clutter-x11-texture-pixmap.h>
|
||||
|
||||
#include <clutter/glx/clutter-glx.h>
|
||||
#include <clutter/glx/clutter-glx-texture-pixmap.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
#define IMAGE "redhand.png"
|
||||
|
||||
# ifdef USE_GDKPIXBUF
|
||||
# include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
static gboolean disable_x11 = FALSE;
|
||||
static gboolean disable_glx = FALSE;
|
||||
|
||||
static GOptionEntry g_options[] =
|
||||
{
|
||||
{ "disable-x11",
|
||||
0, 0,
|
||||
G_OPTION_ARG_NONE,
|
||||
&disable_x11,
|
||||
"Disable redirection through X11 pixmap",
|
||||
NULL },
|
||||
{ "disable-glx",
|
||||
0, 0,
|
||||
G_OPTION_ARG_NONE,
|
||||
&disable_glx,
|
||||
"Disable redirection through GLX pixmap",
|
||||
NULL },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static gboolean
|
||||
stage_key_release_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
switch (clutter_key_event_symbol (&event->key))
|
||||
{
|
||||
case CLUTTER_q:
|
||||
case CLUTTER_Q:
|
||||
clutter_main_quit ();
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stage_button_press_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
Pixmap pxm = (Pixmap)data;
|
||||
Display *dpy = clutter_x11_get_default_display ();
|
||||
GC gc;
|
||||
XGCValues gc_values = {0};
|
||||
|
||||
|
||||
gc = XCreateGC (dpy,
|
||||
pxm,
|
||||
0,
|
||||
&gc_values);
|
||||
|
||||
XDrawLine (dpy, pxm, gc, 0, 0, 100, 100);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Pixmap
|
||||
create_pixmap (guint *width, guint *height, guint *depth)
|
||||
{
|
||||
Display *dpy = clutter_x11_get_default_display ();
|
||||
Pixmap pixmap;
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *error = NULL;
|
||||
XImage *image;
|
||||
char *data, *d;
|
||||
guchar *p, *line, *endofline, *end;
|
||||
guint w, h, rowstride;
|
||||
GC gc;
|
||||
XGCValues gc_values = {0};
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file (IMAGE, &error);
|
||||
if (error)
|
||||
g_error (error->message);
|
||||
|
||||
/* We assume that the image had an alpha channel */
|
||||
g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
|
||||
|
||||
w = gdk_pixbuf_get_width (pixbuf);
|
||||
h = gdk_pixbuf_get_height (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
data = g_malloc (w * h * 4);
|
||||
image = XCreateImage (dpy,
|
||||
None,
|
||||
32,
|
||||
ZPixmap,
|
||||
0,
|
||||
data,
|
||||
w, h,
|
||||
8,
|
||||
w * 4);
|
||||
|
||||
p = gdk_pixbuf_get_pixels (pixbuf);
|
||||
d = data;
|
||||
end = p + rowstride*h;
|
||||
|
||||
/* Convert from RGBA as contained in the pixmap to ARGB as used in X */
|
||||
for (line = p; line < end ; line += rowstride)
|
||||
{
|
||||
p = line;
|
||||
endofline = p + 4 * w;
|
||||
|
||||
for (p = line; p < endofline; p += 4, d+=4)
|
||||
{
|
||||
|
||||
# define r ((guint32)(*(p)))
|
||||
# define g ((guint32)(*(p+1)))
|
||||
# define b ((guint32)(*(p+2)))
|
||||
# define a ((guint32)(*(p+3)))
|
||||
guint32 pixel =
|
||||
((a << 24) & 0xFF000000 ) |
|
||||
((r << 16) & 0x00FF0000 ) |
|
||||
((g << 8) & 0x0000FF00) |
|
||||
((b) & 0x000000FF );
|
||||
|
||||
*((guint32 *)d) = pixel;
|
||||
|
||||
}
|
||||
# undef r
|
||||
# undef g
|
||||
# undef b
|
||||
# undef a
|
||||
|
||||
}
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
pixmap = XCreatePixmap (dpy,
|
||||
DefaultRootWindow (dpy),
|
||||
w, h,
|
||||
32);
|
||||
|
||||
gc = XCreateGC (dpy,
|
||||
pixmap,
|
||||
0,
|
||||
&gc_values);
|
||||
|
||||
XPutImage (dpy,
|
||||
pixmap,
|
||||
gc,
|
||||
image,
|
||||
0, 0,
|
||||
0, 0,
|
||||
w, h);
|
||||
|
||||
XFreeGC (dpy, gc);
|
||||
XDestroyImage (image);
|
||||
|
||||
if (width) *width = w;
|
||||
if (height) *height = h;
|
||||
if (depth) *depth = 32;
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
# endif /* USE_GDKPIXBUF */
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_pixmap_main (int argc, char **argv)
|
||||
{
|
||||
#ifdef USE_GDKPIXBUF
|
||||
GOptionContext *context;
|
||||
ClutterActor *stage, *tex;
|
||||
Pixmap pixmap;
|
||||
const ClutterColor gry = { 0x99, 0x99, 0x99, 0xFF };
|
||||
Window win_remote;
|
||||
guint w, h, d;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
context = g_option_context_new (" - text-pixmap options");
|
||||
g_option_context_add_main_entries (context, g_options, NULL);
|
||||
g_option_context_parse (context, &argc, &argv, NULL);
|
||||
|
||||
if (argc < 2)
|
||||
g_error ("usage: %s <window id>", argv[0]);
|
||||
|
||||
win_remote = strtol (argv[1], NULL, 0);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &gry);
|
||||
|
||||
/* a pixmap */
|
||||
pixmap = create_pixmap (&w, &h, &d);
|
||||
|
||||
tex = clutter_x11_texture_pixmap_new_with_pixmap (pixmap);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), tex);
|
||||
/* oddly, the actor's size is 0 until it is realized, even though
|
||||
pixmap-height is set */
|
||||
clutter_actor_set_position (tex, 0,
|
||||
clutter_actor_get_height (stage)
|
||||
- clutter_actor_get_height (tex));
|
||||
|
||||
/* a window */
|
||||
if (!disable_x11)
|
||||
{
|
||||
tex = clutter_x11_texture_pixmap_new_with_window (win_remote);
|
||||
|
||||
clutter_actor_set_position (tex, 0, 0);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), tex);
|
||||
|
||||
clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (tex),
|
||||
TRUE);
|
||||
}
|
||||
|
||||
# ifdef HAVE_CLUTTER_GLX
|
||||
/* a window with glx */
|
||||
if (!disable_glx)
|
||||
{
|
||||
tex = clutter_glx_texture_pixmap_new_with_window (win_remote);
|
||||
|
||||
clutter_actor_set_position (tex,
|
||||
clutter_actor_get_width (stage)
|
||||
- clutter_actor_get_width (tex),
|
||||
0);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), tex);
|
||||
|
||||
clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (tex),
|
||||
TRUE);
|
||||
}
|
||||
#endif /* HAVE_CLUTTER_GLX */
|
||||
|
||||
g_signal_connect (stage, "key-release-event",
|
||||
G_CALLBACK (stage_key_release_cb), (gpointer)pixmap);
|
||||
g_signal_connect (stage, "button-press-event",
|
||||
G_CALLBACK (stage_button_press_cb), (gpointer)pixmap);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
# endif /* USE_GDKPIXBUF */
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#else /* HAVE_CLUTTER_GLX */
|
||||
int main (int argc, char **argv) { return EXIT_SUCCESS; };
|
||||
#endif /* HAVE_CLUTTER_GLX */
|
242
tests/interactive/test-project.c
Normal file
242
tests/interactive/test-project.c
Normal file
@ -0,0 +1,242 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
static ClutterActor *main_stage, *rect, *p[5];
|
||||
|
||||
static void
|
||||
init_handles ()
|
||||
{
|
||||
gint i;
|
||||
ClutterVertex v[4];
|
||||
ClutterVertex v1, v2;
|
||||
ClutterColor blue = { 0, 0, 0xff, 0xff };
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (rect, v);
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
p[i] = clutter_rectangle_new_with_color (&blue);
|
||||
clutter_actor_set_size (p[i], 5, 5);
|
||||
clutter_actor_set_position (p[i], 0, 0);
|
||||
clutter_group_add (CLUTTER_GROUP (main_stage), p[i]);
|
||||
|
||||
clutter_actor_set_position (p[i],
|
||||
CLUTTER_FIXED_TO_INT (v[i].x) -
|
||||
clutter_actor_get_width (p[i])/2,
|
||||
CLUTTER_FIXED_TO_INT (v[i].y) -
|
||||
clutter_actor_get_height (p[i])/2);
|
||||
|
||||
clutter_actor_raise_top (p[i]);
|
||||
|
||||
clutter_actor_show (p[i]);
|
||||
}
|
||||
|
||||
v1.x = CLUTTER_INT_TO_FIXED (clutter_actor_get_width (rect)/2);
|
||||
v1.y = CLUTTER_INT_TO_FIXED (clutter_actor_get_height (rect)/2);
|
||||
v1.z = 0;
|
||||
|
||||
clutter_actor_apply_transform_to_point (rect, &v1, &v2);
|
||||
p[4] = clutter_rectangle_new_with_color (&blue);
|
||||
clutter_actor_set_size (p[4], 5, 5);
|
||||
clutter_actor_set_position (p[4], 0, 0);
|
||||
clutter_group_add (CLUTTER_GROUP (main_stage), p[4]);
|
||||
clutter_actor_set_position (p[4],
|
||||
CLUTTER_FIXED_TO_INT (v2.x) -
|
||||
clutter_actor_get_width (p[4])/2,
|
||||
CLUTTER_FIXED_TO_INT (v2.y) -
|
||||
clutter_actor_get_height (p[4])/2);
|
||||
|
||||
clutter_actor_raise_top (p[4]);
|
||||
|
||||
clutter_actor_show (p[4]);
|
||||
}
|
||||
|
||||
static void
|
||||
place_handles ()
|
||||
{
|
||||
gint i;
|
||||
ClutterVertex v[4];
|
||||
ClutterVertex v1, v2;
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (rect, v);
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
clutter_actor_set_position (p[i],
|
||||
CLUTTER_FIXED_TO_INT (v[i].x) -
|
||||
clutter_actor_get_width (p[i])/2,
|
||||
CLUTTER_FIXED_TO_INT (v[i].y) -
|
||||
clutter_actor_get_height (p[i])/2);
|
||||
}
|
||||
|
||||
v1.x = CLUTTER_INT_TO_FIXED (clutter_actor_get_width (rect)/2);
|
||||
v1.y = CLUTTER_INT_TO_FIXED (clutter_actor_get_height (rect)/2);
|
||||
v1.z = 0;
|
||||
|
||||
clutter_actor_apply_transform_to_point (rect, &v1, &v2);
|
||||
clutter_actor_set_position (p[4],
|
||||
CLUTTER_FIXED_TO_INT (v2.x) -
|
||||
clutter_actor_get_width (p[4])/2,
|
||||
CLUTTER_FIXED_TO_INT (v2.y) -
|
||||
clutter_actor_get_height (p[4])/2);
|
||||
}
|
||||
|
||||
#define M(m,row,col) (m)[col*4+row]
|
||||
|
||||
static gint
|
||||
find_handle_index (ClutterActor * a)
|
||||
{
|
||||
gint i;
|
||||
for (i = 0; i < sizeof(p)/sizeof(p[0]); ++i)
|
||||
if (p[i] == a)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_event (ClutterStage *stage,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
static ClutterActor * dragging = NULL;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
{
|
||||
gint x, y;
|
||||
ClutterActor * actor;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
actor = clutter_stage_get_actor_at_pos (stage, x, y);
|
||||
|
||||
if (actor != CLUTTER_ACTOR (stage))
|
||||
{
|
||||
if (actor != rect)
|
||||
dragging = actor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
{
|
||||
if (dragging)
|
||||
{
|
||||
gint x, y;
|
||||
gint i;
|
||||
ClutterActorBox box1, box2;
|
||||
ClutterFixed xp, yp;
|
||||
|
||||
i = find_handle_index (dragging);
|
||||
|
||||
if (i < 0)
|
||||
break;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
clutter_actor_get_allocation_box (dragging, &box1);
|
||||
clutter_actor_get_allocation_box (rect, &box2);
|
||||
|
||||
xp = CLUTTER_INT_TO_FIXED (x-3) - box1.x1;
|
||||
yp = CLUTTER_INT_TO_FIXED (y-3) - box1.y1;
|
||||
|
||||
if (i == 4)
|
||||
{
|
||||
g_debug ("moving box by %f, %f",
|
||||
CLUTTER_FIXED_TO_FLOAT (xp),
|
||||
CLUTTER_FIXED_TO_FLOAT (yp));
|
||||
|
||||
clutter_actor_move_by (rect,
|
||||
CLUTTER_FIXED_TO_INT(xp),
|
||||
CLUTTER_FIXED_TO_INT(yp));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("adjusting box by %f, %f, handle %d",
|
||||
CLUTTER_FIXED_TO_FLOAT (xp),
|
||||
CLUTTER_FIXED_TO_FLOAT (yp),
|
||||
i);
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
box2.x1 += xp;
|
||||
box2.y1 += yp;
|
||||
break;
|
||||
case 1:
|
||||
box2.x2 += xp;
|
||||
box2.y1 += yp;
|
||||
break;
|
||||
case 2:
|
||||
box2.x1 += xp;
|
||||
box2.y2 += yp;
|
||||
break;
|
||||
case 3:
|
||||
box2.x2 += xp;
|
||||
box2.y2 += yp;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME this is just plain wrong, to allocate directly
|
||||
* like this
|
||||
*/
|
||||
clutter_actor_allocate (rect, &box2, TRUE);
|
||||
}
|
||||
|
||||
place_handles ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
{
|
||||
dragging = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_project_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *label;
|
||||
|
||||
ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff },
|
||||
white = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
main_stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (main_stage), &stage_color);
|
||||
clutter_actor_set_size (main_stage, 640, 480);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&white);
|
||||
clutter_actor_set_size (rect, 320, 240);
|
||||
clutter_actor_set_position (rect, 180, 120);
|
||||
clutter_actor_set_rotation (rect, CLUTTER_Y_AXIS, 60, 0, 0, 0);
|
||||
clutter_group_add (CLUTTER_GROUP (main_stage), rect);
|
||||
|
||||
label = clutter_label_new_with_text ("Mono 8pt", "Drag the blue rectangles");
|
||||
clutter_label_set_color (CLUTTER_LABEL (label), &white);
|
||||
|
||||
clutter_actor_set_position (label, 10, 10);
|
||||
clutter_group_add (CLUTTER_GROUP (main_stage), label);
|
||||
|
||||
clutter_actor_show_all (main_stage);
|
||||
|
||||
g_signal_connect (main_stage, "event", G_CALLBACK (on_event), NULL);
|
||||
|
||||
init_handles ();
|
||||
|
||||
clutter_main();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
86
tests/interactive/test-random-text.c
Normal file
86
tests/interactive/test-random-text.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_TEXT_LEN 10
|
||||
#define MIN_FONT_SIZE 10
|
||||
#define MAX_FONT_SIZE 30
|
||||
|
||||
static const char * const font_names[] =
|
||||
{
|
||||
"Sans", "Sans Italic", "Serif", "Serif Bold", "Times", "Monospace"
|
||||
};
|
||||
#define FONT_NAME_COUNT 6
|
||||
|
||||
static gboolean
|
||||
on_idle (gpointer data)
|
||||
{
|
||||
ClutterActor *stage = CLUTTER_ACTOR (data);
|
||||
int line_height = 0, xpos = 0, ypos = 0;
|
||||
int stage_width = clutter_actor_get_width (stage);
|
||||
int stage_height = clutter_actor_get_height (stage);
|
||||
char text[MAX_TEXT_LEN + 1];
|
||||
char font_name[64];
|
||||
int i;
|
||||
GList *children, *node;
|
||||
|
||||
/* Remove all of the children of the stage */
|
||||
children = clutter_container_get_children (CLUTTER_CONTAINER (stage));
|
||||
for (node = children; node; node = node->next)
|
||||
clutter_container_remove_actor (CLUTTER_CONTAINER (stage),
|
||||
CLUTTER_ACTOR (node->data));
|
||||
g_list_free (children);
|
||||
|
||||
/* Fill the stage with new random labels */
|
||||
while (ypos < stage_height)
|
||||
{
|
||||
int text_len = rand () % MAX_TEXT_LEN + 1;
|
||||
ClutterActor *label;
|
||||
|
||||
for (i = 0; i < text_len; i++)
|
||||
text[i] = rand () % (128 - 32) + 32;
|
||||
text[text_len] = '\0';
|
||||
|
||||
sprintf (font_name, "%s %i",
|
||||
font_names[rand () % FONT_NAME_COUNT],
|
||||
rand () % (MAX_FONT_SIZE - MIN_FONT_SIZE) + MIN_FONT_SIZE);
|
||||
|
||||
label = clutter_label_new_with_text (font_name, text);
|
||||
|
||||
if (clutter_actor_get_height (label) > line_height)
|
||||
line_height = clutter_actor_get_height (label);
|
||||
|
||||
if (xpos + clutter_actor_get_width (label) > stage_width)
|
||||
{
|
||||
xpos = 0;
|
||||
ypos += line_height;
|
||||
line_height = 0;
|
||||
}
|
||||
|
||||
clutter_actor_set_position (label, xpos, ypos);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL);
|
||||
|
||||
xpos += clutter_actor_get_width (label);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_random_text_main (int argc, char **argv)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_threads_add_idle (on_idle, stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
75
tests/interactive/test-rotate.c
Normal file
75
tests/interactive/test-rotate.c
Normal file
@ -0,0 +1,75 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_rotate_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *r_behave;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *hand, *label;
|
||||
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage),
|
||||
&stage_color);
|
||||
|
||||
/* Make a hand */
|
||||
hand = clutter_texture_new_from_file ("redhand.png", NULL);
|
||||
if (!hand)
|
||||
g_error("pixbuf load failed");
|
||||
|
||||
clutter_actor_set_position (hand, 240, 140);
|
||||
clutter_actor_show (hand);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), hand);
|
||||
|
||||
label = clutter_label_new_with_text ("Mono 16", "The Wonder of the Spinning Hand");
|
||||
clutter_label_set_alignment (CLUTTER_LABEL (label), PANGO_ALIGN_CENTER);
|
||||
clutter_actor_set_position (label, 150, 150);
|
||||
clutter_actor_set_size (label, 500, 100);
|
||||
clutter_actor_show (label);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
|
||||
|
||||
/* Make a timeline */
|
||||
timeline = clutter_timeline_new (200, 26); /* num frames, fps */
|
||||
g_object_set (timeline, "loop", TRUE, NULL);
|
||||
|
||||
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
|
||||
alpha = clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL);
|
||||
|
||||
/* Create a behaviour for that alpha */
|
||||
r_behave = clutter_behaviour_rotate_new (alpha,
|
||||
CLUTTER_Z_AXIS,
|
||||
CLUTTER_ROTATE_CW,
|
||||
0.0, 360.0);
|
||||
|
||||
clutter_behaviour_rotate_set_center (CLUTTER_BEHAVIOUR_ROTATE (r_behave),
|
||||
86, 125, 0);
|
||||
|
||||
/* Apply it to our actor */
|
||||
clutter_behaviour_apply (r_behave, hand);
|
||||
clutter_behaviour_apply (r_behave, label);
|
||||
|
||||
/* start the timeline and thus the animations */
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main();
|
||||
|
||||
g_object_unref (r_behave);
|
||||
|
||||
return 0;
|
||||
}
|
87
tests/interactive/test-scale.c
Normal file
87
tests/interactive/test-scale.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static const ClutterGravity gravities[] = {
|
||||
CLUTTER_GRAVITY_NORTH_EAST,
|
||||
CLUTTER_GRAVITY_NORTH,
|
||||
CLUTTER_GRAVITY_NORTH_WEST,
|
||||
CLUTTER_GRAVITY_WEST,
|
||||
CLUTTER_GRAVITY_SOUTH_WEST,
|
||||
CLUTTER_GRAVITY_SOUTH,
|
||||
CLUTTER_GRAVITY_SOUTH_EAST,
|
||||
CLUTTER_GRAVITY_EAST,
|
||||
CLUTTER_GRAVITY_CENTER,
|
||||
CLUTTER_GRAVITY_NONE
|
||||
};
|
||||
|
||||
static gint gindex = 0;
|
||||
|
||||
static void
|
||||
on_timeline_completed (ClutterTimeline *cluttertimeline,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (data);
|
||||
|
||||
if (++gindex >= G_N_ELEMENTS (gravities))
|
||||
gindex = 0;
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (actor, gravities[gindex]);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_scale_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage, *rect;
|
||||
ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
ClutterColor rect_color = { 0xff, 0xff, 0xff, 0x99 };
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *behave;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_actor_set_size (stage, 300, 300);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_actor_set_size (rect, 100, 100);
|
||||
clutter_actor_set_position (rect, 100, 100);
|
||||
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
rect_color.alpha = 0xff;
|
||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_actor_set_position (rect, 100, 100);
|
||||
clutter_actor_set_size (rect, 100, 100);
|
||||
clutter_actor_move_anchor_point_from_gravity (rect, CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
timeline = clutter_timeline_new_for_duration (750);
|
||||
alpha = clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP,
|
||||
NULL, NULL);
|
||||
|
||||
behave = clutter_behaviour_scale_new (alpha,
|
||||
0.0, 0.0, /* scale start */
|
||||
1.0, 1.0); /* scale end */
|
||||
|
||||
clutter_behaviour_apply (behave, rect);
|
||||
|
||||
clutter_timeline_set_loop (timeline, TRUE);
|
||||
g_signal_connect (timeline, "completed",
|
||||
G_CALLBACK(on_timeline_completed), rect);
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main();
|
||||
|
||||
g_object_unref (timeline);
|
||||
g_object_unref (behave);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
111
tests/interactive/test-score.c
Normal file
111
tests/interactive/test-score.c
Normal file
@ -0,0 +1,111 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static gint level = 1;
|
||||
|
||||
static void
|
||||
on_timeline_started (ClutterScore *score,
|
||||
ClutterTimeline *timeline)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < level; i++)
|
||||
g_print (" ");
|
||||
|
||||
g_print ("Started timeline: `%s'\n",
|
||||
(gchar *) g_object_get_data (G_OBJECT (timeline), "timeline-name"));
|
||||
|
||||
level += 1;
|
||||
}
|
||||
|
||||
static void
|
||||
on_timeline_completed (ClutterScore *score,
|
||||
ClutterTimeline *timeline)
|
||||
{
|
||||
gint i;
|
||||
|
||||
level -= 1;
|
||||
|
||||
for (i = 0; i < level; i++)
|
||||
g_print (" ");
|
||||
|
||||
g_print ("Completed timeline: `%s'\n",
|
||||
(gchar *) g_object_get_data (G_OBJECT (timeline), "timeline-name"));
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_score_main (int argc, char **argv)
|
||||
{
|
||||
ClutterScore *score;
|
||||
ClutterTimeline *timeline_1;
|
||||
ClutterTimeline *timeline_2;
|
||||
ClutterTimeline *timeline_3;
|
||||
ClutterTimeline *timeline_4;
|
||||
ClutterTimeline *timeline_5;
|
||||
GSList *timelines;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
timeline_1 = clutter_timeline_new_for_duration (1000);
|
||||
g_object_set_data_full (G_OBJECT (timeline_1),
|
||||
"timeline-name", g_strdup ("Timeline 1"),
|
||||
g_free);
|
||||
|
||||
timeline_2 = clutter_timeline_new_for_duration (1000);
|
||||
clutter_timeline_add_marker_at_time (timeline_2, "foo", 500);
|
||||
g_object_set_data_full (G_OBJECT (timeline_2),
|
||||
"timeline-name", g_strdup ("Timeline 2"),
|
||||
g_free);
|
||||
|
||||
timeline_3 = clutter_timeline_new_for_duration (1000);
|
||||
g_object_set_data_full (G_OBJECT (timeline_3),
|
||||
"timeline-name", g_strdup ("Timeline 3"),
|
||||
g_free);
|
||||
|
||||
timeline_4 = clutter_timeline_new_for_duration (1000);
|
||||
g_object_set_data_full (G_OBJECT (timeline_4),
|
||||
"timeline-name", g_strdup ("Timeline 4"),
|
||||
g_free);
|
||||
|
||||
timeline_5 = clutter_timeline_new_for_duration (1000);
|
||||
g_object_set_data_full (G_OBJECT (timeline_5),
|
||||
"timeline-name", g_strdup ("Timeline 5"),
|
||||
g_free);
|
||||
|
||||
score = clutter_score_new();
|
||||
g_signal_connect (score, "timeline-started",
|
||||
G_CALLBACK (on_timeline_started),
|
||||
NULL);
|
||||
g_signal_connect (score, "timeline-completed",
|
||||
G_CALLBACK (on_timeline_completed),
|
||||
NULL);
|
||||
g_signal_connect (score, "completed",
|
||||
G_CALLBACK (clutter_main_quit),
|
||||
NULL);
|
||||
|
||||
clutter_score_append (score, NULL, timeline_1);
|
||||
clutter_score_append (score, timeline_1, timeline_2);
|
||||
clutter_score_append (score, timeline_1, timeline_3);
|
||||
clutter_score_append (score, timeline_3, timeline_4);
|
||||
|
||||
clutter_score_append_at_marker (score, timeline_2, "foo", timeline_5);
|
||||
|
||||
timelines = clutter_score_list_timelines (score);
|
||||
g_assert (5 == g_slist_length (timelines));
|
||||
g_slist_free (timelines);
|
||||
|
||||
clutter_score_start (score);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (timeline_1);
|
||||
g_object_unref (timeline_2);
|
||||
g_object_unref (timeline_3);
|
||||
g_object_unref (timeline_4);
|
||||
g_object_unref (timeline_5);
|
||||
g_object_unref (score);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
173
tests/interactive/test-script.c
Normal file
173
tests/interactive/test-script.c
Normal file
@ -0,0 +1,173 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static ClutterScript *script = NULL;
|
||||
static guint merge_id = 0;
|
||||
|
||||
static const gchar *test_unmerge =
|
||||
"["
|
||||
" {"
|
||||
" \"id\" : \"main-stage\","
|
||||
" \"type\" : \"ClutterStage\","
|
||||
" \"children\" : [ \"blue-button\" ]"
|
||||
" },"
|
||||
" {"
|
||||
" \"id\" : \"blue-button\","
|
||||
" \"type\" : \"ClutterRectangle\","
|
||||
" \"color\" : \"#0000ffff\","
|
||||
" \"x\" : 350,"
|
||||
" \"y\" : 50,"
|
||||
" \"width\" : 100,"
|
||||
" \"height\" : 100,"
|
||||
" \"visible\" : true,"
|
||||
" \"reactive\" : true"
|
||||
" }"
|
||||
"]";
|
||||
|
||||
static const gchar *test_behaviour =
|
||||
"["
|
||||
" {"
|
||||
" \"id\" : \"main-timeline\","
|
||||
" \"type\" : \"ClutterTimeline\","
|
||||
" \"duration\" : 5000,"
|
||||
" \"loop\" : true"
|
||||
" },"
|
||||
" {"
|
||||
" \"id\" : \"path-behaviour\","
|
||||
" \"type\" : \"ClutterBehaviourPath\","
|
||||
" \"knots\" : [ [ 50, 50 ], { \"x\" : 100, \"y\" : 100 } ],"
|
||||
" \"alpha\" : {"
|
||||
" \"timeline\" : \"main-timeline\","
|
||||
" \"function\" : \"ramp\""
|
||||
" }"
|
||||
" },"
|
||||
" {"
|
||||
" \"id\" : \"rotate-behaviour\","
|
||||
" \"type\" : \"ClutterBehaviourRotate\","
|
||||
" \"angle-start\" : 0.0,"
|
||||
" \"angle-end\" : 360.0,"
|
||||
" \"axis\" : \"y-axis\","
|
||||
" \"alpha\" : {"
|
||||
" \"timeline\" : \"main-timeline\","
|
||||
" \"function\" : \"sine\""
|
||||
" }"
|
||||
" },"
|
||||
" {"
|
||||
" \"id\" : \"fade-behaviour\","
|
||||
" \"type\" : \"ClutterBehaviourOpacity\","
|
||||
" \"opacity-start\" : 255,"
|
||||
" \"opacity-end\" : 0,"
|
||||
" \"alpha\" : {"
|
||||
" \"timeline\" : \"main-timeline\","
|
||||
" \"function\" : \"ramp-inc\""
|
||||
" }"
|
||||
" }"
|
||||
"]";
|
||||
|
||||
static gboolean
|
||||
blue_button_press (ClutterActor *actor,
|
||||
ClutterButtonEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
g_print ("[*] Pressed `%s'\n", clutter_get_script_id (G_OBJECT (actor)));
|
||||
g_print ("[*] Unmerging objects with merge id: %d\n", merge_id);
|
||||
|
||||
clutter_script_unmerge_objects (script, merge_id);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
red_button_press (ClutterActor *actor,
|
||||
ClutterButtonEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
GObject *timeline;
|
||||
|
||||
g_print ("[*] Pressed `%s'\n", clutter_get_script_id (G_OBJECT (actor)));
|
||||
|
||||
timeline = clutter_script_get_object (script, "main-timeline");
|
||||
g_assert (CLUTTER_IS_TIMELINE (timeline));
|
||||
|
||||
if (!clutter_timeline_is_playing (CLUTTER_TIMELINE (timeline)))
|
||||
clutter_timeline_start (CLUTTER_TIMELINE (timeline));
|
||||
else
|
||||
clutter_timeline_pause (CLUTTER_TIMELINE (timeline));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_script_main (int argc, char *argv[])
|
||||
{
|
||||
GObject *stage, *blue_button, *red_button;
|
||||
GError *error = NULL;
|
||||
gint res;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
script = clutter_script_new ();
|
||||
g_assert (CLUTTER_IS_SCRIPT (script));
|
||||
|
||||
clutter_script_load_from_data (script, test_behaviour, -1, &error);
|
||||
if (error)
|
||||
{
|
||||
g_print ("*** Error:\n"
|
||||
"*** %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (script);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
clutter_script_load_from_file (script, "test-script.json", &error);
|
||||
if (error)
|
||||
{
|
||||
g_print ("*** Error:\n"
|
||||
"*** %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (script);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
merge_id = clutter_script_load_from_data (script, test_unmerge, -1, &error);
|
||||
if (error)
|
||||
{
|
||||
g_print ("*** Error:\n"
|
||||
"*** %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (script);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
clutter_script_connect_signals (script, NULL);
|
||||
|
||||
res = clutter_script_get_objects (script,
|
||||
"main-stage", &stage,
|
||||
"red-button", &red_button,
|
||||
"blue-button", &blue_button,
|
||||
NULL);
|
||||
g_assert (res == 3);
|
||||
|
||||
clutter_actor_show (CLUTTER_ACTOR (stage));
|
||||
|
||||
g_signal_connect (red_button,
|
||||
"button-press-event",
|
||||
G_CALLBACK (red_button_press),
|
||||
NULL);
|
||||
|
||||
g_signal_connect (blue_button,
|
||||
"button-press-event",
|
||||
G_CALLBACK (blue_button_press),
|
||||
NULL);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (script);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
399
tests/interactive/test-shader.c
Normal file
399
tests/interactive/test-shader.c
Normal file
@ -0,0 +1,399 @@
|
||||
/*#define TEST_GROUP */
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include "../config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
/* Dynamic branching appeared in "Shader Model 3.0" that low-end IGPs
|
||||
* don't support.
|
||||
*/
|
||||
#define GPU_SUPPORTS_DYNAMIC_BRANCHING 0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *name;
|
||||
gchar *source;
|
||||
} ShaderSource;
|
||||
|
||||
/* These variables are used instead of the standard GLSL variables on
|
||||
GLES 2 */
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
||||
#define GLES2_VARS \
|
||||
"precision mediump float;\n" \
|
||||
"varying vec2 tex_coord;\n" \
|
||||
"varying vec4 frag_color;\n"
|
||||
#define TEX_COORD "tex_coord"
|
||||
#define COLOR_VAR "frag_color"
|
||||
|
||||
#else /* HAVE_COGL_GLES2 */
|
||||
|
||||
#define GLES2_VARS ""
|
||||
#define TEX_COORD "gl_TexCoord[0]"
|
||||
#define COLOR_VAR "gl_Color"
|
||||
|
||||
#endif /* HAVE_COGL_GLES2 */
|
||||
|
||||
/* a couple of boilerplate defines that are common amongst all the
|
||||
* sample shaders
|
||||
*/
|
||||
|
||||
/* FRAGMENT_SHADER_BEGIN: generate boilerplate with a local vec4 color already
|
||||
* initialized, from a sampler2D in a variable tex.
|
||||
*/
|
||||
#define FRAGMENT_SHADER_VARS \
|
||||
GLES2_VARS \
|
||||
"uniform sampler2D tex;" \
|
||||
"uniform float x_step, y_step;" \
|
||||
|
||||
#define FRAGMENT_SHADER_BEGIN \
|
||||
"void main (){" \
|
||||
" vec4 color = texture2D (tex, vec2(" TEX_COORD "));"
|
||||
|
||||
/* FRAGMENT_SHADER_END: apply the changed color to the output buffer correctly
|
||||
* blended with the gl specified color (makes the opacity of actors work
|
||||
* correctly).
|
||||
*/
|
||||
#define FRAGMENT_SHADER_END \
|
||||
" gl_FragColor = color;" \
|
||||
" gl_FragColor = gl_FragColor * " COLOR_VAR ";" \
|
||||
"}"
|
||||
|
||||
static ShaderSource shaders[]=
|
||||
{
|
||||
{"brightness-contrast",
|
||||
FRAGMENT_SHADER_VARS
|
||||
"uniform float brightness, contrast;"
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
" color.rgb = (color.rgb - vec3(0.5, 0.5, 0.5)) * contrast + "
|
||||
"vec3 (brightness + 0.5, brightness + 0.5, brightness + 0.5);"
|
||||
FRAGMENT_SHADER_END
|
||||
},
|
||||
|
||||
{"box-blur",
|
||||
FRAGMENT_SHADER_VARS
|
||||
|
||||
#if GPU_SUPPORTS_DYNAMIC_BRANCHING
|
||||
"uniform float radius;"
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
"float u, v;"
|
||||
"int count = 1;"
|
||||
"for (u=-radius;u<radius;u++)"
|
||||
" for (v=-radius;v<radius;v++)"
|
||||
" {"
|
||||
" color += texture2D(tex, "
|
||||
" vec2(" TEX_COORD ".s + u * 2.0 * x_step, "
|
||||
" " TEX_COORD ".t + v * 2.0 * y_step));"
|
||||
" count ++;"
|
||||
" }"
|
||||
"color = color / float(count);"
|
||||
FRAGMENT_SHADER_END
|
||||
#else
|
||||
"vec4 get_rgba_rel(sampler2D tex, float dx, float dy)"
|
||||
"{"
|
||||
" return texture2D (tex, " TEX_COORD ".st "
|
||||
" + vec2(dx, dy) * 2.0);"
|
||||
"}"
|
||||
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
" float count = 1.0;"
|
||||
" color += get_rgba_rel (tex, -x_step, -y_step); count++;"
|
||||
" color += get_rgba_rel (tex, -x_step, 0.0); count++;"
|
||||
" color += get_rgba_rel (tex, -x_step, y_step); count++;"
|
||||
" color += get_rgba_rel (tex, 0.0, -y_step); count++;"
|
||||
" color += get_rgba_rel (tex, 0.0, 0.0); count++;"
|
||||
" color += get_rgba_rel (tex, 0.0, y_step); count++;"
|
||||
" color += get_rgba_rel (tex, x_step, -y_step); count++;"
|
||||
" color += get_rgba_rel (tex, x_step, 0.0); count++;"
|
||||
" color += get_rgba_rel (tex, x_step, y_step); count++;"
|
||||
" color = color / count;"
|
||||
FRAGMENT_SHADER_END
|
||||
#endif
|
||||
},
|
||||
|
||||
{"invert",
|
||||
FRAGMENT_SHADER_VARS
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
" color.rgb = vec3(1.0, 1.0, 1.0) - color.rgb;\n"
|
||||
FRAGMENT_SHADER_END
|
||||
},
|
||||
|
||||
{"brightness-contrast",
|
||||
FRAGMENT_SHADER_VARS
|
||||
"uniform float brightness;"
|
||||
"uniform float contrast;"
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
" color.r = (color.r - 0.5) * contrast + brightness + 0.5;"
|
||||
" color.g = (color.g - 0.5) * contrast + brightness + 0.5;"
|
||||
" color.b = (color.b - 0.5) * contrast + brightness + 0.5;"
|
||||
FRAGMENT_SHADER_END
|
||||
},
|
||||
|
||||
{"gray",
|
||||
FRAGMENT_SHADER_VARS
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
" float avg = (color.r + color.g + color.b) / 3.0;"
|
||||
" color.r = avg;"
|
||||
" color.g = avg;"
|
||||
" color.b = avg;"
|
||||
FRAGMENT_SHADER_END
|
||||
},
|
||||
|
||||
{"combined-mirror",
|
||||
FRAGMENT_SHADER_VARS
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
" vec4 colorB = texture2D (tex, vec2(" TEX_COORD ".ts));"
|
||||
" float avg = (color.r + color.g + color.b) / 3.0;"
|
||||
" color.r = avg;"
|
||||
" color.g = avg;"
|
||||
" color.b = avg;"
|
||||
" color = (color + colorB)/2.0;"
|
||||
FRAGMENT_SHADER_END
|
||||
},
|
||||
|
||||
{"edge-detect",
|
||||
FRAGMENT_SHADER_VARS
|
||||
"float get_avg_rel(sampler2D texB, float dx, float dy)"
|
||||
"{"
|
||||
" vec4 colorB = texture2D (texB, " TEX_COORD ".st + vec2(dx, dy));"
|
||||
" return (colorB.r + colorB.g + colorB.b) / 3.0;"
|
||||
"}"
|
||||
FRAGMENT_SHADER_BEGIN
|
||||
" mat3 sobel_h = mat3( 1.0, 2.0, 1.0,"
|
||||
" 0.0, 0.0, 0.0,"
|
||||
" -1.0, -2.0, -1.0);"
|
||||
" mat3 sobel_v = mat3( 1.0, 0.0, -1.0,"
|
||||
" 2.0, 0.0, -2.0,"
|
||||
" 1.0, 0.0, -1.0);"
|
||||
" mat3 map = mat3( get_avg_rel(tex, -x_step, -y_step),"
|
||||
" get_avg_rel(tex, -x_step, 0.0),"
|
||||
" get_avg_rel(tex, -x_step, y_step),"
|
||||
" get_avg_rel(tex, 0.0, -y_step),"
|
||||
" get_avg_rel(tex, 0.0, 0.0),"
|
||||
" get_avg_rel(tex, 0.0, y_step),"
|
||||
" get_avg_rel(tex, x_step, -y_step),"
|
||||
" get_avg_rel(tex, x_step, 0.0),"
|
||||
" get_avg_rel(tex, x_step, y_step) );"
|
||||
" mat3 gh = sobel_h * map;"
|
||||
" mat3 gv = map * sobel_v;"
|
||||
" float avgh = (gh[0][0] + gh[0][1] + gh[0][2] +"
|
||||
" gh[1][0] + gh[1][1] + gh[1][2] +"
|
||||
" gh[2][0] + gh[2][1] + gh[2][2]) / 18.0 + 0.5;"
|
||||
" float avgv = (gv[0][0] + gv[0][1] + gv[0][2] +"
|
||||
" gv[1][0] + gv[1][1] + gv[1][2] +"
|
||||
" gv[2][0] + gv[2][1] + gv[2][2]) / 18.0 + 0.5;"
|
||||
" float avg = (avgh + avgv) / 2.0;"
|
||||
" color.r = avg * color.r;"
|
||||
" color.g = avg * color.g;"
|
||||
" color.b = avg * color.b;"
|
||||
FRAGMENT_SHADER_END
|
||||
},
|
||||
/* Terminating NULL sentinel */
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static gint shader_no = 0;
|
||||
|
||||
static void
|
||||
set_shader_num (ClutterActor *actor, gint new_no)
|
||||
{
|
||||
int tex_width;
|
||||
int tex_height;
|
||||
|
||||
if (new_no >= 0 && shaders[new_no].name)
|
||||
{
|
||||
ClutterShader *shader;
|
||||
GError *error;
|
||||
shader_no = new_no;
|
||||
|
||||
g_print ("setting shaders[%i] named '%s'\n",
|
||||
shader_no,
|
||||
shaders[shader_no].name);
|
||||
|
||||
shader = clutter_shader_new ();
|
||||
|
||||
error = NULL;
|
||||
g_object_set (G_OBJECT (shader),
|
||||
"fragment-source", shaders[shader_no].source, NULL);
|
||||
|
||||
/* try to bind the shader, provoking an error we catch if there is issues
|
||||
* with the shader sources we've provided. At a later stage it should be
|
||||
* possible to iterate through a set of alternate shader sources (glsl ->
|
||||
* asm -> cg?) and the one that succesfully compiles is used.
|
||||
*/
|
||||
clutter_shader_compile (shader, &error);
|
||||
if (error)
|
||||
{
|
||||
g_print ("unable to set shaders[%i] named '%s': %s",
|
||||
shader_no, shaders[shader_no].name,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
clutter_actor_set_shader (actor, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_actor_set_shader (actor, NULL);
|
||||
clutter_actor_set_shader (actor, shader);
|
||||
clutter_actor_set_shader_param (actor, "radius", 3.0);
|
||||
clutter_actor_set_shader_param (actor, "brightness", 0.4);
|
||||
clutter_actor_set_shader_param (actor, "contrast", -1.9);
|
||||
|
||||
if (CLUTTER_IS_TEXTURE (actor))
|
||||
{
|
||||
tex_width = clutter_actor_get_width (actor);
|
||||
tex_width = clutter_util_next_p2 (tex_width);
|
||||
tex_height = clutter_actor_get_height (actor);
|
||||
tex_height = clutter_util_next_p2 (tex_height);
|
||||
|
||||
clutter_actor_set_shader_param (actor, "x_step",
|
||||
1.0f / tex_width);
|
||||
clutter_actor_set_shader_param (actor, "y_step",
|
||||
1.0f / tex_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
button_release_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
gint new_no;
|
||||
|
||||
if (event->button.button == 1)
|
||||
{
|
||||
new_no = shader_no - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_no = shader_no + 1;
|
||||
}
|
||||
|
||||
set_shader_num (actor, new_no);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
static gboolean
|
||||
timeout_cb (gpointer data)
|
||||
{
|
||||
int new_no = shader_no + 1;
|
||||
|
||||
if (shaders[new_no].name == NULL)
|
||||
new_no = 0;
|
||||
|
||||
set_shader_num (CLUTTER_ACTOR (data), new_no);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* HAVE_COGL_GLES2 */
|
||||
|
||||
G_MODULE_EXPORT gint
|
||||
test_shader_main (gint argc, gchar *argv[])
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
|
||||
ClutterShader *shader;
|
||||
GError *error;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_set_size (stage, 512, 384);
|
||||
|
||||
g_print ("applying shaders[%i] named '%s'\n",
|
||||
shader_no,
|
||||
shaders[shader_no].name);
|
||||
|
||||
shader = clutter_shader_new ();
|
||||
|
||||
error = NULL;
|
||||
clutter_shader_set_fragment_source (shader, shaders[shader_no].source, -1);
|
||||
clutter_shader_compile (shader, &error);
|
||||
if (error)
|
||||
{
|
||||
g_print ("unable to load shaders[%d] named '%s': %s\n",
|
||||
shader_no,
|
||||
shaders[shader_no].name,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Shader Test");
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
|
||||
#ifndef TEST_GROUP
|
||||
actor = g_object_new (CLUTTER_TYPE_TEXTURE,
|
||||
"filename", "redhand.png",
|
||||
"disable-slicing", TRUE,
|
||||
NULL);
|
||||
actor = clutter_texture_new_from_file ("redhand.png", &error);
|
||||
if (!actor)
|
||||
g_error("pixbuf load failed: %s", error ? error->message : "Unknown");
|
||||
|
||||
#else
|
||||
actor = clutter_group_new ();
|
||||
{
|
||||
ClutterActor *child1, *child2, *child3, *child4;
|
||||
ClutterColor color = { 0xff, 0x22, 0x66, 0x99 };
|
||||
|
||||
child1 = clutter_texture_new_from_file ("redhand.png", &error);
|
||||
if (!child1)
|
||||
g_error("pixbuf load failed: %s", error ? error->message : "Unknown");
|
||||
child2 = clutter_texture_new_from_file ("redhand.png", &error);
|
||||
if (!child2)
|
||||
g_error("pixbuf load failed: %s", error ? error->message : "Unknown");
|
||||
child3 = clutter_rectangle_new ();
|
||||
child4 = clutter_label_new_with_text ("Sans 20px", "Shady stuff");
|
||||
|
||||
clutter_rectangle_set_color (child3, &color);
|
||||
clutter_actor_set_size (child3, 50, 50);
|
||||
clutter_actor_set_position (child1, 0, 0);
|
||||
clutter_actor_set_position (child2, 50, 100);
|
||||
clutter_actor_set_position (child3, 30, -30);
|
||||
clutter_actor_set_position (child4, -50, 20);
|
||||
|
||||
clutter_group_add (CLUTTER_GROUP (actor), child1);
|
||||
clutter_group_add (CLUTTER_GROUP (actor), child2);
|
||||
clutter_group_add (CLUTTER_GROUP (actor), child3);
|
||||
clutter_group_add (CLUTTER_GROUP (actor), child4);
|
||||
|
||||
clutter_actor_show_all (actor);
|
||||
}
|
||||
#endif
|
||||
|
||||
clutter_actor_set_shader (actor, shader);
|
||||
clutter_actor_set_position (actor, 100, 100);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||
|
||||
|
||||
clutter_actor_set_shader_param (actor, "brightness", 0.4);
|
||||
clutter_actor_set_shader_param (actor, "contrast", -1.9);
|
||||
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
g_signal_connect (actor, "button-release-event",
|
||||
G_CALLBACK (button_release_cb), NULL);
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
/* On an embedded platform it is difficult to right click so we will
|
||||
cycle through the shaders automatically */
|
||||
g_timeout_add_seconds (3, timeout_cb, actor);
|
||||
#endif
|
||||
|
||||
/* Show everying ( and map window ) */
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
156
tests/interactive/test-stage-read-pixels.c
Normal file
156
tests/interactive/test-stage-read-pixels.c
Normal file
@ -0,0 +1,156 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DOT_SIZE 2
|
||||
#define TEX_SIZE 64
|
||||
|
||||
typedef struct _CallbackData CallbackData;
|
||||
|
||||
struct _CallbackData
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *tex;
|
||||
ClutterActor *box;
|
||||
ClutterMotionEvent event;
|
||||
guint idle_source;
|
||||
};
|
||||
|
||||
static ClutterActor *
|
||||
make_label (void)
|
||||
{
|
||||
ClutterActor *label;
|
||||
gchar *text;
|
||||
gchar *argv[] = { "ls", "--help", NULL };
|
||||
|
||||
label = clutter_label_new ();
|
||||
clutter_label_set_font_name (CLUTTER_LABEL (label), "Sans 10");
|
||||
|
||||
if (g_spawn_sync (NULL, argv, NULL,
|
||||
G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, &text, NULL, NULL, NULL))
|
||||
{
|
||||
clutter_label_set_text (CLUTTER_LABEL (label), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
make_tex (void)
|
||||
{
|
||||
ClutterActor *tex = clutter_texture_new ();
|
||||
|
||||
clutter_actor_set_size (tex, TEX_SIZE * 2, TEX_SIZE * 2);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
make_box (void)
|
||||
{
|
||||
ClutterActor *box;
|
||||
static const ClutterColor blue = { 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
box = clutter_rectangle_new_with_color (&blue);
|
||||
clutter_actor_set_size (box, DOT_SIZE + 2, DOT_SIZE + 2);
|
||||
clutter_actor_hide (box);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_motion_idle (gpointer user_data)
|
||||
{
|
||||
CallbackData *data = (CallbackData *) user_data;
|
||||
guchar *pixels, *p;
|
||||
guint stage_width, stage_height;
|
||||
gint x, y;
|
||||
|
||||
data->idle_source = 0;
|
||||
|
||||
clutter_actor_get_size (data->stage, &stage_width, &stage_height);
|
||||
|
||||
x = CLAMP (data->event.x - TEX_SIZE / 2, 0, (int) stage_width - TEX_SIZE);
|
||||
y = CLAMP (data->event.y - TEX_SIZE / 2, 0, (int) stage_height - TEX_SIZE);
|
||||
|
||||
clutter_actor_set_position (data->box, x + TEX_SIZE / 2 - 1,
|
||||
y + TEX_SIZE / 2 - 1);
|
||||
clutter_actor_show (data->box);
|
||||
/* Redraw so that the layouting will be done and the box will be
|
||||
drawn in the right position */
|
||||
clutter_redraw (CLUTTER_STAGE (data->stage));
|
||||
|
||||
pixels = clutter_stage_read_pixels (CLUTTER_STAGE (data->stage),
|
||||
x, y, TEX_SIZE, TEX_SIZE);
|
||||
|
||||
/* Make a red dot in the center */
|
||||
p = pixels + (TEX_SIZE / 2 - DOT_SIZE / 2) * TEX_SIZE * 4
|
||||
+ (TEX_SIZE / 2 - DOT_SIZE / 2) * 4;
|
||||
for (y = 0; y < DOT_SIZE; y++)
|
||||
{
|
||||
for (x = 0; x < DOT_SIZE; x++)
|
||||
{
|
||||
*(p++) = 255;
|
||||
memset (p, 0, 3);
|
||||
p += 3;
|
||||
}
|
||||
p += TEX_SIZE * 4 - DOT_SIZE * 4;
|
||||
}
|
||||
|
||||
/* Set all of the alpa values to full */
|
||||
for (p = pixels + TEX_SIZE * TEX_SIZE * 4; p > pixels; p -= 4)
|
||||
*(p - 1) = 255;
|
||||
|
||||
clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (data->tex),
|
||||
pixels, TRUE,
|
||||
TEX_SIZE, TEX_SIZE,
|
||||
TEX_SIZE * 4, 4, 0, NULL);
|
||||
g_free (pixels);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_motion (ClutterActor *stage, ClutterMotionEvent *event, CallbackData *data)
|
||||
{
|
||||
/* Handle the motion event in an idle handler so that multiple
|
||||
events will be combined into one */
|
||||
if (data->idle_source == 0)
|
||||
data->idle_source = clutter_threads_add_idle (on_motion_idle, data);
|
||||
|
||||
data->event = *event;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_stage_read_pixels_main (int argc, char **argv)
|
||||
{
|
||||
CallbackData data;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
data.idle_source = 0;
|
||||
data.stage = clutter_stage_get_default ();
|
||||
|
||||
data.tex = make_tex ();
|
||||
data.box = make_box ();
|
||||
clutter_actor_set_position (data.tex,
|
||||
clutter_actor_get_width (data.stage)
|
||||
- clutter_actor_get_width (data.tex),
|
||||
clutter_actor_get_height (data.stage)
|
||||
- clutter_actor_get_height (data.tex));
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (data.stage),
|
||||
make_label (), data.tex, data.box, NULL);
|
||||
|
||||
g_signal_connect (data.stage, "motion-event", G_CALLBACK (on_motion), &data);
|
||||
|
||||
clutter_actor_show (data.stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
100
tests/interactive/test-texture-quality.c
Normal file
100
tests/interactive/test-texture-quality.c
Normal file
@ -0,0 +1,100 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
/* each time the timeline animating the label completes, swap the direction */
|
||||
static void
|
||||
timeline_completed (ClutterTimeline *timeline,
|
||||
gpointer user_data)
|
||||
{
|
||||
clutter_timeline_set_direction (timeline,
|
||||
!clutter_timeline_get_direction (timeline));
|
||||
clutter_timeline_start (timeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
change_filter (gpointer actor)
|
||||
{
|
||||
ClutterTextureQuality old_quality;
|
||||
|
||||
old_quality = clutter_texture_get_filter_quality (actor);
|
||||
switch (old_quality)
|
||||
{
|
||||
case CLUTTER_TEXTURE_QUALITY_LOW:
|
||||
clutter_texture_set_filter_quality (actor,
|
||||
CLUTTER_TEXTURE_QUALITY_MEDIUM);
|
||||
g_print ("Setting texture rendering quality to medium\n");
|
||||
break;
|
||||
case CLUTTER_TEXTURE_QUALITY_MEDIUM:
|
||||
clutter_texture_set_filter_quality (actor,
|
||||
CLUTTER_TEXTURE_QUALITY_HIGH);
|
||||
g_print ("Setting texture rendering quality to high\n");
|
||||
break;
|
||||
case CLUTTER_TEXTURE_QUALITY_HIGH:
|
||||
clutter_texture_set_filter_quality (actor,
|
||||
CLUTTER_TEXTURE_QUALITY_LOW);
|
||||
g_print ("Setting texture rendering quality to low\n");
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT gint
|
||||
test_texture_quality_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterBehaviour *depth_behavior;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *image;
|
||||
ClutterColor stage_color = { 0x12, 0x34, 0x56, 0xff };
|
||||
GError *error;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE);
|
||||
clutter_stage_set_fog (CLUTTER_STAGE (stage), 1.0, 10, -50);
|
||||
|
||||
g_signal_connect (stage,
|
||||
"button-press-event", G_CALLBACK (clutter_main_quit),
|
||||
NULL);
|
||||
|
||||
error = NULL;
|
||||
image = clutter_texture_new_from_file (argv[1]?argv[1]:"redhand.png", &error);
|
||||
if (error)
|
||||
g_error ("Unable to load image: %s", error->message);
|
||||
|
||||
if (!argv[1])
|
||||
g_print ("Hint: the redhand.png isn't a good test image for this test.\n"
|
||||
"This test can take any clutter loadable image as an argument\n");
|
||||
|
||||
/* center the image */
|
||||
clutter_actor_set_position (image,
|
||||
(clutter_actor_get_width (stage) - clutter_actor_get_width (image))/2,
|
||||
(clutter_actor_get_height (stage) - clutter_actor_get_height (image))/2);
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), image, NULL);
|
||||
|
||||
timeline = clutter_timeline_new (60*5, 60);
|
||||
g_signal_connect (timeline,
|
||||
"completed", G_CALLBACK (timeline_completed),
|
||||
NULL);
|
||||
|
||||
depth_behavior = clutter_behaviour_depth_new (
|
||||
clutter_alpha_new_full (timeline, CLUTTER_ALPHA_RAMP_INC, NULL, NULL),
|
||||
-2500, 400);
|
||||
|
||||
clutter_behaviour_apply (depth_behavior, image);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
g_timeout_add (10000, change_filter, image);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (depth_behavior);
|
||||
g_object_unref (timeline);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
115
tests/interactive/test-textures.c
Normal file
115
tests/interactive/test-textures.c
Normal file
@ -0,0 +1,115 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
guchar*
|
||||
make_rgba_data (int width, int height, int bpp, int has_alpha, int *rowstride_p)
|
||||
{
|
||||
#define CHECK_SIZE 20
|
||||
|
||||
gint x,y, rowstride, i = 0;
|
||||
guchar *pixels;
|
||||
|
||||
g_assert(bpp == 4);
|
||||
g_assert(has_alpha == TRUE);
|
||||
|
||||
rowstride = width * bpp;
|
||||
*rowstride_p = rowstride;
|
||||
|
||||
pixels = g_try_malloc (height * rowstride);
|
||||
if (!pixels)
|
||||
return NULL;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
i = 0;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
guchar *p;
|
||||
|
||||
p = pixels + y * rowstride + x * bpp;
|
||||
|
||||
p[0] = p[1] = p[2] = 0; p[3] = 0xff;
|
||||
|
||||
if (x && y && y % CHECK_SIZE && x % CHECK_SIZE)
|
||||
{
|
||||
if (x % CHECK_SIZE == 1)
|
||||
{
|
||||
if (++i > 3)
|
||||
i = 0;
|
||||
}
|
||||
p[i] = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
#define SPIN() while (g_main_context_pending (NULL)) \
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_textures_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *texture;
|
||||
ClutterActor *stage;
|
||||
gint i, j;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_actor_show_all (CLUTTER_ACTOR (stage));
|
||||
|
||||
SPIN();
|
||||
|
||||
for (i=100; i<=5000; i += 100)
|
||||
for (j=0; j<4; j++)
|
||||
{
|
||||
const int width = i+j;
|
||||
const int height = i+j;
|
||||
const gboolean has_alpha = TRUE;
|
||||
const int bpp = has_alpha ? 4 : 3;
|
||||
int rowstride;
|
||||
guchar *pixels;
|
||||
|
||||
pixels = make_rgba_data (width, height, bpp, has_alpha, &rowstride);
|
||||
if (!pixels)
|
||||
g_error("No memory for %ix%i RGBA data failed", width, height);
|
||||
|
||||
printf("o %ix%i texture... ", width, height);
|
||||
|
||||
texture = clutter_texture_new ();
|
||||
if (!clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (texture),
|
||||
pixels,
|
||||
has_alpha,
|
||||
width,
|
||||
height,
|
||||
rowstride,
|
||||
bpp,
|
||||
0, NULL))
|
||||
g_error("texture creation failed");
|
||||
g_free(pixels);
|
||||
|
||||
printf("uploaded to texture...\n");
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage), texture, NULL);
|
||||
clutter_actor_set_size (texture, 400, 400);
|
||||
clutter_actor_show (texture);
|
||||
|
||||
/* Hide & show to unreaise then realise the texture */
|
||||
clutter_actor_hide (texture);
|
||||
clutter_actor_show (texture);
|
||||
|
||||
SPIN();
|
||||
|
||||
clutter_container_remove (CLUTTER_CONTAINER (stage), texture, NULL);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
248
tests/interactive/test-threads.c
Normal file
248
tests/interactive/test-threads.c
Normal file
@ -0,0 +1,248 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *label;
|
||||
ClutterActor *progress;
|
||||
|
||||
ClutterTimeline *timeline;
|
||||
|
||||
volatile gboolean cancelled;
|
||||
} TestThreadData;
|
||||
|
||||
static TestThreadData *
|
||||
test_thread_data_new (void)
|
||||
{
|
||||
TestThreadData *data;
|
||||
|
||||
data = g_new0 (TestThreadData, 1);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
test_thread_data_free (TestThreadData *data)
|
||||
{
|
||||
g_object_unref (data->progress);
|
||||
g_object_unref (data->label);
|
||||
g_object_unref (data->stage);
|
||||
g_object_unref (data->timeline);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_thread_done_idle (gpointer user_data)
|
||||
{
|
||||
TestThreadData *data = user_data;
|
||||
|
||||
g_print ("Thread completed\n");
|
||||
|
||||
clutter_label_set_text (CLUTTER_LABEL (data->label), "Completed");
|
||||
clutter_timeline_stop (data->timeline);
|
||||
|
||||
test_thread_data_free (data);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GStaticPrivate test_thread_data = G_STATIC_PRIVATE_INIT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint count;
|
||||
TestThreadData *thread_data;
|
||||
} TestUpdate;
|
||||
|
||||
static gboolean
|
||||
update_label_idle (gpointer data)
|
||||
{
|
||||
TestUpdate *update = data;
|
||||
guint width;
|
||||
gchar *text;
|
||||
|
||||
text = g_strdup_printf ("Count to %d", update->count);
|
||||
|
||||
clutter_label_set_text (CLUTTER_LABEL (update->thread_data->label), text);
|
||||
clutter_actor_set_width (update->thread_data->label, -1);
|
||||
|
||||
if (update->count == 0)
|
||||
width = 0;
|
||||
else if (update->count == 100)
|
||||
width = 350;
|
||||
else
|
||||
width = (guint) (update->count / 100.0 * 350.0);
|
||||
|
||||
clutter_actor_set_width (update->thread_data->progress, width);
|
||||
|
||||
g_free (text);
|
||||
g_free (update);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
do_something_very_slow (void)
|
||||
{
|
||||
TestThreadData *data;
|
||||
gint i;
|
||||
|
||||
data = (TestThreadData *) g_static_private_get (&test_thread_data);
|
||||
if (data->cancelled)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
gint msecs;
|
||||
|
||||
msecs = 1 + (int) (100.0 * rand () / ((RAND_MAX + 1.0) / 3));
|
||||
|
||||
/* sleep for a while */
|
||||
g_usleep (msecs * 1000);
|
||||
|
||||
if ((i % 10) == 0)
|
||||
{
|
||||
TestUpdate *update;
|
||||
|
||||
update = g_new (TestUpdate, 1);
|
||||
update->count = i;
|
||||
update->thread_data = data;
|
||||
|
||||
clutter_threads_add_idle_full (G_PRIORITY_DEFAULT + 30,
|
||||
update_label_idle,
|
||||
update, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gpointer
|
||||
test_thread_func (gpointer user_data)
|
||||
{
|
||||
TestThreadData *data;
|
||||
|
||||
data = user_data;
|
||||
g_static_private_set (&test_thread_data, data, NULL);
|
||||
|
||||
do_something_very_slow ();
|
||||
|
||||
clutter_threads_add_idle_full (G_PRIORITY_DEFAULT + 30,
|
||||
test_thread_done_idle,
|
||||
data, NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ClutterTimeline *timeline = NULL;
|
||||
static ClutterActor *count_label = NULL;
|
||||
static ClutterActor *help_label = NULL;
|
||||
static ClutterActor *progress_rect = NULL;
|
||||
|
||||
static void
|
||||
on_key_press_event (ClutterStage *stage,
|
||||
ClutterKeyEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
TestThreadData *data;
|
||||
|
||||
switch (clutter_key_event_symbol (event))
|
||||
{
|
||||
case CLUTTER_s:
|
||||
clutter_label_set_text (CLUTTER_LABEL (help_label), "Press 'q' to quit");
|
||||
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
data = test_thread_data_new ();
|
||||
data->stage = g_object_ref (stage);
|
||||
data->label = g_object_ref (count_label);
|
||||
data->progress = g_object_ref (progress_rect);
|
||||
data->timeline = g_object_ref (timeline);
|
||||
g_thread_create (test_thread_func, data, FALSE, NULL);
|
||||
break;
|
||||
case CLUTTER_q:
|
||||
clutter_main_quit ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_threads_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *rect;
|
||||
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||
ClutterColor rect_color = { 0xee, 0x55, 0x55, 0x99 };
|
||||
ClutterColor progress_color = { 0x55, 0xee, 0x55, 0xbb };
|
||||
ClutterBehaviour *r_behaviour, *p_behaviour;
|
||||
const ClutterKnot knots[] = {
|
||||
{ 75, 150 },
|
||||
{ 400, 150 }
|
||||
};
|
||||
|
||||
g_thread_init (NULL);
|
||||
clutter_threads_init ();
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_actor_set_size (stage, 600, 300);
|
||||
|
||||
count_label = clutter_label_new_with_text ("Mono 12", "Counter");
|
||||
clutter_actor_set_position (count_label, 350, 50);
|
||||
|
||||
help_label = clutter_label_new_with_text ("Mono 12", "Press 's' to start");
|
||||
clutter_actor_set_position (help_label, 50, 50);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_actor_set_position (rect, 75, 150);
|
||||
clutter_actor_set_size (rect, 50, 50);
|
||||
clutter_actor_set_anchor_point (rect, 25, 25);
|
||||
|
||||
progress_rect = clutter_rectangle_new_with_color (&progress_color);
|
||||
clutter_actor_set_position (progress_rect, 50, 225);
|
||||
clutter_actor_set_size (progress_rect, 350, 50);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (stage),
|
||||
count_label, help_label,
|
||||
rect, progress_rect,
|
||||
NULL);
|
||||
|
||||
timeline = clutter_timeline_new (150, 50);
|
||||
clutter_timeline_set_loop (timeline, TRUE);
|
||||
r_behaviour = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL),
|
||||
CLUTTER_Z_AXIS,
|
||||
CLUTTER_ROTATE_CW,
|
||||
0.0, 360.0);
|
||||
clutter_behaviour_apply (r_behaviour, rect);
|
||||
|
||||
p_behaviour = clutter_behaviour_path_new (clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_SINE,
|
||||
NULL, NULL),
|
||||
knots,
|
||||
G_N_ELEMENTS (knots));
|
||||
clutter_behaviour_apply (p_behaviour, rect);
|
||||
|
||||
g_signal_connect (stage,
|
||||
"button-press-event", G_CALLBACK (clutter_main_quit),
|
||||
NULL);
|
||||
g_signal_connect (stage,
|
||||
"key-press-event", G_CALLBACK (on_key_press_event),
|
||||
NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_threads_enter ();
|
||||
clutter_main ();
|
||||
clutter_threads_leave ();
|
||||
|
||||
g_object_unref (p_behaviour);
|
||||
g_object_unref (r_behaviour);
|
||||
g_object_unref (timeline);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
150
tests/interactive/test-unproject.c
Normal file
150
tests/interactive/test-unproject.c
Normal file
@ -0,0 +1,150 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
ClutterActor *label;
|
||||
|
||||
#define RECT_L 200
|
||||
#define RECT_T 150
|
||||
#define RECT_W 320
|
||||
#define RECT_H 240
|
||||
|
||||
static gboolean
|
||||
on_event (ClutterStage *stage,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
{
|
||||
gint x, y;
|
||||
ClutterActor * actor;
|
||||
ClutterUnit xu2, yu2;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
actor = clutter_stage_get_actor_at_pos (stage, x, y);
|
||||
|
||||
|
||||
if (clutter_actor_transform_stage_point (actor,
|
||||
CLUTTER_UNITS_FROM_DEVICE (x),
|
||||
CLUTTER_UNITS_FROM_DEVICE (y),
|
||||
&xu2, &yu2))
|
||||
{
|
||||
gchar *txt;
|
||||
|
||||
if (actor != CLUTTER_ACTOR (stage))
|
||||
txt = g_strdup_printf ("Click on rectangle\n"
|
||||
"Screen coords: [%d, %d]\n"
|
||||
"Local coords : [%d, %d]",
|
||||
x, y,
|
||||
CLUTTER_UNITS_TO_DEVICE (xu2),
|
||||
CLUTTER_UNITS_TO_DEVICE (yu2));
|
||||
else
|
||||
txt = g_strdup_printf ("Click on stage\n"
|
||||
"Screen coords: [%d, %d]\n"
|
||||
"Local coords : [%d, %d]",
|
||||
x, y,
|
||||
CLUTTER_UNITS_TO_DEVICE (xu2),
|
||||
CLUTTER_UNITS_TO_DEVICE (yu2));
|
||||
|
||||
clutter_label_set_text (CLUTTER_LABEL (label), txt);
|
||||
g_free (txt);
|
||||
}
|
||||
else
|
||||
clutter_label_set_text (CLUTTER_LABEL (label),
|
||||
"Unprojection failed.");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_unproject_main (int argc, char *argv[])
|
||||
{
|
||||
gchar *txt;
|
||||
ClutterActor *rect, *stage, *label0;
|
||||
int i, rotate_x = 0, rotate_y = 60, rotate_z = 0;
|
||||
ClutterColor stage_clr = { 0x0, 0x0, 0x0, 0xff },
|
||||
white = { 0xff, 0xff, 0xff, 0xff },
|
||||
blue = { 0, 0xff, 0xff, 0xff };
|
||||
|
||||
for (i = 0; i < argc; ++i)
|
||||
{
|
||||
if (!strncmp (argv[i], "--rotate-x", 10))
|
||||
{
|
||||
rotate_x = atoi (argv[i] + 11);
|
||||
}
|
||||
else if (!strncmp (argv[i], "--rotate-y", 10))
|
||||
{
|
||||
rotate_y = atoi (argv[i] + 11);
|
||||
}
|
||||
else if (!strncmp (argv[i], "--rotate-z", 10))
|
||||
{
|
||||
rotate_z = atoi (argv[i] + 11);
|
||||
}
|
||||
else if (!strncmp (argv[i], "--help", 6))
|
||||
{
|
||||
printf ("%s [--rotage-x=degrees] [--rotage-y=degrees] "
|
||||
"[--rotage-z=degrees]\n",
|
||||
argv[0]);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr);
|
||||
clutter_actor_set_size (stage, 640, 480);
|
||||
|
||||
rect = clutter_rectangle_new_with_color (&white);
|
||||
clutter_actor_set_size (rect, RECT_W, RECT_H);
|
||||
clutter_actor_set_position (rect, RECT_L, RECT_T);
|
||||
clutter_actor_set_rotation (rect, CLUTTER_X_AXIS, rotate_x, 0, 0, 0);
|
||||
clutter_actor_set_rotation (rect, CLUTTER_Y_AXIS, rotate_y, 0, 0, 0);
|
||||
clutter_actor_set_rotation (rect, CLUTTER_Z_AXIS, rotate_z, 0, 0, 0);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), rect);
|
||||
|
||||
txt = g_strdup_printf ("Rectangle: L %d, R %d, T %d, B %d\n"
|
||||
"Rotation : x %d, y %d, z %d",
|
||||
RECT_L, RECT_L + RECT_W,
|
||||
RECT_T, RECT_T + RECT_H,
|
||||
rotate_x, rotate_y, rotate_z);
|
||||
|
||||
label0 = clutter_label_new_with_text ("Mono 8pt", txt);
|
||||
clutter_label_set_color (CLUTTER_LABEL (label0), &white);
|
||||
|
||||
clutter_actor_set_position (label0, 10, 10);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), label0);
|
||||
|
||||
g_free (txt);
|
||||
|
||||
label =
|
||||
clutter_label_new_with_text ("Mono 8pt", "Click around!");
|
||||
|
||||
clutter_label_set_color (CLUTTER_LABEL (label), &blue);
|
||||
|
||||
clutter_actor_set_position (label, 10, 50);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), label);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
g_signal_connect (stage, "event", G_CALLBACK (on_event), NULL);
|
||||
|
||||
clutter_main();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
66
tests/interactive/test-viewport.c
Normal file
66
tests/interactive/test-viewport.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_viewport_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *r_behave;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *hand;
|
||||
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage),
|
||||
&stage_color);
|
||||
|
||||
/* Make a hand */
|
||||
hand = clutter_texture_new_from_file ("redhand.png", NULL);
|
||||
if (!hand)
|
||||
g_error("pixbuf load failed");
|
||||
|
||||
clutter_actor_set_position (hand, 300, 200);
|
||||
clutter_actor_set_clip (hand, 20, 21, 132, 170);
|
||||
clutter_actor_set_anchor_point (hand, 86, 125);
|
||||
clutter_actor_show (hand);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), hand);
|
||||
|
||||
/* Make a timeline */
|
||||
timeline = clutter_timeline_new (200, 26); /* num frames, fps */
|
||||
g_object_set (timeline, "loop", TRUE, NULL);
|
||||
|
||||
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
|
||||
alpha = clutter_alpha_new_full (timeline,
|
||||
CLUTTER_ALPHA_RAMP_INC,
|
||||
NULL, NULL);
|
||||
|
||||
/* Create a behaviour for that alpha */
|
||||
r_behave = clutter_behaviour_rotate_new (alpha,
|
||||
CLUTTER_Z_AXIS,
|
||||
CLUTTER_ROTATE_CW,
|
||||
0.0, 360.0);
|
||||
|
||||
/* Apply it to our actor */
|
||||
clutter_behaviour_apply (r_behave, hand);
|
||||
|
||||
/* start the timeline and thus the animations */
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main();
|
||||
|
||||
g_object_unref (r_behave);
|
||||
|
||||
return 0;
|
||||
}
|
13
tests/interactive/wrapper.sh
Executable file
13
tests/interactive/wrapper.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
UNIT_TEST=`basename $0`
|
||||
|
||||
echo "Running ./test-interactive $UNIT_TEST $@"
|
||||
echo ""
|
||||
echo "NOTE: For debugging purposes, you can run this single test as follows:"
|
||||
echo "$ libtool --mode=execute \\"
|
||||
echo " gdb --eval-command=\"b `echo $UNIT_TEST|tr '-' '_'`_main\" \\"
|
||||
echo " --args ./test-interactive $UNIT_TEST"
|
||||
|
||||
./test-interactive $UNIT_TEST "$@"
|
||||
|
Reference in New Issue
Block a user