diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-29 04:06:12 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-29 04:06:12 +0000 |
commit | 11dbedfaad4a9a9521ece2198a8dc491678b1902 (patch) | |
tree | 4806dc0ff0c3827ecc40921838c4507340cfdb3a /ruby_1_8_6/ext/tk/lib/tk | |
parent | 29e8d8b439b34c2a394407dc598fc01d14be0c20 (diff) |
add tag v1_8_6_5001v1_8_6_5001
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_6_5001@13304 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ruby_1_8_6/ext/tk/lib/tk')
65 files changed, 17445 insertions, 0 deletions
diff --git a/ruby_1_8_6/ext/tk/lib/tk/after.rb b/ruby_1_8_6/ext/tk/lib/tk/after.rb new file mode 100644 index 0000000000..8c58210331 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/after.rb @@ -0,0 +1,6 @@ +# +# tk/after.rb : methods for Tcl/Tk after command +# +# $Id$ +# +require 'tk/timer' diff --git a/ruby_1_8_6/ext/tk/lib/tk/autoload.rb b/ruby_1_8_6/ext/tk/lib/tk/autoload.rb new file mode 100644 index 0000000000..6b3773f4ea --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/autoload.rb @@ -0,0 +1,196 @@ +# +# autoload +# + +####################### +# geometry manager +autoload :TkGrid, 'tk/grid' +def TkGrid(*args); TkGrid.configure(*args); end + +autoload :TkPack, 'tk/pack' +def TkPack(*args); TkPack.configure(*args); end + +autoload :TkPlace, 'tk/place' +def TkPlace(*args); TkPlace.configure(*args); end + + +####################### +# others +autoload :TkBgError, 'tk/bgerror' + +autoload :TkBindTag, 'tk/bindtag' +autoload :TkBindTagAll, 'tk/bindtag' +autoload :TkDatabaseClass, 'tk/bindtag' + +autoload :TkButton, 'tk/button' + +autoload :TkConsole, 'tk/console' + +autoload :TkCanvas, 'tk/canvas' + +autoload :TkcTagAccess, 'tk/canvastag' +autoload :TkcTag, 'tk/canvastag' +autoload :TkcTagString, 'tk/canvastag' +autoload :TkcNamedTag, 'tk/canvastag' +autoload :TkcTagAll, 'tk/canvastag' +autoload :TkcTagCurrent, 'tk/canvastag' +autoload :TkcTagGroup, 'tk/canvastag' + +autoload :TkCheckButton, 'tk/checkbutton' +autoload :TkCheckbutton, 'tk/checkbutton' + +autoload :TkClipboard, 'tk/clipboard' + +autoload :TkComposite, 'tk/composite' + +autoload :TkConsole, 'tk/console' + +autoload :TkDialog, 'tk/dialog' +autoload :TkDialog2, 'tk/dialog' +autoload :TkDialogObj, 'tk/dialog' +autoload :TkWarning, 'tk/dialog' +autoload :TkWarning2, 'tk/dialog' +autoload :TkWarningObj, 'tk/dialog' + +autoload :TkEntry, 'tk/entry' + +autoload :TkEvent, 'tk/event' + +autoload :TkFont, 'tk/font' +autoload :TkTreatTagFont, 'tk/font' + +autoload :TkFrame, 'tk/frame' + +autoload :TkImage, 'tk/image' +autoload :TkBitmapImage, 'tk/image' +autoload :TkPhotoImage, 'tk/image' + +autoload :TkItemConfigMethod, 'tk/itemconfig' + +autoload :TkTreatItemFont, 'tk/itemfont' + +autoload :TkKinput, 'tk/kinput' + +autoload :TkLabel, 'tk/label' + +autoload :TkLabelFrame, 'tk/labelframe' +autoload :TkLabelframe, 'tk/labelframe' + +autoload :TkListbox, 'tk/listbox' + +autoload :TkMacResource, 'tk/macpkg' + +autoload :TkMenu, 'tk/menu' +autoload :TkMenuClone, 'tk/menu' +autoload :TkSystemMenu, 'tk/menu' +autoload :TkSysMenu_Help, 'tk/menu' +autoload :TkSysMenu_System, 'tk/menu' +autoload :TkSysMenu_Apple, 'tk/menu' +autoload :TkMenubutton, 'tk/menu' +autoload :TkOptionMenubutton, 'tk/menu' + +autoload :TkMenubar, 'tk/menubar' + +autoload :TkMenuSpec, 'tk/menuspec' + +autoload :TkMessage, 'tk/message' + +autoload :TkManageFocus, 'tk/mngfocus' + +autoload :TkMsgCatalog, 'tk/msgcat' +autoload :TkMsgCat, 'tk/msgcat' + +autoload :TkNamespace, 'tk/namespace' + +autoload :TkOptionDB, 'tk/optiondb' +autoload :TkOption, 'tk/optiondb' +autoload :TkResourceDB, 'tk/optiondb' + +autoload :TkPackage, 'tk/package' + +autoload :TkPalette, 'tk/palette' + +autoload :TkPanedWindow, 'tk/panedwindow' +autoload :TkPanedwindow, 'tk/panedwindow' + +autoload :TkRadioButton, 'tk/radiobutton' +autoload :TkRadiobutton, 'tk/radiobutton' + +autoload :TkRoot, 'tk/root' + +autoload :TkScale, 'tk/scale' + +autoload :TkScrollbar, 'tk/scrollbar' +autoload :TkXScrollbar, 'tk/scrollbar' +autoload :TkYScrollbar, 'tk/scrollbar' + +autoload :TkScrollbox, 'tk/scrollbox' + +autoload :TkSelection, 'tk/selection' + +autoload :TkSpinbox, 'tk/spinbox' + +autoload :TkTreatTagFont, 'tk/tagfont' + +autoload :TkText, 'tk/text' + +autoload :TkTextImage, 'tk/textimage' + +autoload :TkTextMark, 'tk/textmark' +autoload :TkTextNamedMark, 'tk/textmark' +autoload :TkTextMarkInsert, 'tk/textmark' +autoload :TkTextMarkCurrent, 'tk/textmark' +autoload :TkTextMarkAnchor, 'tk/textmark' + +autoload :TkTextTag, 'tk/texttag' +autoload :TkTextNamedTag, 'tk/texttag' +autoload :TkTextTagSel, 'tk/texttag' + +autoload :TkTextWindow, 'tk/textwindow' + +autoload :TkAfter, 'tk/timer' +autoload :TkTimer, 'tk/timer' +autoload :TkRTTimer, 'tk/timer' + +autoload :TkToplevel, 'tk/toplevel' + +autoload :TkTextWin, 'tk/txtwin_abst' + +autoload :TkValidation, 'tk/validation' + +autoload :TkVariable, 'tk/variable' +autoload :TkVarAccess, 'tk/variable' + +autoload :TkVirtualEvent, 'tk/virtevent' +autoload :TkNamedVirtualEvent,'tk/virtevent' + +autoload :TkWinfo, 'tk/winfo' + +autoload :TkWinDDE, 'tk/winpkg' +autoload :TkWinRegistry, 'tk/winpkg' + +autoload :TkXIM, 'tk/xim' + + +####################### +# sub-module of Tk +module Tk + autoload :Clock, 'tk/clock' + autoload :OptionObj, 'tk/optionobj' + autoload :X_Scrollable, 'tk/scrollable' + autoload :Y_Scrollable, 'tk/scrollable' + autoload :Scrollable, 'tk/scrollable' + autoload :Wm, 'tk/wm' + + autoload :ValidateConfigure, 'tk/validation' + autoload :ItemValidateConfigure, 'tk/validation' + + autoload :EncodedString, 'tk/encodedstr' + def Tk.EncodedString(str, enc = nil); Tk::EncodedString.new(str, enc); end + + autoload :BinaryString, 'tk/encodedstr' + def Tk.BinaryString(str); Tk::BinaryString.new(str); end + + autoload :UTF8_String, 'tk/encodedstr' + def Tk.UTF8_String(str); Tk::UTF8_String.new(str); end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/bgerror.rb b/ruby_1_8_6/ext/tk/lib/tk/bgerror.rb new file mode 100644 index 0000000000..c82a8e046b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/bgerror.rb @@ -0,0 +1,29 @@ +# +# tkbgerror -- bgerror ( tkerror ) module +# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +require 'tk' + +module TkBgError + extend Tk + + TkCommandNames = ['bgerror'.freeze].freeze + + def bgerror(message) + tk_call('bgerror', message) + end + alias tkerror bgerror + alias show bgerror + module_function :bgerror, :tkerror, :show + + def set_handler(hdlr = Proc.new) #==> 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/ruby_1_8_6/ext/tk/lib/tk/bindtag.rb b/ruby_1_8_6/ext/tk/lib/tk/bindtag.rb new file mode 100644 index 0000000000..9023a08e06 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/bindtag.rb @@ -0,0 +1,81 @@ +# +# tk/bind.rb : control event binding +# +require 'tk' + +class TkBindTag + include TkBindCore + + #BTagID_TBL = {} + BTagID_TBL = TkCore::INTERP.create_table + Tk_BINDTAG_ID = ["btag".freeze, "00000".taint].freeze + + TkCore::INTERP.init_ip_env{ BTagID_TBL.clear } + + def TkBindTag.id2obj(id) + BTagID_TBL[id]? BTagID_TBL[id]: id + end + + def TkBindTag.new_by_name(name, *args, &b) + return BTagID_TBL[name] if BTagID_TBL[name] + self.new.instance_eval{ + BTagID_TBL.delete @id + @id = name + BTagID_TBL[@id] = self + bind(*args, &b) if args != [] + self + } + end + + def initialize(*args, &b) + # @id = Tk_BINDTAG_ID.join('') + @id = Tk_BINDTAG_ID.join(TkCore::INTERP._ip_id_) + Tk_BINDTAG_ID[1].succ! + BTagID_TBL[@id] = self + bind(*args, &b) if args != [] + end + + ALL = self.new_by_name('all') + + def name + @id + end + + def to_eval + @id + end + + def inspect + #Kernel.format "#<TkBindTag: %s>", @id + '#<TkBindTag: ' + @id + '>' + end +end + + +class TkBindTagAll<TkBindTag + def TkBindTagAll.new(*args, &b) + $stderr.puts "Warning: TkBindTagALL is obsolete. Use TkBindTag::ALL\n" + + TkBindTag::ALL.bind(*args, &b) if args != [] + TkBindTag::ALL + end +end + + +class TkDatabaseClass<TkBindTag + def self.new(name, *args, &b) + return BTagID_TBL[name] if BTagID_TBL[name] + super(name, *args, &b) + end + + def initialize(name, *args, &b) + @id = name + BTagID_TBL[@id] = self + bind(*args, &b) if args != [] + end + + def inspect + #Kernel.format "#<TkDatabaseClass: %s>", @id + '#<TkDatabaseClass: ' + @id + '>' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/button.rb b/ruby_1_8_6/ext/tk/lib/tk/button.rb new file mode 100644 index 0000000000..407a47c400 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/button.rb @@ -0,0 +1,27 @@ +# +# tk/button.rb : treat button widget +# +require 'tk' +require 'tk/label' + +class TkButton<TkLabel + TkCommandNames = ['button'.freeze].freeze + WidgetClassName = 'Button'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('button', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('button', @path) + # end + #end + #private :create_self + + def invoke + _fromUTF8(tk_send_without_enc('invoke')) + end + def flash + tk_send_without_enc('flash') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/canvas.rb b/ruby_1_8_6/ext/tk/lib/tk/canvas.rb new file mode 100644 index 0000000000..c30fd79bb9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/canvas.rb @@ -0,0 +1,759 @@ +# +# tk/canvas.rb - Tk canvas classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> +# +require 'tk' +require 'tk/canvastag' +require 'tk/itemconfig' +require 'tk/scrollable' + +module TkCanvasItemConfig + include TkItemConfigMethod + + def __item_strval_optkeys(id) + # maybe need to override + super(id) + [ + 'fill', 'activefill', 'disabledfill', + 'outline', 'activeoutline', 'disabledoutline' + ] + end + private :__item_strval_optkeys + + def __item_methodcall_optkeys(id) + {'coords'=>'coords'} + end + private :__item_methodcall_optkeys + + def __item_val2ruby_optkeys(id) # { key=>proc, ... } + super(id).update('window'=>proc{|i, v| window(v)}) + end + private :__item_val2ruby_optkeys + + def __item_pathname(tagOrId) + if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag) + self.path + ';' + tagOrId.id.to_s + else + self.path + ';' + tagOrId.to_s + end + end + private :__item_pathname +end + +class TkCanvas<TkWindow + include TkCanvasItemConfig + include Tk::Scrollable + + TkCommandNames = ['canvas'.freeze].freeze + WidgetClassName = 'Canvas'.freeze + WidgetClassNames[WidgetClassName] = self + + def __destroy_hook__ + TkcItem::CItemID_TBL.delete(@path) + end + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('canvas', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('canvas', @path) + # end + #end + #private :create_self + + def __numval_optkeys + super() + ['closeenough'] + end + private :__numval_optkeys + + def __boolval_optkeys + super() + ['confine'] + end + private :__boolval_optkeys + + def tagid(tag) + if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag) + tag.id + else + tag # maybe an Array of configure paramters + end + end + private :tagid + + + # create a canvas item without creating a TkcItem object + def create(type, *args) + type.create(self, *args) + end + + + def addtag(tag, mode, *args) + mode = mode.to_s + if args[0] && mode =~ /^(above|below|with(tag)?)$/ + args[0] = tagid(args[0]) + end + tk_send_without_enc('addtag', tagid(tag), mode, *args) + self + end + def addtag_above(tagOrId, target) + addtag(tagOrId, 'above', tagid(target)) + end + def addtag_all(tagOrId) + addtag(tagOrId, 'all') + end + def addtag_below(tagOrId, target) + addtag(tagOrId, 'below', tagid(target)) + end + def addtag_closest(tagOrId, x, y, halo=None, start=None) + addtag(tagOrId, 'closest', x, y, halo, start) + end + def addtag_enclosed(tagOrId, x1, y1, x2, y2) + addtag(tagOrId, 'enclosed', x1, y1, x2, y2) + end + def addtag_overlapping(tagOrId, x1, y1, x2, y2) + addtag(tagOrId, 'overlapping', x1, y1, x2, y2) + end + def addtag_withtag(tagOrId, tag) + addtag(tagOrId, 'withtag', tagid(tag)) + end + + def bbox(tagOrId, *tags) + list(tk_send_without_enc('bbox', tagid(tagOrId), + *tags.collect{|t| tagid(t)})) + end + + #def itembind(tag, context, cmd=Proc.new, *args) + # _bind([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def itembind(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, "bind", tagid(tag)], context, cmd, *args) + self + end + + #def itembind_append(tag, context, cmd=Proc.new, *args) + # _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def itembind_append(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + self + end + + def itembind_remove(tag, context) + _bind_remove([path, "bind", tagid(tag)], context) + self + end + + def itembindinfo(tag, context=nil) + _bindinfo([path, "bind", tagid(tag)], context) + end + + def canvasx(screen_x, *args) + #tk_tcl2ruby(tk_send_without_enc('canvasx', screen_x, *args)) + number(tk_send_without_enc('canvasx', screen_x, *args)) + end + def canvasy(screen_y, *args) + #tk_tcl2ruby(tk_send_without_enc('canvasy', screen_y, *args)) + number(tk_send_without_enc('canvasy', screen_y, *args)) + end + + def coords(tag, *args) + if args == [] + tk_split_list(tk_send_without_enc('coords', tagid(tag))) + else + tk_send_without_enc('coords', tagid(tag), *(args.flatten)) + self + end + end + + def dchars(tag, first, last=None) + tk_send_without_enc('dchars', tagid(tag), + _get_eval_enc_str(first), _get_eval_enc_str(last)) + self + end + + def delete(*args) + if TkcItem::CItemID_TBL[self.path] + args.each{|tag| + find('withtag', tag).each{|item| + if item.kind_of?(TkcItem) + TkcItem::CItemID_TBL[self.path].delete(item.id) + end + } + } + end + tk_send_without_enc('delete', *args.collect{|t| tagid(t)}) + self + end + alias remove delete + + def dtag(tag, tag_to_del=None) + tk_send_without_enc('dtag', tagid(tag), tagid(tag_to_del)) + self + end + alias deltag dtag + + def find(mode, *args) + list(tk_send_without_enc('find', mode, *args)).collect!{|id| + TkcItem.id2obj(self, id) + } + end + def find_above(target) + find('above', tagid(target)) + end + def find_all + find('all') + end + def find_below(target) + find('below', tagid(target)) + end + def find_closest(x, y, halo=None, start=None) + find('closest', x, y, halo, start) + end + def find_enclosed(x1, y1, x2, y2) + find('enclosed', x1, y1, x2, y2) + end + def find_overlapping(x1, y1, x2, y2) + find('overlapping', x1, y1, x2, y2) + end + def find_withtag(tag) + find('withtag', tag) + end + + def itemfocus(tagOrId=nil) + if tagOrId + tk_send_without_enc('focus', tagid(tagOrId)) + self + else + ret = tk_send_without_enc('focus') + if ret == "" + nil + else + TkcItem.id2obj(self, ret) + end + end + end + + def gettags(tagOrId) + list(tk_send_without_enc('gettags', tagid(tagOrId))).collect{|tag| + TkcTag.id2obj(self, tag) + } + end + + def icursor(tagOrId, index) + tk_send_without_enc('icursor', tagid(tagOrId), index) + self + end + + def index(tagOrId, idx) + number(tk_send_without_enc('index', tagid(tagOrId), idx)) + end + + def insert(tagOrId, index, string) + tk_send_without_enc('insert', tagid(tagOrId), index, + _get_eval_enc_str(string)) + self + end + +=begin + def itemcget(tagOrId, option) + case option.to_s + when 'dash', 'activedash', 'disableddash' + conf = tk_send_without_enc('itemcget', tagid(tagOrId), "-#{option}") + if conf =~ /^[0-9]/ + list(conf) + else + conf + end + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + _fromUTF8(tk_send_without_enc('itemcget', tagid(tagOrId), "-#{option}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('itemcget', tagid(tagOrId), "-#{option}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_with_enc('itemcget', tagid(tagOrId), '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(tagid(tagOrId), fnt) + end + if option.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', tagid(tagOrId), + "-#{option}"))) + end + end + + def itemconfigure(tagOrId, key, value=None) + if key.kind_of? Hash + key = _symbolkey2str(key) + coords = key.delete('coords') + self.coords(tagOrId, coords) if coords + + if ( key['font'] || key['kanjifont'] \ + || key['latinfont'] || key['asciifont'] ) + tagfont_configure(tagid(tagOrId), key.dup) + else + _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), + *hash_kv(key, true))) + end + + else + if ( key == 'coords' || key == :coords ) + self.coords(tagOrId, value) + elsif ( key == 'font' || key == :font || + key == 'kanjifont' || key == :kanjifont || + key == 'latinfont' || key == :latinfont || + key == 'asciifont' || key == :asciifont ) + if value == None + tagfontobj(tagid(tagOrId)) + else + tagfont_configure(tagid(tagOrId), {key=>value}) + end + else + _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), + "-#{key}", _get_eval_enc_str(value))) + end + end + self + end +# def itemconfigure(tagOrId, key, value=None) +# if key.kind_of? Hash +# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key) +# else +# tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value +# end +# end +# def itemconfigure(tagOrId, keys) +# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys) +# end + + def itemconfiginfo(tagOrId, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'coords' + return ['coords', '', '', '', self.coords(tagOrId)] + when 'dash', 'activedash', 'disableddash' + conf = tk_split_simplelist(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}")) + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + if conf[4] && conf[4] =~ /^[0-9]/ + conf[4] = list(conf[4]) + end + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),"-#{key}"))) + conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + when 'dash', 'activedash', 'disableddash' + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + if conf[4] && conf[4] =~ /^[0-9]/ + conf[4] = list(conf[4]) + end + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(tagid(tagOrId), fontconf[4]) + ret.push(fontconf) + end + + ret << ['coords', '', '', '', self.coords(tagOrId)] + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'coords' + {'coords' => ['', '', '', self.coords(tagOrId)]} + when 'dash', 'activedash', 'disableddash' + conf = tk_split_simplelist(tk_send_without_enc('itemconfigure', + tagid(tagOrId), + "-#{key}")) + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + if conf[4] && conf[4] =~ /^[0-9]/ + conf[4] = list(conf[4]) + end + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),"-#{key}"))) + conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + when 'dash', 'activedash', 'disableddash' + if conf[2] && conf[2] =~ /^[0-9]/ + conf[2] = list(conf[2]) + end + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(tagid(tagOrId), fontconf[3]) + ret['font'] = fontconf + end + + ret['coords'] = ['', '', '', self.coords(tagOrId)] + + ret + end + end + end + + def current_itemconfiginfo(tagOrId, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = itemconfiginfo(tagOrId, key) + {conf[0] => conf[4]} + else + ret = {} + itemconfiginfo(tagOrId).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + itemconfiginfo(tagOrId, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +=end + + def lower(tag, below=nil) + if below + tk_send_without_enc('lower', tagid(tag), tagid(below)) + else + tk_send_without_enc('lower', tagid(tag)) + end + self + end + + def move(tag, x, y) + tk_send_without_enc('move', tagid(tag), x, y) + self + end + + def postscript(keys) + tk_send("postscript", *hash_kv(keys)) + end + + def raise(tag, above=nil) + if above + tk_send_without_enc('raise', tagid(tag), tagid(above)) + else + tk_send_without_enc('raise', tagid(tag)) + end + self + end + + def scale(tag, x, y, xs, ys) + tk_send_without_enc('scale', tagid(tag), x, y, xs, ys) + self + end + + def scan_mark(x, y) + tk_send_without_enc('scan', 'mark', x, y) + self + end + def scan_dragto(x, y, gain=None) + tk_send_without_enc('scan', 'dragto', x, y, gain) + self + end + + def select(mode, *args) + r = tk_send_without_enc('select', mode, *args) + (mode == 'item')? TkcItem.id2obj(self, r): self + end + def select_adjust(tagOrId, index) + select('adjust', tagid(tagOrId), index) + end + def select_clear + select('clear') + end + def select_from(tagOrId, index) + select('from', tagid(tagOrId), index) + end + def select_item + select('item') + end + def select_to(tagOrId, index) + select('to', tagid(tagOrId), index) + end + + def itemtype(tag) + TkcItem.type2class(tk_send('type', tagid(tag))) + end +end + +class TkcItem<TkObject + extend Tk + include TkcTagAccess + extend TkItemFontOptkeys + extend TkItemConfigOptkeys + + CItemTypeName = nil + CItemTypeToClass = {} + CItemID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ CItemID_TBL.clear } + + def TkcItem.type2class(type) + CItemTypeToClass[type] + end + + def TkcItem.id2obj(canvas, id) + cpath = canvas.path + return id unless CItemID_TBL[cpath] + CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id + end + + ######################################## + def self._parse_create_args(args) + fontkeys = {} + methodkeys = {} + if args[-1].kind_of? Hash + keys = _symbolkey2str(args.pop) + if args.size == 0 + args = keys.delete('coords') + unless args.kind_of?(Array) + fail "coords parameter must be given by an Array" + end + end + + #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key| + # fontkeys[key] = keys.delete(key) if keys.key?(key) + #} + __item_font_optkeys(nil).each{|key| + fkey = key.to_s + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "kanji#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "latin#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "ascii#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + } + + __item_methodcall_optkeys(nil).each{|key| + key = key.to_s + methodkeys[key] = keys.delete(key) if keys.key?(key) + } + + __item_ruby2val_optkeys(nil).each{|key, method| + key = key.to_s + keys[key] = method.call(keys[key]) if keys.has_key?(key) + } + + #args = args.flatten.concat(hash_kv(keys)) + args = args.flatten.concat(itemconfig_hash_kv(nil, keys)) + else + args = args.flatten + end + + [args, fontkeys] + end + private_class_method :_parse_create_args + + def self.create(canvas, *args) + unless self::CItemTypeName + fail RuntimeError, "#{self} is an abstract class" + end + args, fontkeys = _parse_create_args(args) + idnum = tk_call_without_enc(canvas.path, 'create', + self::CItemTypeName, *args) + canvas.itemconfigure(idnum, fontkeys) unless fontkeys.empty? + idnum.to_i # 'canvas item id' is an integer number + end + ######################################## + + def initialize(parent, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @parent = @c = parent + @path = parent.path + + @id = create_self(*args) # an integer number as 'canvas item id' + CItemID_TBL[@path] = {} unless CItemID_TBL[@path] + CItemID_TBL[@path][@id] = self + end + def create_self(*args) + self.class.create(@c, *args) # return an integer number as 'canvas item id' + end + private :create_self + + def id + @id + end + + def exist? + if @c.find_withtag(@id) + true + else + false + end + end + + def delete + @c.delete @id + CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] + self + end + alias remove delete + alias destroy delete +end + +class TkcArc<TkcItem + CItemTypeName = 'arc'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcBitmap<TkcItem + CItemTypeName = 'bitmap'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcImage<TkcItem + CItemTypeName = 'image'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcLine<TkcItem + CItemTypeName = 'line'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcOval<TkcItem + CItemTypeName = 'oval'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcPolygon<TkcItem + CItemTypeName = 'polygon'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcRectangle<TkcItem + CItemTypeName = 'rectangle'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcText<TkcItem + CItemTypeName = 'text'.freeze + CItemTypeToClass[CItemTypeName] = self + def self.create(canvas, *args) + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + txt = keys['text'] + keys['text'] = _get_eval_enc_str(txt) if txt + args.push(keys) + end + super(canvas, *args) + end +end + +class TkcWindow<TkcItem + CItemTypeName = 'window'.freeze + CItemTypeToClass[CItemTypeName] = self + def self.create(canvas, *args) + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + win = keys['window'] + # keys['window'] = win.epath if win.kind_of?(TkWindow) + keys['window'] = _epath(win) if win + args.push(keys) + end + super(canvas, *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/canvastag.rb b/ruby_1_8_6/ext/tk/lib/tk/canvastag.rb new file mode 100644 index 0000000000..a5650ee68b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/canvastag.rb @@ -0,0 +1,375 @@ +# +# tk/canvastag.rb - methods for treating canvas tags +# +require 'tk' +require 'tk/tagfont' + +module TkcTagAccess + include TkComm + include TkTreatTagFont +end + +require 'tk/canvas' + +module TkcTagAccess + def addtag(tag) + @c.addtag(tag, 'withtag', @id) + self + end + + def bbox + @c.bbox(@id) + end + + #def bind(seq, cmd=Proc.new, *args) + # @c.itembind(@id, seq, cmd, *args) + # self + #end + def bind(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @c.itembind(@id, seq, cmd, *args) + self + end + + #def bind_append(seq, cmd=Proc.new, *args) + # @c.itembind_append(@id, seq, cmd, *args) + # self + #end + def bind_append(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @c.itembind_append(@id, seq, cmd, *args) + self + end + + def bind_remove(seq) + @c.itembind_remove(@id, seq) + self + end + + def bindinfo(seq=nil) + @c.itembindinfo(@id, seq) + end + + def cget(option) + @c.itemcget(@id, option) + end + + def configure(key, value=None) + @c.itemconfigure(@id, key, value) + self + end +# def configure(keys) +# @c.itemconfigure @id, keys +# end + + def configinfo(key=nil) + @c.itemconfiginfo(@id, key) + end + + def current_configinfo(key=nil) + @c.current_itemconfiginfo(@id, key) + end + + def coords(*args) + @c.coords(@id, *args) + end + + def dchars(first, last=None) + @c.dchars(@id, first, last) + self + end + + def dtag(tag_to_del=None) + @c.dtag(@id, tag_to_del) + self + end + alias deltag dtag + + def find + @c.find('withtag', @id) + end + alias list find + + def focus + @c.itemfocus(@id) + end + + def gettags + @c.gettags(@id) + end + + def icursor(index) + @c.icursor(@id, index) + self + end + + def index(idx) + @c.index(@id, idx) + end + + def insert(beforethis, string) + @c.insert(@id, beforethis, string) + self + end + + def lower(belowthis=None) + @c.lower(@id, belowthis) + self + end + + def move(xamount, yamount) + @c.move(@id, xamount, yamount) + self + end + + def raise(abovethis=None) + @c.raise(@id, abovethis) + self + end + + def scale(xorigin, yorigin, xscale, yscale) + @c.scale(@id, xorigin, yorigin, xscale, yscale) + self + end + + def select_adjust(index) + @c.select('adjust', @id, index) + self + end + def select_from(index) + @c.select('from', @id, index) + self + end + def select_to(index) + @c.select('to', @id, index) + self + end + + def itemtype + @c.itemtype(@id) + end + + # Following operators support logical expressions of canvas tags + # (for Tk8.3+). + # If tag1.path is 't1' and tag2.path is 't2', then + # ltag = tag1 & tag2; ltag.path => "(t1)&&(t2)" + # ltag = tag1 | tag2; ltag.path => "(t1)||(t2)" + # ltag = tag1 ^ tag2; ltag.path => "(t1)^(t2)" + # ltag = - tag1; ltag.path => "!(t1)" + def & (tag) + if tag.kind_of? TkObject + TkcTagString.new(@c, '(' + @id + ')&&(' + tag.path + ')') + else + TkcTagString.new(@c, '(' + @id + ')&&(' + tag.to_s + ')') + end + end + + def | (tag) + if tag.kind_of? TkObject + TkcTagString.new(@c, '(' + @id + ')||(' + tag.path + ')') + else + TkcTagString.new(@c, '(' + @id + ')||(' + tag.to_s + ')') + end + end + + def ^ (tag) + if tag.kind_of? TkObject + TkcTagString.new(@c, '(' + @id + ')^(' + tag.path + ')') + else + TkcTagString.new(@c, '(' + @id + ')^(' + tag.to_s + ')') + end + end + + def -@ + TkcTagString.new(@c, '!(' + @id + ')') + end +end + +class TkcTag<TkObject + include TkcTagAccess + + CTagID_TBL = TkCore::INTERP.create_table + Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ CTagID_TBL.clear } + + def TkcTag.id2obj(canvas, id) + cpath = canvas.path + return id unless CTagID_TBL[cpath] + CTagID_TBL[cpath][id]? CTagID_TBL[cpath][id]: id + end + + def initialize(parent, mode=nil, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + # @path = @id = Tk_CanvasTag_ID.join('') + @path = @id = Tk_CanvasTag_ID.join(TkCore::INTERP._ip_id_) + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + Tk_CanvasTag_ID[1].succ! + if mode + tk_call_without_enc(@c.path, "addtag", @id, mode, *args) + end + end + def id + @id + end + + def exist? + if @c.find_withtag(@id) + true + else + false + end + end + + def delete + @c.delete @id + CTagID_TBL[@cpath].delete(@id) if CTagID_TBL[@cpath] + self + end + alias remove delete + alias destroy delete + + def set_to_above(target) + @c.addtag_above(@id, target) + self + end + alias above set_to_above + + def set_to_all + @c.addtag_all(@id) + self + end + alias all set_to_all + + def set_to_below(target) + @c.addtag_below(@id, target) + self + end + alias below set_to_below + + def set_to_closest(x, y, halo=None, start=None) + @c.addtag_closest(@id, x, y, halo, start) + self + end + alias closest set_to_closest + + def set_to_enclosed(x1, y1, x2, y2) + @c.addtag_enclosed(@id, x1, y1, x2, y2) + self + end + alias enclosed set_to_enclosed + + def set_to_overlapping(x1, y1, x2, y2) + @c.addtag_overlapping(@id, x1, y1, x2, y2) + self + end + alias overlapping set_to_overlapping + + def set_to_withtag(target) + @c.addtag_withtag(@id, target) + self + end + alias withtag set_to_withtag +end + +class TkcTagString<TkcTag + def self.new(parent, name, *args) + if CTagID_TBL[parent.path] && CTagID_TBL[parent.path][name] + return CTagID_TBL[parent.path][name] + else + super(parent, name, *args) + end + end + + def initialize(parent, name, mode=nil, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + @path = @id = name + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + if mode + tk_call_without_enc(@c.path, "addtag", @id, mode, *args) + end + end +end +TkcNamedTag = TkcTagString + +class TkcTagAll<TkcTag + def initialize(parent) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + @path = @id = 'all' + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + end +end + +class TkcTagCurrent<TkcTag + def initialize(parent) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + @path = @id = 'current' + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + end +end + +class TkcGroup<TkcTag + Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint].freeze + #def create_self(parent, *args) + def initialize(parent, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + # @path = @id = Tk_cGroup_ID.join('') + @path = @id = Tk_cGroup_ID.join(TkCore::INTERP._ip_id_) + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + Tk_cGroup_ID[1].succ! + include(*args) if args != [] + end + #private :create_self + + def include(*tags) + for i in tags + #i.addtag(@id) + @c.addtag_withtag(@id, i) + end + self + end + alias add include + + def exclude(*tags) + for i in tags + #i.dtag(@id) + @c.dtag(i, @id) + end + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/checkbutton.rb b/ruby_1_8_6/ext/tk/lib/tk/checkbutton.rb new file mode 100644 index 0000000000..d76d99c0f2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/checkbutton.rb @@ -0,0 +1,25 @@ +# +# tk/checkbutton.rb : treat checkbutton widget +# +require 'tk' +require 'tk/radiobutton' + +class TkCheckButton<TkRadioButton + TkCommandNames = ['checkbutton'.freeze].freeze + WidgetClassName = 'Checkbutton'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('checkbutton', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('checkbutton', @path) + # end + #end + #private :create_self + + def toggle + tk_send_without_enc('toggle') + self + end +end +TkCheckbutton = TkCheckButton diff --git a/ruby_1_8_6/ext/tk/lib/tk/clipboard.rb b/ruby_1_8_6/ext/tk/lib/tk/clipboard.rb new file mode 100644 index 0000000000..d4205a5c28 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/clipboard.rb @@ -0,0 +1,75 @@ +# +# tk/clipboard.rb : methods to treat clipboard +# +require 'tk' + +module TkClipboard + include Tk + extend Tk + + TkCommandNames = ['clipboard'.freeze].freeze + + def self.clear(win=nil) + if win + tk_call_without_enc('clipboard', 'clear', '-displayof', win) + else + tk_call_without_enc('clipboard', 'clear') + end + end + def self.clear_on_display(win) + tk_call_without_enc('clipboard', 'clear', '-displayof', win) + end + + def self.get(type=nil) + if type + tk_call_without_enc('clipboard', 'get', '-type', type) + else + tk_call_without_enc('clipboard', 'get') + end + end + def self.get_on_display(win, type=nil) + if type + tk_call_without_enc('clipboard', 'get', '-displayof', win, '-type', type) + else + tk_call_without_enc('clipboard', 'get', '-displayof', win) + end + end + + def self.set(data, keys=nil) + clear + append(data, keys) + end + def self.set_on_display(win, data, keys=nil) + clear(win) + append_on_display(win, data, keys) + end + + def self.append(data, keys=nil) + args = ['clipboard', 'append'] + args.concat(hash_kv(keys)) + args.concat(['--', data]) + tk_call(*args) + end + def self.append_on_display(win, data, keys=nil) + args = ['clipboard', 'append', '-displayof', win] + args.concat(hash_kv(keys)) + args.concat(['--', data]) + tk_call(*args) + end + + def clear + TkClipboard.clear_on_display(self) + self + end + def get(type=nil) + TkClipboard.get_on_display(self, type) + end + def set(data, keys=nil) + TkClipboard.set_on_display(self, data, keys) + self + end + def append(data, keys=nil) + TkClipboard.append_on_display(self, data, keys) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/clock.rb b/ruby_1_8_6/ext/tk/lib/tk/clock.rb new file mode 100644 index 0000000000..4e9438f5ab --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/clock.rb @@ -0,0 +1,71 @@ +# +# tk/clock.rb : methods for clock command +# +require 'tk' + +module Tk + module Clock + include Tk + extend TkCore + + def self.add(clk, *args) + tk_call_without_enc('clock','add', clk, *args).to_i + end + + def self.clicks(ms=nil) + ms = ms.to_s if ms.kind_of?(Symbol) + case ms + when nil, '' + tk_call_without_enc('clock','clicks').to_i + when /^mic/ + tk_call_without_enc('clock','clicks','-microseconds').to_i + when /^mil/ + tk_call_without_enc('clock','clicks','-milliseconds').to_i + else + tk_call_without_enc('clock','clicks','-milliseconds').to_i + end + end + + def self.format(clk, form=nil) + if form + tk_call('clock','format',clk,'-format',form) + else + tk_call('clock','format',clk) + end + end + + def self.formatGMT(clk, form=nil) + if form + tk_call('clock','format',clk,'-format',form,'-gmt','1') + else + tk_call('clock','format',clk,'-gmt','1') + end + end + + def self.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 self.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 self.seconds + tk_call_without_enc('clock','seconds').to_i + end + def self.milliseconds + tk_call_without_enc('clock','milliseconds').to_i + end + def self.microseconds + tk_call_without_enc('clock','microseconds').to_i + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/composite.rb b/ruby_1_8_6/ext/tk/lib/tk/composite.rb new file mode 100644 index 0000000000..eaed8ed363 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/composite.rb @@ -0,0 +1,394 @@ +# +# tk/composite.rb : +# +require 'tk' + +module TkComposite + include Tk + extend Tk + +=begin + def initialize(parent=nil, *args) + @delegates = {} + @option_methods = {} + @option_setting = {} + + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + @frame = TkFrame.new(parent) + @path = @epath = @frame.path + initialize_composite(keys) + else + @frame = TkFrame.new(parent) + @path = @epath = @frame.path + initialize_composite(*args) + end + end +=end + + def _choice_classname_of_baseframe + base_class_name = nil + + klass = WidgetClassNames[self.class::WidgetClassName] + + if klass + # WidgetClassName is a known class + if klass <= TkFrame || klass < TkComposite + # klass is valid for the base frame + if self.class <= klass + # use my classname + base_class_name = self.class.name + if base_class_name == '' + # anonymous class -> use ancestor's name + base_class_name = klass.name + end + else + # not subclass -> use WidgetClassName + base_class_name = klass.name + end + + else + # klass is invalid for the base frame + if self.class < TkFrame || self.class.superclass < TkComposite + # my class name is valid for the base frame -> use my classname + base_class_name = self.class.name + if base_class_name == '' + # anonymous class -> use TkFrame + base_class_name = nil + end + else + # no idea for the base frame -> use TkFrame + base_class_name = nil + end + end + + elsif self.class::WidgetClassName && ! self.class::WidgetClassName.empty? + # unknown WidgetClassName is defined -> use it for the base frame + base_class_name = self.class::WidgetClassName + + else + # no valid WidgetClassName + if self.class < TkFrame || self.class.superclass < TkComposite + # my class name is valid for the base frame -> use my classname + base_class_name = self.class.name + if base_class_name == '' + # anonymous class -> use TkFrame + base_class_name = nil + end + else + # no idea for the base frame -> use TkFrame + base_class_name = nil + end + end + + base_class_name + end + private :_choice_classname_of_baseframe + + # def initialize(parent=nil, *args) + def initialize(*args) + @delegates = {} + @option_methods = {} + @option_setting = {} + + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + else + keys = {} + end + parent = args.shift + parent = keys.delete('parent') if keys.has_key?('parent') + + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + if (base_class_name = (keys.delete('class')).to_s).empty? + base_class_name = _choice_classname_of_baseframe + end + + if base_class_name + @frame = TkFrame.new(parent, :class=>base_class_name) + else + @frame = TkFrame.new(parent) + end + @path = @epath = @frame.path + + args.push(keys) unless keys.empty? + initialize_composite(*args) + end + + def database_classname + @frame.database_classname + end + + def database_class + @frame.database_class + end + + def epath + @epath + end + + def initialize_composite(*args) end + private :initialize_composite + + def option_methods(*opts) + opts.each{|m_set, m_cget, m_info| + m_set = m_set.to_s + m_cget = m_set if !m_cget && self.method(m_set).arity == -1 + m_cget = m_cget.to_s if m_cget + m_info = m_info.to_s if m_info + @option_methods[m_set] = { + :set => m_set, :cget => m_cget, :info => m_info + } + } + end + + def delegate_alias(alias_opt, option, *wins) + if wins.length == 0 + fail ArgumentError, "target widgets are not given" + end + if alias_opt != option && (alias_opt == 'DEFAULT' || option == 'DEFAULT') + fail ArgumentError, "cannot alias 'DEFAULT' option" + end + alias_opt = alias_opt.to_s + option = option.to_s + if @delegates[alias_opt].kind_of?(Array) + if (elem = @delegates[alias_opt].assoc(option)) + wins.each{|w| elem[1].push(w)} + else + @delegates[alias_opt] << [option, wins] + end + else + @delegates[alias_opt] = [ [option, wins] ] + end + end + + def delegate(option, *wins) + delegate_alias(option, option, *wins) + end + + def cget(slot) + slot = slot.to_s + + if @option_methods.include?(slot) + if @option_methods[slot][:cget] + return self.__send__(@option_methods[slot][:cget]) + else + if @option_setting[slot] + return @option_setting[slot] + else + return '' + end + end + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + opt, wins = tbl[-1] + opt = slot if opt == 'DEFAULT' + if wins && wins[-1] + return wins[-1].cget(opt) + end + end + rescue + end + + super(slot) + end + + def configure(slot, value=None) + if slot.kind_of? Hash + slot.each{|slot,value| configure slot, value} + return self + end + + slot = slot.to_s + + if @option_methods.include?(slot) + unless @option_methods[slot][:cget] + if value.kind_of?(Symbol) + @option_setting[slot] = value.to_s + else + @option_setting[slot] = value + end + end + return self.__send__(@option_methods[slot][:set], value) + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + last = nil + tbl.each{|opt, wins| + opt = slot if opt == 'DEFAULT' + wins.each{|w| last = w.configure(opt, value)} + } + return last + end + rescue + end + + super(slot, value) + end + + def configinfo(slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + slot = slot.to_s + if @option_methods.include?(slot) + if @option_methods[slot][:info] + return self.__send__(@option_methods[slot][:info]) + else + return [slot, '', '', '', self.cget(slot)] + end + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + if tbl.length == 1 + opt, wins = tbl[0] + if slot == opt || opt == 'DEFAULT' + return wins[-1].configinfo(slot) + else + info = wins[-1].configinfo(opt) + info[0] = slot + return info + end + else + opt, wins = tbl[-1] + return [slot, '', '', '', wins[-1].cget(opt)] + end + end + rescue + end + + super(slot) + + else # slot == nil + info_list = super(slot) + + tbl = @delegates['DEFAULT'] + if tbl + wins = tbl[0][1] + if wins && wins[-1] + wins[-1].configinfo.each{|info| + slot = info[0] + info_list.delete_if{|i| i[0] == slot} << info + } + end + end + + @delegates.each{|slot, tbl| + next if slot == 'DEFAULT' + if tbl.length == 1 + opt, wins = tbl[0] + next unless wins && wins[-1] + if slot == opt + info_list.delete_if{|i| i[0] == slot} << + wins[-1].configinfo(slot) + else + info = wins[-1].configinfo(opt) + info[0] = slot + info_list.delete_if{|i| i[0] == slot} << info + end + else + opt, wins = tbl[-1] + info_list.delete_if{|i| i[0] == slot} << + [slot, '', '', '', wins[-1].cget(opt)] + end + } + + @option_methods.each{|slot, m| + if m[:info] + info = self.__send__(m[:info]) + else + info = [slot, '', '', '', self.cget(slot)] + end + info_list.delete_if{|i| i[0] == slot} << info + } + + info_list + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + slot = slot.to_s + if @option_methods.include?(slot) + if @option_methods[slot][:info] + return self.__send__(@option_methods[slot][:info]) + else + return {slot => ['', '', '', self.cget(slot)]} + end + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + if tbl.length == 1 + opt, wins = tbl[0] + if slot == opt || opt == 'DEFAULT' + return wins[-1].configinfo(slot) + else + return {slot => wins[-1].configinfo(opt)[opt]} + end + else + opt, wins = tbl[-1] + return {slot => ['', '', '', wins[-1].cget(opt)]} + end + end + rescue + end + + super(slot) + + else # slot == nil + info_list = super(slot) + + tbl = @delegates['DEFAULT'] + if tbl + wins = tbl[0][1] + info_list.update(wins[-1].configinfo) if wins && wins[-1] + end + + @delegates.each{|slot, tbl| + next if slot == 'DEFAULT' + if tbl.length == 1 + opt, wins = tbl[0] + next unless wins && wins[-1] + if slot == opt + info_list.update(wins[-1].configinfo(slot)) + else + info_list.update({slot => wins[-1].configinfo(opt)[opt]}) + end + else + opt, wins = tbl[-1] + info_list.update({slot => ['', '', '', wins[-1].cget(opt)]}) + end + } + + @option_methods.each{|slot, m| + if m[:info] + info = self.__send__(m[:info]) + else + info = {slot => ['', '', '', self.cget(slot)]} + end + info_list.update(info) + } + + info_list + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/console.rb b/ruby_1_8_6/ext/tk/lib/tk/console.rb new file mode 100644 index 0000000000..26ce262caa --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/console.rb @@ -0,0 +1,52 @@ +# +# tk/console.rb : control the console on system without a real console +# +require 'tk' + +module TkConsole + include Tk + extend Tk + + TkCommandNames = ['console'.freeze, 'consoleinterp'.freeze].freeze + + def self.create + TkCore::INTERP._create_console + end + self.create # initialize console + + def self.title(str=None) + tk_call 'console', str + end + def self.hide + tk_call_without_enc('console', 'hide') + end + def self.show + tk_call_without_enc('console', 'show') + end + def self.eval(tcl_script) + # + # supports a Tcl script only + # I have no idea to support a Ruby script seamlessly. + # + _fromUTF8(tk_call_without_enc('console', 'eval', + _get_eval_enc_str(tcl_script))) + end + def self.maininterp_eval(tcl_script) + # + # supports a Tcl script only + # I have no idea to support a Ruby script seamlessly. + # + _fromUTF8(tk_call_without_enc('consoleinterp', 'eval', + _get_eval_enc_str(tcl_script))) + + end + def self.maininterp_record(tcl_script) + # + # supports a Tcl script only + # I have no idea to support a Ruby script seamlessly. + # + _fromUTF8(tk_call_without_enc('consoleinterp', 'record', + _get_eval_enc_str(tcl_script))) + + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/dialog.rb b/ruby_1_8_6/ext/tk/lib/tk/dialog.rb new file mode 100644 index 0000000000..180da101e3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/dialog.rb @@ -0,0 +1,326 @@ +# +# tk/dialog.rb : create dialog boxes +# +require 'tk' +require 'tk/variable.rb' + +class TkDialogObj < TkWindow + extend Tk + + TkCommandNames = ['tk_dialog'.freeze].freeze + + def self.show(*args) + dlog = self.new(*args) + dlog.show + dlog + end + + def _set_button_config(configs) + set_config = proc{|c,i| + if $VERBOSE && (c.has_key?('command') || c.has_key?(:command)) + STDERR.print("Warning: cannot give a command option " + + "to the dialog button#{i}. It was removed.\n") + end + c.delete('command'); c.delete(:command) + # @config << Kernel.format("%s.button%s configure %s; ", + # @path, i, hash_kv(c).join(' ')) + # @config << @path+'.button'+i.to_s+' configure '+hash_kv(c).join(' ')+'; ' + @config << @path+'.button'+i.to_s+' configure '+ + array2tk_list(hash_kv(c))+'; ' + } + case configs + when Proc + @buttons.each_index{|i| + if (c = configs.call(i)).kind_of?(Hash) + set_config.call(c,i) + end + } + + when Array + @buttons.each_index{|i| + if (c = configs[i]).kind_of?(Hash) + set_config.call(c,i) + end + } + + when Hash + @buttons.each_with_index{|s,i| + if (c = configs[s]).kind_of?(Hash) + set_config.call(c,i) + end + } + end + # @config = 'after idle {' + @config + '};' if @config != "" + @config = array2tk_list(['after', 'idle', @config]) << ';' if @config != "" + end + private :_set_button_config + + # initialize tk_dialog + def create_self(keys) + # @var = TkVariable.new + @val = nil + + @title = title + + @message = message + @message_config = message_config + @msgframe_config = msgframe_config + + @bitmap = bitmap + @bitmap_config = message_config + + @default_button = default_button + + @buttons = buttons + @button_configs = proc{|num| button_configs(num)} + @btnframe_config = btnframe_config + + #@config = "puts [winfo children .w0000];" + @config = "" + + @command = prev_command + + if keys.kind_of?(Hash) + @title = keys['title'] if keys.key? 'title' + @message = keys['message'] if keys.key? 'message' + @bitmap = keys['bitmap'] if keys.key? 'bitmap' + # @bitmap = '{}' if @bitmap == nil || @bitmap == "" + @bitmap = '' unless @bitmap + @default_button = keys['default'] if keys.key? 'default' + @buttons = keys['buttons'] if keys.key? 'buttons' + + @command = keys['prev_command'] if keys.key? 'prev_command' + + @message_config = keys['message_config'] if keys.key? 'message_config' + @msgframe_config = keys['msgframe_config'] if keys.key? 'msgframe_config' + @bitmap_config = keys['bitmap_config'] if keys.key? 'bitmap_config' + @button_configs = keys['button_configs'] if keys.key? 'button_configs' + @btnframe_config = keys['btnframe_config'] if keys.key? 'btnframe_config' + end + + #if @title.include? ?\s + # @title = '{' + @title + '}' + #end + + if @buttons.kind_of?(Array) + _set_button_config(@buttons.collect{|cfg| + (cfg.kind_of? Array)? cfg[1]: nil}) + @buttons = @buttons.collect{|cfg| (cfg.kind_of? Array)? cfg[0]: cfg} + end + if @buttons.kind_of?(Hash) + _set_button_config(@buttons) + @buttons = @buttons.keys + end + @buttons = tk_split_simplelist(@buttons) if @buttons.kind_of?(String) + @buttons = [] unless @buttons +=begin + @buttons = @buttons.collect{|s| + if s.kind_of?(Array) + s = s.join(' ') + end + if s.include? ?\s + '{' + s + '}' + else + s + end + } +=end + + if @message_config.kind_of?(Hash) + # @config << Kernel.format("%s.msg configure %s;", + # @path, hash_kv(@message_config).join(' ')) + # @config << @path+'.msg configure '+hash_kv(@message_config).join(' ')+';' + @config << @path+'.msg configure '+ + array2tk_list(hash_kv(@message_config))+';' + end + + if @msgframe_config.kind_of?(Hash) + # @config << Kernel.format("%s.top configure %s;", + # @path, hash_kv(@msgframe_config).join(' ')) + # @config << @path+'.top configure '+hash_kv(@msgframe_config).join(' ')+';' + @config << @path+'.top configure '+ + array2tk_list(hash_kv(@msgframe_config))+';' + end + + if @btnframe_config.kind_of?(Hash) + # @config << Kernel.format("%s.bot configure %s;", + # @path, hash_kv(@btnframe_config).join(' ')) + # @config << @path+'.bot configure '+hash_kv(@btnframe_config).join(' ')+';' + @config << @path+'.bot configure '+ + array2tk_list(hash_kv(@btnframe_config))+';' + end + + if @bitmap_config.kind_of?(Hash) + # @config << Kernel.format("%s.bitmap configure %s;", + # @path, hash_kv(@bitmap_config).join(' ')) + # @config << @path+'.bitmap configure '+hash_kv(@bitmap_config).join(' ')+';' + @config << @path+'.bitmap configure '+ + array2tk_list(hash_kv(@bitmap_config))+';' + end + + _set_button_config(@button_configs) if @button_configs + end + private :create_self + + def show + # if @command.kind_of?(Proc) + if TkComm._callback_entry?(@command) + @command.call(self) + end + + if @default_button.kind_of?(String) + default_button = @buttons.index(@default_button) + else + default_button = @default_button + end + # default_button = '{}' if default_button == nil + default_button = '' if default_button == nil + #Tk.ip_eval('eval {global '+@var.id+';'+@config+ + # 'set '+@var.id+' [tk_dialog '+ + # @path+" "+@title+" {#{@message}} "+@bitmap+" "+ + # String(default_button)+" "+@buttons.join(' ')+']}') + Tk.ip_eval(@config) + # @val = Tk.ip_eval('tk_dialog ' + @path + ' ' + @title + + # ' {' + @message + '} ' + @bitmap + ' ' + + # String(default_button) + ' ' + @buttons.join(' ')).to_i + # @val = Tk.ip_eval(self.class::TkCommandNames[0] + ' ' + @path + ' ' + + # @title + ' {' + @message + '} ' + @bitmap + ' ' + + # String(default_button) + ' ' + @buttons.join(' ')).to_i + @val = Tk.ip_eval(array2tk_list([ + self.class::TkCommandNames[0], + @path, @title, @message, @bitmap, + String(default_button) + ].concat(@buttons))).to_i + end + + def value + # @var.value.to_i + @val + end + + def name + (@val)? @buttons[@val]: nil + end + + ############################################################ + # # + # following methods should be overridden for each dialog # + # # + ############################################################ + private + + def title + # returns a title string of the dialog window + return "DIALOG" + end + def message + # returns a message text to display on the dialog + return "MESSAGE" + end + def message_config + # returns a Hash {option=>value, ...} 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 + #return "BUTTON1 BUTTON2" + 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 + def prev_command + # returns nil or a Proc + return nil + end +end +TkDialog2 = TkDialogObj + +# +# TkDialog : with showing at initialize +# +class TkDialog < TkDialogObj + def self.show(*args) + self.new(*args) + end + + def initialize(*args) + super(*args) + show + end +end + + +# +# dialog for warning +# +class TkWarningObj < TkDialogObj + def initialize(parent = nil, mes = nil) + if !mes + if parent.kind_of?(TkWindow) + mes = "" + else + mes = parent.to_s + parent = nil + end + end + super(parent, :message=>mes) + end + + def show(mes = nil) + mes_bup = @message + @message = mes if mes + ret = super() + @message = mes_bup + ret + end + + ####### + private + + def title + return "WARNING"; + end + def bitmap + return "warning"; + end + def default_button + return 0; + end + def buttons + return "OK"; + end +end +TkWarning2 = TkWarningObj + +class TkWarning < TkWarningObj + def self.show(*args) + self.new(*args) + end + def initialize(*args) + super(*args) + show + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/encodedstr.rb b/ruby_1_8_6/ext/tk/lib/tk/encodedstr.rb new file mode 100644 index 0000000000..797e514a4c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/encodedstr.rb @@ -0,0 +1,111 @@ +# +# tk/encodedstr.rb : Tk::EncodedString class +# +require 'tk' + +########################################### +# string with Tcl's encoding +########################################### +module Tk + class EncodedString < String + Encoding = nil + + def self.subst_utf_backslash(str) + # str.gsub(/\\u([0-9A-Fa-f]{1,4})/){[$1.hex].pack('U')} + TclTkLib._subst_UTF_backslash(str) + end + def self.utf_backslash(str) + self.subst_utf_backslash(str) + end + + def self.subst_tk_backslash(str) + TclTkLib._subst_Tcl_backslash(str) + end + + def self.utf_to_backslash_sequence(str) + str.unpack('U*').collect{|c| + if c <= 0xFF # ascii character + c.chr + else + format('\u%X', c) + end + }.join('') + end + def self.utf_to_backslash(str) + self.utf_to_backslash_sequence(str) + end + + def self.to_backslash_sequence(str) + str.unpack('U*').collect{|c| + if c <= 0x1F # control character + case c + when 0x07; '\a' + when 0x08; '\b' + when 0x09; '\t' + when 0x0a; '\n' + when 0x0b; '\v' + when 0x0c; '\f' + when 0x0d; '\r' + else + format('\x%02X', c) + end + elsif c <= 0xFF # ascii character + c.chr + else + format('\u%X', c) + end + }.join('') + end + + def self.new_with_utf_backslash(str, enc = nil) + self.new('', enc).replace(self.subst_utf_backslash(str)) + end + + def self.new_without_utf_backslash(str, enc = nil) + self.new('', enc).replace(str) + end + + def initialize(str, enc = nil) + super(str) + # @encoding = ( enc || + # ((self.class::Encoding)? + # self.class::Encoding : Tk.encoding_system) ) + @encoding = ( enc || + ((self.class::Encoding)? + self.class::Encoding : + ((Tk.encoding)? Tk.encoding : Tk.encoding_system) ) ) + end + + attr_reader :encoding + end + # def Tk.EncodedString(str, enc = nil) + # Tk::EncodedString.new(str, enc) + # end + + ################################## + + class BinaryString < EncodedString + Encoding = 'binary'.freeze + end + # def Tk.BinaryString(str) + # Tk::BinaryString.new(str) + # end + + ################################## + + class UTF8_String < EncodedString + Encoding = 'utf-8'.freeze + def self.new(str) + super(self.subst_utf_backslash(str)) + end + + def to_backslash_sequence + Tk::EncodedString.utf_to_backslash_sequence(self) + end + alias to_backslash to_backslash_sequence + end + # def Tk.UTF8_String(str) + # Tk::UTF8_String.new(str) + # end + +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/entry.rb b/ruby_1_8_6/ext/tk/lib/tk/entry.rb new file mode 100644 index 0000000000..4ac3f28229 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/entry.rb @@ -0,0 +1,117 @@ +# +# tk/entry.rb - Tk entry classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> + +require 'tk' +require 'tk/label' +require 'tk/scrollable' +require 'tk/validation' + +class TkEntry<TkLabel + include X_Scrollable + include TkValidation + + TkCommandNames = ['entry'.freeze].freeze + WidgetClassName = 'Entry'.freeze + WidgetClassNames[WidgetClassName] = self + + #def create_self(keys) + # super(__conv_vcmd_on_hash_kv(keys)) + #end + #private :create_self + + def __strval_optkeys + super() + ['show', 'disabledbackground', 'readonlybackground'] + end + private :__strval_optkeys + + def bbox(index) + list(tk_send_without_enc('bbox', index)) + end + def cursor + number(tk_send_without_enc('index', 'insert')) + end + alias icursor cursor + def cursor=(index) + tk_send_without_enc('icursor', index) + #self + index + end + alias icursor= cursor= + def index(idx) + number(tk_send_without_enc('index', idx)) + end + def insert(pos,text) + tk_send_without_enc('insert', pos, _get_eval_enc_str(text)) + self + end + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + def mark(pos) + tk_send_without_enc('scan', 'mark', pos) + self + end + def dragto(pos) + tk_send_without_enc('scan', 'dragto', pos) + self + end + def selection_adjust(index) + tk_send_without_enc('selection', 'adjust', index) + self + end + def selection_clear + tk_send_without_enc('selection', 'clear') + self + end + def selection_from(index) + tk_send_without_enc('selection', 'from', index) + self + end + def selection_present() + bool(tk_send_without_enc('selection', 'present')) + end + def selection_range(s, e) + tk_send_without_enc('selection', 'range', s, e) + self + end + def selection_to(index) + tk_send_without_enc('selection', 'to', index) + self + end + + def invoke_validate + bool(tk_send_without_enc('validate')) + end + def validate(mode = nil) + if mode + configure 'validate', mode + else + invoke_validate + end + end + + def value + _fromUTF8(tk_send_without_enc('get')) + end + def value= (val) + tk_send_without_enc('delete', 0, 'end') + tk_send_without_enc('insert', 0, _get_eval_enc_str(val)) + val + end + alias get value + alias set value= + + def [](*args) + self.value[*args] + end + def []=(*args) + val = args.pop + str = self.value + str[*args] = val + self.value = str + val + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/event.rb b/ruby_1_8_6/ext/tk/lib/tk/event.rb new file mode 100644 index 0000000000..70a1e38bbe --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/event.rb @@ -0,0 +1,488 @@ +# +# tk/event.rb - module for event +# + +module TkEvent +end + +######################## + +require 'tkutil' +require 'tk' + +######################## + +module TkEvent + class Event < TkUtil::CallbackSubst + module Grp + KEY = 0x1 + BUTTON = 0x2 + MOTION = 0x4 + CROSSING = 0x8 + FOCUS = 0x10 + EXPOSE = 0x20 + VISIBILITY = 0x40 + CREATE = 0x80 + DESTROY = 0x100 + UNMAP = 0x200 + MAP = 0x400 + REPARENT = 0x800 + CONFIG = 0x1000 + GRAVITY = 0x2000 + CIRC = 0x4000 + PROP = 0x8000 + COLORMAP = 0x10000 + VIRTUAL = 0x20000 + ACTIVATE = 0x40000 + MAPREQ = 0x80000 + CONFIGREQ = 0x100000 + RESIZEREQ = 0x200000 + CIRCREQ = 0x400000 + + MWHEEL = 0x10000000 + + ALL = 0xFFFFFFFF + + KEY_BUTTON_MOTION_VIRTUAL = (KEY|MWHEEL|BUTTON|MOTION|VIRTUAL) + KEY_BUTTON_MOTION_CROSSING = (KEY|MWHEEL|BUTTON|MOTION|CROSSING|VIRTUAL) + end + + type_data = [ + #-----+-------------------+------------------+-----------------------# + # ID | const | group_flag | context_name # + #-----+-------------------+------------------+-----------------------# + [ 2, :KeyPress, Grp::KEY, 'KeyPress', 'Key' ], + [ 3, :KeyRelease, Grp::KEY, 'KeyRelease' ], + [ 4, :ButtonPress, Grp::BUTTON, 'ButtonPress', 'Button' ], + [ 5, :ButtonRelease, Grp::BUTTON, 'ButtonRelease' ], + [ 6, :MotionNotify, Grp::MOTION, 'Motion' ], + [ 7, :EnterNotify, Grp::CROSSING, 'Enter' ], + [ 8, :LeaveNotify, Grp::CROSSING, 'Leave' ], + [ 9, :FocusIn, Grp::FOCUS, 'FocusIn' ], + [ 10, :FocusOut, Grp::FOCUS, 'FocusOut' ], + [ 11, :KeymapNotify, 0, ], + [ 12, :Expose, Grp::EXPOSE, 'Expose' ], + [ 13, :GraphicsExpose, Grp::EXPOSE, ], + [ 14, :NoExpose, 0, ], + [ 15, :VisibilityNotify, Grp::VISIBILITY, 'Visibility' ], + [ 16, :CreateNotify, Grp::CREATE, 'Create' ], + [ 17, :DestroyNotify, Grp::DESTROY, 'Destroy' ], + [ 18, :UnmapNotify, Grp::UNMAP, 'Unmap' ], + [ 19, :MapNotify, Grp::MAP, 'Map' ], + [ 20, :MapRequest, Grp::MAPREQ, 'MapRequest' ], + [ 21, :ReparentNotify, Grp::REPARENT, 'Reparent' ], + [ 22, :ConfigureNotify, Grp::CONFIG, 'Configure' ], + [ 23, :ConfigureRequest, Grp::CONFIGREQ, 'ConfigureRequest' ], + [ 24, :GravityNotify, Grp::GRAVITY, 'Gravity' ], + [ 25, :ResizeRequest, Grp::RESIZEREQ, 'ResizeRequest' ], + [ 26, :CirculateNotify, Grp::CIRC, 'Circulate' ], + [ 27, :CirculateRequest, 0, 'CirculateRequest' ], + [ 28, :PropertyNotify, Grp::PROP, 'Property' ], + [ 29, :SelectionClear, 0, ], + [ 30, :SelectionRequest, 0, ], + [ 31, :SelectionNotify, 0, ], + [ 32, :ColormapNotify, Grp::COLORMAP, 'Colormap' ], + [ 33, :ClientMessage, 0, ], + [ 34, :MappingNotify, 0, ], + [ 35, :VirtualEvent, Grp::VIRTUAL, ], + [ 36, :ActivateNotify, Grp::ACTIVATE, 'Activate' ], + [ 37, :DeactivateNotify, Grp::ACTIVATE, 'Deactivate' ], + [ 38, :MouseWheelEvent, Grp::MWHEEL, 'MouseWheel' ], + [ 39, :TK_LASTEVENT, 0, ] + ] + + module TypeNum + end + + TYPE_NAME_TBL = Hash.new + TYPE_ID_TBL = Hash.new + TYPE_GROUP_TBL = Hash.new + + type_data.each{|id, c_name, g_flag, *t_names| + TypeNum.const_set(c_name, id) + t_names.each{|t_name| t_name.freeze; TYPE_NAME_TBL[t_name] = id } + TYPE_ID_TBL[id] = t_names + TYPE_GROUP_TBL[id] = g_flag + } + + TYPE_NAME_TBL.freeze + TYPE_ID_TBL.freeze + + def self.type_id(name) + TYPE_NAME_TBL[name.to_s] + end + + def self.type_name(id) + TYPE_ID_TBL[id] && TYPE_ID_TBL[id][0] + end + + def self.group_flag(id) + TYPE_GROUP_TBL[id] || 0 + end + + ############################################# + + module StateMask + ShiftMask = (1<<0) + LockMask = (1<<1) + ControlMask = (1<<2) + Mod1Mask = (1<<3) + Mod2Mask = (1<<4) + Mod3Mask = (1<<5) + Mod4Mask = (1<<6) + Mod5Mask = (1<<7) + Button1Mask = (1<<8) + Button2Mask = (1<<9) + Button3Mask = (1<<10) + Button4Mask = (1<<11) + Button5Mask = (1<<12) + + AnyModifier = (1<<15) + + META_MASK = (AnyModifier<<1) + ALT_MASK = (AnyModifier<<2) + EXTENDED_MASK = (AnyModifier<<3) + + CommandMask = Mod1Mask + OptionMask = Mod2Mask + end + + ############################################# + + FIELD_FLAG = { + # key => flag + 'above' => Grp::CONFIG, + 'borderwidth' => (Grp::CREATE|Grp::CONFIG), + 'button' => Grp::BUTTON, + 'count' => Grp::EXPOSE, + 'data' => Grp::VIRTUAL, + 'delta' => Grp::MWHEEL, + 'detail' => (Grp::FOCUS|Grp::CROSSING), + 'focus' => Grp::CROSSING, + 'height' => (Grp::EXPOSE|Grp::CONFIG), + 'keycode' => Grp::KEY, + 'keysym' => Grp::KEY, + 'mode' => (Grp::CROSSING|Grp::FOCUS), + 'override' => (Grp::CREATE|Grp::MAP|Grp::REPARENT|Grp::CONFIG), + 'place' => Grp::CIRC, + 'root' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'rootx' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'rooty' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'sendevent' => Grp::ALL, + 'serial' => Grp::ALL, + 'state' => (Grp::KEY_BUTTON_MOTION_VIRTUAL| + Grp::CROSSING|Grp::VISIBILITY), + 'subwindow' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'time' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| + Grp::PROP), + 'warp' => Grp::KEY_BUTTON_MOTION_VIRTUAL, + 'width' => (Grp::EXPOSE|Grp::CREATE|Grp::CONFIG), + 'window' => (Grp::CREATE|Grp::UNMAP|Grp::MAP|Grp::REPARENT| + Grp::CONFIG|Grp::GRAVITY|Grp::CIRC), + 'when' => Grp::ALL, + 'x' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| + Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY| + Grp::REPARENT), + 'y' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| + Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY| + Grp::REPARENT), + } + + FIELD_OPERATION = { + 'root' => proc{|val| + begin + Tk.tk_call_without_enc('winfo', 'pathname', val) + val + rescue + nil + end + }, + + 'subwindow' => proc{|val| + begin + Tk.tk_call_without_enc('winfo', 'pathname', val) + val + rescue + nil + end + }, + + 'window' => proc{|val| nil} + } + + #------------------------------------------- + + def valid_fields(group_flag=nil) + group_flag = self.class.group_flag(self.type) unless group_flag + + fields = {} + FIELD_FLAG.each{|key, flag| + next if (flag & group_flag) == 0 + begin + val = self.__send__(key) + rescue + next + end + next if !val || val == '??' + fields[key] = val + } + + fields + end + + def valid_for_generate(group_flag=nil) + fields = valid_fields(group_flag) + + FIELD_OPERATION.each{|key, cmd| + next unless fields.has_key?(key) + val = FIELD_OPERATION[key].call(fields[key]) + if val + fields[key] = val + else + fields.delete(key) + end + } + + fields + end + + def generate(win, modkeys={}) + klass = self.class + + if modkeys.has_key?(:type) || modkeys.has_key?('type') + modkeys = TkComm._symbolkey2str(modkeys) + type_id = modkeys.delete('type') + else + type_id = self.type + end + + type_name = klass.type_name(type_id) + unless type_name + fail RuntimeError, "type_id #{type_id} is invalid" + end + + group_flag = klass.group_flag(type_id) + + opts = valid_for_generate(group_flag) + + modkeys.each{|key, val| + if val + opts[key.to_s] = val + else + opts.delete(key.to_s) + end + } + + if group_flag != Grp::KEY + Tk.event_generate(win, type_name, opts) + else + # If type is KEY event, focus should be set to target widget. + # If not set, original widget will get the same event. + # That will make infinite loop. + w = Tk.tk_call_without_enc('focus') + begin + Tk.tk_call_without_enc('focus', win) + Tk.event_generate(win, type_name, opts) + ensure + Tk.tk_call_without_enc('focus', w) + end + end + end + + ############################################# + + # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>] + KEY_TBL = [ + [ ?#, ?n, :serial ], + [ ?a, ?s, :above ], + [ ?b, ?n, :num ], + [ ?c, ?n, :count ], + [ ?d, ?s, :detail ], + [ ?f, ?b, :focus ], + [ ?h, ?n, :height ], + [ ?i, ?s, :win_hex ], + [ ?k, ?n, :keycode ], + [ ?m, ?s, :mode ], + [ ?o, ?b, :override ], + [ ?p, ?s, :place ], + [ ?s, ?x, :state ], + [ ?t, ?n, :time ], + [ ?w, ?n, :width ], + [ ?x, ?n, :x ], + [ ?y, ?n, :y ], + [ ?A, ?s, :char ], + [ ?B, ?n, :borderwidth ], + [ ?D, ?n, :wheel_delta ], + [ ?E, ?b, :send_event ], + [ ?K, ?s, :keysym ], + [ ?N, ?n, :keysym_num ], + [ ?P, ?s, :property ], + [ ?R, ?s, :rootwin_id ], + [ ?S, ?s, :subwindow ], + [ ?T, ?n, :type ], + [ ?W, ?w, :widget ], + [ ?X, ?n, :x_root ], + [ ?Y, ?n, :y_root ], + nil + ] + + # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>] + PROC_TBL = [ + [ ?n, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?b, TkComm.method(:bool) ], + [ ?w, TkComm.method(:window) ], + + [ ?x, proc{|val| + begin + TkComm::number(val) + rescue ArgumentError + val + end + } + ], + + nil + ] + + # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys + # + # _get_subst_key() and _get_all_subst_keys() generates key-string + # which describe how to convert callback arguments to ruby objects. + # When binding parameters are given, use _get_subst_key(). + # But when no parameters are given, use _get_all_subst_keys() to + # create a Event class object as a callback parameter. + # + # scan_args() is used when doing callback. It convert arguments + # ( which are Tcl strings ) to ruby objects based on the key string + # that is generated by _get_subst_key() or _get_all_subst_keys(). + # + _setup_subst_table(KEY_TBL, PROC_TBL); + + # + # NOTE: The order of parameters which passed to callback procedure is + # <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ... + # + + # If you need support extra arguments given by Tcl/Tk, + # please override _get_extra_args_tbl + # + #def self._get_extra_args_tbl + # # return an array of convert procs + # [] + #end + +=begin + alias button num + alias delta wheel_delta + alias root rootwin_id + alias rootx x_root + alias root_x x_root + alias rooty y_root + alias root_y y_root + alias sendevent send_event +=end + ALIAS_TBL = { + :button => :num, + :data => :detail, + :delta => :wheel_delta, + :root => :rootwin_id, + :rootx => :x_root, + :root_x => :x_root, + :rooty => :y_root, + :root_y => :y_root, + :sendevent => :send_event, + :window => :widget + } + + _define_attribute_aliases(ALIAS_TBL) + + end + + ############################################### + + def install_bind_for_event_class(klass, cmd, *args) + extra_args_tbl = klass._get_extra_args_tbl + + if args.compact.size > 0 + args = args.join(' ') + keys = klass._get_subst_key(args) + + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + id = install_cmd(cmd) + else + id = install_cmd(proc{|*arg| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + begin + TkUtil.eval_cmd(cmd, *(ex_args.concat(klass.scan_args(keys, arg)))) + rescue Exception=>e + if TkCore::INTERP.kind_of?(TclTkIp) + fail e + else + # MultiTkIp + fail Exception, "#{e.class}: #{e.message.dup}" + end + end + }) + end + else + keys, args = klass._get_all_subst_keys + + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + id = install_cmd(cmd) + else + id = install_cmd(proc{|*arg| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + begin + TkUtil.eval_cmd(cmd, *(ex_args << klass.new(*klass.scan_args(keys, arg)))) + rescue Exception=>e + if TkCore::INTERP.kind_of?(TclTkIp) + fail e + else + # MultiTkIp + fail Exception, "#{e.class}: #{e.message.dup}" + end + end + }) + end + end + + if TkCore::INTERP.kind_of?(TclTkIp) + id + ' ' + args + else + # MultiTkIp + "if {[set st [catch {#{id} #{args}} ret]] != 0} { + if {$st == 4} { + return -code continue $ret + } elseif {$st == 3} { + return -code break $ret + } elseif {$st == 2} { + return -code return $ret + } elseif {[regexp {^Exception: (TkCallbackContinue: .*)$} \ + $ret m msg]} { + return -code continue $msg + } elseif {[regexp {^Exception: (TkCallbackBreak: .*)$} $ret m msg]} { + return -code break $msg + } elseif {[regexp {^Exception: (TkCallbackReturn: .*)$} $ret m msg]} { + return -code return $msg + } elseif {[regexp {^Exception: (\\S+: .*)$} $ret m msg]} { + return -code return $msg + } else { + return -code error $ret + } + } else { + set ret + }" + end + end + + def install_bind(cmd, *args) + install_bind_for_event_class(TkEvent::Event, cmd, *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/font.rb b/ruby_1_8_6/ext/tk/lib/tk/font.rb new file mode 100644 index 0000000000..ab58ac5762 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/font.rb @@ -0,0 +1,1762 @@ +# +# tk/font.rb - the class to treat fonts on Ruby/Tk +# +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +class TkFont + include Tk + extend TkCore + + TkCommandNames = ['font'.freeze].freeze + + Tk_FontID = ["@font".freeze, "00000".taint].freeze + Tk_FontNameTBL = TkCore::INTERP.create_table + Tk_FontUseTBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ + Tk_FontNameTBL.clear + Tk_FontUseTBL.clear + } + + # option_type : default => string + OptionType = Hash.new(?s) + OptionType['size'] = ?n + OptionType['pointadjust'] = ?n + OptionType['underline'] = ?b + OptionType['overstrike'] = ?b + + # metric_type : default => num_or_str + MetricType = Hash.new(?n) + MetricType['fixed'] = ?b + + # set default font + case Tk::TK_VERSION + when /^4\.*/ + DEFAULT_LATIN_FONT_NAME = 'a14'.freeze + DEFAULT_KANJI_FONT_NAME = 'k14'.freeze + + when /^8\.*/ + if JAPANIZED_TK + begin + fontnames = tk_call('font', 'names') + case fontnames + when /defaultgui/ + # Tcl/Tk-JP for Windows + ltn = 'defaultgui' + knj = 'defaultgui' + when /Mincho:Helvetica-Bold-12/ + # Tcl/Tk-JP for UNIX/X + ltn, knj = tk_split_simplelist(tk_call('font', 'configure', + 'Mincho:Helvetica-Bold-12', + '-compound')) + else + # unknown Tcl/Tk-JP + #platform = tk_call('set', 'tcl_platform(platform)') + platform = Tk::PLATFORM['platform'] + case platform + when 'unix' + ltn = {'family'=>'Helvetica'.freeze, + 'size'=>-12, 'weight'=>'bold'.freeze} + #knj = 'k14' + #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0' + knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0' + when 'windows' + ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} + knj = 'mincho' + when 'macintosh' + ltn = 'system' + knj = 'mincho' + else # unknown + ltn = 'Helvetica' + knj = 'mincho' + end + end + rescue + ltn = 'Helvetica' + knj = 'mincho' + end + + else # not JAPANIZED_TK + begin + #platform = tk_call('set', 'tcl_platform(platform)') + platform = Tk::PLATFORM['platform'] + case platform + when 'unix' + ltn = {'family'=>'Helvetica'.freeze, + 'size'=>-12, 'weight'=>'bold'.freeze} + when 'windows' + ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} + when 'macintosh' + ltn = 'system' + else # unknown + ltn = 'Helvetica' + end + rescue + ltn = 'Helvetica' + end + + knj = ltn.dup + end + + DEFAULT_LATIN_FONT_NAME = ltn.freeze + DEFAULT_KANJI_FONT_NAME = knj.freeze + + else # unknown version + DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze + DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze + + end + + if $DEBUG + print "default latin font = "; p DEFAULT_LATIN_FONT_NAME + print "default kanji font = "; p DEFAULT_KANJI_FONT_NAME + end + + + ################################### + class DescendantFont + def initialize(compound, type) + unless compound.kind_of?(TkFont) + fail ArgumentError, "a TkFont object is expected for the 1st argument" + end + @compound = compound + case type + when 'kanji', 'latin', 'ascii' + @type = type + when :kanji, :latin, :ascii + @type = type.to_s + else + fail ArgumentError, "unknown type '#{type}'" + end + end + + def dup + fail RuntimeError, "cannot dupulicate a descendant font" + end + def clone + fail RuntimeError, "cannot clone a descendant font" + end + + def to_eval + @compound.__send__(@type + '_font_id') + end + def font + @compound.__send__(@type + '_font_id') + end + + def [](slot) + @compound.__send__(@type + '_configinfo', slot) + end + def []=(slot, value) + @compound.__send__(@type + '_configure', slot, value) + value + end + + def method_missing(id, *args) + @compound.__send__(@type + '_' + id.id2name, *args) + end + end + + + ################################### + # class methods + ################################### + def TkFont.actual(fnt, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.actual(option) + else + actual_core(fnt, nil, option) + end + end + + def TkFont.actual_displayof(fnt, win, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.actual_displayof(win, option) + else + win = '.' unless win + actual_core(fnt, win, option) + end + end + + def TkFont.configure(fnt, slot, value=None) + if fnt.kind_of?(TkFont) + fnt.configure(fnt, slot, value) + else + configure_core(fnt, slot, value) + end + fnt + end + + def TkFont.configinfo(fnt, slot=nil) + if fnt.kind_of?(TkFont) + fnt.configinfo(fnt, slot) + else + configinfo_core(fnt, slot) + end + end + + def TkFont.current_configinfo(fnt, slot=nil) + if fnt.kind_of?(TkFont) + fnt.current_configinfo(fnt, slot) + else + current_configinfo_core(fnt, slot) + end + end + + def TkFont.measure(fnt, text) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.measure(text) + else + measure_core(fnt, nil, text) + end + end + + def TkFont.measure_displayof(fnt, win, text) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.measure_displayof(win, text) + else + win = '.' unless win + measure_core(fnt, win, text) + end + end + + def TkFont.metrics(fnt, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.metrics(option) + else + metrics_core(fnt, nil, option) + end + end + + def TkFont.metrics_displayof(fnt, win, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + font.metrics_displayof(win, option=nil) + else + win = '.' unless win + metrics_core(fnt, win, option) + end + end + + def TkFont.families(win=nil) + case (Tk::TK_VERSION) + when /^4\.*/ + ['fixed'] + + when /^8\.*/ + if win + tk_split_simplelist(tk_call('font', 'families', '-displayof', win)) + else + tk_split_simplelist(tk_call('font', 'families')) + end + end + end + + def TkFont.names + case (Tk::TK_VERSION) + when /^4\.*/ + r = ['fixed'] + r += ['a14', 'k14'] if JAPANIZED_TK + Tk_FontNameTBL.each_value{|obj| r.push(obj)} + r | [] + + when /^8\.*/ + tk_split_simplelist(tk_call('font', 'names')) + + end + end + + def TkFont.create_copy(font) + fail 'source-font must be a TkFont object' unless font.kind_of? TkFont + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + keys = {} + font.configinfo.each{|key,value| keys[key] = value } + TkFont.new(font.latin_font_id, font.kanji_font_id, keys) + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + TkFont.new(font.latin_font_id, font.kanji_font_id, font.configinfo) + end + end + + def TkFont.get_obj(name) + if name =~ /^(@font[0-9]+)(|c|l|k)$/ + Tk_FontNameTBL[$1] + else + nil + end + end + + def TkFont.init_widget_font(pathname, *args) + win, tag, key = pathname.split(';') + key = 'font' if key == nil || key == '' + path = [win, tag, key].join(';') + + case (Tk::TK_VERSION) + when /^4\.*/ + regexp = /^-(|kanji)#{key} / + + conf_list = tk_split_simplelist(tk_call(*args)). + find_all{|prop| prop =~ regexp}. + collect{|prop| tk_split_simplelist(prop)} + + if conf_list.size == 0 + raise RuntimeError, "the widget may not support 'font' option" + end + + args << {} + + ltn_key = "-#{key}" + knj_key = "-kanji#{key}" + + ltn_info = conf_list.find{|conf| conf[0] == ltn_key} + ltn = ltn_info[-1] + ltn = nil if ltn == [] || ltn == "" + + knj_info = conf_list.find{|conf| conf[0] == knj_key} + knj = knj_info[-1] + knj = nil if knj == [] || knj == "" + + TkFont.new(ltn, knj).call_font_configure([path, key], *args) + + when /^8\.*/ + regexp = /^-#{key} / + + conf_list = tk_split_simplelist(tk_call(*args)). + find_all{|prop| prop =~ regexp}. + collect{|prop| tk_split_simplelist(prop)} + + if conf_list.size == 0 + raise RuntimeError, "the widget may not support 'font' option" + end + + args << {} + + optkey = "-#{key}" + + info = conf_list.find{|conf| conf[0] == optkey} + fnt = info[-1] + fnt = nil if fnt == [] || fnt == "" + + unless fnt + # create dummy + # TkFont.new(nil, nil).call_font_configure([path, key], *args) + dummy_fnt = TkFont.allocate + dummy_fnt.instance_eval{ init_dummy_fontobj() } + dummy_fnt + else + begin + compound = tk_split_simplelist( + Hash[*tk_split_simplelist(tk_call('font', 'configure', + fnt))].collect{|k,v| + [k[1..-1], v] + }.assoc('compound')[1]) + rescue + compound = [] + end + if compound == [] + TkFont.new(fnt).call_font_configure([path, key], *args) + else + TkFont.new(compound[0], + compound[1]).call_font_configure([path, key], *args) + end + end + end + end + + def TkFont.used_on(path=nil) + if path + Tk_FontUseTBL[path] + else + Tk_FontUseTBL.values | [] + end + end + + def TkFont.failsafe(font) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + tk_call('font', 'failsafe', font) + end + rescue + end + end + + ################################### + # instance methods + ################################### + private + ################################### + def init_dummy_fontobj + @id = Tk_FontID.join(TkCore::INTERP._ip_id_) + Tk_FontID[1].succ! + Tk_FontNameTBL[@id] = self + + @latin_desscendant = nil + @kanji_desscendant = nil + + case (Tk::TK_VERSION) + when /^4\.*/ + @latinfont = "" + @kanjifont = "" + if JAPANIZED_TK + @compoundfont = [[@latinfont], [@kanjifont]] + @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont} + else + @compoundfont = @latinfont + @fontslot = {'font'=>@latinfont} + end + else + @latinfont = @id + 'l' + @kanjifont = @id + 'k' + @compoundfont = @id + 'c' + + if JAPANIZED_TK + tk_call('font', 'create', @latinfont, '-charset', 'iso8859') + tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont]) + else + tk_call('font', 'create', @latinfont) + tk_call('font', 'create', @kanjifont) + tk_call('font', 'create', @compoundfont) + end + + @fontslot = {'font'=>@compoundfont} + end + + self + end + + def initialize(ltn=nil, knj=nil, keys=nil) + ltn = '{}' if ltn == '' + knj = '{}' if knj == '' + + # @id = Tk_FontID.join('') + @id = Tk_FontID.join(TkCore::INTERP._ip_id_) + Tk_FontID[1].succ! + Tk_FontNameTBL[@id] = self + + @latin_desscendant = nil + @kanji_desscendant = nil + + if knj.kind_of?(Hash) && !keys + keys = knj + knj = nil + end + + # compound font check + if Tk::TK_VERSION == '8.0' && JAPANIZED_TK + begin + compound = tk_split_simplelist(tk_call('font', 'configure', + ltn, '-compound')) + if knj == nil + if compound != [] + ltn, knj = compound + end + else + if compound != [] + ltn = compound[0] + end + compound = tk_split_simplelist(tk_call('font', 'configure', + knj, '-compound')) + if compound != [] + knj = compound[1] + end + end + rescue + end + end + + if ltn + if JAPANIZED_TK && !knj + if Tk::TK_VERSION =~ /^4.*/ + knj = DEFAULT_KANJI_FONT_NAME + else + knj = ltn + end + end + else + ltn = DEFAULT_LATIN_FONT_NAME + knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj + end + + create_compoundfont(ltn, knj, keys) + end + + def initialize_copy(font) + unless font.kind_of?(TkFont) + fail TypeError, '"initialize_copy should take same class object' + end + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + keys = {} + font.configinfo.each{|key,value| keys[key] = value } + initialize(font.latin_font_id, font.kanji_font_id, keys) + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + initialize(font.latin_font_id, font.kanji_font_id, font.configinfo) + end + end + + def _get_font_info_from_hash(font) + font = _symbolkey2str(font) + foundry = (info = font['foundry'] .to_s)? info: '*' + family = (info = font['family'] .to_s)? info: '*' + weight = (info = font['weight'] .to_s)? info: '*' + slant = (info = font['slant'] .to_s)? info: '*' + swidth = (info = font['swidth'] .to_s)? info: '*' + adstyle = (info = font['adstyle'] .to_s)? info: '*' + pixels = (info = font['pixels'] .to_s)? info: '*' + points = (info = font['points'] .to_s)? info: '*' + resx = (info = font['resx'] .to_s)? info: '*' + resy = (info = font['resy'] .to_s)? info: '*' + space = (info = font['space'] .to_s)? info: '*' + avgWidth = (info = font['avgWidth'].to_s)? info: '*' + charset = (info = font['charset'] .to_s)? info: '*' + encoding = (info = font['encoding'].to_s)? info: '*' + + [foundry, family, weight, slant, swidth, adstyle, + pixels, points, resx, resy, space, avgWidth, charset, encoding] + end + + def create_latinfont_tk4x(font) + if font.kind_of? Hash + @latinfont = '-' + _get_font_info_from_hash(font).join('-') + '-' + + elsif font.kind_of? Array + finfo = {} + finfo['family'] = font[0].to_s + if font[1] + fsize = font[1].to_s + if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ + if $1 == '-' + finfo['pixels'] = $2 + else + finfo['points'] = $2 + end + else + finfo['points'] = '13' + end + end + font[2..-1].each{|style| + case (style) + when 'normal' + finfo['weight'] = style + when 'bold' + finfo['weight'] = style + when 'roman' + finfo['slant'] = 'r' + when 'italic' + finfo['slant'] = 'i' + end + } + + @latinfont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' + + elsif font.kind_of? TkFont + @latinfont = font.latin_font + + else + if font + @latinfont = font + else + @latinfont = DEFAULT_LATIN_FONT_NAME + end + + end + end + + def create_kanjifont_tk4x(font) + unless JAPANIZED_TK + @kanjifont = "" + return + end + + if font.kind_of? Hash + @kanjifont = '-' + _get_font_info_from_hash(font).join('-') + '-' + + elsif font.kind_of? Array + finfo = {} + finfo['family'] = font[0].to_s + if font[1] + fsize = font[1].to_s + if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ + if $1 == '-' + finfo['pixels'] = $2 + else + finfo['points'] = $2 + end + else + finfo['points'] = '13' + end + end + font[2..-1].each{|style| + case (style) + when 'normal' + finfo['weight'] = style + when 'bold' + finfo['weight'] = style + when 'roman' + finfo['slant'] = 'r' + when 'italic' + finfo['slant'] = 'i' + end + } + + @kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' + elsif font.kind_of? TkFont + @kanjifont = font.kanji_font_id + else + if font + @kanjifont = font + else + @kanjifont = DEFAULT_KANJI_FONT_NAME + end + end + end + + def create_compoundfont_tk4x(ltn, knj, keys) + create_latinfont(ltn) + create_kanjifont(knj) + + if JAPANIZED_TK + @compoundfont = [[@latinfont], [@kanjifont]] + @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont} + else + @compoundfont = @latinfont + @fontslot = {'font'=>@latinfont} + end + end + + def create_latinfont_tk8x(font) + @latinfont = @id + 'l' + + if JAPANIZED_TK + if font.kind_of? Hash + if font[:charset] || font['charset'] + tk_call('font', 'create', @latinfont, *hash_kv(font)) + else + tk_call('font', 'create', @latinfont, + '-charset', 'iso8859', *hash_kv(font)) + end + elsif font.kind_of? Array + tk_call('font', 'create', @latinfont, '-copy', array2tk_list(font)) + tk_call('font', 'configure', @latinfont, '-charset', 'iso8859') + elsif font.kind_of? TkFont + tk_call('font', 'create', @latinfont, '-copy', font.latin_font) + elsif font + tk_call('font', 'create', @latinfont, '-copy', font, + '-charset', 'iso8859') + else + tk_call('font', 'create', @latinfont, '-charset', 'iso8859') + end + else + if font.kind_of? Hash + tk_call('font', 'create', @latinfont, *hash_kv(font)) + else + keys = {} + if font.kind_of? Array + actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} + elsif font.kind_of? TkFont + actual_core(font.latin_font).each{|key,val| keys[key] = val} + elsif font + actual_core(font).each{|key,val| keys[key] = val} + end + tk_call('font', 'create', @latinfont, *hash_kv(keys)) + end + + if font && @compoundfont + keys = {} + actual_core(@latinfont).each{|key,val| keys[key] = val} + tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) + end + end + end + + def create_kanjifont_tk8x(font) + @kanjifont = @id + 'k' + + if JAPANIZED_TK + if font.kind_of? Hash + if font[:charset] || font['charset'] + tk_call('font', 'create', @kanjifont, *hash_kv(font)) + else + tk_call('font', 'create', @kanjifont, + '-charset', 'jisx0208.1983', *hash_kv(font)) + end + elsif font.kind_of? Array + tk_call('font', 'create', @kanjifont, '-copy', array2tk_list(font)) + tk_call('font', 'configure', @kanjifont, '-charset', 'jisx0208.1983') + elsif font.kind_of? TkFont + tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font_id) + elsif font + tk_call('font', 'create', @kanjifont, '-copy', font, + '-charset', 'jisx0208.1983') + else + tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') + end + # end of JAPANIZED_TK + + else + if font.kind_of? Hash + tk_call('font', 'create', @kanjifont, *hash_kv(font)) + else + keys = {} + if font.kind_of? Array + actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} + elsif font.kind_of? TkFont + actual_core(font.kanji_font_id).each{|key,val| keys[key] = val} + elsif font + actual_core(font).each{|key,val| keys[key] = val} + end + tk_call('font', 'create', @kanjifont, *hash_kv(keys)) + end + + if font && @compoundfont + keys = {} + actual_core(@kanjifont).each{|key,val| keys[key] = val} + tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) + end + end + end + + def create_compoundfont_tk8x(ltn, knj, keys) + if knj + create_latinfont(ltn) + create_kanjifont(knj) + else + cfnt = ltn + create_kanjifont(cfnt) + create_latinfont(cfnt) + end + + @compoundfont = @id + 'c' + + if JAPANIZED_TK + unless keys + keys = {} + else + keys = keys.dup + end + if (tk_call('font', 'configure', @latinfont, '-underline') == '1' && + tk_call('font', 'configure', @kanjifont, '-underline') == '1' && + !keys.key?('underline')) + keys['underline'] = true + end + if (tk_call('font', 'configure', @latinfont, '-overstrike') == '1' && + tk_call('font', 'configure', @kanjifont, '-overstrike') == '1' && + !keys.key?('overstrike')) + keys['overstrike'] = true + end + + @fontslot = {'font'=>@compoundfont} + begin + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + rescue RuntimeError => e + if ltn == knj + if e.message =~ /kanji font .* specified/ + tk_call('font', 'delete', @latinfont) + create_latinfont(DEFAULT_LATIN_FONT_NAME) + opts = [] + Hash[*(tk_split_simplelist(tk_call('font', 'configure', + @kanjifont)))].each{|k,v| + case k + when '-size', '-weight', '-slant', '-underline', '-overstrike' + opts << k << v + end + } + tk_call('font', 'configure', @latinfont, *opts) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + + elsif e.message =~ /ascii font .* specified/ + tk_call('font', 'delete', @kanjifont) + create_kanjifont(DEFAULT_KANJI_FONT_NAME) + opts = [] + Hash[*(tk_split_simplelist(tk_call('font', 'configure', + @latinfont)))].each{|k,v| + case k + when '-size', '-weight', '-slant', '-underline', '-overstrike' + opts << k << v + end + } + tk_call('font', 'configure', @kanjifont, *opts) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + + else + raise e + end + else + raise e + end + end + else + tk_call('font', 'create', @compoundfont) + + latinkeys = {} + begin + actual_core(@latinfont).each{|key,val| latinkeys[key] = val} + rescue + latinkeys = {} + end + if latinkeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) + end + + if knj + compoundkeys = nil + kanjikeys = {} + begin + actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val} + rescue + kanjikeys = {} + end + if kanjikeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(kanjikeys)) + end + end + + if cfnt + if cfnt.kind_of?(Hash) + compoundkeys = cfnt.dup + else + compoundkeys = {} + actual_core(cfnt).each{|key,val| compoundkeys[key] = val} + end + compoundkeys.update(_symbolkey2str(keys)) + keys = compoundkeys + end + + @fontslot = {'font'=>@compoundfont} + tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) + end + end + + ################################### + public + ################################### + def inspect + sprintf("#<%s:%0x:%s>", self.class.inspect, self.__id__, @compoundfont) + end + + def method_missing(id, *args) + name = id.id2name + case args.length + when 1 + if name[-1] == ?= + configure name[0..-2], args[0] + args[0] + else + configure name, args[0] + self + end + when 0 + begin + configinfo name + rescue + super(id, *args) +# fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at + end + else + super(id, *args) +# fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at + end + end + + def call_font_configure(path, *args) + if path.kind_of?(Array) + # [path, optkey] + win, tag = path[0].split(';') + optkey = path[1].to_s + else + win, tag, optkey = path.split(';') + end + + fontslot = _symbolkey2str(@fontslot) + if optkey && optkey != "" + ltn = fontslot.delete('font') + knj = fontslot.delete('kanjifont') + fontslot[optkey] = ltn if ltn + fontslot["kanji#{optkey}"] = knj if knj + end + + keys = _symbolkey2str(args.pop).update(fontslot) + args.concat(hash_kv(keys)) + tk_call(*args) + Tk_FontUseTBL[[win, tag, optkey].join(';')] = self + self + end + + def used + ret = [] + Tk_FontUseTBL.each{|key,value| + next unless self == value + if key.include?(';') + win, tag, optkey = key.split(';') + winobj = tk_tcl2ruby(win) + if winobj.kind_of? TkText + if optkey + ret.push([winobj, winobj.tagid2obj(tag), optkey]) + else + ret.push([winobj, winobj.tagid2obj(tag)]) + end + elsif winobj.kind_of? TkCanvas + if (tagobj = TkcTag.id2obj(winobj, tag)).kind_of? TkcTag + if optkey + ret.push([winobj, tagobj, optkey]) + else + ret.push([winobj, tagobj]) + end + elsif (tagobj = TkcItem.id2obj(winobj, tag)).kind_of? TkcItem + if optkey + ret.push([winobj, tagobj, optkey]) + else + ret.push([winobj, tagobj]) + end + else + if optkey + ret.push([winobj, tag, optkey]) + else + ret.push([winobj, tag]) + end + end + elsif winobj.kind_of? TkMenu + if optkey + ret.push([winobj, tag, optkey]) + else + ret.push([winobj, tag]) + end + else + if optkey + ret.push([win, tag, optkey]) + else + ret.push([win, tag]) + end + end + else + ret.push(tk_tcl2ruby(key)) + end + } + ret + end + + def id + @id + end + + def to_eval + font + end + + def font + @compoundfont + end + alias font_id font + + def latin_font_id + @latinfont + end + + def latin_font + # @latinfont + if @latin_descendant + @latin_descendant + else + @latin_descendant = DescendantFont.new(self, 'latin') + end + end + alias latinfont latin_font + + def kanji_font_id + @kanjifont + end + + def kanji_font + # @kanjifont + if @kanji_descendant + @kanji_descendant + else + @kanji_descendant = DescendantFont.new(self, 'kanji') + end + end + alias kanjifont kanji_font + + def actual(option=nil) + actual_core(@compoundfont, nil, option) + end + + def actual_displayof(win, option=nil) + win = '.' unless win + actual_core(@compoundfont, win, option) + end + + def latin_actual(option=nil) + actual_core(@latinfont, nil, option) + end + + def latin_actual_displayof(win, option=nil) + win = '.' unless win + actual_core(@latinfont, win, option) + end + + def kanji_actual(option=nil) + #if JAPANIZED_TK + if @kanjifont != "" + actual_core(@kanjifont, nil, option) + else + actual_core_tk4x(nil, nil, option) + end + end + + def kanji_actual_displayof(win, option=nil) + #if JAPANIZED_TK + if @kanjifont != "" + win = '.' unless win + actual_core(@kanjifont, win, option) + else + actual_core_tk4x(nil, win, option) + end + end + + def [](slot) + configinfo slot + end + + def []=(slot, val) + configure slot, val + val + end + + def configure(slot, value=None) + configure_core(@compoundfont, slot, value) + self + end + + def configinfo(slot=nil) + configinfo_core(@compoundfont, slot) + end + + def current_configinfo(slot=nil) + current_configinfo_core(@compoundfont, slot) + end + + def delete + delete_core + end + + def latin_configure(slot, value=None) + if JAPANIZED_TK + configure_core(@latinfont, slot, value) + else + configure(slot, value) + end + self + end + + def latin_configinfo(slot=nil) + if JAPANIZED_TK + configinfo_core(@latinfont, slot) + else + configinfo(slot) + end + end + + def kanji_configure(slot, value=None) + #if JAPANIZED_TK + if @kanjifont != "" + configure_core(@kanjifont, slot, value) + configure('size'=>configinfo('size')) # to reflect new configuration + else + #"" + configure(slot, value) + end + self + end + + def kanji_configinfo(slot=nil) + #if JAPANIZED_TK + if @kanjifont != "" + configinfo_core(@kanjifont, slot) + else + #[] + configinfo(slot) + end + end + + def replace(ltn, knj=None) + knj = ltn if knj == None + latin_replace(ltn) + kanji_replace(knj) + self + end + + def latin_replace(ltn) + latin_replace_core(ltn) + reset_pointadjust + self + end + + def kanji_replace(knj) + kanji_replace_core(knj) + reset_pointadjust + self + end + + def measure(text) + measure_core(@compoundfont, nil, text) + end + + def measure_displayof(win, text) + win = '.' unless win + measure_core(@compoundfont, win, text) + end + + def metrics(option=nil) + metrics_core(@compoundfont, nil, option) + end + + def metrics_displayof(win, option=nil) + win = '.' unless win + metrics_core(@compoundfont, win, option) + end + + def latin_metrics(option=nil) + metrics_core(@latinfont, nil, option) + end + + def latin_metrics_displayof(win, option=nil) + win = '.' unless win + metrics_core(@latinfont, win, option) + end + + def kanji_metrics(option=nil) + if JAPANIZED_TK + metrics_core(@kanjifont, nil, option) + else + metrics_core_tk4x(nil, nil, option) + end + end + + def kanji_metrics_displayof(win, option=nil) + if JAPANIZED_TK + win = '.' unless win + metrics_core(@kanjifont, win, option) + else + metrics_core_tk4x(nil, win, option) + end + end + + def reset_pointadjust + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + configure('pointadjust' => latin_actual.assoc('size')[1].to_f / + kanji_actual.assoc('size')[1].to_f ) + end + rescue + end + self + end + + ################################### + # private alias + ################################### + case (Tk::TK_VERSION) + when /^4\.*/ + alias create_latinfont create_latinfont_tk4x + alias create_kanjifont create_kanjifont_tk4x + alias create_compoundfont create_compoundfont_tk4x + + when /^8\.[0-5]/ + alias create_latinfont create_latinfont_tk8x + alias create_kanjifont create_kanjifont_tk8x + alias create_compoundfont create_compoundfont_tk8x + + else + alias create_latinfont create_latinfont_tk8x + alias create_kanjifont create_kanjifont_tk8x + alias create_compoundfont create_compoundfont_tk8x + + end + + ################################### + # public alias + ################################### + alias ascii_font latin_font + alias asciifont latinfont + alias create_asciifont create_latinfont + alias ascii_actual latin_actual + alias ascii_actual_displayof latin_actual_displayof + alias ascii_configure latin_configure + alias ascii_configinfo latin_configinfo + alias ascii_replace latin_replace + alias ascii_metrics latin_metrics + + ################################### +=begin + def dup + TkFont.new(self) + end + def clone + TkFont.new(self) + end +=end +end + +module TkFont::CoreMethods + include Tk + extend TkCore + + private + + def actual_core_tk4x(font, win=nil, option=nil) + # dummy + if option == 'pointadjust' || option == :pointadjust + 1.0 + elsif option + case TkFont::OptionType[option.to_s] + when ?n + 0 + when ?b + false + else + '' + end + else + [['family',''], ['size',0], ['weight',''], ['slant',''], + ['underline',false], ['overstrike',false], ['charset',''], + ['pointadjust',0]] + end + end + + def actual_core_tk8x(font, win=nil, option=nil) + font = '{}' if font == '' + + if option == 'compound' || option == :compound + "" + elsif option + if win + val = tk_call('font', 'actual', font, + "-displayof", win, "-#{option}") + else + val = tk_call('font', 'actual', font, "-#{option}") + end + case TkFont::OptionType[option.to_s] + when ?n + num_or_str(val) + when ?b + bool(val) + else + val + end + else + l = tk_split_simplelist(if win + tk_call('font', 'actual', font, + "-displayof", win) + else + tk_call('font', 'actual', font) + end) + r = [] + while key=l.shift + if key == '-compound' + l.shift + else + key = key[1..-1] + val = l.shift + case TkFont::OptionType[key] + when ?n + r.push [key, num_or_str(val)] + when ?b + r.push [key, bool(val)] + else + r.push [key, val] + end + end + end + r + end + end + + def configure_core_tk4x(font, slot, value=None) + #"" + self + end + + def configinfo_core_tk4x(font, option=nil) + # dummy + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + if option == 'pointadjust' || option == :pointadjust + 1.0 + elsif option + case TkFont::OptionType[option.to_s] + when ?n + 0 + when ?b + false + else + '' + end + else + [['family',''], ['size',0], ['weight',''], ['slant',''], + ['underline',false], ['overstrike',false], ['charset',''], + ['pointadjust',1.0]] + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + current_configinfo_core_tk4x(font, option) + end + end + + def current_configinfo_core_tk4x(font, option=nil) + if option + case TkFont::OptionType[option.to_s] + when ?n + 0 + when ?b + false + else + '' + end + else + {'family'=>'', 'size'=>0, 'weight'=>'', 'slant'=>'', + 'underline'=>false, 'overstrike'=>false, + 'charset'=>false, 'pointadjust'=>1.0} + end + end + + def configure_core_tk8x(font, slot, value=None) + if JAPANIZED_TK + begin + padjust = tk_call('font', 'configure', font, '-pointadjust') + rescue + padjust = nil + end + else + padjust = nil + end + if slot.kind_of? Hash + if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family)) + slot = _symbolkey2str(slot) + configure_core_tk8x(font, 'family', slot.delete('family')) + end + + if ((slot.key?('size') || slot.key?(:size)) && + padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust)) + tk_call('font', 'configure', font, + '-pointadjust', padjust, *hash_kv(slot)) + else + tk_call('font', 'configure', font, *hash_kv(slot)) + end + elsif (slot == 'size' || slot == :size) && padjust != nil + tk_call('font', 'configure', font, + "-#{slot}", value, '-pointadjust', padjust) + elsif JAPANIZED_TK && (slot == 'family' || slot == :family) + # coumpund font? + begin + compound = tk_split_simplelist(tk_call('font', 'configure', + font, '-compound')) + rescue + tk_call('font', 'configure', font, '-family', value) + return self + end + if compound == [] + tk_call('font', 'configure', font, '-family', value) + return self + end + ltn, knj = compound + + lfnt = tk_call('font', 'create', '-copy', ltn) + begin + tk_call('font', 'configure', lfnt, '-family', value) + latin_replace_core_tk8x(lfnt) + rescue RuntimeError => e + fail e if $DEBUG + ensure + tk_call('font', 'delete', lfnt) if lfnt != '' + end + + kfnt = tk_call('font', 'create', '-copy', knj) + begin + tk_call('font', 'configure', kfnt, '-family', value) + kanji_replace_core_tk8x(lfnt) + rescue RuntimeError => e + fail e if $DEBUG + ensure + tk_call('font', 'delete', kfnt) if kfnt != '' + end + + else + tk_call('font', 'configure', font, "-#{slot}", value) + end + self + end + + def configinfo_core_tk8x(font, option=nil) + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + if option == 'compound' || option == :compound + "" + elsif option + val = tk_call('font', 'configure', font, "-#{option}") + case TkFont::OptionType[option.to_s] + when ?n + num_or_str(val) + when ?b + bool(val) + else + val + end + else + l = tk_split_simplelist(tk_call('font', 'configure', font)) + r = [] + while key=l.shift + if key == '-compound' + l.shift + else + key = key[1..-1] + val = l.shift + case TkFont::OptionType[key] + when ?n + r.push [key, num_or_str(val)] + when ?b + r.push [key, bool(val)] + else + r.push [key, val] + end + end + end + r + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + current_configinfo_core_tk8x(font, option) + end + end + + def current_configinfo_core_tk8x(font, option=nil) + if option == 'compound' + "" + elsif option + val = tk_call('font', 'configure', font, "-#{option}") + case TkFont::OptionType[option.to_s] + when ?n + num_or_str(val) + when ?b + bool(val) + else + val + end + else + l = tk_split_simplelist(tk_call('font', 'configure', font)) + h = {} + while key=l.shift + if key == '-compound' + l.shift + else + key = key[1..-1] + val = l.shift + case TkFont::OptionType[key] + when ?n + h[key] = num_or_str(val) + when ?b + h[key] = bool(val) + else + h[key] = val + end + end + end + h + end + end + + def delete_core_tk4x + TkFont::Tk_FontNameTBL.delete(@id) + TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self} + end + + def delete_core_tk8x + begin + tk_call('font', 'delete', @latinfont) + rescue + end + begin + tk_call('font', 'delete', @kanjifont) + rescue + end + begin + tk_call('font', 'delete', @compoundfont) + rescue + end + TkFont::Tk_FontNameTBL.delete(@id) + TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self} + end + + def latin_replace_core_tk4x(ltn) + create_latinfont_tk4x(ltn) + @compoundfont[0] = [@latinfont] if JAPANIZED_TK + @fontslot['font'] = @latinfont + TkFont::Tk_FontUseTBL.dup.each{|w, fobj| + if self == fobj + begin + if w.include?(';') + win, tag, optkey = w.split(';') + optkey = 'font' if optkey == nil || optkey == '' + winobj = tk_tcl2ruby(win) +# winobj.tagfont_configure(tag, {'font'=>@latinfont}) + if winobj.kind_of? TkText + tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @latinfont) + elsif winobj.kind_of? TkCanvas + tk_call(win, 'itemconfigure', tag, "-#{optkey}", @latinfont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont) + else + raise RuntimeError, "unknown widget type" + end + else +# tk_tcl2ruby(w).font_configure('font'=>@latinfont) + tk_call(w, 'configure', '-font', @latinfont) + end + rescue + TkFont::Tk_FontUseTBL.delete(w) + end + end + } + self + end + + def kanji_replace_core_tk4x(knj) + return self unless JAPANIZED_TK + + create_kanjifont_tk4x(knj) + @compoundfont[1] = [@kanjifont] + @fontslot['kanjifont'] = @kanjifont + TkFont::Tk_FontUseTBL.dup.each{|w, fobj| + if self == fobj + begin + if w.include?(';') + win, tag, optkey = w.split(';') + optkey = 'kanjifont' unless optkey + winobj = tk_tcl2ruby(win) +# winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont}) + if winobj.kind_of? TkText + tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @kanjifont) + elsif winobj.kind_of? TkCanvas + tk_call(win, 'itemconfigure', tag, "-#{optkey}", @kanjifont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont) + else + raise RuntimeError, "unknown widget type" + end + else +# tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont) + tk_call(w, 'configure', '-kanjifont', @kanjifont) + end + rescue + TkFont::Tk_FontUseTBL.delete(w) + end + end + } + self + end + + def latin_replace_core_tk8x(ltn) + ltn = '{}' if ltn == '' + + if JAPANIZED_TK + begin + tk_call('font', 'delete', '@font_tmp') + rescue + end + begin + fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont) + rescue + #fnt_bup = '' + fnt_bup = TkFont::DEFAULT_LATIN_FONT_NAME + end + end + + begin + tk_call('font', 'delete', @latinfont) + rescue + end + create_latinfont(ltn) + + if JAPANIZED_TK + keys = self.configinfo + tk_call('font', 'delete', @compoundfont) + begin + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) +=begin + latinkeys = {} + begin + actual_core(@latinfont).each{|key,val| latinkeys[key] = val} + rescue + latinkeys = {} + end + if latinkeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) + end +=end + rescue RuntimeError => e + tk_call('font', 'delete', @latinfont) + if fnt_bup && fnt_bup != '' + tk_call('font', 'create', @latinfont, '-copy', fnt_bup) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + tk_call('font', 'delete', fnt_bup) + else + fail e + end + end + + else + latinkeys = {} + begin + actual_core(@latinfont).each{|key,val| latinkeys[key] = val} + rescue + latinkeys = {} + end + if latinkeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) + end + end + self + end + + def kanji_replace_core_tk8x(knj) + knj = '{}' if knj == '' + + if JAPANIZED_TK + begin + tk_call('font', 'delete', '@font_tmp') + rescue + end + begin + fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont) + rescue + #fnt_bup = '' + fnt_bup = TkFont::DEFAULT_KANJI_FONT_NAME + end + end + + begin + tk_call('font', 'delete', @kanjifont) + rescue + end + create_kanjifont(knj) + + if JAPANIZED_TK + keys = self.configinfo + tk_call('font', 'delete', @compoundfont) + begin + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + rescue RuntimeError => e + tk_call('font', 'delete', @kanjifont) + if fnt_bup && fnt_bup != '' + tk_call('font', 'create', @kanjifont, '-copy', fnt_bup) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + tk_call('font', 'delete', fnt_bup) + else + fail e + end + end + end + self + end + + def measure_core_tk4x(font, win, text) + 0 + end + + def measure_core_tk8x(font, win, text) + font = '{}' if font == '' + + if win + number(tk_call('font', 'measure', font, + '-displayof', win, text)) + else + number(tk_call('font', 'measure', font, text)) + end + end + + def metrics_core_tk4x(font, win, option=nil) + # dummy + if option + "" + else + [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]] + end + end + + def metrics_core_tk8x(font, win, option=nil) + font = '{}' if font == '' + + if option + if win + number(tk_call('font', 'metrics', font, + "-displayof", win, "-#{option}")) + else + number(tk_call('font', 'metrics', font, "-#{option}")) + end + else + l = tk_split_list(if win + tk_call('font','metrics',font,"-displayof",win) + else + tk_call('font','metrics',font) + end) + r = [] + while key=l.shift + r.push [key[1..-1], l.shift.to_i] + end + r + end + end + + ################################### + # private alias + ################################### + case (Tk::TK_VERSION) + when /^4\.*/ + alias actual_core actual_core_tk4x + alias configure_core configure_core_tk4x + alias configinfo_core configinfo_core_tk4x + alias current_configinfo_core current_configinfo_core_tk4x + alias delete_core delete_core_tk4x + alias latin_replace_core latin_replace_core_tk4x + alias kanji_replace_core kanji_replace_core_tk4x + alias measure_core measure_core_tk4x + alias metrics_core metrics_core_tk4x + + when /^8\.[0-5]/ + alias actual_core actual_core_tk8x + alias configure_core configure_core_tk8x + alias configinfo_core configinfo_core_tk8x + alias current_configinfo_core current_configinfo_core_tk8x + alias delete_core delete_core_tk8x + alias latin_replace_core latin_replace_core_tk8x + alias kanji_replace_core kanji_replace_core_tk8x + alias measure_core measure_core_tk8x + alias metrics_core metrics_core_tk8x + + else + alias actual_core actual_core_tk8x + alias configure_core configure_core_tk8x + alias configinfo_core configinfo_core_tk8x + alias current_configinfo_core current_configinfo_core_tk8x + alias delete_core delete_core_tk8x + alias latin_replace_core latin_replace_core_tk8x + alias kanji_replace_core kanji_replace_core_tk8x + alias measure_core measure_core_tk8x + alias metrics_core metrics_core_tk8x + + end +end + +class TkFont + include TkFont::CoreMethods + extend TkFont::CoreMethods +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/frame.rb b/ruby_1_8_6/ext/tk/lib/tk/frame.rb new file mode 100644 index 0000000000..6636fef5b5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/frame.rb @@ -0,0 +1,128 @@ +# +# tk/frame.rb : treat frame widget +# +require 'tk' + +class TkFrame<TkWindow + TkCommandNames = ['frame'.freeze].freeze + WidgetClassName = 'Frame'.freeze + WidgetClassNames[WidgetClassName] = self + +################# old version +# def initialize(parent=nil, keys=nil) +# if keys.kind_of? Hash +# keys = keys.dup +# @classname = keys.delete('classname') if keys.key?('classname') +# @colormap = keys.delete('colormap') if keys.key?('colormap') +# @container = keys.delete('container') if keys.key?('container') +# @visual = keys.delete('visual') if keys.key?('visual') +# end +# super(parent, keys) +# end +# +# def create_self +# s = [] +# s << "-class" << @classname if @classname +# s << "-colormap" << @colormap if @colormap +# s << "-container" << @container if @container +# s << "-visual" << @visual if @visual +# tk_call 'frame', @path, *s +# end +################# + + def __boolval_optkeys + super() << 'container' + end + private :__boolval_optkeys + + def initialize(parent=nil, keys=nil) + my_class_name = nil + if self.class < WidgetClassNames[self.class::WidgetClassName] + my_class_name = self.class.name + my_class_name = nil if my_class_name == '' + end + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + else + if keys + keys = _symbolkey2str(keys) + keys['parent'] = parent + else + keys = {'parent'=>parent} + end + end + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + @classname = keys['class'] + @colormap = keys['colormap'] + @container = keys['container'] + @visual = keys['visual'] + if !@classname && my_class_name + keys['class'] = @classname = my_class_name + end + if @classname.kind_of? TkBindTag + @db_class = @classname + @classname = @classname.id + elsif @classname + @db_class = TkDatabaseClass.new(@classname) + else + @db_class = self.class + @classname = @db_class::WidgetClassName + end + super(keys) + end + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('frame', @path, *hash_kv(keys)) + # else + # tk_call_without_enc( 'frame', @path) + # end + #end + #private :create_self + + def database_classname + @classname + end + + def self.database_class + if self == WidgetClassNames[WidgetClassName] || self.name == '' + self + else + TkDatabaseClass.new(self.name) + end + end + def self.database_classname + self.database_class.name + end + + def self.bind(*args, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind(*args, &b) + end + end + def self.bind_append(*args, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind_append(*args, &b) + end + end + def self.bind_remove(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bind_remove(*args) + end + end + def self.bindinfo(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bindinfo(*args) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/grid.rb b/ruby_1_8_6/ext/tk/lib/tk/grid.rb new file mode 100644 index 0000000000..10fdf3569b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/grid.rb @@ -0,0 +1,220 @@ +# +# tk/grid.rb : control grid geometry manager +# +require 'tk' + +module TkGrid + include Tk + extend Tk + + TkCommandNames = ['grid'.freeze].freeze + + def anchor(master, anchor=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + tk_call_without_enc('grid', 'anchor', master, anchor) + end + + def bbox(master, *args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + args.unshift(master) + list(tk_call_without_enc('grid', 'bbox', *args)) + end + + def configure(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + params.push(_epath(win)) + args.each{|win| + case win + when '-', 'x', '^' # RELATIVE PLACEMENT + params.push(win) + else + params.push(_epath(win)) + end + } + opts.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + if Tk::TCL_MAJOR_VERSION < 8 || + (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION <= 3) + if params[0] == '-' || params[0] == 'x' || params[0] == '^' + tk_call_without_enc('grid', *params) + else + tk_call_without_enc('grid', 'configure', *params) + end + else + tk_call_without_enc('grid', 'configure', *params) + end + end + alias grid configure + + def columnconfigure(master, index, args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + tk_call_without_enc("grid", 'columnconfigure', + master, index, *hash_kv(args)) + end + + def rowconfigure(master, index, args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + tk_call_without_enc("grid", 'rowconfigure', master, index, *hash_kv(args)) + end + + def columnconfiginfo(master, index, slot=nil) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if slot + case slot + when 'uniform', :uniform + tk_call_without_enc('grid', 'columnconfigure', + master, index, "-#{slot}") + else + num_or_str(tk_call_without_enc('grid', 'columnconfigure', + master, index, "-#{slot}")) + end + else + #ilist = list(tk_call_without_enc('grid','columnconfigure',master,index)) + ilist = simplelist(tk_call_without_enc('grid', 'columnconfigure', + master, index)) + info = {} + while key = ilist.shift + case key + when 'uniform' + info[key[1..-1]] = ilist.shift + else + info[key[1..-1]] = tk_tcl2ruby(ilist.shift) + end + end + info + end + end + + def rowconfiginfo(master, index, slot=nil) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if slot + case slot + when 'uniform', :uniform + tk_call_without_enc('grid', 'rowconfigure', + master, index, "-#{slot}") + else + num_or_str(tk_call_without_enc('grid', 'rowconfigure', + master, index, "-#{slot}")) + end + else + #ilist = list(tk_call_without_enc('grid', 'rowconfigure', master, index)) + ilist = simplelist(tk_call_without_enc('grid', 'rowconfigure', + master, index)) + info = {} + while key = ilist.shift + case key + when 'uniform' + info[key[1..-1]] = ilist.shift + else + info[key[1..-1]] = tk_tcl2ruby(ilist.shift) + end + end + info + end + end + + def add(widget, *args) + configure(widget, *args) + end + + def forget(*args) + return '' if args.size == 0 + wins = args.collect{|win| + # (win.kind_of?(TkObject))? win.epath: win + _epath(win) + } + tk_call_without_enc('grid', 'forget', *wins) + end + + def info(slave) + # slave = slave.epath if slave.kind_of?(TkObject) + slave = _epath(slave) + #ilist = list(tk_call_without_enc('grid', 'info', slave)) + ilist = simplelist(tk_call_without_enc('grid', 'info', slave)) + info = {} + while key = ilist.shift + #info[key[1..-1]] = ilist.shift + info[key[1..-1]] = tk_tcl2ruby(ilist.shift) + end + return info + end + + def location(master, x, y) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('grid', 'location', master, x, y)) + end + + def propagate(master, mode=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if mode == None + bool(tk_call_without_enc('grid', 'propagate', master)) + else + tk_call_without_enc('grid', 'propagate', master, mode) + end + end + + def remove(*args) + return '' if args.size == 0 + wins = args.collect{|win| + # (win.kind_of?(TkObject))? win.epath: win + _epath(win) + } + tk_call_without_enc('grid', 'remove', *wins) + end + + def size(master) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('grid', 'size', master)) + end + + def slaves(master, args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('grid', 'slaves', master, *hash_kv(args))) + end + + module_function :bbox, :forget, :propagate, :info + module_function :remove, :size, :slaves, :location + module_function :grid, :configure, :columnconfigure, :rowconfigure + module_function :columnconfiginfo, :rowconfiginfo +end +=begin +def TkGrid(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + params.push((win.kind_of?(TkObject))? win.epath: win) + args.each{|win| + case win + when '-', 'x', '^' # RELATIVE PLACEMENT + params.push(win) + else + params.push((win.kind_of?(TkObject))? win.epath: win) + end + } + opts.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + tk_call_without_enc("grid", *params) +end +=end diff --git a/ruby_1_8_6/ext/tk/lib/tk/image.rb b/ruby_1_8_6/ext/tk/lib/tk/image.rb new file mode 100644 index 0000000000..35e2c4e394 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/image.rb @@ -0,0 +1,237 @@ +# +# tk/image.rb : treat Tk image objects +# + +require 'tk' + +class TkImage<TkObject + include Tk + + TkCommandNames = ['image'.freeze].freeze + + Tk_IMGTBL = TkCore::INTERP.create_table + Tk_Image_ID = ['i'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ Tk_IMGTBL.clear } + + def self.new(keys=nil) + if keys.kind_of?(Hash) + name = nil + if keys.key?(:imagename) + name = keys[:imagename] + elsif keys.key?('imagename') + name = keys['imagename'] + end + if name + if name.kind_of?(TkImage) + obj = name + else + name = _get_eval_string(name) + obj = Tk_IMGTBL[name] + end + if obj + if !(keys[:without_creating] || keys['without_creating']) + keys = _symbolkey2str(keys) + keys.delete('imagename') + keys.delete('without_creating') + obj.instance_eval{ + tk_call_without_enc('image', 'create', + @type, @path, *hash_kv(keys, true)) + } + end + return obj + end + end + end + super(keys) + end + + def initialize(keys=nil) + @path = nil + without_creating = false + if keys.kind_of?(Hash) + keys = _symbolkey2str(keys) + @path = keys.delete('imagename') + without_creating = keys.delete('without_creating') + end + unless @path + # @path = Tk_Image_ID.join('') + @path = Tk_Image_ID.join(TkCore::INTERP._ip_id_) + Tk_Image_ID[1].succ! + end + unless without_creating + tk_call_without_enc('image', 'create', + @type, @path, *hash_kv(keys, true)) + end + Tk_IMGTBL[@path] = self + end + + def delete + Tk_IMGTBL.delete(@id) if @id + tk_call_without_enc('image', 'delete', @path) + self + end + def height + number(tk_call_without_enc('image', 'height', @path)) + end + def inuse + bool(tk_call_without_enc('image', 'inuse', @path)) + end + def itemtype + tk_call_without_enc('image', 'type', @path) + end + def width + number(tk_call_without_enc('image', 'width', @path)) + end + + def TkImage.names + Tk.tk_call_without_enc('image', 'names').split.collect!{|id| + (Tk_IMGTBL[id])? Tk_IMGTBL[id] : id + } + end + + def TkImage.types + Tk.tk_call_without_enc('image', 'types').split + end +end + +class TkBitmapImage<TkImage + def __strval_optkeys + super() + ['maskdata', 'maskfile'] + end + private :__strval_optkeys + + def initialize(*args) + @type = 'bitmap' + super(*args) + end +end + +class TkPhotoImage<TkImage + NullArgOptionKeys = [ "shrink", "grayscale" ] + + def _photo_hash_kv(keys) + keys = _symbolkey2str(keys) + NullArgOptionKeys.collect{|opt| + if keys[opt] + keys[opt] = None + else + keys.delete(opt) + end + } + keys.collect{|k,v| + ['-' << k, v] + }.flatten + end + private :_photo_hash_kv + + def initialize(*args) + @type = 'photo' + super(*args) + end + + def blank + tk_send_without_enc('blank') + self + end + + def cget(option) + case option.to_s + when 'data', 'file' + tk_send 'cget', '-' << option.to_s + else + tk_tcl2ruby(tk_send('cget', '-' << option.to_s)) + end + end + + def copy(src, *opts) + if opts.size == 0 + tk_send('copy', src) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('copy', src, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + args = opts.collect{|term| + if term.kind_of?(String) && term.include?(?\s) + term.split + else + term + end + }.flatten + tk_send('copy', src, *args) + end + self + end + + def data(keys={}) + #tk_send('data', *_photo_hash_kv(keys)) + tk_split_list(tk_send('data', *_photo_hash_kv(keys))) + end + + def get(x, y) + tk_send('get', x, y).split.collect{|n| n.to_i} + end + + def put(data, *opts) + if opts == [] + tk_send('put', data) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('put', data, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + tk_send('put', data, '-to', *opts) + end + self + end + + def read(file, *opts) + if opts.size == 0 + tk_send('read', file) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('read', file, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + args = opts.collect{|term| + if term.kind_of?(String) && term.include?(?\s) + term.split + else + term + end + }.flatten + tk_send('read', file, *args) + end + self + end + + def redither + tk_send 'redither' + self + end + + def get_transparency(x, y) + bool(tk_send('transparency', 'get', x, y)) + end + def set_transparency(x, y, st) + tk_send('transparency', 'set', x, y, st) + self + end + + def write(file, *opts) + if opts.size == 0 + tk_send('write', file) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('write', file, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + args = opts.collect{|term| + if term.kind_of?(String) && term.include?(?\s) + term.split + else + term + end + }.flatten + tk_send('write', file, *args) + end + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/itemconfig.rb b/ruby_1_8_6/ext/tk/lib/tk/itemconfig.rb new file mode 100644 index 0000000000..a7885e74f3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/itemconfig.rb @@ -0,0 +1,1061 @@ +# +# tk/itemconfig.rb : control item/tag configuration of widget +# +require 'tk' +require 'tkutil' +require 'tk/itemfont.rb' + +module TkItemConfigOptkeys + include TkUtil + + def __item_numval_optkeys(id) + [] + end + private :__item_numval_optkeys + + def __item_numstrval_optkeys(id) + [] + end + private :__item_numstrval_optkeys + + def __item_boolval_optkeys(id) + ['exportselection', 'jump', 'setgrid', 'takefocus'] + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + # maybe need to override + [ + 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile', + 'activebackground', 'activeforeground', 'background', + 'disabledforeground', 'disabledbackground', 'foreground', + 'highlightbackground', 'highlightcolor', 'insertbackground', + 'selectbackground', 'selectforeground', 'troughcolor' + ] + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys + + def __item_numlistval_optkeys(id) + # maybe need to override + ['dash', 'activedash', 'disableddash'] + end + private :__item_numlistval_optkeys + + def __item_tkvariable_optkeys(id) + ['variable', 'textvariable'] + end + private :__item_tkvariable_optkeys + + def __item_val2ruby_optkeys(id) # { key=>method, ... } + # The method is used to convert a opt-value to a ruby's object. + # When get the value of the option "key", "method.call(id, val)" is called. + {} + end + private :__item_val2ruby_optkeys + + def __item_ruby2val_optkeys(id) # { key=>method, ... } + # The method is used to convert a ruby's object to a opt-value. + # When set the value of the option "key", "method.call(id, val)" is called. + # That is, "-#{key} #{method.call(id, value)}". + {} + end + private :__item_ruby2val_optkeys + + def __item_methodcall_optkeys(id) # { key=>method, ... } + # Use the method for both of get and set. + # Usually, the 'key' will not be a widget option. + # + # maybe need to override + # {'coords'=>'coords'} + {} + end + private :__item_methodcall_optkeys + + ################################################ + + def __item_keyonly_optkeys(id) # { def_key=>(undef_key|nil), ... } + # maybe need to override + {} + end + private :__item_keyonly_optkeys + + + def __conv_item_keyonly_opts(id, keys) + return keys unless keys.kind_of?(Hash) + keyonly = __item_keyonly_optkeys(id) + keys2 = {} + keys.each{|k, v| + optkey = keyonly.find{|kk,vv| kk.to_s == k.to_s} + if optkey + defkey, undefkey = optkey + if v + keys2[defkey.to_s] = None + else + keys2[undefkey.to_s] = None + end + else + keys2[k.to_s] = v + end + } + keys2 + end + + def itemconfig_hash_kv(id, keys, enc_mode = nil, conf = nil) + hash_kv(__conv_item_keyonly_opts(id, keys), enc_mode, conf) + end +end + +module TkItemConfigMethod + include TkUtil + include TkTreatItemFont + include TkItemConfigOptkeys + + def __item_cget_cmd(id) + # maybe need to override + [self.path, 'itemcget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + # maybe need to override + [self.path, 'itemconfigure', id] + end + private :__item_config_cmd + + def __item_confinfo_cmd(id) + # maybe need to override + __item_config_cmd(id) + end + private :__item_confinfo_cmd + + def __item_configinfo_struct(id) + # maybe need to override + {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, + :default_value=>3, :current_value=>4} + end + private :__item_configinfo_struct + + ################################################ + + def tagid(tagOrId) + # maybe need to override + tagOrId + end + + ################################################ + + def itemcget(tagOrId, option) + orig_opt = option + option = option.to_s + + if option.length == 0 + fail ArgumentError, "Invalid option `#{orig_opt.inspect}'" + end + + if ( method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[option] ) + optval = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")) + begin + return method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + return optval + end + end + + if ( method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[option] ) + return self.__send__(method, tagOrId) + end + + case option + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + number(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + rescue + nil + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + num_or_str(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + bool(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + rescue + nil + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + simplelist(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + conf = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")) + if conf =~ /^[0-9]/ + list(conf) + else + conf + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + v = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")) + (v.empty?)? nil: TkVarAccess.new(v) + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + _fromUTF8(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + + when /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/ + fontcode = $1 + fontkey = $2 + fnt = tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{fontkey}")), true) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(tagid(tagOrId), fontkey) + end + if fontcode == 'kanji' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")), true) + end + end + + def itemconfigure(tagOrId, slot, value=None) + if slot.kind_of? Hash + slot = _symbolkey2str(slot) + + __item_methodcall_optkeys(tagid(tagOrId)).each{|key, method| + value = slot.delete(key.to_s) + self.__send__(method, tagOrId, value) if value + } + + __item_ruby2val_optkeys(tagid(tagOrId)).each{|key, method| + key = key.to_s + slot[key] = method.call(tagOrId, slot[key]) if slot.has_key?(key) + } + + __item_keyonly_optkeys(tagid(tagOrId)).each{|defkey, undefkey| + conf = slot.find{|kk, vv| kk == defkey.to_s} + if conf + k, v = conf + if v + slot[k] = None + else + slot[undefkey.to_s] = None if undefkey + slot.delete(k) + end + end + } + + if (slot.find{|k, v| k =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/}) + tagfont_configure(tagid(tagOrId), slot) + elsif slot.size > 0 + tk_call(*(__item_config_cmd(tagid(tagOrId)).concat(hash_kv(slot)))) + end + + else + orig_slot = slot + slot = slot.to_s + if slot.length == 0 + fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" + end + + if ( conf = __item_keyonly_optkeys(tagid(tagOrId)).find{|k, v| k.to_s == slot } ) + defkey, undefkey = conf + if value + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{defkey}")) + elsif undefkey + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{undefkey}")) + end + elsif ( method = _symbolkey2str(__item_ruby2val_optkeys(tagid(tagOrId)))[slot] ) + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{slot}" << method.call(tagOrId, value))) + elsif ( method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] ) + self.__send__(method, tagOrId, value) + elsif (slot =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + if value == None + tagfontobj(tagid(tagOrId), $2) + else + tagfont_configure(tagid(tagOrId), {slot=>value}) + end + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{slot}" << value)) + end + end + self + end + + def __itemconfiginfo_core(tagOrId, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + fontkey = $2 + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")), false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), fontkey) + elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- ) + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + conf + else + if slot + slot = slot.to_s + case slot + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] + return [slot, '', '', '', self.__send__(method, tagOrId)] + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_list(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), 0, false, true) + end + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- ) + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + + conf + + else + # ret = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))))).collect{|conflist| + # conf = tk_split_simplelist(conflist) + ret = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + optkey = conf[__item_configinfo_struct(tagid(tagOrId))[:key]] + case optkey + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey] + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # do nothing + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + end + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + end + end + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- ) + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + + conf + } + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + fontconf = ret.assoc(optkey) + if fontconf && fontconf.size > 2 + ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/} + fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey) + ret.push(fontconf) + end + } + + __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| + ret << [optkey.to_s, '', '', '', self.__send__(method, tagOrId)] + } + + ret + end + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + fontkey = $2 + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")), false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = fontobj(tagid(tagOrId), fontkey) + { conf.shift => conf } + elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + { conf[0] => conf[1] } + else + { conf.shift => conf } + end + else + if slot + slot = slot.to_s + case slot + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] + return {slot => ['', '', '', self.__send__(method, tagOrId)]} + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_stre(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_list(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), 0, false, true) + end + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + { conf[0] => conf[1] } + else + { conf.shift => conf } + end + + else + ret = {} + # tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))))).each{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + optkey = conf[__item_configinfo_struct(tagid(tagOrId))[:key]] + case optkey + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey] + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # do nothing + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + end + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + end + end + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + ret[conf[0]] = conf[1] + else + ret[conf.shift] = conf + end + } + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + fontconf = ret[optkey] + if fontconf.kind_of?(Array) + ret.delete(optkey) + ret.delete('latin' << optkey) + ret.delete('ascii' << optkey) + ret.delete('kanji' << optkey) + fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey) + ret[optkey] = fontconf + end + } + + __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| + ret[optkey.to_s] = ['', '', '', self.__send__(method, tagOrId)] + } + + ret + end + end + end + end + private :__itemconfiginfo_core + + def itemconfiginfo(tagOrId, slot = nil) + __itemconfiginfo_core(tagOrId, slot) + end + + def current_itemconfiginfo(tagOrId, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + org_slot = slot + begin + conf = __itemconfiginfo_core(tagOrId, slot) + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + return {conf[0] => conf[-1]} + end + slot = conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] + end while(org_slot != slot) + fail RuntimeError, + "there is a configure alias loop about '#{org_slot}'" + else + ret = {} + __itemconfiginfo_core(tagOrId).each{|conf| + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + ret[conf[0]] = conf[-1] + end + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + __itemconfiginfo_core(tagOrId, slot).each{|key, conf| + ret[key] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/itemfont.rb b/ruby_1_8_6/ext/tk/lib/tk/itemfont.rb new file mode 100644 index 0000000000..ab9e3ff6c9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/itemfont.rb @@ -0,0 +1,300 @@ +# +# tk/itemfont.rb : control font of widget items +# +require 'tk' + +module TkItemFontOptkeys + def __item_font_optkeys(id) + # maybe need to override + ['font'] + end + private :__item_font_optkeys +end + +module TkTreatItemFont + include TkItemFontOptkeys + + def __item_pathname(id) + # maybe need to override + [self.path, id].join(';') + end + private :__item_pathname + + ################################################ + + def tagfont_configinfo(tagOrId, key = nil) + optkeys = __item_font_optkeys(tagid(tagOrId)) + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __item_pathname(tagid(tagOrId)).split(';') + + if key + pathname = [win, tag, key].join(';') + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, + *(__item_confinfo_cmd(tagid(tagOrId)))) + elsif optkeys.size == 1 + pathname = [win, tag, optkeys[0]].join(';') + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, + *(__item_confinfo_cmd(tagid(tagOrId)))) + else + fonts = {} + optkeys.each{|key| + key = key.to_s + pathname = [win, tag, key].join(';') + fonts[key] = + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, + *(__item_confinfo_cmd(tagid(tagOrId)))) + } + fonts + end + end + alias tagfontobj tagfont_configinfo + + def tagfont_configure(tagOrId, slot) + pathname = __item_pathname(tagid(tagOrId)) + + slot = _symbolkey2str(slot) + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + l_optkey = 'latin' << optkey + a_optkey = 'ascii' << optkey + k_optkey = 'kanji' << optkey + + if slot.key?(optkey) + fnt = slot.delete(optkey) + if fnt.kind_of?(TkFont) + slot.delete(l_optkey) + slot.delete(a_optkey) + slot.delete(k_optkey) + + fnt.call_font_configure([pathname, optkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + next + else + if fnt + if (slot.key?(l_optkey) || + slot.key?(a_optkey) || + slot.key?(k_optkey)) + fnt = TkFont.new(fnt) + + lfnt = slot.delete(l_optkey) + lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) + kfnt = slot.delete(k_optkey) + + fnt.latin_replace(lfnt) if lfnt + fnt.kanji_replace(kfnt) if kfnt + + fnt.call_font_configure([pathname, optkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + next + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << fnt)) + end + end + next + end + end + + lfnt = slot.delete(l_optkey) + lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) + kfnt = slot.delete(k_optkey) + + if lfnt && kfnt + TkFont.new(lfnt, kfnt).call_font_configure([pathname, optkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + elsif lfnt + latintagfont_configure([lfnt, optkey]) + elsif kfnt + kanjitagfont_configure([kfnt, optkey]) + end + } + + # configure other (without font) options + tk_call(*(__item_config_cmd(tagid(tagOrId)).concat(hash_kv(slot)))) if slot != {} + self + end + + def latintagfont_configure(tagOrId, ltn, keys=nil) + if ltn.kind_of?(Array) + key = ltn[1] + ltn = ltn[0] + else + key = nil + end + + optkeys = __item_font_optkeys(tagid(tagOrId)) + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __item_pathname(tagid(tagOrId)).split(';') + + optkeys = [key] if key + + optkeys.each{|optkey| + optkey = optkey.to_s + + pathname = [win, tag, optkey].join(';') + + if (fobj = TkFont.used_on(pathname)) + fobj = TkFont.new(fobj) # create a new TkFont object + elsif Tk::JAPANIZED_TK + fobj = fontobj # create a new TkFont object + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << ltn)) + next + end + + if fobj.kind_of?(TkFont) + if ltn.kind_of?(TkFont) + conf = {} + ltn.latin_configinfo.each{|key,val| conf[key] = val} + if keys + fobj.latin_configure(conf.update(keys)) + else + fobj.latin_configure(conf) + end + else + fobj.latin_replace(ltn) + end + end + + fobj.call_font_configure([pathname, optkey], *(__item_config_cmd(tagid(tagOrId)) << {})) + } + self + end + alias asciitagfont_configure latintagfont_configure + + def kanjitagfont_configure(tagOrId, knj, keys=nil) + if knj.kind_of?(Array) + key = knj[1] + knj = knj[0] + else + key = nil + end + + optkeys = __item_font_optkeys(tagid(tagOrId)) + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __item_pathname(tagid(tagOrId)).split(';') + + optkeys = [key] if key + + optkeys.each{|optkey| + optkey = optkey.to_s + + pathname = [win, tag, optkey].join(';') + + if (fobj = TkFont.used_on(pathname)) + fobj = TkFont.new(fobj) # create a new TkFont object + elsif Tk::JAPANIZED_TK + fobj = fontobj # create a new TkFont object + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << knj)) + next + end + + if fobj.kind_of?(TkFont) + if knj.kind_of?(TkFont) + conf = {} + knj.kanji_configinfo.each{|key,val| conf[key] = val} + if keys + fobj.kanji_configure(conf.update(keys)) + else + fobj.kanji_configure(conf) + end + else + fobj.kanji_replace(knj) + end + end + + fobj.call_font_configure([pathname, optkey], *(__item_config_cmd(tagid(tagOrId)) << {})) + } + self + end + + def tagfont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil) + if wintag + if winkey + fnt = win.tagfontobj(wintag, winkey).dup + else + fnt = win.tagfontobj(wintag).dup + end + else + if winkey + fnt = win.fontobj(winkey).dup + else + fnt = win.fontobj.dup + end + end + + if targetkey + fnt.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + else + fnt.call_font_configure(__item_pathname(tagid(tagOrId)), + *(__item_config_cmd(tagid(tagOrId)) << {})) + end + self + end + + + def latintagfont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil) + if targetkey + fontobj(targetkey).dup.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + else + fontobj.dup.call_font_configure(__item_pathname(tagid(tagOrId)), + *(__item_config_cmd(tagid(tagOrId)) << {})) + end + + if wintag + if winkey + fontobj.latin_replace(win.tagfontobj(wintag, winkey).latin_font_id) + else + fontobj.latin_replace(win.tagfontobj(wintag).latin_font_id) + end + else + if winkey + fontobj.latin_replace(win.fontobj(winkey).latin_font_id) + else + fontobj.latin_replace(win.fontobj.latin_font_id) + end + end + self + end + alias asciitagfont_copy latintagfont_copy + + def kanjifont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil) + if targetkey + fontobj(targetkey).dup.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + else + fontobj.dup.call_font_configure(__item_pathname(tagid(tagOrId)), + *(__item_config_cmd(tagid(tagOrId)) << {})) + end + + if wintag + if winkey + fontobj.kanji_replace(win.tagfontobj(wintag, winkey).kanji_font_id) + else + fontobj.kanji_replace(win.tagfontobj(wintag).kanji_font_id) + end + else + if winkey + fontobj.kanji_replace(win.fontobj(winkey).kanji_font_id) + else + fontobj.kanji_replace(win.fontobj.kanji_font_id) + end + end + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/kinput.rb b/ruby_1_8_6/ext/tk/lib/tk/kinput.rb new file mode 100644 index 0000000000..a29dbcdb72 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/kinput.rb @@ -0,0 +1,71 @@ +# +# tk/kinput.rb : control kinput +# +require 'tk' + +module TkKinput + include Tk + extend Tk + + TkCommandNames = [ + 'kinput_start'.freeze, + 'kinput_send_spot'.freeze, + 'kanjiInput'.freeze + ].freeze + + def TkKinput.start(win, style=None) + tk_call('kinput_start', win, style) + end + def kinput_start(style=None) + TkKinput.start(self, style) + end + + def TkKinput.send_spot(win) + tk_call('kinput_send_spot', win) + end + def kinput_send_spot + TkKinput.send_spot(self) + end + + def TkKinput.input_start(win, keys=nil) + tk_call('kanjiInput', 'start', win, *hash_kv(keys)) + end + def kanji_input_start(keys=nil) + TkKinput.input_start(self, keys) + end + + def TkKinput.attribute_config(win, slot, value=None) + if slot.kind_of? Hash + tk_call('kanjiInput', 'attribute', win, *hash_kv(slot)) + else + tk_call('kanjiInput', 'attribute', win, "-#{slot}", value) + end + end + def kinput_attribute_config(slot, value=None) + TkKinput.attribute_config(self, slot, value) + end + + def TkKinput.attribute_info(win, slot=nil) + if slot + conf = tk_split_list(tk_call('kanjiInput', 'attribute', + win, "-#{slot}")) + conf[0] = conf[0][1..-1] + conf + else + tk_split_list(tk_call('kanjiInput', 'attribute', win)).collect{|conf| + conf[0] = conf[0][1..-1] + conf + } + end + end + def kinput_attribute_info(slot=nil) + TkKinput.attribute_info(self, slot) + end + + def TkKinput.input_end(win) + tk_call('kanjiInput', 'end', win) + end + def kanji_input_end + TkKinput.input_end(self) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/label.rb b/ruby_1_8_6/ext/tk/lib/tk/label.rb new file mode 100644 index 0000000000..8b45db9b30 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/label.rb @@ -0,0 +1,18 @@ +# +# tk/label.rb : treat label widget +# +require 'tk' + +class TkLabel<TkWindow + TkCommandNames = ['label'.freeze].freeze + WidgetClassName = 'Label'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('label', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('label', @path) + # end + #end + #private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/labelframe.rb b/ruby_1_8_6/ext/tk/lib/tk/labelframe.rb new file mode 100644 index 0000000000..73d5603200 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/labelframe.rb @@ -0,0 +1,25 @@ +# +# tk/labelframe.rb : treat labelframe widget +# +require 'tk' +require 'tk/frame' + +class TkLabelFrame<TkFrame + TkCommandNames = ['labelframe'.freeze].freeze + WidgetClassName = 'Labelframe'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('labelframe', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('labelframe', @path) + # end + #end + #private :create_self + + def __val2ruby_optkeys # { key=>proc, ... } + super().update('labelwidget'=>proc{|v| window(v)}) + end + private :__val2ruby_optkeys +end +TkLabelframe = TkLabelFrame diff --git a/ruby_1_8_6/ext/tk/lib/tk/listbox.rb b/ruby_1_8_6/ext/tk/lib/tk/listbox.rb new file mode 100644 index 0000000000..41d02d279e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/listbox.rb @@ -0,0 +1,279 @@ +# +# tk/listbox.rb : treat listbox widget +# +require 'tk' +require 'tk/itemconfig' +require 'tk/scrollable' +require 'tk/txtwin_abst' + +module TkListItemConfig + include TkItemConfigMethod + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys +end + +class TkListbox<TkTextWin + include TkListItemConfig + include Scrollable + + TkCommandNames = ['listbox'.freeze].freeze + WidgetClassName = 'Listbox'.freeze + WidgetClassNames[WidgetClassName] = self + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('listbox', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('listbox', @path) + # end + #end + #private :create_self + + def __tkvariable_optkeys + super() << 'listvariable' + end + private :__tkvariable_optkeys + + def tagid(id) + #id.to_s + _get_eval_string(id) + end + + def activate(y) + tk_send_without_enc('activate', y) + self + end + def curselection + list(tk_send_without_enc('curselection')) + end + def get(first, last=nil) + if last + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('get', first, last))) + tk_split_simplelist(tk_send_without_enc('get', first, last), false, true) + else + _fromUTF8(tk_send_without_enc('get', first)) + end + end + def nearest(y) + tk_send_without_enc('nearest', y).to_i + end + def size + tk_send_without_enc('size').to_i + end + def selection_anchor(index) + tk_send_without_enc('selection', 'anchor', index) + self + end + def selection_clear(first, last=None) + tk_send_without_enc('selection', 'clear', first, last) + self + end + def selection_includes(index) + bool(tk_send_without_enc('selection', 'includes', index)) + end + def selection_set(first, last=None) + tk_send_without_enc('selection', 'set', first, last) + self + end + + def index(idx) + tk_send_without_enc('index', idx).to_i + end + + def value + get('0', 'end') + end + + def value= (vals) + unless vals.kind_of?(Array) + fail ArgumentError, 'an Array is expected' + end + tk_send_without_enc('delete', '0', 'end') + tk_send_without_enc('insert', '0', + *(vals.collect{|v| _get_eval_enc_str(v)})) + vals + end + + def clear + tk_send_without_enc('delete', '0', 'end') + self + end + alias erase clear + +=begin + def itemcget(index, key) + case key.to_s + when 'text', 'label', 'show' + _fromUTF8(tk_send_without_enc('itemcget', index, "-#{key}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('itemcget', index, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', index, + '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(index, fnt) + end + if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', index, "-#{key}"))) + end + end + def itemconfigure(index, key, val=None) + if key.kind_of? Hash + if (key['font'] || key[:font] || + key['kanjifont'] || key[:kanjifont] || + key['latinfont'] || key[:latinfont] || + key['asciifont'] || key[:asciifont] ) + tagfont_configure(index, _symbolkey2str(key)) + else + tk_send_without_enc('itemconfigure', index, *hash_kv(key, true)) + end + + else + if (key == 'font' || key == :font || + key == 'kanjifont' || key == :kanjifont || + key == 'latinfont' || key == :latinfont || + key == 'asciifont' || key == :asciifont ) + if val == None + tagfontobj(index) + else + tagfont_configure(index, {key=>val}) + end + else + tk_call('itemconfigure', index, "-#{key}", val) + end + end + self + end + + def itemconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', index))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(index, fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', index))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(index, fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_itemconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = itemconfiginfo(index, key) + {conf[0] => conf[4]} + else + ret = {} + itemconfiginfo(index).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + itemconfiginfo(index, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +=end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/macpkg.rb b/ruby_1_8_6/ext/tk/lib/tk/macpkg.rb new file mode 100644 index 0000000000..1802073f46 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/macpkg.rb @@ -0,0 +1,73 @@ +# +# tk/macpkg.rb : methods for Tcl/Tk packages for Macintosh +# 2000/11/22 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +# ATTENTION !! +# This is NOT TESTED. Because I have no test-environment. +# +# +require 'tk' + +module Tk + def Tk.load_tclscript_rsrc(resource_name, file=None) + # Mac only + tk_call('source', '-rsrc', resource_name, file) + end + + def Tk.load_tclscript_rsrcid(resource_id, file=None) + # Mac only + tk_call('source', '-rsrcid', resource_id, file) + end +end + +module TkMacResource + extend Tk + extend TkMacResource + + TkCommandNames = ['resource'.freeze].freeze + + PACKAGE_NAME = 'resource'.freeze + def self.package_name + PACKAGE_NAME + end + + tk_call_without_enc('package', 'require', 'resource') + + def close(rsrcRef) + tk_call('resource', 'close', rsrcRef) + end + + def delete(rsrcType, opts=nil) + tk_call('resource', 'delete', *(hash_kv(opts) << rsrcType)) + end + + def files(rsrcRef=nil) + if rsrcRef + tk_call('resource', 'files', rsrcRef) + else + tk_split_simplelist(tk_call('resource', 'files')) + end + end + + def list(rsrcType, rsrcRef=nil) + tk_split_simplelist(tk_call('resource', 'list', rsrcType, rsrcRef)) + end + + def open(fname, access=nil) + tk_call('resource', 'open', fname, access) + end + + def read(rsrcType, rsrcID, rsrcRef=nil) + tk_call('resource', 'read', rsrcType, rsrcID, rsrcRef) + end + + def types(rsrcRef=nil) + tk_split_simplelist(tk_call('resource', 'types', rsrcRef)) + end + + def write(rsrcType, data, opts=nil) + tk_call('resource', 'write', *(hash_kv(opts) << rsrcType << data)) + end + + module_function :close, :delete, :files, :list, :open, :read, :types, :write +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/menu.rb b/ruby_1_8_6/ext/tk/lib/tk/menu.rb new file mode 100644 index 0000000000..ddddc8e53e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/menu.rb @@ -0,0 +1,632 @@ +# +# tk/menu.rb : treat menu and menubutton +# +require 'tk' +require 'tk/itemconfig' +require 'tk/menuspec' + +module TkMenuEntryConfig + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'entrycget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'entryconfigure', id] + end + private :__item_config_cmd + + def __item_strval_optkeys(id) + super(id) << 'selectcolor' + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys + + def __item_val2ruby_optkeys(id) # { key=>proc, ... } + super(id).update('menu'=>proc{|i, v| window(v)}) + end + private :__item_val2ruby_optkeys + + alias entrycget itemcget + alias entryconfigure itemconfigure + alias entryconfiginfo itemconfiginfo + alias current_entryconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +class TkMenu<TkWindow + include Wm + include TkMenuEntryConfig + extend TkMenuSpec + + TkCommandNames = ['menu'.freeze].freeze + WidgetClassName = 'Menu'.freeze + WidgetClassNames[WidgetClassName] = self + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('menu', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('menu', @path) + # end + #end + #private :create_self + + def __strval_optkeys + super() << 'selectcolor' << 'title' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'tearoff' + end + private :__boolval_optkeys + + def self.new_menuspec(menu_spec, parent = nil, tearoff = false, keys = nil) + if parent.kind_of?(Hash) + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + tearoff = keys.delete('tearoff') + elsif tearoff.kind_of?(Hash) + keys = _symbolkey2str(tearoff) + tearoff = keys.delete('tearoff') + elsif keys + keys = _symbolkey2str(keys) + else + keys = {} + end + + widgetname = keys.delete('widgetname') + _create_menu(parent, menu_spec, widgetname, tearoff, keys) + end + + def tagid(id) + #id.to_s + _get_eval_string(id) + end + + def activate(index) + tk_send_without_enc('activate', _get_eval_enc_str(index)) + self + end + def add(type, keys=nil) + tk_send_without_enc('add', type, *hash_kv(keys, true)) + self + end + def add_cascade(keys=nil) + add('cascade', keys) + end + def add_checkbutton(keys=nil) + add('checkbutton', keys) + end + def add_command(keys=nil) + add('command', keys) + end + def add_radiobutton(keys=nil) + add('radiobutton', keys) + end + def add_separator(keys=nil) + add('separator', keys) + end + + def clone_menu(*args) + if args[0].kind_of?(TkWindow) + parent = args.shift + else + parent = self + end + + if args[0].kind_of?(String) || args[0].kind_of?(Symbol) # menu type + type = args.shift + else + type = None # 'normal' + end + + if args[0].kind_of?(Hash) + keys = _symbolkey2str(args.shift) + else + keys = {} + end + + parent = keys.delete('parent') if keys.has_key?('parent') + type = keys.delete('type') if keys.has_key?('type') + + if keys.empty? + TkMenuClone.new(self, parent, type) + else + TkMenuClone.new(self, parent, type, keys) + end + end + + def index(idx) + ret = tk_send_without_enc('index', _get_eval_enc_str(idx)) + (ret == 'none')? nil: number(ret) + end + def invoke(index) + _fromUTF8(tk_send_without_enc('invoke', _get_eval_enc_str(index))) + end + def insert(index, type, keys=nil) + tk_send_without_enc('insert', _get_eval_enc_str(index), + type, *hash_kv(keys, true)) + self + end + def delete(first, last=nil) + if last + tk_send_without_enc('delete', _get_eval_enc_str(first), + _get_eval_enc_str(last)) + else + tk_send_without_enc('delete', _get_eval_enc_str(first)) + end + self + end + def popup(x, y, index=nil) + if index + tk_call_without_enc('tk_popup', path, x, y, + _get_eval_enc_str(index)) + else + tk_call_without_enc('tk_popup', path, x, y) + end + self + end + def post(x, y) + _fromUTF8(tk_send_without_enc('post', x, y)) + end + def postcascade(index) + tk_send_without_enc('postcascade', _get_eval_enc_str(index)) + self + end + def postcommand(cmd=Proc.new) + configure_cmd 'postcommand', cmd + self + end + def set_focus + tk_call_without_enc('tk_menuSetFocus', path) + self + end + def tearoffcommand(cmd=Proc.new) + configure_cmd 'tearoffcommand', cmd + self + end + def menutype(index) + tk_send_without_enc('type', _get_eval_enc_str(index)) + end + def unpost + tk_send_without_enc('unpost') + self + end + def yposition(index) + number(tk_send_without_enc('yposition', _get_eval_enc_str(index))) + end + +=begin + def entrycget(index, key) + case key.to_s + when 'text', 'label', 'show' + _fromUTF8(tk_send_without_enc('entrycget', + _get_eval_enc_str(index), "-#{key}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('entrycget', index, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('entrycget', _get_eval_enc_str(index), '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(index, fnt) + end + if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('entrycget', _get_eval_enc_str(index), "-#{key}"))) + end + end + def entryconfigure(index, key, val=None) + if key.kind_of? Hash + if (key['font'] || key[:font] || + key['kanjifont'] || key[:kanjifont] || + key['latinfont'] || key[:latinfont] || + key['asciifont'] || key[:asciifont]) + tagfont_configure(index, _symbolkey2str(key)) + else + tk_send_without_enc('entryconfigure', _get_eval_enc_str(index), + *hash_kv(key, true)) + end + + else + if (key == 'font' || key == :font || + key == 'kanjifont' || key == :kanjifont || + key == 'latinfont' || key == :latinfont || + key == 'asciifont' || key == :asciifont ) + if val == None + tagfontobj(index) + else + tagfont_configure(index, {key=>val}) + end + else + tk_call('entryconfigure', index, "-#{key}", val) + end + end + self + end + + def entryconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(index, fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(index, fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_entryconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = entryconfiginfo(index, key) + {conf[0] => conf[4]} + else + ret = {} + entryconfiginfo(index).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + entryconfiginfo(index, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +=end +end + + +class TkMenuClone<TkMenu +=begin + def initialize(parent, type=None) + widgetname = nil + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + widgetname = keys.delete('widgetname') + type = keys.delete('type'); type = None unless type + end + #unless parent.kind_of?(TkMenu) + # fail ArgumentError, "parent must be TkMenu" + #end + @parent = parent + install_win(@parent.path, widgetname) + tk_call_without_enc(@parent.path, 'clone', @path, type) + end +=end + def initialize(src_menu, *args) + widgetname = nil + + if args[0].kind_of?(TkWindow) # parent window + parent = args.shift + else + parent = src_menu + end + + if args[0].kind_of?(String) || args[0].kind_of?(Symbol) # menu type + type = args.shift + else + type = None # 'normal' + end + + if args[0].kind_of?(Hash) + keys = _symbolkey2str(args.shift) + parent = keys.delete('parent') if keys.has_key?('parent') + widgetname = keys.delete('widgetname') + type = keys.delete('type') if keys.has_key?('type') + else + keys = nil + end + + @src_menu = src_menu + @parent = parent + @type = type + install_win(@parent.path, widgetname) + tk_call_without_enc(@src_menu.path, 'clone', @path, @type) + configure(keys) if keys && !keys.empty? + end + + def source_menu + @src_menu + end +end +TkCloneMenu = TkMenuClone + +module TkSystemMenu + def initialize(parent, keys=nil) + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + end + #unless parent.kind_of? TkMenu + # fail ArgumentError, "parent must be a TkMenu object" + #end + # @path = Kernel.format("%s.%s", parent.path, self.class::SYSMENU_NAME) + @path = parent.path + '.' + self.class::SYSMENU_NAME + #TkComm::Tk_WINDOWS[@path] = self + TkCore::INTERP.tk_windows[@path] = self + if self.method(:create_self).arity == 0 + p 'create_self has no arg' if $DEBUG + create_self + configure(keys) if keys + else + p 'create_self has an arg' if $DEBUG + create_self(keys) + end + end +end + + +class TkSysMenu_Help<TkMenu + # for all platform + include TkSystemMenu + SYSMENU_NAME = 'help' +end + + +class TkSysMenu_System<TkMenu + # for Windows + include TkSystemMenu + SYSMENU_NAME = 'system' +end + + +class TkSysMenu_Apple<TkMenu + # for Machintosh + include TkSystemMenu + SYSMENU_NAME = 'apple' +end + + +class TkMenubutton<TkLabel + TkCommandNames = ['menubutton'.freeze].freeze + WidgetClassName = 'Menubutton'.freeze + WidgetClassNames[WidgetClassName] = self + def create_self(keys) + if keys and keys != None + # tk_call_without_enc('menubutton', @path, *hash_kv(keys, true)) + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + # tk_call_without_enc('menubutton', @path) + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def __boolval_optkeys + super() << 'indicatoron' + end + private :__boolval_optkeys + +end +TkMenuButton = TkMenubutton + + +class TkOptionMenubutton<TkMenubutton + TkCommandNames = ['tk_optionMenu'.freeze].freeze + + class OptionMenu<TkMenu + def initialize(path) #==> return value of tk_optionMenu + @path = path + #TkComm::Tk_WINDOWS[@path] = self + TkCore::INTERP.tk_windows[@path] = self + end + end + + def initialize(*args) + # args :: [parent,] [var,] [value[, ...],] [keys] + # parent --> TkWindow or nil + # var --> TkVariable or nil + # keys --> Hash + # keys[:parent] or keys['parent'] --> parent + # keys[:variable] or keys['variable'] --> var + # keys[:values] or keys['values'] --> value, ... + # other Hash keys are menubutton options + keys = {} + keys = args.pop if args[-1].kind_of?(Hash) + keys = _symbolkey2str(keys) + + parent = nil + if args[0].kind_of?(TkWindow) || args[0] == nil + keys.delete('parent') # ignore + parent = args.shift + else + parent = keys.delete('parent') + end + + @variable = nil + if args[0].kind_of?(TkVariable) || args[0] == nil + keys.delete('variable') # ignore + @variable = args.shift + else + @variable = keys.delete('variable') + end + @variable = TkVariable.new unless @variable + + (args = keys.delete('values') || []) if args.empty? + if args.empty? + args << @variable.value + else + @variable.value = args[0] + end + + install_win(if parent then parent.path end) + @menu = OptionMenu.new(tk_call('tk_optionMenu', + @path, @variable.id, *args)) + + configure(keys) if keys + end + + def value + @variable.value + end + + def value=(val) + @variable.value = val + end + + def activate(index) + @menu.activate(index) + self + end + def add(value) + @menu.add('radiobutton', 'variable'=>@variable, + 'label'=>value, 'value'=>value) + self + end + def index(index) + @menu.index(index) + end + def invoke(index) + @menu.invoke(index) + end + def insert(index, value) + @menu.insert(index, 'radiobutton', 'variable'=>@variable, + 'label'=>value, 'value'=>value) + self + end + def delete(index, last=None) + @menu.delete(index, last) + self + end + def yposition(index) + @menu.yposition(index) + end + def menu + @menu + end + def menucget(key) + @menu.cget(key) + end + def menuconfigure(key, val=None) + @menu.configure(key, val) + self + end + def menuconfiginfo(key=nil) + @menu.configinfo(key) + end + def current_menuconfiginfo(key=nil) + @menu.current_configinfo(key) + end + def entrycget(index, key) + @menu.entrycget(index, key) + end + def entryconfigure(index, key, val=None) + @menu.entryconfigure(index, key, val) + self + end + def entryconfiginfo(index, key=nil) + @menu.entryconfiginfo(index, key) + end + def current_entryconfiginfo(index, key=nil) + @menu.current_entryconfiginfo(index, key) + end +end +TkOptionMenuButton = TkOptionMenubutton diff --git a/ruby_1_8_6/ext/tk/lib/tk/menubar.rb b/ruby_1_8_6/ext/tk/lib/tk/menubar.rb new file mode 100644 index 0000000000..392b6fbd4e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/menubar.rb @@ -0,0 +1,131 @@ +# +# tk/menubar.rb +# +# Original version: +# Copyright (C) 1998 maeda shugo. All rights reserved. +# This file can be distributed under the terms of the Ruby. + +# Usage: +# +# menu_spec = [ +# [['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]], +# [['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]] +# ] +# menubar = TkMenubar.new(nil, menu_spec, +# 'tearoff'=>false, +# 'foreground'=>'grey40', +# 'activeforeground'=>'red', +# 'font'=>'-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') +# +# +# OR +# +# +# menubar = TkMenubar.new +# menubar.add_menu([['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]]) +# menubar.add_menu([['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]]) +# menubar.configure('tearoff', false) +# menubar.configure('foreground', 'grey40') +# menubar.configure('activeforeground', 'red') +# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') +# +# +# OR +# +# radio_var = TkVariable.new('y') +# menu_spec = [ +# [['File', 0], +# {:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0}, +# '---', +# ['Check_A', TkVariable.new(true), 6], +# {:type=>'checkbutton', :label=>'Check_B', +# :variable=>TkVariable.new, :underline=>6}, +# '---', +# ['Radio_X', [radio_var, 'x'], 6], +# ['Radio_Y', [radio_var, 'y'], 6], +# ['Radio_Z', [radio_var, 'z'], 6], +# '---', +# ['cascade', [ +# ['sss', proc{p 'sss'}, 0], +# ['ttt', proc{p 'ttt'}, 0], +# ['uuu', proc{p 'uuu'}, 0], +# ['vvv', proc{p 'vvv'}, 0], +# ], 0], +# '---', +# ['Quit', proc{exit}, 0]], +# [['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]] +# ] +# menubar = TkMenubar.new(nil, menu_spec, +# 'tearoff'=>false, +# 'foreground'=>'grey40', +# 'activeforeground'=>'red', +# 'font'=>'Helvetia 12 bold') +# menubar.pack('side'=>'top', 'fill'=>'x') + +# See tk/menuspce.rb about the format of the menu_spec + +# To use add_menu, configuration must be done by calling configure after +# adding all menus by add_menu, not by the constructor arguments. + +require 'tk' +require 'tk/frame' +require 'tk/composite' +require 'tk/menuspec' + +class TkMenubar<TkFrame + include TkComposite + include TkMenuSpec + + def initialize(parent = nil, spec = nil, options = nil) + if parent.kind_of? Hash + options = _symbolkey2str(parent) + spec = options.delete('spec') + super(options) + else + super(parent, options) + end + + @menus = [] + + spec.each{|info| add_menu(info)} if spec + + options.each{|key, value| configure(key, value)} if options + end + + def add_menu(menu_info) + mbtn, menu = _create_menubutton(@frame, menu_info) + + submenus = _get_cascade_menus(menu).flatten + + @menus.push([mbtn, menu]) + delegate('tearoff', menu, *submenus) + delegate('foreground', mbtn, menu, *submenus) + delegate('background', mbtn, menu, *submenus) + delegate('disabledforeground', mbtn, menu, *submenus) + delegate('activeforeground', mbtn, menu, *submenus) + delegate('activebackground', mbtn, menu, *submenus) + delegate('font', mbtn, menu, *submenus) + delegate('kanjifont', mbtn, menu, *submenus) + end + + def [](index) + return @menus[index] + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/menuspec.rb b/ruby_1_8_6/ext/tk/lib/tk/menuspec.rb new file mode 100644 index 0000000000..118a4f42b1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/menuspec.rb @@ -0,0 +1,269 @@ +# +# tk/menuspec.rb +# Hidethoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# based on tkmenubar.rb : +# Copyright (C) 1998 maeda shugo. All rights reserved. +# This file can be distributed under the terms of the Ruby. +# +# The format of the menu_spec is: +# [ menu_info, menu_info, ... ] +# +# And the format of the menu_info is: +# [ +# [text, underline, configs], # menu button/entry (*1) +# [label, command, underline, accelerator, configs], # command entry +# [label, TkVar_obj, underline, accelerator, configs], # checkbutton entry +# [label, [TkVar_obj, value], +# underline, accelerator, configs], # radiobutton entry +# [label, [[...menu_info...], [...menu_info...], ...], +# underline, accelerator, configs], # cascade entry (*2) +# '---', # separator +# ... +# ] +# +# underline, accelerator, and configs are optional pearameters. +# Hashes are OK instead of Arrays. Then the entry type ('command', +# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key +# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info +# is acceptable for 'menu' key (then, create sub-menu). +# +# NOTE: (*1) +# If you want to make special menus (*.help for UNIX, *.system for Win, +# and *.apple for Mac), append 'menu_name'=>name (name is 'help' for UNIX, +# 'system' for Win, and 'apple' for Mac) option to the configs hash of +# menu button/entry information. +# +# NOTE: (*2) +# If you want to configure a cascade menu, add :menu_config=>{...configs..} +# to the configs of the cascade entry. + +module TkMenuSpec + def _create_menu(parent, menu_info, menu_name = nil, + tearoff = false, default_opts = nil) + if tearoff.kind_of?(Hash) + default_opts = tearoff + tearoff = false + end + + if menu_name.kind_of?(Hash) + default_opts = menu_name + menu_name = nil + tearoff = false + end + + if default_opts.kind_of?(Hash) + orig_opts = _symbolkey2str(default_opts) + else + orig_opts = {} + end + + tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff') + + if menu_name + menu = TkMenu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff) + else + menu = TkMenu.new(parent, :tearoff=>tearoff) + end + + for item_info in menu_info + if item_info.kind_of?(Hash) + options = orig_opts.dup + options.update(_symbolkey2str(item_info)) + item_type = (options.delete('type') || 'command').to_s + menu_name = options.delete('menu_name') + menu_opts = orig_opts.dup + menu_opts.update(_symbolkey2str(options.delete('menu_config') || {})) + if item_type == 'cascade' && options['menu'].kind_of?(Array) + # create cascade menu + submenu = _create_menu(menu, options['menu'], menu_name, + tearoff, menu_opts) + options['menu'] = submenu + end + menu.add(item_type, options) + + elsif item_info.kind_of?(Array) + options = orig_opts.dup + + options['label'] = item_info[0] if item_info[0] + + case item_info[1] + when TkVariable + # checkbutton + item_type = 'checkbutton' + options['variable'] = item_info[1] + options['onvalue'] = true + options['offvalue'] = false + + when Array + # radiobutton or cascade + if item_info[1][0].kind_of?(TkVariable) + # radiobutton + item_type = 'radiobutton' + options['variable'] = item_info[1][0] + options['value'] = item_info[1][1] if item_info[1][1] + + else + # cascade + item_type = 'cascade' + menu_opts = orig_opts.dup + if item_info[4] && item_info[4].kind_of?(Hash) + opts = _symbolkey2str(item_info[4]) + menu_name = opts.delete('menu_name') + menu_config = opts.delete('menu_config') || {} + menu_opts.update(_symbolkey2str(menu_config)) + end + submenu = _create_menu(menu, item_info[1], menu_name, + tearoff, menu_opts) + options['menu'] = submenu + end + + else + # command + item_type = 'command' + options['command'] = item_info[1] if item_info[1] + end + + options['underline'] = item_info[2] if item_info[2] + options['accelerator'] = item_info[3] if item_info[3] + if item_info[4] && item_info[4].kind_of?(Hash) + opts = _symbolkey2str(item_info[4]) + if item_type == 'cascade' + opts.delete('menu_name') + opts.delete('menu_config') + end + options.update(opts) + end + menu.add(item_type, options) + + elsif /^-+$/ =~ item_info + menu.add('separator') + + else + menu.add('command', 'label' => item_info) + end + end + + menu + end + private :_create_menu + + def _use_menubar?(parent) + use_menubar = false + if parent.kind_of?(TkRoot) || parent.kind_of?(TkToplevel) + return true + else + begin + parent.cget('menu') + return true + rescue + end + end + false + end + private :_use_menubar? + + def _create_menu_for_menubar(parent) + unless (mbar = parent.menu).kind_of?(TkMenu) + mbar = TkMenu.new(parent, :tearoff=>false) + parent.menu(mbar) + end + mbar + end + private :_create_menu_for_menubar + + def _create_menubutton(parent, menu_info, tearoff=false, default_opts = nil) + btn_info = menu_info[0] + + if tearoff.kind_of?(Hash) + default_opts = tearoff + tearoff = false + end + + if default_opts.kind_of?(Hash) + keys = _symbolkey2str(default_opts) + else + keys = {} + end + + tearoff = keys.delete('tearoff') if keys.key?('tearoff') + + if _use_menubar?(parent) + # menubar by menu entries + + mbar = _create_menu_for_menubar(parent) + + menu_name = nil + + if btn_info.kind_of?(Hash) + keys.update(_symbolkey2str(btn_info)) + menu_name = keys.delete('menu_name') + keys['label'] = keys.delete('text') if keys.key?('text') + elsif btn_info.kind_of?(Array) + keys['label'] = btn_info[0] if btn_info[0] + keys['underline'] = btn_info[1] if btn_info[1] + if btn_info[2]&&btn_info[2].kind_of?(Hash) + keys.update(_symbolkey2str(btn_info[2])) + menu_name = keys.delete('menu_name') + end + else + keys = {:label=>btn_info} + end + + menu = _create_menu(mbar, menu_info[1..-1], menu_name, + tearoff, default_opts) + menu.tearoff(tearoff) + + keys['menu'] = menu + mbar.add('cascade', keys) + + [mbar, menu] + + else + # menubar by menubuttons + mbtn = TkMenubutton.new(parent) + + menu_name = nil + + if btn_info.kind_of?(Hash) + keys.update(_symbolkey2str(btn_info)) + menu_name = keys.delete('menu_name') + keys['text'] = keys.delete('label') if keys.key?('label') + mbtn.configure(keys) + elsif btn_info.kind_of?(Array) + mbtn.configure('text', btn_info[0]) if btn_info[0] + mbtn.configure('underline', btn_info[1]) if btn_info[1] + # mbtn.configure('accelerator', btn_info[2]) if btn_info[2] + if btn_info[2]&&btn_info[2].kind_of?(Hash) + keys.update(_symbolkey2str(btn_info[2])) + menu_name = keys.delete('menu_name') + mbtn.configure(keys) + end + else + mbtn.configure('text', btn_info) + end + + mbtn.pack('side' => 'left') + + menu = _create_menu(mbtn, menu_info[1..-1], menu_name, + tearoff, default_opts) + + mbtn.menu(menu) + + [mbtn, menu] + end + end + private :_create_menubutton + + def _get_cascade_menus(menu) + menus = [] + (0..(menu.index('last'))).each{|idx| + if menu.menutype(idx) == 'cascade' + submenu = menu.entrycget(idx, 'menu') + menus << [submenu, _get_cascade_menus(submenu)] + end + } + menus + end + private :_get_cascade_menus +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/message.rb b/ruby_1_8_6/ext/tk/lib/tk/message.rb new file mode 100644 index 0000000000..79121bebb3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/message.rb @@ -0,0 +1,19 @@ +# +# tk/message.rb : treat message widget +# +require 'tk' +require 'tk/label' + +class TkMessage<TkLabel + TkCommandNames = ['message'.freeze].freeze + WidgetClassName = 'Message'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('message', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('message', @path) + # end + #end + private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/mngfocus.rb b/ruby_1_8_6/ext/tk/lib/tk/mngfocus.rb new file mode 100644 index 0000000000..1a2049c8a8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/mngfocus.rb @@ -0,0 +1,33 @@ +# +# tk/mngfocus.rb : methods for Tcl/Tk standard library 'focus.tcl' +# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +require 'tk' + +module TkManageFocus + extend Tk + + TkCommandNames = [ + 'tk_focusFollowMouse'.freeze, + 'tk_focusNext'.freeze, + 'tk_focusPrev'.freeze + ].freeze + + def TkManageFocus.followsMouse + tk_call_without_enc('tk_focusFollowsMouse') + end + + def TkManageFocus.next(win) + tk_tcl2ruby(tk_call('tk_focusNext', win)) + end + def focusNext + TkManageFocus.next(self) + end + + def TkManageFocus.prev(win) + tk_tcl2ruby(tk_call('tk_focusPrev', win)) + end + def focusPrev + TkManageFocus.prev(self) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/msgcat.rb b/ruby_1_8_6/ext/tk/lib/tk/msgcat.rb new file mode 100644 index 0000000000..061e43fd89 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/msgcat.rb @@ -0,0 +1,292 @@ +# +# tk/msgcat.rb : methods for Tcl message catalog +# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +require 'tk' + +#class TkMsgCatalog +class TkMsgCatalog < TkObject + include TkCore + extend Tk + #extend TkMsgCatalog + + TkCommandNames = [ + '::msgcat::mc'.freeze, + '::msgcat::mcmax'.freeze, + '::msgcat::mclocale'.freeze, + '::msgcat::mcpreferences'.freeze, + '::msgcat::mcload'.freeze, + '::msgcat::mcset'.freeze, + '::msgcat::mcmset'.freeze, + '::msgcat::mcunknown'.freeze + ].freeze + + tk_call_without_enc('package', 'require', 'Tcl', '8.2') + + PACKAGE_NAME = 'msgcat'.freeze + def self.package_name + PACKAGE_NAME + end + + if self.const_defined? :FORCE_VERSION + tk_call_without_enc('package', 'require', 'msgcat', FORCE_VERSION) + else + tk_call_without_enc('package', 'require', 'msgcat') + end + + MSGCAT_EXT = '.msg' + + UNKNOWN_CBTBL = Hash.new{|hash,key| hash[key] = {}}.taint + + TkCore::INTERP.add_tk_procs('::msgcat::mcunknown', 'args', <<-'EOL') + if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} { + #return -code $st $ret + set idx [string first "\n\n" $ret] + if {$idx > 0} { + return -code $st \ + -errorinfo [string range $ret [expr $idx + 2] \ + [string length $ret]] \ + [string range $ret 0 [expr $idx - 1]] + } else { + return -code $st $ret + } + } else { + return $ret + } + EOL + + def self.callback(namespace, locale, src_str, *args) + src_str = sprintf(src_str, *args) unless args.empty? + cmd_tbl = TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip] + cmd = cmd_tbl[namespace] + cmd = cmd_tbl['::'] unless cmd # use global scope as interp default + return src_str unless cmd # no cmd -> return src-str (default action) + begin + cmd.call(locale, src_str) + rescue SystemExit + exit(0) + rescue Interrupt + exit!(1) + rescue Exception => e + begin + msg = _toUTF8(e.class.inspect) + ': ' + + _toUTF8(e.message) + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + _toUTF8(e.backtrace.join("\n")) + + "\n---< backtrace of Tk side >-------" + msg.instance_variable_set(:@encoding, 'utf-8') + rescue Exception + msg = e.class.inspect + ': ' + e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------" + end + fail(e, msg) + end + end + + def initialize(namespace = nil) + if namespace.kind_of?(TkNamespace) + @namespace = namespace + elsif namespace == nil + @namespace = TkNamespace.new('::') # global namespace + else + @namespace = TkNamespace.new(namespace) + end + @path = @namespace.path + + @msgcat_ext = '.msg' + end + attr_accessor :msgcat_ext + + def method_missing(id, *args) + # locale(src, trans) ==> set_translation(locale, src, trans) + loc = id.id2name + case args.length + when 0 # set locale + self.locale=(loc) + + when 1 # src only, or trans_list + if args[0].kind_of?(Array) + # trans_list + #list = args[0].collect{|src, trans| + # [ Tk::UTF8_String.new(src), Tk::UTF8_String.new(trans) ] + #} + self.set_translation_list(loc, args[0]) + else + # src + #self.set_translation(loc, Tk::UTF8_String.new(args[0])) + self.set_translation(loc, args[0]) + end + + when 2 # src and trans, or, trans_list and enc + if args[0].kind_of?(Array) + else + #self.set_translation(loc, args[0], Tk::UTF8_String.new(args[1])) + self.set_translation(loc, *args) + end + + when 3 # src and trans and enc + self.set_translation(loc, *args) + + else + super(id, *args) +# fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at + + end + end + + # *args ::= form, arg, arg, ... + def self.translate(*args) + dst = args.collect{|src| + tk_call_without_enc('::msgcat::mc', _get_eval_string(src, true)) + } + Tk.UTF8_String(sprintf(*dst)) + end + class << self + alias mc translate + alias [] translate + end + def translate(*args) + dst = args.collect{|src| + @namespace.eval{tk_call_without_enc('::msgcat::mc', + _get_eval_string(src, true))} + } + Tk.UTF8_String(sprintf(*dst)) + end + alias mc translate + alias [] translate + + def self.maxlen(*src_strings) + tk_call('::msgcat::mcmax', *src_strings).to_i + end + def maxlen(*src_strings) + @namespace.eval{tk_call('::msgcat::mcmax', *src_strings).to_i} + end + + def self.locale + tk_call('::msgcat::mclocale') + end + def locale + @namespace.eval{tk_call('::msgcat::mclocale')} + end + + def self.locale=(locale) + tk_call('::msgcat::mclocale', locale) + end + def locale=(locale) + @namespace.eval{tk_call('::msgcat::mclocale', locale)} + end + + def self.preferences + tk_split_simplelist(tk_call('::msgcat::mcpreferences')) + end + def preferences + tk_split_simplelist(@namespace.eval{tk_call('::msgcat::mcpreferences')}) + end + + def self.load_tk(dir) + number(tk_call('::msgcat::mcload', dir)) + end + + def self.load_rb(dir) + count = 0 + preferences().each{|loc| + file = File.join(dir, loc + self::MSGCAT_EXT) + if File.readable?(file) + count += 1 + eval(open(file){|f| f.read}) + end + } + count + end + + def load_tk(dir) + number(@namespace.eval{tk_call('::msgcat::mcload', dir)}) + end + + def load_rb(dir) + count = 0 + preferences().each{|loc| + file = File.join(dir, loc + @msgcat_ext) + if File.readable?(file) + count += 1 + @namespace.eval(open(file){|f| f.read}) + end + } + count + end + + def self.load(dir) + self.load_rb(dir) + end + alias load load_rb + + def self.set_translation(locale, src_str, trans_str=None, enc='utf-8') + if trans_str && trans_str != None + trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc)) + Tk.UTF8_String(tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true), + trans_str)) + else + Tk.UTF8_String(tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true))) + end + end + def set_translation(locale, src_str, trans_str=None, enc='utf-8') + if trans_str && trans_str != None + trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc)) + Tk.UTF8_String(@namespace.eval{ + tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true), + trans_str) + }) + else + Tk.UTF8_String(@namespace.eval{ + tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true))}) + end + end + + def self.set_translation_list(locale, trans_list, enc='utf-8') + # trans_list ::= [ [src, trans], [src, trans], ... ] + list = [] + trans_list.each{|src, trans| + if trans && trans != None + list << _get_eval_string(src, true) + list << Tk.UTF8_Stirng(_toUTF8(trans, enc)) + else + list << _get_eval_string(src, true) << '' + end + } + number(tk_call_without_enc('::msgcat::mcmset', locale, list)) + end + def set_translation_list(locale, trans_list, enc='utf-8') + # trans_list ::= [ [src, trans], [src, trans], ... ] + list = [] + trans_list.each{|src, trans| + if trans && trans != None + list << _get_eval_string(src, true) + list << Tk.UTF8_String(_toUTF8(trans, enc)) + else + list << _get_eval_string(src, true) << '' + end + } + number(@namespace.eval{ + tk_call_without_enc('::msgcat::mcmset', locale, list) + }) + end + + def self.def_unknown_proc(cmd=Proc.new) + TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip]['::'] = cmd + end + def def_unknown_proc(cmd=Proc.new) + TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip][@namespace.path] = cmd + end +end + +TkMsgCat = TkMsgCatalog diff --git a/ruby_1_8_6/ext/tk/lib/tk/namespace.rb b/ruby_1_8_6/ext/tk/lib/tk/namespace.rb new file mode 100644 index 0000000000..5bf6474c5b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/namespace.rb @@ -0,0 +1,500 @@ +# +# tk/namespace.rb : methods to manipulate Tcl/Tk namespace +# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +require 'tk' + +class TkNamespace < TkObject + extend Tk + + TkCommandNames = [ + 'namespace'.freeze, + ].freeze + + Tk_Namespace_ID_TBL = TkCore::INTERP.create_table + Tk_Namespace_ID = ["ns".freeze, "00000".taint].freeze + + Tk_NsCode_RetObjID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ + Tk_Namespace_ID_TBL.clear + Tk_NsCode_RetObjID_TBL.clear + } + + def TkNamespace.id2obj(id) + Tk_Namespace_ID_TBL[id]? Tk_Namespace_ID_TBL[id]: id + end + + ##################################### + + class Ensemble < TkObject + def __cget_cmd + ['namespace', 'ensemble', 'configure', self.path] + end + private :__cget_cmd + + def __config_cmd + ['namespace', 'ensemble', 'configure', self.path] + end + private :__config_cmd + + def __configinfo_struct + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>nil, :current_value=>2} + end + private :__configinfo_struct + + def __boolval_optkeys + ['prefixes'] + end + private :__boolval_optkeys + + def __listval_optkeys + ['map', 'subcommands', 'unknown'] + end + private :__listval_optkeys + + def self.exist?(ensemble) + bool(tk_call('namespace', 'ensemble', 'exists', ensemble)) + end + + def initialize(keys = {}) + @ensemble = @path = tk_call('namespace', 'ensemble', 'create', keys) + end + + def cget(slot) + if slot == :namespace || slot == 'namespace' + ns = super(slot) + if TkNamespace::Tk_Namespace_ID_TBL.key?(ns) + TkNamespace::Tk_Namespace_ID_TBL[ns] + else + ns + end + else + super(slot) + end + end + + def configinfo(slot = nil) + if slot + if slot == :namespace || slot == 'namespace' + val = super(slot) + if TkNamespace::Tk_Namespace_ID_TBL.key?(val) + val = TkNamespace::Tk_Namespace_ID_TBL[val] + end + else + val = super(slot) + end + + if TkComm::GET_CONFIGINFO_AS_ARRAY + [slot.to_s, val] + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + {slot.to_s => val} + end + + else + info = super() + + if TkComm::GET_CONFIGINFO_AS_ARRAY + info.map!{|inf| + if inf[0] == 'namespace' && + TkNamespace::Tk_Namespace_ID_TBL.key?(inf[-1]) + [inf[0], TkNamespace::Tk_Namespace_ID_TBL[inf[-1]]] + else + inf + end + } + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + val = info['namespace'] + if TkNamespace::Tk_Namespace_ID_TBL.key?(val) + info['namespace'] = TkNamespace::Tk_Namespace_ID_TBL[val] + end + end + + info + end + end + + def exists? + bool(tk_call('namespace', 'ensemble', 'exists', @path)) + end + end + + ##################################### + + class ScopeArgs < Array + include Tk + + # alias __tk_call tk_call + # alias __tk_call_without_enc tk_call_without_enc + # alias __tk_call_with_enc tk_call_with_enc + def tk_call(*args) + #super('namespace', 'eval', @namespace, *args) + args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''} + super('namespace', 'eval', @namespace, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_without_enc(*args) + #super('namespace', 'eval', @namespace, *args) + args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''} + super('namespace', 'eval', @namespace, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_with_enc(*args) + #super('namespace', 'eval', @namespace, *args) + args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''} + super('namespace', 'eval', @namespace, + TkCore::INTERP._merge_tklist(*args)) + end + + def initialize(namespace, *args) + @namespace = namespace + super(args.size) + self.replace(args) + end + end + + ##################################### + + class NsCode < TkObject + def initialize(scope, use_obj_id = false) + @scope = scope + ' ' + @use_obj_id = use_obj_id + end + def path + @scope + end + def to_eval + @scope + end + def call(*args) + ret = TkCore::INTERP._eval_without_enc(@scope + array2tk_list(args)) + if @use_obj_id + ret = TkNamespace::Tk_NsCode_RetObjID_TBL.delete(ret.to_i) + end + ret + end + end + + ##################################### + + def install_cmd(cmd) + lst = tk_split_simplelist(super(cmd), false, false) + if lst[1] =~ /^::/ + lst[1] = @fullname + else + lst.insert(1, @fullname) + end + TkCore::INTERP._merge_tklist(*lst) + end + + alias __tk_call tk_call + alias __tk_call_without_enc tk_call_without_enc + alias __tk_call_with_enc tk_call_with_enc + def tk_call(*args) + #super('namespace', 'eval', @fullname, *args) + args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''} + super('namespace', 'eval', @fullname, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_without_enc(*args) + #super('namespace', 'eval', @fullname, *args) + args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''} + super('namespace', 'eval', @fullname, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_with_enc(*args) + #super('namespace', 'eval', @fullname, *args) + args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''} + super('namespace', 'eval', @fullname, + TkCore::INTERP._merge_tklist(*args)) + end + alias ns_tk_call tk_call + alias ns_tk_call_without_enc tk_call_without_enc + alias ns_tk_call_with_enc tk_call_with_enc + + def initialize(name = nil, parent = nil) + unless name + # name = Tk_Namespace_ID.join('') + name = Tk_Namespace_ID.join(TkCore::INTERP._ip_id_) + Tk_Namespace_ID[1].succ! + end + name = __tk_call('namespace', 'current') if name == '' + if parent + if parent =~ /^::/ + if name =~ /^::/ + @fullname = parent + name + else + @fullname = parent +'::'+ name + end + else + ancestor = __tk_call('namespace', 'current') + ancestor = '' if ancestor == '::' + if name =~ /^::/ + @fullname = ancestor + '::' + parent + name + else + @fullname = ancestor + '::'+ parent +'::'+ name + end + end + else # parent == nil + ancestor = __tk_call('namespace', 'current') + ancestor = '' if ancestor == '::' + if name =~ /^::/ + @fullname = name + else + @fullname = ancestor + '::' + name + end + end + @path = @fullname + @parent = __tk_call('namespace', 'qualifiers', @fullname) + @name = __tk_call('namespace', 'tail', @fullname) + + # create namespace + __tk_call('namespace', 'eval', @fullname, '') + + Tk_Namespace_ID_TBL[@fullname] = self + end + + def self.children(*args) + # args ::= [<namespace>] [<pattern>] + # <pattern> must be glob-style pattern + tk_split_simplelist(tk_call('namespace', 'children', *args)).collect{|ns| + # ns is fullname + if Tk_Namespace_ID_TBL.key?(ns) + Tk_Namespace_ID_TBL[ns] + else + ns + end + } + end + def children(pattern=None) + TkNamespace.children(@fullname, pattern) + end + + def self.code(script = Proc.new) + TkNamespace.new('').code(script) + end +=begin + def code(script = Proc.new) + if script.kind_of?(String) + cmd = proc{|*args| ScopeArgs.new(@fullname,*args).instance_eval(script)} + elsif script.kind_of?(Proc) + cmd = proc{|*args| ScopeArgs.new(@fullname,*args).instance_eval(&script)} + else + fail ArgumentError, "String or Proc is expected" + end + TkNamespace::NsCode.new(tk_call_without_enc('namespace', 'code', + _get_eval_string(cmd, false))) + end +=end + def code(script = Proc.new) + if script.kind_of?(String) + cmd = proc{|*args| + ret = ScopeArgs.new(@fullname,*args).instance_eval(script) + id = ret.object_id + TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret + id + } + elsif script.kind_of?(Proc) + cmd = proc{|*args| + ret = ScopeArgs.new(@fullname,*args).instance_eval(&script) + id = ret.object_id + TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret + id + } + else + fail ArgumentError, "String or Proc is expected" + end + TkNamespace::NsCode.new(tk_call_without_enc('namespace', 'code', + _get_eval_string(cmd, false)), + true) + end + + def self.current_path + tk_call('namespace', 'current') + end + def current_path + @fullname + end + + def self.current + ns = self.current_path + if Tk_Namespace_ID_TBL.key?(ns) + Tk_Namespace_ID_TBL[ns] + else + ns + end + end + def current_namespace + # ns_tk_call('namespace', 'current') + # @fullname + self + end + alias current current_namespace + + def self.delete(*ns_list) + tk_call('namespace', 'delete', *ns_list) + ns_list.each{|ns| + if ns.kind_of?(TkNamespace) + Tk_Namespace_ID_TBL.delete(ns.path) + else + Tk_Namespace_ID_TBL.delete(ns.to_s) + end + } + end + def delete + TkNamespece.delete(@fullname) + end + + def self.ensemble_create(*keys) + tk_call('namespace', 'ensemble', 'create', *hash_kv(keys)) + end + def self.ensemble_configure(cmd, slot, value=None) + if slot.kind_of?(Hash) + tk_call('namespace', 'ensemble', 'configure', cmd, *hash_kv(slot)) + else + tk_call('namespace', 'ensemble', 'configure', cmd, '-'+slot.to_s, value) + end + end + def self.ensemble_configinfo(cmd, slot = nil) + if slot + tk_call('namespace', 'ensemble', 'configure', cmd, '-' + slot.to_s) + else + inf = {} + Hash(*tk_split_simplelist(tk_call('namespace', 'ensemble', 'configure', cmd))).each{|k, v| inf[k[1..-1]] = v} + inf + end + end + def self.ensemble_exist?(cmd) + bool(tk_call('namespace', 'ensemble', 'exists', cmd)) + end + + def self.eval(namespace, cmd = Proc.new, *args) + #tk_call('namespace', 'eval', namespace, cmd, *args) + TkNamespace.new(namespece).eval(cmd, *args) + end +=begin + def eval(cmd = Proc.new, *args) + #TkNamespace.eval(@fullname, cmd, *args) + #ns_tk_call(cmd, *args) + code_obj = code(cmd) + ret = code_obj.call(*args) + # uninstall_cmd(TkCore::INTERP._split_tklist(code_obj.path)[-1]) + uninstall_cmd(_fromUTF8(TkCore::INTERP._split_tklist(_toUTF8(code_obj.path))[-1])) + tk_tcl2ruby(ret) + end +=end + def eval(cmd = Proc.new, *args) + code_obj = code(cmd) + ret = code_obj.call(*args) + uninstall_cmd(_fromUTF8(TkCore::INTERP._split_tklist(_toUTF8(code_obj.path))[-1])) + ret + end + + def self.exist?(ns) + bool(tk_call('namespace', 'exists', ns)) + end + def exist? + TkNamespece.exist?(@fullname) + end + + def self.export(*patterns) + tk_call('namespace', 'export', *patterns) + end + def self.export_with_clear(*patterns) + tk_call('namespace', 'export', '-clear', *patterns) + end + def export + TkNamespace.export(@fullname) + end + def export_with_clear + TkNamespace.export_with_clear(@fullname) + end + + def self.forget(*patterns) + tk_call('namespace', 'forget', *patterns) + end + def forget + TkNamespace.forget(@fullname) + end + + def self.import(*patterns) + tk_call('namespace', 'import', *patterns) + end + def self.force_import(*patterns) + tk_call('namespace', 'import', '-force', *patterns) + end + def import + TkNamespace.import(@fullname) + end + def force_import + TkNamespace.force_import(@fullname) + end + + def self.inscope(namespace, script, *args) + tk_call('namespace', 'inscope', namespace, script, *args) + end + def inscope(script, *args) + TkNamespace.inscope(@fullname, script, *args) + end + + def self.origin(cmd) + tk_call('namespace', 'origin', cmd) + end + + def self.parent(namespace=None) + ns = tk_call('namespace', 'parent', namespace) + if Tk_Namespace_ID_TBL.key?(ns) + Tk_Namespace_ID_TBL[ns] + else + ns + end + end + def parent + tk_call('namespace', 'parent', @fullname) + end + + def self.get_path + tk_call('namespace', 'path') + end + def self.set_path(*namespace_list) + tk_call('namespace', 'path', array2tk_list(namespace_list)) + end + def set_path + tk_call('namespace', 'path', @fullname) + end + + def self.qualifiers(str) + tk_call('namespace', 'qualifiers', str) + end + + def self.tail(str) + tk_call('namespace', 'tail', str) + end + + def self.upvar(namespace, *var_pairs) + tk_call('namespace', 'upvar', namespace, *(var_pairs.flatten)) + end + def upvar(*var_pairs) + TkNamespace.inscope(@fullname, *(var_pairs.flatten)) + end + + def self.get_unknown_handler + tk_tcl2ruby(tk_call('namespace', 'unknown')) + end + def self.set_unknown_handler(cmd = Proc.new) + tk_call('namespace', 'unknown', cmd) + end + + def self.which(name) + tk_call('namespace', 'which', name) + end + def self.which_command(name) + tk_call('namespace', 'which', '-command', name) + end + def self.which_variable(name) + tk_call('namespace', 'which', '-variable', name) + end +end + +TkNamespace::Global = TkNamespace.new('::') diff --git a/ruby_1_8_6/ext/tk/lib/tk/optiondb.rb b/ruby_1_8_6/ext/tk/lib/tk/optiondb.rb new file mode 100644 index 0000000000..a806f3971d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/optiondb.rb @@ -0,0 +1,371 @@ +# +# tk/optiondb.rb : treat option database +# +require 'tk' + +module TkOptionDB + include Tk + extend Tk + + TkCommandNames = ['option'.freeze].freeze + CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint].freeze + + module Priority + WidgetDefault = 20 + StartupFile = 40 + UserDefault = 60 + Interactive = 80 + end + + def add(pat, value, pri=None) + # if $SAFE >= 4 + # fail SecurityError, "can't call 'TkOptionDB.add' at $SAFE >= 4" + # end + tk_call('option', 'add', pat, value, pri) + end + def clear + # if $SAFE >= 4 + # fail SecurityError, "can't call 'TkOptionDB.crear' at $SAFE >= 4" + # end + tk_call_without_enc('option', 'clear') + end + def get(win, name, klass) + tk_call('option', 'get', win ,name, klass) + end + def readfile(file, pri=None) + tk_call('option', 'readfile', file, pri) + end + alias read_file readfile + module_function :add, :clear, :get, :readfile, :read_file + + def read_entries(file, f_enc=nil) + if TkCore::INTERP.safe? + fail SecurityError, + "can't call 'TkOptionDB.read_entries' on a safe interpreter" + end + + i_enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system) + + unless f_enc + f_enc = i_enc + end + + ent = [] + cline = '' + open(file, 'r') {|f| + while line = f.gets + #cline += line.chomp! + cline.concat(line.chomp!) + case cline + when /\\$/ # continue + cline.chop! + next + when /^\s*(!|#)/ # coment + cline = '' + next + when /^([^:]+):(.*)$/ + pat = $1.strip + val = $2.lstrip + p "ResourceDB: #{[pat, val].inspect}" if $DEBUG + pat = TkCore::INTERP._toUTF8(pat, f_enc) + pat = TkCore::INTERP._fromUTF8(pat, i_enc) + val = TkCore::INTERP._toUTF8(val, f_enc) + val = TkCore::INTERP._fromUTF8(val, i_enc) + ent << [pat, val] + cline = '' + else # unknown --> ignore + cline = '' + next + end + end + } + ent + end + module_function :read_entries + + def read_with_encoding(file, f_enc=nil, pri=None) + # try to read the file as an OptionDB file + read_entries(file, f_enc).each{|pat, val| + add(pat, val, pri) + } + +=begin + i_enc = Tk.encoding() + + unless f_enc + f_enc = i_enc + end + + cline = '' + open(file, 'r') {|f| + while line = f.gets + cline += line.chomp! + case cline + when /\\$/ # continue + cline.chop! + next + when /^\s*!/ # coment + cline = '' + next + when /^([^:]+):\s(.*)$/ + pat = $1 + val = $2 + p "ResourceDB: #{[pat, val].inspect}" if $DEBUG + pat = TkCore::INTERP._toUTF8(pat, f_enc) + pat = TkCore::INTERP._fromUTF8(pat, i_enc) + val = TkCore::INTERP._toUTF8(val, f_enc) + val = TkCore::INTERP._fromUTF8(val, i_enc) + add(pat, val, pri) + cline = '' + else # unknown --> ignore + cline = '' + next + end + end + } +=end + end + module_function :read_with_encoding + + # support procs on the resource database + @@resource_proc_class = Class.new + + @@resource_proc_class.const_set(:CARRIER, '.'.freeze) + + @@resource_proc_class.instance_variable_set('@method_tbl', + TkCore::INTERP.create_table) + @@resource_proc_class.instance_variable_set('@add_method', false) + @@resource_proc_class.instance_variable_set('@safe_mode', 4) + + class << @@resource_proc_class + private :new + +=begin + CARRIER = '.'.freeze + METHOD_TBL = TkCore::INTERP.create_table + ADD_METHOD = false + SAFE_MODE = 4 +=end + +=begin + def __closed_block_check__(str) + depth = 0 + str.scan(/[{}]/){|x| + if x == "{" + depth += 1 + elsif x == "}" + depth -= 1 + end + if depth <= 0 && !($' =~ /\A\s*\Z/) + fail RuntimeError, "bad string for procedure : #{str.inspect}" + end + } + str + end + private :__closed_block_check__ +=end + + def __check_proc_string__(str) + # If you want to check the proc_string, do it in this method. + # Please define this in the block given to 'new_proc_class' method. + str + end + + def method_missing(id, *args) + #res_proc, proc_str = self::METHOD_TBL[id] + res_proc, proc_str = @method_tbl[id] + + proc_source = TkOptionDB.get(self::CARRIER, id.id2name, '').strip + res_proc = nil if proc_str != proc_source # resource is changed + + # unless res_proc.kind_of?(Proc) + unless TkComm._callback_entry?(res_proc) + #if id == :new || !(self::METHOD_TBL.has_key?(id) || self::ADD_METHOD) + if id == :new || !(@method_tbl.has_key?(id) || @add_method) + raise NoMethodError, + "not support resource-proc '#{id.id2name}' for #{self.name}" + end + proc_str = proc_source + proc_str = '{' + proc_str + '}' unless /\A\{.*\}\Z/ =~ proc_str + #proc_str = __closed_block_check__(proc_str) + proc_str = __check_proc_string__(proc_str) + res_proc = proc{ + begin + #eval("$SAFE = #{self::SAFE_MODE};\nProc.new" + proc_str) + eval("$SAFE = #{@safe_mode};\nProc.new" + proc_str) + rescue SyntaxError=>err + raise SyntaxError, + TkCore::INTERP._toUTF8(err.message.gsub(/\(eval\):\d:/, + "(#{id.id2name}):")) + end + }.call + #self::METHOD_TBL[id] = [res_proc, proc_source] + @method_tbl[id] = [res_proc, proc_source] + end + res_proc.call(*args) + end + + private :__check_proc_string__, :method_missing + end + @@resource_proc_class.freeze + +=begin + def __create_new_class(klass, func, safe = 4, add = false, parent = nil) + klass = klass.to_s if klass.kind_of? Symbol + unless (?A..?Z) === klass[0] + fail ArgumentError, "bad string '#{klass}' for class name" + end + unless func.kind_of? Array + fail ArgumentError, "method-list must be Array" + end + func_str = func.join(' ') + if parent == nil + install_win(parent) + elsif parent <= @@resource_proc_class + install_win(parent::CARRIER) + else + fail ArgumentError, "parent must be Resource-Proc class" + end + carrier = Tk.tk_call_without_enc('frame', @path, '-class', klass) + + body = <<-"EOD" + class #{klass} < TkOptionDB.module_eval('@@resource_proc_class') + CARRIER = '#{carrier}'.freeze + METHOD_TBL = TkCore::INTERP.create_table + ADD_METHOD = #{add} + SAFE_MODE = #{safe} + %w(#{func_str}).each{|f| METHOD_TBL[f.intern] = nil } + end + EOD + + if parent.kind_of?(Class) && parent <= @@resource_proc_class + parent.class_eval(body) + eval(parent.name + '::' + klass) + else + eval(body) + eval('TkOptionDB::' + klass) + end + end +=end + def __create_new_class(klass, func, safe = 4, add = false, parent = nil) + if klass.kind_of?(TkWindow) + carrier = klass.path + klass = CmdClassID.join(TkCore::INTERP._ip_id_) + CmdClassID[1].succ! + parent = nil # ignore parent + else + klass = klass.to_s if klass.kind_of?(Symbol) + unless (?A..?Z) === klass[0] + fail ArgumentError, "bad string '#{klass}' for class name" + end + if parent == nil + install_win(nil) + elsif parent.kind_of?(TkWindow) + install_win(parent.path) + elsif parent <= @@resource_proc_class + install_win(parent::CARRIER) + else + fail ArgumentError, "parent must be Resource-Proc class" + end + carrier = Tk.tk_call_without_enc('frame', @path, '-class', klass) + end + + unless func.kind_of?(Array) + fail ArgumentError, "method-list must be Array" + end + func_str = func.join(' ') + + if parent.kind_of?(Class) && parent <= @@resource_proc_class + cmd_klass = Class.new(parent) + else + cmd_klass = Class.new(TkOptionDB.module_eval('@@resource_proc_class')) + end + cmd_klass.const_set(:CARRIER, carrier.dup.freeze) + + cmd_klass.instance_variable_set('@method_tbl', TkCore::INTERP.create_table) + cmd_klass.instance_variable_set('@add_method', add) + cmd_klass.instance_variable_set('@safe_mode', safe) + func.each{|f| + cmd_klass.instance_variable_get('@method_tbl')[f.to_s.intern] = nil + } +=begin + cmd_klass.const_set(:METHOD_TBL, TkCore::INTERP.create_table) + cmd_klass.const_set(:ADD_METHOD, add) + cmd_klass.const_set(:SAFE_MODE, safe) + func.each{|f| cmd_klass::METHOD_TBL[f.to_s.intern] = nil } +=end + + cmd_klass + end + module_function :__create_new_class + private_class_method :__create_new_class + + def __remove_methods_of_proc_class(klass) + # for security, make these methods invalid + class << klass + def __null_method(*args); nil; end + [ :class_eval, :name, :superclass, :clone, :dup, :autoload, :autoload?, + :ancestors, :const_defined?, :const_get, :const_set, :const_missing, + :class_variables, :constants, :included_modules, :instance_methods, + :method_defined?, :module_eval, :private_instance_methods, + :protected_instance_methods, :public_instance_methods, + :singleton_methods, :remove_const, :remove_method, :undef_method, + :to_s, :inspect, :display, :method, :methods, :respond_to?, + :instance_variable_get, :instance_variable_set, :instance_method, + :instance_eval, :instance_variables, :kind_of?, :is_a?, + :private_methods, :protected_methods, :public_methods ].each{|m| + alias_method(m, :__null_method) + } + end + end + module_function :__remove_methods_of_proc_class + private_class_method :__remove_methods_of_proc_class + + RAND_BASE_CNT = [0] + RAND_BASE_HEAD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + RAND_BASE_CHAR = RAND_BASE_HEAD + 'abcdefghijklmnopqrstuvwxyz0123456789_' + def __get_random_basename + name = '%s%03d' % [RAND_BASE_HEAD[rand(RAND_BASE_HEAD.size),1], + RAND_BASE_CNT[0]] + len = RAND_BASE_CHAR.size + (6+rand(10)).times{ + name << RAND_BASE_CHAR[rand(len),1] + } + RAND_BASE_CNT[0] = RAND_BASE_CNT[0] + 1 + name + end + module_function :__get_random_basename + private_class_method :__get_random_basename + + # define new proc class : + # If you want to modify the new class or create a new subclass, + # you must do such operation in the block parameter. + # Because the created class is flozen after evaluating the block. + def new_proc_class(klass, func, safe = 4, add = false, parent = nil, &b) + new_klass = __create_new_class(klass, func, safe, add, parent) + new_klass.class_eval(&b) if block_given? + __remove_methods_of_proc_class(new_klass) + new_klass.freeze + new_klass + end + module_function :new_proc_class + + def eval_under_random_base(parent = nil, &b) + new_klass = __create_new_class(__get_random_basename(), + [], 4, false, parent) + ret = new_klass.class_eval(&b) if block_given? + __remove_methods_of_proc_class(new_klass) + new_klass.freeze + ret + end + module_function :eval_under_random_base + + def new_proc_class_random(klass, func, safe = 4, add = false, &b) + eval_under_random_base(){ + TkOption.new_proc_class(klass, func, safe, add, self, &b) + } + end + module_function :new_proc_class_random +end +TkOption = TkOptionDB +TkResourceDB = TkOptionDB diff --git a/ruby_1_8_6/ext/tk/lib/tk/optionobj.rb b/ruby_1_8_6/ext/tk/lib/tk/optionobj.rb new file mode 100644 index 0000000000..8fe7e0ee5a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/optionobj.rb @@ -0,0 +1,212 @@ +# +# tk/optionobj.rb : control options for a group of widgets +# +# NOTE: If you want to use key-only option (no value), +# use Tk::None for the value of the key-only option. +# +# e.g. hash_kv({'aaa'=>1, 'bbb'=>Tk::None, 'ccc'=>3}) +# => ["-aaa", 1, "-bbb", "-ccc", 3] +# +require 'tk' + +module Tk + class OptionObj < Hash + include TkUtil + + def initialize(hash = nil) + super() + @observ = [] + update_without_notify(_symbolkey2str(hash)) if hash + end + + def observ_info + @observ.dup + end + + def observs + @observ.collect{|win| + if win.kind_of?(Array) + win[0] + else + win + end + } + end + + def _remove_win(win) + if win.kind_of?(Array) + widget, method = win + @observ.delete_if{|x| + if x.kind_of?(Array) + x[0] == widget + else + x == widget + end + } + else + @observ.delete_if{|x| + if x.kind_of?(Array) + x[0] == win + else + x == win + end + } + end + end + private :_remove_win + + def assign(*wins) + # win := + # widget #==> call widget.configure(hash) + # [widget] #==> call widget.configure(hash) + # [widget, nil, {src=>target, ... }] + # #==> call widget.configure(hash) + # with converting hash-key + # [widget, method] #==> call widget.method(hash) + # [widget, method, {src=>target, ... }] + # #==> call widget.method(hash) + # with converting hash-key + # [widget [receiver, method, arg, ... ]] + # #==> call receiver.method(arg, ... , hash) + # [widget [receiver, method, arg, ... ], {src=>target, ... }] + # #==> call receiver.method(arg, ... , hash) + # with onverting hash-key + # + # src := option_name_on_optobj + # + # target := + # nil #==> not use the src + # option_name_on_target_widget + # [ option_name_on_target_widget, ... ] + # #==> set all of them + # + wins.each{|win| + _remove_win(win) + @observ << win + notify(win) + } + self + end + + def unassign(*wins) + wins.each{|win| + _remove_win(win) + } + self + end + + def notify(target = nil) + if target + targets = [target] + elsif @observ.empty? + return self + else + targets = @observ.dup + end + + return self if empty? + + org_hash = _symbolkey2str(self) + + targets.each{|win| + widget = receiver = win + hash = org_hash + begin + if win.kind_of?(Array) + widget, method, conv_tbl = win + receiver = widget + + if conv_tbl + hash = {} + org_hash.each{|key, val| + key = conv_tbl[key] if conv_tbl.key?(key) + next unless key + if key.kind_of?(Array) + key.each{|k| hash[k] = val} + else + hash[key] = val + end + } + end + + if method.kind_of?(Array) + receiver, method, *args = method + receiver.__send__(method, *(args << hash)) + elsif method + widget.__send__(method, hash) + else + widget.configure(hash) + end + + else + widget.configure(self) + end + rescue => e + if ( ( widget.kind_of?(TkObject) \ + && widget.respond_to?('exist?') \ + && ! receiver.exist? ) \ + || ( receiver.kind_of?(TkObject) \ + && receiver.respond_to?('exist?') \ + && ! receiver.exist? ) ) + @observ.delete(win) + else + fail e + end + end + } + + self + end + alias apply notify + + def +(hash) + unless hash.kind_of?(Hash) + fail ArgumentError, "expect a Hash" + end + new_obj = self.dup + new_obj.update_without_notify(_symbolkey2str(hash)) + new_obj + end + + alias update_without_notify update + + def update(hash) + update_without_notify(_symbolkey2str(hash)) + notify + end + + def configure(key, value=nil) + if key.kind_of?(Hash) + update(key) + else + store(key,value) + end + end + + def [](key) + super(key.to_s) + end + alias cget [] + + def store(key, val) + key = key.to_s + super(key, val) + notify + end + def []=(key, val) + store(key,val) + end + + def replace(hash) + super(_symbolkey2str(hash)) + notify + end + + def default(opt) + fail RuntimeError, "unknown option `#{opt}'" + end + private :default + + undef :default= + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/pack.rb b/ruby_1_8_6/ext/tk/lib/tk/pack.rb new file mode 100644 index 0000000000..8fab363121 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/pack.rb @@ -0,0 +1,90 @@ +# +# tk/pack.rb : control pack geometry manager +# +require 'tk' + +module TkPack + include Tk + extend Tk + + TkCommandNames = ['pack'.freeze].freeze + + def configure(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + # params.push((win.kind_of?(TkObject))? win.epath: win) + params.push(_epath(win)) + args.each{|win| + # params.push((win.kind_of?(TkObject))? win.epath: win) + params.push(_epath(win)) + } + opts.each{|k, v| + params.push("-#{k}") + # params.push((v.kind_of?(TkObject))? v.epath: v) + params.push(_epath(v)) + } + tk_call_without_enc("pack", 'configure', *params) + end + alias pack configure + + def forget(*args) + return '' if args.size == 0 + wins = args.collect{|win| + # (win.kind_of?(TkObject))? win.epath: win + _epath(win) + } + tk_call_without_enc('pack', 'forget', *wins) + end + + def info(slave) + # slave = slave.epath if slave.kind_of?(TkObject) + slave = _epath(slave) + ilist = list(tk_call_without_enc('pack', 'info', slave)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + return info + end + + def propagate(master, mode=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if mode == None + bool(tk_call_without_enc('pack', 'propagate', master)) + else + tk_call_without_enc('pack', 'propagate', master, mode) + end + end + + def slaves(master) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('pack', 'slaves', master)) + end + + module_function :pack, :configure, :forget, :info, :propagate, :slaves +end +=begin +def TkPack(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + params.push((win.kind_of?(TkObject))? win.epath: win) + args.each{|win| + params.push((win.kind_of?(TkObject))? win.epath: win) + } + opts.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + tk_call_without_enc("pack", *params) +end +=end diff --git a/ruby_1_8_6/ext/tk/lib/tk/package.rb b/ruby_1_8_6/ext/tk/lib/tk/package.rb new file mode 100644 index 0000000000..d1eb27674d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/package.rb @@ -0,0 +1,139 @@ +# +# tk/package.rb : package command +# +require 'tk' + +module TkPackage + include TkCore + extend TkPackage + + TkCommandNames = ['package'.freeze].freeze + + def add_path(path) + Tk::AUTO_PATH.value = Tk::AUTO_PATH.to_a << path + end + + def forget(package) + tk_call('package', 'forget', package) + nil + end + + def if_needed(pkg, ver, *arg, &b) + size = arg.size + + if size==0 && !b + # proc info + procedure(tk_call('package', 'ifneeded', pkg, ver)) + + elsif size==0 && b + # set proc + cmd = proc(&b) + tk_call('package', 'ifneeded', pkg, ver, cmd) + cmd + + elsif size==1 && !b + # set proc + cmd = arg[0] + if cmd + tk_call('package', 'ifneeded', pkg, ver, cmd) + cmd + else + # remove proc + tk_call('package', 'ifneeded', pkg, ver, '') + nil + end + + else + fail ArgumentError, 'too many arguments' + end + end + + def names + tk_split_simplelist(tk_call('package', 'names')) + end + + def provide(package, version=nil) + if version + tk_call('package', 'provide', package, version) + end + if (ret = tk_call('package', 'provide', package)) == '' + nil + else + ret + end + end + + def present(package, version=None) + begin + tk_call('package', 'present', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def present_exact(package, version) + begin + tk_call('package', 'present', '-exact', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def require(package, version=None) + begin + tk_call('package', 'require', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def require_exact(package, version) + begin + tk_call('package', 'require', '-exact', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def unknown_proc(*arg, &b) + size = arg.size + + if size==0 && !b + # proc info + procedure(tk_call('package', 'unknown')) + + elsif size==0 && b + # set proc + cmd = proc(&b) + tk_call('package', 'unknown', cmd) + cmd + + elsif size==1 && !b + # set proc + cmd = arg[0] + if cmd + tk_call('package', 'unknown', cmd) + cmd + else + # remove proc + tk_call('package', 'unknown', '') + nil + end + + else + fail ArgumentError, 'too many arguments' + end + end + + def versions(package) + tk_split_simplelist(tk_call('package', 'versions', package)) + end + + def vcompare(version1, version2) + number(tk_call('package', 'vcompare', version1, version2)) + end + + def vsatisfies(version1, version2) + bool(tk_call('package', 'vsatisfies', version1, version2)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/palette.rb b/ruby_1_8_6/ext/tk/lib/tk/palette.rb new file mode 100644 index 0000000000..2b6fdf5d90 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/palette.rb @@ -0,0 +1,55 @@ +# +# tk/palette.rb : methods for Tcl/Tk standard library 'palette.tcl' +# 1998/06/21 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +require 'tk' + +module TkPalette + include Tk + extend Tk + + TkCommandNames = [ + 'tk_setPalette'.freeze, + 'tk_bisque'.freeze, + 'tkDarken'.freeze + ].freeze + + def TkPalette.set(*args) + args = args.to_a.flatten if args.kind_of? Hash + tk_call('tk_setPalette', *args) + end + def TkPalette.setPalette(*args) + TkPalette.set(*args) + end + + def TkPalette.bisque + tk_call('tk_bisque') + end + + def TkPalette.darken(color, percent) + tk_call('tkDarken', color, percent) + end + + def TkPalette.recolorTree(win, colors) + if not colors.kind_of?(Hash) + fail "2nd arg need to be Hash" + end + + tk_call('global', "tkPalette") + colors.each{|key, value| + begin + if win.cget(key) == tk_call('set', "tkPalette(#{key})") + win[key] = colors[key] + end + rescue + # ignore + end + } + + TkWinfo.children(win).each{|w| TkPalette.recolorTree(w, colors)} + end + + def recolorTree(colors) + TkPalette.recolorTree(self, colors) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/panedwindow.rb b/ruby_1_8_6/ext/tk/lib/tk/panedwindow.rb new file mode 100644 index 0000000000..c6cf3cd11f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/panedwindow.rb @@ -0,0 +1,232 @@ +# +# tk/panedwindow.rb : treat panedwindow +# +require 'tk' + +class TkPanedWindow<TkWindow + TkCommandNames = ['panedwindow'.freeze].freeze + WidgetClassName = 'Panedwindow'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('panedwindow', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('panedwindow', @path) + # end + #end + #private :create_self + + def add(*args) + keys = args.pop + fail ArgumentError, "no window in arguments" unless keys + if keys && keys.kind_of?(Hash) + fail ArgumentError, "no window in arguments" if args == [] + # args = args.collect{|w| (w.kind_of?(TkObject))? w.epath: w } + args = args.collect{|w| _epath(w) } + #args.push(hash_kv(keys)) + args.concat(hash_kv(keys)) + else + args.push(keys) if keys + # args = args.collect{|w| (w.kind_of?(TkObject))? w.epath: w } + args = args.collect{|w| _epath(w) } + end + tk_send_without_enc('add', *args) + self + end + + def forget(win, *wins) + wins.unshift(win) + # tk_send_without_enc('forget', *((w.kind_of?(TkObject))? w.epath: w)) + tk_send_without_enc('forget', *(wins.collect{|w| _epath(w)})) + self + end + alias del forget + alias delete forget + alias remove forget + + def identify(x, y) + list(tk_send_without_enc('identify', x, y)) + end + + def proxy_coord + list(tk_send_without_enc('proxy', 'coord')) + end + def proxy_forget + tk_send_without_enc('proxy', 'forget') + self + end + def proxy_place(x, y) + tk_send_without_enc('proxy', 'place', x, y) + self + end + + def sash_coord(index) + list(tk_send('sash', 'coord', index)) + end + def sash_dragto(index, x, y) + tk_send('sash', 'dragto', index, x, y) + self + end + def sash_mark(index, x, y) + tk_send('sash', 'mark', index, x, y) + self + end + def sash_place(index, x, y) + tk_send('sash', 'place', index, x, y) + self + end + + def panecget(win, key) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + tk_tcl2ruby(tk_send_without_enc('panecget', win, "-#{key}")) + end + + def paneconfigure(win, key, value=nil) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if key.kind_of? Hash + params = [] + key.each{|k, v| + params.push("-#{k}") + # params.push((v.kind_of?(TkObject))? v.epath: v) + params.push(_epath(v)) + } + tk_send_without_enc('paneconfigure', win, *params) + else + # value = value.epath if value.kind_of?(TkObject) + value = _epath(value) + tk_send_without_enc('paneconfigure', win, "-#{key}", value) + end + self + end + alias pane_config paneconfigure + + def paneconfiginfo(win, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if key + #conf = tk_split_list(tk_send_without_enc('paneconfigure', + # win, "-#{key}")) + conf = tk_split_list(tk_send_without_enc('paneconfigure', + win, "-#{key}"), + false, true) + conf[0] = conf[0][1..-1] + if conf[0] == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + conf[4] = bool(conf[4]) unless conf[4].empty? + end + conf + else + #tk_split_simplelist(tk_send_without_enc('paneconfigure', + # win)).collect{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('paneconfigure', win), + false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[0] = conf[0][1..-1] + if conf[3] + if conf[0] == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + elsif conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[0] == 'hide' + conf[4] = bool(conf[4]) unless conf[4].empty? + elsif conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if key + #conf = tk_split_list(tk_send_without_enc('paneconfigure', + # win, "-#{key}")) + conf = tk_split_list(tk_send_without_enc('paneconfigure', + win, "-#{key}"), + false, true) + key = conf.shift[1..-1] + if key == 'hide' + conf[2] = bool(conf[2]) unless conf[2].empty? + conf[3] = bool(conf[3]) unless conf[3].empty? + end + { key => conf } + else + ret = {} + #tk_split_simplelist(tk_send_without_enc('paneconfigure', + # win)).each{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('paneconfigure', win), + false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + key = conf.shift[1..-1] + if key + if key == 'hide' + conf[2] = bool(conf[2]) unless conf[2].empty? + elsif conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if key == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + elsif conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + alias pane_configinfo paneconfiginfo + + def current_paneconfiginfo(win, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = paneconfiginfo(win, key) + {conf[0] => conf[4]} + else + ret = {} + paneconfiginfo(win).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + paneconfiginfo(win, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + alias current_pane_configinfo current_paneconfiginfo + + def panes + list(tk_send_without_enc('panes')) + end +end +TkPanedwindow = TkPanedWindow diff --git a/ruby_1_8_6/ext/tk/lib/tk/place.rb b/ruby_1_8_6/ext/tk/lib/tk/place.rb new file mode 100644 index 0000000000..f7ebdfcbd6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/place.rb @@ -0,0 +1,128 @@ +# +# tk/place.rb : control place geometry manager +# +require 'tk' + +module TkPlace + include Tk + extend Tk + + TkCommandNames = ['place'.freeze].freeze + + def configure(win, slot, value=None) + # for >= Tk8.4a2 ? + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if slot.kind_of? Hash + params = [] + slot.each{|k, v| + params.push("-#{k}") + # params.push((v.kind_of?(TkObject))? v.epath: v) + params.push(_epath(v)) + } + tk_call_without_enc('place', 'configure', win, *params) + else + # value = value.epath if value.kind_of?(TkObject) + value = _epath(value) + tk_call_without_enc('place', 'configure', win, "-#{slot}", value) + end + end + alias place configure + + def configinfo(win, slot = nil) + # for >= Tk8.4a2 ? + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if slot + #conf = tk_split_list(tk_call_without_enc('place', 'configure', + # win, "-#{slot}") ) + conf = tk_split_simplelist(tk_call_without_enc('place', 'configure', + win, "-#{slot}") ) + conf[0] = conf[0][1..-1] + conf[1] = tk_tcl2ruby(conf[1]) + conf[2] = tk_tcl2ruby(conf[1]) + conf[3] = tk_tcl2ruby(conf[1]) + conf[4] = tk_tcl2ruby(conf[1]) + conf + else + tk_split_simplelist(tk_call_without_enc('place', 'configure', + win)).collect{|conflist| + #conf = list(conflist) + conf = simplelist(conflist).collect!{|inf| tk_tcl2ruby(inf)} + conf[0] = conf[0][1..-1] + conf + } + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + current_configinfo(win, slot) + end + end + + def current_configinfo(win, slot = nil) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if slot + #conf = tk_split_list(tk_call_without_enc('place', 'configure', + # win, "-#{slot}") ) + conf = tk_split_simplelist(tk_call_without_enc('place', 'configure', + win, "-#{slot}") ) + # { conf[0][1..-1] => conf[1] } + { conf[0][1..-1] => tk_tcl2ruby(conf[4]) } + else + ret = {} + #tk_split_list(tk_call_without_enc('place','configure',win)).each{|conf| + tk_split_simplelist(tk_call_without_enc('place', 'configure', + win)).each{|conf_list| + #ret[conf[0][1..-1]] = conf[1] + conf = simplelist(conf_list) + ret[conf[0][1..-1]] = tk_tcl2ruby(conf[4]) + } + ret + end + end + + def forget(win) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + tk_call_without_enc('place', 'forget', win) + end + + def info(win) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + #ilist = list(tk_call_without_enc('place', 'info', win)) + ilist = simplelist(tk_call_without_enc('place', 'info', win)) + info = {} + while key = ilist.shift + #info[key[1..-1]] = ilist.shift + info[key[1..-1]] = tk_tcl2ruby(ilist.shift) + end + return info + end + + def slaves(master) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call('place', 'slaves', master)) + end + + module_function :place, :configure, :configinfo, :current_configinfo + module_function :forget, :info, :slaves +end +=begin +def TkPlace(win, slot, value=None) + win = win.epath if win.kind_of?(TkObject) + if slot.kind_of? Hash + params = [] + slot.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + tk_call_without_enc('place', win, *params) + else + value = value.epath if value.kind_of?(TkObject) + tk_call_without_enc('place', win, "-#{slot}", value) + end +end +=end diff --git a/ruby_1_8_6/ext/tk/lib/tk/radiobutton.rb b/ruby_1_8_6/ext/tk/lib/tk/radiobutton.rb new file mode 100644 index 0000000000..f8f67d709a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/radiobutton.rb @@ -0,0 +1,66 @@ +# +# tk/radiobutton.rb : treat radiobutton widget +# +require 'tk' +require 'tk/button' + +class TkRadioButton<TkButton + TkCommandNames = ['radiobutton'.freeze].freeze + WidgetClassName = 'Radiobutton'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('radiobutton', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('radiobutton', @path) + # end + #end + #private :create_self + + def __boolval_optkeys + super() << 'indicatoron' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'selectcolor' + end + private :__strval_optkeys + + def __ruby2val_optkeys # { key=>proc, ... } + { + 'variable'=>proc{|v| tk_trace_variable(v)} # for backward compatibility + } + end + private :__ruby2val_optkeys + + + def deselect + tk_send_without_enc('deselect') + self + end + def select + tk_send_without_enc('select') + self + end + + def get_value + var = tk_send_without_enc('cget', '-variable') + if TkVariable::USE_TCLs_SET_VARIABLE_FUNCTIONS + _fromUTF8(INTERP._get_global_var(var)) + else + INTERP._eval(Kernel.format('global %s; set %s', var, var)) + end + end + + def set_value(val) + var = tk_send_without_enc('cget', '-variable') + if TkVariable::USE_TCLs_SET_VARIABLE_FUNCTIONS + _fromUTF8(INTERP._set_global_var(var, _get_eval_string(val, true))) + else + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; set %s %s', var, var, s)) + end + end +end +TkRadiobutton = TkRadioButton diff --git a/ruby_1_8_6/ext/tk/lib/tk/root.rb b/ruby_1_8_6/ext/tk/lib/tk/root.rb new file mode 100644 index 0000000000..0e5584c7c1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/root.rb @@ -0,0 +1,108 @@ +# +# tk/root.rb : treat root widget +# +require 'tk' +require 'tk/wm' +require 'tk/menuspec' + +class TkRoot<TkWindow + include Wm + include TkMenuSpec + + def __methodcall_optkeys # { key=>method, ... } + TOPLEVEL_METHODCALL_OPTKEYS + end + private :__methodcall_optkeys + +=begin + ROOT = [] + def TkRoot.new(keys=nil) + if ROOT[0] + Tk_WINDOWS["."] = ROOT[0] + return ROOT[0] + end + new = super(:without_creating=>true, :widgetname=>'.') + if keys # wm commands + keys.each{|k,v| + if v.kind_of? Array + new.send(k,*v) + else + new.send(k,v) + end + } + end + ROOT[0] = new + Tk_WINDOWS["."] = new + end +=end + def TkRoot.new(keys=nil, &b) + unless TkCore::INTERP.tk_windows['.'] + TkCore::INTERP.tk_windows['.'] = + super(:without_creating=>true, :widgetname=>'.'){} + end + root = TkCore::INTERP.tk_windows['.'] + + keys = _symbolkey2str(keys) + + # wm commands + root.instance_eval{ + __methodcall_optkeys.each{|key, method| + value = keys.delete(key.to_s) + self.__send__(method, value) if value + } + } + + if keys # wm commands ( for backward comaptibility ) + keys.each{|k,v| + if v.kind_of? Array + root.__send__(k,*v) + else + root.__send__(k,v) + end + } + end + + root.instance_eval(&b) if block_given? + root + end + + WidgetClassName = 'Tk'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.to_eval + # self::WidgetClassName + '.' + end + + def create_self + @path = '.' + end + private :create_self + + def path + "." + end + + def add_menu(menu_info, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_info. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_info can override it. + if tearoff.kind_of?(Hash) + opts = tearoff + tearoff = false + end + _create_menubutton(self, menu_info, tearoff, opts) + end + + def add_menubar(menu_spec, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_spec. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_spec can override it. + menu_spec.each{|info| add_menu(info, tearoff, opts)} + self.menu + end + + def TkRoot.destroy + TkCore::INTERP._invoke('destroy', '.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/scale.rb b/ruby_1_8_6/ext/tk/lib/tk/scale.rb new file mode 100644 index 0000000000..0b703aa055 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scale.rb @@ -0,0 +1,86 @@ +# +# tk/scale.rb : treat scale widget +# +require 'tk' + +class TkScale<TkWindow + TkCommandNames = ['scale'.freeze].freeze + WidgetClassName = 'Scale'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + if keys.key?('command') && ! keys['command'].kind_of?(String) + cmd = keys.delete('command') + keys['command'] = proc{|val| cmd.call(val.to_f)} + end + #tk_call_without_enc('scale', @path, *hash_kv(keys, true)) + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + #tk_call_without_enc('scale', @path) + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def __strval_optkeys + super() << 'label' + end + private :__strval_optkeys + + def _wrap_command_arg(cmd) + proc{|val| + if val.kind_of?(String) + cmd.call(number(val)) + else + cmd.call(val) + end + } + end + private :_wrap_command_arg + + def configure_cmd(slot, value) + configure(slot=>value) + end + + def configure(slot, value=None) + if (slot == 'command' || slot == :command) + configure('command'=>value) + elsif slot.kind_of?(Hash) && + (slot.key?('command') || slot.key?(:command)) + slot = _symbolkey2str(slot) + slot['command'] = _wrap_command_arg(slot.delete('command')) + end + super(slot, value) + end + + def command(cmd=Proc.new) + configure('command'=>cmd) + end + + def get(x=None, y=None) + number(tk_send_without_enc('get', x, y)) + end + + def coords(val=None) + tk_split_list(tk_send_without_enc('coords', val)) + end + + def identify(x, y) + tk_send_without_enc('identify', x, y) + end + + def set(val) + tk_send_without_enc('set', val) + end + + def value + get + end + + def value= (val) + set(val) + val + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/scrollable.rb b/ruby_1_8_6/ext/tk/lib/tk/scrollable.rb new file mode 100644 index 0000000000..96959b7a4b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scrollable.rb @@ -0,0 +1,82 @@ +# +# tk/scrollable.rb : module for scrollable widget +# +require 'tk' + +module Tk + module XScrollable + def xscrollcommand(cmd=Proc.new) + configure_cmd 'xscrollcommand', cmd + # Tk.update # avoid scrollbar trouble + self + end + + def xview(*index) + if index.size == 0 + list(tk_send_without_enc('xview')) + else + tk_send_without_enc('xview', *index) + self + end + end + def xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + end + + def xscrollbar(bar=nil) + if bar + @xscrollbar = bar + @xscrollbar.orient 'horizontal' + self.xscrollcommand {|*arg| @xscrollbar.set(*arg)} + @xscrollbar.command {|*arg| self.xview(*arg)} + Tk.update # avoid scrollbar trouble + end + @xscrollbar + end + end + + module YScrollable + def yscrollcommand(cmd=Proc.new) + configure_cmd 'yscrollcommand', cmd + # Tk.update # avoid scrollbar trouble + self + end + + def yview(*index) + if index.size == 0 + list(tk_send_without_enc('yview')) + else + tk_send_without_enc('yview', *index) + self + end + end + def yview_moveto(*index) + yview('moveto', *index) + end + def yview_scroll(*index) + yview('scroll', *index) + end + + def yscrollbar(bar=nil) + if bar + @yscrollbar = bar + @yscrollbar.orient 'vertical' + self.yscrollcommand {|*arg| @yscrollbar.set(*arg)} + @yscrollbar.command {|*arg| self.yview(*arg)} + Tk.update # avoid scrollbar trouble + end + @yscrollbar + end + end + + X_Scrollable = XScrollable + Y_Scrollable = YScrollable + + module Scrollable + include XScrollable + include YScrollable + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/scrollbar.rb b/ruby_1_8_6/ext/tk/lib/tk/scrollbar.rb new file mode 100644 index 0000000000..70aadfdd4c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scrollbar.rb @@ -0,0 +1,124 @@ +# +# tk/scrollbar.rb : treat scrollbar widget +# +require 'tk' + +class TkScrollbar<TkWindow + TkCommandNames = ['scrollbar'.freeze].freeze + WidgetClassName = 'Scrollbar'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + @assigned = [] + @scroll_proc = proc{|*args| + if self.orient == 'horizontal' + @assigned.each{|w| w.xview(*args)} + else # 'vertical' + @assigned.each{|w| w.yview(*args)} + end + } + + if keys and keys != None + #tk_call_without_enc('scrollbar', @path, *hash_kv(keys, true)) + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + #tk_call_without_enc('scrollbar', @path) + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def propagate_set(src_win, first, last) + self.set(first, last) + if self.orient == 'horizontal' + @assigned.each{|w| w.xview('moveto', first) if w != src_win} + else # 'vertical' + @assigned.each{|w| w.yview('moveto', first) if w != src_win} + end + end + + def assign(*wins) + begin + self.command(@scroll_proc) if self.cget('command').cmd != @scroll_proc + rescue Exception + self.command(@scroll_proc) + end + orient = self.orient + wins.each{|w| + @assigned << w unless @assigned.index(w) + if orient == 'horizontal' + w.xscrollcommand proc{|first, last| self.propagate_set(w, first, last)} + else # 'vertical' + w.yscrollcommand proc{|first, last| self.propagate_set(w, first, last)} + end + } + Tk.update # avoid scrollbar trouble + self + end + + def assigned_list + begin + return @assigned.dup if self.cget('command').cmd == @scroll_proc + rescue Exception + end + fail RuntimeError, "not depend on the assigned_list" + end + + def configure(*args) + ret = super(*args) + # Tk.update # avoid scrollbar trouble + ret + end + + #def delta(deltax=None, deltay=None) + def delta(deltax, deltay) + number(tk_send_without_enc('delta', deltax, deltay)) + end + + #def fraction(x=None, y=None) + def fraction(x, y) + number(tk_send_without_enc('fraction', x, y)) + end + + def identify(x, y) + tk_send_without_enc('identify', x, y) + end + + def get + #ary1 = tk_send('get').split + #ary2 = [] + #for i in ary1 + # ary2.push number(i) + #end + #ary2 + list(tk_send_without_enc('get')) + end + + def set(first, last) + tk_send_without_enc('set', first, last) + self + end + + def activate(element=None) + tk_send_without_enc('activate', element) + end +end + +class TkXScrollbar<TkScrollbar + def create_self(keys) + keys = {} unless keys + keys['orient'] = 'horizontal' + super(keys) + end + private :create_self +end + +class TkYScrollbar<TkScrollbar + def create_self(keys) + keys = {} unless keys + keys['orient'] = 'vertical' + super(keys) + end + private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/scrollbox.rb b/ruby_1_8_6/ext/tk/lib/tk/scrollbox.rb new file mode 100644 index 0000000000..fd04057fb6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scrollbox.rb @@ -0,0 +1,36 @@ +# +# tk/scrollbox.rb - Tk Listbox with Scrollbar +# as an example of Composite Widget +# $Date$ +# by Yukihiro Matsumoto <matz@netlab.co.jp> +# +require 'tk' +require 'tk/listbox' + +class TkScrollbox<TkListbox + include TkComposite + def initialize_composite(keys=nil) + list = TkListbox.new(@frame) + scroll = TkScrollbar.new(@frame) + @path = list.path + +=begin + list.configure 'yscroll', scroll.path+" set" + list.pack 'side'=>'left','fill'=>'both','expand'=>'yes' + scroll.configure 'command', list.path+" yview" + scroll.pack 'side'=>'right','fill'=>'y' +=end + list.yscrollbar(scroll) + list.pack('side'=>'left','fill'=>'both','expand'=>'yes') + scroll.pack('side'=>'right','fill'=>'y') + + delegate('DEFAULT', list) + delegate('foreground', list) + delegate('background', list, scroll) + delegate('borderwidth', @frame) + delegate('relief', @frame) + + configure keys if keys + end + private :initialize_composite +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/selection.rb b/ruby_1_8_6/ext/tk/lib/tk/selection.rb new file mode 100644 index 0000000000..5caa6ef8ef --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/selection.rb @@ -0,0 +1,86 @@ +# +# tk/selection.rb : control selection +# +require 'tk' + +module TkSelection + include Tk + extend Tk + + TkCommandNames = ['selection'.freeze].freeze + + def self.clear(sel=nil) + if sel + tk_call_without_enc('selection', 'clear', '-selection', sel) + else + tk_call_without_enc('selection', 'clear') + end + end + def self.clear_on_display(win, sel=nil) + if sel + tk_call_without_enc('selection', 'clear', + '-displayof', win, '-selection', sel) + else + tk_call_without_enc('selection', 'clear', '-displayof', win) + end + end + def clear(sel=nil) + TkSelection.clear_on_display(self, sel) + self + end + + def self.get(keys=nil) + #tk_call('selection', 'get', *hash_kv(keys)) + _fromUTF8(tk_call_without_enc('selection', 'get', *hash_kv(keys))) + end + def self.get_on_display(win, keys=nil) + #tk_call('selection', 'get', '-displayof', win, *hash_kv(keys)) + _fromUTF8(tk_call_without_enc('selection', 'get', '-displayof', + win, *hash_kv(keys))) + end + def get(keys=nil) + TkSelection.get_on_display(self, sel) + end + + def self.handle(win, func=Proc.new, keys=nil, &b) + if func.kind_of?(Hash) && keys == nil + keys = func + func = Proc.new(&b) + end + args = ['selection', 'handle'] + args.concat(hash_kv(keys)) + args.concat([win, func]) + tk_call_without_enc(*args) + end + def handle(func=Proc.new, keys=nil, &b) + TkSelection.handle(self, func, keys, &b) + end + + def self.get_owner(sel=nil) + if sel + window(tk_call_without_enc('selection', 'own', '-selection', sel)) + else + window(tk_call_without_enc('selection', 'own')) + end + end + def self.get_owner_on_display(win, sel=nil) + if sel + window(tk_call_without_enc('selection', 'own', + '-displayof', win, '-selection', sel)) + else + window(tk_call_without_enc('selection', 'own', '-displayof', win)) + end + end + def get_owner(sel=nil) + TkSelection.get_owner_on_display(self, sel) + self + end + + def self.set_owner(win, keys=nil) + tk_call_without_enc('selection', 'own', *(hash_kv(keys) << win)) + end + def set_owner(keys=nil) + TkSelection.set_owner(self, keys) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/spinbox.rb b/ruby_1_8_6/ext/tk/lib/tk/spinbox.rb new file mode 100644 index 0000000000..9a10977d12 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/spinbox.rb @@ -0,0 +1,99 @@ +# +# tk/spinbox.rb - Tk spinbox classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> +# +require 'tk' +require 'tk/entry' + +class TkSpinbox<TkEntry + TkCommandNames = ['spinbox'.freeze].freeze + WidgetClassName = 'Spinbox'.freeze + WidgetClassNames[WidgetClassName] = self + + class SpinCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?d, ?s, :direction ], + [ ?s, ?e, :current ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + + [ ?e, proc{|val| + #enc = Tk.encoding + enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system) + if enc + Tk.fromUTF8(TkComm::string(val), enc) + else + TkComm::string(val) + end + } + ], + + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + (val)? '1': '0' + end + end + + def self._config_keys + ['command'] + end + end + + def __validation_class_list + super() << SpinCommand + end + + Tk::ValidateConfigure.__def_validcmd(binding, SpinCommand) + + #def create_self(keys) + # tk_call_without_enc('spinbox', @path) + # if keys and keys != None + # configure(keys) + # end + #end + #private :create_self + + def __boolval_optkeys + super() << 'wrap' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'buttonbackground' << 'format' + end + private :__strval_optkeys + + def __listval_optkeys + super() << 'values' + end + private :__listval_optkeys + + def identify(x, y) + tk_send_without_enc('identify', x, y) + end + + def spinup + tk_send_without_enc('invoke', 'spinup') + self + end + + def spindown + tk_send_without_enc('invoke', 'spindown') + self + end + + def set(str) + _fromUTF8(tk_send_without_enc('set', _get_eval_enc_str(str))) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/tagfont.rb b/ruby_1_8_6/ext/tk/lib/tk/tagfont.rb new file mode 100644 index 0000000000..a1807395d2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/tagfont.rb @@ -0,0 +1,43 @@ +# +# tk/tagfont.rb : control font of tags +# +require 'tk' + +module TkTreatTagFont + def font_configinfo + @parent.tagfont_configinfo(@id) + end +# alias font font_configinfo + + def font_configure(slot) + @parent.tagfont_configure(@id, slot) + self + end + + def latinfont_configure(ltn, keys=nil) + @parent.latintagfont_configure(@id, ltn, keys) + self + end + alias asciifont_configure latinfont_configure + + def kanjifont_configure(knj, keys=nil) + @parent.kanjitagfont_configure(@id, ltn, keys) + self + end + + def font_copy(win, wintag=nil) + @parent.tagfont_copy(@id, win, wintag) + self + end + + def latinfont_copy(win, wintag=nil) + @parent.latintagfont_copy(@id, win, wintag) + self + end + alias asciifont_copy latinfont_copy + + def kanjifont_copy(win, wintag=nil) + @parent.kanjitagfont_copy(@id, win, wintag) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/text.rb b/ruby_1_8_6/ext/tk/lib/tk/text.rb new file mode 100644 index 0000000000..49d4b5625b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/text.rb @@ -0,0 +1,1550 @@ +# +# tk/text.rb - Tk text classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> +require 'tk' +require 'tk/itemfont' +require 'tk/itemconfig' +require 'tk/scrollable' +require 'tk/txtwin_abst' + +module TkTextTagConfig + include TkTreatItemFont + include TkItemConfigMethod + + def __item_cget_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'cget', id[1]] + end + private :__item_cget_cmd + + def __item_config_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'configure', id[1]] + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + id = tagid(id[1]) + end + [self.path, id].join(';') + end + private :__item_pathname + + def tag_cget(tagOrId, option) + itemcget(['tag', tagOrId], option) + end + def tag_configure(tagOrId, slot, value=None) + itemconfigure(['tag', tagOrId], slot, value) + end + def tag_configinfo(tagOrId, slot=nil) + itemconfigure(['tag', tagOrId], slot) + end + def current_tag_configinfo(tagOrId, slot=nil) + itemconfigure(['tag', tagOrId], slot) + end + + def window_cget(tagOrId, option) + itemcget(['window', tagOrId], option) + end + def window_configure(tagOrId, slot, value=None) + itemconfigure(['window', tagOrId], slot, value) + end + def window_configinfo(tagOrId, slot=nil) + itemconfigure(['window', tagOrId], slot) + end + def current_window_configinfo(tagOrId, slot=nil) + itemconfigure(['window', tagOrId], slot) + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +class TkText<TkTextWin + ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze + #include TkTreatTextTagFont + include TkTextTagConfig + include Scrollable + + ####################################### + + module IndexModMethods + def +(mod) + return chars(mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(String.new(id) << ' + ' << mod) + else + TkText::IndexString.new(String.new(id) << ' ' << mod) + end + end + + def -(mod) + return chars(-mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(String.new(id) << ' - ' << mod) + elsif mod =~ /^\s*[-]\s+(\d.*)$/ + TkText::IndexString.new(String.new(id) << ' - -' << $1) + else + TkText::IndexString.new(String.new(id) << ' ' << mod) + end + end + + def chars(mod) + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' chars') + end + end + alias char chars + + def display_chars(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display chars') + end + end + alias display_char display_chars + + def any_chars(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any chars') + end + end + alias any_char any_chars + + def indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' indices') + end + end + + def display_indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display indices') + end + end + + def any_indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any indices') + end + end + + def lines(mod) + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' lines') + end + end + alias line lines + + def display_lines(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display_lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display lines') + end + end + alias display_line display_lines + + def any_lines(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any_lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any lines') + end + end + alias any_line any_lines + + def linestart + TkText::IndexString.new(String.new(id) << ' linestart') + end + def lineend + TkText::IndexString.new(String.new(id) << ' lineend') + end + + def display_linestart + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display linestart') + end + def display_lineend + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display lineend') + end + + def wordstart + TkText::IndexString.new(String.new(id) << ' wordstart') + end + def wordend + TkText::IndexString.new(String.new(id) << ' wordend') + end + + def display_wordstart + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display wordstart') + end + def display_wordend + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display wordend') + end + end + + class IndexString < String + include IndexModMethods + + def self.at(x,y) + self.new("@#{x},#{y}") + end + + def self.new(str) + if str.kind_of?(String) + super(str) + elsif str.kind_of?(Symbol) + super(str.to_s) + else + str + end + end + + def id + self + end + end + + ####################################### + + TkCommandNames = ['text'.freeze].freeze + WidgetClassName = 'Text'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.new(*args, &block) + obj = super(*args){} + obj.init_instance_variable + obj.instance_eval(&block) if defined? yield + obj + end + + def init_instance_variable + @cmdtbl = [] + @tags = {} + end + + def __destroy_hook__ + TkTextTag::TTagID_TBL.delete(@path) + TkTextMark::TMarkID_TBL.delete(@path) + end + + def create_self(keys) + #if keys and keys != None + # #tk_call_without_enc('text', @path, *hash_kv(keys, true)) + # tk_call_without_enc(self.class::TkCommandNames[0], @path, + # *hash_kv(keys, true)) + #else + # #tk_call_without_enc('text', @path) + # tk_call_without_enc(self.class::TkCommandNames[0], @path) + #end + super(keys) + init_instance_variable + end + private :create_self + + def __strval_optkeys + super() << 'inactiveseletcionbackground' + end + private :__strval_optkeys + + def self.at(x, y) + TkText::IndexString.at(x, y) + end + + def at(x, y) + TkText::IndexString.at(x, y) + end + + def index(idx) + TkText::IndexString.new(tk_send_without_enc('index', + _get_eval_enc_str(idx))) + end + + def get_displaychars(*index) + # Tk8.5 feature + get('-displaychars', *index) + end + + def value + _fromUTF8(tk_send_without_enc('get', "1.0", "end - 1 char")) + end + + def value= (val) + tk_send_without_enc('delete', "1.0", 'end') + tk_send_without_enc('insert', "1.0", _get_eval_enc_str(val)) + val + end + + def clear + tk_send_without_enc('delete', "1.0", 'end') + self + end + alias erase clear + + def _addcmd(cmd) + @cmdtbl.push cmd + end + + def _addtag(name, obj) + @tags[name] = obj + end + + def tagid(tag) + if tag.kind_of?(TkTextTag) \ + || tag.kind_of?(TkTextMark) \ + || tag.kind_of?(TkTextImage) \ + || tag.kind_of?(TkTextWindow) + tag.id + else + tag # maybe an Array of configure paramters + end + end + private :tagid + + def tagid2obj(tagid) + if @tags[tagid] + @tags[tagid] + else + tagid + end + end + + def tag_names(index=None) + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def mark_names + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('mark', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('mark', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def mark_gravity(mark, direction=nil) + if direction + tk_send_without_enc('mark', 'gravity', + _get_eval_enc_str(mark), direction) + self + else + tk_send_without_enc('mark', 'gravity', _get_eval_enc_str(mark)) + end + end + + def mark_set(mark, index) + tk_send_without_enc('mark', 'set', _get_eval_enc_str(mark), + _get_eval_enc_str(index)) + self + end + alias set_mark mark_set + + def mark_unset(*marks) + tk_send_without_enc('mark', 'unset', + *(marks.collect{|mark| _get_eval_enc_str(mark)})) + self + end + alias unset_mark mark_unset + + def mark_next(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'next', + _get_eval_enc_str(index)))) + end + alias next_mark mark_next + + def mark_previous(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'previous', + _get_eval_enc_str(index)))) + end + alias previous_mark mark_previous + + def image_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), "-#{slot}")) + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), + "-#{slot}"))) + end + end + + def image_configure(index, slot, value=None) + if slot.kind_of?(Hash) + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + *hash_kv(slot, true))) + else + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + "-#{slot}", + _get_eval_enc_str(value))) + end + self + end + + def image_configinfo(index, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + conf[0] = conf[0][1..-1] + conf + else + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).collect{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).each{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + + def current_image_configinfo(index, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + conf = image_configinfo(index, slot) + {conf[0] => conf[4]} + else + ret = {} + image_configinfo(index).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + image_configinfo(index, slot).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + def image_names + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('image', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def set_insert(index) + tk_send_without_enc('mark','set','insert', _get_eval_enc_str(index)) + self + end + + def set_current(index) + tk_send_without_enc('mark','set','current', _get_eval_enc_str(index)) + self + end + + def insert(index, chars, *tags) + if tags[0].kind_of?(Array) + # multiple chars-taglist argument :: str, [tag,...], str, [tag,...], ... + args = [chars] + while tags.size > 0 + args << 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 :: str, tag, tag, ... + if tags.size == 0 + super(index, chars) + else + super(index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ')) + end + end + end + + def destroy + @tags = {} unless @tags + @tags.each_value do |t| + t.destroy + end + super() + end + + def backspace + self.delete 'insert' + end + + def bbox(index) + list(tk_send_without_enc('bbox', _get_eval_enc_str(index))) + end + + def compare(idx1, op, idx2) + bool(tk_send_without_enc('compare', _get_eval_enc_str(idx1), + op, _get_eval_enc_str(idx2))) + end + + def count(idx1, idx2, *opts) + # opts are Tk8.5 feature + cnt = 0 + args = opts.collect{|opt| + str = opt.to_s + cnt += 1 if str != 'update' + '-' + str + } + args << _get_eval_enc_str(idx1) << _get_eval_enc_str(idx2) + if cnt <= 1 + number(tk_send_without_enc('count', *opts)) + else + list(tk_send_without_enc('count', *opts)) + end + end + + def count_info(idx1, idx2, update=true) + # Tk8.5 feature + opts = [ + :chars, :displaychars, :displayindices, :displaylines, + :indices, :lines, :xpixels, :ypixels + ] + if update + lst = count(idx1, idx2, :update, *opts) + else + lst = count(idx1, idx2, *opts) + end + info = {} + opts.each_with_index{|key, idx| info[key] = lst[idx]} + info + end + + def peer_names() + # Tk8.5 feature + list(tk_send_without_enc('peer', 'names')) + end + + def replace(idx1, idx2, *opts) + tk_send('replace', idx1, idx2, *opts) + self + end + + def debug + bool(tk_send_without_enc('debug')) + end + def debug=(boolean) + tk_send_without_enc('debug', boolean) + #self + boolean + end + + def dlineinfo(index) + list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index))) + end + + def modified? + bool(tk_send_without_enc('edit', 'modified')) + end + def modified(mode) + tk_send_without_enc('edit', 'modified', mode) + self + end + def modified=(mode) + modified(mode) + mode + end + + def edit_redo + tk_send_without_enc('edit', 'redo') + self + end + def edit_reset + tk_send_without_enc('edit', 'reset') + self + end + def edit_separator + tk_send_without_enc('edit', 'separator') + self + end + def edit_undo + tk_send_without_enc('edit', 'undo') + self + end + + def xview_pickplace(index) + tk_send_without_enc('xview', '-pickplace', _get_eval_enc_str(index)) + self + end + + def yview_pickplace(index) + tk_send_without_enc('yview', '-pickplace', _get_eval_enc_str(index)) + self + end + + def text_copy + # Tk8.4 feature + tk_call_without_enc('tk_textCopy', @path) + self + end + + def text_cut + # Tk8.4 feature + tk_call_without_enc('tk_textCut', @path) + self + end + + def text_paste + # Tk8.4 feature + tk_call_without_enc('tk_textPaste', @path) + self + end + + def tag_add(tag, index1, index2=None) + tk_send_without_enc('tag', 'add', _get_eval_enc_str(tag), + _get_eval_enc_str(index1), + _get_eval_enc_str(index2)) + self + end + alias addtag tag_add + alias add_tag tag_add + + def tag_delete(*tags) + tk_send_without_enc('tag', 'delete', + *(tags.collect{|tag| _get_eval_enc_str(tag)})) + if TkTextTag::TTagID_TBL[@path] + tags.each{|tag| + if tag.kind_of?(TkTextTag) + TkTextTag::TTagID_TBL[@path].delete(tag.id) + else + TkTextTag::TTagID_TBL[@path].delete(tag) + end + } + end + self + end + alias deltag tag_delete + alias delete_tag tag_delete + + #def tag_bind(tag, seq, cmd=Proc.new, *args) + # _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) + # self + #end + def tag_bind(tag, seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) + self + end + + #def tag_bind_append(tag, seq, cmd=Proc.new, *args) + # _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args) + # self + #end + def tag_bind_append(tag, seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args) + self + end + + def tag_bind_remove(tag, seq) + _bind_remove([@path, 'tag', 'bind', tag], seq) + self + end + + def tag_bindinfo(tag, context=nil) + _bindinfo([@path, 'tag', 'bind', tag], context) + end + +=begin + def tag_cget(tag, key) + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + tk_call_without_enc(@path, 'tag', 'cget', + _get_eval_enc_str(tag), "-#{key}") + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('tag','cget',_get_eval_enc_str(tag),'-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(tag, fnt) + end + if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@path,'tag','cget',_get_eval_enc_str(tag),"-#{key}"))) + end + end + + def tag_configure(tag, key, val=None) + if key.kind_of?(Hash) + key = _symbolkey2str(key) + if ( key['font'] || key['kanjifont'] \ + || key['latinfont'] || key['asciifont'] ) + tagfont_configure(tag, key) + else + tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), + *hash_kv(key, true)) + end + + else + if key == 'font' || key == :font || + key == 'kanjifont' || key == :kanjifont || + key == 'latinfont' || key == :latinfont || + key == 'asciifont' || key == :asciifont + if val == None + tagfontobj(tag) + else + tagfont_configure(tag, {key=>val}) + end + else + tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), + "-#{key}", _get_eval_enc_str(val)) + end + end + self + end + + def tag_configinfo(tag, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + conf[4] = tagfont_configinfo(tag, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(tag, fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + conf[4] = tagfont_configinfo(tag, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(tag, fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_tag_configinfo(tag, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = tag_configinfo(tag, key) + {conf[0] => conf[4]} + else + ret = {} + tag_configinfo(tag).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + tag_configinfo(tag, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +=end + + def tag_raise(tag, above=None) + tk_send_without_enc('tag', 'raise', _get_eval_enc_str(tag), + _get_eval_enc_str(above)) + self + end + + def tag_lower(tag, below=None) + tk_send_without_enc('tag', 'lower', _get_eval_enc_str(tag), + _get_eval_enc_str(below)) + self + end + + def tag_remove(tag, *indices) + tk_send_without_enc('tag', 'remove', _get_eval_enc_str(tag), + *(indices.collect{|idx| _get_eval_enc_str(idx)})) + self + end + + def tag_ranges(tag) + #l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges', + # _get_eval_enc_str(tag))) + l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges', + _get_eval_enc_str(tag)), + false, true) + r = [] + while key=l.shift + r.push [TkText::IndexString.new(key), TkText::IndexString.new(l.shift)] + end + r + end + + def tag_nextrange(tag, first, last=None) + simplelist(tk_send_without_enc('tag', 'nextrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + + def tag_prevrange(tag, first, last=None) + simplelist(tk_send_without_enc('tag', 'prevrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + +=begin + def window_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_send_without_enc('window', 'cget', + _get_eval_enc_str(index), "-#{slot}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(index, fnt) + end + if slot.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), "-#{slot}"))) + end + end + + def window_configure(index, slot, value=None) + if index.kind_of?(TkTextWindow) + index.configure(slot, value) + else + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + win = slot['window'] + # slot['window'] = win.epath if win.kind_of?(TkWindow) + slot['window'] = _epath(win) if win + if slot['create'] + p_create = slot['create'] + if p_create.kind_of?(Proc) +#=begin + slot['create'] = install_cmd(proc{ + id = p_create.call + if id.kind_of?(TkWindow) + id.epath + else + id + end + }) +#=end + slot['create'] = install_cmd(proc{_epath(p_create.call)}) + end + end + tk_send_without_enc('window', 'configure', + _get_eval_enc_str(index), + *hash_kv(slot, true)) + else + if slot == 'window' || slot == :window + # id = value + # value = id.epath if id.kind_of?(TkWindow) + value = _epath(value) + end + if slot == 'create' || slot == :create + p_create = value + if p_create.kind_of?(Proc) +#=begin + value = install_cmd(proc{ + id = p_create.call + if id.kind_of?(TkWindow) + id.epath + else + id + end + }) +#=end + value = install_cmd(proc{_epath(p_create.call)}) + end + end + tk_send_without_enc('window', 'configure', + _get_eval_enc_str(index), + "-#{slot}", _get_eval_enc_str(value)) + end + end + self + end + + def window_configinfo(win, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + else + conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + end + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + else + conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + + def current_window_configinfo(win, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + conf = window_configinfo(win, slot) + {conf[0] => conf[4]} + else + ret = {} + window_configinfo(win).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + window_configinfo(win, slot).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +=end + + def window_names + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('window', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('window', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def _ktext_length(txt) + if $KCODE !~ /n/i + return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length + end + + # $KCODE == 'NONE' + if JAPANIZED_TK + tk_call_without_enc('kstring', 'length', + _get_eval_enc_str(txt)).to_i + else + begin + tk_call_without_enc('encoding', 'convertto', 'ascii', + _get_eval_enc_str(txt)).length + rescue StandardError, NameError + # sorry, I have no plan + txt.length + end + end + end + private :_ktext_length + + def tksearch(*args) + # call 'search' subcommand of text widget + # args ::= [<array_of_opts>] <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + nocase = false + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| + s_opt = opt.to_s + nocase = true if s_opt == 'nocase' + '-' + s_opt + } + else + opts = [] + end + + if args[0].kind_of?(Regexp) + regexp = args.shift + if !nocase && (regexp.options & Regexp::IGNORECASE) != 0 + opts << '-nocase' + end + args.unshift(regexp.source) + end + + opts << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + TkText::IndexString.new(ret) + end + end + + def tksearch_with_count(*args) + # call 'search' subcommand of text widget + # args ::= [<array_of_opts>] <var> <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + nocase = false + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| + s_opt = opt.to_s + nocase = true if s_opt == 'nocase' + '-' + s_opt + } + else + opts = [] + end + + opts << '-count' << args.shift + + if args[0].kind_of?(Regexp) + regexp = args.shift + if !nocase && (regexp.options & Regexp::IGNORECASE) != 0 + opts << '-nocase' + end + args.unshift(regexp.source) + end + + opts << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + TkText::IndexString.new(ret) + end + end + + def search_with_length(pat,start,stop=None) + pat = pat.chr if pat.kind_of?(Integer) + if stop != None + return ["", 0] if compare(start,'>=',stop) + txt = get(start,stop) + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index(start + " + #{pos} chars"), pat.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index(start + " + #{pos} chars"), $&.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(match), match] + end + else + return ["", 0] + end + else + txt = get(start,'end - 1 char') + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index(start + " + #{pos} chars"), pat.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index(start + " + #{pos} chars"), $&.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(match), match] + end + else + txt = get('1.0','end - 1 char') + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + end + end + end + + def search(pat,start,stop=None) + search_with_length(pat,start,stop)[0] + end + + def rsearch_with_length(pat,start,stop=None) + pat = pat.chr if pat.kind_of?(Integer) + if stop != None + return ["", 0] if compare(start,'<=',stop) + txt = get(stop,start) + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index(stop + " + #{pos} chars"), pat.split('').length] + return [index(stop + " + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index(stop + " + #{pos} chars"), $&.split('').length] + return [index(stop + " + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + else + txt = get('1.0',start) + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + txt = get('1.0','end - 1 char') + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of?(String) + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + end + end + end + + def rsearch(pat,start,stop=None) + rsearch_with_length(pat,start,stop)[0] + end + + def dump(type_info, *index, &block) + if type_info.kind_of?(Symbol) + type_info = [ type_info.to_s ] + elsif type_info.kind_of?(String) + type_info = [ type_info ] + end + args = type_info.collect{|inf| '-' + inf} + args << '-command' << block if block + str = tk_send('dump', *(args + index)) + result = [] + sel = nil + i = 0 + while i < str.size + # retrieve key + idx = str.index(/ /, i) + result.push str[i..(idx-1)] + i = idx + 1 + + # retrieve value + case result[-1] + when 'text' + if str[i] == ?{ + # text formed as {...} + val, i = _retrieve_braced_text(str, i) + result.push val + else + # text which may contain backslahes + val, i = _retrieve_backslashed_text(str, i) + result.push val + end + else + idx = str.index(/ /, i) + val = str[i..(idx-1)] + case result[-1] + when 'mark' + case val + when 'insert' + result.push TkTextMarkInsert.new(self) + when 'current' + result.push TkTextMarkCurrent.new(self) + when 'anchor' + result.push TkTextMarkAnchor.new(self) + else + result.push tk_tcl2ruby(val) + end + when 'tagon' + if val == 'sel' + if sel + result.push sel + else + result.push TkTextTagSel.new(self) + end + else + result.push tk_tcl2ruby(val) + end + when 'tagoff' + result.push tk_tcl2ruby(val) + when 'window' + result.push tk_tcl2ruby(val) + when 'image' + result.push tk_tcl2ruby(val) + end + i = idx + 1 + end + + # retrieve index + idx = str.index(/ /, i) + if idx + result.push(TkText::IndexString.new(str[i..(idx-1)])) + i = idx + 1 + else + result.push(TkText::IndexString.new(str[i..-1])) + break + end + end + + kvis = [] + until result.empty? + kvis.push [result.shift, result.shift, result.shift] + end + kvis # result is [[key1, value1, index1], [key2, value2, index2], ...] + end + + def _retrieve_braced_text(str, i) + cnt = 0 + idx = i + while idx < str.size + case str[idx] + when ?{ + cnt += 1 + when ?} + cnt -= 1 + if cnt == 0 + break + end + end + idx += 1 + end + return str[i+1..idx-1], idx + 2 + end + private :_retrieve_braced_text + + def _retrieve_backslashed_text(str, i) + j = i + idx = nil + loop { + idx = str.index(/ /, j) + if str[idx-1] == ?\\ + j += 1 + else + break + end + } + val = str[i..(idx-1)] + val.gsub!(/\\( |\{|\})/, '\1') + return val, idx + 1 + end + private :_retrieve_backslashed_text + + def dump_all(*index, &block) + dump(['all'], *index, &block) + end + def dump_mark(*index, &block) + dump(['mark'], *index, &block) + end + def dump_tag(*index, &block) + dump(['tag'], *index, &block) + end + def dump_text(*index, &block) + dump(['text'], *index, &block) + end + def dump_window(*index, &block) + dump(['window'], *index, &block) + end + def dump_image(*index, &block) + dump(['image'], *index, &block) + end +end + +####################################### + +class TkText::Peer < TkText + # Tk8.5 feature + def initialize(text, parent=nil, keys={}) + unless text.kind_of?(TkText) + fail ArgumentError, "TkText is expected for 1st argument" + end + @src_text = text + super(parent, keys) + end + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(@src_text.path, 'peer', 'create', @path) + else + tk_call_without_enc(@src_text.path, 'peer', 'create', @path) + end + end + private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/textimage.rb b/ruby_1_8_6/ext/tk/lib/tk/textimage.rb new file mode 100644 index 0000000000..a29b23c7dd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/textimage.rb @@ -0,0 +1,82 @@ +# +# tk/textimage.rb - treat Tk text image object +# +require 'tk' +require 'tk/text' + +class TkTextImage<TkObject + include TkText::IndexModMethods + + def initialize(parent, index, keys) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @t = parent + if index == 'end' || index == :end + @path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars')) + elsif index.kind_of? TkTextMark + if tk_call_without_enc(@t.path,'index',index.path) == tk_call_without_enc(@t.path,'index','end') + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + 'end - 1 chars')) + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + index.path)) + end + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + _get_eval_enc_str(index))) + end + @path.gravity = 'left' + @index = @path.path + @id = tk_call_without_enc(@t.path, 'image', 'create', @index, + *hash_kv(keys, true)).freeze + @path.gravity = 'right' + end + + def id + TkText::IndexString.new(@id) + end + def mark + @path + end + + def [](slot) + cget(slot) + end + def []=(slot, value) + configure(slot, value) + value + end + + def cget(slot) + @t.image_cget(@index, slot) + end + + def configure(slot, value=None) + @t.image_configure(@index, slot, value) + self + end +# def configure(slot, value) +# tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value +# end + + def configinfo(slot = nil) + @t.image_configinfo(@index, slot) + end + + def current_configinfo(slot = nil) + @t.current_image_configinfo(@index, slot) + end + + def image + img = tk_call_without_enc(@t.path, 'image', 'cget', @index, '-image') + TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img + end + + def image=(value) + tk_call_without_enc(@t.path, 'image', 'configure', @index, '-image', + _get_eval_enc_str(value)) + #self + value + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/textmark.rb b/ruby_1_8_6/ext/tk/lib/tk/textmark.rb new file mode 100644 index 0000000000..650d95af70 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/textmark.rb @@ -0,0 +1,166 @@ +# +# tk/textmark.rb - methods for treating text marks +# +require 'tk' +require 'tk/text' + +class TkTextMark<TkObject + include TkText::IndexModMethods + + TMarkID_TBL = TkCore::INTERP.create_table + Tk_TextMark_ID = ['mark'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TMarkID_TBL.clear } + + def TkTextMark.id2obj(text, id) + tpath = text.path + return id unless TMarkID_TBL[tpath] + TMarkID_TBL[tpath][id]? TMarkID_TBL[tpath][id]: id + end + + def initialize(parent, index) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + # @path = @id = Tk_TextMark_ID.join('') + @path = @id = Tk_TextMark_ID.join(TkCore::INTERP._ip_id_).freeze + TMarkID_TBL[@id] = self + TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath] + TMarkID_TBL[@tpath][@id] = self + Tk_TextMark_ID[1].succ! + tk_call_without_enc(@t.path, 'mark', 'set', @id, + _get_eval_enc_str(index)) + @t._addtag id, self + end + + def id + TkText::IndexString.new(@id) + end + + def exist? + #if ( tk_split_simplelist(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'names'))).find{|id| id == @id } ) + if ( tk_split_simplelist(tk_call_without_enc(@t.path, 'mark', 'names'), false, true).find{|id| id == @id } ) + true + else + false + end + end + +=begin + # move to TkText::IndexModMethods module + def +(mod) + return chars(mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(@id + ' + ' + mod) + else + TkText::IndexString.new(@id + ' ' + mod) + end + end + + def -(mod) + return chars(-mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(@id + ' - ' + mod) + elsif mod =~ /^\s*[-]\s+(\d.*)$/ + TkText::IndexString.new(@id + ' - -' + $1) + else + TkText::IndexString.new(@id + ' ' + mod) + end + end +=end + + def pos + @t.index(@id) + end + + def pos=(where) + set(where) + end + + def set(where) + tk_call_without_enc(@t.path, 'mark', 'set', @id, + _get_eval_enc_str(where)) + self + end + + def unset + tk_call_without_enc(@t.path, 'mark', 'unset', @id) + self + end + alias destroy unset + + def gravity + tk_call_without_enc(@t.path, 'mark', 'gravity', @id) + end + + def gravity=(direction) + tk_call_without_enc(@t.path, 'mark', 'gravity', @id, direction) + #self + direction + end + + def next(index = nil) + if index + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', _get_eval_enc_str(index)))) + else + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', @id))) + end + end + + def previous(index = nil) + if index + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', _get_eval_enc_str(index)))) + else + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', @id))) + end + end +end + +class TkTextNamedMark<TkTextMark + def self.new(parent, name, *args) + if TMarkID_TBL[parent.path] && TMarkID_TBL[parent.path][name] + return TMarkID_TBL[parent.path][name] + else + super(parent, name, *args) + end + end + + def initialize(parent, name, index=nil) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + @path = @id = name + TMarkID_TBL[@id] = self + TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath] + TMarkID_TBL[@tpath][@id] = self unless TMarkID_TBL[@tpath][@id] + tk_call_without_enc(@t.path, 'mark', 'set', @id, + _get_eval_enc_str(index)) if index + @t._addtag id, self + end +end + +class TkTextMarkInsert<TkTextNamedMark + def self.new(parent,*args) + super(parent, 'insert', *args) + end +end + +class TkTextMarkCurrent<TkTextNamedMark + def self.new(parent,*args) + super(parent, 'current', *args) + end +end + +class TkTextMarkAnchor<TkTextNamedMark + def self.new(parent,*args) + super(parent, 'anchor', *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/texttag.rb b/ruby_1_8_6/ext/tk/lib/tk/texttag.rb new file mode 100644 index 0000000000..cc2c56210f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/texttag.rb @@ -0,0 +1,279 @@ +# +# tk/texttag.rb - methods for treating text tags +# +require 'tk' +require 'tk/text' +require 'tk/tagfont' + +class TkTextTag<TkObject + include TkTreatTagFont + include TkText::IndexModMethods + + TTagID_TBL = TkCore::INTERP.create_table + Tk_TextTag_ID = ['tag'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TTagID_TBL.clear } + + def TkTextTag.id2obj(text, id) + tpath = text.path + return id unless TTagID_TBL[tpath] + TTagID_TBL[tpath][id]? TTagID_TBL[tpath][id]: id + end + + def initialize(parent, *args) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + # @path = @id = Tk_TextTag_ID.join('') + @path = @id = Tk_TextTag_ID.join(TkCore::INTERP._ip_id_).freeze + # TTagID_TBL[@id] = self + TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath] + TTagID_TBL[@tpath][@id] = self + Tk_TextTag_ID[1].succ! + #tk_call @t.path, "tag", "configure", @id, *hash_kv(keys) + if args != [] + keys = args.pop + if keys.kind_of?(Hash) + add(*args) if args != [] + configure(keys) + else + args.push keys + add(*args) + end + end + @t._addtag id, self + end + + def id + TkText::IndexString.new(@id) + end + + def exist? + #if ( tk_split_simplelist(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'names'))).find{|id| id == @id } ) + if ( tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'names'), false, true).find{|id| id == @id } ) + true + else + false + end + end + + def first + TkText::IndexString.new(@id + '.first') + end + + def last + TkText::IndexString.new(@id + '.last') + end + + def add(*indices) + tk_call_without_enc(@t.path, 'tag', 'add', @id, + *(indices.collect{|idx| _get_eval_enc_str(idx)})) + self + end + + def remove(*indices) + tk_call_without_enc(@t.path, 'tag', 'remove', @id, + *(indices.collect{|idx| _get_eval_enc_str(idx)})) + self + end + + def ranges + l = tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'ranges', @id)) + r = [] + while key=l.shift + r.push [TkText::IndexString.new(key), TkText::IndexString.new(l.shift)] + end + r + end + + def nextrange(first, last=None) + simplelist(tk_call_without_enc(@t.path, 'tag', 'nextrange', @id, + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + + def prevrange(first, last=None) + simplelist(tk_call_without_enc(@t.path, 'tag', 'prevrange', @id, + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + + def [](key) + cget key + end + + def []=(key,val) + configure key, val + val + end + + def cget(key) + @t.tag_cget @id, key + end +=begin + def cget(key) + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', @id, "-#{key}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', + @id, '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(@id, fnt) + end + if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', + @id, "-#{key}"))) + end + end +=end + + def configure(key, val=None) + @t.tag_configure @id, key, val + end +# def configure(key, val=None) +# if key.kind_of?(Hash) +# tk_call @t.path, 'tag', 'configure', @id, *hash_kv(key) +# else +# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", val +# end +# end +# def configure(key, value) +# if value == FALSE +# value = "0" +# elsif value.kind_of?(Proc) +# value = install_cmd(value) +# end +# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", value +# end + + def configinfo(key=nil) + @t.tag_configinfo @id, key + end + + def current_configinfo(key=nil) + @t.current_tag_configinfo @id, key + end + + #def bind(seq, cmd=Proc.new, *args) + # _bind([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + # self + #end + def bind(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + self + end + + #def bind_append(seq, cmd=Proc.new, *args) + # _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + # self + #end + def bind_append(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + self + end + + def bind_remove(seq) + _bind_remove([@t.path, 'tag', 'bind', @id], seq) + self + end + + def bindinfo(context=nil) + _bindinfo([@t.path, 'tag', 'bind', @id], context) + end + + def raise(above=None) + tk_call_without_enc(@t.path, 'tag', 'raise', @id, + _get_eval_enc_str(above)) + self + end + + def lower(below=None) + tk_call_without_enc(@t.path, 'tag', 'lower', @id, + _get_eval_enc_str(below)) + self + end + + def destroy + tk_call_without_enc(@t.path, 'tag', 'delete', @id) + TTagID_TBL[@tpath].delete(@id) if TTagID_TBL[@tpath] + self + end +end + +class TkTextNamedTag<TkTextTag + def self.new(parent, name, *args) + if TTagID_TBL[parent.path] && TTagID_TBL[parent.path][name] + tagobj = TTagID_TBL[parent.path][name] + if args != [] + keys = args.pop + if keys.kind_of?(Hash) + tagobj.add(*args) if args != [] + tagobj.configure(keys) + else + args.push keys + tagobj.add(*args) + end + end + return tagobj + else + super(parent, name, *args) + end + end + + def initialize(parent, name, *args) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + @path = @id = name + TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath] + TTagID_TBL[@tpath][@id] = self unless TTagID_TBL[@tpath][@id] + #if mode + # tk_call @t.path, "addtag", @id, *args + #end + if args != [] + keys = args.pop + if keys.kind_of?(Hash) + add(*args) if args != [] + configure(keys) + else + args.push keys + add(*args) + end + end + @t._addtag id, self + end +end + +class TkTextTagSel<TkTextNamedTag + def self.new(parent, *args) + super(parent, 'sel', *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/textwindow.rb b/ruby_1_8_6/ext/tk/lib/tk/textwindow.rb new file mode 100644 index 0000000000..605c40addd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/textwindow.rb @@ -0,0 +1,149 @@ +# +# tk/textwindow.rb - treat Tk text window object +# +require 'tk' +require 'tk/text' + +class TkTextWindow<TkObject + include TkText::IndexModMethods + + def initialize(parent, index, keys = {}) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @t = parent + if index == 'end' || index == :end + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + 'end - 1 chars')) + elsif index.kind_of?(TkTextMark) + if tk_call_without_enc(@t.path,'index',index.path) == tk_call_without_enc(@t.path,'index','end') + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + 'end - 1 chars')) + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + index.path)) + end + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', _get_eval_enc_str(index))) + end + @path.gravity = 'left' + @index = @path.path + keys = _symbolkey2str(keys) + @id = keys['window'] + # keys['window'] = @id.epath if @id.kind_of?(TkWindow) + keys['window'] = _epath(@id) if @id + if keys['create'] + @p_create = keys['create'] + # if @p_create.kind_of?(Proc) + if TkComm._callback_entry?(@p_create) +=begin + keys['create'] = install_cmd(proc{ + @id = @p_create.call + if @id.kind_of?(TkWindow) + @id.epath + else + @id + end + }) +=end + keys['create'] = install_cmd(proc{@id = @p_create.call; _epath(@id)}) + end + end + tk_call_without_enc(@t.path, 'window', 'create', @index, + *hash_kv(keys, true)) + @path.gravity = 'right' + end + + def id + TkText::IndexString.new(_epath(@id)) + end + def mark + @path + end + + def [](slot) + cget(slot) + end + def []=(slot, value) + configure(slot, value) + value + end + + def cget(slot) + @t.window_cget(@index, slot) + end + + def configure(slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + if slot['window'] + @id = slot['window'] + # slot['window'] = @id.epath if @id.kind_of?(TkWindow) + slot['window'] = _epath(@id) if @id + end + if slot['create'] + self.create=slot.delete('create') + end + if slot.size > 0 + tk_call_without_enc(@t.path, 'window', 'configure', @index, + *hash_kv(slot, true)) + end + else + if slot == 'window' || slot == :window + @id = value + # value = @id.epath if @id.kind_of?(TkWindow) + value = _epath(@id) if @id + end + if slot == 'create' || slot == :create + self.create=value + else + tk_call_without_enc(@t.path, 'window', 'configure', @index, + "-#{slot}", _get_eval_enc_str(value)) + end + end + self + end + + def configinfo(slot = nil) + @t.window_configinfo(@index, slot) + end + + def current_configinfo(slot = nil) + @t.current_window_configinfo(@index, slot) + end + + def window + @id + end + + def window=(value) + @id = value + # value = @id.epath if @id.kind_of?(TkWindow) + value = _epath(@id) if @id + tk_call_without_enc(@t.path, 'window', 'configure', @index, + '-window', _get_eval_enc_str(value)) + value + end + + def create + @p_create + end + + def create=(value) + @p_create = value + # if @p_create.kind_of?(Proc) + if TkComm._callback_entry?(@p_create) + value = install_cmd(proc{ + @id = @p_create.call + if @id.kind_of?(TkWindow) + @id.epath + else + @id + end + }) + end + tk_call_without_enc(@t.path, 'window', 'configure', @index, + '-create', _get_eval_enc_str(value)) + value + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/timer.rb b/ruby_1_8_6/ext/tk/lib/tk/timer.rb new file mode 100644 index 0000000000..47f2b79350 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/timer.rb @@ -0,0 +1,634 @@ +# +# tk/timer.rb : methods for Tcl/Tk after command +# +# $Id$ +# +require 'tk' + +class TkTimer + include TkCore + extend TkCore + + TkCommandNames = ['after'.freeze].freeze + + Tk_CBID = ['a'.freeze, '00000'.taint].freeze + Tk_CBTBL = {}.taint + + TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL') + if {[set st [catch {eval {ruby_cmd TkTimer callback} $id} ret]] != 0} { + return -code $st $ret + } { + return $ret + } + EOL + + DEFAULT_IGNORE_EXCEPTIONS = [ NameError, RuntimeError ].freeze + + ############################### + # class methods + ############################### + def self.start(*args, &b) + self.new(*args, &b).start + end + + def self.callback(obj_id) + ex_obj = Tk_CBTBL[obj_id] + return "" if ex_obj == nil; # canceled + ex_obj.cb_call + end + + def self.info(obj = nil) + if obj + if obj.kind_of?(TkTimer) + if obj.after_id + inf = tk_split_list(tk_call_without_enc('after','info',obj.after_id)) + [Tk_CBTBL[inf[0][1]], inf[1]] + else + nil + end + else + fail ArgumentError, "TkTimer object is expected" + end + else + tk_call_without_enc('after', 'info').split(' ').collect!{|id| + ret = Tk_CBTBL.find{|key,val| val.after_id == id} + (ret == nil)? id: ret[1] + } + end + end + + + ############################### + # instance methods + ############################### + def do_callback + @in_callback = true + @after_id = nil + begin + @return_value = @current_proc.call(self) + rescue SystemExit + exit(0) + rescue Interrupt + exit!(1) + rescue Exception => e + if @cancel_on_exception && + @cancel_on_exception.find{|exc| e.kind_of?(exc)} + cancel + @return_value = e + @in_callback = false + return e + else + fail e + end + end + if @set_next + set_next_callback(@current_args) + else + @set_next = true + end + @in_callback = false + @return_value + end + + def set_callback(sleep, args=nil) + if TkCore::INTERP.deleted? + self.cancel + return self + end + @after_script = "rb_after #{@id}" + @after_id = tk_call_without_enc('after', sleep, @after_script) + @current_args = args + @current_script = [sleep, @after_script] + self + end + + def set_next_callback(args) + if @running == false || @proc_max == 0 || @do_loop == 0 + Tk_CBTBL.delete(@id) ;# for GC + @running = false + @wait_var.value = 0 + return + end + if @current_pos >= @proc_max + if @do_loop < 0 || (@do_loop -= 1) > 0 + @current_pos = 0 + else + Tk_CBTBL.delete(@id) ;# for GC + @running = false + @wait_var.value = 0 + return + end + end + + @current_args = args + + # if @sleep_time.kind_of?(Proc) + if TkComm._callback_entry?(@sleep_time) + sleep = @sleep_time.call(self) + else + sleep = @sleep_time + end + @current_sleep = sleep + + cmd, *cmd_args = @loop_proc[@current_pos] + @current_pos += 1 + @current_proc = cmd + + set_callback(sleep, cmd_args) + end + + def initialize(*args, &b) + # @id = Tk_CBID.join('') + @id = Tk_CBID.join(TkCore::INTERP._ip_id_) + Tk_CBID[1].succ! + + @wait_var = TkVariable.new(0) + + @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback)) + + @set_next = true + + @init_sleep = 0 + @init_proc = nil + @init_args = [] + + @current_script = [] + @current_proc = nil + @current_args = nil + @return_value = nil + + @sleep_time = 0 + @current_sleep = 0 + @loop_exec = 0 + @do_loop = 0 + @loop_proc = [] + @proc_max = 0 + @current_pos = 0 + + @after_id = nil + @after_script = nil + + @cancel_on_exception = DEFAULT_IGNORE_EXCEPTIONS + # Unless @cancel_on_exception, Ruby/Tk shows an error dialog box when + # an excepsion is raised on TkTimer callback procedure. + # If @cancel_on_exception is an array of exception classes and the raised + # exception is included in the array, Ruby/Tk cancels executing TkTimer + # callback procedures silently (TkTimer#cancel is called and no dialog is + # shown). + + if b + case args.size + when 0 + add_procs(b) + when 1 + args << -1 << b + else + args << b + end + end + + set_procs(*args) if args != [] + + @running = false + @in_callback = false + end + + attr :after_id + attr :after_script + attr :current_proc + attr :current_args + attr :current_sleep + alias :current_interval :current_sleep + attr :return_value + + attr_accessor :loop_exec + + def cb_call + @cb_cmd.call + end + + def get_procs + [@init_sleep, @init_proc, @init_args, @sleep_time, @loop_exec, @loop_proc] + end + + def current_status + [@running, @current_sleep, @current_proc, @current_args, + @do_loop, @cancel_on_exception] + end + + def cancel_on_exception? + @cancel_on_exception + end + + def cancel_on_exception=(mode) + if mode.kind_of?(Array) + @cancel_on_exception = mode + elsif mode + @cancel_on_exception = DEFAULT_IGNORE_EXCEPTIONS + else + @cancel_on_exception = false + end + #self + end + + def running? + @running + end + + def loop_rest + @do_loop + end + + def loop_rest=(rest) + @do_loop = rest + #self + end + + def set_interval(interval) + #if interval != 'idle' && interval != :idle \ + # && !interval.kind_of?(Integer) && !interval.kind_of?(Proc) + if interval != 'idle' && interval != :idle \ + && !interval.kind_of?(Integer) && !TkComm._callback_entry?(interval) + fail ArgumentError, "expect Integer or Proc" + end + @sleep_time = interval + end + + def set_procs(interval, loop_exec, *procs) + #if interval != 'idle' && interval != :idle \ + # && !interval.kind_of?(Integer) && !interval.kind_of?(Proc) + if interval != 'idle' && interval != :idle \ + && !interval.kind_of?(Integer) && !TkComm._callback_entry?(interval) + fail ArgumentError, "expect Integer or Proc for 1st argument" + end + @sleep_time = interval + + @loop_proc = [] + procs.each{|e| + # if e.kind_of?(Proc) + if TkComm._callback_entry?(e) + @loop_proc.push([e]) + else + @loop_proc.push(e) + end + } + @proc_max = @loop_proc.size + @current_pos = 0 + + if loop_exec.kind_of?(Integer) && loop_exec < 0 + @loop_exec = -1 + elsif loop_exec == true + @loop_exec = -1 + elsif loop_exec == nil || loop_exec == false || loop_exec == 0 + @loop_exec = 0 + else + if not loop_exec.kind_of?(Integer) + fail ArgumentError, "expect Integer for 2nd argument" + end + @loop_exec = loop_exec + end + @do_loop = @loop_exec + + self + end + + def add_procs(*procs) + procs.each{|e| + # if e.kind_of?(Proc) + if TkComm._callback_entry?(e) + @loop_proc.push([e]) + else + @loop_proc.push(e) + end + } + @proc_max = @loop_proc.size + + self + end + + def delete_procs(*procs) + procs.each{|e| + # if e.kind_of?(Proc) + if TkComm._callback_entry?(e) + @loop_proc.delete([e]) + else + @loop_proc.delete(e) + end + } + @proc_max = @loop_proc.size + + cancel if @proc_max == 0 + + self + end + + def delete_at(n) + @loop_proc.delete_at(n) + @proc_max = @loop_proc.size + cancel if @proc_max == 0 + self + end + + def set_start_proc(sleep=nil, init_proc=nil, *init_args, &b) + # set parameters for 'restart' + sleep = @init_sleep unless sleep + + if sleep != 'idle' && sleep != :idle && !sleep.kind_of?(Integer) + fail ArgumentError, "expect Integer or 'idle' for 1st argument" + end + + @init_sleep = sleep + @init_proc = init_proc + @init_args = init_args + + @init_proc = b if !@init_proc && b + @init_proc = proc{|*args| } if @init_sleep > 0 && !@init_proc + + self + end + + def start(*init_args, &b) + return nil if @running + + Tk_CBTBL[@id] = self + @do_loop = @loop_exec + @current_pos = 0 + @return_value = nil + @after_id = nil + + @init_sleep = 0 + @init_proc = nil + @init_args = nil + + argc = init_args.size + if argc > 0 + sleep = init_args.shift + if sleep != 'idle' && sleep != :idle && !sleep.kind_of?(Integer) + fail ArgumentError, "expect Integer or 'idle' for 1st argument" + end + @init_sleep = sleep + end + @init_proc = init_args.shift if argc > 1 + @init_args = init_args if argc > 2 + + @init_proc = b if !@init_proc && b + @init_proc = proc{|*args| } if @init_sleep > 0 && !@init_proc + + @current_sleep = @init_sleep + @running = true + if @init_proc + # if not @init_proc.kind_of?(Proc) + if !TkComm._callback_entry?(@init_proc) + fail ArgumentError, "Argument '#{@init_proc}' need to be Proc" + end + @current_proc = @init_proc + set_callback(@init_sleep, @init_args) + @set_next = false if @in_callback + else + set_next_callback(@init_args) + end + + self + end + + def reset(*reset_args) + restart() if @running + + if @init_proc + @return_value = @init_proc.call(self) + else + @return_value = nil + end + + @current_pos = 0 + @current_args = @init_args + @current_script = [] + + @set_next = false if @in_callback + + self + end + + def restart(*restart_args, &b) + cancel if @running + if restart_args == [] && !b + start(@init_sleep, @init_proc, *@init_args) + else + start(*restart_args, &b) + end + end + + def cancel + @running = false + @wait_var.value = 0 + tk_call 'after', 'cancel', @after_id if @after_id + @after_id = nil + + Tk_CBTBL.delete(@id) ;# for GC + self + end + alias stop cancel + + def continue(wait=nil) + fail RuntimeError, "is already running" if @running + return restart() if @current_script.empty? + sleep, cmd = @current_script + fail RuntimeError, "no procedure to continue" unless cmd + if wait + unless wait.kind_of?(Integer) + fail ArgumentError, "expect Integer for 1st argument" + end + sleep = wait + end + Tk_CBTBL[@id] = self + @running = true + @after_id = tk_call_without_enc('after', sleep, cmd) + self + end + + def skip + fail RuntimeError, "is not running now" unless @running + cancel + Tk_CBTBL[@id] = self + @running = true + set_next_callback(@current_args) + self + end + + def info + if @after_id + inf = tk_split_list(tk_call_without_enc('after', 'info', @after_id)) + [Tk_CBTBL[inf[0][1]], inf[1]] + else + nil + end + end + + def wait(on_thread = true, check_root = false) + if $SAFE >= 4 + fail SecurityError, "can't wait timer at $SAFE >= 4" + end + + unless @running + if @return_value.kind_of?(Exception) + fail @return_value + else + return @return_value + end + end + + @wait_var.wait(on_thread, check_root) + if @return_value.kind_of?(Exception) + fail @return_value + else + @return_value + end + end + def eventloop_wait(check_root = false) + wait(false, check_root) + end + def thread_wait(check_root = false) + wait(true, check_root) + end + def tkwait(on_thread = true) + wait(on_thread, true) + end + def eventloop_tkwait + wait(false, true) + end + def thread_tkwait + wait(true, true) + end +end + +TkAfter = TkTimer + + +class TkRTTimer < TkTimer + DEFAULT_OFFSET_LIST_SIZE = 5 + + def initialize(*args, &b) + super(*args, &b) + + @offset_list = Array.new(DEFAULT_OFFSET_LIST_SIZE){ [0, 0] } + @offset_s = 0 + @offset_u = 0 + @est_time = nil + end + + def start(*args, &b) + return nil if @running + @est_time = nil + @cb_start_time = Time.now + super(*args, &b) + end + + def cancel + super() + @est_time = nil + @cb_start_time = Time.now + self + end + alias stop cancel + + def continue(wait=nil) + fail RuntimeError, "is already running" if @running + @cb_start_time = Time.now + super(wait) + end + + def set_interval(interval) + super(interval) + @est_time = nil + end + + def _offset_ave + size = 0 + d_sec = 0; d_usec = 0 + @offset_list.each_with_index{|offset, idx| + # weight = 1 + weight = idx + 1 + size += weight + d_sec += offset[0] * weight + d_usec += offset[1] * weight + } + offset_s, mod = d_sec.divmod(size) + offset_u = ((mod * 1000000 + d_usec) / size.to_f).round + [offset_s, offset_u] + end + private :_offset_ave + + def set_next_callback(args) + if @running == false || @proc_max == 0 || @do_loop == 0 + Tk_CBTBL.delete(@id) ;# for GC + @running = false + @wait_var.value = 0 + return + end + if @current_pos >= @proc_max + if @do_loop < 0 || (@do_loop -= 1) > 0 + @current_pos = 0 + else + Tk_CBTBL.delete(@id) ;# for GC + @running = false + @wait_var.value = 0 + return + end + end + + @current_args = args + + cmd, *cmd_args = @loop_proc[@current_pos] + @current_pos += 1 + @current_proc = cmd + + @offset_s, @offset_u = _offset_ave + + if TkComm._callback_entry?(@sleep_time) + sleep = @sleep_time.call(self) + else + sleep = @sleep_time + end + + if @est_time + @est_time = Time.at(@est_time.to_i, @est_time.usec + sleep*1000) + else + @est_time = Time.at(@cb_start_time.to_i, + @cb_start_time.usec + sleep*1000) + end + + now = Time.now + real_sleep = ((@est_time.to_i - now.to_i + @offset_s)*1000.0 + + (@est_time.usec - now.usec + @offset_u)/1000.0).round + if real_sleep <= 0 + real_sleep = 0 + @offset_s = now.to_i + @offset_u = now.usec + end + @current_sleep = real_sleep + + set_callback(real_sleep, cmd_args) + end + + def cb_call + if @est_time + @offset_list.shift + + @cb_start_time = Time.now + + if @current_sleep == 0 + @offset_list.push([ + @offset_s - @cb_start_time.to_i, + @offset_u - @cb_start_time.usec + ]) + else + @offset_list.push([ + @offset_s + (@est_time.to_i - @cb_start_time.to_i), + @offset_u + (@est_time.usec - @cb_start_time.usec) + ]) + end + end + + @cb_cmd.call + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/toplevel.rb b/ruby_1_8_6/ext/tk/lib/tk/toplevel.rb new file mode 100644 index 0000000000..5e199e1330 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/toplevel.rb @@ -0,0 +1,257 @@ +# +# tk/toplevel.rb : treat toplevel widget +# +require 'tk' +require 'tk/wm' +require 'tk/menuspec' + +class TkToplevel<TkWindow + include Wm + include TkMenuSpec + + TkCommandNames = ['toplevel'.freeze].freeze + WidgetClassName = 'Toplevel'.freeze + WidgetClassNames[WidgetClassName] = self + +################# old version +# def initialize(parent=nil, screen=nil, classname=nil, keys=nil) +# if screen.kind_of? Hash +# keys = screen.dup +# else +# @screen = screen +# end +# @classname = classname +# if keys.kind_of? Hash +# keys = keys.dup +# @classname = keys.delete('classname') if keys.key?('classname') +# @colormap = keys.delete('colormap') if keys.key?('colormap') +# @container = keys.delete('container') if keys.key?('container') +# @screen = keys.delete('screen') if keys.key?('screen') +# @use = keys.delete('use') if keys.key?('use') +# @visual = keys.delete('visual') if keys.key?('visual') +# end +# super(parent, keys) +# end +# +# def create_self +# s = [] +# s << "-class" << @classname if @classname +# s << "-colormap" << @colormap if @colormap +# s << "-container" << @container if @container +# s << "-screen" << @screen if @screen +# s << "-use" << @use if @use +# s << "-visual" << @visual if @visual +# tk_call 'toplevel', @path, *s +# end +################# + + def __boolval_optkeys + super() << 'container' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'screen' + end + private :__strval_optkeys + + def __val2ruby_optkeys # { key=>proc, ... } + super().update('menu'=>proc{|v| window(v)}) + end + private :__val2ruby_optkeys + + def __methodcall_optkeys # { key=>method, ... } + TOPLEVEL_METHODCALL_OPTKEYS + end + private :__methodcall_optkeys + + def _wm_command_option_chk(keys) + keys = {} unless keys + new_keys = {} + wm_cmds = {} + + conf_methods = _symbolkey2str(__methodcall_optkeys()) + + keys.each{|k,v| + if conf_methods.key?(k) + wm_cmds[conf_methods[k]] = v + elsif Wm.method_defined?(k) + case k + when 'screen','class','colormap','container','use','visual' + new_keys[k] = v + else + case self.method(k).arity + when -1,1 + wm_cmds[k] = v + else + new_keys[k] = v + end + end + else + new_keys[k] = v + end + } + [new_keys, wm_cmds] + end + private :_wm_command_option_chk + + def initialize(parent=nil, screen=nil, classname=nil, keys=nil) + my_class_name = nil + if self.class < WidgetClassNames[WidgetClassName] + my_class_name = self.class.name + my_class_name = nil if my_class_name == '' + end + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + @classname = keys['class'] + @colormap = keys['colormap'] + @container = keys['container'] + @screen = keys['screen'] + @use = keys['use'] + @visual = keys['visual'] + if !@classname && my_class_name + keys['class'] = @classname = my_class_name + end + if @classname.kind_of? TkBindTag + @db_class = @classname + @classname = @classname.id + elsif @classname + @db_class = TkDatabaseClass.new(@classname) + else + @db_class = self.class + @classname = @db_class::WidgetClassName + end + keys, cmds = _wm_command_option_chk(keys) + super(keys) + cmds.each{|k,v| + if v.kind_of? Array + self.__send__(k,*v) + else + self.__send__(k,v) + end + } + return + end + + if screen.kind_of? Hash + keys = screen + else + @screen = screen + if classname.kind_of? Hash + keys = classname + else + @classname = classname + end + end + if keys.kind_of? Hash + keys = _symbolkey2str(keys) + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + @classname = keys['class'] unless @classname + @colormap = keys['colormap'] + @container = keys['container'] + @screen = keys['screen'] unless @screen + @use = keys['use'] + @visual = keys['visual'] + else + keys = {} + end + if !@classname && my_class_name + keys['class'] = @classname = my_class_name + end + if @classname.kind_of? TkBindTag + @db_class = @classname + @classname = @classname.id + elsif @classname + @db_class = TkDatabaseClass.new(@classname) + else + @db_class = self.class + @classname = @db_class::WidgetClassName + end + keys, cmds = _wm_command_option_chk(keys) + super(parent, keys) + cmds.each{|k,v| + if v.kind_of? Array + self.send(k,*v) + else + self.send(k,v) + end + } + end + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('toplevel', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('toplevel', @path) + # end + #end + #private :create_self + + def specific_class + @classname + end + + def add_menu(menu_info, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_info. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_info can override it. + if tearoff.kind_of?(Hash) + opts = tearoff + tearoff = false + end + _create_menubutton(self, menu_info, tearoff, opts) + end + + def add_menubar(menu_spec, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_spec. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_spec can override it. + menu_spec.each{|info| add_menu(info, tearoff, opts)} + self.menu + end + + def self.database_class + if self == WidgetClassNames[WidgetClassName] || self.name == '' + self + else + TkDatabaseClass.new(self.name) + end + end + def self.database_classname + self.database_class.name + end + + def self.bind(*args, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind(*args, &b) + end + end + def self.bind_append(*args, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind_append(*args, &b) + end + end + def self.bind_remove(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bind_remove(*args) + end + end + def self.bindinfo(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bindinfo(*args) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/txtwin_abst.rb b/ruby_1_8_6/ext/tk/lib/tk/txtwin_abst.rb new file mode 100644 index 0000000000..540f806d17 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/txtwin_abst.rb @@ -0,0 +1,39 @@ +# +# tk/txtwin_abst.rb : TkTextWin abstruct class +# +require 'tk' + +class TkTextWin<TkWindow + TkCommandNames = [].freeze + #def create_self + # fail RuntimeError, "TkTextWin is an abstract class" + #end + #private :create_self + + def bbox(index) + list(tk_send_without_enc('bbox', index)) + end + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + def get(*index) + _fromUTF8(tk_send_without_enc('get', *index)) + end + def insert(index, *args) + tk_send('insert', index, *args) + self + end + def scan_mark(x, y) + tk_send_without_enc('scan', 'mark', x, y) + self + end + def scan_dragto(x, y) + tk_send_without_enc('scan', 'dragto', x, y) + self + end + def see(index) + tk_send_without_enc('see', index) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/validation.rb b/ruby_1_8_6/ext/tk/lib/tk/validation.rb new file mode 100644 index 0000000000..0c5b5c61b9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/validation.rb @@ -0,0 +1,376 @@ +# +# tk/validation.rb - validation support module for entry, spinbox, and so on +# +require 'tk' + +module Tk + module ValidateConfigure + def self.__def_validcmd(scope, klass, keys=nil) + keys = klass._config_keys unless keys + keys.each{|key| + eval("def #{key}(*args, &b) + __validcmd_call(#{klass.name}, '#{key}', *args, &b) + end", scope) + } + end + + def __validcmd_call(klass, key, *args, &b) + return cget(key) if args.empty? && !b + + cmd = (b)? proc(&b) : args.shift + + if cmd.kind_of?(klass) + configure(key, cmd) + elsif !args.empty? + configure(key, [cmd, args]) + else + configure(key, cmd) + end + end + + def __validation_class_list + # maybe need to override + [] + end + + def __get_validate_key2class + k2c = {} + __validation_class_list.each{|klass| + klass._config_keys.each{|key| + k2c[key.to_s] = klass + } + } + k2c + end + + def __conv_vcmd_on_hash_kv(keys) + key2class = __get_validate_key2class + + keys = _symbolkey2str(keys) + key2class.each{|key, klass| + if keys[key].kind_of?(Array) + cmd, *args = keys[key] + keys[key] = klass.new(cmd, args.join(' ')) + # elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method) + elsif TkComm._callback_entry?(keys[key]) + keys[key] = klass.new(keys[key]) + end + } + keys + end + + def create_self(keys) + super(__conv_vcmd_on_hash_kv(keys)) + end + private :create_self + + def configure(slot, value=TkComm::None) + if slot.kind_of?(Hash) + super(__conv_vcmd_on_hash_kv(slot)) + else + super(__conv_vcmd_on_hash_kv(slot=>value)) + end + self + end +=begin + def configure(slot, value=TkComm::None) + key2class = __get_validate_key2class + + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + key2class.each{|key, klass| + if slot[key].kind_of?(Array) + cmd, *args = slot[key] + slot[key] = klass.new(cmd, args.join(' ')) + elsif slot[key].kind_of?(Proc) || slot[key].kind_of?(Method) + slot[key] = klass.new(slot[key]) + end + } + super(slot) + + else + slot = slot.to_s + if (klass = key2class[slot]) + if value.kind_of?(Array) + cmd, *args = value + value = klass.new(cmd, args.join(' ')) + elsif value.kind_of?(Proc) || value.kind_of?(Method) + value = klass.new(value) + end + end + super(slot, value) + end + + self + end +=end + end + + module ItemValidateConfigure + def self.__def_validcmd(scope, klass, keys=nil) + keys = klass._config_keys unless keys + keys.each{|key| + eval("def item_#{key}(id, *args, &b) + __item_validcmd_call(#{klass.name}, '#{key}', id, *args, &b) + end", scope) + } + end + + def __item_validcmd_call(tagOrId, klass, key, *args, &b) + return itemcget(tagid(tagOrId), key) if args.empty? && !b + + cmd = (b)? proc(&b) : args.shift + + if cmd.kind_of?(klass) + itemconfigure(tagid(tagOrId), key, cmd) + elsif !args.empty? + itemconfigure(tagid(tagOrId), key, [cmd, args]) + else + itemconfigure(tagid(tagOrId), key, cmd) + end + end + + def __item_validation_class_list(id) + # maybe need to override + [] + end + + def __get_item_validate_key2class(id) + k2c = {} + __item_validation_class_list(id).each{|klass| + klass._config_keys.each{|key| + k2c[key.to_s] = klass + } + } + end + + def __conv_item_vcmd_on_hash_kv(keys) + key2class = __get_item_validate_key2class(tagid(tagOrId)) + + keys = _symbolkey2str(keys) + key2class.each{|key, klass| + if keys[key].kind_of?(Array) + cmd, *args = keys[key] + keys[key] = klass.new(cmd, args.join(' ')) + # elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method) + elsif TkComm._callback_entry?(keys[key]) + keys[key] = klass.new(keys[key]) + end + } + keys + end + + def itemconfigure(tagOrId, slot, value=TkComm::None) + if slot.kind_of?(Hash) + super(__conv_item_vcmd_on_hash_kv(slot)) + else + super(__conv_item_vcmd_on_hash_kv(slot=>value)) + end + self + end +=begin + def itemconfigure(tagOrId, slot, value=TkComm::None) + key2class = __get_item_validate_key2class(tagid(tagOrId)) + + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + key2class.each{|key, klass| + if slot[key].kind_of?(Array) + cmd, *args = slot[key] + slot[key] = klass.new(cmd, args.join(' ')) + elsif slot[key].kind_of?(Proc) || slot[key].kind_of?(Method) + slot[key] = klass.new(slot[key]) + end + } + super(slot) + + else + slot = slot.to_s + if (klass = key2class[slot]) + if value.kind_of?(Array) + cmd, *args = value + value = klass.new(cmd, args.join(' ')) + elsif value.kind_of?(Proc) || value.kind_of?(Method) + value = klass.new(value) + end + end + super(slot, value) + end + + self + end +=end + end +end + +class TkValidateCommand + include TkComm + extend TkComm + + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?d, ?n, :action ], + [ ?i, ?x, :index ], + [ ?s, ?e, :current ], + [ ?v, ?s, :type ], + [ ?P, ?e, :value ], + [ ?S, ?e, :string ], + [ ?V, ?s, :triggered ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:number) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + + [ ?e, proc{|val| + #enc = Tk.encoding + enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system) + if enc + Tk.fromUTF8(TkComm::string(val), enc) + else + TkComm::string(val) + end + } + ], + + [ ?x, proc{|val| + idx = TkComm::number(val) + if idx < 0 + nil + else + idx + end + } + ], + + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + # + # NOTE: The order of parameters which passed to callback procedure is + # <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ... + # + + #def self._get_extra_args_tbl + # # return an array of convert procs + # [] + #end + + def self.ret_val(val) + (val)? '1': '0' + end + end + + ############################################### + + def self._config_keys + # array of config-option key (string or symbol) + ['vcmd', 'validatecommand', 'invcmd', 'invalidcommand'] + end + + def _initialize_for_cb_class(klass, cmd = Proc.new, *args) + extra_args_tbl = klass._get_extra_args_tbl + + if args.compact.size > 0 + args = args.join(' ') + keys = klass._get_subst_key(args) + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + @id = install_cmd(cmd) + else + @id = install_cmd(proc{|*arg| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + klass.ret_val(cmd.call( + *(ex_args.concat(klass.scan_args(keys, arg))) + )) + }) + ' ' + args + end + else + keys, args = klass._get_all_subst_keys + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + @id = install_cmd(cmd) + else + @id = install_cmd(proc{|*arg| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + klass.ret_val(cmd.call( + *(ex_args << klass.new(*klass.scan_args(keys, arg))) + )) + }) + ' ' + args + end + end + end + + def initialize(cmd = Proc.new, *args) + _initialize_for_cb_class(self.class::ValidateArgs, cmd, *args) + end + + def to_eval + @id + end +end + +module TkValidation + include Tk::ValidateConfigure + + class ValidateCmd < TkValidateCommand + module Action + Insert = 1 + Delete = 0 + Others = -1 + Focus = -1 + Forced = -1 + Textvariable = -1 + TextVariable = -1 + end + end + + ##################################### + + def __validation_class_list + super() << ValidateCmd + end + + Tk::ValidateConfigure.__def_validcmd(binding, ValidateCmd) + +=begin + def validatecommand(cmd = Proc.new, args = nil) + if cmd.kind_of?(ValidateCmd) + configure('validatecommand', cmd) + elsif args + configure('validatecommand', [cmd, args]) + else + configure('validatecommand', cmd) + end + end +=end +# def validatecommand(*args, &b) +# __validcmd_call(ValidateCmd, 'validatecommand', *args, &b) +# end +# alias vcmd validatecommand + +=begin + def invalidcommand(cmd = Proc.new, args = nil) + if cmd.kind_of?(ValidateCmd) + configure('invalidcommand', cmd) + elsif args + configure('invalidcommand', [cmd, args]) + else + configure('invalidcommand', cmd) + end + end +=end +# def invalidcommand(*args, &b) +# __validcmd_call(ValidateCmd, 'invalidcommand', *args, &b) +# end +# alias invcmd invalidcommand +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/variable.rb b/ruby_1_8_6/ext/tk/lib/tk/variable.rb new file mode 100644 index 0000000000..e5cacadc1a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/variable.rb @@ -0,0 +1,1651 @@ +# +# tk/variable.rb : treat Tk variable object +# +require 'tk' + +class TkVariable + include Tk + extend TkCore + + include Comparable + + #TkCommandNames = ['tkwait'.freeze].freeze + TkCommandNames = ['vwait'.freeze].freeze + + #TkVar_CB_TBL = {} + #TkVar_ID_TBL = {} + TkVar_CB_TBL = TkCore::INTERP.create_table + TkVar_ID_TBL = TkCore::INTERP.create_table + Tk_VARIABLE_ID = ["v".freeze, "00000".taint].freeze + + #TkCore::INTERP.add_tk_procs('rb_var', 'args', + # "ruby [format \"TkVariable.callback %%Q!%s!\" $args]") +TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') + if {[set st [catch {eval {ruby_cmd TkVariable callback} $args} ret]] != 0} { + set idx [string first "\n\n" $ret] + if {$idx > 0} { + global errorInfo + set tcl_backtrace $errorInfo + set errorInfo [string range $ret [expr $idx + 2] \ + [string length $ret]] + append errorInfo "\n" $tcl_backtrace + bgerror [string range $ret 0 [expr $idx - 1]] + } else { + bgerror $ret + } + return "" + #return -code $st $ret + } else { + return $ret + } + EOL + + #def TkVariable.callback(args) + def TkVariable.callback(id, name1, name2, op) + #name1,name2,op = tk_split_list(args) + #name1,name2,op = tk_split_simplelist(args) + if TkVar_CB_TBL[id] + #_get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op)) + begin + _get_eval_string(TkVar_CB_TBL[id].trace_callback(name2, op)) + rescue SystemExit + exit(0) + rescue Interrupt + exit!(1) + rescue Exception => e + begin + msg = _toUTF8(e.class.inspect) + ': ' + + _toUTF8(e.message) + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + _toUTF8(e.backtrace.join("\n")) + + "\n---< backtrace of Tk side >-------" + msg.instance_variable_set(:@encoding, 'utf-8') + rescue Exception + msg = e.class.inspect + ': ' + e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------" + end + fail(e, msg) + end +=begin + begin + raise 'check backtrace' + rescue + # ignore backtrace before 'callback' + pos = -($!.backtrace.size) + end + begin + _get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op)) + rescue + trace = $!.backtrace + raise $!, "\n#{trace[0]}: #{$!.message} (#{$!.class})\n" + + "\tfrom #{trace[1..pos].join("\n\tfrom ")}" + end +=end + else + '' + end + end + + def self.new_hash(val = {}) + if val.kind_of?(Hash) + self.new(val) + else + fail ArgumentError, 'Hash is expected' + end + end + + # + # default_value is available only when the variable is an assoc array. + # + def default_value(val=nil, &b) + if b + @def_default = :proc + @default_val = proc(&b) + else + @def_default = :val + @default_val = val + end + self + end + def set_default_value(val) + @def_default = :val + @default_val = val + self + end + alias default_value= set_default_value + def default_proc(cmd = Proc.new) + @def_default = :proc + @default_val = cmd + self + end + + def undef_default + @default_val = nil + @def_default = false + self + end + + def default_value_type + @type + end + def default_element_value_type(idxs) + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + @element_type[index] + end + + def _set_default_value_type_core(type, idxs) + if type.kind_of?(Class) + if type == NilClass + type = nil + elsif type == Numeric + type = :numeric + elsif type == TrueClass || type == FalseClass + type = :bool + elsif type == String + type = :string + elsif type == Symbol + type = :symbol + elsif type == Array + type = :list + elsif type <= TkVariable + type = :variable + elsif type <= TkWindow + type = :window + elsif TkComm._callback_entry_class?(type) + type = :procedure + else + type = nil + end + else + case(type) + when nil + type = nil + when :numeric, 'numeric' + type = :numeric + when true, false, :bool, 'bool' + type = :bool + when :string, 'string' + type = :string + when :symbol, 'symbol' + type = :symbol + when :list, 'list' + type = :list + when :numlist, 'numlist' + type = :numlist + when :variable, 'variable' + type = :variable + when :window, 'window' + type = :window + when :procedure, 'procedure' + type = :procedure + else + return _set_default_value_type_core(type.class, idxs) + end + end + if idxs + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + @element_type[index] = type + else + @type = type + end + type + end + private :_set_default_value_type_core + + def set_default_value_type(type) + _set_default_value_type_core(type, nil) + self + end + alias default_value_type= set_default_value_type + + def set_default_element_value_type(idxs, type) + _set_default_value_type_core(type, idxs) + self + end + + def _to_default_type(val, idxs = nil) + if idxs + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + type = @element_type[index] + else + type = @type + end + return val unless type + if val.kind_of?(Hash) + val.keys.each{|k| val[k] = _to_default_type(val[k], idxs) } + val + else + begin + case(type) + when :numeric + number(val) + when :bool + TkComm.bool(val) + when :string + val + when :symbol + val.intern + when :list + tk_split_simplelist(val) + when :numlist + tk_split_simplelist(val).collect!{|v| number(v)} + when :variable + TkVarAccess.new(val) + when :window + TkComm.window(val) + when :procedure + TkComm.procedure(val) + else + val + end + rescue + val + end + end + end + private :_to_default_type + + def _to_default_element_type(idxs, val) + _to_default_type(val, idxs) + end + private :_to_default_element_type + + def initialize(val="", type=nil) + # @id = Tk_VARIABLE_ID.join('') + begin + @id = Tk_VARIABLE_ID.join(TkCore::INTERP._ip_id_) + Tk_VARIABLE_ID[1].succ! + end until INTERP._invoke_without_enc('info', 'globals', @id).empty? + + TkVar_ID_TBL[@id] = self + + @var = @id + @elem = nil + + @def_default = false + @default_val = nil + + @trace_var = nil + @trace_elem = nil + @trace_opts = nil + + @type = nil + var = self + @element_type = Hash.new{|k,v| var.default_value_type } + + self.default_value_type = type + + # teach Tk-ip that @id is global var + INTERP._invoke_without_enc('global', @id) + #INTERP._invoke('global', @id) + + # create and init + if val.kind_of?(Hash) + # assoc-array variable + self[''] = 0 + self.clear + end + self.value = val + +=begin + if val == [] + # INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)', + # @id, @id, @id)) + elsif val.kind_of?(Array) + a = [] + # val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} + # s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' + val.each_with_index{|e,i| a.push(i); a.push(e)} + #s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + array2tk_list(a).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) + elsif val.kind_of?(Hash) + #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + # .gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + .gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) + else + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(format('global %s; set %s %s', @id, @id, s)) + end +=end +=begin + if val.kind_of?(Hash) + #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + # .gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + .gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; array set %s %s', @id, @id, s)) + else + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) + end +=end + end + + def wait(on_thread = false, check_root = false) + if $SAFE >= 4 + fail SecurityError, "can't wait variable at $SAFE >= 4" + end + on_thread &= (Thread.list.size != 1) + if on_thread + if check_root + INTERP._thread_tkwait('variable', @id) + else + INTERP._thread_vwait(@id) + end + else + if check_root + INTERP._invoke_without_enc('tkwait', 'variable', @id) + else + INTERP._invoke_without_enc('vwait', @id) + end + end + end + def eventloop_wait(check_root = false) + wait(false, check_root) + end + def thread_wait(check_root = false) + wait(true, check_root) + end + def tkwait(on_thread = true) + wait(on_thread, true) + end + def eventloop_tkwait + wait(false, true) + end + def thread_tkwait + wait(true, true) + end + + def id + @id + end + + def ref(*idxs) + # "#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})" + TkVarAccess.new("#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})") + end + + def is_hash? + #ITNERP._eval("global #{@id}; array exist #{@id}") == '1' + INTERP._invoke_without_enc('global', @id) + # INTERP._invoke_without_enc('array', 'exist', @id) == '1' + TkComm.bool(INTERP._invoke_without_enc('array', 'exist', @id)) + end + + def is_scalar? + ! is_hash? + end + + def exist?(*elems) + INTERP._invoke_without_enc('global', @id) + if elems.empty? + TkComm.bool(tk_call('info', 'exist', @id)) + else + # array + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + TkComm.bool(tk_call('info', 'exist', "#{@id}")) && + TkComm.bool(tk_call('info', 'exist', "#{@id}(#{index})")) + end + end + + def keys + if (is_scalar?) + fail RuntimeError, 'cannot get keys from a scalar variable' + end + #tk_split_simplelist(INTERP._eval("global #{@id}; array get #{@id}")) + INTERP._invoke_without_enc('global', @id) + #tk_split_simplelist(INTERP._fromUTF8(INTERP._invoke_without_enc('array', 'names', @id))) + tk_split_simplelist(INTERP._invoke_without_enc('array', 'names', @id), + false, true) + end + + def size + INTERP._invoke_without_enc('global', @id) + TkComm.number(INTERP._invoke_without_enc('array', 'size', @id)) + end + + def clear + if (is_scalar?) + fail RuntimeError, 'cannot clear a scalar variable' + end + keys.each{|k| unset(k)} + self + end + + def update(hash) + if (is_scalar?) + fail RuntimeError, 'cannot update a scalar variable' + end + hash.each{|k,v| self[k] = v} + self + end + +unless const_defined?(:USE_TCLs_SET_VARIABLE_FUNCTIONS) + USE_TCLs_SET_VARIABLE_FUNCTIONS = true +end + +if USE_TCLs_SET_VARIABLE_FUNCTIONS + ########################################################################### + # use Tcl function version of set tkvariable + ########################################################################### + + def _value + #if INTERP._eval("global #{@id}; array exist #{@id}") == '1' + INTERP._invoke_without_enc('global', @id) + # if INTERP._invoke('array', 'exist', @id) == '1' + if TkComm.bool(INTERP._invoke('array', 'exist', @id)) + #Hash[*tk_split_simplelist(INTERP._eval("global #{@id}; array get #{@id}"))] + Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', @id))] + else + _fromUTF8(INTERP._get_global_var(@id)) + end + end + + def value=(val) + val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable) + if val.kind_of?(Hash) + self.clear + val.each{|k, v| + #INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(k)), + # _toUTF8(_get_eval_string(v))) + INTERP._set_global_var2(@id, _get_eval_string(k, true), + _get_eval_string(v, true)) + } + self.value +# elsif val.kind_of?(Array) +=begin + INTERP._set_global_var(@id, '') + val.each{|v| + #INTERP._set_variable(@id, _toUTF8(_get_eval_string(v)), + INTERP._set_variable(@id, _get_eval_string(v, true), + TclTkLib::VarAccessFlag::GLOBAL_ONLY | + TclTkLib::VarAccessFlag::LEAVE_ERR_MSG | + TclTkLib::VarAccessFlag::APPEND_VALUE | + TclTkLib::VarAccessFlag::LIST_ELEMENT) + } + self.value +=end +# _fromUTF8(INTERP._set_global_var(@id, array2tk_list(val, true))) + else + #_fromUTF8(INTERP._set_global_var(@id, _toUTF8(_get_eval_string(val)))) + _fromUTF8(INTERP._set_global_var(@id, _get_eval_string(val, true))) + end + end + + def _element_value(*idxs) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + begin + _fromUTF8(INTERP._get_global_var2(@id, index)) + rescue => e + case @def_default + when :proc + @default_val.call(self, *idxs) + when :val + @default_val + else + fail e + end + end + #_fromUTF8(INTERP._get_global_var2(@id, index)) + #_fromUTF8(INTERP._get_global_var2(@id, _toUTF8(_get_eval_string(index)))) + #_fromUTF8(INTERP._get_global_var2(@id, _get_eval_string(index, true))) + end + + def []=(*args) + val = args.pop + type = default_element_value_type(args) + val = val._value if !type && type != :variable && val.kind_of?(TkVariable) + index = args.collect{|idx| _get_eval_string(idx, true)}.join(',') + _fromUTF8(INTERP._set_global_var2(@id, index, _get_eval_string(val, true))) + #_fromUTF8(INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(index)), + # _toUTF8(_get_eval_string(val)))) + #_fromUTF8(INTERP._set_global_var2(@id, _get_eval_string(index, true), + # _get_eval_string(val, true))) + end + + def unset(*elems) + if elems.empty? + INTERP._unset_global_var(@id) + else + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + INTERP._unset_global_var2(@id, index) + end + end + alias remove unset + +else + ########################################################################### + # use Ruby script version of set tkvariable (traditional methods) + ########################################################################### + + def _value + begin + INTERP._eval(Kernel.format('global %s; set %s', @id, @id)) + #INTERP._eval(Kernel.format('set %s', @id)) + #INTERP._invoke_without_enc('set', @id) + rescue + if INTERP._eval(Kernel.format('global %s; array exists %s', + @id, @id)) != "1" + #if INTERP._eval(Kernel.format('array exists %s', @id)) != "1" + #if INTERP._invoke_without_enc('array', 'exists', @id) != "1" + fail + else + Hash[*tk_split_simplelist(INTERP._eval(Kernel.format('global %s; array get %s', @id, @id)))] + #Hash[*tk_split_simplelist(_fromUTF8(INTERP._invoke_without_enc('array', 'get', @id)))] + end + end + end + + def value=(val) + val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable) + begin + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) + #INTERP._eval(Kernel.format('set %s %s', @id, s)) + #_fromUTF8(INTERP._invoke_without_enc('set', @id, _toUTF8(s))) + rescue + if INTERP._eval(Kernel.format('global %s; array exists %s', + @id, @id)) != "1" + #if INTERP._eval(Kernel.format('array exists %s', @id)) != "1" + #if INTERP._invoke_without_enc('array', 'exists', @id) != "1" + fail + else + if val == [] + INTERP._eval(Kernel.format('global %s; unset %s; set %s(0) 0; unset %s(0)', @id, @id, @id, @id)) + #INTERP._eval(Kernel.format('unset %s; set %s(0) 0; unset %s(0)', + # @id, @id, @id)) + #INTERP._invoke_without_enc('unset', @id) + #INTERP._invoke_without_enc('set', @id+'(0)', 0) + #INTERP._invoke_without_enc('unset', @id+'(0)') + elsif val.kind_of?(Array) + a = [] + val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e, true))} + #s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + a.join(" ").gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', + @id, @id, @id, s)) + #INTERP._eval(Kernel.format('unset %s; array set %s %s', + # @id, @id, s)) + #INTERP._invoke_without_enc('unset', @id) + #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s))) + elsif val.kind_of?(Hash) + #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + # .gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + val.to_a.collect{|e| array2tk_list(e, true)}.join(" ")\ + .gsub(/[\[\]$\\"]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', + @id, @id, @id, s)) + #INTERP._eval(Kernel.format('unset %s; array set %s %s', + # @id, @id, s)) + #INTERP._invoke_without_enc('unset', @id) + #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s))) + else + fail + end + end + end + end + + def _element_value(*idxs) + index = idxs.collect{|idx| _get_eval_string(idx)}.join(',') + begin + INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index)) + rescue => e + case @def_default + when :proc + @default_val.call(self, *idxs) + when :val + @default_val + else + fail e + end + end + #INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index)) + #INTERP._eval(Kernel.format('global %s; set %s(%s)', + # @id, @id, _get_eval_string(index))) + #INTERP._eval(Kernel.format('set %s(%s)', @id, _get_eval_string(index))) + #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ')') + end + + def []=(*args) + val = args.pop + type = default_element_value_type(args) + val = val._value if !type && type != :variable && val.kind_of?(TkVariable) + index = args.collect{|idx| _get_eval_string(idx)}.join(',') + INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, + index, _get_eval_string(val))) + #INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, + # _get_eval_string(index), _get_eval_string(val))) + #INTERP._eval(Kernel.format('set %s(%s) %s', @id, + # _get_eval_string(index), _get_eval_string(val))) + #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ') ' + + # _get_eval_string(val)) + end + + def unset(*elems) + if elems.empty? + INTERP._eval(Kernel.format('global %s; unset %s', @id, @id)) + #INTERP._eval(Kernel.format('unset %s', @id)) + #INTERP._eval('unset ' + @id) + else + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + INTERP._eval(Kernel.format('global %s; unset %s(%s)', @id, @id, index)) + #INTERP._eval(Kernel.format('global %s; unset %s(%s)', + # @id, @id, _get_eval_string(elem))) + #INTERP._eval(Kernel.format('unset %s(%s)', @id, tk_tcl2ruby(elem))) + #INTERP._eval('unset ' + @id + '(' + _get_eval_string(elem) + ')') + end + end + alias remove unset + +end + + protected :_value, :_element_value + + def value + _to_default_type(_value) + end + + def [](*idxs) + _to_default_element_type(idxs, _element_value(*idxs)) + end + + def set_value(val) + self.value = val + self + end + + def set_element_value(idxs, val) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + + def set_value_type(val) + self.default_value_type = val.class + self.value = val + self + end + + alias value_type= set_value_type + + def set_element_value_type(idxs, val) + self.set_default_element_value_type(idxs, val.class) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + + def numeric + number(_value) + end + def numeric_element(*idxs) + number(_element_value(*idxs)) + end + def set_numeric(val) + case val + when Numeric + self.value=(val) + when TkVariable + self.value=(val.numeric) + else + raise ArgumentError, "Numeric is expected" + end + self + end + alias numeric= set_numeric + def set_numeric_element(idxs, val) + case val + when Numeric + val + when TkVariable + val = val.numeric + else + raise ArgumentError, "Numeric is expected" + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_numeric_type(val) + @type = :numeric + self.numeric=(val) + self + end + alias numeric_type= set_numeric_type + def set_numeric_element_type(idxs, val) + self.set_default_element_value_type(idxs, :numeric) + self.set_numeric_element(idxs, val) + end + + def bool + TkComm.bool(_value) +=begin + # see Tcl_GetBoolean man-page + case _value.downcase + when '0', 'false', 'no', 'off' + false + else + true + end +=end + end + def bool_element(*idxs) + TkComm.bool(_element_value(*idxs)) + end + def set_bool(val) + if ! val + self.value = '0' + else + case val.to_s.downcase + when 'false', '0', 'no', 'off' + self.value = '0' + else + self.value = '1' + end + end + self + end + alias bool= set_bool + def set_bool_element(idxs, val) + if ! val + val = '0' + else + case val.to_s.downcase + when 'false', '0', 'no', 'off' + val = '0' + else + val = '1' + end + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_bool_type(val) + @type = :bool + self.bool=(val) + self + end + alias bool_type= set_bool_type + def set_bool_element_type(idxs, val) + self.set_default_element_value_type(idxs, :bool) + self.set_bool_element(idxs, val) + end + + def variable + # keeps a Tcl's variable name + TkVarAccess.new(self._value) + end + def variable_element(*idxs) + TkVarAccess.new(_element_value(*idxs)) + end + def set_variable(var) + var = var.id if var.kind_of?(TkVariable) + self.value = var + self + end + alias variable= set_variable + def set_variable_element(idxs, var) + var = var.id if var.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=var + else + self[idxs]=var + end + self + end + def set_variable_type(var) + @type = :variable + var = var.id if var.kind_of?(TkVariable) + self.value = var + self + end + alias variable_type= set_variable_type + def set_variable_element_type(idxs, var) + self.set_default_element_value_type(idxs, :variable) + self.set_variable_element(idxs, var) + end + + def window + TkComm.window(self._value) + end + def window_element(*idxs) + TkComm.window(_element_value(*idxs)) + end + def set_window(win) + win = win._value if win.kind_of?(TkVariable) + self.value = win + self + end + alias window= set_window + def set_window_element(idxs, win) + win = win._value if win.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=win + else + self[idxs]=win + end + self + end + def set_window_type(win) + @type = :window + self.window=(win) + self + end + alias window_type= set_window_type + def set_window_element_type(idxs, win) + self.set_default_element_value_type(idxs, :window) + self.set_window_element(idxs, win) + end + + def procedure + TkComm.procedure(self._value) + end + def procedure_element(*idxs) + TkComm.procedure(_element_value(*idxs)) + end + def set_procedure(cmd) + self.value = cmd + self + end + alias procedure= set_procedure + def set_procedure_element(idxs, cmd) + cmd = cmd._value if cmd.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=cmd + else + self[idxs]=cmd + end + self + end + def set_procedure_type(cmd) + @type = :procedure + self.procedure=(cmd) + self + end + alias procedure_type= set_procedure_type + def set_procedure_element_type(idxs, cmd) + self.set_default_element_value_type(idxs, :procedure) + self.set_proceure_element(idxs, cmd) + end + + def to_i + number(_value).to_i + end + def element_to_i(*idxs) + number(_element_value(*idxs)).to_i + end + + def to_f + number(_value).to_f + end + def element_to_f(*idxs) + number(_element_value(*idxs)).to_f + end + + def to_s + #string(value).to_s + _value + end + alias string to_s + def element_to_s(*idxs) + _element_value(*idxs) + end + def string_element(*idxs) + _element_value(*idxs) + end + def set_string(val) + val = val._value if val.kind_of?(TkVariable) + self.value=val + self + end + alias string= set_string + def set_string_element(idxs, val) + val = val._value if val.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_string_type(val) + @type = :string + self.string=(val) + self + end + alias string_type= set_string_type + def set_string_element_type(idxs, val) + self.set_default_element_value_type(idxs, :string) + self.set_string_element(idxs, val) + end + + def to_sym + _value.intern + end + alias symbol to_sym + def element_to_sym(*idxs) + _element_value(*idxs).intern + end + alias symbol_element element_to_sym + def set_symbol(val) + val = val._value if val.kind_of?(TkVariable) + self.value=val + self + end + alias symbol= set_symbol + def set_symbol_element(idxs, val) + val = val._value if val.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_symbol_type(val) + @type = :symbol + self.value=(val) + self + end + alias symbol_type= set_symbol_type + def set_symbol_element_type(idxs, val) + self.set_default_element_value_type(idxs, :symbol) + self.set_symbol_element(idxs, val) + end + + def list + #tk_split_list(value) + tk_split_simplelist(_value) + end + alias to_a list + def list_element(*idxs) + tk_split_simplelist(_element_value(*idxs)) + end + alias element_to_a list_element + + def numlist + list.collect!{|val| number(val)} + end + def numlist_element(*idxs) + list_element(*idxs).collect!{|val| number(val)} + end + + def set_list(val) + case val + when Array + self.value=(val) + when TkVariable + self.value=(val.list) + else + raise ArgumentError, "Array is expected" + end + self + end + alias list= set_list + + alias set_numlist set_list + alias numlist= set_numlist + + def set_list_element(idxs, val) + case val + when Array + val + when TkVariable + val = val.list + else + raise ArgumentError, "Array is expected" + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + alias set_numlist_element set_list_element + + def set_list_type(val) + @type = :list + self.list=(val) + self + end + alias list_type= set_list_type + def set_list_element_type(idxs, val) + self.set_default_element_value_type(idxs, :list) + self.set_list_element(idxs, val) + end + def set_numlist_type(val) + @type = :numlist + self.numlist=(val) + self + end + alias numlist_type= set_numlist_type + def set_numlist_element_type(idxs, val) + self.set_default_element_value_type(idxs, :numlist) + self.set_numlist_element(idxs, val) + end + + def lappend(*elems) + tk_call('lappend', @id, *elems) + self + end + def element_lappend(idxs, *elems) + if idxs.kind_of?(Array) + idxs = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + end + tk_call('lappend', "#{@id}(#{idxs})", *elems) + self + end + + def lindex(idx) + tk_call('lindex', self._value, idx) + end + alias lget lindex + def element_lindex(elem_idxs, idx) + if elem_idxs.kind_of?(Array) + val = _element_value(*elem_idxs) + else + val = _element_value(elem_idxs) + end + tk_call('lindex', val, idx) + end + alias element_lget element_lindex + + def lget_i(idx) + number(lget(idx)).to_i + end + def element_lget_i(elem_idxs, idx) + number(element_lget(elem_idxs, idx)).to_i + end + + def lget_f(idx) + number(lget(idx)).to_f + end + def element_lget_f(elem_idxs, idx) + number(element_lget(elem_idxs, idx)).to_f + end + + def lset(idx, val) + tk_call('lset', @id, idx, val) + self + end + def element_lset(elem_idxs, idx, val) + if elem_idxs.kind_of?(Array) + idxs = elem_idxs.collect{|i| _get_eval_string(i, true)}.join(',') + end + tk_call('lset', "#{@id}(#{idxs})", idx, val) + self + end + + def inspect + #Kernel.format "#<TkVariable: %s>", @id + '#<TkVariable: ' + @id + '>' + end + + def coerce(other) + case other + when TkVariable + [other._value, self._value] + when String + [other, self.to_s] + when Symbol + [other, self.to_sym] + when Integer + [other, self.to_i] + when Float + [other, self.to_f] + when Array + [other, self.to_a] + else + [other, self._value] + end + end + + def &(other) + if other.kind_of?(Array) + self.to_a & other.to_a + else + self.to_i & other.to_i + end + end + def |(other) + if other.kind_of?(Array) + self.to_a | other.to_a + else + self.to_i | other.to_i + end + end + def +(other) + case other + when Array + self.to_a + other + when String + self._value + other + else + begin + number(self._value) + other + rescue + self._value + other.to_s + end + end + end + def -(other) + if other.kind_of?(Array) + self.to_a - other + else + number(self._value) - other + end + end + def *(other) + num_or_str(self._value) * other.to_i + #begin + # number(self._value) * other + #rescue + # self._value * other + #end + end + def /(other) + number(self._value) / other + end + def %(other) + num_or_str(self._value) % other.to_i + #begin + # number(self._value) % other + #rescue + # self._value % other + #end + end + def **(other) + number(self._value) ** other + end + def =~(other) + self._value =~ other + end + + def ==(other) + case other + when TkVariable + #self.equal?(other) + self._value == other._value + when String + self.to_s == other + when Symbol + self.to_sym == other + when Integer + self.to_i == other + when Float + self.to_f == other + when Array + self.to_a == other + when Hash + # false if self is not an assoc array + self._value == other + else + # false + self._value == _get_eval_string(other) + end + end + + def zero? + numeric.zero? + end + def nonzero? + !(numeric.zero?) + end + + def <=>(other) + if other.kind_of?(TkVariable) + begin + val = other.numeric + other = val + rescue + other = other._value + end + elsif other.kind_of?(Numeric) + begin + return self.numeric <=> other + rescue + return self._value <=> other.to_s + end + elsif other.kind_of?(Array) + return self.list <=> other + else + return self._value <=> other + end + end + + def to_eval + @id + end + + def trace_callback(elem, op) + if @trace_var.kind_of? Array + @trace_var.each{|m,e| e.call(self,elem,op) if m.index(op)} + end + if elem.kind_of?(String) && elem != '' + if @trace_elem.kind_of?(Hash) && @trace_elem[elem].kind_of?(Array) + @trace_elem[elem].each{|m,e| e.call(self,elem,op) if m.index(op)} + end + end + end + + def trace(opts, cmd = Proc.new) + @trace_var = [] if @trace_var == nil + #opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + opts = opts.to_s + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + @trace_var.unshift([opts,cmd]) + if @trace_opts == nil + TkVar_CB_TBL[@id] = self + @trace_opts = opts.dup + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') + end +=end + else + newopts = @trace_opts.dup + #opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} + opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, + 'rb_var ' << @id) + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + end + end + self + end + + def trace_element(elem, opts, cmd = Proc.new) + if @elem + fail(RuntimeError, + "invalid for a TkVariable which denotes an element of Tcl's array") + end + @trace_elem = {} if @trace_elem == nil + @trace_elem[elem] = [] if @trace_elem[elem] == nil + opts = opts.to_s + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + @trace_elem[elem].unshift([opts,cmd]) + if @trace_opts == nil + TkVar_CB_TBL[@id] = self + @trace_opts = opts.dup + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + else + newopts = @trace_opts.dup + # opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} + opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, + 'rb_var ' << @id) + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + end + end + self + end + + def trace_vinfo + return [] unless @trace_var + @trace_var.dup + end + + def _trace_vinfo_for_element(elem) + if @elem + fail(RuntimeError, + "invalid for a TkVariable which denotes an element of Tcl's array") + end + return [] unless @trace_elem + return [] unless @trace_elem[elem] + @trace_elem[elem].dup + end + + def trace_vdelete(opts,cmd) + return self unless @trace_var.kind_of? Array + opts = opts.to_s + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + idx = -1 + newopts = '' + @trace_var.each_with_index{|e,i| + if idx < 0 && e[0] == opts && e[1] == cmd + idx = i + next + end + # e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + } + if idx >= 0 + @trace_var.delete_at(idx) + else + return self + end + + @trace_elem.each{|elem| + @trace_elem[elem].each{|e| + # e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + } + } + + newopts = newopts.to_s + newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + end +=end + @trace_opts.replace(newopts) + if @trace_opts != '' + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + end + end + + self + end + + def trace_vdelete_for_element(elem,opts,cmd) + if @elem + fail(RuntimeError, + "invalid for a TkVariable which denotes an element of Tcl's array") + end + return self unless @trace_elem.kind_of? Hash + return self unless @trace_elem[elem].kind_of? Array + opts = opts.to_s + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + idx = -1 + @trace_elem[elem].each_with_index{|e,i| + if idx < 0 && e[0] == opts && e[1] == cmd + idx = i + next + end + } + if idx >= 0 + @trace_elem[elem].delete_at(idx) + else + return self + end + + newopts = '' + @trace_var.each{|e| + # e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + } + @trace_elem.each{|elem| + @trace_elem[elem].each{|e| + # e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + } + } + + newopts = newopts.to_s + newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + end +=end + @trace_opts.replace(newopts) + if @trace_opts != '' + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', @id, + @trace_opts, 'rb_var') + end +=end + end + end + + self + end +end + +class TkVarAccess<TkVariable + def self.new(name, *args) + if name.kind_of?(TkVariable) + name.value = args[0] unless args.empty? + return name + end + + if v = TkVar_ID_TBL[name] + v.value = args[0] unless args.empty? + return v + end + + super(name, *args) + end + + def self.new_hash(name, *args) + if name.kind_of?(TkVariable) + unless name.is_hash? + fail ArgumentError, "already exist as a scalar variable" + end + name.value = args[0] unless args.empty? + return name + end + + if v = TkVar_ID_TBL[name] + unless v.is_hash? + fail ArgumentError, "already exist as a scalar variable" + end + v.value = args[0] unless args.empty? + return v + end + + INTERP._invoke_without_enc('global', name) + if args.empty? && INTERP._invoke_without_enc('array', 'exist', name) == '0' + self.new(name, {}) # force creating + else + self.new(name, *args) + end + end + + def initialize(varname, val=nil) + @id = varname + TkVar_ID_TBL[@id] = self + + @var = @id + @elem = nil + + @def_default = false + @default_val = nil + + @trace_var = nil + @trace_elem = nil + @trace_opts = nil + + @type = nil + var = self + @element_type = Hash.new{|k,v| var.default_value_type } + + # is an element? + if @id =~ /^([^(]+)\((.+)\)$/ + # is an element --> var == $1, elem == $2 + @var = $1 + @elem = $2 + end + + # teach Tk-ip that @id is global var + INTERP._invoke_without_enc('global', @var) +=begin + begin + INTERP._invoke_without_enc('global', @id) + rescue => e + if @id =~ /^(.+)\([^()]+\)$/ + # is an element --> varname == $1 + INTERP._invoke_without_enc('global', $1) + else + fail e + end + end +=end + + if val + if val.kind_of?(Hash) + # assoc-array variable + self[''] = 0 + self.clear + end + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #" + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' #" + #INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) + #INTERP._set_global_var(@id, _toUTF8(_get_eval_string(val))) + self.value = val + end + end +end + +module Tk + begin + INTERP._invoke_without_enc('global', 'auto_path') + auto_path = INTERP._invoke('set', 'auto_path') + rescue => e + begin + INTERP._invoke_without_enc('global', 'env') + auto_path = INTERP._invoke('set', 'env(TCLLIBPATH)') + rescue => e + auto_path = Tk::LIBRARY + end + end + + AUTO_PATH = TkVarAccess.new('auto_path', auto_path) + +=begin + AUTO_OLDPATH = tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath')) + AUTO_OLDPATH.each{|s| s.freeze} + AUTO_OLDPATH.freeze +=end + + TCL_PACKAGE_PATH = TkVarAccess.new('tcl_pkgPath') + PACKAGE_PATH = TCL_PACKAGE_PATH + + TCL_LIBRARY_PATH = TkVarAccess.new('tcl_libPath') + LIBRARY_PATH = TCL_LIBRARY_PATH + + TCL_PRECISION = TkVarAccess.new('tcl_precision') +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/virtevent.rb b/ruby_1_8_6/ext/tk/lib/tk/virtevent.rb new file mode 100644 index 0000000000..d47e80aecd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/virtevent.rb @@ -0,0 +1,106 @@ +# +# tk/virtevent.rb : treats virtual events +# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +require 'tk' + +class TkVirtualEvent<TkObject + extend Tk + + TkCommandNames = ['event'.freeze].freeze + + TkVirtualEventID = ["VirtEvent".freeze, "00000".taint].freeze + TkVirtualEventTBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ TkVirtualEventTBL.clear } + + class PreDefVirtEvent<self + def self.new(event, *sequences) + if event =~ /^<(<.*>)>$/ + event = $1 + elsif event !~ /^<.*>$/ + event = '<' + event + '>' + end + if TkVirtualEvent::TkVirtualEventTBL.has_key?(event) + TkVirtualEvent::TkVirtualEventTBL[event] + else + super(event, *sequences) + end + end + + def initialize(event, *sequences) + @path = @id = event + TkVirtualEvent::TkVirtualEventTBL[@id] = self + add(*sequences) + end + end + + def TkVirtualEvent.getobj(event) + obj = TkVirtualEventTBL[event] + if obj + obj + else + if tk_call_without_enc('event', 'info').index("<#{event}>") + PreDefVirtEvent.new(event) + else + fail ArgumentError, "undefined virtual event '<#{event}>'" + end + end + end + + def TkVirtualEvent.info + tk_call_without_enc('event', 'info').split(/\s+/).collect!{|seq| + TkVirtualEvent.getobj(seq[1..-2]) + } + end + + def initialize(*sequences) + # @path = @id = '<' + TkVirtualEventID.join('') + '>' + @path = @id = '<' + TkVirtualEventID.join(TkCore::INTERP._ip_id_) + '>' + TkVirtualEventID[1].succ! + add(*sequences) + end + + def add(*sequences) + if sequences != [] + tk_call_without_enc('event', 'add', "<#{@id}>", + *(sequences.collect{|seq| + "<#{tk_event_sequence(seq)}>" + }) ) + TkVirtualEventTBL[@id] = self + end + self + end + + def delete(*sequences) + if sequences == [] + tk_call_without_enc('event', 'delete', "<#{@id}>") + TkVirtualEventTBL.delete(@id) + else + tk_call_without_enc('event', 'delete', "<#{@id}>", + *(sequences.collect{|seq| + "<#{tk_event_sequence(seq)}>" + }) ) + TkVirtualEventTBL.delete(@id) if info == [] + end + self + end + + def info + tk_call_without_enc('event','info',"<#{@id}>").split(/\s+/).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 + +TkNamedVirtualEvent = TkVirtualEvent::PreDefVirtEvent diff --git a/ruby_1_8_6/ext/tk/lib/tk/winfo.rb b/ruby_1_8_6/ext/tk/lib/tk/winfo.rb new file mode 100644 index 0000000000..c649b4a0c9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/winfo.rb @@ -0,0 +1,392 @@ +# +# tk/winfo.rb : methods for winfo command +# +module TkWinfo +end + +require 'tk' + +module TkWinfo + include Tk + extend Tk + + TkCommandNames = ['winfo'.freeze].freeze + + def TkWinfo.atom(name, win=nil) + if win + number(tk_call_without_enc('winfo', 'atom', '-displayof', win, + _get_eval_enc_str(name))) + else + number(tk_call_without_enc('winfo', 'atom', _get_eval_enc_str(name))) + end + end + def winfo_atom(name) + TkWinfo.atom(name, self) + end + + def TkWinfo.atomname(id, win=nil) + if win + _fromUTF8(tk_call_without_enc('winfo', 'atomname', + '-displayof', win, id)) + else + _fromUTF8(tk_call_without_enc('winfo', 'atomname', id)) + end + end + def winfo_atomname(id) + TkWinfo.atomname(id, self) + end + + def TkWinfo.cells(win) + number(tk_call_without_enc('winfo', 'cells', win)) + end + def winfo_cells + TkWinfo.cells self + end + + def TkWinfo.children(win) + list(tk_call_without_enc('winfo', 'children', win)) + end + def winfo_children + TkWinfo.children self + end + + def TkWinfo.classname(win) + tk_call_without_enc('winfo', 'class', win) + end + def winfo_classname + TkWinfo.classname self + end + alias winfo_class winfo_classname + + def TkWinfo.colormapfull(win) + bool(tk_call_without_enc('winfo', 'colormapfull', win)) + end + def winfo_colormapfull + TkWinfo.colormapfull self + end + + def TkWinfo.containing(rootX, rootY, win=nil) + if win + window(tk_call_without_enc('winfo', 'containing', + '-displayof', win, rootX, rootY)) + else + window(tk_call_without_enc('winfo', 'containing', rootX, rootY)) + end + end + def winfo_containing(x, y) + TkWinfo.containing(x, y, self) + end + + def TkWinfo.depth(win) + number(tk_call_without_enc('winfo', 'depth', win)) + end + def winfo_depth + TkWinfo.depth self + end + + def TkWinfo.exist?(win) + bool(tk_call_without_enc('winfo', 'exists', win)) + end + def winfo_exist? + TkWinfo.exist? self + end + + def TkWinfo.fpixels(win, dist) + number(tk_call_without_enc('winfo', 'fpixels', win, dist)) + end + def winfo_fpixels(dist) + TkWinfo.fpixels self, dist + end + + def TkWinfo.geometry(win) + tk_call_without_enc('winfo', 'geometry', win) + end + def winfo_geometry + TkWinfo.geometry self + end + + def TkWinfo.height(win) + number(tk_call_without_enc('winfo', 'height', win)) + end + def winfo_height + TkWinfo.height self + end + + def TkWinfo.id(win) + tk_call_without_enc('winfo', 'id', win) + end + def winfo_id + TkWinfo.id self + end + + def TkWinfo.interps(win=nil) + if win + #tk_split_simplelist(tk_call_without_enc('winfo', 'interps', + # '-displayof', win)) + tk_split_simplelist(tk_call_without_enc('winfo', 'interps', + '-displayof', win), + false, true) + else + #tk_split_simplelist(tk_call_without_enc('winfo', 'interps')) + tk_split_simplelist(tk_call_without_enc('winfo', 'interps'), + false, true) + end + end + def winfo_interps + TkWinfo.interps self + end + + def TkWinfo.mapped?(win) + bool(tk_call_without_enc('winfo', 'ismapped', win)) + end + def winfo_mapped? + TkWinfo.mapped? self + end + + def TkWinfo.manager(win) + tk_call_without_enc('winfo', 'manager', win) + end + def winfo_manager + TkWinfo.manager self + end + + def TkWinfo.appname(win) + tk_call('winfo', 'name', win) + end + def winfo_appname + TkWinfo.appname self + end + + def TkWinfo.parent(win) + window(tk_call_without_enc('winfo', 'parent', win)) + end + def winfo_parent + TkWinfo.parent self + end + + def TkWinfo.widget(id, win=nil) + if win + window(tk_call_without_enc('winfo', 'pathname', '-displayof', win, id)) + else + window(tk_call_without_enc('winfo', 'pathname', id)) + end + end + def winfo_widget(id) + TkWinfo.widget id, self + end + + def TkWinfo.pixels(win, dist) + number(tk_call_without_enc('winfo', 'pixels', win, dist)) + end + def winfo_pixels(dist) + TkWinfo.pixels self, dist + end + + def TkWinfo.reqheight(win) + number(tk_call_without_enc('winfo', 'reqheight', win)) + end + def winfo_reqheight + TkWinfo.reqheight self + end + + def TkWinfo.reqwidth(win) + number(tk_call_without_enc('winfo', 'reqwidth', win)) + end + def winfo_reqwidth + TkWinfo.reqwidth self + end + + def TkWinfo.rgb(win, color) + list(tk_call_without_enc('winfo', 'rgb', win, color)) + end + def winfo_rgb(color) + TkWinfo.rgb self, color + end + + def TkWinfo.rootx(win) + number(tk_call_without_enc('winfo', 'rootx', win)) + end + def winfo_rootx + TkWinfo.rootx self + end + + def TkWinfo.rooty(win) + number(tk_call_without_enc('winfo', 'rooty', win)) + end + def winfo_rooty + TkWinfo.rooty self + end + + def TkWinfo.screen(win) + tk_call('winfo', 'screen', win) + end + def winfo_screen + TkWinfo.screen self + end + + def TkWinfo.screencells(win) + number(tk_call_without_enc('winfo', 'screencells', win)) + end + def winfo_screencells + TkWinfo.screencells self + end + + def TkWinfo.screendepth(win) + number(tk_call_without_enc('winfo', 'screendepth', win)) + end + def winfo_screendepth + TkWinfo.screendepth self + end + + def TkWinfo.screenheight (win) + number(tk_call_without_enc('winfo', 'screenheight', win)) + end + def winfo_screenheight + TkWinfo.screenheight self + end + + def TkWinfo.screenmmheight(win) + number(tk_call_without_enc('winfo', 'screenmmheight', win)) + end + def winfo_screenmmheight + TkWinfo.screenmmheight self + end + + def TkWinfo.screenmmwidth(win) + number(tk_call_without_enc('winfo', 'screenmmwidth', win)) + end + def winfo_screenmmwidth + TkWinfo.screenmmwidth self + end + + def TkWinfo.screenvisual(win) + tk_call_without_enc('winfo', 'screenvisual', win) + end + def winfo_screenvisual + TkWinfo.screenvisual self + end + + def TkWinfo.screenwidth(win) + number(tk_call_without_enc('winfo', 'screenwidth', win)) + end + def winfo_screenwidth + TkWinfo.screenwidth self + end + + def TkWinfo.server(win) + tk_call('winfo', 'server', win) + end + def winfo_server + TkWinfo.server self + end + + def TkWinfo.toplevel(win) + window(tk_call_without_enc('winfo', 'toplevel', win)) + end + def winfo_toplevel + TkWinfo.toplevel self + end + + def TkWinfo.visual(win) + tk_call_without_enc('winfo', 'visual', win) + end + def winfo_visual + TkWinfo.visual self + end + + def TkWinfo.visualid(win) + tk_call_without_enc('winfo', 'visualid', win) + end + def winfo_visualid + TkWinfo.visualid self + end + + def TkWinfo.visualsavailable(win, includeids=false) + if includeids + list(tk_call_without_enc('winfo', 'visualsavailable', + win, "includeids")) + else + list(tk_call_without_enc('winfo', 'visualsavailable', win)) + end + end + def winfo_visualsavailable(includeids=false) + TkWinfo.visualsavailable self, includeids + end + + def TkWinfo.vrootheight(win) + number(tk_call_without_enc('winfo', 'vrootheight', win)) + end + def winfo_vrootheight + TkWinfo.vrootheight self + end + + def TkWinfo.vrootwidth(win) + number(tk_call_without_enc('winfo', 'vrootwidth', win)) + end + def winfo_vrootwidth + TkWinfo.vrootwidth self + end + + def TkWinfo.vrootx(win) + number(tk_call_without_enc('winfo', 'vrootx', win)) + end + def winfo_vrootx + TkWinfo.vrootx self + end + + def TkWinfo.vrooty(win) + number(tk_call_without_enc('winfo', 'vrooty', win)) + end + def winfo_vrooty + TkWinfo.vrooty self + end + + def TkWinfo.width(win) + number(tk_call_without_enc('winfo', 'width', win)) + end + def winfo_width + TkWinfo.width self + end + + def TkWinfo.x(win) + number(tk_call_without_enc('winfo', 'x', win)) + end + def winfo_x + TkWinfo.x self + end + + def TkWinfo.y(win) + number(tk_call_without_enc('winfo', 'y', win)) + end + def winfo_y + TkWinfo.y self + end + + def TkWinfo.viewable(win) + bool(tk_call_without_enc('winfo', 'viewable', win)) + end + def winfo_viewable + TkWinfo.viewable self + end + + def TkWinfo.pointerx(win) + number(tk_call_without_enc('winfo', 'pointerx', win)) + end + def winfo_pointerx + TkWinfo.pointerx self + end + + def TkWinfo.pointery(win) + number(tk_call_without_enc('winfo', 'pointery', win)) + end + def winfo_pointery + TkWinfo.pointery self + end + + def TkWinfo.pointerxy(win) + list(tk_call_without_enc('winfo', 'pointerxy', win)) + end + def winfo_pointerxy + TkWinfo.pointerxy self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/winpkg.rb b/ruby_1_8_6/ext/tk/lib/tk/winpkg.rb new file mode 100644 index 0000000000..737fb959b5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/winpkg.rb @@ -0,0 +1,143 @@ +# +# tk/winpkg.rb : methods for Tcl/Tk packages for Microsoft Windows +# 2000/11/22 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +# ATTENTION !! +# This is NOT TESTED. Because I have no test-environment. +# +require 'tk' + +module TkWinDDE + extend Tk + extend TkWinDDE + + TkCommandNames = ['dde'.freeze].freeze + + PACKAGE_NAME = 'dde'.freeze + def self.package_name + PACKAGE_NAME + end + + if self.const_defined? :FORCE_VERSION + tk_call_without_enc('package', 'require', 'dde', FORCE_VERSION) + else + tk_call_without_enc('package', 'require', 'dde') + end + + #def servername(topic=None) + # tk_call('dde', 'servername', topic) + #end + def servername(*args) + if args.size == 0 + tk_call('dde', 'servername') + else + if args[-1].kind_of?(Hash) # dde 1.2 + + keys = _symbolkey2str(args.pop) + force = (keys.delete('force'))? '-force': None + exact = (keys.delete('exact'))? '-exact': None + if keys.size == 0 + tk_call('dde', 'servername', force, exact) + elsif args.size == 0 + tk_call('dde', 'servername', force, exact, *hash_kv(keys)) + else + tk_call('dde', 'servername', force, exact, + *((hash_kv(keys) << '--') + args)) + end + else + tk_call('dde', 'servername', *args) + end + end + end + + def execute(service, topic, data) + tk_call('dde', 'execute', service, topic, data) + end + + def async_execute(service, topic, data) + tk_call('dde', '-async', 'execute', service, topic, data) + end + + def poke(service, topic, item, data) + tk_call('dde', 'poke', service, topic, item, data) + end + + def request(service, topic, item) + tk_call('dde', 'request', service, topic, item) + end + + def binary_request(service, topic, item) + tk_call('dde', 'request', '-binary', service, topic, item) + end + + def services(service, topic) + tk_call('dde', 'services', service, topic) + end + + def eval(topic, cmd, *args) + tk_call('dde', 'eval', topic, cmd, *args) + end + + def async_eval(topic, cmd, *args) + tk_call('dde', 'eval', -async, topic, cmd, *args) + end + + module_function :servername, :execute, :async_execute, + :poke, :request, :services, :eval +end + +module TkWinRegistry + extend Tk + extend TkWinRegistry + + TkCommandNames = ['registry'.freeze].freeze + + if self.const_defined? :FORCE_VERSION + tk_call('package', 'require', 'registry', FORCE_VERSION) + else + tk_call('package', 'require', 'registry') + end + + def broadcast(keynam, timeout=nil) + if timeout + tk_call('registry', 'broadcast', keynam, '-timeout', timeout) + else + tk_call('registry', 'broadcast', keynam) + end + end + + def delete(keynam, valnam=None) + tk_call('registry', 'delete', keynam, valnam) + end + + def get(keynam, valnam) + tk_call('registry', 'get', keynam, valnam) + end + + def keys(keynam, pattern=nil) + lst = tk_split_simplelist(tk_call('registry', 'keys', keynam)) + if pattern + lst.find_all{|key| key =~ pattern} + else + lst + end + end + + def set(keynam, valnam=None, data=None, dattype=None) + tk_call('registry', 'set', keynam, valnam, data, dattype) + end + + def type(keynam, valnam) + tk_call('registry', 'type', keynam, valnam) + end + + def values(keynam, pattern=nil) + lst = tk_split_simplelist(tk_call('registry', 'values', keynam)) + if pattern + lst.find_all{|val| val =~ pattern} + else + lst + end + end + + module_function :delete, :get, :keys, :set, :type, :values +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/wm.rb b/ruby_1_8_6/ext/tk/lib/tk/wm.rb new file mode 100644 index 0000000000..1f432a3848 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/wm.rb @@ -0,0 +1,360 @@ +# +# tk/wm.rb : methods for wm command +# +require 'tk' + +module Tk + module Wm + include TkComm + + TkCommandNames = ['wm'.freeze].freeze + + TOPLEVEL_METHODCALL_OPTKEYS = {} + + def aspect(*args) + if args.length == 0 + list(tk_call_without_enc('wm', 'aspect', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call('wm', 'aspect', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['aspect'] = 'aspect' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['attributes'] = 'attributes' + + def client(name=None) + if name == None + tk_call('wm', 'client', path) + else + name = '' if name == nil + tk_call('wm', 'client', path, name) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['client'] = 'client' + + def colormapwindows(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'colormapwindows', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'colormapwindows', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['colormapwindows'] = 'colormapwindows' + + def wm_command(value=nil) + if value + tk_call('wm', 'command', path, value) + self + else + #procedure(tk_call('wm', 'command', path)) + tk_call('wm', 'command', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['wm_command'] = 'wm_command' + + def deiconify(ex = true) + if ex + tk_call_without_enc('wm', 'deiconify', path) + else + self.iconify + end + self + end + + def focusmodel(mode = nil) + if mode + tk_call_without_enc('wm', 'focusmodel', path, mode) + self + else + tk_call_without_enc('wm', 'focusmodel', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['focusmodel'] = 'focusmodel' + + def frame + tk_call_without_enc('wm', 'frame', path) + end + + def geometry(geom=nil) + if geom + tk_call_without_enc('wm', 'geometry', path, geom) + self + else + tk_call_without_enc('wm', 'geometry', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['geometry'] = 'geometry' + + def wm_grid(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'grid', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'grid', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['wm_grid'] = 'wm_grid' + + def group(leader = nil) + if leader + tk_call('wm', 'group', path, leader) + self + else + window(tk_call('wm', 'group', path)) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['group'] = 'group' + + def iconbitmap(bmp=nil) + if bmp + tk_call_without_enc('wm', 'iconbitmap', path, bmp) + self + else + image_obj(tk_call_without_enc('wm', 'iconbitmap', path)) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['iconbitmap'] = 'iconbitmap' + + def iconphoto(*imgs) + if imgs.empty? + @wm_iconphoto = nil unless defined? @wm_iconphoto + return @wm_iconphoto + end + + imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array) + tk_call_without_enc('wm', 'iconphoto', path, *imgs) + @wm_iconphoto = imgs + self + end + TOPLEVEL_METHODCALL_OPTKEYS['iconphoto'] = 'iconphoto' + + def iconphoto_default(*imgs) + imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array) + tk_call_without_enc('wm', 'iconphoto', path, '-default', *imgs) + self + end + + def iconify(ex = true) + if ex + tk_call_without_enc('wm', 'iconify', path) + else + self.deiconify + end + self + end + + def iconmask(bmp=nil) + if bmp + tk_call_without_enc('wm', 'iconmask', path, bmp) + self + else + image_obj(tk_call_without_enc('wm', 'iconmask', path)) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['iconmask'] = 'iconmask' + + def iconname(name=nil) + if name + tk_call('wm', 'iconname', path, name) + self + else + tk_call('wm', 'iconname', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['iconname'] = 'iconname' + + def iconposition(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'iconposition', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'iconposition', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['iconposition'] = 'iconposition' + + def iconwindow(win = nil) + if win + tk_call_without_enc('wm', 'iconwindow', path, win) + self + else + w = tk_call_without_enc('wm', 'iconwindow', path) + (w == '')? nil: window(w) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['iconwindow'] = 'iconwindow' + + def maxsize(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'maxsize', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'maxsize', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['maxsize'] = 'maxsize' + + def minsize(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'minsize', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'minsize', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['minsize'] = 'minsize' + + def overrideredirect(mode=None) + if mode == None + bool(tk_call_without_enc('wm', 'overrideredirect', path)) + else + tk_call_without_enc('wm', 'overrideredirect', path, mode) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['overrideredirect'] = 'overrideredirect' + + def positionfrom(who=None) + if who == None + r = tk_call_without_enc('wm', 'positionfrom', path) + (r == "")? nil: r + else + tk_call_without_enc('wm', 'positionfrom', path, who) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['positionfrom'] = 'positionfrom' + + def protocol(name=nil, cmd=nil, &b) + if cmd + tk_call_without_enc('wm', 'protocol', path, name, cmd) + self + elsif b + tk_call_without_enc('wm', 'protocol', path, name, proc(&b)) + self + elsif name + result = tk_call_without_enc('wm', 'protocol', path, name) + (result == "")? nil : tk_tcl2ruby(result) + else + tk_split_simplelist(tk_call_without_enc('wm', 'protocol', path)) + end + end + + def protocols(kv=nil) + unless kv + ret = {} + self.protocol.each{|name| + ret[name] = self.protocol(name) + } + return ret + end + + unless kv.kind_of?(Hash) + fail ArgumentError, 'expect a hash of protocol=>command' + end + kv.each{|k, v| self.protocol(k, v)} + self + end + TOPLEVEL_METHODCALL_OPTKEYS['protocols'] = 'protocols' + + def resizable(*args) + if args.length == 0 + list(tk_call_without_enc('wm', 'resizable', path)).collect{|e| bool(e)} + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'resizable', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['resizable'] = 'resizable' + + def sizefrom(who=None) + if who == None + r = tk_call_without_enc('wm', 'sizefrom', path) + (r == "")? nil: r + else + tk_call_without_enc('wm', 'sizefrom', path, who) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['sizefrom'] = 'sizefrom' + + def stackorder + list(tk_call('wm', 'stackorder', path)) + end + + def stackorder_isabove(win) + bool(tk_call('wm', 'stackorder', path, 'isabove', win)) + end + + def stackorder_isbelow(win) + bool(tk_call('wm', 'stackorder', path, 'isbelow', win)) + end + + def state(st=nil) + if st + tk_call_without_enc('wm', 'state', path, st) + self + else + tk_call_without_enc('wm', 'state', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['state'] = 'state' + + def title(str=nil) + if str + tk_call('wm', 'title', path, str) + self + else + tk_call('wm', 'title', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['title'] = 'title' + + def transient(master=nil) + if master + tk_call_without_enc('wm', 'transient', path, master) + self + else + window(tk_call_without_enc('wm', 'transient', path)) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['transient'] = 'transient' + + def withdraw(ex = true) + if ex + tk_call_without_enc('wm', 'withdraw', path) + else + self.deiconify + end + self + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/xim.rb b/ruby_1_8_6/ext/tk/lib/tk/xim.rb new file mode 100644 index 0000000000..0ac8559bb9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/xim.rb @@ -0,0 +1,122 @@ +# +# tk/xim.rb : control imput_method +# +require 'tk' + +module TkXIM + include Tk + extend Tk + + TkCommandNames = ['imconfigure'.freeze].freeze + + def TkXIM.useinputmethods(value = None, win = nil) + if value == None + if win + bool(tk_call_without_enc('tk', 'useinputmethods', + '-displayof', win)) + else + bool(tk_call_without_enc('tk', 'useinputmethods')) + end + else + if win + bool(tk_call_without_enc('tk', 'useinputmethods', + '-displayof', win, value)) + else + bool(tk_call_without_enc('tk', 'useinputmethods', value)) + end + end + end + + def TkXIM.useinputmethods_displayof(win, value = None) + TkXIM.useinputmethods(value, win) + end + + def TkXIM.caret(win, keys=nil) + if keys + tk_call_without_enc('tk', 'caret', win, *hash_kv(keys)) + self + else + lst = tk_split_list(tk_call_without_enc('tk', 'caret', win)) + info = {} + while key = lst.shift + info[key[1..-1]] = lst.shift + end + info + end + end + + def TkXIM.configure(win, slot, value=None) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot.kind_of? Hash + tk_call('imconfigure', win, *hash_kv(slot)) + else + tk_call('imconfigure', win, "-#{slot}", value) + end + end + rescue + end + end + + def TkXIM.configinfo(win, slot=nil) + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot + conf = tk_split_list(tk_call('imconfigure', win, "-#{slot}")) + conf[0] = conf[0][1..-1] + conf + else + tk_split_list(tk_call('imconfigure', win)).collect{|conf| + conf[0] = conf[0][1..-1] + conf + } + end + else + [] + end + rescue + [] + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + TkXIM.current_configinfo(win, slot) + end + end + + def TkXIM.current_configinfo(win, slot=nil) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot + conf = tk_split_list(tk_call('imconfigure', win, "-#{slot}")) + { conf[0][1..-1] => conf[1] } + else + ret = {} + tk_split_list(tk_call('imconfigure', win)).each{|conf| + ret[conf[0][1..-1]] = conf[1] + } + ret + end + else + {} + end + rescue + {} + end + end + + def useinputmethods(value=None) + TkXIM.useinputmethods(value, self) + end + + def caret(keys=nil) + TkXIM.caret(self, keys=nil) + end + + def imconfigure(slot, value=None) + TkXIM.configure(self, slot, value) + end + + def imconfiginfo(slot=nil) + TkXIM.configinfo(self, slot) + end +end |