How Webkit render a button
看了这位老兄的blog后,我对webkit也有了兴趣。webkit可以根据布局结构来动态的产生HTML控件,这个在很多可视化开发工具里面可以看到,比如Netbeans,XCode都可以用拖放的方式开发UI。我原来很好奇,这些IDE是如何显示这些控件的呢?因为这些控件和IDE本身的控件有一致外观(OS的主题外观),如果使用普通的API来搞,比如”new JButton()”来构造UI,感觉有点头晕。
找了下,webkit的代码Source\WebCore\platform\gtk\RenderThemeGtk3.cpp是用来创建Gnome 3外观风格的控件,比如方法paintToggle就是对应单选框。我把里面的代码抽取出来,做了个小例子。费了老大劲,因为压根不知道如何得到context和cairo_t这些上下文信息(或者称为状态机,Functional Language反感的就是这个)。GTK的getting started在这里。
/**
this code show how to render a button with gtk 3
Some code copy from webkit/Source/WebCore/platform/gtk
*/
#include <gtk/gtk.h>
static gboolean
draw_cb (GtkWidget *widget, cairo_t *cr){
GtkStyleContext *context;
context = gtk_widget_get_style_context (widget);
gtk_style_context_save(context);
gtk_style_context_add_class(context,GTK_STYLE_CLASS_CHECK );
gtk_style_context_set_state(context, GTK_STATE_FLAG_ACTIVE);
int i;
for(i = 0; i < 20; i++){
gtk_render_check(context, cr, 10*(i+1), 10*(i+1), 10, 10);
}
gtk_style_context_restore(context);
}
int
main (int argc, char *argv[]){
GtkWidget *window;
GtkWidget *ebox;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
ebox = gtk_event_box_new ();
gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), TRUE);
gtk_container_add (GTK_CONTAINER (window), ebox);
g_signal_connect_after (ebox, "draw", G_CALLBACK (draw_cb), NULL);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
上面的截图中可以看到checkbox有native的looking(本人非Nike控),不同的是这些控件只是画上去的(没有JButton这种类的层次结构),没有event binding,也就是MVC只有MV。C的一块可能就由浏览器接过来来统一管理,那得遵循HTML Dom Event Model的规范。
这里不考虑CSS的外观。Gnome 3也是用CSS来控制外观,不知道是不是借鉴webkit。Windows的theme我还没有找到在哪里。
从webkit的代码看其已经支持Gtk+-3.0的back-end,不过Chrome还没有推出相应版本,据说是因为他跟Gtk+-2.0绑的太紧,跟Ubuntu走的太近(Ubuntu没有支持gnome 3)。唉,才几年又轻又快的东东就成了个史前巨无霸。
