って事でGTKバインディング作ります!
mattn's go-gtk at master - GitHubGoでは継承が使えないので、例えばGtkBoxを継承したGtkVBox/GtkHBox、GtkWidgetを継承したGtkWindow/GtkButton/GtkLabel...が上手く表現出来ません。
gtk extension for go
http://github.com/mattn/go-gtk
出来ないというか、GtkButtonにGtkWidgetと同じメソッドを生やそうと思うと、同じコードを書かなければなりません。
色々と模索した結果、gtk.Window()やgtk.Button()で返すのは常にGtkWidgetとし、GtkWindowやGtkButton独自のメソッドを呼び出したい場合には
(>k.GtkWindow{window.Widget}).SetTitle("GTK Go!");
こういう風に型変換して貰う事にしました。まぁコンポジションぽい物?C言語バージョンにおいても同じ処理をする時には
gtk_window_set_title(GTK_WINDOW(w), "GTK Go!");
とする訳だし、似てると言えば似てる訳だし...要は、Widget毎にGtkWidgetからGtkXXXへの変換関数なんか作ってらんねぇよ。バカ!
という訳です。
現状、コールバック(gtk_signal_connect)も動作しています。少しハマった理由としては、goroutineを勝手にスレッドだと思っていたので、スレッド間通信を想定してpipeのコードを書いていましたが、よく考えたらscheduled coroutineだし、自分のwrite pipeを自分でreadしてどうするよ...って気付いたのです。
結局変数ポーリングに変えて現状上手く動いています。
GoでGTKのプログラミングをすると、以下の様なコードになります。
package main
import (
"os";
"gtk";
"unsafe";
)
func main() {
gtk.Init(&os.Args);
window := gtk.Window(gtk.GTK_WINDOW_TOPLEVEL);
(>k.GtkWindow{window.Widget}).SetTitle("GTK Go!");
vbox := gtk.VBox(0, 1);
label := gtk.Label("ハローワールド");
(>k.GtkBox{vbox.Widget}).PackStart(label, 0, 1, 0);
entry := gtk.Entry();
(>k.GtkEntry{entry.Widget}).SetText("入力エリア!");
vbox.Add(entry);
button := gtk.ButtonWithLabel("こんにちわ!こんにちわ!");
button.Connect("clicked", func(widget *gtk.GtkWidget, data unsafe.Pointer){
println("button clicked");
println((>k.GtkButton{button.Widget}).GetLabel());
}, nil);
vbox.Add(button);
window.Add(vbox);
window.ShowAll();
gtk.Main();
}
そして実行画面。まだ、GtkWindow/GtkButton/GtkLabel/GtkVBox/GtkHBox/GtkEntryのそれぞれ一部のメソッドしか動いていませんが、宜しければ遊んでみて下さい。
そしてもし「おおし!おいらも作るお!」って方が居られたら、ぜひgithubでforkして下さい。