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)。唉,才几年又轻又快的东东就成了个史前巨无霸。