diff options
author | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-06-18 19:46:20 +0000 |
---|---|---|
committer | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-06-18 19:46:20 +0000 |
commit | d8b02b509608c5b90056c7befa89fa29fda45f8f (patch) | |
tree | fa79099d51b611202df51b03218b0743c2cdfbf1 /ext/tk/lib | |
parent | 151f1241c665b0307234e931bec2c32bfea0138d (diff) | |
download | ruby-d8b02b509608c5b90056c7befa89fa29fda45f8f.tar.gz |
tk.rb :
* small bug fix
* rename 'no_create' option to 'without_creating'
* add TkWindow#pack_in, TkWindow#grid_in, TkWindow#place_in
* add TkWindow#bind_class and TkWindow#database_class
If defined specific_class (@db_class), bind_class returns @db_class.
In other case, bind_class returns TkWinow#class().
It is useful for binding.
TkWindow#database_class is defined for querying the option database.
It's same to TkWinfo.classname(self).
* add TkBindTag.new_by_name and TkDatabaseClass for binding to database class
* check varname whether already exsist or not. (TkVarAccess.new)
* TkTextWin#bbox returns an array of four numbers
* autoload TkDialog2, TkWarning2
* scan event callback arguments and convert to proper type
* TkBindTag.new accepts a block ( TkBindTag.new(context){callback} )
* If given taglist, TkWindow#bindtags(taglist) returns taglist
* add TkWindow#bindtags=(taglist)
* Tk.focue and Tk.focus_lastfor return nil if there is no target widget.
* Tk::Wm.client returns the argument string when setting name
* TkGrid.columnconfiginfo and rowconfiginfo given a slot return a number.
* TkWindow.grid_columnconfiginfo and grid_rowconfiginfo :: ditto
* rename and define alias :: TkOption ==> TkOptionDB
* define alias :: TkTimer ==> TkAfter
* some instance methods change from public to private
* some TkComm methods change to module functions
(help to treat return values from Tk)
* add support for -displayof option to some TkWinfo methods
* bind, bind_append and bind_remove :: returns the target of event-binding
* add Tk8.4 features
* add TkPaneWindow
tkdialog.rb:
* classes without showing at initialize : TkDialog2, TkWarning2
* add show method to reuse TkDialog object
* some instance methods change from public to private
* add new features for configuration
tktext.rb :
* small bug fix
* some methods return self
* add TkTextMark#+(mod) and TkTextMark#-(mod) (e.g. mark + '3 chars')
* add some methods
tkcanvas.rb :
* small bug fix
* some methods return self
tkentry.rb :
* some methods return self
* TkEntry#bbox returns an array of four numbers
* scan validatecommand arguments and convert to proper type
tkbgerror.rb :
* support to define a error handler by user
tcltklib.rb :
* reported by Ferenc Engard <engard@all.hu> on [ruby-talk:60759]
... and so on
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3960 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk/lib')
-rw-r--r-- | ext/tk/lib/README | 1 | ||||
-rw-r--r-- | ext/tk/lib/tk.rb | 1218 | ||||
-rw-r--r-- | ext/tk/lib/tkafter.rb | 12 | ||||
-rw-r--r-- | ext/tk/lib/tkbgerror.rb | 12 | ||||
-rw-r--r-- | ext/tk/lib/tkcanvas.rb | 114 | ||||
-rw-r--r-- | ext/tk/lib/tkconsole.rb | 26 | ||||
-rw-r--r-- | ext/tk/lib/tkdialog.rb | 185 | ||||
-rw-r--r-- | ext/tk/lib/tkentry.rb | 80 | ||||
-rw-r--r-- | ext/tk/lib/tkfont.rb | 19 | ||||
-rw-r--r-- | ext/tk/lib/tkmngfocus.rb | 6 | ||||
-rw-r--r-- | ext/tk/lib/tktext.rb | 395 | ||||
-rw-r--r-- | ext/tk/lib/tkvirtevent.rb | 7 |
12 files changed, 1645 insertions, 430 deletions
diff --git a/ext/tk/lib/README b/ext/tk/lib/README index 2d9e72bced..73beaf6414 100644 --- a/ext/tk/lib/README +++ b/ext/tk/lib/README @@ -4,6 +4,7 @@ tkafter.rb handles Tcl after tkbgerror.rb Tk error module tkcanvas.rb Tk canvas interface tkclass.rb provides generic names for Tk classes +tkconsole.rb console command support tkdialog.rb Tk dialog class tkentry.rb Tk entry class tkfont.rb Tk font support diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index cefb87400a..35b9e7ce97 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -17,6 +17,13 @@ module TkComm Tk_CMDTBL = {} Tk_WINDOWS = {} + Tk_IDs = [0, 0] # [0]-cmdid, [1]-winid + + INITIALIZE_TARGETS = [self] + + def self.__init_tables__ + Tk_WINDOWS.clear + end def error_at frames = caller() @@ -31,7 +38,8 @@ module TkComm return TkRoot.new if path == '.' begin - tk_class = TkCore::INTERP._invoke('winfo', 'class', path) + #tk_class = TkCore::INTERP._invoke('winfo', 'class', path) + tk_class = Tk.tk_call('winfo', 'class', path) rescue return path end @@ -48,6 +56,7 @@ module TkComm end eval "#{gen_class_name}.new('#{path}')" end + private :_genobj_for_tkwidget def tk_tcl2ruby(val) if val =~ /^rb_out (c\d+)/ @@ -63,11 +72,13 @@ module TkComm val.to_i when /^\./ Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val) + when /^i\d+$/ + TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val when / / val.split.collect{|elt| tk_tcl2ruby(elt) } - when /^-?\d+\.\d*$/ + when /^-?\d+\.?\d*(e[-+]?\d+)?$/ val.to_f else val @@ -177,19 +188,19 @@ module TkComm def bool(val) case val when "1", 1, 'yes', 'true' - TRUE + true else - FALSE + false end end def number(val) case val when /^-?\d+$/ val.to_i - when /^-?\d+\.\d*$/ + when /^-?\d+\.?\d*(e[-+]?\d+)?$/ val.to_f else - val + fail ArgumentError, format('invalid value for Number:"%s"', val.to_s) end end def string(val) @@ -204,17 +215,27 @@ module TkComm def list(val) tk_split_list(val) end + def simplelist(val) + tk_split_simplelist(val) + end def window(val) - Tk_WINDOWS[val] + if val =~ /^\./ + Tk_WINDOWS[val]? Tk_WINDOWS[val] : _genobj_for_tkwidget(val) + else + nil + end end def procedure(val) if val =~ /^rb_out (c\d+)/ Tk_CMDTBL[$1] else - nil + #nil + val end end - private :bool, :number, :string, :list, :window, :procedure + private :bool, :number, :string, :list, :simplelist, :window, :procedure + module_function :bool, :number, :string, :list, :simplelist + module_function :window, :procedure def _get_eval_string(str) return nil if str == None @@ -237,7 +258,11 @@ module TkComm elsif (str.respond_to?(:to_eval)) str = str.to_eval() else - str = str.to_s() + str = str.to_s() || '' + unless str.kind_of? String + fail RuntimeError, "fail to convert the object to a string" + end + str end return str end @@ -254,7 +279,6 @@ module TkComm end private :ruby2tcl - Tk_IDs = [0, 0] # [0]-cmdid, [1]-winid def _curr_cmd_id id = format("c%.4d", Tk_IDs[0]) end @@ -263,6 +287,8 @@ module TkComm Tk_IDs[0] += 1 id end + private :_curr_cmd_id, :_next_cmd_id + def install_cmd(cmd) return '' if cmd == '' id = _next_cmd_id @@ -295,20 +321,94 @@ module TkComm def uninstall_win() Tk_WINDOWS.delete(@path) end + private :install_win, :uninstall_win class Event - def initialize(seq,a,b,c,d,f,h,k,m,o,p,s,t,w,x,y, + module TypeNum + KeyPress = 2 + KeyRelease = 3 + ButtonPress = 4 + ButtonRelease = 5 + MotionNotify = 6 + EnterNotify = 7 + LeaveNotify = 8 + FocusIn = 9 + FocusOut = 10 + KeymapNotify = 11 + Expose = 12 + GraphicsExpose = 13 + NoExpose = 14 + VisibilityNotify = 15 + CreateNotify = 16 + DestroyNotify = 17 + UnmapNotify = 18 + MapNotify = 19 + MapRequest = 20 + ReparentNotify = 21 + ConfigureNotify = 22 + ConfigureRequest = 23 + GravityNotify = 24 + ResizeRequest = 25 + CirculateNotify = 26 + CirculateRequest = 27 + PropertyNotify = 28 + SelectionClear = 29 + SelectionRequest = 30 + SelectionNotify = 31 + ColormapNotify = 32 + ClientMessage = 33 + MappingNotify = 34 + end + + EV_KEY = '#abcdfhikmopstwxyABDEKNRSTWXY' + EV_TYPE = 'nsnnsbnsnsbsxnnnnsnnbsnssnwnn' + + def self.scan_args(arg_str, arg_val) + arg_cnv = [] + arg_str.strip.split(/\s+/).each_with_index{|kwd,idx| + if kwd =~ /^%(.)$/ + if num = EV_KEY.index($1) + case EV_TYPE[num] + when ?n + arg_cnv << TkComm::number(arg_val[idx]) + when ?s + arg_cnv << TkComm::string(arg_val[idx]) + when ?b + arg_cnv << TkComm::bool(arg_val[idx]) + when ?w + arg_cnv << TkComm::window(arg_val[idx]) + when ?x + begin + arg_cnv << TkComm::number(arg_val[idx]) + rescue ArgumentError + arg_cnv << arg_val[idx] + end + else + arg_cnv << arg_val[idx] + end + else + arg_cnv << arg_val[idx] + end + else + arg_cnv << arg_val[idx] + end + } + arg_cnv + end + + def initialize(seq,a,b,c,d,f,h,i,k,m,o,p,s,t,w,x,y, aa,bb,dd,ee,kk,nn,rr,ss,tt,ww,xx,yy) @serial = seq @above = a @num = b @count = c @detail = d - @focus = (f == 1) + @focus = f @height = h + @win_hex = i @keycode = k @mode = m - @override = (o == 1) + @override = o @place = p @state = s @time = t @@ -318,7 +418,7 @@ module TkComm @char = aa @borderwidth = bb @wheel_delta = dd - @send_event = (ee == 1) + @send_event = ee @keysym = kk @keysym_num = nn @rootwin_id = rr @@ -335,6 +435,7 @@ module TkComm attr :detail attr :focus attr :height + attr :win_hex attr :keycode attr :mode attr :override @@ -361,15 +462,16 @@ module TkComm def install_bind(cmd, args=nil) if args id = install_cmd(proc{|*arg| - TkUtil.eval_cmd cmd, *arg + TkUtil.eval_cmd(cmd, *Event.scan_args(args, arg)) }) id + " " + args else + args = ' %# %a %b %c %d %f %h %i %k %m %o %p %s %t %w %x %y' + + ' %A %B %D %E %K %N %R %S %T %W %X %Y' id = install_cmd(proc{|*arg| - TkUtil.eval_cmd cmd, Event.new(*arg) + TkUtil.eval_cmd(cmd, Event.new(*Event.scan_args(args, arg))) }) - id + ' %# %a %b %c %d %f %h %k %m %o %p %s %t %w %x %y' + - ' %A %B %D %E %K %N %R %S %T %W %X %Y' + id + args end end @@ -445,14 +547,17 @@ module TkComm def bind(tagOrClass, context, cmd=Proc.new, args=nil) _bind(["bind", tagOrClass], context, cmd, args) + tagOrClass end def bind_append(tagOrClass, context, cmd=Proc.new, args=nil) _bind_append(["bind", tagOrClass], context, cmd, args) + tagOrClass end def bind_remove(tagOrClass, context) _bind_remove(['bind', tagOrClass], context) + tagOrClass end def bindinfo(tagOrClass, context=nil) @@ -461,10 +566,17 @@ module TkComm def bind_all(context, cmd=Proc.new, args=nil) _bind(['bind', 'all'], context, cmd, args) + TkBindTag::ALL end def bind_append_all(context, cmd=Proc.new, args=nil) _bind_append(['bind', 'all'], context, cmd, args) + TkBindTag::ALL + end + + def bind_remove_all(context) + _bind_remove(['bind', 'all'], context) + TkBindTag::ALL end def bindinfo_all(context=nil) @@ -584,10 +696,15 @@ module TkCore end def TkCore.callback(arg) - arg = tk_split_list(arg) + # arg = tk_split_list(arg) + arg = tk_split_simplelist(arg) _get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg)) end + def windowingsystem + tk_call('tk', 'windowingsystem') + end + def scaling(scale=nil) if scale tk_call('tk', 'scaling', scale) @@ -669,14 +786,15 @@ module TkCore end def restart(app_name = nil, use = nil) + TkComm::INITIALIZE_TARGETS.each{|m| m.__init_tables__ } + tk_call('set', 'argv0', app_name) if app_name if use tk_call('set', 'argc', 2) tk_call('set', 'argv', "-use #{use}") end - TkCore::INTERP.restart - TkComm::Tk_CMDTBL.clear - TkComm::Tk_WINDOWS.clear + + INTERP.restart nil end @@ -702,6 +820,10 @@ module TkCore tk_call 'tk_getSaveFile', *hash_kv(keys) end + def chooseDirectory(keys = nil) + tk_call 'tk_chooseDIrectory', *hash_kv(keys) + end + def chooseColor(keys = nil) tk_call 'tk_chooseColor', *hash_kv(keys) end @@ -722,7 +844,8 @@ module TkCore err = $! begin args.unshift "unknown" - res = INTERP._invoke(*args) + #res = INTERP._invoke(*args) + res = INTERP._invoke(*args).taint rescue fail unless /^invalid command/ =~ $! fail err @@ -795,39 +918,82 @@ module Tk include TkCore extend Tk - TCL_VERSION = INTERP._invoke("info", "tclversion") - TK_VERSION = INTERP._invoke("set", "tk_version") + TCL_VERSION = INTERP._invoke("info", "tclversion").freeze + TK_VERSION = INTERP._invoke("set", "tk_version").freeze - TCL_PATCHLEVEL = INTERP._invoke("info", "patchlevel") - TK_PATCHLEVEL = INTERP._invoke("set", "tk_patchLevel") + TCL_PATCHLEVEL = INTERP._invoke("info", "patchlevel").freeze + TK_PATCHLEVEL = INTERP._invoke("set", "tk_patchLevel").freeze - TCL_LIBRARY = INTERP._invoke("set", "tcl_library") - TK_LIBRARY = INTERP._invoke("set", "tk_library") - LIBRARY = INTERP._invoke("info", "library") + TCL_LIBRARY = INTERP._invoke("set", "tcl_library").freeze + TK_LIBRARY = INTERP._invoke("set", "tk_library").freeze + LIBRARY = INTERP._invoke("info", "library").freeze PLATFORM = Hash[*tk_split_simplelist(INTERP._eval('array get tcl_platform'))] + PLATFORM.each{|k, v| k.freeze; v.freeze} + PLATFORM.freeze - JAPANIZED_TK = (INTERP._invoke("info", "commands", "kanji") != "") + TK_PREV = {} + Hash[*tk_split_simplelist(INTERP._eval('array get tkPriv'))].each{|k,v| + k.freeze + case v + when /^-?\d+$/ + TK_PREV[k] = v.to_i + when /^-?\d+\.?\d*(e[-+]?\d+)?$/ + TK_PREV[k] = v.to_f + else + TK_PREV[k] = v.freeze + end + } + TK_PREV.freeze + + JAPANIZED_TK = (INTERP._invoke("info", "commands", "kanji") != "").freeze def root TkRoot.new end - def bell - tk_call 'bell' + def bell(nice = false) + if nice + tk_call 'bell', '-nice' + else + tk_call 'bell' + end + end + + def bell_on_display(win, nice = false) + if nice + tk_call('bell', '-displayof', win, '-nice') + else + tk_call('bell', '-displayof', win) + end + end + + def Tk.destroy(*wins) + tk_call('destroy', *wins) + end + + def Tk.current_grabs + tk_split_list(tk_call('grab', 'current')) end def Tk.focus(display=nil) if display == nil - r = tk_call('focus') + window(tk_call('focus')) else - r = tk_call('focus', '-displayof', display) + window(tk_call('focus', '-displayof', display)) end - tk_tcl2ruby(r) end def Tk.focus_lastfor(win) - tk_tcl2ruby(tk_call('focus', '-lastfor', win)) + window(tk_call('focus', '-lastfor', win)) + end + + def Tk.focus_next(win) + TkManageFocus.next(win) + end + + def Tk.focus_prev(win) + TkManageFocus.prev(win) end def Tk.strictMotif(bool=None) @@ -911,78 +1077,175 @@ module Tk include TkComm def aspect(*args) w = tk_call('wm', 'aspect', path, *args) - list(w) if args.length == 0 + if args.length == 0 + list(w) + else + self + end + end + def attributes(slot=nil,value=None) + if slot == nil + lst = tk_split_list(tk_call('wm', 'attributes', path)) + info = {} + while key = lst.shift + info[key[1..-1]] = lst.shift + end + info + elsif slot.kind_of? Hash + tk_call('wm', 'attributes', path, *hash_kv(slot)) + self + elsif value == None + tk_call('wm', 'attributes', path, "-#{slot}") + else + tk_call('wm', 'attributes', path, "-#{slot}", value) + self + end end def client(name=None) - tk_call 'wm', 'client', path, name + if name == None + tk_call 'wm', 'client', path + else + name = '' if name == nil + tk_call 'wm', 'client', path, name + self + end end def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) + r = tk_call('wm', 'colormapwindows', path, *args) + if args.size == 0 + list(r) + else + self + end end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) + def wm_command(value=nil) + if value + tk_call('wm', 'command', path, value) + self + else + procedure(tk_call('wm', 'command', path)) + end end def deiconify tk_call 'wm', 'deiconify', path + self end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args + def focusmodel(mode = nil) + if mode + tk_call 'wm', 'focusmodel', path, mode + self + else + tk_call 'wm', 'focusmodel', path + end end def frame tk_call('wm', 'frame', path) end - def geometry(*args) - tk_call('wm', 'geometry', path, *args) + def geometry(geom) + if geom + tk_call('wm', 'geometry', path, geom) + self + else + tk_call('wm', 'geometry', path) + end end def grid(*args) w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 + if args.size == 0 + list(w) + else + self + end end def group(*args) w = tk_call 'wm', 'group', path, *args - window(w) if args.size == 0 + if args.size == 0 + window(w) + else + self + end end - def iconbitmap(*args) - tk_call 'wm', 'iconbitmap', path, *args + def iconbitmap(bmp=nil) + if bmp + tk_call 'wm', 'iconbitmap', path, bmp + self + else + tk_call 'wm', 'iconbitmap', path + end end def iconify tk_call 'wm', 'iconify', path + self end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args + def iconmask(bmp=nil) + if bmp + tk_call 'wm', 'iconmask', path, bmp + self + else + tk_call 'wm', 'iconmask', path + end end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args + def iconname(name=nil) + if name + tk_call 'wm', 'iconname', path, name + self + else + tk_call 'wm', 'iconname', path + end end def iconposition(*args) w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 + if args.size == 0 + list(w) + else + self + end end def iconwindow(*args) w = tk_call('wm', 'iconwindow', path, *args) - window(w) if args.size == 0 + if args.size == 0 + window(w) + else + self + end end def maxsize(*args) w = tk_call('wm', 'maxsize', path, *args) - list(w) if args.size == 0 + if args.size == 0 + list(w) + else + self + end end def minsize(*args) w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 + if args.size == 0 + list(w) + else + self + end end def overrideredirect(bool=None) if bool == None bool(tk_call('wm', 'overrideredirect', path)) else tk_call 'wm', 'overrideredirect', path, bool + self end end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args + def positionfrom(who=None) + if who == None + r = tk_call('wm', 'positionfrom', path) + (r == "")? nil: r + else + tk_call('wm', 'positionfrom', path, who) + self + end end def protocol(name=nil, cmd=nil) if cmd tk_call('wm', 'protocol', path, name, cmd) + self elsif name result = tk_call('wm', 'protocol', path, name) (result == "")? nil : tk_tcl2ruby(result) @@ -994,22 +1257,55 @@ module Tk w = tk_call('wm', 'resizable', path, *args) if args.length == 0 list(w).collect{|e| bool(e)} + else + self end end - def sizefrom(*args) - tk_call('wm', 'sizefrom', path, *args) + def sizefrom(who=None) + if who == None + r = tk_call('wm', 'sizefrom', path) + (r == "")? nil: r + else + tk_call('wm', 'sizefrom', path, who) + self + end + end + def stackorder + list(tk_call('wm', 'stackorder', path)) end - def state(state=None) - tk_call 'wm', 'state', path, state + def stackorder_isabove(win) + bool(tk_call('wm', 'stackorder', path, 'isabove', win)) end - def title(*args) - tk_call 'wm', 'title', path, *args + def stackorder_isbelow(win) + bool(tk_call('wm', 'stackorder', path, 'isbelow', win)) end - def transient(*args) - window(tk_call('wm', 'transient', path, *args)) + def state(state=nil) + if state + tk_call 'wm', 'state', path, state + self + else + tk_call 'wm', 'state', path + end + end + def title(str=nil) + if str + tk_call('wm', 'title', path, str) + self + else + tk_call('wm', 'title', path) + end + end + def transient(master=nil) + if master + tk_call('wm', 'transient', path, master) + self + else + window(tk_call('wm', 'transient', path, master)) + end end def withdraw tk_call 'wm', 'withdraw', path + self end end end @@ -1106,19 +1402,19 @@ end module TkBindCore def bind(context, cmd=Proc.new, args=nil) - Tk.bind(to_eval, context, cmd, args) + Tk.bind(self, context, cmd, args) end def bind_append(context, cmd=Proc.new, args=nil) - Tk.bind_append(to_eval, context, cmd, args) + Tk.bind_append(self, context, cmd, args) end def bind_remove(context) - Tk.bind_remove(to_eval, context) + Tk.bind_remove(self, context) end def bindinfo(context=nil) - Tk.bindinfo(to_eval, context) + Tk.bindinfo(self, context) end end @@ -1128,21 +1424,33 @@ class TkBindTag BTagID_TBL = {} Tk_BINDTAG_ID = ["btag00000"] + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + BTagID_TBL.clear + Tk_BINDTAG_ID[0] = "btag00000" + end + def TkBindTag.id2obj(id) BTagID_TBL[id]? BTagID_TBL[id]: id end - ALL = self.new - ALL.instance_eval { - @id = 'all' - BTagID_TBL[@id] = self - } + def TkBindTag.new_by_name(name, *args, &b) + return BTagID_TBL[name] if BTagID_TBL[name] + self.new(*args, &b).instance_eval{ + BTagID_TBL.delete @id + @id = name + BTagID_TBL[@id] = self + } + end - def initialize(*args) + ALL = self.new_by_name('all') + + def initialize(*args, &b) @id = Tk_BINDTAG_ID[0] Tk_BINDTAG_ID[0] = Tk_BINDTAG_ID[0].succ BTagID_TBL[@id] = self - bind(*args) if args != [] + bind(*args, &b) if args != [] end def to_eval @@ -1155,22 +1463,48 @@ class TkBindTag end class TkBindTagAll<TkBindTag - def TkBindTagAll.new(*args) + def TkBindTagAll.new(*args, &b) $stderr.puts "Warning: TkBindTagALL is obsolete. Use TkBindTag::ALL\n" - TkBindTag::ALL.bind(*args) if args != [] + TkBindTag::ALL.bind(*args, &b) if args != [] TkBindTag::ALL end end +class TkDatabaseClass<TkBindTag + def self.new(name, *args, &b) + return BTagID_TBL[name] if BTagID_TBL[name] + super(name, *args, &b) + end + + def initialize(name, *args, &b) + @id = name + BTagID_TBL[@id] = self + bind(*args, &b) if args != [] + end + + def inspect + format "#<TkDatabaseClass: %s>", @id + end +end + class TkVariable include Tk extend TkCore TkVar_CB_TBL = {} + TkVar_ID_TBL = {} Tk_VARIABLE_ID = ["v00000"] - INTERP._invoke("proc", "rb_var", "args", "ruby [format \"TkVariable.callback %%Q!%s!\" $args]") + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + # cannot clear + # Tcl interpreter may keeps callbacks + end + + INTERP._invoke("proc", "rb_var", "args", + "ruby [format \"TkVariable.callback %%Q!%s!\" $args]") def TkVariable.callback(args) name1,name2,op = tk_split_list(args) @@ -1184,6 +1518,7 @@ class TkVariable def initialize(val="") @id = Tk_VARIABLE_ID[0] Tk_VARIABLE_ID[0] = Tk_VARIABLE_ID[0].succ + TkVar_ID_TBL[@id] = self if val == [] INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)', @id, @id, @id)) @@ -1281,7 +1616,7 @@ class TkVariable def ==(other) case other when TkVariable - self.equal(other) + self.equal?(other) when String self.to_s == other when Integer @@ -1446,8 +1781,14 @@ class TkVariable end class TkVarAccess<TkVariable + def self.new(name, *args) + return TkVar_ID_TBL[name] if TkVar_ID_TBL[name] + super(name, *args) + end + def initialize(varname, val=nil) @id = varname + TkVar_ID_TBL[@id] = self if val s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #" INTERP._eval(format('global %s; set %s %s', @id, @id, s)) @@ -1468,31 +1809,83 @@ module Tk AUTO_PATH = TkVarAccess.new('auto_path', auto_path) TCL_PACKAGE_PATH = TkVarAccess.new('tcl_pkgPath') + + TCL_PRECISION = TkVarAccess.new('tcl_precision') end module TkSelection include Tk extend Tk - def clear(win=Tk.root) - tk_call 'selection', 'clear', win.path + + def self.clear(sel=nil) + if sel + tk_call 'selection', 'clear', '-selection', sel + else + tk_call 'selection', 'clear' + end end - def get(type=None) - tk_call 'selection', 'get', type + def self.clear_on_display(win, sel=nil) + if sel + tk_call 'selection', 'clear', '-displayof', win, '-selection', sel + else + tk_call 'selection', 'clear', '-displayof', win + end end - def TkSelection.handle(win, func, type=None, format=None) - tk_call 'selection', 'handle', win.path, func, type, format + def clear(sel=nil) + TkSelection.clear_on_display(self, sel) + self end - def handle(func, type=None, format=None) - TkSelection.handle self, func, type, format + + def self.get(keys=nil) + tk_call 'selection', 'get', *hash_kv(keys) end - def TkSelection.own(win=None, func=None) - window(tk_call('selection', 'own', win, func)) + def self.get_on_display(win, keys=nil) + tk_call 'selection', 'get', '-displayof', win, *hash_kv(keys) end - def own(func=None) - TkSelection.own self, func + def get(keys=nil) + TkSelection.get_on_display(self, sel) end - module_function :clear, :get + def self.handle(win, func=Proc.new, keys=nil, &b) + if func.kind_of?(Hash) && keys == nil + keys = func + func = Proc.new(&b) + end + args = ['selection', 'handle'] + args += hash_kv(keys) + args += [win, func] + tk_call(*args) + end + def handle(func=Proc.new, keys=nil, &b) + TkSelection.handle(self, func, keys, &b) + end + + def self.get_owner(sel=nil) + if sel + window(tk_call('selection', 'own', '-selection', sel)) + else + window(tk_call('selection', 'own')) + end + end + def self.get_owner_on_display(win, sel=nil) + if sel + window(tk_call('selection', 'own', '-displayof', win, '-selection', sel)) + else + window(tk_call('selection', 'own', '-displayof', win)) + end + end + def get_owner(sel=nil) + TkSelection.get_owner_on_display(self, sel) + self + end + + def self.set_owner(win, keys=nil) + tk_call('selection', 'own', *(hash_kv(keys) << win)) + end + def set_owner(keys=nil) + TkSelection.set_owner(self, keys) + self + end end module TkKinput @@ -1577,6 +1970,20 @@ module TkXIM end end + def TkXIM.caret(window, keys=nil) + if keys + tk_call('tk', 'caret', window, *hash_kv(keys)) + self + else + lst = tk_split_list(tk_call('tk', 'caret', window)) + info = {} + while key = lst.shift + info[key[1..-1]] = lst.shift + end + info + end + end + def TkXIM.configure(window, slot, value=None) begin if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK @@ -1615,36 +2022,52 @@ module TkXIM TkXIM.useinputmethods(self, value) end - def imconfigure(window, slot, value=None) - TkXIM.configinfo(window, slot, value) + def caret(keys=nil) + TkXIM.caret(self, keys=nil) + end + + def imconfigure(slot, value=None) + TkXIM.configinfo(self, slot, value) end def imconfiginfo(slot=nil) - TkXIM.configinfo(window, slot) + TkXIM.configinfo(self, slot) end end module TkWinfo include Tk extend Tk - def TkWinfo.atom(name) - number(tk_call('winfo', 'atom', name)) + + def TkWinfo.atom(name, win=nil) + if win + number(tk_call('winfo', 'atom', '-displayof', win, name)) + else + number(tk_call('winfo', 'atom', name)) + end end def winfo_atom(name) - TkWinfo.atom name + TkWinfo.atom(name, self) end - def TkWinfo.atomname(id) - tk_call 'winfo', 'atomname', id + + def TkWinfo.atomname(id, win=nil) + if win + tk_call('winfo', 'atomname', '-displayof', win, id) + else + tk_call('winfo', 'atomname', id) + end end def winfo_atomname(id) - TkWinfo.atomname id + TkWinfo.atomname(id, self) end + def TkWinfo.cells(window) number(tk_call('winfo', 'cells', window.path)) end def winfo_cells TkWinfo.cells self end + def TkWinfo.children(window) c = tk_call('winfo', 'children', window.path) list(c) @@ -1652,61 +2075,75 @@ module TkWinfo def winfo_children TkWinfo.children self end + def TkWinfo.classname(window) tk_call 'winfo', 'class', window.path end def winfo_classname TkWinfo.classname self end + alias winfo_class winfo_classname + def TkWinfo.colormapfull(window) bool(tk_call('winfo', 'colormapfull', window.path)) end def winfo_colormapfull TkWinfo.colormapfull self end - def TkWinfo.containing(rootX, rootY) - path = tk_call('winfo', 'containing', rootX, rootY) - window(path) + + def TkWinfo.containing(rootX, rootY, win=nil) + if win + window(tk_call('winfo', 'containing', '-displayof', win, rootX, rootY)) + else + window(tk_call('winfo', 'containing', rootX, rootY)) + end end def winfo_containing(x, y) - TkWinfo.containing x, y + TkWinfo.containing(x, y, self) end + def TkWinfo.depth(window) number(tk_call('winfo', 'depth', window.path)) end def winfo_depth TkWinfo.depth self end + def TkWinfo.exist?(window) bool(tk_call('winfo', 'exists', window.path)) end def winfo_exist? TkWinfo.exist? self end - def TkWinfo.fpixels(window, number) - number(tk_call('winfo', 'fpixels', window.path, number)) + + def TkWinfo.fpixels(window, dist) + number(tk_call('winfo', 'fpixels', window.path, dist)) end - def winfo_fpixels(number) - TkWinfo.fpixels self, number + def winfo_fpixels(dist) + TkWinfo.fpixels self, dist end + def TkWinfo.geometry(window) tk_call('winfo', 'geometry', window.path) end def winfo_geometry TkWinfo.geometry self end + def TkWinfo.height(window) number(tk_call('winfo', 'height', window.path)) end def winfo_height TkWinfo.height self end + def TkWinfo.id(window) tk_call('winfo', 'id', window.path) end def winfo_id TkWinfo.id self end + def TkWinfo.interps(window=nil) if window tk_split_simplelist(tk_call('winfo', 'interps', @@ -1718,215 +2155,253 @@ module TkWinfo def winfo_interps TkWinfo.interps self end + def TkWinfo.mapped?(window) bool(tk_call('winfo', 'ismapped', window.path)) end def winfo_mapped? TkWinfo.mapped? self end + def TkWinfo.manager(window) tk_call('winfo', 'manager', window.path) end def winfo_manager TkWinfo.manager self end + def TkWinfo.appname(window) tk_call('winfo', 'name', window.path) end def winfo_appname TkWinfo.appname self end + def TkWinfo.parent(window) window(tk_call('winfo', 'parent', window.path)) end def winfo_parent TkWinfo.parent self end - def TkWinfo.widget(id) - window(tk_call('winfo', 'pathname', id)) + + def TkWinfo.widget(id, win=nil) + if win + window(tk_call('winfo', 'pathname', '-displayof', win, id)) + else + window(tk_call('winfo', 'pathname', id)) + end end def winfo_widget(id) - TkWinfo.widget id + TkWinfo.widget id, self end - def TkWinfo.pixels(window, number) - number(tk_call('winfo', 'pixels', window.path, number)) + + def TkWinfo.pixels(window, dist) + number(tk_call('winfo', 'pixels', window.path, dist)) end - def winfo_pixels(number) - TkWinfo.pixels self, number + def winfo_pixels(dist) + TkWinfo.pixels self, dist end + def TkWinfo.reqheight(window) number(tk_call('winfo', 'reqheight', window.path)) end def winfo_reqheight TkWinfo.reqheight self end + def TkWinfo.reqwidth(window) number(tk_call('winfo', 'reqwidth', window.path)) end def winfo_reqwidth TkWinfo.reqwidth self end + def TkWinfo.rgb(window, color) list(tk_call('winfo', 'rgb', window.path, color)) end def winfo_rgb(color) TkWinfo.rgb self, color end + def TkWinfo.rootx(window) number(tk_call('winfo', 'rootx', window.path)) end def winfo_rootx TkWinfo.rootx self end + def TkWinfo.rooty(window) number(tk_call('winfo', 'rooty', window.path)) end def winfo_rooty TkWinfo.rooty self end + def TkWinfo.screen(window) tk_call 'winfo', 'screen', window.path end def winfo_screen TkWinfo.screen self end + def TkWinfo.screencells(window) number(tk_call('winfo', 'screencells', window.path)) end def winfo_screencells TkWinfo.screencells self end + def TkWinfo.screendepth(window) number(tk_call('winfo', 'screendepth', window.path)) end def winfo_screendepth TkWinfo.screendepth self end + def TkWinfo.screenheight (window) number(tk_call('winfo', 'screenheight', window.path)) end def winfo_screenheight TkWinfo.screenheight self end + def TkWinfo.screenmmheight(window) number(tk_call('winfo', 'screenmmheight', window.path)) end def winfo_screenmmheight TkWinfo.screenmmheight self end + def TkWinfo.screenmmwidth(window) number(tk_call('winfo', 'screenmmwidth', window.path)) end def winfo_screenmmwidth TkWinfo.screenmmwidth self end + def TkWinfo.screenvisual(window) - tk_call 'winfo', 'screenvisual', window.path + tk_call('winfo', 'screenvisual', window.path) end def winfo_screenvisual TkWinfo.screenvisual self end + def TkWinfo.screenwidth(window) number(tk_call('winfo', 'screenwidth', window.path)) end def winfo_screenwidth TkWinfo.screenwidth self end + def TkWinfo.server(window) tk_call 'winfo', 'server', window.path end def winfo_server TkWinfo.server self end + def TkWinfo.toplevel(window) window(tk_call('winfo', 'toplevel', window.path)) end def winfo_toplevel TkWinfo.toplevel self end + def TkWinfo.visual(window) - tk_call 'winfo', 'visual', window.path + tk_call('winfo', 'visual', window.path) end def winfo_visual TkWinfo.visual self end + def TkWinfo.visualid(window) - tk_call 'winfo', 'visualid', window.path + tk_call('winfo', 'visualid', window.path) end def winfo_visualid TkWinfo.visualid self end + def TkWinfo.visualsavailable(window, includeids=false) if includeids - v = tk_call('winfo', 'visualsavailable', window.path, "includeids") + list(tk_call('winfo', 'visualsavailable', window.path, "includeids")) else - v = tk_call('winfo', 'visualsavailable', window.path) + list(tk_call('winfo', 'visualsavailable', window.path)) end - list(v) end def winfo_visualsavailable(includeids=false) TkWinfo.visualsavailable self, includeids end + def TkWinfo.vrootheight(window) number(tk_call('winfo', 'vrootheight', window.path)) end def winfo_vrootheight TkWinfo.vrootheight self end + def TkWinfo.vrootwidth(window) number(tk_call('winfo', 'vrootwidth', window.path)) end def winfo_vrootwidth TkWinfo.vrootwidth self end + def TkWinfo.vrootx(window) number(tk_call('winfo', 'vrootx', window.path)) end def winfo_vrootx TkWinfo.vrootx self end + def TkWinfo.vrooty(window) number(tk_call('winfo', 'vrooty', window.path)) end def winfo_vrooty TkWinfo.vrooty self end + def TkWinfo.width(window) number(tk_call('winfo', 'width', window.path)) end def winfo_width TkWinfo.width self end + def TkWinfo.x(window) number(tk_call('winfo', 'x', window.path)) end def winfo_x TkWinfo.x self end + def TkWinfo.y(window) number(tk_call('winfo', 'y', window.path)) end def winfo_y TkWinfo.y self end + def TkWinfo.viewable(window) bool(tk_call('winfo', 'viewable', window.path)) end def winfo_viewable TkWinfo.viewable self end + def TkWinfo.pointerx(window) number(tk_call('winfo', 'pointerx', window.path)) end def winfo_pointerx TkWinfo.pointerx self end + def TkWinfo.pointery(window) number(tk_call('winfo', 'pointery', window.path)) end def winfo_pointery TkWinfo.pointery self end + def TkWinfo.pointerxy(window) list(tk_call('winfo', 'pointerxy', window.path)) end @@ -2006,7 +2481,7 @@ module TkGrid def columnconfiginfo(master, index, slot=nil) if slot - tk_call 'grid', 'columnconfigure', master, index, "-#{slot}" + tk_call('grid', 'columnconfigure', master, index, "-#{slot}").to_i else ilist = list(tk_call('grid', 'columnconfigure', master, index)) info = {} @@ -2019,7 +2494,7 @@ module TkGrid def rowconfiginfo(master, index, slot=nil) if slot - tk_call 'grid', 'rowconfigure', master, index, "-#{slot}" + tk_call('grid', 'rowconfigure', master, index, "-#{slot}").to_i else ilist = list(tk_call('grid', 'rowconfigure', master, index)) info = {} @@ -2121,19 +2596,27 @@ module TkPlace module_function :configure, :configinfo, :forget, :info, :slaves end -module TkOption +module TkOptionDB include Tk extend Tk - def add pat, value, pri=None + + module Priority + WidgetDefault = 20 + StartupFile = 40 + UserDefault = 60 + Interactive = 80 + end + + def add(pat, value, pri=None) tk_call 'option', 'add', pat, value, pri end def clear tk_call 'option', 'clear' end - def get win, name, klass + def get(win, name, klass) tk_call('option', 'get', win ,name, klass).taint end - def readfile file, pri=None + def readfile(file, pri=None) tk_call 'option', 'readfile', file, pri end module_function :add, :clear, :get, :readfile @@ -2160,7 +2643,7 @@ module TkOption raise NoMethodError, "not support resource-proc '#{id.id2name}' for #{self.name}" end - proc_str = TkOption.get(self::CARRIER, id.id2name, '') + proc_str = TkOptionDB.get(self::CARRIER, id.id2name, '') proc_str = '{' + proc_str + '}' unless /\A\{.*\}\Z/ =~ proc_str proc_str = __check_proc_string__(proc_str) res_proc = eval 'Proc.new' + proc_str @@ -2194,7 +2677,7 @@ module TkOption carrier = Tk.tk_call('frame', @path, '-class', klass) body = <<-"EOD" - class #{klass} < TkOption.module_eval('@@resource_proc_class') + class #{klass} < TkOptionDB.module_eval('@@resource_proc_class') CARRIER = '#{carrier}'.freeze METHOD_TBL = {} ADD_METHOD = #{add} @@ -2208,11 +2691,12 @@ module TkOption eval parent.name + '::' + klass else eval body - eval 'TkOption::' + klass + eval 'TkOptionDB::' + klass end end module_function :new_proc_class end +TkOption = TkOptionDB module TkTreatFont def font_configinfo @@ -2260,6 +2744,7 @@ module TkTreatFont else fobj.latin_replace(ltn) end + self end alias asciifont_configure latinfont_configure @@ -2276,6 +2761,7 @@ module TkTreatFont else fobj.kanji_replace(knj) end + self end def font_copy(window, tag=nil) @@ -2291,6 +2777,7 @@ module TkTreatFont } fontobj.replace(window.fontobj.latin_font, window.fontobj.kanji_font) end + self end def latinfont_copy(window, tag=nil) @@ -2299,6 +2786,7 @@ module TkTreatFont else fontobj.latin_replace(window.fontobj.latin_font) end + self end alias asciifont_copy latinfont_copy @@ -2308,6 +2796,7 @@ module TkTreatFont else fontobj.kanji_replace(window.fontobj.kanji_font) end + self end end @@ -2374,6 +2863,7 @@ module TkTreatItemFont else fobj.latin_replace(ltn) end + self end alias asciitagfont_configure latintagfont_configure @@ -2393,6 +2883,7 @@ module TkTreatItemFont else fobj.kanji_replace(knj) end + self end def tagfont_copy(tagOrId, window, wintag=nil) @@ -2409,6 +2900,7 @@ module TkTreatItemFont tagfontobj(tagOrId).replace(window.fontobj.latin_font, window.fontobj.kanji_font) end + self end def latintagfont_copy(tagOrId, window, wintag=nil) @@ -2417,6 +2909,7 @@ module TkTreatItemFont else tagfontobj(tagOrId).latin_replace(window.fontobj.latin_font) end + self end alias asciitagfont_copy latintagfont_copy @@ -2426,6 +2919,7 @@ module TkTreatItemFont else tagfontobj(tagOrId).kanji_replace(window.fontobj.kanji_font) end + self end end @@ -2577,7 +3071,8 @@ class TkObject<TkKernel def tk_trace_variable(v) unless v.kind_of?(TkVariable) - fail ArgumentError, format("requires TkVariable given %s", v.type) + fail ArgumentError, + format("type error (%s); must be TkVariable object", v.class) end v end @@ -2591,6 +3086,11 @@ end class TkWindow<TkObject extend TkBindCore + WidgetClassName = ''.freeze + def self.to_eval + self::WidgetClassName + end + def initialize(parent=nil, keys=nil) if parent.kind_of? Hash keys = _symbolkey2str(parent) @@ -2598,26 +3098,26 @@ class TkWindow<TkObject parent = keys.delete('parent') widgetname = keys.delete('widgetname') install_win(if parent then parent.path end, widgetname) - no_create = keys.delete('no_create') - if no_create && !widgetname + without_creating = keys.delete('without_creating') + if without_creating && !widgetname fail ArgumentError, - "if 'no_create' option set true, need to define 'widgetname'" + "if set 'without_creating' to true, need to define 'widgetname'" end elsif keys keys = _symbolkey2str(keys) widgetname = keys.delete('widgetname') install_win(if parent then parent.path end, widgetname) - no_create = keys.delete('no_create') - if no_create && !widgetname + without_creating = keys.delete('without_creating') + if without_creating && !widgetname fail ArgumentError, - "if 'no_create' option set true, need to define 'widgetname'" + "if set 'without_creating' to true, need to define 'widgetname'" end else install_win(if parent then parent.path end) end if self.method(:create_self).arity == 0 p 'create_self has no arg' if $DEBUG - create_self unless no_create + create_self unless without_creating if keys # tk_call @path, 'configure', *hash_kv(keys) configure(keys) @@ -2630,7 +3130,7 @@ class TkWindow<TkObject fontkeys[key] = keys.delete(key) if keys.key?(key) } end - if no_create && keys + if without_creating && keys configure(keys) else create_self(keys) @@ -2643,11 +3143,30 @@ class TkWindow<TkObject end private :create_self + def bind_class + @db_class || self.class() + end + + def database_class + TkWinfo.classname(self) + end + def pack(keys = nil) tk_call 'pack', epath, *hash_kv(keys) self end + def pack_in(target, keys = nil) + if keys + keys = keys.dup + keys['in'] = target + else + keys = {'in'=>target} + end + tk_call 'pack', epath, *hash_kv(keys) + self + end + def unpack tk_call 'pack', 'forget', epath self @@ -2688,6 +3207,17 @@ class TkWindow<TkObject self end + def grid_in(target, keys = nil) + if keys + keys = keys.dup + keys['in'] = target + else + keys = {'in'=>target} + end + tk_call 'grid', epath, *hash_kv(keys) + self + end + def ungrid tk_call 'grid', 'forget', epath self @@ -2716,7 +3246,7 @@ class TkWindow<TkObject def grid_columnconfiginfo(index, slot=nil) if slot - tk_call('grid', 'columnconfigure', epath, index, "-#{slot}") + tk_call('grid', 'columnconfigure', epath, index, "-#{slot}").to_i else ilist = list(tk_call('grid', 'columnconfigure', epath, index)) info = {} @@ -2729,7 +3259,7 @@ class TkWindow<TkObject def grid_rowconfiginfo(index, slot=nil) if slot - tk_call('grid', 'rowconfigure', epath, index, "-#{slot}") + tk_call('grid', 'rowconfigure', epath, index, "-#{slot}").to_i else ilist = list(tk_call('grid', 'rowconfigure', epath, index)) info = {} @@ -2773,6 +3303,17 @@ class TkWindow<TkObject self end + def place_in(target, keys = nil) + if keys + keys = keys.dup + keys['in'] = target + else + keys = {'in'=>target} + end + tk_call 'place', epath, *hash_kv(keys) + self + end + def unplace tk_call 'place', 'forget', epath self @@ -2828,12 +3369,17 @@ class TkWindow<TkObject def grab(*args) if !args or args.length == 0 tk_call 'grab', 'set', path + self elsif args.length == 1 case args[0] when 'global', :global - return(tk_call('grab', 'set', '-global', path)) + #return(tk_call('grab', 'set', '-global', path)) + tk_call('grab', 'set', '-global', path) + return self when 'release', :release - return tk_call('grab', 'release', path) + #return tk_call('grab', 'release', path) + tk_call('grab', 'release', path) + return self else val = tk_call('grab', args[0], path) end @@ -2843,11 +3389,25 @@ class TkWindow<TkObject when 'status', :status return val end + self else fail ArgumentError, 'wrong # of args' end end + def grab_current + grab('current') + end + def grab_set + grab('set') + end + def grab_set_global + grab('global') + end + def grab_status + grab('status') + end + def lower(below=None) tk_call 'lower', epath, below self @@ -2888,8 +3448,9 @@ class TkWindow<TkObject def bindtags(taglist=nil) if taglist - fail ArgumentError unless taglist.kind_of? Array + fail ArgumentError, "taglist must be Array" unless taglist.kind_of? Array tk_call('bindtags', path, taglist) + taglist else list(tk_call('bindtags', path)).collect{|tag| if tag.kind_of?(String) @@ -2906,23 +3467,38 @@ class TkWindow<TkObject } end end + + def bindtags=(taglist) + bindtags(taglist) + end + + def bindtags_shift + taglist = bindtags + tag = taglist.shift + bindtags(taglist) + tag + end + + def bindtags_unshift(tag) + bindtags(bindtags().unshift(tag)) + end end class TkRoot<TkWindow include Wm ROOT = [] def TkRoot.new - return ROOT[0] if ROOT[0] - new = super + if ROOT[0] + Tk_WINDOWS["."] = ROOT[0] + return ROOT[0] + end + new = super(:without_creating=>true, :widgetname=>'.') ROOT[0] = new Tk_WINDOWS["."] = new end WidgetClassName = 'Tk'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end def create_self @path = '.' @@ -2937,9 +3513,6 @@ class TkToplevel<TkWindow WidgetClassName = 'Toplevel'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end ################# old version # def initialize(parent=nil, screen=nil, classname=nil, keys=nil) @@ -2983,18 +3556,24 @@ class TkToplevel<TkWindow @screen = keys['screen'] @use = keys['use'] @visual = keys['visual'] + if @classname.kind_of? TkBindTag + @db_class = @classname + @classname = @classname.id + else + @db_class = TkDatabaseClass.new(@classname) + end super(keys) return end if screen.kind_of? Hash - keys = _symbolkey2str(screen) + keys = screen else @screen = screen end @classname = classname if keys.kind_of? Hash keys = _symbolkey2str(keys) - if keys.key?(:classname) || keys.key?('classname') + if keys.key?('classname') keys['class'] = keys.delete('classname') end @classname = keys['class'] @@ -3004,6 +3583,12 @@ class TkToplevel<TkWindow @use = keys['use'] @visual = keys['visual'] end + if @classname.kind_of? TkBindTag + @db_class = @classname + @classname = @classname.id + else + @db_class = TkDatabaseClass.new(@classname) + end super(parent, keys) end @@ -3023,9 +3608,6 @@ end class TkFrame<TkWindow WidgetClassName = 'Frame'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end ################# old version # def initialize(parent=nil, keys=nil) @@ -3067,6 +3649,12 @@ class TkFrame<TkWindow @colormap = keys['colormap'] @container = keys['container'] @visual = keys['visual'] + if @classname.kind_of? TkBindTag + @db_class = @classname + @classname = @classname.id + else + @db_class = TkDatabaseClass.new(@classname) + end super(keys) end @@ -3077,14 +3665,132 @@ class TkFrame<TkWindow tk_call 'frame', @path end end + + def specific_class + @classname + end +end + +class TkLabelFrame<TkFrame + def create_self(keys) + if keys and keys != None + tk_call 'labelframe', @path, *hash_kv(keys) + else + tk_call 'labelframe', @path + end + end end +class TkPanedWindow<TkWindow + WidgetClassName = 'Panedwindow'.freeze + WidgetClassNames[WidgetClassName] = self + def create_self(keys) + if keys and keys != None + tk_call 'panedwindow', @path, *hash_kv(keys) + else + tk_call 'panedwindow', @path + end + end + + def add(*args) + keys = args.pop + fail ArgumentError, "no window in arguments" unless keys + if keys && keys.kind_of?(Hash) + fail ArgumentError, "no window in arguments" if args == [] + args += hash_kv(keys) + else + args.push(keys) if keys + end + tk_send('add', *args) + self + end + + def forget(win, *wins) + tk_send('forget', win, *wins) + self + end + alias del forget + alias delete forget + alias remove forget + + def identify(x, y) + ######### + end + + def proxy_coord + list(tk_send('proxy', 'coord')) + end + def proxy_forget + tk_send('proxy', 'forget') + self + end + def proxy_place(x, y) + tk_send('proxy', 'place', x, y) + self + end + + def sash_coord(index) + list(tk_send('sash', 'coord', index)) + end + def sash_mark(index, x, y) + tk_send('sash', 'mark', x, y) + self + end + def sash_place(index, x, y) + tk_send('sash', 'place', x, y) + self + end + + def panecget(win, key) + tk_tcl2ruby(tk_send('panecget', win, "-#{key}")) + end + + def paneconfigure(win, key, value=nil) + if key.kind_of? Hash + tk_send('paneconfigure', win, *hash_kv(key)) + else + tk_send('paneconfigure', win, "-#{key}", value) + end + self + end + + def paneconfiginfo(win, key=nil) + if key + conf = tk_split_list(tk_send('paneconfigure', win, "-#{key}")) + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(tk_send('paneconfigure', win)).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + conf + } + end + end + + def panes + list(tk_send('panes')) + end +end +TkPanedwindow = TkPanedWindow + class TkLabel<TkWindow WidgetClassName = 'Label'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end def create_self(keys) if keys and keys != None tk_call 'label', @path, *hash_kv(keys) @@ -3098,10 +3804,8 @@ class TkLabel<TkWindow end class TkButton<TkLabel - WidgetClassNames['Button'] = self - def TkButton.to_eval - 'Button' - end + WidgetClassName = 'Button'.freeze + WidgetClassNames[WidgetClassName] = self def create_self(keys) if keys and keys != None tk_call 'button', @path, *hash_kv(keys) @@ -3114,14 +3818,13 @@ class TkButton<TkLabel end def flash tk_send 'flash' + self end end class TkRadioButton<TkButton - WidgetClassNames['Radiobutton'] = self - def TkRadioButton.to_eval - 'Radiobutton' - end + WidgetClassName = 'Radiobutton'.freeze + WidgetClassNames[WidgetClassName] = self def create_self(keys) if keys and keys != None tk_call 'radiobutton', @path, *hash_kv(keys) @@ -3131,9 +3834,11 @@ class TkRadioButton<TkButton end def deselect tk_send 'deselect' + self end def select tk_send 'select' + self end def variable(v) configure 'variable', tk_trace_variable(v) @@ -3142,10 +3847,8 @@ end TkRadiobutton = TkRadioButton class TkCheckButton<TkRadioButton - WidgetClassNames['Checkbutton'] = self - def TkCheckButton.to_eval - 'Checkbutton' - end + WidgetClassName = 'Checkbutton'.freeze + WidgetClassNames[WidgetClassName] = self def create_self(keys) if keys and keys != None tk_call 'checkbutton', @path, *hash_kv(keys) @@ -3155,15 +3858,14 @@ class TkCheckButton<TkRadioButton end def toggle tk_send 'toggle' + self end end TkCheckbutton = TkCheckButton class TkMessage<TkLabel - WidgetClassNames['Message'] = self - def TkMessage.to_eval - 'Message' - end + WidgetClassName = 'Message'.freeze + WidgetClassNames[WidgetClassName] = self def create_self(keys) if keys and keys != None tk_call 'message', @path, *hash_kv(keys) @@ -3176,9 +3878,6 @@ end class TkScale<TkWindow WidgetClassName = 'Scale'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end def create_self(keys) if keys and keys != None @@ -3216,9 +3915,6 @@ end class TkScrollbar<TkWindow WidgetClassName = 'Scrollbar'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end def create_self(keys) if keys and keys != None @@ -3251,6 +3947,7 @@ class TkScrollbar<TkWindow def set(first, last) tk_send "set", first, last + self end def activate(element=None) @@ -3264,28 +3961,30 @@ class TkTextWin<TkWindow end def bbox(index) - tk_send 'bbox', index + list(tk_send('bbox', index)) end def delete(first, last=None) tk_send 'delete', first, last + self end def get(*index) tk_send 'get', *index end - def index(index) - tk_send 'index', index - end - def insert(index, chars, *args) - tk_send 'insert', index, chars, *args + def insert(index, *args) + tk_send 'insert', index, *args + self end def scan_mark(x, y) tk_send 'scan', 'mark', x, y + self end def scan_dragto(x, y) tk_send 'scan', 'dragto', x, y + self end def see(index) tk_send 'see', index + self end end @@ -3306,10 +4005,9 @@ class TkListbox<TkTextWin include TkTreatListItemFont include Scrollable - WidgetClassNames['Listbox'] = self - def TkListbox.to_eval - 'Listbox' - end + WidgetClassName = 'Listbox'.freeze + WidgetClassNames[WidgetClassName] = self + def create_self(keys) if keys and keys != None tk_call 'listbox', @path, *hash_kv(keys) @@ -3320,6 +4018,7 @@ class TkListbox<TkTextWin def activate(y) tk_send 'activate', y + self end def curselection list(tk_send('curselection')) @@ -3340,23 +4039,30 @@ class TkListbox<TkTextWin end def selection_anchor(index) tk_send 'selection', 'anchor', index + self end def selection_clear(first, last=None) tk_send 'selection', 'clear', first, last + self end def selection_includes(index) bool(tk_send('selection', 'includes', index)) end def selection_set(first, last=None) tk_send 'selection', 'set', first, last + self + end + + def index(index) + tk_send('index', index).to_i end def itemcget(index, key) case key.to_s when 'text', 'label', 'show' - tk_send 'itemcget', index, "-#{key}" + tk_send('itemcget', index, "-#{key}") else - tk_tcl2ruby tk_send('itemcget', index, "-#{key}") + tk_tcl2ruby(tk_send('itemcget', index, "-#{key}")) end end def itemconfigure(index, key, val=None) @@ -3380,6 +4086,7 @@ class TkListbox<TkTextWin tk_call 'itemconfigure', index, "-#{key}", val end end + self end def itemconfiginfo(index, key=nil) @@ -3438,9 +4145,7 @@ class TkMenu<TkWindow WidgetClassName = 'Menu'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end + def create_self(keys) if keys and keys != None tk_call 'menu', @path, *hash_kv(keys) @@ -3450,36 +4155,46 @@ class TkMenu<TkWindow end def activate(index) tk_send 'activate', index + self end def add(type, keys=nil) tk_send 'add', type, *hash_kv(keys) + self end def index(index) - tk_send 'index', index + ret = tk_send('index', index) + (ret == 'none')? nil: number(ret) end def invoke(index) tk_send 'invoke', index end def insert(index, type, keys=nil) tk_send 'insert', index, type, *hash_kv(keys) + self end def delete(index, last=None) tk_send 'delete', index, last + self end def popup(x, y, index=None) - tk_call 'tk_popup', path, x, y, index + tk_call('tk_popup', path, x, y, index) + self end def post(x, y) tk_send 'post', x, y + self end def postcascade(index) tk_send 'postcascade', index + self end def postcommand(cmd=Proc.new) configure_cmd 'postcommand', cmd + self end def tearoffcommand(cmd=Proc.new) configure_cmd 'tearoffcommand', cmd + self end def menutype(index) tk_send 'type', index @@ -3519,6 +4234,7 @@ class TkMenu<TkWindow tk_call 'entryconfigure', index, "-#{key}", val end end + self end def entryconfiginfo(index, key=nil) @@ -3583,8 +4299,10 @@ module TkSystemMenu keys = _symbolkey2str(parent) parent = keys.delete('parent') end - fail unless parent.kind_of? TkMenu - @path = format("%s.%s", parent.path, self.type::SYSMENU_NAME) + unless parent.kind_of? TkMenu + fail ArgumentError, "parent must be a TkMenu object" + end + @path = format("%s.%s", parent.path, self.class::SYSMENU_NAME) TkComm::Tk_WINDOWS[@path] = self if self.method(:create_self).arity == 0 p 'create_self has no arg' if $DEBUG @@ -3616,10 +4334,8 @@ class TkSysMenu_Apple<TkMenu end class TkMenubutton<TkLabel - WidgetClassNames['Menubutton'] = self - def TkMenubutton.to_eval - 'Menubutton' - end + WidgetClassName = 'Menubutton'.freeze + WidgetClassNames[WidgetClassName] = self def create_self(keys) if keys and keys != None tk_call 'menubutton', @path, *hash_kv(keys) @@ -3638,7 +4354,7 @@ class TkOptionMenubutton<TkMenubutton end def initialize(parent=nil, var=TkVariable.new, firstval=nil, *vals) - if parent.kind_of Hash + if parent.kind_of? Hash keys = _symbolkey2str(parent) parent = keys['parent'] var = keys['variable'] if keys['variable'] @@ -3659,10 +4375,12 @@ class TkOptionMenubutton<TkMenubutton def activate(index) @menu.activate(index) + self end def add(value) @menu.add('radiobutton', 'variable'=>@variable, 'label'=>value, 'value'=>value) + self end def index(index) @menu.index(index) @@ -3673,9 +4391,11 @@ class TkOptionMenubutton<TkMenubutton def insert(index, value) @menu.add(index, 'radiobutton', 'variable'=>@variable, 'label'=>value, 'value'=>value) + self end def delete(index, last=None) @menu.delete(index, last) + self end def yposition(index) @menu.yposition(index) @@ -3685,6 +4405,7 @@ class TkOptionMenubutton<TkMenubutton end def menuconfigure(index, key, val=None) @menu.configure(index, key, val) + self end def menuconfiginfo(index, key=nil) @menu.configinfo(index, key) @@ -3694,6 +4415,7 @@ class TkOptionMenubutton<TkMenubutton end def entryconfigure(index, key, val=None) @menu.entryconfigure(index, key, val) + self end def entryconfiginfo(index, key=nil) @menu.entryconfiginfo(index, key) @@ -3764,25 +4486,69 @@ module TkClipboard include Tk extend Tk - def clear - tk_call 'clipboard', 'clear' + def self.clear(win=nil) + if win + tk_call 'clipboard', 'clear', '-displayof', win + else + tk_call 'clipboard', 'clear' + end end - def get - begin - tk_call 'selection', 'get', '-selection', 'CLIPBOARD' - rescue - '' + def self.clear_on_display(win) + tk_call 'clipboard', 'clear', '-displayof', win + end + + def self.get(type=nil) + if type + tk_call 'clipboard', 'get', '-type', type + else + tk_call 'clipboard', 'get' end end - def set(data) + def self.get_on_display(win, type=nil) + if type + tk_call 'clipboard', 'get', '-displayof', win, '-type', type + else + tk_call 'clipboard', 'get', '-displayof', win + end + end + + def self.set(data, keys=nil) clear - append(data) + append(data, keys) end - def append(data) - tk_call 'clipboard', 'append', data + def self.set_on_display(win, data, keys=nil) + clear(win) + append_on_display(win, data, keys) end - module_function :clear, :set, :get, :append + def self.append(data, keys=nil) + args = ['clipboard', 'append'] + args += hash_kv(keys) + args += ['--', data] + tk_call(*args) + end + def self.append_on_display(win, data, keys=nil) + args = ['clipboard', 'append', '-displayof', win] + args += hash_kv(keys) + args += ['--', data] + tk_call(*args) + end + + def clear + TkClipboard.clear_on_display(self) + self + end + def get(type=nil) + TkClipboard.get_on_display(self, type) + end + def set(data, keys=nil) + TkClipboard.set_on_display(self, data, keys) + self + end + def append(data, keys=nil) + TkClipboard.append_on_display(self, data, keys) + self + end end autoload :TkCanvas, 'tkcanvas' @@ -3793,9 +4559,12 @@ autoload :TkEntry, 'tkentry' autoload :TkSpinbox, 'tkentry' autoload :TkText, 'tktext' autoload :TkDialog, 'tkdialog' +autoload :TkDialog2, 'tkdialog' autoload :TkWarning, 'tkdialog' +autoload :TkWarning2, 'tkdialog' autoload :TkMenubar, 'tkmenubar' autoload :TkAfter, 'tkafter' +autoload :TkTimer, 'tkafter' autoload :TkPalette, 'tkpalette' autoload :TkFont, 'tkfont' autoload :TkVirtualEvent, 'tkvirtevent' @@ -3805,3 +4574,4 @@ autoload :TkPalette, 'tkpalette' autoload :TkWinDDE, 'tkwinpkg' autoload :TkWinRegistry, 'tkwinpkg' autoload :TkMacResource, 'tkmacpkg' +autoload :TkConsole, 'tkconsole' diff --git a/ext/tk/lib/tkafter.rb b/ext/tk/lib/tkafter.rb index b7c21e7529..5176db3e35 100644 --- a/ext/tk/lib/tkafter.rb +++ b/ext/tk/lib/tkafter.rb @@ -12,7 +12,15 @@ class TkAfter Tk_CBID = [0] Tk_CBTBL = {} - INTERP._invoke("proc", "rb_after", "id", "ruby [format \"TkAfter.callback %%Q!%s!\" $id]") + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + # cannot clear + # Tcl interpreter may keep callbacks + end + + INTERP._invoke("proc", "rb_after", "id", + "ruby [format \"TkAfter.callback %%Q!%s!\" $id]") ############################### # class methods @@ -310,3 +318,5 @@ class TkAfter end end end + +TkTimer = TkAfter diff --git a/ext/tk/lib/tkbgerror.rb b/ext/tk/lib/tkbgerror.rb index 8022077a3f..e068155b1c 100644 --- a/ext/tk/lib/tkbgerror.rb +++ b/ext/tk/lib/tkbgerror.rb @@ -12,6 +12,16 @@ module TkBgError end alias tkerror bgerror alias show bgerror - module_function :bgerror, :tkerror, :show + + def set_handler(hdlr = Proc.new) #==> handler :: proc{|msg| ...body... } + tk_call('proc', 'bgerror', 'msg', install_cmd(hdlr) + ' $msg') + end + def set_default + begin + tk_call('rename', 'bgerror', '') + rescue RuntimeError + end + end + module_function :set_handler, :set_default end diff --git a/ext/tk/lib/tkcanvas.rb b/ext/tk/lib/tkcanvas.rb index 4a5e4b45bb..ef6b54c876 100644 --- a/ext/tk/lib/tkcanvas.rb +++ b/ext/tk/lib/tkcanvas.rb @@ -31,9 +31,6 @@ class TkCanvas<TkWindow WidgetClassName = 'Canvas'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end def create_self(keys) if keys and keys != None @@ -54,6 +51,7 @@ class TkCanvas<TkWindow def addtag(tag, mode, *args) tk_send 'addtag', tagid(tag), mode, *args + self end def addtag_above(tagOrId, target) addtag(tagOrId, 'above', tagid(target)) @@ -83,10 +81,17 @@ class TkCanvas<TkWindow def itembind(tag, context, cmd=Proc.new, args=nil) _bind([path, "bind", tagid(tag)], context, cmd, args) + self end def itembind_append(tag, context, cmd=Proc.new, args=nil) _bind_append([path, "bind", tagid(tag)], context, cmd, args) + self + end + + def itembind_remove(tag, context) + _bind_remove([path, "bind", tagid(tag)], context) + self end def itembindinfo(tag, context=nil) @@ -104,21 +109,24 @@ class TkCanvas<TkWindow if args == [] tk_split_list(tk_send('coords', tagid(tag))) else - tk_send('coords', tagid(tag), *args) + tk_send('coords', tagid(tag), *(args.flatten)) end end def dchars(tag, first, last=None) tk_send 'dchars', tagid(tag), first, last + self end def delete(*args) tk_send 'delete', *args.collect{|t| tagid(t)} + self end alias remove delete def dtag(tag, tag_to_del=None) tk_send 'dtag', tagid(tag), tag_to_del + self end def find(mode, *args) @@ -151,6 +159,7 @@ class TkCanvas<TkWindow def itemfocus(tagOrId=nil) if tagOrId tk_send 'focus', tagid(tagOrId) + self else ret = tk_send('focus') if ret == "" @@ -169,14 +178,16 @@ class TkCanvas<TkWindow def icursor(tagOrId, index) tk_send 'icursor', tagid(tagOrId), index + self end def index(tagOrId, index) - tk_send 'index', tagid(tagOrId), index + number(tk_send('index', tagid(tagOrId), index)) end def insert(tagOrId, index, string) tk_send 'insert', tagid(tagOrId), index, string + self end def itemcget(tagOrId, option) @@ -215,6 +226,7 @@ class TkCanvas<TkWindow tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value end end + self end # def itemconfigure(tagOrId, key, value=None) # if key.kind_of? Hash @@ -285,10 +297,12 @@ class TkCanvas<TkWindow def lower(tag, below=None) tk_send 'lower', tagid(tag), tagid(below) + self end def move(tag, x, y) tk_send 'move', tagid(tag), x, y + self end def postscript(keys) @@ -297,21 +311,26 @@ class TkCanvas<TkWindow def raise(tag, above=None) tk_send 'raise', tagid(tag), tagid(above) + self end def scale(tag, x, y, xs, ys) tk_send 'scale', tagid(tag), x, y, xs, ys + self end def scan_mark(x, y) tk_send 'scan', 'mark', x, y + self end def scan_dragto(x, y) tk_send 'scan', 'dragto', x, y + self end def select(mode, *args) - tk_send 'select', mode, *args + r = tk_send('select', mode, *args) + (mode == 'item')? TkcItem.id2obj(self, r): self end def select_adjust(tagOrId, index) select('adjust', tagid(tagOrId), index) @@ -340,6 +359,7 @@ module TkcTagAccess def addtag(tag) @c.addtag(tag, 'with', @id) + self end def bbox @@ -348,6 +368,17 @@ module TkcTagAccess def bind(seq, cmd=Proc.new, args=nil) @c.itembind @id, seq, cmd, args + self + end + + def bind_append(seq, cmd=Proc.new, args=nil) + @c.itembind_append @id, seq, cmd, args + self + end + + def bind_remove(seq) + @c.itembind_remove @id, seq + self end def bindinfo(seq=nil) @@ -360,6 +391,7 @@ module TkcTagAccess def configure(key, value=None) @c.itemconfigure @id, key, value + self end # def configure(keys) # @c.itemconfigure @id, keys @@ -375,10 +407,12 @@ module TkcTagAccess def dchars(first, last=None) @c.dchars @id, first, last + self end def dtag(tag_to_del=None) @c.dtag @id, tag_to_del + self end def find @@ -396,6 +430,7 @@ module TkcTagAccess def icursor(index) @c.icursor @id, index + self end def index(index) @@ -404,32 +439,40 @@ module TkcTagAccess def insert(beforethis, string) @c.insert @id, beforethis, string + self end def lower(belowthis=None) @c.lower @id, belowthis + self end def move(xamount, yamount) @c.move @id, xamount, yamount + self end def raise(abovethis=None) @c.raise @id, abovethis + self end def scale(xorigin, yorigin, xscale, yscale) @c.scale @id, xorigin, yorigin, xscale, yscale + self end def select_adjust(index) @c.select('adjust', @id, index) + self end def select_from(index) @c.select('from', @id, index) + self end def select_to(index) @c.select('to', @id, index) + self end def itemtype @@ -478,6 +521,13 @@ class TkcTag<TkObject CTagID_TBL = {} Tk_CanvasTag_ID = ['ctag0000'] + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + CTagID_TBL.clear + Tk_CanvasTag_ID[0] = 'ctag0000' + end + def TkcTag.id2obj(canvas, id) cpath = canvas.path return id unless CTagID_TBL[cpath] @@ -499,48 +549,56 @@ class TkcTag<TkObject end end def id - return @id + @id end def delete @c.delete @id CTagID_TBL[@cpath].delete(@id) if CTagID_TBL[@cpath] + self end alias remove delete alias destroy delete def set_to_above(target) @c.addtag_above(@id, target) + self end alias above set_to_above def set_to_all @c.addtag_all(@id) + self end alias all set_to_all def set_to_below(target) @c.addtag_below(@id, target) + self end alias below set_to_below def set_to_closest(x, y, halo=None, start=None) @c.addtag_closest(@id, x, y, halo, start) + self end alias closest set_to_closest def set_to_enclosed(x1, y1, x2, y2) @c.addtag_enclosed(@id, x1, y1, x2, y2) + self end alias enclosed set_to_enclosed def set_to_overlapping(x1, y1, x2, y2) @c.addtag_overlapping(@id, x1, y1, x2, y2) + self end alias overlapping set_to_overlapping def set_to_withtag(target) @c.addtag_withtag(@id, target) + self end alias withtag set_to_withtag end @@ -615,12 +673,14 @@ class TkcGroup<TkcTag for i in tags i.addtag @id end + self end def exclude(*tags) for i in tags i.delete @id end + self end end @@ -630,6 +690,12 @@ class TkcItem<TkObject CItemTypeToClass = {} CItemID_TBL = {} + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + CItemID_TBL.clear + end + def TkcItem.type2class(type) CItemTypeToClass[type] end @@ -683,12 +749,13 @@ class TkcItem<TkObject def create_self(*args); end private :create_self def id - return @id + @id end def delete @c.delete @id CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] + self end alias remove delete alias destroy delete @@ -753,8 +820,15 @@ class TkImage<TkObject include Tk Tk_IMGTBL = {} - Tk_Image_ID = ['i00000'] + + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + Tk_IMGTBL.clear + Tk_Image_ID[0] = 'i00000' + end + def initialize(keys=nil) @path = Tk_Image_ID[0] Tk_Image_ID[0] = Tk_Image_ID[0].succ @@ -765,6 +839,7 @@ class TkImage<TkObject def delete Tk_IMGTBL.delete(@id) if @id tk_call('image', 'delete', @path) + self end def height number(tk_call('image', 'height', @path)) @@ -805,6 +880,7 @@ class TkPhotoImage<TkImage def blank tk_send 'blank' + self end def cget(option) @@ -826,14 +902,16 @@ class TkPhotoImage<TkImage }.flatten tk_send 'copy', source, *args + + self end def data(keys=nil) - tk_send 'data', *hash_kv(keys) + tk_send('data', *hash_kv(keys)) end def get(x, y) - tk_send 'get', x, y + tk_send('get', x, y).split.collect{|n| n.to_i} end def put(data, *to) @@ -842,6 +920,7 @@ class TkPhotoImage<TkImage else tk_send 'put', data, '-to', *to end + self end def read(file, *opts) @@ -854,10 +933,21 @@ class TkPhotoImage<TkImage }.flatten tk_send 'read', file, *args + + self end def redither tk_send 'redither' + self + end + + def get_transparency(x, y) + bool(tk_send('transparency', 'get', x, y)) + end + def set_transparency(x, y, st) + tk_send('transparency', 'set', x, y, st) + self end def write(file, *opts) @@ -870,5 +960,7 @@ class TkPhotoImage<TkImage }.flatten tk_send 'write', file, *args + + self end end diff --git a/ext/tk/lib/tkconsole.rb b/ext/tk/lib/tkconsole.rb new file mode 100644 index 0000000000..0129501bee --- /dev/null +++ b/ext/tk/lib/tkconsole.rb @@ -0,0 +1,26 @@ +# +# tkconsole.rb : control the console on system without a real console +# +require 'tk' + +module TkConsole + include Tk + extend Tk + + def self.title(str=None) + tk_call 'console', str + end + def self.hide + tk_call 'console', 'hide' + end + def self.show + tk_call 'console', 'show' + end + def self.eval(tcl_script) + # + # supports a Tcl script only + # I have no idea to support a Ruby script seamlessly. + # + tk_call 'console', 'eval', tcl_script + end +end diff --git a/ext/tk/lib/tkdialog.rb b/ext/tk/lib/tkdialog.rb index 8b8ee69128..31d50fc67b 100644 --- a/ext/tk/lib/tkdialog.rb +++ b/ext/tk/lib/tkdialog.rb @@ -1,13 +1,55 @@ require "tk" -class TkDialog < TkWindow +class TkDialog2 < TkWindow extend Tk + def self.show(*args) + dlog = self.new(*args) + dlog.show + dlog + end + + def _set_button_config(configs) + set_config = proc{|c,i| + if $VERBOSE && (c.has_key?('command') || c.has_key?(:command)) + STDERR.print("Warning: cannot give a command option " + + "to the dialog button#{i}. It was removed.\n") + end + c.delete('command'); c.delete(:command) + @config << format("%s.button%s configure %s; ", + @path, i, hash_kv(c).join(' ')) + } + case configs + when Proc + @buttons.each_index{|i| + if (c = configs.call(i)).kind_of? Hash + set_config.call(c,i) + end + } + + when Array + @buttons.each_index{|i| + if (c = configs[i]).kind_of? Hash + set_config.call(c,i) + end + } + + when Hash + @buttons.each_with_index{|s,i| + if (c = configs[s]).kind_of? Hash + set_config.call(c,i) + end + } + end + @config = 'after idle {' + @config + '};' if @config != "" + end + private :_set_button_config + # initialize tk_dialog def initialize(keys = nil) super() + @var = TkVariable.new - id = @var.id @title = title @@ -20,28 +62,42 @@ class TkDialog < TkWindow @default_button = default_button @buttons = buttons - @button_configs = proc{|num| button_configs num} + @button_configs = proc{|num| button_configs(num)} + + #@config = "puts [winfo children .w0000];" + @config = "" if keys.kind_of? Hash keys = _symbolkey2str(keys) - @title = keys['title'] if keys['title'] - @message = keys['message'] if keys['message'] - @bitmap = keys['bitmap'] if keys['bitmap'] - @default_button = keys['default'] if keys['default'] - @buttons = keys['buttons'] if keys['buttons'] + @title = keys['title'] if keys.key? 'title' + @message = keys['message'] if keys.key? 'message' + @bitmap = keys['bitmap'] if keys.key? 'bitmap' + @default_button = keys['default'] if keys.key? 'default' + @buttons = keys['buttons'] if keys.key? 'buttons' @command = keys['prev_command'] - @message_config = keys['message_config'] if keys['message_config'] - @bitmap_config = keys['bitmap_config'] if keys['bitmap_config'] - @button_configs = keys['button_configs'] if keys['button_configs'] + @message_config = keys['message_config'] if keys.key? 'message_config' + @msgframe_config = keys['msgframe_config'] if keys.key? 'msgframe_config' + @bitmap_config = keys['bitmap_config'] if keys.key? 'bitmap_config' + @button_configs = keys['button_configs'] if keys.key? 'button_configs' + @btnframe_config = keys['btnframe_config'] if keys.key? 'btnframe_config' end if @title.include? ?\s @title = '{' + @title + '}' end - @buttons = tk_split_list(@buttons) if @buttons.kind_of? String + if @buttons.kind_of? Array + _set_button_config(@buttons.collect{|cfg| + (cfg.kind_of? Array)? cfg[1]: nil}) + @buttons = @buttons.collect{|cfg| (cfg.kind_of? Array)? cfg[0]: cfg} + end + if @buttons.kind_of? Hash + _set_button_config(@buttons) + @buttons = @buttons.keys + end + @buttons = tk_split_simplelist(@buttons) if @buttons.kind_of? String @buttons = @buttons.collect{|s| if s.kind_of? Array s = s.join(' ') @@ -53,34 +109,46 @@ class TkDialog < TkWindow end } - config = "" if @message_config.kind_of? Hash - config << format("%s.msg configure %s\n", + @config << format("%s.msg configure %s;", @path, hash_kv(@message_config).join(' ')) end + + if @msgframe_config.kind_of? Hash + @config << format("%s.top configure %s;", + @path, hash_kv(@msgframe_config).join(' ')) + end + + if @btnframe_config.kind_of? Hash + @config << format("%s.bot configure %s;", + @path, hash_kv(@btnframe_config).join(' ')) + end + if @bitmap_config.kind_of? Hash - config << format("%s.msg configure %s\n", + @config << format("%s.bitmap configure %s;", @path, hash_kv(@bitmap_config).join(' ')) end - if @button_configs.kind_of? Proc - @buttons.each_index{|i| - if (c = @button_configs.call(i)).kind_of? Hash - config << format("%s.button%s configure %s\n", - @path, i, hash_kv(c).join(' ')) - end - } - end - config = 'after idle {' + config + '};' if config != "" + + _set_button_config(@button_configs) if @button_configs if @command.kind_of? Proc @command.call(self) end + end - INTERP._eval('eval {global '+id+';'+config+ - 'set '+id+' [tk_dialog '+ + def show + if @default_button.kind_of? String + default_button = @buttons.index(@default_button) + else + default_button = @default_button + end + default_button = '{}' if default_button == nil + INTERP._eval('eval {global '+@var.id+';'+@config+ + 'set '+@var.id+' [tk_dialog '+ @path+" "+@title+" {#{@message}} "+@bitmap+" "+ - String(@default_button)+" "+@buttons.join(' ')+']}') + String(default_button)+" "+@buttons.join(' ')+']}') end + def value return @var.value.to_i end @@ -89,22 +157,36 @@ class TkDialog < TkWindow # these methods must be overridden for each dialog # # # ###################################################### + private + def title + # returns a title string of the dialog window return "DIALOG" end def message + # returns a message text to display on the dialog return "MESSAGE" end def message_config + # returns a Hash {option=>value, ...} for the message text + return nil + end + def msgframe_config + # returns a Hash {option=>value, ...} for the message text frame return nil end def bitmap + # returns a bitmap name or a bitmap file path + # (@ + path ; e.g. '@/usr/share/bitmap/sample.xbm') return "info" end def bitmap_config + # returns nil or a Hash {option=>value, ...} for the bitmap return nil end def default_button + # returns a default button's number or name + # if nil or null string, set no-default return 0 end def buttons @@ -112,21 +194,50 @@ class TkDialog < TkWindow return ["BUTTON1", "BUTTON2"] end def button_configs(num) + # returns nil / Proc / Array or Hash (see _set_button_config) + return nil + end + def btnframe_config + # returns nil or a Hash {option=>value, ...} for the button frame return nil end end + +# +# TkDialog : with showing at initialize +# +class TkDialog < TkDialog2 + def self.show(*args) + self.new(*args) + end + + def initialize(*args) + super(*args) + show + end +end + + # # dialog for warning # -class TkWarning < TkDialog +class TkWarning2 < TkDialog2 def initialize(mes) - @mes = mes - super() + super(:message=>mes) end - def message - return @mes + + def show(mes = nil) + mes_bup = @message + @message = mes if mes + ret = super() + @message = mes_bup + ret end + + ####### + private + def title return "WARNING"; end @@ -140,3 +251,13 @@ class TkWarning < TkDialog return "OK"; end end + +class TkWarning < TkWarning2 + def self.show(*args) + self.new(*args) + end + def initialize(mes) + super(mes) + show + end +end diff --git a/ext/tk/lib/tkentry.rb b/ext/tk/lib/tkentry.rb index 2772dfd676..20cca6bec7 100644 --- a/ext/tk/lib/tkentry.rb +++ b/ext/tk/lib/tkentry.rb @@ -10,14 +10,39 @@ class TkEntry<TkLabel WidgetClassName = 'Entry'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end class ValidateCmd include TkComm class ValidateArgs + VARG_KEY = 'disvPSVW' + VARG_TYPE = 'nnsssssw' + + def self.scan_args(arg_str, arg_val) + arg_cnv = [] + arg_str.strip.split(/\s+/).each_with_index{|kwd,idx| + if kwd =~ /^%(.)$/ + if num = VARG_KEY.index($1) + case VARG_TYPE[num] + when ?n + arg_cnv << TkComm::number(arg_val[idx]) + when ?s + arg_cnv << TkComm::string(arg_val[idx]) + when ?w + arg_cnv << TkComm::window(arg_val[idx]) + else + arg_cnv << arg_val[idx] + end + else + arg_cnv << arg_val[idx] + end + else + arg_cnv << arg_val[idx] + end + } + arg_cnv + end + def initialize(d,i,s,v,pp,ss,vv,ww) @action = d @index = i @@ -40,13 +65,19 @@ class TkEntry<TkLabel def initialize(cmd = Proc.new, args=nil) if args - @id = install_cmd(proc{|*arg| - TkUtil.eval_cmd cmd, *arg - }) + " " + args + @id = + install_cmd(proc{|*arg| + TkUtil.eval_cmd(cmd, ValidateArgs.scan_args(args, arg)) + }) + " " + args else - @id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, ValidateArgs.new(*arg) - }) + ' %d %i %s %v %P %S %V %W' + args = ' %d %i %s %v %P %S %V %W' + @id = + install_cmd(proc{|*arg| + TkUtil.eval_cmd( + cmd, + ValidateArgs.new(ValidateArgs.scan_args(args, arg)) + ) + }) + args end end @@ -63,14 +94,6 @@ class TkEntry<TkLabel end end - def bbox(index) - tk_send 'bbox', index - end - - def delete(s, e=None) - tk_send 'delete', s, e - end - def configure(slot, value=None) if slot.kind_of? Hash slot = _symbolkey2str(slot) @@ -113,54 +136,60 @@ class TkEntry<TkLabel end super(slot, value) end + self end def cursor - tk_send 'index', 'insert' + number(tk_send('index', 'insert')) end def cursor=(index) tk_send 'icursor', index + self end def index(index) number(tk_send('index', index)) end def insert(pos,text) tk_send 'insert', pos, text + self end def mark(pos) tk_send 'scan', 'mark', pos + self end def dragto(pos) tk_send 'scan', 'dragto', pos + self end def selection_adjust(index) tk_send 'selection', 'adjust', index + self end def selection_clear tk_send 'selection', 'clear' + self end def selection_from(index) tk_send 'selection', 'from', index + self end def selection_present() bool(tk_send('selection', 'present')) end def selection_range(s, e) tk_send 'selection', 'range', s, e + self end def selection_to(index) tk_send 'selection', 'to', index + self end def validate(mode = nil) if mode configure 'validate', mode else - if tk_send('validate') == '0' - false - else - true - end + bool(tk_send('validate')) end end @@ -194,9 +223,6 @@ end class TkSpinbox<TkEntry WidgetClassName = 'Spinbox'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end def create_self(keys) if keys and keys != None @@ -212,10 +238,12 @@ class TkSpinbox<TkEntry def spinup tk_send 'invoke', 'spinup' + self end def spindown tk_send 'invoke', 'spindown' + self end def set(str) diff --git a/ext/tk/lib/tkfont.rb b/ext/tk/lib/tkfont.rb index d9eb8ecbed..b53919a145 100644 --- a/ext/tk/lib/tkfont.rb +++ b/ext/tk/lib/tkfont.rb @@ -13,6 +13,14 @@ class TkFont Tk_FontNameTBL = {} Tk_FontUseTBL = {} + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + Tk_FontNameTBL.clear + Tk_FontUseTBL.clear + Tk_FontID[0] = 0 + end + # set default font case Tk::TK_VERSION when /^4\.*/ @@ -879,6 +887,7 @@ class TkFont def configure(slot, value=None) configure_core(@compoundfont, slot, value) + self end def configinfo(slot=nil) @@ -895,6 +904,7 @@ class TkFont else configure(slot, value) end + self end def latin_configinfo(slot=nil) @@ -914,6 +924,7 @@ class TkFont #"" configure(slot, value) end + self end def kanji_configinfo(slot=nil) @@ -935,11 +946,13 @@ class TkFont def latin_replace(ltn) latin_replace_core(ltn) reset_pointadjust + self end def kanji_replace(knj) kanji_replace_core(knj) reset_pointadjust + self end def measure(text) @@ -1019,27 +1032,33 @@ module TkTreatTagFont def font_configure(slot) @parent.tagfont_configure(@id, slot) + self end def latinfont_configure(ltn, keys=nil) @parent.latintagfont_configure(@id, ltn, keys) + self end alias asciifont_configure latinfont_configure def kanjifont_configure(knj, keys=nil) @parent.kanjitagfont_configure(@id, ltn, keys) + self end def font_copy(window, wintag=nil) @parent.tagfont_copy(@id, window, wintag) + self end def latinfont_copy(window, wintag=nil) @parent.latintagfont_copy(@id, window, wintag) + self end alias asciifont_copy latinfont_copy def kanjifont_copy(window, wintag=nil) @parent.kanjitagfont_copy(@id, window, wintag) + self end end diff --git a/ext/tk/lib/tkmngfocus.rb b/ext/tk/lib/tkmngfocus.rb index 921fb646e7..f76855ed9f 100644 --- a/ext/tk/lib/tkmngfocus.rb +++ b/ext/tk/lib/tkmngfocus.rb @@ -1,6 +1,6 @@ # # tkmngfocus.rb : methods for Tcl/Tk standard library 'focus.tcl' -# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> # require 'tk' @@ -12,14 +12,14 @@ module TkManageFocus end def TkManageFocus.next(window) - tk_call 'tk_focusNext', window + tk_tcl2ruby(tk_call('tk_focusNext', window)) end def focusNext TkManageFocus.next(self) end def TkManageFocus.prev(window) - tk_call 'tk_focusPrev', window + tk_tcl2ruby(tk_call('tk_focusPrev', window)) end def focusPrev TkManageFocus.prev(self) diff --git a/ext/tk/lib/tktext.rb b/ext/tk/lib/tktext.rb index 62747be0bd..a2c641646d 100644 --- a/ext/tk/lib/tktext.rb +++ b/ext/tk/lib/tktext.rb @@ -31,10 +31,6 @@ class TkText<TkTextWin WidgetClassName = 'Text'.freeze WidgetClassNames[WidgetClassName] = self - def self.to_eval - WidgetClassName - end - def self.new(*args, &block) obj = super(*args){} obj.init_instance_variable @@ -85,13 +81,13 @@ class TkText<TkTextWin end def tag_names(index=None) - tk_split_list(tk_send('tag', 'names', index)).collect{|elt| + tk_split_simplelist(tk_send('tag', 'names', index)).collect{|elt| tagid2obj(elt) } end def mark_names - tk_split_list(tk_send('mark', 'names')).collect{|elt| + tk_split_simplelist(tk_send('mark', 'names')).collect{|elt| tagid2obj(elt) } end @@ -104,28 +100,93 @@ class TkText<TkTextWin tagid2obj(tk_send('mark', 'previous', index)) end - def window_names - tk_send('window', 'names').collect{|elt| - tagid2obj(elt) - } + def image_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + tk_send('image', 'cget', index, "-#{slot}") + else + tk_tcl2ruby(tk_send('image', 'cget', index, "-#{slot}")) + end + end + + def image_configure(index, slot, value=None) + if slot.kind_of? Hash + tk_send('image', 'configure', index, *hash_kv(slot)) + else + tk_send('image', 'configure', index, "-#{slot}", value) + end + self + end + + def image_configinfo(index, slot = nil) + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(tk_send('image', 'configure', + index, "-#{slot}")) + else + conf = tk_split_list(tk_send('image', 'configure', + index, "-#{slot}")) + end + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(tk_send('image', 'configure', + index)).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf + } + end end def image_names - tk_send('image', 'names').collect{|elt| + tk_split_simplelist(tk_send('image', 'names')).collect{|elt| tagid2obj(elt) } end def set_insert(index) tk_send 'mark', 'set', 'insert', index + self end def set_current(index) tk_send 'mark', 'set', 'current', index + self end def insert(index, chars, *tags) - super index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ') + if tags[0].kind_of? Array + # multiple chars-taglist argument + args = [chars] + while tags.size > 0 + tags.shift.collect{|x|_get_eval_string(x)}.join(' ') # taglist + args << tags.shift if tags.size > 0 # chars + end + super index, *args + else + # single chars-taglist argument + super index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ') + end end def destroy @@ -149,47 +210,87 @@ class TkText<TkTextWin end def debug=(boolean) tk_send 'debug', boolean + self end - def bbox(index) - inf = tk_send('bbox', index) - (inf == "")? [0,0,0,0]: inf + list(tk_send('bbox', index)) end + def dlineinfo(index) - inf = tk_send('dlineinfo', index) - (inf == "")? [0,0,0,0,0]: inf + list(tk_send('dlineinfo', index)) + end + + def modified? + bool(tk_send('edit', 'modified')) + end + def modified(mode) + tk_send('edit', 'modified', mode) + self + end + def edit_redo + tk_send('edit', 'redo') + self + end + def edit_reset + tk_send('edit', 'reset') + self + end + def edit_separator + tk_send('edit', 'separator') + self + end + def edit_undo + tk_send('edit', 'undo') + self end def yview_pickplace(*what) tk_send 'yview', '-pickplace', *what + self end def xview_pickplace(*what) tk_send 'xview', '-pickplace', *what + self end def tag_add(tag, index1, index2=None) tk_send 'tag', 'add', tag, index1, index2 + self end + alias addtag tag_add + + def tag_delete(*tags) + tk_send 'tag', 'delete', *tags + self + end + alias deltag tag_delete def tag_bind(tag, seq, cmd=Proc.new, args=nil) - _bind(['tag', 'bind', tag], seq, cmd, args) + _bind([@path, 'tag', 'bind', tag], seq, cmd, args) + self end def tag_bind_append(tag, seq, cmd=Proc.new, args=nil) - _bind_append(['tag', 'bind', tag], seq, cmd, args) + _bind_append([@path, 'tag', 'bind', tag], seq, cmd, args) + self + end + + def tag_bind_remove(tag, seq) + _bind_remove([@path, 'tag', 'bind', tag], seq) + self end def tag_bindinfo(tag, context=nil) - _bindinfo(['tag', 'bind', tag], context) + _bindinfo([@path, 'tag', 'bind', tag], context) end def tag_cget(tag, key) case key.to_s when 'text', 'label', 'show', 'data', 'file' - tk_call @path, 'tag', 'cget', tag, "-#{key}" + tk_call(@path, 'tag', 'cget', tag, "-#{key}") else - tk_tcl2ruby tk_call(@path, 'tag', 'cget', tag, "-#{key}") + tk_tcl2ruby(tk_call(@path, 'tag', 'cget', tag, "-#{key}")) end end @@ -213,6 +314,7 @@ class TkText<TkTextWin tk_send 'tag', 'configure', tag, "-#{key}", val end end + self end def tag_configinfo(tag, key=nil) @@ -254,14 +356,17 @@ class TkText<TkTextWin def tag_raise(tag, above=None) tk_send 'tag', 'raise', tag, above + self end def tag_lower(tag, below=None) tk_send 'tag', 'lower', tag, below + self end def tag_remove(tag, *index) tk_send 'tag', 'remove', tag, *index + self end def tag_ranges(tag) @@ -274,11 +379,79 @@ class TkText<TkTextWin end def tag_nextrange(tag, first, last=None) - tk_split_simplelist(tk_send('tag', 'nextrange', tag, first, last)) + tk_split_list(tk_send('tag', 'nextrange', tag, first, last)) end def tag_prevrange(tag, first, last=None) - tk_split_simplelist(tk_send('tag', 'prevrange', tag, first, last)) + tk_split_list(tk_send('tag', 'prevrange', tag, first, last)) + end + + def window_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + tk_send('window', 'cget', index, "-#{slot}") + else + tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}")) + end + end + + def window_configure(index, slot, value=None) + if index.kind_of? TkTextWindow + index.configure(slot, value) + else + if slot.kind_of? Hash + tk_send('window', 'configure', index, *hash_kv(slot)) + else + tk_send('window', 'configure', index, "-#{slot}", value) + end + end + self + end + + def window_configinfo(win, slot = nil) + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(tk_send('window', 'configure', + win, "-#{slot}")) + else + conf = tk_split_list(tk_send('window', 'configure', + win, "-#{slot}")) + end + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(tk_send('window', 'configure', + win)).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf + } + end + end + + def window_names + tk_split_simplelist(tk_send('window', 'names')).collect{|elt| + tagid2obj(elt) + } end def _ktext_length(txt) @@ -468,7 +641,7 @@ class TkText<TkTextWin result.push tk_tcl2ruby(val) end when 'tagoff' - result.push tk_tcl2ruby(sel) + result.push tk_tcl2ruby(val) when 'window' result.push tk_tcl2ruby(val) end @@ -555,6 +728,13 @@ class TkTextTag<TkObject TTagID_TBL = {} Tk_TextTag_ID = ['tag0000'] + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + TTagID_TBL.clear + Tk_TextTag_ID[0] = 'tag0000' + end + def TkTextTag.id2obj(text, id) tpath = text.path return id unless TTagID_TBL[tpath] @@ -587,7 +767,7 @@ class TkTextTag<TkObject end def id - return @id + @id end def first @@ -600,10 +780,12 @@ class TkTextTag<TkObject def add(*index) tk_call @t.path, 'tag', 'add', @id, *index + self end def remove(*index) tk_call @t.path, 'tag', 'remove', @id, *index + self end def ranges @@ -616,11 +798,11 @@ class TkTextTag<TkObject end def nextrange(first, last=None) - tk_split_simplelist(tk_call(@t.path, 'tag', 'nextrange', @id, first, last)) + tk_split_list(tk_call(@t.path, 'tag', 'nextrange', @id, first, last)) end def prevrange(first, last=None) - tk_split_simplelist(tk_call(@t.path, 'tag', 'prevrange', @id, first, last)) + tk_split_list(tk_call(@t.path, 'tag', 'prevrange', @id, first, last)) end def [](key) @@ -665,10 +847,17 @@ class TkTextTag<TkObject def bind(seq, cmd=Proc.new, args=nil) _bind([@t.path, 'tag', 'bind', @id], seq, cmd, args) + self end def bind_append(seq, cmd=Proc.new, args=nil) _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, args) + self + end + + def bind_remove(seq) + _bind_remove([@t.path, 'tag', 'bind', @id], seq) + self end def bindinfo(context=nil) @@ -677,15 +866,18 @@ class TkTextTag<TkObject def raise(above=None) tk_call @t.path, 'tag', 'raise', @id, above + self end def lower(below=None) tk_call @t.path, 'tag', 'lower', @id, below + self end def destroy tk_call @t.path, 'tag', 'delete', @id TTagID_TBL[@tpath].delete(@id) if CTagID_TBL[@tpath] + self end end @@ -707,9 +899,20 @@ class TkTextNamedTag<TkTextTag @path = @id = name TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath] TTagID_TBL[@tpath][@id] = self - if mode - tk_call @t.path, "addtag", @id, *args + #if mode + # tk_call @t.path, "addtag", @id, *args + #end + if args != [] then + keys = args.pop + if keys.kind_of? Hash then + add(*args) if args != [] + configure(keys) + else + args.push keys + add(*args) + end end + @t._addtag id, self end end @@ -738,16 +941,26 @@ class TkTextMark<TkObject tk_call @t.path, 'mark', 'set', @id, index @t._addtag id, self end + def id - return @id + @id + end + + def +(mod) + @id + ' + ' + mod + end + def -(mod) + @id + ' - ' + mod end def set(where) tk_call @t.path, 'mark', 'set', @id, where + self end def unset tk_call @t.path, 'mark', 'unset', @id + self end alias destroy unset @@ -757,6 +970,7 @@ class TkTextMark<TkObject def gravity=(direction) tk_call @t.path, 'mark', 'gravity', @id, direction + self end def next(index = nil) @@ -850,12 +1064,7 @@ class TkTextWindow<TkObject end def cget(slot) - case slot.to_s - when 'text', 'label', 'show', 'data', 'file' - tk_call @t.path, 'window', 'cget', @index, "-#{slot}" - else - tk_tcl2ruby tk_call(@t.path, 'window', 'cget', @index, "-#{slot}") - end + @t.window_cget(@index, slot) end def configure(slot, value=None) @@ -867,16 +1076,21 @@ class TkTextWindow<TkObject slot['create']=nil end if slot.size > 0 - tk_call @t.path, 'window', 'configure', @index, *hash_kv(slot) + tk_call(@t.path, 'window', 'configure', @index, *hash_kv(slot)) end else @id = value if slot == 'window' || slot == :window if slot == 'create' || slot == :create self.create=value else - tk_call @t.path, 'window', 'configure', @index, "-#{slot}", value + tk_call(@t.path, 'window', 'configure', @index, "-#{slot}", value) end end + self + end + + def configinfo(slot = nil) + @t.window_configinfo(@index, slot) end def window @@ -899,47 +1113,6 @@ class TkTextWindow<TkObject end tk_call @t.path, 'window', 'configure', @index, '-create', value end - - def configinfo(slot = nil) - if slot - case slot.to_s - when 'text', 'label', 'show', 'data', 'file' - conf = tk_split_simplelist(tk_call(@t.path, 'window', 'configure', - @index, "-#{slot}")) - else - conf = tk_split_list(tk_call(@t.path, 'window', 'configure', - @index, "-#{slot}")) - end - conf[0] = conf[0][1..-1] - conf - else - tk_split_simplelist(tk_call(@t.path, 'window', 'configure', - @index)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] - when 'text', 'label', 'show', 'data', 'file' - else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end - end - conf - } - end - end - end class TkTextImage<TkObject @@ -972,70 +1145,28 @@ class TkTextImage<TkObject end def cget(slot) - case slot.to_s - when 'text', 'label', 'show', 'data', 'file' - tk_call @t.path, 'image', 'cget', @index, "-#{slot}" - else - tk_tcl2ruby tk_call(@t.path, 'image', 'cget', @index, "-#{slot}") - end + @t.image_cget(@index, slot) end def configure(slot, value=None) - if slot.kind_of? Hash - tk_call @t.path, 'image', 'configure', @index, *hash_kv(slot) - else - tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value - end + @t.image_configure(@index, slot, value) + self end # def configure(slot, value) # tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value # end + def configinfo(slot = nil) + @t.image_configinfo(@index, slot) + end + def image - tk_call @t.path, 'image', 'configure', @index, '-image' + img = tk_call(@t.path, 'image', 'configure', @index, '-image') + TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img end def image=(value) tk_call @t.path, 'image', 'configure', @index, '-image', value - end - - def configinfo(slot = nil) - if slot - case slot.to_s - when 'text', 'label', 'show', 'data', 'file' - conf = tk_split_simplelist(tk_call(@t.path, 'image', 'configure', - @index, "-#{slot}")) - else - conf = tk_split_list(tk_call(@t.path, 'image', 'configure', - @index, "-#{slot}")) - end - conf[0] = conf[0][1..-1] - conf - else - tk_split_simplelist(tk_call(@t.path, 'image', 'configure', - @index)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] - when 'text', 'label', 'show', 'data', 'file' - else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end - end - conf - } - end + self end end diff --git a/ext/tk/lib/tkvirtevent.rb b/ext/tk/lib/tkvirtevent.rb index f5dcdc9429..e87be340af 100644 --- a/ext/tk/lib/tkvirtevent.rb +++ b/ext/tk/lib/tkvirtevent.rb @@ -10,6 +10,13 @@ class TkVirtualEvent<TkObject TkVirtualEventID = [0] TkVirtualEventTBL = {} + TkComm::INITIALIZE_TARGETS << self + + def self.__init_tables__ + TkVirtualEventTBL.clear + TkVirtualEventID[0] = 0 + end + class PreDefVirtEvent<self def initialize(event) @path = @id = event |