From d8b02b509608c5b90056c7befa89fa29fda45f8f Mon Sep 17 00:00:00 2001 From: nagai Date: Wed, 18 Jun 2003 19:46:20 +0000 Subject: 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 on [ruby-talk:60759] ... and so on git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3960 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/tcltklib/lib/tcltk.rb | 6 +- ext/tk/MANIFEST | 1 + ext/tk/lib/README | 1 + ext/tk/lib/tk.rb | 1218 ++++++++++++++++++++++++++++++++++++--------- ext/tk/lib/tkafter.rb | 12 +- ext/tk/lib/tkbgerror.rb | 12 +- ext/tk/lib/tkcanvas.rb | 114 ++++- ext/tk/lib/tkconsole.rb | 26 + ext/tk/lib/tkdialog.rb | 185 +++++-- ext/tk/lib/tkentry.rb | 80 ++- ext/tk/lib/tkfont.rb | 19 + ext/tk/lib/tkmngfocus.rb | 6 +- ext/tk/lib/tktext.rb | 395 ++++++++++----- ext/tk/lib/tkvirtevent.rb | 7 + 14 files changed, 1650 insertions(+), 432 deletions(-) create mode 100644 ext/tk/lib/tkconsole.rb (limited to 'ext') diff --git a/ext/tcltklib/lib/tcltk.rb b/ext/tcltklib/lib/tcltk.rb index 54a00e8f3c..b7d0f11bec 100644 --- a/ext/tcltklib/lib/tcltk.rb +++ b/ext/tcltklib/lib/tcltk.rb @@ -93,9 +93,11 @@ class TclTkInterpreter # ruby_fmt command format arguments by `format' and call `ruby' command # (notice ruby command receives only one argument) if $DEBUG - @ip._eval("proc ruby_fmt {fmt args} { puts \"ruby_fmt: $fmt $args\" ; ruby [format $fmt $args] }") + @ip._eval("proc ruby_fmt {fmt args} { puts \"ruby_fmt: $fmt +$args\" ; set cmd [list ruby [format $fmt $args]] ; uplevel $cmd }") else - @ip._eval("proc ruby_fmt {fmt args} { ruby [format $fmt $args] }") + @ip._eval("proc ruby_fmt {fmt args} { set cmd [list ruby [format +$fmt $args]] ; uplevel $cmd }") end # @ip._get_eval_string(*args): generate string to evaluate in tcl interpreter diff --git a/ext/tk/MANIFEST b/ext/tk/MANIFEST index 5280553ba3..058ed4bcc8 100644 --- a/ext/tk/MANIFEST +++ b/ext/tk/MANIFEST @@ -8,6 +8,7 @@ lib/tkafter.rb lib/tkbgerror.rb lib/tkcanvas.rb lib/tkclass.rb +lib/tkconsole.rb lib/tkdialog.rb lib/tkentry.rb lib/tkfont.rb 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", @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 TkVarAccesstarget} + end + tk_call 'pack', epath, *hash_kv(keys) + self + end + def unpack tk_call 'pack', 'forget', epath self @@ -2688,6 +3207,17 @@ class TkWindowtarget} + end + tk_call 'grid', epath, *hash_kv(keys) + self + end + def ungrid tk_call 'grid', 'forget', epath self @@ -2716,7 +3246,7 @@ class TkWindowtarget} + end + tk_call 'place', epath, *hash_kv(keys) + self + end + def unplace tk_call 'place', 'forget', epath self @@ -2828,12 +3369,17 @@ class TkWindowtrue, :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@variable, 'label'=>value, 'value'=>value) + self end def index(index) @menu.index(index) @@ -3673,9 +4391,11 @@ class TkOptionMenubutton@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 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 TkCanvasvalue, ...} 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 +# by Hidetoshi Nagai # 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 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 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