1. 概述
Clutter 是一个 C API 集合。核心概念是: stage (画布,舞台)和 actor (演员)。画布相当于一个 window ,或者 framebuffer ,是 actor 的舞台。 所有的 Clutter 程序都需要创建一个 stage ,它是最顶层的对象,也是一个 container (容器,让其他 actor 在上面表演)。 actor 们本身都是 2D 对 象,是平面的,不过 Clutter 允许我们对这些 actor 在 3D 空间进行操作, 比如绕着 x,y,z 轴旋转。
Clutter 除了可以让我们在 3D 空间操作 2D 的 actor 外,最有特色的就是可 以使用时间线,通过多条时间线的协同使用,我们可以很容易创造出“有生气”“有 活力”的程序。
当然, Clutter 也会处理传统的键盘、鼠标事件!
这就是 Clutter !
2. 准备环境
以下实例都以 libclutter-0.9-dev 为基础
要使用 clutter APIs ,可以使用下面命令得到的参数编译程序:
pkg-config clutter-0.9 --cflags pkg-config clutter-0.9 --libs
如果使用 automake,authconf 之类工具,可以设置 PKG_CHECK_MODULES 宏:
PKG_CHECK_MODULES(EXAMPLE, clutter-0.9) AC_SUBST(EXAMPLE_CFLAGS) AC_SUBST(EXAMPLE_LIBS)
3. 基本 Actor
先看一个例子,修改 moblin 网站的 sample-helloworld 程序,使之可以显示 UTF-8 字符集。源程序: clutter_春江花月夜
这个例子中的五个字会随机运动,绕着x,y,z轴随机旋转。编译源代码:
gcc -Wall `pkg-config clutter-0.9 --cflags --libs` clutter_春江花月夜.c ./a.out
stage
每个 Clutter 应用程序都至少包括一个 ClutterStage 。这个 stage 容纳 Actors (比如 rectangles,images,or text).
基本 Clutter 程序设计 和 stage 的基本概念
clutter_init() clutter_stage_get_default() clutter_actor_show() clutter_container_add() clutter_main()
开始一个 clutter 程序,使用 clutter_init() 初始化。使用 clutter_stage_get_default() 创建一个 stage 。也可以使用 GtkClutterEmbed widget 在一个 GTK+ 窗口中使用 Clutter。
ClutterStage 从 ClutterActor 对象派生,所以很多 ClutterActor 的属性都可以 用在 stage 上。例如调用 clutter_actor_show() 显示stage。
ClutterStage 也操作 ClutterContainer ,允许使用 clutter_container_add() 添加子 actors。
调用 clutter_main() 开始一个 main loop,让 stage “活”起来!
#include <clutter/clutter.h> #include <stdlib.h> static gboolean on_stage_button_press (ClutterStage *stage,ClutterEvent *event,gpointer data) { gint x = 0; gint y = 0; clutter_event_get_coords (event,&x,&y); g_print ("在 (%d,%d) 处点击 : ",x,y); if (x < 250) printf("stage左边部分!\n"); else if (x == 250) printf("中奖了!恰好是中间!\n"); else printf("stage右边部分!\n"); return TRUE; } int main(int argc,char **argv) { ClutterColor stage_color = {0x00,0x00,0x00,0xff}; clutter_init (&argc,&argv); // 创建 stage 并设置大小和颜色 ClutterActor *stage = clutter_stage_get_default(); clutter_actor_set_size(stage,500,200); clutter_stage_set_color(CLUTTER_STAGE(stage),&stage_color); // 显示 stage clutter_actor_show(stage); // 连接事件 g_signal_connect (stage,"button-press-event", G_CALLBACK(on_stage_button_press),NULL); // 让 stage 活起来 clutter_main(); return EXIT_SUCCESS; }
stage widget
GtkClutterEmbed widget 允许把 ClutterStage 放到一个 GTK+ 窗口中。使用 gtk_clutter_embed_new() 创建一个实例,再用 gtk_clutter_embed_get_stage() 从 GtkClutterEmbed 对象创建一个 ClutterStage 实例.
使用 GtkClutterEmbed widget ,需要用 gtk_clutter_init 代替 clutter_init 和 gtk_init 初始化 Clutter 和 GTK+。使用 gtk_main() 代替 clutter_main() 创建 main loop。
#include <gtk/gtk.h> #include <clutter/clutter.h> #include <clutter-gtk/clutter-gtk.h> #include <stdlib.h> int main (int argc, char **argv) { ClutterColor stage_color = {0x61,0x64,0x8c,0xff}; if (gtk_clutter_init (&argc,&argv) != CLUTTER_INIT_SUCCESS) g_error ("初始化 GtkClutter 失败!"); if (argc !=2) g_error ("用法: 程序名 <image file>"); // 创建一个 toplevel 窗口 GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window),640,480); gtk_window_set_title (GTK_WINDOW (window),"浏览图片"); g_signal_connect (window,"destory", G_CALLBACK(gtk_main_quit),NULL); // 创建一个 table 包括 scrollbar 和 clutter embed widget GtkWidget *table = gtk_table_new (2,2,FALSE); gtk_container_add (GTK_CONTAINER (window),table); gtk_widget_show (table); // 创建一个 ClutterEmbed widget GtkWidget *embed = gtk_clutter_embed_new(); gtk_table_attach (GTK_TABLE (table),embed, 0,1, 0,1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0,0); gtk_widget_show (embed); // 初始化 stage ClutterActor *stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (embed)); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); clutter_actor_set_size (stage,640,480); // 创建一个 viewport actor ClutterActor *viewport = gtk_clutter_viewport_new (NULL,NULL); clutter_container_add_actor (CLUTTER_CONTAINER (stage),viewport); // 加载 image ClutterActor *texture = clutter_texture_new_from_file (argv[1],NULL); clutter_container_add_actor (CLUTTER_CONTAINER (viewport),texture); clutter_actor_set_position (texture,0,0); clutter_actor_set_position (viewport,0,0); clutter_actor_set_size (viewport,640,480); // 创建 scrollbar ,并连接到 viewport GtkAdjustment *h_adjustment = NULL; GtkAdjustment *v_adjustment = NULL; gtk_clutter_scrollable_get_adjustments (GTK_CLUTTER_SCROLLABLE (viewport), &h_adjustment,&v_adjustment); GtkWidget *scrollbar = gtk_vscrollbar_new (v_adjustment); gtk_table_attach (GTK_TABLE (table),scrollbar, 1,2, 0,1, 0,GTK_EXPAND | GTK_FILL, 0,0); gtk_widget_show (scrollbar); scrollbar = gtk_hscrollbar_new (h_adjustment); gtk_table_attach (GTK_TABLE (table),scrollbar, 0,1, 1,2, GTK_EXPAND | GTK_FILL,0, 0,0); gtk_widget_show (scrollbar); gtk_widget_show (window); gtk_main(); return EXIT_SUCCESS; }
Actors
Clutter 中基本 actor 有:
- ClutterStage — stage
- ClutterRectangle — 矩形
- ClutterText — 显示和编辑文本
- ClutterTexture — 图片
每个 actor 需要用 clutter_container_add() 添加到 stage 中,并且用 clutter_actor_set_position() 设置位置(x,y坐标),z 轴使用 clutter_actor_set_depth() 设置。使用 clutter_actor_set_size() 设置宽度和 长度(width and height)
actor 的位置默认在 parent container(比如stage) 的 top-left(0,0),可以用 clutter_actor_set_anchor_point() 改变。
默认情况下,actor 是隐藏的,需要调用 clutter_actor_show() 显示。可以调用 clutter_actor_hide() 隐藏对象。
actor 可以使用 scaling (缩放) 、rotation (旋转) 、partly transparent (透 明) 变形。
示例:两个静止的 actor
#include <clutter/clutter.h> #include <stdlib.h> int main (int argc, char **argv) { ClutterColor stage_color = {0x00,0x00,0x00,0xff}; ClutterColor actor_color = {0xff,0xff,0xff,0x99}; clutter_init (&argc, &argv); // 创建 stage 并设置大小和颜色 ClutterActor *stage = clutter_stage_get_default (); clutter_actor_set_size (stage,300,200); clutter_stage_set_color (CLUTTER_STAGE (stage),&stage_color); // 添加一个 rectangle 到 stage ClutterActor *rect = clutter_rectangle_new_with_color (&actor_color); clutter_actor_set_size (rect,150,100); clutter_actor_set_position (rect,20,20); clutter_container_add_actor (CLUTTER_CONTAINER (stage),rect); clutter_actor_show (rect); // 添加一个 label 到 stage ClutterActor *label = clutter_text_new_full ("Sans 12","测试文本",&actor_color); clutter_actor_set_size (label,500,500); clutter_actor_set_position (label,20,160); clutter_container_add_actor (CLUTTER_CONTAINER (stage),label); clutter_actor_show (label); // 显示 stage clutter_actor_show (stage); clutter_main(); return EXIT_SUCCESS; }
Tansformations (转换)
Actors can be scaled, rotated, and moved.
Scaling (缩放比例)
调用 clutter_actor_set_scale() 增加和减少actor显示的大小。但是不改变 clutter_actor_get_width() 和 clutter_actor_get_height() 的值。因为它仅仅 改变用户"看到"的大小。再次调用 clutter_actor_set_scale() 会替换第一次的改变 而不是在之基础上。
Rotation (旋转,循环)
调用 clutter_actor_set_rotation() 可以让 actor 绕着坐标轴(axis)旋转,坐标 轴可以是 CLUTTER_X_AXIS、CLUTTER_Y_AXIS、CLUTTER_Z_AXIS 或想要的角度。
同 clutter_actor_set_scale() 一样,这个函数也不改变 actor 本身的值,比如 用 clutter_actor_get_x() 的到的值。
Clipping (剪切)
actor 可以用 clutter_actor_set_clip() 剪切后只让部分可见。这样,可以创建 一个很大的 actor,然后设置一个 clip rectangle,这样任何时刻只有一部分可见。 可以使用 clutter_actor_remove_clip() 删除。
Movement
可以使用 clutter_actor_move_by() 和 clutter_actor_set_depth() 移动 actor。
clutter_actor_move_by() 会改变 clutter_actor_get_x() 的值!
示例
#include <clutter/clutter.h> #include <stdlib.h> int main (int argc, char **argv) { ClutterColor stage_color = {0x00,0x00,0x00,0xff}; ClutterColor actor_color = {0xff,0xff,0xff,0x99}; clutter_init (&argc, &argv); ClutterActor *stage = clutter_stage_get_default (); clutter_actor_set_size (stage,500,300); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); ClutterActor *rect = clutter_rectangle_new_with_color (&actor_color); clutter_actor_set_size (rect,150,150); clutter_actor_set_position (rect,20,20); clutter_container_add_actor (CLUTTER_CONTAINER (stage),rect); clutter_actor_show (rect); clutter_actor_set_rotation (rect,CLUTTER_X_AXIS,-80,0,0,0); ClutterActor *label = clutter_text_new_full ("Sans 12","春江花月夜",&actor_color); clutter_actor_set_size (label,500,500); clutter_actor_set_position (label,60,150); clutter_container_add_actor (CLUTTER_CONTAINER (stage),label); clutter_actor_show (label); clutter_actor_set_scale (label,6.00,1.0); clutter_actor_move_by (label,20,-20); clutter_actor_set_depth (label,-80); clutter_actor_show (stage); clutter_main(); return EXIT_SUCCESS; }
Containers (容器)
ClutterContainer ClutterStage ClutterGroup
使用 ClutterGroup 可以同时操作几个 actor
示例:两个actor组成的ClutterGroup
#include <clutter/clutter.h> #include <stdlib.h> int main (int argc, char **argv) { ClutterColor stage_color = {0x00,0x00,0x00,0xff}; ClutterColor actor_color = {0xff,0xff,0xff,0x99}; clutter_init (&argc, &argv); // 创建 stage 并设置大小和颜色 ClutterActor *stage = clutter_stage_get_default (); clutter_actor_set_size (stage,300,200); clutter_stage_set_color (CLUTTER_STAGE (stage),&stage_color); // 添加一个 group ClutterActor *group = clutter_group_new (); clutter_actor_set_position (group,40,40); clutter_container_add_actor (CLUTTER_CONTAINER (stage),group); clutter_actor_show (group); // 添加一个 rectangle 到 group ClutterActor *rect = clutter_rectangle_new_with_color (&actor_color); clutter_actor_set_size (rect,50,50); clutter_actor_set_position (rect,0,0); clutter_container_add_actor (CLUTTER_CONTAINER (group),rect); clutter_actor_show (rect); // 添加一个 label 到 group ClutterActor *label = clutter_text_new_full ("Sans 9","春江潮水连海平",&actor_color); clutter_actor_set_position (label,0,60); clutter_container_add_actor (CLUTTER_CONTAINER (group),label); clutter_actor_show (label); // 绕 x 轴 scale group 到 120% clutter_actor_set_scale (group,3.00,1.0); // 绕 z 周 ratate clutter_actor_set_rotation (group,CLUTTER_Z_AXIS,10,0,0,0); clutter_actor_show (stage); clutter_main (); return EXIT_SUCCESS; }

