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/tk.rb | |
parent | 151f1241c665b0307234e931bec2c32bfea0138d (diff) |
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/tk.rb')
-rw-r--r-- | ext/tk/lib/tk.rb | 1218 |
1 files changed, 994 insertions, 224 deletions
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' |