⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tk.rb

📁 ruby的源代码
💻 RB
📖 第 1 页 / 共 5 页
字号:
##		tk.rb - Tk interface module using tcltklib#			$Date: 2002/03/12 09:27:29 $#			by Yukihiro Matsumoto <matz@netlab.co.jp># use Shigehiro's tcltklibrequire "tcltklib"require "tkutil"module TkComm  WidgetClassNames = {}  None = Object.new  def None.to_s    'None'  end  Tk_CMDTBL = {}  Tk_WINDOWS = {}  def error_at    frames = caller()    frames.delete_if do |c|      c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+!    end    frames  end  private :error_at  def _genobj_for_tkwidget(path)    return TkRoot.new if path == '.'    begin      tk_class = TkCore::INTERP._invoke('winfo', 'class', path)    rescue      return path    end    ruby_class = WidgetClassNames[tk_class]    gen_class_name = ruby_class.name + 'GeneratedOnTk'    unless Object.const_defined? gen_class_name      eval "class #{gen_class_name}<#{ruby_class.name}              def initialize(path)                @path=path                Tk_WINDOWS[@path] = self              end            end"    end    eval "#{gen_class_name}.new('#{path}')"  end  def tk_tcl2ruby(val)    if val =~ /^rb_out (c\d+)/      return Tk_CMDTBL[$1]    end    if val.include? ?\s      return val.split.collect{|v| tk_tcl2ruby(v)}    end    case val    when /^@font/      TkFont.get_obj(val)    when /^-?\d+$/      val.to_i    when /^\./      Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val)    when / /      val.split.collect{|elt|	tk_tcl2ruby(elt)      }    when /^-?\d+\.\d*$/      val.to_f    else      val    end  end  def tk_split_list(str)    return [] if str == ""    idx = str.index('{')    while idx and idx > 0 and str[idx-1] == ?\\      idx = str.index('{', idx+1)    end    return tk_tcl2ruby(str) unless idx    list = tk_tcl2ruby(str[0,idx])    list = [] if list == ""    str = str[idx+1..-1]    i = -1    brace = 1    str.each_byte {|c|      i += 1      brace += 1 if c == ?{      brace -= 1 if c == ?}      break if brace == 0    }    if str[0, i] == ' '      list.push ' '    else      list.push tk_split_list(str[0, i])    end    list += tk_split_list(str[i+1..-1])    list  end  def tk_split_simplelist(str)    return [] if str == ""    idx = str.index('{')    while idx and idx > 0 and str[idx-1] == ?\\      idx = str.index('{', idx+1)    end    return str.split unless idx    list = str[0,idx].split    str = str[idx+1..-1]    i = -1    brace = 1    str.each_byte {|c|      i += 1      brace += 1 if c == ?{      brace -= 1 if c == ?}      break if brace == 0    }    if i == 0      list.push ''    elsif str[0, i] == ' '      list.push ' '    else      list.push str[0..i-1]    end    list += tk_split_simplelist(str[i+1..-1])    list  end  private :tk_tcl2ruby, :tk_split_list, :tk_split_simplelist  def hash_kv(keys)    conf = []    if keys and keys != None      for k, v in keys	 conf.push("-#{k}")	 conf.push(v)      end    end    conf  end  private :hash_kv  def array2tk_list(ary)    ary.collect{|e|      if e.kind_of? Array	"{#{array2tk_list(e)}}"      elsif e.kind_of? Hash	"{#{e.to_a.collect{|ee| array2tk_list(ee)}.join(' ')}}"      else	s = _get_eval_string(e)	(s.index(/\s/))? "{#{s}}": s      end    }.join(" ")  end  private :array2tk_list  def bool(val)    case val    when "1", 1, 'yes', 'true'      TRUE    else      FALSE    end  end  def number(val)    case val    when /^-?\d+$/      val.to_i    when /^-?\d+\.\d*$/      val.to_f    else      val    end  end  def string(val)    if val == "{}"      ''    elsif val[0] == ?{      val[1..-2]    else      val    end  end  def list(val)    tk_split_list(val).to_a  end  def window(val)    Tk_WINDOWS[val]  end  def procedure(val)    if val =~ /^rb_out (c\d+)/      Tk_CMDTBL[$1]    else      nil    end  end  private :bool, :number, :string, :list, :window, :procedure  def _get_eval_string(str)    return nil if str == None    if str.kind_of?(String)      # do nothing    elsif str.kind_of?(Hash)      str = hash_kv(str).join(" ")    elsif str.kind_of?(Array)      str = array2tk_list(str)    elsif str.kind_of?(Proc)      str = install_cmd(str)    elsif str == nil      str = ""    elsif str == false      str = "0"    elsif str == true      str = "1"    elsif (str.respond_to?(:to_eval))      str = str.to_eval()    else      str = str.to_s()    end    return str  end  private :_get_eval_string  def ruby2tcl(v)    if v.kind_of?(Hash)      v = hash_kv(v)      v.flatten!      v.collect{|e|ruby2tcl(e)}    else      _get_eval_string(v)    end  end  private :ruby2tcl  Tk_IDs = [0, 0]		# [0]-cmdid, [1]-winid  def _curr_cmd_id    id = format("c%.4d", Tk_IDs[0])  end  def _next_cmd_id    id = _curr_cmd_id    Tk_IDs[0] += 1    id  end  def install_cmd(cmd)    return '' if cmd == ''    id = _next_cmd_id    Tk_CMDTBL[id] = cmd    @cmdtbl = [] unless @cmdtbl    @cmdtbl.push id    return format("rb_out %s", id);  end  def uninstall_cmd(id)    id = $1 if /rb_out (c\d+)/ =~ id    Tk_CMDTBL[id] = nil  end  private :install_cmd, :uninstall_cmd  def install_win(ppath)    id = format("w%.4d", Tk_IDs[1])    Tk_IDs[1] += 1    if !ppath or ppath == "."      @path = format(".%s", id);    else      @path = format("%s.%s", ppath, id)    end    Tk_WINDOWS[@path] = self  end  def uninstall_win()    Tk_WINDOWS[@path] = nil  end  class Event    def initialize(seq,a,b,c,d,f,h,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)      @height = h      @keycode = k      @mode = m      @override = (o == 1)      @place = p      @state = s      @time = t      @width = w      @x = x      @y = y      @char = aa      @borderwidth = bb      @wheel_delta = dd      @send_event = (ee == 1)      @keysym = kk      @keysym_num = nn      @rootwin_id = rr      @subwindow = ss      @type = tt      @widget = ww      @x_root = xx      @y_root = yy    end    attr :serial    attr :above    attr :num    attr :count    attr :detail    attr :focus    attr :height    attr :keycode    attr :mode    attr :override    attr :place    attr :state    attr :time    attr :width    attr :x    attr :y    attr :char    attr :borderwidth    attr :wheel_delta    attr :send_event    attr :keysym    attr :keysym_num    attr :rootwin_id    attr :subwindow    attr :type    attr :widget    attr :x_root    attr :y_root  end  def install_bind(cmd, args=nil)    if args      id = install_cmd(proc{|*arg|	TkUtil.eval_cmd cmd, *arg      })      id + " " + args    else      id = install_cmd(proc{|arg|	TkUtil.eval_cmd cmd, Event.new(*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'    end  end  def tk_event_sequence(context)    if context.kind_of? TkVirtualEvent      context = context.path    end    if context.kind_of? Array      context = context.collect{|ev|	if ev.kind_of? TkVirtualEvent	  ev.path	else	  ev	end      }.join("><")    end    if /,/ =~ context      context = context.split(/\s*,\s*/).join("><")    else      context    end  end  def _bind_core(mode, what, context, cmd, args=nil)    id = install_bind(cmd, args) if cmd    begin      tk_call(*(what + ["<#{tk_event_sequence(context)}>", mode + id]))    rescue      uninstall_cmd(id) if cmd      fail    end  end  def _bind(what, context, cmd, args=nil)    _bind_core('', what, context, cmd, args)  end  def _bind_append(what, context, cmd, args=nil)    _bind_core('+', what, context, cmd, args)  end  def _bind_remove(what, context)    tk_call(*(what + ["<#{tk_event_sequence(context)}>", '']))  end  def _bindinfo(what, context=nil)    if context      tk_call(*what+["<#{tk_event_sequence(context)}>"]).collect {|cmdline|	if cmdline =~ /^rb_out (c\d+)\s+(.*)$/	  [Tk_CMDTBL[$1], $2]	else	  cmdline	end      }    else      tk_split_simplelist(tk_call(*what)).collect!{|seq|	l = seq.scan(/<*[^<>]+>*/).collect!{|subseq|	  case (subseq)	  when /^<<[^<>]+>>$/	    TkVirtualEvent.getobj(subseq[1..-2])	  when /^<[^<>]+>$/	    subseq[1..-2]	  else	    subseq.split('')	  end	}.flatten	(l.size == 1) ? l[0] : l      }    end  end  private :install_bind, :tk_event_sequence,           :_bind_core, :_bind, :_bind_append, :_bind_remove, :_bindinfo  def bind(tagOrClass, context, cmd=Proc.new, args=nil)    _bind(["bind", tagOrClass], context, cmd, args)  end  def bind_append(tagOrClass, context, cmd=Proc.new, args=nil)    _bind_append(["bind", tagOrClass], context, cmd, args)  end  def bind_remove(tagOrClass, context)    _bind_remove(['bind', tagOrClass], context)  end  def bindinfo(tagOrClass, context=nil)    _bindinfo(['bind', tagOrClass], context)  end  def bind_all(context, cmd=Proc.new, args=nil)    _bind(['bind', 'all'], context, cmd, args)  end  def bind_append_all(context, cmd=Proc.new, args=nil)    _bind_append(['bind', 'all'], context, cmd, args)  end  def bindinfo_all(context=nil)    _bindinfo(['bind', 'all'], context)  end  def pack(*args)    TkPack.configure(*args)  end  def grid(*args)    TkGrid.configure(*args)  end  def update(idle=nil)    if idle      tk_call 'update', 'idletasks'    else      tk_call 'update'    end  endendmodule TkCore  include TkComm  extend TkComm  INTERP = TclTkIp.new  INTERP._invoke("proc", "rb_out", "args", <<-'EOL')    regsub -all {!} $args {\\!} args    regsub -all "{" $args "\\{" args    if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} {	return -code $st $ret    } {	return $ret    }  EOL  def callback_break    fail TkCallbackBreak, "Tk callback returns 'break' status"  end  def callback_continue    fail TkCallbackContinue, "Tk callback returns 'continue' status"  end  def after(ms, cmd=Proc.new)    myid = _curr_cmd_id    cmdid = install_cmd(cmd)    tk_call("after",ms,cmdid)#    return#    if false #defined? Thread#      Thread.start do#	ms = Float(ms)/1000#	ms = 10 if ms == 0#	sleep ms/1000#	cmd.call#      end#    else#      cmdid = install_cmd(cmd)#      tk_call("after",ms,cmdid)#    end  end  def after_idle(cmd=Proc.new)    myid = _curr_cmd_id    cmdid = install_cmd(cmd)    tk_call('after','idle',cmdid)  end  def clock_clicks(ms=nil)    if ms      tk_call('clock','clicks','-milliseconds').to_i    else      tk_call('clock','clicks').to_i    end  end  def clock_format(clk, form=nil)    if form      tk_call('clock','format',clk,'-format',form).to_i    else      tk_call('clock','format',clk).to_i    end  end  def clock_formatGMT(clk, form=nil)    if form      tk_call('clock','format',clk,'-format',form,'-gmt','1').to_i    else      tk_call('clock','format',clk,'-gmt','1').to_i    end  end  def clock_scan(str, base=nil)    if base      tk_call('clock','scan',str,'-base',base).to_i    else      tk_call('clock','scan',str).to_i    end  end  def clock_scanGMT(str, base=nil)    if base      tk_call('clock','scan',str,'-base',base,'-gmt','1').to_i    else      tk_call('clock','scan',str,'-gmt','1').to_i    end  end  def clock_seconds    tk_call('clock','seconds').to_i  end  def TkCore.callback(arg)    arg = Array(tk_split_list(arg))    _get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg))  end  def scaling(scale=nil)    if scale      tk_call('tk', 'scaling', scale)    else      Float(number(tk_call('tk', 'scaling')))    end  end  def scaling_displayof(win, scale=nil)    if scale      tk_call('tk', 'scaling', '-displayof', win, scale)    else      Float(number(tk_call('tk', '-displayof', win, 'scaling')))    end  end  def appname(name=None)    tk_call('tk', 'appname', name)  end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -