diff options
Diffstat (limited to 'lib/tk.rb')
-rw-r--r-- | lib/tk.rb | 1215 |
1 files changed, 1215 insertions, 0 deletions
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' |