mutter/examples/slider.c

197 lines
4.3 KiB
C
Raw Normal View History

#include <stdlib.h>
#include <stdio.h>
#include <clutter/clutter.h>
typedef struct Tile
{
ClutterActor *actor;
gint orig_pos;
}
Tile;
static Tile *Tiles[4][4];
static int TileW, TileH, BlankTileX, BlankTileY;
static ClutterEffectTemplate *Template;
static ClutterTimeline *EffectTimeline;
ClutterActor*
make_tiles (GdkPixbuf *pixbuf)
{
int x, y , w, h;
int i = 0, j = 0;
int pos = 0;
ClutterActor *group;
group = clutter_group_new();
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
TileW = w / 4;
TileH = h / 4;
for (y = 0; y < h; y += TileH)
{
for (x = 0; x < w; x += TileW)
{
GdkPixbuf *subpixbuf;
Tile *tile;
subpixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
8, TileW, TileH);
gdk_pixbuf_copy_area (pixbuf, x, y, TileW, TileH,
subpixbuf, 0, 0);
tile = g_slice_new0 (Tile);
if (pos != 15)
{
tile->actor = clutter_texture_new_from_pixbuf (subpixbuf);
clutter_container_add_actor (CLUTTER_CONTAINER (group),
tile->actor);
clutter_actor_set_position (tile->actor, x, y);
}
else
{
/* blank tile */
tile->actor = NULL;
BlankTileX = i;
BlankTileY = j;
}
g_object_unref (subpixbuf);
tile->orig_pos = pos;
Tiles[j][i] = tile;
pos++; i++;
}
i=0; j++;
}
return group;
}
static void
switch_blank_tile (int i, int j)
{
Tile *tmp;
ClutterKnot knots[2];
knots[0].x = i * TileW;
knots[0].y = j * TileH;
knots[1].x = BlankTileX * TileW;
knots[1].y = BlankTileY * TileH;
EffectTimeline = clutter_effect_move (Template,
Tiles[j][i]->actor,
knots,
2,
NULL,
NULL);
/* Add a week pointer to returned timeline so we know whilst its
* playing and thus valid.
*/
g_object_add_weak_pointer (G_OBJECT(EffectTimeline),
(gpointer*)&EffectTimeline);
tmp = Tiles[BlankTileY][BlankTileX];
Tiles[BlankTileY][BlankTileX] = Tiles[j][i];
Tiles[j][i] = tmp;
BlankTileY = j;
BlankTileX = i;
}
static void
key_press_event_cb (ClutterStage *stage,
ClutterKeyEvent *event,
gpointer user_data)
{
Tile *tmp, *tmp2;
if (clutter_key_event_symbol(event) == CLUTTER_q)
clutter_main_quit();
/* Do move if there is a move already happening */
if (EffectTimeline != NULL)
return;
switch (clutter_key_event_symbol(event))
{
case CLUTTER_Up:
if (BlankTileY < 3)
switch_blank_tile (BlankTileX, BlankTileY+1);
break;
case CLUTTER_Down:
if (BlankTileY > 0)
switch_blank_tile (BlankTileX, BlankTileY-1);
break;
case CLUTTER_Left:
if (BlankTileX < 3)
switch_blank_tile (BlankTileX+1, BlankTileY);
break;
case CLUTTER_Right:
if (BlankTileX > 0)
switch_blank_tile (BlankTileX-1, BlankTileY);
break;
default:
break;
}
}
int
main (int argc, char **argv)
{
GError *error;
GdkPixbuf *pixbuf;
ClutterActor *stage, *group;
ClutterColor bgcolour;
/* Initiate clutter */
clutter_init (&argc, &argv);
/* Setup the stage */
stage = clutter_stage_get_default ();
g_object_set (stage, "fullscreen", TRUE, NULL);
clutter_color_parse ("#000000", &bgcolour);
clutter_stage_set_color (CLUTTER_STAGE (stage), &bgcolour);
/* Create Tiles */
error = NULL;
pixbuf = gdk_pixbuf_new_from_file ("image.jpg", &error);
if (error)
{
g_warning ("Unable to load `image.jpg': %s", error->message);
g_error_free (error);
return EXIT_FAILURE;
}
group = make_tiles (pixbuf);
/* Add to stage and center */
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
clutter_actor_set_position (group,
(clutter_actor_get_width (stage) - clutter_actor_get_width (group)) / 2,
(clutter_actor_get_height (stage) - clutter_actor_get_height (group)) / 2);
/* Link up event collection */
g_signal_connect (stage,
"key-press-event",
G_CALLBACK(key_press_event_cb),
NULL);
/* Template to use for slider animation */
Template = clutter_effect_template_new (clutter_timeline_new (15, 60),
CLUTTER_ALPHA_RAMP_INC);
clutter_actor_show_all (stage);
clutter_main();
}