Clutter調用底層原理剖析

1 初識Clutter

按照Clutter官網所述,Clutter是一個支持2D曲面的3D動畫的GUI庫,是一個C API集合。目前版本Clutter1.8.0-stable release,http://download.gnome.org/sources/clutter/1.8。

2 編程在Gjs

const Clutter = imports.gi.Clutter;

正是通過這條語句在Gjs編程中導入路Clutter模塊,使得Gjs可以訪問底層基於C語言實現的Clutter lib。

2.1 基本Class

clutter的核心概念是:stage(畫布,舞臺)和actor(演員)。莎士比亞說“全世界是一座舞臺,所有的男人女人不過是演員”,這句話很好的表現了這點。畫布相當於一個window是actor的舞臺。Clutter是一種封裝,封裝就會有container。所以clutter程序都需要創建一個stage,它是最頂層的對象,也是一個container(容器),讓其他的actor在其上面表演。actor們本身都是2D對象,是平面的,不過clutter允許我們對這些actor在3D空間進行操作,比如繞着x,y,z軸旋轉。

2.2 簡單編程示例(C到Gjs)

程序實現一個矩形中嵌套一個小矩形,顯示文字,並接受mouse事件。


int main(int argc,char **argv)
{
ClutterColor stage_color ={0x00,0x00,0x00,0xff};
clutter_init (&argc,&argv);
ClutterActor *stage = clutter_stage_get_default();
clutter_actor_set_size(stage,200,200);
clutter_stage_set_color(CLUTTER_STAGE(stage),&stage_color);
ClutterActor *actor= clutter_rectangle_new();
clutter_actor_set_size(actor,100,100);
clutter_container_add_actor(CLUTTER_CONTAINER(stage),actor);
clutter_actor_set_position (actor,50,50);
ClutterColor color_color={0xff,0xff,0xff,0xff};
ClutterActor *label = clutter_text_new_full ("Sans 12","Alex_Test",&color_color);
clutter_actor_set_size (label,50,20);
clutter_actor_set_position (label,20,160);
clutter_container_add_actor (CLUTTER_CONTAINER (stage),label);
clutter_actor_set_scale(actor,0.5,0.5);
clutter_actor_set_scale(actor,0.5,0.5);
clutter_actor_show(stage);
g_signal_connect (stage,"button-press-event",
G_CALLBACK(on_stage_button_press),NULL);
clutter_main();
return EXIT_SUCCESS;
}

使用Gjs編程,就需要改變Mothod,使用Gjs環境下的Clutter編程。方法類的調用,可以通過Clutter-1.0.gir查閱(詳見下文)。


<class name="Timeline"
c:symbol-prefix="timeline"
c:type="ClutterTimeline"
version="0.2"
parent="GObject.Object"
glib:type-name="ClutterTimeline"
glib:get-type="clutter_timeline_get_type"
glib:type-struct="TimelineClass">

2.3 ClutterTimeline

 clutter除了可以讓我們在3D空間操作2D的actor之外,最有特色的就是可以使用時間線。

以下是改動DockBar js文件中用於隱藏Bar的代碼:


_hideDock: function (){
this._timeline = new Clutter.Timeline({ duration: 200 });
this._timeline.start();
this._timeline.connect('new-frame', Lang.bind(this,
function(timeline, frame) {
this._onHideNewFrame(frame);
}));
hideDock=true;
},
_onHideNewFrame : function(frame) {
let monitor = global.get_primary_monitor();
this._time = this._timeline.get_elapsed_time();
this.bin.set_position ((-this.actor.width)*(this._time/200)+1,monitor.height*0.122);
},


3 附錄

關於clutter導入細節以及C到js的Clutter方法查詢參考。

3.1 lib導入到Gjs(Clutter-1.0 version)

兩條路徑:

.typelib path:/usr/lib/girepository-1.0/

.gir path:/usr/share/gir-1.0/

GI(GObject Introspection)可以將API的信息描述成XML,再parse成typelib格式,即binary格式,方便runtime時使用。正是通過這一過程,GI使得基於GObject的native lib能輕易porting到script language。

3.2 GNOME 庫被 GI 化

現在,GNOME 桌面的大部分程序庫皆已 GI 化,通常可在 /usr/lib/girepository-1.0 目錄中看到它們,只要在該目錄中的出現的 typelib 文件,其對應的庫便可在 gjs 通過 imports.gi 對象進行連接。如想查詢API在js中使用的方法,可以使用command:

[alex@alex girepository-1.0]$ g-ir-generate Clutter-1.0.typelib | grep timeline

或者 可以從/usr/share/gir-1.0/對應的.gir文件查詢C函數原型信息。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章