diff options
Diffstat (limited to 'trunk/ext/tk/lib/tk/event.rb')
-rw-r--r-- | trunk/ext/tk/lib/tk/event.rb | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/trunk/ext/tk/lib/tk/event.rb b/trunk/ext/tk/lib/tk/event.rb deleted file mode 100644 index d8aad6248b..0000000000 --- a/trunk/ext/tk/lib/tk/event.rb +++ /dev/null @@ -1,542 +0,0 @@ -# -# tk/event.rb - module for event -# - -module TkEvent -end - -######################## - -require 'tkutil' -require 'tk' - -######################## - -module TkEvent - class Event < TkUtil::CallbackSubst - module Grp - KEY = 0x1 - BUTTON = 0x2 - MOTION = 0x4 - CROSSING = 0x8 - FOCUS = 0x10 - EXPOSE = 0x20 - VISIBILITY = 0x40 - CREATE = 0x80 - DESTROY = 0x100 - UNMAP = 0x200 - MAP = 0x400 - REPARENT = 0x800 - CONFIG = 0x1000 - GRAVITY = 0x2000 - CIRC = 0x4000 - PROP = 0x8000 - COLORMAP = 0x10000 - VIRTUAL = 0x20000 - ACTIVATE = 0x40000 - MAPREQ = 0x80000 - CONFIGREQ = 0x100000 - RESIZEREQ = 0x200000 - CIRCREQ = 0x400000 - - MWHEEL = KEY - - STRING_DATA = 0x80000000 # special flag for 'data' field - - ALL = 0xFFFFFFFF - - KEY_BUTTON_MOTION_VIRTUAL = (KEY|MWHEEL|BUTTON|MOTION|VIRTUAL) - KEY_BUTTON_MOTION_CROSSING = (KEY|MWHEEL|BUTTON|MOTION|CROSSING|VIRTUAL) - end - - type_data = [ - #-----+-------------------+------------------+-----------------------# - # ID | const | group_flag | context_name # - #-----+-------------------+------------------+-----------------------# - [ 2, :KeyPress, Grp::KEY, 'KeyPress', 'Key' ], - [ 3, :KeyRelease, Grp::KEY, 'KeyRelease' ], - [ 4, :ButtonPress, Grp::BUTTON, 'ButtonPress', 'Button' ], - [ 5, :ButtonRelease, Grp::BUTTON, 'ButtonRelease' ], - [ 6, :MotionNotify, Grp::MOTION, 'Motion' ], - [ 7, :EnterNotify, Grp::CROSSING, 'Enter' ], - [ 8, :LeaveNotify, Grp::CROSSING, 'Leave' ], - [ 9, :FocusIn, Grp::FOCUS, 'FocusIn' ], - [ 10, :FocusOut, Grp::FOCUS, 'FocusOut' ], - [ 11, :KeymapNotify, 0, ], - [ 12, :Expose, Grp::EXPOSE, 'Expose' ], - [ 13, :GraphicsExpose, Grp::EXPOSE, ], - [ 14, :NoExpose, 0, ], - [ 15, :VisibilityNotify, Grp::VISIBILITY, 'Visibility' ], - [ 16, :CreateNotify, Grp::CREATE, 'Create' ], - [ 17, :DestroyNotify, Grp::DESTROY, 'Destroy' ], - [ 18, :UnmapNotify, Grp::UNMAP, 'Unmap' ], - [ 19, :MapNotify, Grp::MAP, 'Map' ], - [ 20, :MapRequest, Grp::MAPREQ, 'MapRequest' ], - [ 21, :ReparentNotify, Grp::REPARENT, 'Reparent' ], - [ 22, :ConfigureNotify, Grp::CONFIG, 'Configure' ], - [ 23, :ConfigureRequest, Grp::CONFIGREQ, 'ConfigureRequest' ], - [ 24, :GravityNotify, Grp::GRAVITY, 'Gravity' ], - [ 25, :ResizeRequest, Grp::RESIZEREQ, 'ResizeRequest' ], - [ 26, :CirculateNotify, Grp::CIRC, 'Circulate' ], - [ 27, :CirculateRequest, 0, 'CirculateRequest' ], - [ 28, :PropertyNotify, Grp::PROP, 'Property' ], - [ 29, :SelectionClear, 0, ], - [ 30, :SelectionRequest, 0, ], - [ 31, :SelectionNotify, 0, ], - [ 32, :ColormapNotify, Grp::COLORMAP, 'Colormap' ], - [ 33, :ClientMessage, 0, ], - [ 34, :MappingNotify, 0, ], - [ 35, :VirtualEvent, Grp::VIRTUAL, ], - [ 36, :ActivateNotify, Grp::ACTIVATE, 'Activate' ], - [ 37, :DeactivateNotify, Grp::ACTIVATE, 'Deactivate' ], - [ 38, :MouseWheelEvent, Grp::MWHEEL, 'MouseWheel' ], - [ 39, :TK_LASTEVENT, 0, ] - ] - - module TypeNum - end - - TYPE_NAME_TBL = Hash.new - TYPE_ID_TBL = Hash.new - TYPE_GROUP_TBL = Hash.new - - type_data.each{|id, c_name, g_flag, *t_names| - TypeNum.const_set(c_name, id) - t_names.each{|t_name| t_name.freeze; TYPE_NAME_TBL[t_name] = id } - TYPE_ID_TBL[id] = t_names - TYPE_GROUP_TBL[id] = g_flag - } - - TYPE_NAME_TBL.freeze - TYPE_ID_TBL.freeze - - def self.type_id(name) - TYPE_NAME_TBL[name.to_s] - end - - def self.type_name(id) - TYPE_ID_TBL[id] && TYPE_ID_TBL[id][0] - end - - def self.group_flag(id) - TYPE_GROUP_TBL[id] || 0 - end - - ############################################# - - module StateMask - ShiftMask = (1<<0) - LockMask = (1<<1) - ControlMask = (1<<2) - Mod1Mask = (1<<3) - Mod2Mask = (1<<4) - Mod3Mask = (1<<5) - Mod4Mask = (1<<6) - Mod5Mask = (1<<7) - Button1Mask = (1<<8) - Button2Mask = (1<<9) - Button3Mask = (1<<10) - Button4Mask = (1<<11) - Button5Mask = (1<<12) - - AnyModifier = (1<<15) - - META_MASK = (AnyModifier<<1) - ALT_MASK = (AnyModifier<<2) - EXTENDED_MASK = (AnyModifier<<3) - - CommandMask = Mod1Mask - OptionMask = Mod2Mask - end - - ############################################# - - FIELD_FLAG = { - # key => flag - 'above' => Grp::CONFIG, - 'borderwidth' => (Grp::CREATE|Grp::CONFIG), - 'button' => Grp::BUTTON, - 'count' => Grp::EXPOSE, - 'data' => (Grp::VIRTUAL|Grp::STRING_DATA), - 'delta' => Grp::MWHEEL, - 'detail' => (Grp::FOCUS|Grp::CROSSING), - 'focus' => Grp::CROSSING, - 'height' => (Grp::EXPOSE|Grp::CONFIG), - 'keycode' => Grp::KEY, - 'keysym' => Grp::KEY, - 'mode' => (Grp::CROSSING|Grp::FOCUS), - 'override' => (Grp::CREATE|Grp::MAP|Grp::REPARENT|Grp::CONFIG), - 'place' => Grp::CIRC, - 'root' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), - 'rootx' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), - 'rooty' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), - 'sendevent' => Grp::ALL, - 'serial' => Grp::ALL, - 'state' => (Grp::KEY_BUTTON_MOTION_VIRTUAL| - Grp::CROSSING|Grp::VISIBILITY), - 'subwindow' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), - 'time' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| - Grp::PROP), - 'warp' => Grp::KEY_BUTTON_MOTION_VIRTUAL, - 'width' => (Grp::EXPOSE|Grp::CREATE|Grp::CONFIG), - 'window' => (Grp::CREATE|Grp::UNMAP|Grp::MAP|Grp::REPARENT| - Grp::CONFIG|Grp::GRAVITY|Grp::CIRC), - 'when' => Grp::ALL, - 'x' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| - Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY| - Grp::REPARENT), - 'y' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| - Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY| - Grp::REPARENT), - } - - FIELD_OPERATION = { - 'root' => proc{|val| - begin - Tk.tk_call_without_enc('winfo', 'pathname', val) - val - rescue - nil - end - }, - - 'subwindow' => proc{|val| - begin - Tk.tk_call_without_enc('winfo', 'pathname', val) - val - rescue - nil - end - }, - - 'window' => proc{|val| nil} - } - - #------------------------------------------- - - def valid_fields(group_flag=nil) - group_flag = self.class.group_flag(self.type) unless group_flag - - fields = {} - FIELD_FLAG.each{|key, flag| - next if (flag & group_flag) == 0 - begin - val = self.__send__(key) - rescue - next - end - # next if !val || val == '??' - next if !val || (val == '??' && (flag & Grp::STRING_DATA)) - fields[key] = val - } - - fields - end - - def valid_for_generate(group_flag=nil) - fields = valid_fields(group_flag) - - FIELD_OPERATION.each{|key, cmd| - next unless fields.has_key?(key) - val = FIELD_OPERATION[key].call(fields[key]) - if val - fields[key] = val - else - fields.delete(key) - end - } - - fields - end - - def generate(win, modkeys={}) - klass = self.class - - if modkeys.has_key?(:type) || modkeys.has_key?('type') - modkeys = TkComm._symbolkey2str(modkeys) - type_id = modkeys.delete('type') - else - type_id = self.type - end - - type_name = klass.type_name(type_id) - unless type_name - fail RuntimeError, "type_id #{type_id} is invalid" - end - - group_flag = klass.group_flag(type_id) - - opts = valid_for_generate(group_flag) - - modkeys.each{|key, val| - if val - opts[key.to_s] = val - else - opts.delete(key.to_s) - end - } - - if group_flag != Grp::KEY - Tk.event_generate(win, type_name, opts) - else - # If type is KEY event, focus should be set to target widget. - # If not set, original widget will get the same event. - # That will make infinite loop. - w = Tk.tk_call_without_enc('focus') - begin - Tk.tk_call_without_enc('focus', win) - Tk.event_generate(win, type_name, opts) - ensure - Tk.tk_call_without_enc('focus', w) - end - end - end - - ############################################# - - # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>] - KEY_TBL = [ - [ ?#, ?n, :serial ], - [ ?a, ?s, :above ], - [ ?b, ?n, :num ], - [ ?c, ?n, :count ], - [ ?d, ?s, :detail ], - # ?e - [ ?f, ?b, :focus ], - # ?g - [ ?h, ?n, :height ], - [ ?i, ?s, :win_hex ], - # ?j - [ ?k, ?n, :keycode ], - # ?l - [ ?m, ?s, :mode ], - # ?n - [ ?o, ?b, :override ], - [ ?p, ?s, :place ], - # ?q - # ?r - [ ?s, ?x, :state ], - [ ?t, ?n, :time ], - # ?u - [ ?v, ?n, :value_mask ], - [ ?w, ?n, :width ], - [ ?x, ?n, :x ], - [ ?y, ?n, :y ], - # ?z - [ ?A, ?s, :char ], - [ ?B, ?n, :borderwidth ], - # ?C - [ ?D, ?n, :wheel_delta ], - [ ?E, ?b, :send_event ], - # ?F - # ?G - # ?H - # ?I - # ?J - [ ?K, ?s, :keysym ], - # ?L - # ?M - [ ?N, ?n, :keysym_num ], - # ?O - [ ?P, ?s, :property ], - # ?Q - [ ?R, ?s, :rootwin_id ], - [ ?S, ?s, :subwindow ], - [ ?T, ?n, :type ], - # ?U - # ?V - [ ?W, ?w, :widget ], - [ ?X, ?n, :x_root ], - [ ?Y, ?n, :y_root ], - # ?Z - nil - ] - - # [ <'%' subst-key str>, <proc type char>, <instance var (accessor) name>] - # the subst-key string will be converted to a bytecode (128+idx). - LONGKEY_TBL = [ - # for example, for %CTT and %CST subst-key on tkdnd-2.0 - # ['CTT', ?l, :drop_target_type], - # ['CST', ?l, :drop_source_type], - ] - - # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>] - PROC_TBL = [ - [ ?n, TkComm.method(:num_or_str) ], - [ ?s, TkComm.method(:string) ], - [ ?b, TkComm.method(:bool) ], - [ ?w, TkComm.method(:window) ], - - [ ?x, proc{|val| - begin - TkComm::number(val) - rescue ArgumentError - val - end - } - ], - - nil - ] - -=begin - # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) ) - KEY_TBL.map!{|inf| - if inf.kind_of?(Array) - inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String) - inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String) - end - inf - } - - PROC_TBL.map!{|inf| - if inf.kind_of?(Array) - inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String) - end - inf - } -=end - - # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys - # - # _get_subst_key() and _get_all_subst_keys() generates key-string - # which describe how to convert callback arguments to ruby objects. - # When binding parameters are given, use _get_subst_key(). - # But when no parameters are given, use _get_all_subst_keys() to - # create a Event class object as a callback parameter. - # - # scan_args() is used when doing callback. It convert arguments - # ( which are Tcl strings ) to ruby objects based on the key string - # that is generated by _get_subst_key() or _get_all_subst_keys(). - # - _setup_subst_table(KEY_TBL, PROC_TBL) - # _setup_subst_table(KEY_TBL, LONGKEY_TBL, PROC_TBL) # if use longname-keys - - # - # NOTE: The order of parameters which passed to callback procedure is - # <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ... - # - - # If you need support extra arguments given by Tcl/Tk, - # please override _get_extra_args_tbl - # - #def self._get_extra_args_tbl - # # return an array of convert procs - # [] - #end - -=begin - alias button num - alias delta wheel_delta - alias root rootwin_id - alias rootx x_root - alias root_x x_root - alias rooty y_root - alias root_y y_root - alias sendevent send_event -=end - ALIAS_TBL = { - :button => :num, - :data => :detail, - :delta => :wheel_delta, - :root => :rootwin_id, - :rootx => :x_root, - :root_x => :x_root, - :rooty => :y_root, - :root_y => :y_root, - :sendevent => :send_event, - :window => :widget - } - - _define_attribute_aliases(ALIAS_TBL) - - end - - ############################################### - - def install_bind_for_event_class(klass, cmd, *args) - extra_args_tbl = klass._get_extra_args_tbl - - if args.compact.size > 0 - args.map!{|arg| klass._sym2subst(arg)} - args = args.join(' ') - keys = klass._get_subst_key(args) - - if cmd.kind_of?(String) - id = cmd - elsif cmd.kind_of?(TkCallbackEntry) - id = install_cmd(cmd) - else - id = install_cmd(proc{|*arg| - ex_args = [] - extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} - begin - TkUtil.eval_cmd(cmd, *(ex_args.concat(klass.scan_args(keys, arg)))) - rescue Exception=>e - if TkCore::INTERP.kind_of?(TclTkIp) - fail e - else - # MultiTkIp - fail Exception, "#{e.class}: #{e.message.dup}" - end - end - }) - end - else - keys, args = klass._get_all_subst_keys - - if cmd.kind_of?(String) - id = cmd - elsif cmd.kind_of?(TkCallbackEntry) - id = install_cmd(cmd) - else - id = install_cmd(proc{|*arg| - ex_args = [] - extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} - begin - TkUtil.eval_cmd(cmd, *(ex_args << klass.new(*klass.scan_args(keys, arg)))) - rescue Exception=>e - if TkCore::INTERP.kind_of?(TclTkIp) - fail e - else - # MultiTkIp - fail Exception, "#{e.class}: #{e.message.dup}" - end - end - }) - end - end - - if TkCore::INTERP.kind_of?(TclTkIp) - id + ' ' + args - else - # MultiTkIp - "if {[set st [catch {#{id} #{args}} ret]] != 0} { - if {$st == 4} { - return -code continue $ret - } elseif {$st == 3} { - return -code break $ret - } elseif {$st == 2} { - return -code return $ret - } elseif {[regexp {^Exception: (TkCallbackContinue: .*)$} \ - $ret m msg]} { - return -code continue $msg - } elseif {[regexp {^Exception: (TkCallbackBreak: .*)$} $ret m msg]} { - return -code break $msg - } elseif {[regexp {^Exception: (TkCallbackReturn: .*)$} $ret m msg]} { - return -code return $msg - } elseif {[regexp {^Exception: (\\S+: .*)$} $ret m msg]} { - return -code return $msg - } else { - return -code error $ret - } - } else { - set ret - }" - end - end - - def install_bind(cmd, *args) - install_bind_for_event_class(TkEvent::Event, cmd, *args) - end -end |