From: "D.Kanda" Date: 1998-12-24T07:20:26+09:00 Subject: [ruby-list:11431] Re: gtk ----Next_Part(Thu_Dec_24_07:15:30_1998_893)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit かんだ@楓街です。 Takehama Hirohisa さんの書かれた、 「[ruby-list:11395] Re: gtk 」 からの引用です。 > かんださん、ありがとうございます。 > > > > ・signal_connect の最後で、真偽値か整数値を返さないといけないようなのですが、 > > > これは何の値でしょうか? > > > > その signal の処理を続けるかやめるかを指定します。trueだとそこで止めます。 > > ある signal に複数の handler が登録されている場合はその登録順に渡されます > > が、さらに子signal方向、親widget 方向へと辿るようです。 > > 3つめの質問と関連していますが、true を返して signal の処理をやめると、 > widget のもともとのキー入力処理を横取りできないのでしょうか。試したと > ころ、 > > text.signal_connect('key_press_event') {|w, e| > true > } > > としただけでは、あいかわらずデフォルトの動作(文字が挿入されたり、カー > ソル移動したり)が行なわれます。 Gtk+のソースを読んでみたところ、どうも親signal を辿るかどうかに使われて いるようです。同じ signal の次の handler を辿らないようにしたい場合は、処 理をやめたい handler 内で gtk_signal_emit_stop() を実行すればよいようです。 # これでいいんでしょうか? > Gtkな方々 とりあえず GC の周りは考えずに Gtk::Object::signal_emit_stop() メソッドを 定義しておきました。パッチ付けます。 しかし、Gtk+ って signal 周りが難しい… 全てのコードは signal に通ず、signal を制する者は Gtk+ を制す :-P > > event周りはまだほとんどできていません。ここはホントは GdkEventKey インス > > タンスを返すべきところで、GdkEventKey は keyval とかいうメソッドが定義され > > るようです。 > > # これくらいならすぐにできますが、今ちょっと忙しいので今夜にでも > > お手数ですが是非お願いします。 KeyEvent だけ実装しました。週末にでももう少し整理して新しい版を出してお きます。gdk/gdkkeysyms.h に定義されている無数の:) キー番号もそのときに付け ますので、必要でしたらしばらくは直接整数を記述して下さいませ。 GtkText のキー入力を横取りするサンプルを付けておきます。小文字で入力して も大文字にします。 > > gtktext には control_key['z'-'a'+1] とかいった配列が用意されていて、これ > > に関数ポインタを埋め込んでいます。で、実際に ctrl-a とかが押されると、 > > control_key[0] の関数が呼び出される。だから、この配列に別の関数ポインタを代 > > 入すればそれでキーバインドが変更できることになりますね。ただ、gtkの関数とし > > て用意はされていないようですので、仕様から考えることになります。 > > Tk ではイベントを のように指定できますね。さらに > とか とかできます。GTK でもここまでで > きるとうれしいなと思います。 基本は Gtk+ 互換にしたいので、余分な機能は組み込むとしても別になると思い ます。問題は Gtk+ でも直接関数ポインタを代入すれば上の機能は果たせるのだけ れど、それは認められている方法なのかどうかかな…。とりあえずは代用できます ので、提供しないでおきます。 ----Next_Part(Thu_Dec_24_07:15:30_1998_893)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=texthook.rb require 'gtk' w = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) w.signal_connect("delete_event") { exit } w.signal_connect("destroy") { exit } text = Gtk::Text.new text.set_editable(true) text.signal_connect("key_press_event") do |widget, event| p event ret = false if widget.editable? if event.length == 1 and ?a <= event.keyval and event.keyval <= ?z widget.delete_selection() widget.insert_text(event.string.capitalize, widget.get_length) widget.signal_emit_stop("key_press_event") ret = true end end ret end w.add(text) text.show w.show Gtk::main() ----Next_Part(Thu_Dec_24_07:15:30_1998_893)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=gtk.c.diff *** gtk.c.orig Mon Dec 21 20:15:52 1998 --- gtk.c Thu Dec 24 06:57:56 1998 *************** *** 1002,1007 **** --- 1002,1010 ---- case GDK_3BUTTON_PRESS: return Data_Wrap_Struct(gdkEventButton, 0, gdk_event_free, event); break; + case GDK_KEY_PRESS: + return Data_Wrap_Struct(gdkEventKey, 0, gdk_event_free, event); + break; default: return Data_Wrap_Struct(gdkEvent, 0, gdk_event_free, event); } *************** *** 1597,1602 **** --- 1600,1615 ---- } static VALUE + gobj_emit_stop(self, sig) + VALUE self, sig; + { + GtkObject *obj = get_gobject(self); + + gtk_signal_emit_stop_by_name(obj, STR2CSTR(sig)); + return self; + } + + static VALUE gobj_destroy(self) VALUE self; { *************** *** 4426,4431 **** --- 4439,4451 ---- } static VALUE + txt_has_cursor(self) + VALUE self; + { + return GTK_TEXT(get_widget(self))->has_cursor? TRUE: FALSE; + } + + static VALUE tbar_initialize(argc, argv, self) int argc; VALUE *argv; *************** *** 5253,5258 **** --- 5273,5285 ---- } static VALUE + edit_is_editable(self) + VALUE self; + { + return GTK_EDITABLE(get_widget(self))->editable? TRUE: FALSE; + } + + static VALUE entry_initialize(self) VALUE self; { *************** *** 6755,6760 **** --- 6782,6817 ---- } static VALUE + gdkeventkey_time(self) + { + return INT2NUM(((GdkEventKey*)get_gdkevent(self))->time); + } + + static VALUE + gdkeventkey_state(self) + { + return INT2NUM(((GdkEventKey*)get_gdkevent(self))->state); + } + + static VALUE + gdkeventkey_keyval(self) + { + return INT2NUM(((GdkEventKey*)get_gdkevent(self))->keyval); + } + + static VALUE + gdkeventkey_length(self) + { + return INT2NUM(((GdkEventKey*)get_gdkevent(self))->length); + } + + static VALUE + gdkeventkey_string(self) + { + return str_new2(((GdkEventKey*)get_gdkevent(self))->string); + } + + static VALUE gdkeventmotion_window(self) { return make_gdkwindow(((GdkEventMotion*)get_gdkevent(self))->window); *************** *** 7074,7079 **** --- 7131,7138 ---- rb_define_method(gObject, "==", gobj_equal, 1); rb_define_method(gObject, "inspect", gobj_inspect, 0); + rb_define_method(gObject, "signal_emit_stop", gobj_emit_stop, 1); + /* Widget */ rb_define_method(gWidget, "show", widget_show, 0); rb_define_method(gWidget, "show_all", widget_show_all, 0); *************** *** 7379,7384 **** --- 7438,7444 ---- rb_define_method(gEditable, "claim_selection", edit_claim_selection, 2); rb_define_method(gEditable, "delete_selection", edit_delete_selection, 0); rb_define_method(gEditable, "changed", edit_changed, 0); + rb_define_method(gEditable, "editable?", edit_is_editable, 0); /* Entry */ rb_define_method(gEntry, "initialize", entry_initialize, 0); *************** *** 7680,7685 **** --- 7740,7746 ---- rb_define_method(gText, "insert", txt_insert, 4); rb_define_method(gText, "backward_delete", txt_backward_delete, 1); rb_define_method(gText, "forward_delete", txt_forward_delete, 1); + rb_define_method(gText, "has_cursor?", txt_has_cursor, 0); /* Toolbar */ rb_define_method(gToolbar, "initialize", tbar_initialize, -1); *************** *** 7905,7911 **** rb_define_method(gdkRectangle, "height", gdkrect_h, 0); /* GdkEvent */ ! rb_define_method(gdkEvent, "type", gdkevent_type, 0); /* GdkEventExpose */ rb_define_method(gdkEventExpose, "area", gdkeventexpose_area, 0); --- 7966,7972 ---- rb_define_method(gdkRectangle, "height", gdkrect_h, 0); /* GdkEvent */ ! rb_define_method(gdkEvent, "event_type", gdkevent_type, 0); /* GdkEventExpose */ rb_define_method(gdkEventExpose, "area", gdkeventexpose_area, 0); *************** *** 7914,7919 **** --- 7975,7987 ---- rb_define_method(gdkEventButton, "x", gdkeventbutton_x, 0); rb_define_method(gdkEventButton, "y", gdkeventbutton_y, 0); rb_define_method(gdkEventButton, "button", gdkeventbutton_button, 0); + + /* GdkEventKey */ + rb_define_method(gdkEventKey, "time", gdkeventkey_time, 0); + rb_define_method(gdkEventKey, "state", gdkeventkey_state, 0); + rb_define_method(gdkEventKey, "keyval", gdkeventkey_keyval, 0); + rb_define_method(gdkEventKey, "length", gdkeventkey_length, 0); + rb_define_method(gdkEventKey, "string", gdkeventkey_string, 0); /* GdkEventMotion */ rb_define_method(gdkEventMotion, "window", gdkeventmotion_window, 0); ----Next_Part(Thu_Dec_24_07:15:30_1998_893)----