mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
184 lines
4.0 KiB
C
184 lines
4.0 KiB
C
|
#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_group_add (CLUTTER_GROUP (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)
|
||
|
{
|
||
|
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 */
|
||
|
pixbuf = gdk_pixbuf_new_from_file ("image.jpg", NULL);
|
||
|
group = make_tiles (pixbuf);
|
||
|
|
||
|
/* Add to stage and center */
|
||
|
clutter_group_add (CLUTTER_GROUP (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();
|
||
|
}
|