Clutter is a new cool toolkit (kind of, quite low level though, there is currently not even button widget implemented, to make button, you have to create your own) for creating appealing user interfaces with full utilization of the GPU. The Clutter demos found from clutter project svn look cool, but I decided to create a more basic example for people to get started. I made it on purpose with C++ (Clutter can be commanded from C++ also with no problem). If you are not yet familiar with Clutter, please go to the project home page here. Clutter is available obviously for Linux and apparently also MacOSX port may be coming (there is a bug in clutter bugzilla about it). Anyway, here is the hello world example written in C++ which creates two labels and rotates the another label.
Makefile:
LIBS=`pkg-config --libs clutter-0.5`
INCS=`pkg-config --cflags clutter-0.5`
.cpp.o:
g++ -g -Wall $(CFLAGS) $(INCS) -c $*.cpp
all: hello2
hello2: clutterhello.o hello2.o
g++ -g -Wall $(CFLAGS) -o $@ clutterhello.o hello2.o $(LIBS)
clean:
rm -fr *.o hello2
clutterhello.h:
// clutterhello.h
#ifndef __CLUTTER_HELLO__H__
#define __CLUTTER_HELLO__H__
#define STAGE_WIDTH 1280
#define STAGE_HEIGHT 720
class ClutterHello {
public:
ClutterHello();
~ClutterHello();
void run();
void frame_callback(ClutterTimeline *timeline, gint frame_num, gpointer data);
private:
void build_ui();
ClutterActor *stage;
ClutterColor stage_color;
ClutterColor label_color;
ClutterActor *label1;
ClutterActor *label2;
ClutterTimeline *timeline;
};
#endif
clutterhello.cpp:
// clutterhello.cpp
#include <clutter/clutter.h>
#include \"clutterhello.h\"
extern void frame_cb
(ClutterTimeline *timeline, gint frame_num, gpointer data);
ClutterHello::ClutterHello()
{
ClutterColor stage_col = { 0xff, 0xff, 0xff, 0xff };
ClutterColor label_col = { 0x00, 0x00, 0x00, 0xff };
stage_color = stage_col;
label_color = label_col;
stage = clutter_stage_get_default ();
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
}
ClutterHello::~ClutterHello
()
{
}
void
ClutterHello::frame_callback (ClutterTimeline *timeline,
gint frame_num, gpointer data){
clutter_actor_rotate_z (CLUTTER_ACTOR(this->label1), frame_num, 228/2, 19 );
}
void
ClutterHello::build_ui()
{
/* Create Hello World -label */
label1 = clutter_label_new_with_text
(\"Sans 38px\", \"Hello World!\");
label2 = clutter_label_new_with_text
(\"Sans 10px\", \"Extended Hello Wold, which makes rotate_z to the label\");
clutter_label_set_color (CLUTTER_LABEL (label1), &label_color);
clutter_actor_set_position (label1, 455, 300);
clutter_label_set_color (CLUTTER_LABEL (label2), &label_color);
clutter_actor_set_position (label2, 455, 400);
clutter_label_set_line_wrap (CLUTTER_LABEL (label1), FALSE);
clutter_label_set_line_wrap (CLUTTER_LABEL (label2), FALSE);
/* Add the label created to stage container */
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label1);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label2);
/* Show all actors, just like Gtk+! */
clutter_actor_show_all (stage);
timeline = clutter_timeline_new (360, 60);
g_object_set (timeline, \"loop\", TRUE, NULL);
g_signal_connect (timeline, \"new-frame\", G_CALLBACK (frame_cb), NULL);
g_signal_connect (stage, \"key-press-event\",
G_CALLBACK (clutter_main_quit), NULL);
}
void
ClutterHello::run()
{
build_ui();
clutter_timeline_start (timeline);
clutter_main();
}
hello2.cpp:
// hello2.cpp
// Simple hello world with Clutter
#include <clutter/clutter.h>
using namespace std;
#include \"clutterhello.h\"
ClutterHello *helloApp;
void
frame_cb (ClutterTimeline *timeline, gint frame_num, gpointer data)
{
/* Frame number is also the angle */
if(helloApp){
helloApp->frame_callback(timeline, frame_num, data);
}
}
int
main (int argc, char *argv[])
{
/* Init & create stage where to put actors */
clutter_init (&argc, &argv);
helloApp = new ClutterHello();
helloApp->run();
if(helloApp){
delete helloApp;
helloApp=NULL;
}
return 0;
}