summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base64.rb55
-rw-r--r--lib/find.rb38
-rw-r--r--lib/getopts.rb117
-rw-r--r--lib/mailread.rb45
-rw-r--r--lib/parsearg.rb69
-rw-r--r--lib/parsedate.rb42
-rw-r--r--lib/tk.rb1215
-rw-r--r--lib/tkcanvas.rb318
-rw-r--r--lib/tkclass.rb36
-rw-r--r--lib/tkentry.rb74
-rw-r--r--lib/tktext.rb160
11 files changed, 2169 insertions, 0 deletions
diff --git a/lib/base64.rb b/lib/base64.rb
new file mode 100644
index 0000000000..a6bf1adf92
--- /dev/null
+++ b/lib/base64.rb
@@ -0,0 +1,55 @@
+def decode64(str)
+ e = -1;
+ c = ","
+ string=''
+ for line in str.split("\n")
+ line.sub!(/=+$/, '')
+ line.tr! 'A-Za-z0-9+/', "\000-\377"
+ line.each_byte { |ch|
+ n +=1
+ e +=1
+ if e==0
+ c = ch << 2
+ elsif e==1
+ c |= ch >>4
+ string += [c].pack('c')
+ c = ch << 4
+ elsif e == 2
+ c |= ch >> 2
+ string += [c].pack('c');
+ c = ch << 6
+ elsif e==3
+ c |= ch
+ string += [c].pack('c')
+ e = -1
+ end
+ }
+ end
+ return string
+end
+
+def j2e(str)
+ while str =~ /\033\$B([^\033]*)\033\(B/
+ s = $1
+ pre, post = $`, $'
+ s.gsub!(/./) { |ch|
+ (ch[0]|0x80).chr
+ }
+ str = pre + s + post
+ end
+# str.gsub!(/\033\$B([^\033]*)\033\(B/) {
+# $1.gsub!(/./) { |ch|
+# (ch[0]|0x80).chr
+# }
+# }
+ str
+end
+
+def decode_b(str)
+ str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/) {
+ decode64($1)
+ }
+ str.gsub!(/\n/, ' ')
+ str.gsub!(/\0/, '')
+ j2e(str)
+end
diff --git a/lib/find.rb b/lib/find.rb
new file mode 100644
index 0000000000..340461c653
--- /dev/null
+++ b/lib/find.rb
@@ -0,0 +1,38 @@
+# Usage:
+# require "find.rb"
+#
+# Find.find('/foo','/bar') {|f| ...}
+# or
+# include Find
+# find('/foo','/bar') {|f| ...}
+#
+
+module Find
+ extend Find
+
+ def findpath(path, ary)
+ ary.push(path)
+ d = Dir.open(path)
+ for f in d
+ continue if f =~ /^\.\.?$/
+ f = path + "/" + f
+ if File.directory? f
+ findpath(f, ary)
+ else
+ ary.push(f)
+ end
+ end
+ end
+ private :findpath
+
+ def find(*path)
+ ary = []
+ for p in path
+ findpath(p, ary)
+ for f in ary
+ yield f
+ end
+ end
+ end
+ module_function :find
+end
diff --git a/lib/getopts.rb b/lib/getopts.rb
new file mode 100644
index 0000000000..37fd3dc69d
--- /dev/null
+++ b/lib/getopts.rb
@@ -0,0 +1,117 @@
+#
+# getopts.rb - get options
+# $Release Version: $
+# $Revision: 1.2 $
+# $Date: 1994/02/15 05:17:15 $
+# by Yasuo OHBA(STAFS Development Room)
+#
+# --
+# オプションの解析をし, $OPT_?? に値をセットします.
+# 指定のないオプションが指定された時は nil を返します.
+# 正常終了した場合は, セットされたオプションの数を返します.
+#
+# getopts(single_opts, *opts)
+#
+# ex. sample [options] filename
+# options ...
+# -f -x --version --geometry 100x200 -d unix:0.0
+# ↓
+# getopts("fx", "version", "geometry:", "d:")
+#
+# 第一引数:
+# -f や -x (= -fx) の様な一文字のオプションの指定をします.
+# ここで引数がないときは nil の指定が必要です.
+# 第二引数以降:
+# ロングネームのオプションや, 引数の伴うオプションの指定をします.
+# --version や, --geometry 300x400 や, -d host:0.0 等です.
+# 引数を伴う指定は ":" を必ず付けてください.
+#
+# オプションの指定があった場合, 変数 $OPT_?? に non-nil もしくは, そのオ
+# プションの引数がセットされます.
+# -f -> $OPT_f = TRUE
+# --geometry 300x400 -> $OPT_geometry = 300x400
+#
+# - もしくは -- は, それ以降, 全てオプションの解析をしません.
+#
+
+$RCS_ID="$Header: /var/ohba/RCS/getopts.rb,v 1.2 1994/02/15 05:17:15 ohba Exp ohba $"
+
+def getopts(single_opts, *opts)
+ if (opts)
+ single_colon = ""
+ long_opts = []
+ sc = 0
+ for option in opts
+ if (option.length <= 2)
+ single_colon[sc, 0] = option[0, 1]
+ sc += 1
+ else
+ long_opts.push(option)
+ end
+ end
+ end
+
+ opts = {}
+ count = 0
+ while ($ARGV.length != 0)
+ compare = nil
+ case $ARGV[0]
+ when /^--?$/
+ $ARGV.shift
+ break
+ when /^--.*/
+ compare = $ARGV[0][2, ($ARGV[0].length - 2)]
+ if (long_opts != "")
+ for option in long_opts
+ if (option[(option.length - 1), 1] == ":" &&
+ option[0, (option.length - 1)] == compare)
+ if ($ARGV.length <= 1)
+ return nil
+ end
+ eval("$OPT_" + compare + " = " + '$ARGV[1]')
+ opts[compare] = TRUE
+ $ARGV.shift
+ count += 1
+ break
+ elsif (option == compare)
+ eval("$OPT_" + compare + " = TRUE")
+ opts[compare] = TRUE
+ count += 1
+ break
+ end
+ end
+ end
+ when /^-.*/
+ for index in 1..($ARGV[0].length - 1)
+ compare = $ARGV[0][index, 1]
+ if (single_opts && compare =~ "[" + single_opts + "]")
+ eval("$OPT_" + compare + " = TRUE")
+ opts[compare] = TRUE
+ count += 1
+ elsif (single_colon != "" && compare =~ "[" + single_colon + "]")
+ if ($ARGV[0][index..-1].length > 1)
+ eval("$OPT_" + compare + " = " + '$ARGV[0][(index + 1)..-1]')
+ opts[compare] = TRUE
+ count += 1
+ elsif ($ARGV.length <= 1)
+ return nil
+ else
+ eval("$OPT_" + compare + " = " + '$ARGV[1]')
+ opts[compare] = TRUE
+ $ARGV.shift
+ count = count + 1
+ end
+ break
+ end
+ end
+ else
+ break
+ end
+
+ $ARGV.shift
+ if (!opts.includes(compare))
+ return nil
+ end
+ end
+ return count
+end
diff --git a/lib/mailread.rb b/lib/mailread.rb
new file mode 100644
index 0000000000..4b04445beb
--- /dev/null
+++ b/lib/mailread.rb
@@ -0,0 +1,45 @@
+class Mail
+
+ def Mail.new(f)
+ if !f.is_kind_of?(IO)
+ f = open(f, "r")
+ me = super
+ f.close
+ else
+ me = super
+ end
+ return me
+ end
+
+ def initialize(f)
+ @header = {}
+ @body = []
+ while f.gets()
+ $_.chop!
+ continue if /^From / # skip From-line
+ break if /^$/ # end of header
+ if /^(\S+):\s*(.*)/
+ @header[attr = $1.capitalize] = $2
+ elsif attr
+ sub(/^\s*/, '')
+ @header[attr] += "\n" + $_
+ end
+ end
+
+ return if ! $_
+
+ while f.gets()
+ break if /^From /
+ @body.push($_)
+ end
+ end
+
+ def header
+ return @header
+ end
+
+ def body
+ return @body
+ end
+
+end
diff --git a/lib/parsearg.rb b/lib/parsearg.rb
new file mode 100644
index 0000000000..e7e2b7a7f3
--- /dev/null
+++ b/lib/parsearg.rb
@@ -0,0 +1,69 @@
+#
+# parseargs.rb - parse arguments
+# $Release Version: $
+# $Revision: 1.3 $
+# $Date: 1994/02/15 05:16:21 $
+# by Yasuo OHBA(STAFS Development Room)
+#
+# --
+# 引数の解析をし, $OPT_?? に値をセットします.
+# 正常終了した場合は, セットされたオプションの数を返します.
+#
+# parseArgs(argc, single_opts, *opts)
+#
+# ex. sample [options] filename
+# options ...
+# -f -x --version --geometry 100x200 -d unix:0.0
+# ↓
+# parseArgs(1, nil, "fx", "version", "geometry:", "d:")
+#
+# 第一引数:
+# オプション以外の最低引数の数
+# 第二引数:
+# オプションの必要性…必ず必要なら %TRUE そうでなければ %FALSE.
+# 第三引数:
+# -f や -x (= -fx) の様な一文字のオプションの指定をします.
+# ここで引数がないときは nil の指定が必要です.
+# 第四引数以降:
+# ロングネームのオプションや, 引数の伴うオプションの指定をします.
+# --version や, --geometry 300x400 や, -d host:0.0 等です.
+# 引数を伴う指定は ":" を必ず付けてください.
+#
+# オプションの指定があった場合, 変数 $OPT_?? に non-nil もしくは, そのオ
+# プションの引数がセットされます.
+# -f -> $OPT_f = %TRUE
+# --geometry 300x400 -> $OPT_geometry = 300x400
+#
+# usage を使いたい場合は, $USAGE に usage() を指定します.
+# def usage()
+# …
+# end
+# $USAGE = 'usage'
+# usage は, --help が指定された時, 間違った指定をした時に表示します.
+#
+# - もしくは -- は, それ以降, 全てオプションの解析をしません.
+#
+
+$RCS_ID="$Header: /var/ohba/RCS/parseargs.rb,v 1.3 1994/02/15 05:16:21 ohba Exp ohba $"
+
+load("getopts.rb")
+
+def printUsageAndExit()
+ if $USAGE
+ apply($USAGE)
+ end
+ exit()
+end
+
+def parseArgs(argc, nopt, single_opts, *opts)
+ if ((noOptions = getopts(single_opts, *opts)) == nil)
+ printUsageAndExit()
+ end
+ if (nopt && noOptions == 0)
+ printUsageAndExit()
+ end
+ if ($ARGV.length < argc)
+ printUsageAndExit()
+ end
+ return noOptions
+end
diff --git a/lib/parsedate.rb b/lib/parsedate.rb
new file mode 100644
index 0000000000..3f4612ebe5
--- /dev/null
+++ b/lib/parsedate.rb
@@ -0,0 +1,42 @@
+module ParseDate
+ MONTHS = {
+ 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
+ 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
+ 'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 }
+ MONTHPAT = MONTHS.keys.join('|')
+ DAYPAT = 'mon|tue|wed|thu|fri|sat|sun'
+
+ def parsedate(date)
+ if date.sub!(/(#{DAYPAT})/i, ' ')
+ dayofweek = $1
+ end
+ if date.sub!(/\s+(\d+:\d+(:\d+)?)/, ' ')
+ time = $1
+ end
+ if date =~ /19(\d\d)/
+ year = $1
+ end
+ if date.sub!(/\s*(\d+)\s+(#{MONTHPAT})\S*\s+/i, ' ')
+ dayofmonth = $1
+ monthname = $2
+ elsif date.sub!(/\s*(#{MONTHPAT})\S*\s+(\d+)\s+/i, ' ')
+ monthname = $1
+ dayofmonth = $2
+ elsif date.sub!(/\s*(#{MONTHPAT})\S*\s+(\d+)\D+/i, ' ')
+ monthname = $1
+ dayofmonth = $2
+ elsif date.sub!(/\s*(\d\d?)\/(\d\d?)/, ' ')
+ month = $1
+ dayofmonth = $2
+ end
+ if monthname
+ month = MONTHS[monthname.downcase]
+ end
+ if ! year && date =~ /\d\d/
+ year = $&
+ end
+ return year, month, dayofmonth
+ end
+
+ module_function :parsedate
+end
diff --git a/lib/tk.rb b/lib/tk.rb
new file mode 100644
index 0000000000..9c61269881
--- /dev/null
+++ b/lib/tk.rb
@@ -0,0 +1,1215 @@
+#
+# tk.rb - Tk interface for ruby
+# $Date: 1995/11/03 08:17:15 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require "tkutil"
+
+trap "PIPE", proc{exit 0}
+trap "EXIT", proc{Tk.tk_exit}
+
+module Tk
+ include TkUtil
+ extend Tk
+
+ $0 =~ /\/(.*$)/
+
+ PORT = open(format("|%s -n %s", WISH_PATH, $1), "w+");
+ def tk_write(*args)
+ printf PORT, *args;
+ PORT.print "\n"
+ PORT.flush
+ end
+ tk_write '\
+wm withdraw .
+proc rb_out args {
+ puts [format %%s $args]
+ flush stdout
+}
+proc tkerror args { exit }
+proc keepalive {} { rb_out alive; after 120000 keepalive}
+after 120000 keepalive'
+
+ READABLE = []
+ READ_CMD = {}
+
+ def file_readable(port, cmd)
+ READABLE.push port
+ READ_CMD[port] = cmd
+ end
+
+ WRITABLE = []
+ WRITE_CMD = {}
+ def file_writable
+ WRITABLE.push port
+ WRITE_CMD[port] = cmd
+ end
+ module_function :file_readable, :file_writable
+
+ file_readable PORT, proc {
+ exit if not PORT.gets
+ Tk.dispatch($_.chop!)
+ }
+
+ def tk_exit
+ PORT.print "exit\n"
+ PORT.close
+ end
+
+ def error_at
+ n = 1
+ while c = caller(n)
+ break if c !~ /tk\.rb:/
+ n+=1
+ end
+ c
+ end
+
+ def tk_tcl2ruby(val)
+ case val
+ when /^-?\d+$/
+ val.to_i
+ when /^\./
+ $tk_window_list[val]
+ when /^rb_out (c\d+)/
+ $tk_cmdtbl[$1]
+ when / /
+ val.split.collect{|elt|
+ tk_tcl2ruby(elt)
+ }
+ when /^-?\d+\.\d*$/
+ val.to_f
+ else
+ val
+ end
+ end
+
+ def tk_split_list(str)
+ idx = str.index('{')
+ return tk_tcl2ruby(str) if not idx
+
+ list = tk_tcl2ruby(str[0,idx])
+ 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
+ private :tk_tcl2ruby, :tk_split_list
+
+ def bool(val)
+ case bool
+ 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)
+ end
+ def window(val)
+ $tk_window_list[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
+
+ # mark for non-given arguments
+ None = Object.new
+ def None.to_s
+ 'None'
+ end
+
+ $tk_event_queue = []
+ def tk_call(*args)
+ args = args.collect{|s|
+ continue if s == None
+ if s == FALSE
+ s = "0"
+ elsif s == TRUE
+ s = "1"
+ elsif s.is_kind_of?(TkObject)
+ s = s.path
+ else
+ s = s.to_s
+ s.gsub!(/[{}]/, '\\\\\0')
+ end
+ "{#{s}}"
+ }
+ str = args.join(" ")
+ tk_write 'if [catch {%s} var] {puts "!$var"} {puts "=$var@@"};flush stdout', str
+ while PORT.gets
+ $_.chop!
+ if /^=(.*)@@$/
+ val = $1
+ break
+ elsif /^=/
+ val = $' + "\n"
+ while TRUE
+ PORT.gets
+ fail 'wish closed' if not $_
+ if ~/@@$/
+ val += $'
+ return val
+ else
+ val += $_
+ end
+ end
+ elsif /^!/
+ $@ = error_at
+ msg = $'
+ if msg =~ /unknown option "-(.*)"/
+ fail format("undefined method `%s' for %s(%s)'", $1, self, self.type)
+ else
+ fail format("%s - %s", self.type, msg)
+ end
+ end
+ $tk_event_queue.push $_
+ end
+
+ while ev = $tk_event_queue.shift
+ Tk.dispatch ev
+ end
+ fail 'wish closed' if not $_
+# tk_split_list(val)
+ val
+ end
+
+ def hash_kv(keys)
+ conf = []
+ if keys
+ for k, v in keys
+ conf.push("-#{k}")
+ v = install_cmd(v) if v.type == Proc
+ conf.push(v)
+ end
+ end
+ conf
+ end
+ private :tk_call, :error_at, :hash_kv
+
+ $tk_cmdid = "c00000"
+ def install_cmd(cmd)
+ return '' if cmd == '' # uninstall cmd
+ id = $tk_cmdid
+ $tk_cmdid = $tk_cmdid.next
+ $tk_cmdtbl[id] = cmd
+ @cmdtbl = [] if not @cmdtbl
+ @cmdtbl.push id
+ return format('rb_out %s', id)
+ end
+ def uninstall_cmd(id)
+ $tk_cmdtbl[id] = nil
+ end
+ private :install_cmd, :uninstall_cmd
+
+ $tk_window_list = {}
+ class Event
+ def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy)
+ @serial = seq
+ @num = b
+ @focus = (f == 1)
+ @height = h
+ @keycode = k
+ @state = s
+ @time = t
+ @width = w
+ @x = x
+ @y = y
+ @char = aa
+ @send_event = (ee == 1)
+ @keysym = kk
+ @keysym_num = nn
+ @type = tt
+ @widget = ww
+ @x_root = xx
+ @y_root = yy
+ end
+ attr :serial
+ attr :num
+ attr :focus
+ attr :height
+ attr :keycode
+ attr :state
+ attr :time
+ attr :width
+ attr :x
+ attr :y
+ attr :char
+ attr :send_event
+ attr :keysym
+ attr :keysym_num
+ attr :type
+ attr :widget
+ attr :x_root
+ attr :y_root
+ end
+
+ def install_bind(cmd)
+ id = install_cmd(proc{|args|
+ TkUtil.eval_cmd cmd, Event.new(*args)
+ })
+ id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y"
+ end
+
+ def _bind(path, context, cmd)
+ begin
+ id = install_bind(cmd)
+ tk_call 'bind', path, "<#{context}>", id
+ rescue
+ $tk_cmdtbl[id] = nil
+ fail
+ end
+ end
+ private :install_bind, :_bind
+
+ def bind_all(context, cmd=Proc.new)
+ _bind 'all', context, cmd
+ end
+
+ $tk_cmdtbl = {}
+
+ def after(ms, cmd=Proc.new)
+ myid = $tk_cmdid
+ tk_call 'after', ms,
+ install_cmd(proc{
+ TkUtil.eval_cmd cmd
+ uninstall_cmd myid
+ })
+ end
+
+ def update(idle=nil)
+ if idle
+ tk_call 'update', 'idletasks'
+ else
+ tk_call 'update'
+ end
+ end
+
+ def dispatch(line)
+ if line =~ /^c\d+/
+ cmd = $&
+ fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd]
+ args = tk_split_list($')
+ TkUtil.eval_cmd $tk_cmdtbl[cmd], *args
+ elsif line =~ /^alive$/
+ # keep alive, do nothing
+ else
+ fail "malformed line <#{line}>"
+ end
+ end
+
+ def mainloop
+ begin
+ tk_write 'after idle {wm deiconify .}'
+ while TRUE
+ rf, wf = select(READABLE, WRITABLE)
+ for f in rf
+ READ_CMD[f].call(f) if READ_CMD[f]
+ if f.closed?
+ READABLE.delete f
+ READ_CMD[f] = nil
+ end
+ end
+ for f in wf
+ WRITE_CMD[f].call(f) if WRITE_CMD[f]
+ if f.closed?
+ WRITABLE.delete f
+ WRITE_CMD[f] = nil
+ end
+ end
+ end
+ rescue
+ exit if $! =~ /^Interrupt/
+ fail
+ ensure
+ tk_exit
+ end
+ end
+
+ def root
+ $tk_root
+ end
+
+ module_function :after, :update, :dispatch, :mainloop, :root
+
+ module Scrollable
+ def xscrollcommand(cmd)
+ configure_cmd 'xscrollcommand', cmd
+ end
+ def yscrollcommand(cmd)
+ configure_cmd 'yscrollcommand', cmd
+ end
+ end
+
+ module Wm
+ def aspect(*args)
+ w = window(tk_call('wm', 'grid', path, *args))
+ w.split.collect{|s|s.to_i} if args.length == 0
+ end
+ def client(name=None)
+ tk_call 'wm', 'client', path, name
+ end
+ def colormapwindows(*args)
+ list(tk_call('wm', 'colormapwindows', path, *args))
+ end
+ def wm_command(value=None)
+ string(tk_call('wm', 'command', path, value))
+ end
+ def deiconify
+ tk_call 'wm', 'deiconify', path
+ end
+ def focusmodel(*args)
+ tk_call 'wm', 'focusmodel', path, *args
+ end
+ def frame
+ tk_call 'wm', 'frame', path
+ end
+ def geometry(*args)
+ list(tk_call('wm', 'geometry', path, *args))
+ end
+ def grid(*args)
+ w = tk_call('wm', 'grid', path, *args)
+ list(w) if args.size == 0
+ end
+ def group(*args)
+ tk_call 'wm', 'path', path, *args
+ end
+ def iconbitmap(*args)
+ tk_call 'wm', 'bitmap', path, *args
+ end
+ def iconify
+ tk_call 'wm', 'iconify'
+ end
+ def iconmask(*args)
+ tk_call 'wm', 'iconmask', path, *args
+ end
+ def iconname(*args)
+ tk_call 'wm', 'iconname', path, *args
+ end
+ def iconposition(*args)
+ w = tk_call('wm', 'iconposition', path, *args)
+ list(w) if args.size == 0
+ end
+ def iconwindow(*args)
+ tk_call 'wm', 'iconwindow', path, *args
+ end
+ def maxsize(*args)
+ w = tk_call('wm', 'maxsize', path, *args)
+ list(w) if not args.size == 0
+ end
+ def minsize(*args)
+ w = tk_call('wm', 'minsize', path, *args)
+ list(w) if args.size == 0
+ end
+ def overrideredirect(bool=None)
+ if bool == None
+ bool(tk_call('wm', 'overrideredirect', path))
+ else
+ tk_call 'wm', 'overrideredirect', path, bool
+ end
+ end
+ def positionfrom(*args)
+ tk_call 'wm', 'positionfrom', path, *args
+ end
+ def protocol(name, func=None)
+ func = install_cmd(func) if not func == None
+ tk_call 'wm', 'command', path, name, func
+ end
+ def resizable(*args)
+ w = tk_call('wm', 'resizable', path, *args)
+ if args.length == 0
+ list(w).collect{|e| bool(e)}
+ end
+ end
+ def sizefrom(*args)
+ list(tk_call('wm', 'sizefrom', path, *args))
+ end
+ def state
+ tk_call 'wm', 'state', path
+ end
+ def title(*args)
+ tk_call 'wm', 'title', path, *args
+ end
+ def transient(*args)
+ tk_call 'wm', 'transient', path, *args
+ end
+ def withdraw
+ tk_call 'wm', 'withdraw', path
+ end
+ end
+end
+
+module TkSelection
+ include Tk
+ extend Tk
+ def clear(win=Tk.root)
+ tk_call 'selection', 'clear', win.path
+ end
+ def get(type=None)
+ tk_call 'selection', 'get', type
+ end
+ def TkSelection.handle(win, func, type=None, format=None)
+ id = install_cmd(func)
+ tk_call 'selection', 'handle', win.path, id, type, format
+ end
+ def handle(func, type=None, format=None)
+ TkSelection.handle self, func, type, format
+ end
+ def TkSelection.own(win, func=None)
+ id = install_cmd(func)
+ tk_call 'selection', 'own', win.path, id
+ end
+ def own(func=None)
+ TkSelection.own self, func
+ end
+
+ module_function :clear, :get
+end
+
+module TkWinfo
+ include Tk
+ extend Tk
+ def TkWinfo.atom(name)
+ tk_call 'winfo', name
+ end
+ def winfo_atom(name)
+ TkWinfo.atom name
+ end
+ def TkWinfo.atomname(id)
+ tk_call 'winfo', id
+ end
+ def winfo_atomname(id)
+ TkWinfo.atomname id
+ end
+ def TkWinfo.cells(window)
+ number(tk_call('winfo', window.path))
+ end
+ def winfo_cells
+ TkWinfo.cells self
+ end
+ def TkWinfo.children(window)
+ c = tk_call('winfo', 'children', window.path)
+ list(c)
+ end
+ 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
+ def TkWinfo.containing(rootX, rootY)
+ path = tk_call('winfo', 'class', window.path)
+ window(path)
+ end
+ def winfo_containing(x, y)
+ TkWinfo.containing x, y
+ end
+ def TkWinfo.depth(window)
+ number(tk_call('winfo', 'depth', window.path))
+ end
+ def winfo_depth(window)
+ TkWinfo.depth self
+ end
+ def TkWinfo.exists(window)
+ bool(tk_call('winfo', 'exists', window.path))
+ end
+ def winfo_exists(window)
+ TkWinfo.exists self
+ end
+ def TkWinfo.fpixels(window, number)
+ number(tk_call('winfo', 'fpixels', window.path, number))
+ end
+ def winfo_fpixels(window, number)
+ TkWinfo.fpixels self
+ end
+ def TkWinfo.geometry(window)
+ list(tk_call('winfo', 'geometry', window.path))
+ end
+ def winfo_geometry(window)
+ TkWinfo.geometry self
+ end
+ def TkWinfo.height(window)
+ number(tk_call('winfo', 'height', window.path))
+ end
+ def winfo_height(window)
+ TkWinfo.height self
+ end
+ def TkWinfo.id(window)
+ number(tk_call('winfo', 'id', window.path))
+ end
+ def winfo_id(window)
+ TkWinfo.id self
+ end
+ def TkWinfo.ismapped(window)
+ bool(tk_call('winfo', 'ismapped', window.path))
+ end
+ def winfo_ismapped(window)
+ TkWinfo.ismapped self
+ end
+ def TkWinfo.parent(window)
+ window(tk_call('winfo', 'parent', window.path))
+ end
+ def winfo_parent(window)
+ TkWinfo.parent self
+ end
+ def TkWinfo.widget(id)
+ window(tk_call('winfo', 'pathname', id))
+ end
+ def winfo_widget(id)
+ TkWinfo.widget id
+ end
+ def TkWinfo.pixels(window, number)
+ number(tk_call('winfo', 'pixels', window.path, number))
+ end
+ def winfo_pixels(window, number)
+ TkWinfo.pixels self, number
+ end
+ def TkWinfo.reqheight(window)
+ number(tk_call('winfo', 'reqheight', window.path))
+ end
+ def winfo_reqheight(window)
+ TkWinfo.reqheight self
+ end
+ def TkWinfo.reqwidth(window)
+ number(tk_call('winfo', 'reqwidth', window.path))
+ end
+ def winfo_reqwidth(window)
+ TkWinfo.reqwidth self
+ end
+ def TkWinfo.rgb(window, color)
+ list(tk_call('winfo', 'rgb', window.path, color))
+ end
+ def winfo_rgb(window, color)
+ TkWinfo.rgb self, color
+ end
+ def TkWinfo.rootx(window)
+ number(tk_call('winfo', 'rootx', window.path))
+ end
+ def winfo_rootx(window)
+ TkWinfo.rootx self
+ end
+ def TkWinfo.rooty(window)
+ number(tk_call('winfo', 'rooty', window.path))
+ end
+ def winfo_rooty(window)
+ TkWinfo.rooty self
+ end
+ def TkWinfo.screen(window)
+ tk_call 'winfo', 'screen', window.path
+ end
+ def winfo_screen(window)
+ TkWinfo.screen self
+ end
+ def TkWinfo.screencells(window)
+ number(tk_call('winfo', 'screencells', window.path))
+ end
+ def winfo_screencells(window)
+ TkWinfo.screencells self
+ end
+ def TkWinfo.screendepth(window)
+ number(tk_call('winfo', 'screendepth', window.path))
+ end
+ def winfo_screendepth(window)
+ TkWinfo.screendepth self
+ end
+ def TkWinfo.screenheight (window)
+ number(tk_call('winfo', 'screenheight', window.path))
+ end
+ def winfo_screenheight(window)
+ TkWinfo.screenheight self
+ end
+ def TkWinfo.screenmmheight(window)
+ number(tk_call('winfo', 'screenmmheight', window.path))
+ end
+ def winfo_screenmmheight(window)
+ TkWinfo.screenmmheight self
+ end
+ def TkWinfo.screenmmwidth(window)
+ number(tk_call('winfo', 'screenmmwidth', window.path))
+ end
+ def winfo_screenmmwidth(window)
+ TkWinfo.screenmmwidth self
+ end
+ def TkWinfo.screenvisual(window)
+ tk_call 'winfo', 'screenvisual', window.path
+ end
+ def winfo_screenvisual(window)
+ TkWinfo.screenvisual self
+ end
+ def TkWinfo.screenwidth(window)
+ number(tk_call('winfo', 'screenwidth', window.path))
+ end
+ def winfo_screenwidth(window)
+ TkWinfo.screenwidth self
+ end
+ def TkWinfo.toplevel(window)
+ window(tk_call('winfo', 'toplevel', window.path))
+ end
+ def winfo_toplevel(window)
+ TkWinfo.toplevel self
+ end
+ def TkWinfo.visual(window)
+ tk_call 'winfo', 'visual', window.path
+ end
+ def winfo_visual(window)
+ TkWinfo.visual self
+ end
+ def TkWinfo.vrootheigh(window)
+ number(tk_call('winfo', 'vrootheight', window.path))
+ end
+ def winfo_vrootheight(window)
+ TkWinfo.vrootheight self
+ end
+ def TkWinfo.vrootwidth(window)
+ number(tk_call('winfo', 'vrootwidth', window.path))
+ end
+ def winfo_vrootwidth(window)
+ TkWinfo.vrootwidth self
+ end
+ def TkWinfo.vrootx(window)
+ number(tk_call('winfo', 'vrootx', window.path))
+ end
+ def winfo_vrootx(window)
+ TkWinfo.vrootx self
+ end
+ def TkWinfo.vrooty(window)
+ number(tk_call('winfo', 'vrooty', window.path))
+ end
+ def winfo_vrooty(window)
+ TkWinfo.vrooty self
+ end
+ def TkWinfo.width(window)
+ number(tk_call('winfo', 'width', window.path))
+ end
+ def winfo_width(window)
+ TkWinfo.width self
+ end
+ def TkWinfo.x(window)
+ number(tk_call('winfo', 'x', window.path))
+ end
+ def winfo_x(window)
+ TkWinfo.x self
+ end
+ def TkWinfo.y(window)
+ number(tk_call('winfo', 'y', window.path))
+ end
+ def winfo_y(window)
+ TkWinfo.y self
+ end
+end
+
+module TkPack
+ include Tk
+ extend Tk
+ def configure(win, *args)
+ if args[-1].is_kind_of(Hash)
+ keys = args.pop
+ end
+ wins = [win.epath]
+ for i in args
+ wins.push i.epath
+ end
+ tk_call "pack", 'configure', *(wins+hash_kv(keys))
+ end
+
+ def forget(*args)
+ tk_call 'pack', 'forget' *args
+ end
+
+ def propagate(master, bool=None)
+ bool(tk_call('pack', 'propagate', mastaer.epath, bool))
+ end
+ module_function :configure, :forget, :propagate
+end
+
+module TkOption
+ include Tk
+ extend Tk
+ def add pat, value, pri=None
+ tk_call 'option', 'add', pat, value, pri
+ end
+ def clear
+ tk_call 'option', 'clear'
+ end
+ def get win, classname, name
+ tk_call 'option', 'get', classname, name
+ end
+ def readfile file, pri=None
+ tk_call 'option', 'readfile', file, pri
+ end
+ module_function :add, :clear, :get, :readfile
+end
+
+class TkObject:TkKernel
+ include Tk
+
+ def path
+ return @path
+ end
+
+ def epath
+ return @path
+ end
+
+ def tk_send(cmd, *rest)
+ tk_call path, cmd, *rest
+ end
+ private :tk_send
+
+ def method_missing(id, *args)
+ if (args.length == 1)
+ configure id.id2name, args[0]
+ else
+ $@ = error_at
+ super
+ end
+ end
+
+ def []=(id, val)
+ configure id, val
+ end
+
+ def configure(slot, value)
+ if value == FALSE
+ value = "0"
+ elsif value.type == Proc
+ value = install_cmd(value)
+ end
+ tk_call path, 'configure', "-#{slot}", value
+ end
+
+ def configure_cmd(slot, value)
+ configure slot, install_cmd(value)
+ end
+
+ def bind(context, cmd=Proc.new)
+ _bind path, context, cmd
+ end
+end
+
+class TkWindow:TkObject
+ $tk_window_id = "w00000"
+ def initialize(parent=nil, keys=nil)
+ id = $tk_window_id
+ $tk_window_id = $tk_window_id.next
+ if !parent or parent == Tk.root
+ @path = format(".%s", id);
+ else
+ @path = format("%s.%s", parent.path, id)
+ end
+ $tk_window_list[@path] = self
+ create_self
+ if keys
+ tk_call @path, 'configure', *hash_kv(keys)
+ end
+ end
+
+ def create_self
+ end
+ private :create_self
+
+ def pack(keys = nil)
+ tk_call 'pack', epath, *hash_kv(keys)
+ self
+ end
+
+ def unpack(keys = nil)
+ tk_call 'pack', 'forget', epath
+ self
+ end
+
+ def focus
+ tk_call 'focus', path
+ self
+ end
+
+ def grab(*args)
+ if !args or args.length == 0
+ tk_call 'grab', 'set', path
+ elsif args.length == 1
+ case args[0]
+ when 'global'
+ tk_call 'grab', 'set', '-global', path
+ else
+ val = tk_call('grab', arg[0], path)
+ end
+ case args[0]
+ when 'current'
+ return window(val)
+ when 'status'
+ return val
+ end
+ else
+ fail 'wrong # of args'
+ end
+ end
+
+ def lower(below=None)
+ tk_call 'lower', path, below
+ self
+ end
+ def raise(above=None)
+ tk_call 'raise', path, above
+ self
+ end
+
+ def command(cmd)
+ configure_cmd 'command', cmd
+ end
+
+ def colormodel model=None
+ tk_call 'tk', 'colormodel', path, model
+ self
+ end
+
+ def destroy
+ tk_call 'destroy', path
+ if @cmdtbl
+ for id in @cmdtbl
+ uninstall_cmd id
+ end
+ end
+ $tk_window_list[path] = nil
+ end
+end
+
+class TkRoot:TkWindow
+ include Wm
+ def TkRoot.new
+ return $tk_root if $tk_root
+ super
+ end
+ def path
+ "."
+ end
+ $tk_root = TkRoot.new
+ $tk_window_list['.'] = $tk_root
+end
+
+class TkToplevel:TkWindow
+ include Wm
+ def initialize(parent=nil, screen=nil, classname=nil)
+ @screen = screen if screen
+ @classname = classname if classname
+ super
+ end
+
+ def create_self
+ s = []
+ s.push "-screen #@screen" if @screen
+ s.push "-class #@classname" if @classname
+ tk_call 'toplevel', path, *s
+ end
+end
+
+class TkFrame:TkWindow
+ def create_self
+ tk_call 'frame', @path
+ end
+end
+
+class TkLabel:TkWindow
+ def create_self
+ tk_call 'label', @path
+ end
+ def textvariable(v)
+ vn = @path + v.id2name
+ vset = format("global {%s}; set {%s}", vn, vn)
+ tk_call vset, eval(v.id2name).inspect
+ trace_var v, proc{|val|
+ tk_call vset, val.inspect
+ }
+ configure 'textvariable', vn
+ end
+end
+
+class TkButton:TkLabel
+ def create_self
+ tk_call 'button', @path
+ end
+ def invoke
+ tk_send 'invoke'
+ end
+ def flash
+ tk_send 'flash'
+ end
+end
+
+class TkRadioButton:TkButton
+ def create_self
+ tk_call 'radiobutton', @path
+ end
+ def deselect
+ tk_send 'deselect'
+ end
+ def select
+ tk_send 'select'
+ end
+ def variable(v)
+ vn = v.id2name; vn =~ /^./
+ vn = 'btns_selected_' + $'
+ trace_var v, proc{|val|
+ tk_call 'set', vn, val
+ }
+ @var_id = install_cmd(proc{|name1,|
+ val = tk_call('set', name1)
+ eval(format("%s = '%s'", v.id2name, val))
+ })
+ tk_call 'trace variable', vn, 'w', @var_id
+ configure 'variable', vn
+ end
+ def destroy
+ tk_call 'trace vdelete', vn, 'w', @var_id
+ super
+ end
+end
+
+class TkCheckButton:TkRadioButton
+ def create_self
+ tk_call 'checkbutton', @path
+ end
+ def toggle
+ tk_send 'toggle'
+ end
+end
+
+class TkMessage:TkLabel
+ def create_self
+ tk_call 'message', @path
+ end
+end
+
+class TkScale:TkWindow
+ def create_self
+ tk_call 'scale', path
+ end
+
+ def get
+ number(tk_send('get'))
+ end
+
+ def set(val)
+ tk_send "set", val
+ end
+
+ def value
+ get
+ end
+
+ def value= (val)
+ set val
+ end
+end
+
+class TkScrollbar:TkWindow
+ def create_self
+ tk_call 'scrollbar', path
+ end
+
+ def get
+ ary1 = tk_send('get', path).split
+ ary2 = []
+ for i in ary1
+ push number(i)
+ end
+ ary2
+ end
+
+ def set(first, last)
+ tk_send "set", first, last
+ end
+end
+
+# abstract class for Text and Listbox
+class TkTextWin:TkWindow
+ def bbox(index)
+ tk_send 'bbox', index
+ end
+ def delete(first, last=None)
+ tk_send 'delete', first, last
+ end
+ def get(*index)
+ tk_send 'get', *index
+ end
+ def insert(index, *rest)
+ tk_send 'insert', index, *rest
+ end
+ def index(index)
+ tk_send 'index', index
+ end
+ def insert(index, chars, *args)
+ tk_send 'insert', index, chars, *args
+ end
+ def scan_mark(x, y)
+ tk_send 'scan', 'mark', x, y
+ end
+ def scan_dragto(x, y)
+ tk_send 'scan', 'dragto', x, y
+ end
+ def see(index)
+ tk_send 'see', index
+ end
+end
+
+class TkListbox:TkTextWin
+ def create_self
+ tk_call 'listbox', path
+ end
+
+ def nearest(y)
+ tk_send 'nearest', y
+ end
+ def selection_anchor(index)
+ tk_send 'selection', 'anchor', index
+ end
+ def selection_clear(first, last=None)
+ tk_send 'selection', 'clear', first, last
+ end
+ def selection_includes
+ bool(tk_send('selection', 'includes'))
+ end
+ def selection_set(first, last=None)
+ tk_send 'selection', 'set', first, last
+ end
+ def xview(cmd, index, *more)
+ tk_send 'xview', cmd, index, *more
+ end
+ def yview(cmd, index, *more)
+ tk_send 'yview', cmd, index, *more
+ end
+end
+
+class TkMenu:TkWindow
+ def create_self
+ tk_call 'menu', path
+ end
+ def activate(index)
+ tk_send 'activate', index
+ end
+ def add(type, keys=nil)
+ tk_send 'add', type, *kv_hash(keys)
+ end
+ def index(index)
+ tk_send 'index', index
+ end
+ def invoke
+ tk_send 'invoke'
+ end
+ def insert(index, type, keys=nil)
+ tk_send 'add', index, type, *kv_hash(keys)
+ end
+ def post(x, y)
+ tk_send 'post', x, y
+ end
+ def postcascade(index)
+ tk_send 'postcascade', index
+ end
+ def postcommand(cmd)
+ configure_cmd 'postcommand', cmd
+ end
+ def menutype(index)
+ tk_send 'type', index
+ end
+ def unpost
+ tk_send 'unpost'
+ end
+ def yposition(index)
+ number(tk_send('yposition', index))
+ end
+end
+
+class TkMenubutton:TkLabel
+ def create_self
+ tk_call 'menubutton', path
+ end
+end
+
+module TkComposite
+ def initialize(parent=nil, *args)
+ @frame = TkFrame.new(parent)
+ @path = @epath = @frame.path
+ initialize_composite(*args)
+ end
+
+ def epath
+ @epath
+ end
+
+ def initialize_composite(*args) end
+ private :initialize_composite
+
+ def delegate(option, *wins)
+ @delegates = {} if not @delegates
+ @delegates['DEFAULT'] = @frame
+ if option.is_kind_of? String
+ @delegates[option] = wins
+ else
+ for i in option
+ @delegates[i] = wins
+ end
+ end
+ end
+
+ def configure(slot, value)
+ if @delegates and @delegates[slot]
+ for i in @delegates[slot]
+ if not i
+ i = @delegates['DEFALUT']
+ redo
+ else
+ last = i.configure(slot, value)
+ end
+ end
+ last
+ else
+ super
+ end
+ end
+end
+
+autoload :TkCanvas, 'tkcanvas'
+autoload :TkImage, 'tkcanvas'
+autoload :TkBitmapImage, 'tkcanvas'
+autoload :TkPhotoImage, 'tkcanvas'
+autoload :TkEntry, 'tkentry'
+autoload :TkText, 'tktext'
diff --git a/lib/tkcanvas.rb b/lib/tkcanvas.rb
new file mode 100644
index 0000000000..33b28e3eff
--- /dev/null
+++ b/lib/tkcanvas.rb
@@ -0,0 +1,318 @@
+#
+# tkcanvas.rb - Tk canvas classes
+# $Date: 1995/11/11 11:17:15 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require "tk"
+
+class TkCanvas:TkWindow
+ def create_self
+ tk_call 'canvas', path
+ end
+ def tagid(tag)
+ if tag.is_kind_of?(TkcItem)
+ tag.id
+ else
+ tag
+ end
+ end
+ private :tagid
+ def addtag(tag, *args)
+ tk_send 'addtag', tagid(tag), *args
+ end
+ def addtag_above(tagOrId)
+ addtag('above', tagOrId)
+ end
+ def addtag_all
+ addtag('all')
+ end
+ def addtag_below(tagOrId)
+ addtag('below', tagOrId)
+ end
+ def addtag_closest(x, y, halo=None, start=None)
+ addtag('closest', x, y, halo, start)
+ end
+ def addtag_enclosed(x1, y1, x2, y2)
+ addtag('enclosed', x1, y1, x2, y2)
+ end
+ def addtag_overlapping(x1, y1, x2, y2)
+ addtag('overlapping', x1, y1, x2, y2)
+ end
+ def addtag_withtag(tagOrId)
+ addtag('withtag', tagOrId)
+ end
+ def bbox(tag)
+ list(tk_send('bbox', tagid(tag)))
+ end
+ def itembind(tag, seq, cmd=Proc.new)
+ id = install_cmd(cmd)
+ tk_send 'bind', tagid(tag), "<#{seq}>", id
+ @cmdtbl.push id
+ end
+ def canvasx(x, *args)
+ tk_send 'canvasx', x, *args
+ end
+ def canvasy(y, *args)
+ tk_send 'canvasy', y, *args
+ end
+ def coords(tag, *args)
+ tk_send 'coords', tagid(tag), *args
+ end
+ def dchars(tag, first, last=None)
+ tk_send 'dchars', tagid(tag), first, last
+ end
+ def delete(*args)
+ tk_send 'delete', *args
+ end
+ alias remove delete
+ def dtag(tag, tag_to_del=None)
+ tk_send 'dtag', tagid(tag), tag_to_del
+ end
+ def find(*args)
+ tk_send 'find', *args
+ end
+ def itemfocus(tag)
+ tk_send 'find', tagid(tag)
+ end
+ def gettags(tag)
+ tk_send 'gettags', tagid(tag)
+ end
+ def icursor(tag, index)
+ tk_send 'icursor', tagid(tag), index
+ end
+ def index(tag)
+ tk_send 'index', tagid(tag), index
+ end
+ def lower(tag, below=None)
+ tk_send 'lower', tagid(tag), below
+ end
+ def move(tag, x, y)
+ tk_send 'move', tagid(tag), x, y
+ end
+ def postscript(keys=None)
+ tk_call "pack", *hash_kv(keys)
+ end
+ def raise(tag, above=None)
+ tk_send 'raise', tagid(tag), above
+ end
+ def scale(tag, x, y, xs, ys)
+ tk_send 'scale', tagid(tag), x, y, xs, ys
+ end
+ def scan_mark(x, y)
+ tk_send 'scan', 'mark', x, y
+ end
+ def scan_dragto(x, y)
+ tk_send 'scan', 'dragto', x, y
+ end
+ def select(*args)
+ tk_send 'select', *args
+ end
+ def xview(index)
+ tk_send 'xview', index
+ end
+ def yview(index)
+ tk_send 'yview', index
+ end
+end
+
+class TkcItem:TkObject
+ def initialize(parent, *args)
+ if not parent.is_kind_of?(TkCanvas)
+ fail format("%s need to be TkCanvas", parent.inspect)
+ end
+ @c = parent
+ @path = parent.path
+ if args[-1].type == Hash
+ keys = args.pop
+ end
+ @id = create_self(*args)
+ if keys
+ tk_call @path, 'itemconfigure', *hash_kv(keys)
+ end
+ end
+ def create_self(*args) end
+ private :create_self
+ def id
+ return @id
+ end
+
+ def configure(slot, value)
+ tk_call path, 'itemconfigure', id, "-#{slot}", value
+ end
+
+ def addtag(tag)
+ @c.addtag(tag, 'withtag', @id)
+ end
+ def bbox
+ @c.bbox(@id)
+ end
+ def bind(seq, cmd=Proc.new)
+ @c.itembind @id, seq, cmd
+ end
+ def coords(*args)
+ @c.coords @id, *args
+ end
+ def dchars(first, last=None)
+ @c.dchars @id, first, last
+ end
+ def dtag(ttd)
+ @c.dtag @id, ttd
+ end
+ def focus
+ @c.focus @id
+ end
+ def gettags
+ @c.gettags @id
+ end
+ def icursor
+ @c.icursor @id
+ end
+ def index
+ @c.index @id
+ end
+ def insert(beforethis, string)
+ @c.insert @id, beforethis, string
+ end
+ def lower(belowthis=None)
+ @c.lower @id, belowthis
+ end
+ def move(xamount, yamount)
+ @c.move @id, xamount, yamount
+ end
+ def raise(abovethis=None)
+ @c.raise @id, abovethis
+ end
+ def scale(xorigin, yorigin, xscale, yscale)
+ @c.scale @id, xorigin, yorigin, xscale, yscale
+ end
+ def type
+ @c.type @id
+ end
+ def destroy
+ tk_call path, 'delete', @id
+ end
+end
+
+class TkcArc:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'arc', *args)
+ end
+end
+class TkcBitmap:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'bitmap', *args)
+ end
+end
+class TkcImage:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'image', *args)
+ end
+end
+class TkcLine:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'line', *args)
+ end
+end
+class TkcOval:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'oval', *args)
+ end
+end
+class TkcPolygon:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'polygon', *args)
+ end
+end
+class TkcText:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'text', *args)
+ end
+end
+class TkcWindow:TkcItem
+ def create_self(*args)
+ tk_call(@path, 'create', 'window', *args)
+ end
+end
+class TkcGroup:TkcItem
+ $tk_group_id = 'tkg00000'
+ def create_self(*args)
+ @id = $tk_group_id
+ $tk_group_id = $tk_group_id.next
+ end
+
+ def add(*tags)
+ for i in tags
+ i.addtag @id
+ end
+ end
+ def add(*tags)
+ for i in tags
+ i.addtag @id
+ end
+ end
+ def delete(*tags)
+ for i in tags
+ i.delete @id
+ end
+ end
+ def list
+ @c.find 'withtag', @id
+ end
+ alias remove delete
+end
+
+
+class TkImage:TkObject
+ include Tk
+
+ $tk_image_id = 'i00000'
+ def initialize(keys=nil)
+ @path = $tk_image_id
+ $tk_image_id = $tk_image_id.next
+ tk_call 'image', @type, @path, *hash_kv(keys)
+ end
+
+ def height
+ number(tk_call('image', 'height', @path))
+ end
+ def type
+ tk_call('image', 'type', @path)
+ end
+ def width
+ number(tk_call('image', 'height', @path))
+ end
+
+ def TkImage.names
+ tk_call('image', 'names', @path).split
+ end
+ def TkImage.types
+ tk_call('image', 'types', @path).split
+ end
+end
+
+class TkBitmapImage:TkImage
+ def initialize(*args)
+ @type = 'bitmap'
+ super
+ end
+end
+
+class TkPhotoImage:TkImage
+ def initialize(*args)
+ @type = 'bitmap'
+ super
+ end
+
+ def blank
+ tk_send 'blank'
+ end
+ def cget
+ tk_send 'cget'
+ end
+ def get(x, y)
+ tk_send 'get', x, y
+ end
+ def put(data, to=None)
+ tk_send 'put', data, to
+ end
+end
diff --git a/lib/tkclass.rb b/lib/tkclass.rb
new file mode 100644
index 0000000000..10ecc80b20
--- /dev/null
+++ b/lib/tkclass.rb
@@ -0,0 +1,36 @@
+#
+# tkclass.rb - Tk classes
+# $Date: 1995/11/11 19:17:15 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require "tk"
+
+TopLevel = TkToplevel
+Frame = TkFrame
+Label = TkLabel
+Button = TkButton
+Radiobutton = TkRadioButton
+Checkbutton = TkCheckButton
+Message = TkMessage
+Entry = TkEntry
+Text = TkText
+Scale = TkScale
+Scrollbar = TkScrollbar
+Listbox = TkListbox
+Menu = TkMenu
+Menubutton = TkMenubutton
+Canvas = TkCanvas
+Arc = TkcArc
+Bitmap = TkcBitmap
+Line = TkcLine
+Oval = TkcOval
+Polygon = TkcPolygon
+TextItem = TkcText
+WindowItem = TkcWindow
+Selection = TkSelection
+Winfo = TkWinfo
+Pack = TkPack
+
+def Mainloop
+ Tk.mainloop
+end
diff --git a/lib/tkentry.rb b/lib/tkentry.rb
new file mode 100644
index 0000000000..dbd848d0ca
--- /dev/null
+++ b/lib/tkentry.rb
@@ -0,0 +1,74 @@
+#
+# tkentry.rb - Tk entry classes
+# $Date: 1995/12/07 15:01:10 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require 'tk.rb'
+
+class TkEntry:TkLabel
+ def create_self
+ tk_call 'entry', @path
+ end
+ def scrollcommand(cmd)
+ configure 'scrollcommand', cmd
+ end
+
+ def delete(s, e=None)
+ if e
+ tk_send 'delete', s
+ else
+ tk_send 'delete', s, e
+ end
+ end
+
+ def cursor
+ tk_send 'index', 'insert'
+ end
+ def cursor=(index)
+ tk_send 'icursor', index
+ end
+ def index(index)
+ tk_send 'index', index
+ end
+ def insert(text, pos=None)
+ if pos
+ tk_send 'icursor', pos
+ end
+ tk_send 'insert', 'insert', text
+ end
+ def mark(pos)
+ tk_send 'scan', 'mark', pos
+ end
+ def dragto(pos)
+ tk_send 'scan', 'dragto', pos
+ end
+ def select_adjust(index)
+ tk_send 'select', 'adjust', index
+ end
+ def select_clear
+ tk_send 'select', 'clear', 'end'
+ end
+ def select_from(index)
+ tk_send 'select', 'from', index
+ end
+ def select_present()
+ tk_send('select', 'present') == 1
+ end
+ def select_range(s, e)
+ tk_send 'select', 'range', s, e
+ end
+ def select_to(index)
+ tk_send 'select', 'to', index
+ end
+ def xview(*index)
+ tk_send 'xview', *index
+ end
+
+ def value
+ tk_send 'get'
+ end
+ def value= (val)
+ tk_send 'delete', 0, 'end'
+ tk_send 'insert', 0, val
+ end
+end
diff --git a/lib/tktext.rb b/lib/tktext.rb
new file mode 100644
index 0000000000..e7a2be950f
--- /dev/null
+++ b/lib/tktext.rb
@@ -0,0 +1,160 @@
+#
+# tktext.rb - Tk text classes
+# $Date: 1995/12/07 08:37:10 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require 'tk.rb'
+
+class TkText:TkTextWin
+ include Scrollable
+ def create_self
+ tk_call 'text', @path
+ @tags = {}
+ end
+ def index(index)
+ tk_send 'index', index
+ end
+ def value
+ tk_send 'get', "1.0", "end"
+ end
+ def value= (val)
+ tk_send 'delete', "1.0", 'end'
+ tk_send 'insert', "1.0", val
+ end
+ def _addcmd(cmd)
+ @cmdtbl.push id
+ end
+ def _addtag(cmd)
+ @cmdtbl.push id
+ end
+ private :_addcmd, :_addtag
+ def tag_names
+ tk_send('tag', 'names').collect{|elt|
+ if not @tags[elt]
+ elt
+ else
+ @tags[elt]
+ end
+ }
+ end
+ def window_names
+ tk_send('window', 'names').collect{|elt|
+ if not @tags[elt]
+ elt
+ else
+ @tags[elt]
+ end
+ }
+ end
+
+ def destroy
+ for t in @tags
+ t.destroy
+ end
+ super
+ end
+
+ def backspace
+ self.delete 'insert'
+ end
+
+ def compare(idx1, op, idx2)
+ bool(tk_send('compare', idx1, op, idx2))
+ end
+
+ def debug
+ bool(tk_send('debug'))
+ end
+ def debug=(boolean)
+ tk_send 'debug', boolean
+ end
+
+ def yview(*what)
+ tk_send 'yview', *what
+ end
+ def yview_pickplace(*what)
+ tk_send 'yview', '-pickplace', *what
+ end
+end
+
+class TkTextTag:TkObject
+ $tk_text_tag = 'tag0000'
+ def initialize(parent)
+ if not parent.is_kind_of?(TkText)
+ fail format("%s need to be TkText", parent.inspect)
+ end
+ @t = parent
+ @path = parent.path
+ @id = $tk_text_tag
+ $tk_text_tag = $tk_text_tag.next
+ @t._addtag id, self
+ end
+ def id
+ return @id
+ end
+
+ def add(*index)
+ tk_call path, 'tag', 'add', @id, *index
+ end
+
+ def configure(slot, value)
+ tk_call path, 'tag', 'configure', id, "-#{slot}", value
+ end
+
+ def bind(seq, cmd=Proc.new)
+ id = install_cmd(cmd)
+ tk_call path, 'tag', 'bind', tag, "<#{seq}>", id
+ @t._addcmd cmd
+ end
+
+ def lower(below=None)
+ tk_call path, 'tag', 'lower', below
+ end
+
+ def destroy
+ tk_call path, 'tag', 'delete', @id
+ end
+end
+
+class TkTextMark:TkObject
+ $tk_text_mark = 'mark0000'
+ def initialize(parent, index)
+ if not parent.is_kind_of?(TkText)
+ fail format("%s need to be TkText", parent.inspect)
+ end
+ @t = parent
+ @path = parent.path
+ @id = $tk_text_mark
+ $tk_text_mark = $tk_text_mark.next
+ tk_call @t, 'set', @id, index
+ @t._addtag id, self
+ end
+ def id
+ return @id
+ end
+
+ def set(where)
+ tk_call path, 'mark', 'unset', @id, where
+ end
+
+ def unset
+ tk_call path, 'mark', 'unset', @id
+ end
+ alias destroy unset
+end
+
+class TkTextWindow:TkObject
+ def initialize(parent, index, *args)
+ if not parent.is_kind_of?(TkText)
+ fail format("%s need to be TkText", parent.inspect)
+ end
+ @t = parent
+ @path = parent.path
+ @index = index
+ tk_call @path, 'window', 'create', index, *args
+ end
+
+ def configure(slot, value)
+ tk_call path, 'window', 'configure', @index, "-#{slot}", value
+ end
+end