summaryrefslogtreecommitdiff
path: root/jni/ruby/ext/tk/lib/tkextlib/blt
diff options
context:
space:
mode:
Diffstat (limited to 'jni/ruby/ext/tk/lib/tkextlib/blt')
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/barchart.rb79
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/bitmap.rb112
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/busy.rb83
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/component.rb2218
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/container.rb28
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/cutbuffer.rb23
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/dragdrop.rb269
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/eps.rb32
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/graph.rb67
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/htext.rb112
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/setup.rb8
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/spline.rb23
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/stripchart.rb74
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/table.rb412
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tabnotebook.rb110
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tabset.rb504
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/ted.rb68
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile.rb25
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile/button.rb16
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb17
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile/frame.rb16
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile/label.rb16
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb17
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb16
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tile/toplevel.rb16
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/tree.rb1058
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/treeview.rb1287
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/unix_dnd.rb141
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/vector.rb256
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/watch.rb175
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/win_printer.rb61
-rw-r--r--jni/ruby/ext/tk/lib/tkextlib/blt/winop.rb107
32 files changed, 7446 insertions, 0 deletions
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/barchart.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/barchart.rb
new file mode 100644
index 0000000..a86b91c
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/barchart.rb
@@ -0,0 +1,79 @@
+#
+# tkextlib/blt/barchart.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+require 'tkextlib/blt/component.rb'
+
+module Tk::BLT
+ class Barchart < TkWindow
+ TkCommandNames = ['::blt::barchart'.freeze].freeze
+ WidgetClassName = 'Barchart'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ include PlotComponent
+ include GraphCommand
+
+ def __boolval_optkeys
+ ['bufferelements', 'buffergraph', 'invertxy']
+ end
+ private :__boolval_optkeys
+
+ def __strval_optkeys
+ ['text', 'label', 'title', 'file',
+ 'background', 'plotbackground']
+ end
+ private :__strval_optkeys
+
+ def __tkvariable_optkeys
+ super() << 'colormap' << 'fontmap'
+ end
+ private :__tkvariable_optkeys
+
+=begin
+ BarElement_ID = ['blt_barchart_bar'.freeze, TkUtil.untrust('00000')].freeze
+
+ def bar(elem=nil, keys={})
+ if elem.kind_of?(Hash)
+ keys = elem
+ elem = nil
+ end
+ unless elem
+ elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze
+ BarElement_ID[1].succ!
+ end
+ tk_send('bar', elem, keys)
+ Element.new(self, elem, :without_creating=>true)
+ end
+=end
+
+ def extents(item)
+ num_or_str(tk_send_without_enc('extents', item))
+ end
+
+ def invtransform(x, y)
+ list(tk_send_without_enc('invtransform', x, y))
+ end
+
+ def inside(x, y)
+ bool(tk_send_without_enc('inside', x, y))
+ end
+
+ def metafile(file=None)
+ # Windows only
+ tk_send('metafile', file)
+ self
+ end
+
+ def snap(output, keys={})
+ tk_send_without_enc('snap', *(hash_kv(keys, false) + output))
+ self
+ end
+
+ def transform(x, y)
+ list(tk_send_without_enc('transform', x, y))
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/bitmap.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/bitmap.rb
new file mode 100644
index 0000000..3254b63
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/bitmap.rb
@@ -0,0 +1,112 @@
+#
+# tkextlib/blt/bitmap.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Bitmap < TkObject
+ extend TkCore
+
+ TkCommandNames = ['::blt::bitmap'.freeze].freeze
+
+ BITMAP_ID_TBL = TkCore::INTERP.create_table
+
+ (BITMAP_ID = ['blt_bitmap_id'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ TkCore::INTERP.init_ip_env{
+ BITMAP_ID_TBL.mutex.synchronize{ BITMAP_ID_TBL.clear }
+ }
+
+ def self.data(name)
+ dat = tk_simple_list(tk_call('::blt::bitmap', 'data', name))
+ [ tk_split_list(dat[0]), tk_simple_list(dat[1]) ]
+ end
+
+ def self.exist?(name)
+ bool(tk_call('::blt::bitmap', 'exists', name))
+ end
+
+ def self.height(name)
+ number(tk_call('::blt::bitmap', 'height', name))
+ end
+
+ def self.width(name)
+ number(tk_call('::blt::bitmap', 'width', name))
+ end
+
+ def self.source(name)
+ tk_simple_list(tk_call('::blt::bitmap', 'source', name))
+ end
+
+ #################################
+
+ class << self
+ alias _new new
+
+ def new(data, keys={})
+ _new(:data, nil, data, keys)
+ end
+ alias define new
+
+ def new_with_name(name, data, keys={})
+ _new(:data, name, data, keys)
+ end
+ alias define_with_name new_with_name
+
+ def compose(text, keys={})
+ _new(:text, nil, text, keys)
+ end
+
+ def compose_with_name(name, text, keys={})
+ _new(:text, name, text, keys)
+ end
+ end
+
+ def initialize(type, name, data, keys = {})
+ if name
+ @id = name
+ else
+ BITMAP_ID.mutex.synchronize{
+ @id = BITMAP_ID.join(TkCore::INTERP._ip_id_)
+ BITMAP_ID[1].succ!
+ }
+ BITMAP_ID_TBL.mutex.synchronize{
+ BITMAP_ID_TBL[@id] = self
+ }
+ end
+
+ @path = @id
+
+ unless bool(tk_call('::blt::bitmap', 'exists', @id))
+ if type == :text
+ tk_call('::blt::bitmap', 'compose', @id, data, *hash_kv(keys))
+ else # :data
+ tk_call('::blt::bitmap', 'define', @id, data, *hash_kv(keys))
+ end
+ end
+ end
+
+ def exist?
+ bool(tk_call('::blt::bitmap', 'exists', @id))
+ end
+
+ def height
+ number(tk_call('::blt::bitmap', 'height', @id))
+ end
+
+ def width
+ number(tk_call('::blt::bitmap', 'width', @id))
+ end
+
+ def source
+ tk_simple_list(tk_call('::blt::bitmap', 'source', @id))
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/busy.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/busy.rb
new file mode 100644
index 0000000..b5287fb
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/busy.rb
@@ -0,0 +1,83 @@
+#
+# tkextlib/blt/busy.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/itemconfig.rb'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module Busy
+ extend TkCore
+ extend TkItemConfigMethod
+
+ TkCommandNames = ['::blt::busy'.freeze].freeze
+
+ ###########################
+
+ class Shield < TkWindow
+ def self.shield_path(win)
+ win = window(win) unless win.kind_of?(TkWindow)
+ if win.kind_of?(Tk::Toplevel)
+ win.path + '._Busy'
+ else
+ win.path + '_Busy'
+ end
+ end
+
+ def initialize(win)
+ @path = self.class.shield_path(win)
+ end
+ end
+
+ def self.shield_path(win)
+ Tk::BLT::Busy::Shield.shield_path(win)
+ end
+ end
+end
+
+class << Tk::BLT::Busy
+ def __item_config_cmd(win)
+ ['::blt::busy', 'configure', win]
+ end
+ private :__item_config_cmd
+
+ undef itemcget
+ undef itemcget_tkstring
+ alias configure itemconfigure
+ alias configinfo itemconfiginfo
+ alias current_configinfo current_itemconfiginfo
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ ##################################
+
+ def hold(win, keys={})
+ tk_call('::blt::busy', 'hold', win, *hash_kv(keys))
+ end
+
+ def release(*wins)
+ tk_call('::blt::busy', 'release', *wins)
+ end
+
+ def forget(*wins)
+ tk_call('::blt::busy', 'forget', *wins)
+ end
+
+ def is_busy(pat=None)
+ tk_split_list(tk_call('::blt::busy', 'isbusy', pat))
+ end
+
+ def names(pat=None)
+ tk_split_list(tk_call('::blt::busy', 'names', pat))
+ end
+ alias windows names
+
+ def check(win)
+ bool(tk_call('::blt::busy', 'check', win))
+ end
+
+ def status(win)
+ bool(tk_call('::blt::busy', 'status', win))
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/component.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/component.rb
new file mode 100644
index 0000000..c7ea213
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/component.rb
@@ -0,0 +1,2218 @@
+#
+# tkextlib/blt/component.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module PlotComponent
+ include TkItemConfigMethod
+
+ module OptKeys
+ def __item_font_optkeys(id)
+ ['font', 'tickfont', 'titlefont']
+ end
+ private :__item_font_optkeys
+
+ def __item_numstrval_optkeys(id)
+ ['xoffset', 'yoffset']
+ end
+ private :__item_numstrval_optkeys
+
+ def __item_boolval_optkeys(id)
+ ['hide', 'under', 'descending', 'logscale', 'loose', 'showticks',
+ 'titlealternate', 'scalesymbols', 'minor', 'raised',
+ 'center', 'decoration', 'landscape', 'maxpect']
+ end
+ private :__item_boolval_optkeys
+
+ def __item_strval_optkeys(id)
+ ['text', 'label', 'limits', 'title',
+ 'show', 'file', 'maskdata', 'maskfile',
+ 'color', 'titlecolor', 'fill', 'outline', 'offdash']
+ end
+ private :__item_strval_optkeys
+
+ def __item_listval_optkeys(id)
+ ['bindtags']
+ end
+ private :__item_listval_optkeys
+
+ def __item_numlistval_optkeys(id)
+ ['dashes', 'majorticks', 'minorticks']
+ end
+ private :__item_numlistval_optkeys
+
+ def __item_tkvariable_optkeys(id)
+ ['variable', 'textvariable', 'colormap', 'fontmap']
+ end
+ private :__item_tkvariable_optkeys
+ end
+
+ include OptKeys
+
+ def __item_cget_cmd(id)
+ if id.kind_of?(Array)
+ # id := [ type, name ]
+ [self.path, id[0], 'cget', id[1]]
+ else
+ [self.path, id, 'cget']
+ end
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(id)
+ if id.kind_of?(Array)
+ # id := [ type, name, ... ]
+ type, *names = id
+ [self.path, type, 'configure'].concat(names)
+ else
+ [self.path, id, 'configure']
+ end
+ 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 axis_cget_tkstring(id, option)
+ ret = itemcget_tkstring(['axis', tagid(id)], option)
+ end
+ def axis_cget(id, option)
+ ret = itemcget(['axis', tagid(id)], option)
+ end
+ def axis_cget_strict(id, option)
+ ret = itemcget_strict(['axis', tagid(id)], option)
+ end
+ def axis_configure(*args)
+ slot = args.pop
+ if slot.kind_of?(Hash)
+ value = None
+ slot = _symbolkey2str(slot)
+ if cmd = slot.delete('command')
+ slot['command'] = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ else
+ value = slot
+ slot = args.pop
+ if slot == :command || slot == 'command'
+ cmd = value
+ value = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ end
+ id_list = args.flatten.collect!{|id| tagid(id)}.unshift('axis')
+ itemconfigure(id_list, slot, value)
+ end
+ def axis_configinfo(id, slot=nil)
+ itemconfiginfo(['axis', tagid(id)], slot)
+ end
+ def current_axis_configinfo(id, slot=nil)
+ current_itemconfiginfo(['axis', tagid(id)], slot)
+ end
+
+ def crosshairs_cget_tkstring(option)
+ itemcget_tkstring('crosshairs', option)
+ end
+ def crosshairs_cget(option)
+ itemcget('crosshairs', option)
+ end
+ def crosshairs_cget_strict(option)
+ itemcget_strict('crosshairs', option)
+ end
+ def crosshairs_configure(slot, value=None)
+ itemconfigure('crosshairs', slot, value)
+ end
+ def crosshairs_configinfo(slot=nil)
+ itemconfiginfo('crosshairs', slot)
+ end
+ def current_crosshairs_configinfo(slot=nil)
+ current_itemconfiginfo('crosshairs', slot)
+ end
+
+ def element_cget_tkstring(id, option)
+ itemcget_tkstring(['element', tagid(id)], option)
+ end
+ def element_cget(id, option)
+ itemcget(['element', tagid(id)], option)
+ end
+ def element_cget_strict(id, option)
+ itemcget_strict(['element', tagid(id)], option)
+ end
+ def element_configure(*args)
+ slot = args.pop
+ if slot.kind_of?(Hash)
+ value = None
+ else
+ value = slot
+ slot = args.pop
+ end
+ id_list = args.flatten.collect!{|id| tagid(id)}.unshift('element')
+ itemconfigure(id_list, slot, value)
+ end
+ def element_configinfo(id, slot=nil)
+ itemconfiginfo(['element', tagid(id)], slot)
+ end
+ def current_element_configinfo(id, slot=nil)
+ current_itemconfiginfo(['element', tagid(id)], slot)
+ end
+
+ def bar_cget_tkstring(id, option)
+ itemcget_tkstring(['bar', tagid(id)], option)
+ end
+ def bar_cget(id, option)
+ itemcget(['bar', tagid(id)], option)
+ end
+ def bar_cget_strict(id, option)
+ itemcget_strict(['bar', tagid(id)], option)
+ end
+ def bar_configure(*args)
+ slot = args.pop
+ if slot.kind_of?(Hash)
+ value = None
+ else
+ value = slot
+ slot = args.pop
+ end
+ id_list = args.flatten.collect!{|id| tagid(id)}.unshift('bar')
+ itemconfigure(id_list, slot, value)
+ end
+ def bar_configinfo(id, slot=nil)
+ itemconfiginfo(['bar', tagid(id)], slot)
+ end
+ def current_bar_configinfo(id, slot=nil)
+ current_itemconfiginfo(['bar', tagid(id)], slot)
+ end
+
+ def line_cget_tkstring(id, option)
+ itemcget_tkstring(['line', tagid(id)], option)
+ end
+ def line_cget(id, option)
+ itemcget(['line', tagid(id)], option)
+ end
+ def line_cget_strict(id, option)
+ itemcget_strict(['line', tagid(id)], option)
+ end
+ def line_configure(*args)
+ slot = args.pop
+ if slot.kind_of?(Hash)
+ value = None
+ else
+ value = slot
+ slot = args.pop
+ end
+ id_list = args.flatten.collect!{|id| tagid(id)}.unshift('line')
+ itemconfigure(id_list, slot, value)
+ end
+ def line_configinfo(id, slot=nil)
+ itemconfiginfo(['line', tagid(id)], slot)
+ end
+ def current_line_configinfo(id, slot=nil)
+ current_itemconfiginfo(['line', tagid(id)], slot)
+ end
+
+ def gridline_cget_tkstring(option)
+ itemcget_tkstring('grid', option)
+ end
+ def gridline_cget(option)
+ itemcget('grid', option)
+ end
+ def gridline_cget_strict(option)
+ itemcget_strict('grid', option)
+ end
+ def gridline_configure(slot, value=None)
+ itemconfigure('grid', slot, value)
+ end
+ def gridline_configinfo(slot=nil)
+ itemconfiginfo('grid', slot)
+ end
+ def current_gridline_configinfo(slot=nil)
+ current_itemconfiginfo('grid', slot)
+ end
+
+ def legend_cget_tkstring(option)
+ itemcget_tkstring('legend', option)
+ end
+ def legend_cget(option)
+ itemcget('legend', option)
+ end
+ def legend_cget_strict(option)
+ itemcget_strict('legend', option)
+ end
+ def legend_configure(slot, value=None)
+ itemconfigure('legend', slot, value)
+ end
+ def legend_configinfo(slot=nil)
+ itemconfiginfo('legend', slot)
+ end
+ def current_legend_configinfo(slot=nil)
+ current_itemconfiginfo('legend', slot)
+ end
+
+ def pen_cget_tkstring(id, option)
+ itemcget_tkstring(['pen', tagid(id)], option)
+ end
+ def pen_cget(id, option)
+ itemcget(['pen', tagid(id)], option)
+ end
+ def pen_cget_strict(id, option)
+ itemcget_strict(['pen', tagid(id)], option)
+ end
+ def pen_configure(*args)
+ slot = args.pop
+ if slot.kind_of?(Hash)
+ value = None
+ else
+ value = slot
+ slot = args.pop
+ end
+ id_list = args.flatten.collect!{|id| tagid(id)}.unshift('pen')
+ itemconfigure(id_list, slot, value)
+ end
+ def pen_configinfo(id, slot=nil)
+ itemconfiginfo(['pen', tagid(id)], slot)
+ end
+ def current_pen_configinfo(id, slot=nil)
+ current_itemconfiginfo(['pen', tagid(id)], slot)
+ end
+
+ def postscript_cget_tkstring(option)
+ itemcget_tkstring('postscript', option)
+ end
+ def postscript_cget(option)
+ itemcget('postscript', option)
+ end
+ def postscript_cget_strict(option)
+ itemcget_strict('postscript', option)
+ end
+ def postscript_configure(slot, value=None)
+ itemconfigure('postscript', slot, value)
+ end
+ def postscript_configinfo(slot=nil)
+ itemconfiginfo('postscript', slot)
+ end
+ def current_postscript_configinfo(slot=nil)
+ current_itemconfiginfo('postscript', slot)
+ end
+
+ def marker_cget_tkstring(id, option)
+ itemcget_tkstring(['marker', tagid(id)], option)
+ end
+ def marker_cget(id, option)
+ itemcget(['marker', tagid(id)], option)
+ end
+ def marker_cget_strict(id, option)
+ itemcget_strict(['marker', tagid(id)], option)
+ end
+ def marker_configure(*args)
+ slot = args.pop
+ if slot.kind_of?(Hash)
+ value = None
+ else
+ value = slot
+ slot = args.pop
+ end
+ id_list = args.flatten.collect!{|id| tagid(id)}.unshift('marker')
+ itemconfigure(id_list, slot, value)
+ end
+ def marker_configinfo(id, slot=nil)
+ itemconfiginfo(['marker', tagid(id)], slot)
+ end
+ def current_marker_configinfo(id, slot=nil)
+ current_itemconfiginfo(['marker', tagid(id)], slot)
+ end
+
+ alias __itemcget_tkstring itemcget_tkstring
+ alias __itemcget itemcget
+ alias __itemcget_strict itemcget_strict
+ alias __itemconfiginfo itemconfiginfo
+ alias __current_itemconfiginfo current_itemconfiginfo
+ private :__itemcget_tkstring, :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo
+
+ def itemcget_tkstring(tagOrId, option)
+ __itemcget_tkstring(tagid(tagOrId), option)
+ end
+ def itemcget_strict(tagOrId, option)
+ ret = __itemcget(tagid(tagOrId), option)
+ if option == 'bindtags' || option == :bindtags
+ ret.collect{|tag| TkBindTag.id2obj(tag)}
+ else
+ ret
+ end
+ end
+ def itemcget(tagOrId, option)
+ unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
+ itemcget_strict(tagOrId, option)
+ else
+ begin
+ itemcget_strict(tagOrId, option)
+ rescue => e
+ begin
+ if current_itemconfiginfo(tagOrId).has_key?(option.to_s)
+ # error on known option
+ fail e
+ else
+ # unknown option
+ nil
+ end
+ rescue
+ fail e # tag error
+ end
+ end
+ end
+ end
+ def itemconfiginfo(tagOrId, slot = nil)
+ ret = __itemconfiginfo(tagid(tagOrId), slot)
+
+ if TkComm::GET_CONFIGINFO_AS_ARRAY
+ if slot
+ if slot == 'bindtags' || slot == :bindtags
+ ret[-2] = ret[-2].collect{|tag| TkBindTag.id2obj(tag)}
+ ret[-1] = ret[-1].collect{|tag| TkBindTag.id2obj(tag)}
+ end
+ else
+ if (inf = ret.assoc('bindtags'))
+ inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}
+ inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}
+ end
+ end
+
+ else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
+ if (inf = ret['bindtags'])
+ inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}
+ inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}
+ ret['bindtags'] = inf
+ end
+ end
+
+ ret
+ end
+ def current_itemconfiginfo(tagOrId, slot = nil)
+ ret = __current_itemconfiginfo(tagid(tagOrId), slot)
+
+ if (val = ret['bindtags'])
+ ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)}
+ end
+
+ ret
+ end
+
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ #################
+
+ class Axis < TkObject
+ (OBJ_ID = ['blt_chart_axis'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ AxisID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ AxisID_TBL.mutex.synchronize{ AxisID_TBL.clear }
+ }
+
+ def self.id2obj(chart, id)
+ cpath = chart.path
+ AxisID_TBL.mutex.synchronize{
+ return id unless AxisID_TBL[cpath]
+ AxisID_TBL[cpath][id]? AxisID_TBL[cpath][id]: id
+ }
+ end
+
+ def self.new(chart, axis=nil, keys={})
+ if axis.kind_of?(Hash)
+ keys = axis
+ axis = nil
+ end
+ if keys
+ keys = _symbolkey2str(keys)
+ not_create = keys.delete('without_creating')
+ else
+ not_create = false
+ end
+
+ obj = nil
+ AxisID_TBL.mutex.synchronize{
+ chart_path = chart.path
+ AxisID_TBL[chart_path] ||= {}
+ if axis && AxisID_TBL[chart_path][axis]
+ obj = AxisID_TBL[chart_path][axis]
+ else
+ (obj = self.allocate).instance_eval{
+ if axis
+ @axis = @id = axis.to_s
+ else
+ OBJ_ID.mutex.synchronize{
+ @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
+ OBJ_ID[1].succ!
+ }
+ end
+ @path = @id
+ @parent = @chart = chart
+ @cpath = @chart.path
+ Axis::AxisID_TBL[@cpath][@axis] = self
+ unless not_create
+ tk_call(@chart, 'axis', 'create', @axis, keys)
+ return obj
+ end
+ }
+ end
+ }
+
+ obj.configure(keys) if obj && ! keys.empty?
+ obj
+ end
+
+ def initialize(chart, axis=nil, keys={})
+ # dummy:: not called by 'new' method
+
+ if axis.kind_of?(Hash)
+ keys = axis
+ axis = nil
+ end
+ if axis
+ @axis = @id = axis.to_s
+ else
+ OBJ_ID.mutex.synchronize{
+ @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
+ OBJ_ID[1].succ!
+ }
+ end
+ @path = @id
+ @parent = @chart = chart
+ @cpath = @chart.path
+ # Axis::AxisID_TBL[@cpath][@axis] = self
+ keys = _symbolkey2str(keys)
+ unless keys.delete('without_creating')
+ # @chart.axis_create(@axis, keys)
+ tk_call(@chart, 'axis', 'create', @axis, keys)
+ end
+ end
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ @chart.axis_cget_tkstring(@id, option)
+ end
+ def cget(option)
+ @chart.axis_cget(@id, option)
+ end
+ def cget_strict(option)
+ @chart.axis_cget_strict(@id, option)
+ end
+ def configure(key, value=None)
+ @chart.axis_configure(@id, key, value)
+ self
+ end
+ def configinfo(key=nil)
+ @chart.axis_configinfo(@id, key)
+ end
+ def current_configinfo(key=nil)
+ @chart.current_axis_configinfo(@id, key)
+ end
+
+ def command(cmd=nil, &b)
+ if cmd
+ configure('command', cmd)
+ elsif b
+ configure('command', Proc.new(&b))
+ else
+ cget('command')
+ end
+ end
+
+ def delete
+ @chart.axis_delete(@id)
+ self
+ end
+
+ def invtransform(val)
+ @chart.axis_invtransform(@id, val)
+ end
+
+ def limits
+ @chart.axis_limits(@id)
+ end
+
+ def name
+ @axis
+ end
+
+ def transform(val)
+ @chart.axis_transform(@id, val)
+ end
+
+ def view
+ @chart.axis_view(@id)
+ self
+ end
+
+ def use(name=None) # if @id == xaxis | x2axis | yaxis | y2axis
+ @chart.axis_use(@id, name)
+ end
+
+ def use_as(axis) # axis := xaxis | x2axis | yaxis | y2axis
+ @chart.axis_use(axis, @id)
+ end
+ end
+
+ #################
+
+ class Crosshairs < TkObject
+ CrosshairsID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ CrosshairsID_TBL.mutex.synchronize{ CrosshairsID_TBL.clear }
+ }
+
+ def self.new(chart, keys={})
+ obj = nil
+ CrosshairsID_TBL.mutex.synchronize{
+ unless (obj = CrosshairsID_TBL[chart.path])
+ (obj = self.allocate).instance_eval{
+ @parent = @chart = chart
+ @cpath = @chart.path
+ @path = @id = 'crosshairs'
+ Crosshairs::CrosshairsID_TBL[@cpath] = self
+ }
+ end
+ }
+ chart.crosshair_configure(keys) if obj && ! keys.empty?
+ obj
+ end
+
+ def initialize(chart, keys={})
+ # dummy:: not called by 'new' method
+
+ @parent = @chart = chart
+ @cpath = @chart.path
+ # Crosshairs::CrosshairsID_TBL[@cpath] = self
+ @chart.crosshair_configure(keys) unless keys.empty?
+ @path = @id = 'crosshairs'
+ end
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ @chart.crosshair_cget_tkstring(option)
+ end
+ def cget(option)
+ @chart.crosshair_cget(option)
+ end
+ def cget_strict(option)
+ @chart.crosshair_cget_strict(option)
+ end
+ def configure(key, value=None)
+ @chart.crosshair_configure(key, value)
+ self
+ end
+ def configinfo(key=nil)
+ @chart.crosshair_configinfo(key)
+ end
+ def current_configinfo(key=nil)
+ @chart.current_crosshair_configinfo(key)
+ end
+
+ def off
+ @chart.crosshair_off
+ self
+ end
+ def on
+ @chart.crosshair_on
+ self
+ end
+ def toggle
+ @chart.crosshair_toggle
+ self
+ end
+ end
+
+ #################
+
+ class Element < TkObject
+ extend Tk
+ extend TkItemFontOptkeys
+ extend TkItemConfigOptkeys
+
+ extend Tk::BLT::PlotComponent::OptKeys
+
+ ElementTypeName = 'element'
+ ElementTypeToClass = { ElementTypeName=>self }
+
+ ElementID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ ElementID_TBL.mutex.synchronize{ ElementID_TBL.clear }
+ }
+
+ (OBJ_ID = ['blt_chart_element'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ def Element.type2class(type)
+ ElementTypeToClass[type]
+ end
+
+ def Element.id2obj(chart, id)
+ cpath = chart.path
+ ElementID_TBL.mutex.synchronize{
+ return id unless ElementID_TBL[cpath]
+ ElementID_TBL[cpath][id]? ElementID_TBL[cpath][id]: id
+ }
+ end
+
+ def self.new(chart, element=nil, keys={})
+ if element.kind_of?(Hash)
+ keys = element
+ element = nil
+ end
+ if keys
+ keys = _symbolkey2str(keys)
+ not_create = keys.delete('without_creating')
+ else
+ not_create = false
+ end
+
+ obj = nil
+ ElementID_TBL.mutex.synchronize{
+ chart_path = chart.path
+ ElementID_TBL[chart_path] ||= {}
+ if element && ElementID_TBL[chart_path][element]
+ obj = ElementID_TBL[chart_path][element]
+ else
+ (obj = self.allocate).instance_eval{
+ if element
+ @element = @id = element.to_s
+ else
+ OBJ_ID.mutex.synchronize{
+ @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
+ OBJ_ID[1].succ!
+ }
+ end
+ @path = @id
+ @parent = @chart = chart
+ @cpath = @chart.path
+ @typename = self.class::ElementTypeName
+ Element::ElementID_TBL[@cpath][@element] = self
+ unless not_create
+ tk_call(@chart, @typename, 'create', @element, keys)
+ return obj
+ end
+ }
+ end
+ }
+
+ obj.configure(keys) if obj && ! keys.empty?
+ obj
+ end
+
+ def initialize(chart, element=nil, keys={})
+ # dummy:: not called by 'new' method
+
+ if element.kind_of?(Hash)
+ keys = element
+ element = nil
+ end
+ if element
+ @element = @id = element.to_s
+ else
+ OBJ_ID.mutex.synchronize{
+ @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
+ OBJ_ID[1].succ!
+ }
+ end
+ @path = @id
+ @parent = @chart = chart
+ @cpath = @chart.path
+ @typename = self.class::ElementTypeName
+ # Element::ElementID_TBL[@cpath][@element] = self
+ keys = _symbolkey2str(keys)
+ unless keys.delete('without_creating')
+ # @chart.element_create(@element, keys)
+ tk_call(@chart, @typename, 'create', @element, keys)
+ end
+ end
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ # @chart.element_cget(@id, option)
+ @chart.__send__(@typename + '_cget_tkstring', @id, option)
+ end
+ def cget(option)
+ # @chart.element_cget(@id, option)
+ @chart.__send__(@typename + '_cget', @id, option)
+ end
+ def cget_strict(option)
+ @chart.__send__(@typename + '_cget_strict', @id, option)
+ end
+ def configure(key, value=None)
+ # @chart.element_configure(@id, key, value)
+ @chart.__send__(@typename + '_configure', @id, key, value)
+ self
+ end
+ def configinfo(key=nil)
+ # @chart.element_configinfo(@id, key)
+ @chart.__send__(@typename + '_configinfo', @id, key)
+ end
+ def current_configinfo(key=nil)
+ # @chart.current_element_configinfo(@id, key)
+ @chart.__send__('current_' << @typename << '_configinfo', @id, key)
+ end
+
+ def activate(*args)
+ @chart.element_activate(@id, *args)
+ end
+
+ def closest(x, y, var, keys={})
+ # @chart.element_closest(x, y, var, @id, keys)
+ @chart.__send__(@typename + '_closest', x, y, var, @id, keys)
+ end
+
+ def deactivate
+ @chart.element_deactivate(@id)
+ self
+ end
+
+ def delete
+ @chart.element_delete(@id)
+ self
+ end
+
+ def exist?
+ @chart.element_exist?(@id)
+ end
+
+ def name
+ @element
+ end
+
+ def type
+ @chart.element_type(@id)
+ end
+ end
+
+ class Bar < Element
+ ElementTypeName = 'bar'.freeze
+ ElementTypeToClass[ElementTypeName] = self
+ end
+ class Line < Element
+ ElementTypeName = 'line'.freeze
+ ElementTypeToClass[ElementTypeName] = self
+ end
+
+ #################
+
+ class GridLine < TkObject
+ GridLineID_TBL = TkCore::INTERP.create_table
+ TkCore::INTERP.init_ip_env{
+ GridLineID_TBL.mutex.synchronize{ GridLineID_TBL.clear }
+ }
+
+ def self.new(chart, keys={})
+ obj = nil
+ GridLineID_TBL.mutex.synchronize{
+ unless (obj = GridLineID_TBL[chart.path])
+ (obj = self.allocate).instance_eval{
+ @parent = @chart = chart
+ @cpath = @chart.path
+ @path = @id = 'grid'
+ GridLine::GridLineID_TBL[@cpath] = self
+ }
+ end
+ }
+ chart.gridline_configure(keys) if obj && ! keys.empty?
+ obj
+ end
+
+ def initialize(chart, keys={})
+ # dummy:: not called by 'new' method
+
+ @parent = @chart = chart
+ @cpath = @chart.path
+ # GridLine::GridLineID_TBL[@cpath] = self
+ @chart.gridline_configure(keys) unless keys.empty?
+ @path = @id = 'grid'
+ end
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ @chart.gridline_cget_tkstring(option)
+ end
+ def cget(option)
+ @chart.gridline_cget(option)
+ end
+ def cget_strict(option)
+ @chart.gridline_cget_strict(option)
+ end
+ def configure(key, value=None)
+ @chart.gridline_configure(key, value)
+ self
+ end
+ def configinfo(key=nil)
+ @chart.gridline_configinfo(key)
+ end
+ def current_configinfo(key=nil)
+ @chart.current_gridline_configinfo(key)
+ end
+
+ def off
+ @chart.gridline_off
+ self
+ end
+ def on
+ @chart.gridline_on
+ self
+ end
+ def toggle
+ @chart.gridline_toggle
+ self
+ end
+ end
+
+ #################
+
+ class Legend < TkObject
+ LegendID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ LegendID_TBL.mutex.synchronize{ LegendID_TBL.clear }
+ }
+
+ def self.new(chart, keys={})
+ obj = nil
+ LegenedID_TBL.mutex.synchronize{
+ unless (obj = LegenedID_TBL[chart.path])
+ (obj = self.allocate).instance_eval{
+ @parent = @chart = chart
+ @cpath = @chart.path
+ @path = @id = 'crosshairs'
+ Legend::LegenedID_TBL[@cpath] = self
+ }
+ end
+ }
+ chart.legend_configure(keys) if obj && ! keys.empty?
+ obj
+ end
+
+ def initialize(chart, keys={})
+ # dummy:: not called by 'new' method
+
+ @parent = @chart = chart
+ @cpath = @chart.path
+ # Legend::LegendID_TBL[@cpath] = self
+ @chart.legend_configure(keys) unless keys.empty?
+ @path = @id = 'legend'
+ end
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ @chart.legend_cget_tkstring(option)
+ end
+ def cget(option)
+ @chart.legend_cget(option)
+ end
+ def cget_strict(option)
+ @chart.legend_cget_strict(option)
+ end
+ def configure(key, value=None)
+ @chart.legend_configure(key, value)
+ self
+ end
+ def configinfo(key=nil)
+ @chart.legend_configinfo(key)
+ end
+ def current_configinfo(key=nil)
+ @chart.current_legend_configinfo(key)
+ end
+
+ def activate(*args)
+ @chart.legend_activate(*args)
+ end
+
+ def deactivate(*args)
+ @chart.legend_deactivate(*args)
+ end
+
+ def get(pos, y=nil)
+ @chart.legend_get(pos, y)
+ end
+ end
+
+ #################
+
+ class Pen < TkObject
+ (OBJ_ID = ['blt_chart_pen'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ PenID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ PenID_TBL.mutex.synchronize{ PenID_TBL.clear }
+ }
+
+ def self.id2obj(chart, id)
+ cpath = chart.path
+ PenID_TBL.mutex.synchronize{
+ return id unless PenID_TBL[cpath]
+ PenID_TBL[cpath][id]? PenID_TBL[cpath][id]: id
+ }
+ end
+
+ def self.new(chart, pen=nil, keys={})
+ if pen.kind_of?(Hash)
+ keys = pen
+ pen = nil
+ end
+ if keys
+ keys = _symbolkey2str(keys)
+ not_create = keys.delete('without_creating')
+ else
+ not_create = false
+ end
+
+ obj = nil
+ PenID_TBL.mutex.synchronize{
+ chart_path = chart.path
+ PenID_TBL[chart_path] ||= {}
+ if pen && PenID_TBL[chart_path][pen]
+ obj = PenID_TBL[chart_path][pen]
+ else
+ (obj = self.allocate).instance_eval{
+ if pen
+ @pen = @id = pen.to_s
+ else
+ OBJ_ID.mutex.synchronize{
+ @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
+ OBJ_ID[1].succ!
+ }
+ end
+ @path = @id
+ @parent = @chart = chart
+ @cpath = @chart.path
+ Pen::PenID_TBL[@cpath][@pen] = self
+ unless not_create
+ tk_call(@chart, 'pen', 'create', @pen, keys)
+ return obj
+ end
+ }
+ end
+ }
+
+ obj.configure(keys) if obj && ! keys.empty?
+ obj
+ end
+
+ def initialize(chart, pen=nil, keys={})
+ if pen.kind_of?(Hash)
+ keys = pen
+ pen = nil
+ end
+ if pen
+ @pen = @id = pen.to_s
+ else
+ OBJ_ID.mutex.synchronize{
+ @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
+ OBJ_ID[1].succ!
+ }
+ end
+ @path = @id
+ @parent = @chart = chart
+ @cpath = @chart.path
+ Pen::PenID_TBL[@cpath][@pen] = self
+ keys = _symbolkey2str(keys)
+ unless keys.delete('without_creating')
+ # @chart.pen_create(@pen, keys)
+ tk_call(@chart, 'pen', 'create', @pen, keys)
+ end
+ end
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ @chart.pen_cget_tkstring(@id, option)
+ end
+ def cget(option)
+ @chart.pen_cget(@id, option)
+ end
+ def cget_strict(option)
+ @chart.pen_cget_strict(@id, option)
+ end
+ def configure(key, value=None)
+ @chart.pen_configure(@id, key, value)
+ self
+ end
+ def configinfo(key=nil)
+ @chart.pen_configinfo(@id, key)
+ end
+ def current_configinfo(key=nil)
+ @chart.current_pen_configinfo(@id, key)
+ end
+
+ def delete
+ @chart.pen_delete(@id)
+ self
+ end
+
+ def name
+ @pen
+ end
+ end
+
+ #################
+
+ class Postscript < TkObject
+ PostscriptID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ PostscriptID_TBL.mutex.synchronize{ PostscriptID_TBL.clear }
+ }
+
+ def self.new(chart, keys={})
+ obj = nil
+ PostscriptID_TBL.mutex.synchronize{
+ unless (obj = PostscriptID_TBL[chart.path])
+ (obj = self.allocate).instance_eval{
+ @parent = @chart = chart
+ @cpath = @chart.path
+ @path = @id = 'postscript'
+ Postscript::PostscriptID_TBL[@cpath] = self
+ }
+ end
+ }
+ chart.postscript_configure(keys) if obj && ! keys.empty?
+ obj
+ end
+
+ def initialize(chart, keys={})
+ # dummy:: not called by 'new' method
+
+ @parent = @chart = chart
+ @cpath = @chart.path
+ # Postscript::PostscriptID_TBL[@cpath] = self
+ @chart.postscript_configure(keys) unless keys.empty?
+ @path = @id = 'postscript'
+ end
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ @chart.postscript_cget_tkstring(option)
+ end
+ def cget(option)
+ @chart.postscript_cget(option)
+ end
+ def cget_strict(option)
+ @chart.postscript_cget_strict(option)
+ end
+ def configure(key, value=None)
+ @chart.postscript_configure(key, value)
+ self
+ end
+ def configinfo(key=nil)
+ @chart.postscript_configinfo(key)
+ end
+ def current_configinfo(key=nil)
+ @chart.current_postscript_configinfo(key)
+ end
+
+ def output(file=nil, keys={})
+ if file.kind_of?(Hash)
+ keys = file
+ file = nil
+ end
+
+ ret = @chart.postscript_output(file, keys)
+
+ if file
+ self
+ else
+ ret
+ end
+ end
+ end
+
+ #################
+ class Marker < TkObject
+ extend Tk
+ extend TkItemFontOptkeys
+ extend TkItemConfigOptkeys
+
+ extend Tk::BLT::PlotComponent::OptKeys
+
+ MarkerTypeName = nil
+ MarkerTypeToClass = {}
+ MarkerID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ MarkerID_TBL.mutex.synchronize{ MarkerID_TBL.clear }
+ }
+
+ def Marker.type2class(type)
+ MarkerTypeToClass[type]
+ end
+
+ def Marker.id2obj(chart, id)
+ cpath = chart.path
+ MarkerID_TBL.mutex.synchronize{
+ if MarkerID_TBL[cpath]
+ MarkerID_TBL[cpath][id]? MarkerID_TBL[cpath][id]: id
+ else
+ id
+ end
+ }
+ end
+
+ def self._parse_create_args(keys)
+ fontkeys = {}
+ methodkeys = {}
+ if keys.kind_of? Hash
+ keys = _symbolkey2str(keys)
+
+ __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_optkey_aliases(nil).each{|alias_name, real_name|
+ alias_name = alias_name.to_s
+ if keys.has_key?(alias_name)
+ keys[real_name.to_s] = keys.delete(alias_name)
+ end
+ }
+
+ __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 = itemconfig_hash_kv(nil, keys)
+ else
+ args = []
+ end
+
+ [args, fontkeys, methodkeys]
+ end
+ private_class_method :_parse_create_args
+
+ def self.create(chart, keys={})
+ unless self::MarkerTypeName
+ fail RuntimeError, "#{self} is an abstract class"
+ end
+ args, fontkeys, methodkeys = _parse_create_args(keys)
+ idnum = tk_call_without_enc(chart.path, 'marker', 'create',
+ self::MarkerTypeName, *args)
+ chart.marker_configure(idnum, fontkeys) unless fontkeys.empty?
+ chart.marker_configure(idnum, methodkeys) unless methodkeys.empty?
+ idnum.to_i # 'item id' is an integer number
+ end
+
+ def self.create_type(chart, type, keys={})
+ args, fontkeys, methodkeys = _parse_create_args(keys)
+ idnum = tk_call_without_enc(chart.path, 'marker', 'create',
+ type, *args)
+ chart.marker_configure(idnum, fontkeys) unless fontkeys.empty?
+ chart.marker_configure(idnum, methodkeys) unless methodkeys.empty?
+ id = idnum.to_i # 'item id' is an integer number
+ obj = self.allocate
+ obj.instance_eval{
+ @parent = @chart = chart
+ @cpath = chart.path
+ @id = id
+ Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{
+ Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {}
+ Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self
+ }
+ }
+ obj
+ end
+
+ def initialize(parent, *args)
+ @parent = @chart = parent
+ @cpath = parent.path
+
+ @path = @id = create_self(*args) # an integer number as 'item id'
+ Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{
+ Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {}
+ Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self
+ }
+ end
+ def create_self(*args)
+ self.class.create(@chart, *args) # return an integer as 'item id'
+ end
+ private :create_self
+
+ def id
+ @id
+ end
+
+ def to_eval
+ @id
+ end
+
+ def cget_tkstring(option)
+ @chart.marker_cget_tkstring(@id, option)
+ end
+ def cget(option)
+ @chart.marker_cget(@id, option)
+ end
+ def cget_strict(option)
+ @chart.marker_cget_strict(@id, option)
+ end
+ def configure(key, value=None)
+ @chart.marker_configure(@id, key, value)
+ self
+ end
+ def configinfo(key=nil)
+ @chart.marker_configinfo(@id, key)
+ end
+ def current_configinfo(key=nil)
+ @chart.current_marker_configinfo(@id, key)
+ end
+
+ def after(target=None)
+ @chart.marker_after(@id, target)
+ end
+
+ def before(target=None)
+ @chart.marker_before(@id, target)
+ end
+
+ def delete
+ @chart.marker_delete(@id)
+ end
+
+ def exist?
+ @chart.marker_exist(@id)
+ end
+
+ def type
+ @chart.marker_type(@id)
+ end
+ end
+
+ class TextMarker < Marker
+ MarkerTypeName = 'text'.freeze
+ MarkerTypeToClass[MarkerTypeName] = self
+ end
+ class LineMarker < Marker
+ MarkerTypeName = 'line'.freeze
+ MarkerTypeToClass[MarkerTypeName] = self
+ end
+ class BitmapMarker < Marker
+ MarkerTypeName = 'bitmap'.freeze
+ MarkerTypeToClass[MarkerTypeName] = self
+ end
+ class ImageMarker < Marker
+ MarkerTypeName = 'image'.freeze
+ MarkerTypeToClass[MarkerTypeName] = self
+ end
+ class PolygonMarker < Marker
+ MarkerTypeName = 'polygon'.freeze
+ MarkerTypeToClass[MarkerTypeName] = self
+ end
+ class WindowMarker < Marker
+ MarkerTypeName = 'window'.freeze
+ MarkerTypeToClass[MarkerTypeName] = self
+ end
+
+ #################
+
+ def __destroy_hook__
+ Axis::AxisID_TBL.delete(@path)
+ Crosshairs::CrosshairsID_TBL.delete(@path)
+ Element::ElementID_TBL.delete(@path)
+ GridLine::GridLineID_TBL.delete(@path)
+ Legend::LegendID_TBL.delete(@path)
+ Pen::PenID_TBL.delete(@path)
+ Postscript::PostscriptID_TBL.delete(@path)
+ Marker::MarkerID_TBL.delete(@path)
+ super()
+ end
+
+ #################
+
+ def tagid(tag)
+ if tag.kind_of?(Axis) ||
+ tag.kind_of?(Crosshairs) ||
+ tag.kind_of?(Element) ||
+ tag.kind_of?(GridLine) ||
+ tag.kind_of?(Legend) ||
+ tag.kind_of?(Pen) ||
+ tag.kind_of?(Postscript) ||
+ tag.kind_of?(Marker)
+ tag.id
+ else
+ tag # maybe an Array of configure parameters
+ end
+ end
+
+ def _component_bind(target, tag, context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind([path, target, 'bind', tagid(tag)], context, cmd, *args)
+ self
+ end
+ def _component_bind_append(target, tag, context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append([path, target, 'bind', tagid(tag)], context, cmd, *args)
+ self
+ end
+ def _component_bind_remove(target, tag, context)
+ _bind_remove([path, target, 'bind', tagid(tag)], context)
+ self
+ end
+ def _component_bindinfo(target, tag, context=nil)
+ _bindinfo([path, target, 'bind', tagid(tag)], context)
+ end
+ private :_component_bind, :_component_bind_append
+ private :_component_bind_remove, :_component_bindinfo
+
+ def axis_bind(tag, context, *args)
+ _component_bind('axis', tag, context, *args)
+ end
+ def axis_bind_append(tag, context, *args)
+ _component_bind_append('axis', tag, context, *args)
+ end
+ def axis_bind_remove(tag, context)
+ _component_bind_remove('axis', tag, context)
+ end
+ def axis_bindinfo(tag, context=nil)
+ _component_bindinfo('axis', tag, context)
+ end
+
+ def element_bind(tag, context, *args)
+ _component_bind('element', tag, context, *args)
+ end
+ def element_bind_append(tag, context, *args)
+ _component_bind_append('element', tag, context, *args)
+ end
+ def element_bind_remove(tag, context)
+ _component_bind_remove('element', tag, context)
+ end
+ def element_bindinfo(tag, context=nil)
+ _component_bindinfo('element', tag, context)
+ end
+
+ def bar_bind(tag, context, *args)
+ _component_bind('bar', tag, context, *args)
+ end
+ def bar_bind_append(tag, context, *args)
+ _component_bind_append('bar', tag, context, *args)
+ end
+ def bar_bind_remove(tag, context)
+ _component_bind_remove('bar', tag, context)
+ end
+ def bar_bindinfo(tag, context=nil)
+ _component_bindinfo('bar', tag, context)
+ end
+
+ def line_bind(tag, context, *args)
+ _component_bind('line', tag, context, *args)
+ end
+ def line_bind_append(tag, context, *args)
+ _component_bind_append('line', tag, context, *args)
+ end
+ def line_bind_remove(tag, context)
+ _component_bind_remove('line', tag, context)
+ end
+ def line_bindinfo(tag, context=nil)
+ _component_bindinfo('line', tag, context)
+ end
+
+ def legend_bind(tag, context, *args)
+ _component_bind('legend', tag, context, *args)
+ end
+ def legend_bind_append(tag, context, *args)
+ _component_bind_append('legend', tag, context, *args)
+ end
+ def legend_bind_remove(tag, context)
+ _component_bind_remove('legend', tag, context)
+ end
+ def legend_bindinfo(tag, context=nil)
+ _component_bindinfo('legend', tag, context)
+ end
+
+ def marker_bind(tag, context, *args)
+ _component_bind('marker', tag, context, *args)
+ end
+ def marker_bind_append(tag, context, *args)
+ _component_bind_append('marker', tag, context, *args)
+ end
+ def marker_bind_remove(tag, context)
+ _component_bind_remove('marker', tag, context)
+ end
+ def marker_bindinfo(tag, context=nil)
+ _component_bindinfo('marker', tag, context)
+ end
+
+ ###################
+
+ def axis_create(id=nil, keys={})
+ # tk_send('axis', 'create', tagid(id), keys)
+ Tk::BLT::PlotComponent::Axis.new(self, tagid(id), keys)
+ end
+ def axis_delete(*ids)
+ tk_send('axis', 'delete', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def axis_invtransform(id, val)
+ list(tk_send('axis', 'invtransform', tagid(id), val))
+ end
+ def axis_limits(id)
+ list(tk_send('axis', 'limits', tagid(id)))
+ end
+ def axis_names(*pats)
+ simplelist(tk_send('axis', 'names',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|axis|
+ Tk::BLT::PlotComponent::Axis.id2obj(self, axis)
+ }
+ end
+ def axis_transform(id, val)
+ list(tk_send('axis', 'transform', tagid(id), val))
+ end
+ def axis_view(id)
+ tk_send('axis', 'view', tagid(id))
+ self
+ end
+ def axis_use(id, target=nil)
+ if target
+ Tk::BLT::PlotComponent::Axis.id2obj(self,
+ tk_send('axis', 'use',
+ tagid(id), tagid(target)))
+ else
+ Tk::BLT::PlotComponent::Axis.id2obj(self,
+ tk_send('axis', 'use', tagid(id)))
+ end
+ end
+
+ ###################
+
+ def crosshairs_off
+ tk_send_without_enc('crosshairs', 'off')
+ self
+ end
+ def crosshairs_on
+ tk_send_without_enc('crosshairs', 'on')
+ self
+ end
+ def crosshairs_toggle
+ tk_send_without_enc('crosshairs', 'toggle')
+ self
+ end
+
+ ###################
+
+ def element_create(id=nil, keys={})
+ # tk_send('element', 'create', tagid(id), keys)
+ Tk::BLT::PlotComponent::Element.new(self, tagid(id), keys)
+ end
+ def element_activate(*args)
+ if args.empty?
+ list(tk_send('element', 'activate')).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ else
+ # id, *indices
+ id = args.shift
+ tk_send('element', 'activate', tagid(id), *args)
+ end
+ end
+ def element_closest(x, y, var, *args)
+ if args[-1].kind_of?(Hash)
+ keys = args.pop
+ bool(tk_send('element', 'closest', x, y, var,
+ *(hash_kv(keys).concat(args.collect{|id| tagid(id)}))))
+ else
+ bool(tk_send('element', 'closest', x, y, var,
+ *(args.collect{|id| tagid(id)})))
+ end
+ end
+ def element_deactivate(*ids)
+ tk_send('element', 'deactivate', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def element_delete(*ids)
+ tk_send('element', 'delete', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def element_exist?(id)
+ bool(tk_send('element', 'exists', tagid(id)))
+ end
+ def element_names(*pats)
+ simplelist(tk_send('element', 'names',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ end
+ def element_show(*names)
+ if names.empty?
+ simplelist(tk_send('element', 'show'))
+ else
+ tk_send('element', 'show', *(names.collect{|n| tagid(n)}))
+ self
+ end
+ end
+ def element_type(id)
+ tk_send('element', 'type', tagid(id))
+ end
+
+ ###################
+
+ def bar_create(id=nil, keys={})
+ # tk_send('bar', 'create', tagid(id), keys)
+ Tk::BLT::PlotComponent::Bar.new(self, tagid(id), keys)
+ end
+ alias bar bar_create
+ def bar_activate(*args)
+ if args.empty?
+ list(tk_send('bar', 'activate')).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ else
+ # id, *indices
+ id = args.shift
+ tk_send('bar', 'activate', tagid(id), *args)
+ end
+ end
+ def bar_closest(x, y, var, *args)
+ if args[-1].kind_of?(Hash)
+ keys = args.pop
+ bool(tk_send('bar', 'closest', x, y, var,
+ *(hash_kv(keys).concat(args.collect{|id| tagid(id)}))))
+ else
+ bool(tk_send('bar', 'closest', x, y, var,
+ *(args.collect{|id| tagid(id)})))
+ end
+ end
+ def bar_deactivate(*ids)
+ tk_send('bar', 'deactivate', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def bar_delete(*ids)
+ tk_send('bar', 'delete', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def bar_exist?(id)
+ bool(tk_send('bar', 'exists', tagid(id)))
+ end
+ def bar_names(*pats)
+ simplelist(tk_send('bar', 'names',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ end
+ def bar_show(*names)
+ if names.empty?
+ simplelist(tk_send('bar', 'show'))
+ else
+ tk_send('bar', 'show', *(names.collect{|n| tagid(n)}))
+ self
+ end
+ end
+ def bar_type(id)
+ tk_send('bar', 'type', tagid(id))
+ end
+
+ ###################
+
+ def line_create(id=nil, keys={})
+ # tk_send('line', 'create', tagid(id), keys)
+ Tk::BLT::PlotComponent::Line.new(self, tagid(id), keys)
+ end
+ alias bar line_create
+ def line_activate(*args)
+ if args.empty?
+ list(tk_send('line', 'activate')).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ else
+ # id, *indices
+ id = args.shift
+ tk_send('line', 'activate', tagid(id), *args)
+ end
+ end
+ def line_closest(x, y, var, *args)
+ if args[-1].kind_of?(Hash)
+ keys = args.pop
+ bool(tk_send('line', 'closest', x, y, var,
+ *(hash_kv(keys).concat(args.collect{|id| tagid(id)}))))
+ else
+ bool(tk_send('line', 'closest', x, y, var,
+ *(args.collect{|id| tagid(id)})))
+ end
+ end
+ def line_deactivate(*ids)
+ tk_send('line', 'deactivate', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def line_delete(*ids)
+ tk_send('line', 'delete', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def line_exist?(id)
+ bool(tk_send('line', 'exists', tagid(id)))
+ end
+ def line_names(*pats)
+ simplelist(tk_send('line', 'names',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ end
+ def line_show(*names)
+ if names.empty?
+ simplelist(tk_send('line', 'show'))
+ else
+ tk_send('line', 'show', *(names.collect{|n| tagid(n)}))
+ self
+ end
+ end
+ def line_type(id)
+ tk_send('line', 'type', tagid(id))
+ end
+
+ ###################
+
+ def gridline_off
+ tk_send_without_enc('grid', 'off')
+ self
+ end
+ def gridline_on
+ tk_send_without_enc('grid', 'on')
+ self
+ end
+ def gridline_toggle
+ tk_send_without_enc('grid', 'toggle')
+ self
+ end
+
+ ###################
+
+ def legend_window_create(parent=nil, keys=nil)
+ if parent.kind_of?(Hash)
+ keys = _symbolkey2str(parent)
+ parent = keys.delete('parent')
+ widgetname = keys.delete('widgetname')
+ keys.delete('without_creating')
+ elsif keys
+ keys = _symbolkey2str(keys)
+ widgetname = keys.delete('widgetname')
+ keys.delete('without_creating')
+ end
+
+ legend = self.class.new(parent, :without_creating=>true,
+ :widgetname=>widgetname)
+ class << legend
+ def __destroy_hook__
+ TkCore::INTERP.tk_windows.delete(@path)
+ end
+ end
+
+ if keys
+ self.legend_configure(keys.update('position'=>legend))
+ else
+ self.legend_configure('position'=>legend)
+ end
+ legend
+ end
+
+ def legend_activate(*pats)
+ list(tk_send('legend', 'activate',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ end
+ def legend_deactivate(*pats)
+ list(tk_send('legend', 'deactivate',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|elem|
+ Tk::BLT::PlotComponent::Element.id2obj(self, elem)
+ }
+ end
+ def legend_get(pos, y=nil)
+ if y
+ Tk::BLT::PlotComponent::Element.id2obj(self,
+ tk_send('legend', 'get',
+ _at(pos, y)))
+ else
+ Tk::BLT::PlotComponent::Element.id2obj(self,
+ tk_send('legend', 'get', pos))
+ end
+ end
+
+ ###################
+
+ def pen_create(id=nil, keys={})
+ # tk_send('pen', 'create', tagid(id), keys)
+ Tk::BLT::PlotComponent::Pen.new(self, tagid(id), keys)
+ end
+ def pen_delete(*ids)
+ tk_send('pen', 'delete', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def pen_names(*pats)
+ simplelist(tk_send('pen', 'names',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|pen|
+ Tk::BLT::PlotComponent::Pen.id2obj(self, pen)
+ }
+ end
+
+ ###################
+
+ def postscript_output(file=nil, keys={})
+ if file.kind_of?(Hash)
+ keys = file
+ file = nil
+ end
+
+ if file
+ tk_send('postscript', 'output', file, keys)
+ self
+ else
+ tk_send('postscript', 'output', keys)
+ end
+ end
+
+ ###################
+
+ def marker_create(type, keys={})
+ case type
+ when :text, 'text'
+ Tk::BLT::PlotComponent::TextMarker.new(self, keys)
+ when :line, 'line'
+ Tk::BLT::PlotComponent::LineMarker.new(self, keys)
+ when :bitmap, 'bitmap'
+ Tk::BLT::PlotComponent::BitmapMarker.new(self, keys)
+ when :image, 'image'
+ Tk::BLT::PlotComponent::ImageMarker.new(self, keys)
+ when :polygon, 'polygon'
+ Tk::BLT::PlotComponent::PolygonMarker.new(self, keys)
+ when :window, 'window'
+ Tk::BLT::PlotComponent::WindowMarker.new(self, keys)
+ else
+ if type.kind_of?(Tk::BLT::PlotComponent::Marker)
+ type.new(self, keys)
+ else
+ Tk::BLT::PlotComponent::Marker.create_type(self, type, keys)
+ end
+ end
+ end
+ def marker_after(id, target=nil)
+ if target
+ tk_send_without_enc('marker', 'after', tagid(id), tagid(target))
+ else
+ tk_send_without_enc('marker', 'after', tagid(id))
+ end
+ self
+ end
+ def marker_before(id, target=None)
+ if target
+ tk_send_without_enc('marker', 'before', tagid(id), tagid(target))
+ else
+ tk_send_without_enc('marker', 'before', tagid(id))
+ end
+ self
+ end
+ def marker_delete(*ids)
+ tk_send('marker', 'delete', *(ids.collect{|id| tagid(id)}))
+ self
+ end
+ def marker_exist?(id)
+ bool(tk_send('marker', 'exists', tagid(id)))
+ end
+ def marker_names(*pats)
+ simplelist(tk_send('marker', 'names',
+ *(pats.collect{|pat| tagid(pat)}))).collect{|id|
+ Tk::BLT::PlotComponent::Marker.id2obj(self, id)
+ }
+ end
+ def marker_type(id)
+ tk_send('marker', 'type', tagid(id))
+ end
+
+ ###################
+
+ def xaxis_cget_tkstring(option)
+ itemcget_tkstring('xaxis', option)
+ end
+ def xaxis_cget(option)
+ itemcget('xaxis', option)
+ end
+ def xaxis_cget_strict(option)
+ itemcget_strict('xaxis', option)
+ end
+ def xaxis_configure(slot, value=None)
+ if slot.kind_of?(Hash)
+ slot = _symbolkey2str(slot)
+ if cmd = slot.delete('command')
+ slot['command'] = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ elsif slot == :command || slot == 'command'
+ cmd = value
+ value = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ itemconfigure('xaxis', slot, value)
+ end
+ def xaxis_configinfo(slot=nil)
+ itemconfiginfo('xaxis', slot)
+ end
+ def current_xaxis_configinfo(slot=nil)
+ current_itemconfiginfo('xaxis', slot)
+ end
+ def xaxis_bind(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind([path, 'xaxis', 'bind'], context, cmd, *args)
+ self
+ end
+ def xaxis_bind_append(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append([path, 'xaxis', 'bind'], context, cmd, *args)
+ self
+ end
+ def xaxis_bind_remove(context)
+ _bind_remove([path, 'xaxis', 'bind'], context)
+ self
+ end
+ def xaxis_bindinfo(context=nil)
+ _bindinfo([path, 'xaxis', 'bind'], context)
+ end
+ def xaxis_invtransform(val)
+ list(tk_send('xaxis', 'invtransform', val))
+ end
+ def xaxis_limits
+ list(tk_send('xaxis', 'limits'))
+ end
+ def xaxis_transform(val)
+ list(tk_send('xaxis', 'transform', val))
+ end
+ def xaxis_use(target=nil)
+ if target
+ Tk::BLT::PlotComponent::Axis.id2obj(self,
+ tk_send('xaxis', 'use',
+ tagid(target)))
+ else
+ Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('xaxis', 'use'))
+ end
+ end
+
+ def x2axis_cget_tkstring(option)
+ itemcget_tkstring('x2axis', option)
+ end
+ def x2axis_cget(option)
+ itemcget('x2axis', option)
+ end
+ def x2axis_cget_strict(option)
+ itemcget_strict('x2axis', option)
+ end
+ def x2axis_configure(slot, value=None)
+ if slot.kind_of?(Hash)
+ slot = _symbolkey2str(slot)
+ if cmd = slot.delete('command')
+ slot['command'] = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ elsif slot == :command || slot == 'command'
+ cmd = value
+ value = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ itemconfigure('x2axis', slot, value)
+ end
+ def x2axis_configinfo(slot=nil)
+ itemconfiginfo('x2axis', slot)
+ end
+ def current_x2axis_configinfo(slot=nil)
+ current_itemconfiginfo('x2axis', slot)
+ end
+ def x2axis_bind(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind([path, 'x2axis', 'bind'], context, cmd, *args)
+ self
+ end
+ def x2axis_bind_append(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append([path, 'x2axis', 'bind'], context, cmd, *args)
+ self
+ end
+ def x2axis_bind_remove(context)
+ _bind_remove([path, 'x2axis', 'bind'], context)
+ self
+ end
+ def x2axis_bindinfo(context=nil)
+ _bindinfo([path, 'x2axis', 'bind'], context)
+ end
+ def x2axis_invtransform(val)
+ list(tk_send('x2axis', 'invtransform', val))
+ end
+ def x2axis_limits
+ list(tk_send('x2axis', 'limits'))
+ end
+ def x2axis_transform(val)
+ list(tk_send('x2axis', 'transform', val))
+ end
+ def x2axis_use(target=nil)
+ if target
+ Tk::BLT::PlotComponent::Axis.id2obj(self,
+ tk_send('x2axis', 'use',
+ tagid(target)))
+ else
+ Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('x2axis', 'use'))
+ end
+ end
+
+ def yaxis_cget_tkstring(option)
+ itemcget_tkstring('yaxis', option)
+ end
+ def yaxis_cget(option)
+ itemcget('yaxis', option)
+ end
+ def yaxis_cget_strict(option)
+ itemcget_strict('yaxis', option)
+ end
+ def yaxis_configure(slot, value=None)
+ if slot.kind_of?(Hash)
+ slot = _symbolkey2str(slot)
+ if cmd = slot.delete('command')
+ slot['command'] = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ elsif slot == :command || slot == 'command'
+ cmd = value
+ value = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ itemconfigure('yaxis', slot, value)
+ end
+ def yaxis_configinfo(slot=nil)
+ itemconfiginfo('yaxis', slot)
+ end
+ def current_yaxis_configinfo(slot=nil)
+ current_itemconfiginfo('yaxis', slot)
+ end
+ def yaxis_bind(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind([path, 'yaxis', 'bind'], context, cmd, *args)
+ self
+ end
+ def yaxis_bind_append(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append([path, 'yaxis', 'bind'], context, cmd, *args)
+ self
+ end
+ def yaxis_bind_remove(context)
+ _bind_remove([path, 'yaxis', 'bind'], context)
+ self
+ end
+ def yaxis_bindinfo(context=nil)
+ _bindinfo([path, 'yaxis', 'bind'], context)
+ end
+ def yaxis_invtransform(val)
+ list(tk_send('yaxis', 'invtransform', val))
+ end
+ def yaxis_limits
+ list(tk_send('yaxis', 'limits'))
+ end
+ def yaxis_transform(val)
+ list(tk_send('yaxis', 'transform', val))
+ end
+ def yaxis_use(target=nil)
+ if target
+ Tk::BLT::PlotComponent::Axis.id2obj(self,
+ tk_send('yaxis', 'use',
+ tagid(target)))
+ else
+ Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('yaxis', 'use'))
+ end
+ end
+
+ def y2axis_cget_tkstring(option)
+ itemcget_tkstring('y2axis', option)
+ end
+ def y2axis_cget(option)
+ itemcget('y2axis', option)
+ end
+ def y2axis_cget_strict(option)
+ itemcget_strict('y2axis', option)
+ end
+ def y2axis_configure(slot, value=None)
+ if slot.kind_of?(Hash)
+ slot = _symbolkey2str(slot)
+ if cmd = slot.delete('command')
+ slot['command'] = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ elsif slot == :command || slot == 'command'
+ cmd = value
+ value = proc{|w, tick|
+ cmd.call(TkComm.window(w), TkComm.num_or_str(tick))
+ }
+ end
+ itemconfigure('y2axis', slot, value)
+ end
+ def y2axis_configinfo(slot=nil)
+ axis_configinfo('y2axis', slot)
+ end
+ def current_y2axis_configinfo(slot=nil)
+ current_itemconfiginfo('y2axis', slot)
+ end
+ def y2axis_bind(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind([path, 'y2axis', 'bind'], context, cmd, *args)
+ self
+ end
+ def y2axis_bind_append(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append([path, 'y2axis', 'bind'], context, cmd, *args)
+ self
+ end
+ def y2axis_bind_remove(context)
+ _bind_remove([path, 'y2axis', 'bind'], context)
+ self
+ end
+ def y2axis_bindinfo(context=nil)
+ _bindinfo([path, 'y2axis', 'bind'], context)
+ end
+ def y2axis_invtransform(val)
+ list(tk_send('y2axis', 'invtransform', val))
+ end
+ def y2axis_limits
+ list(tk_send('y2axis', 'limits'))
+ end
+ def y2axis_transform(val)
+ list(tk_send('y2axis', 'transform', val))
+ end
+ def y2axis_use(target=nil)
+ if target
+ Tk::BLT::PlotComponent::Axis.id2obj(self,
+ tk_send('y2axis', 'use',
+ tagid(target)))
+ else
+ Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('y2axis', 'use'))
+ end
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/container.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/container.rb
new file mode 100644
index 0000000..be05828
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/container.rb
@@ -0,0 +1,28 @@
+#
+# tkextlib/blt/container.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Container < TkWindow
+ TkCommandNames = ['::blt::container'.freeze].freeze
+ WidgetClassName = 'Container'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ def __strval_optkeys
+ super() << 'name'
+ end
+ private :__strval_optkeys
+
+ def find_command(pat)
+ Hash[*simplelist(tk_send_without_enc('find', '-command', pat))]
+ end
+
+ def find_name(pat)
+ Hash[*simplelist(tk_send_without_enc('find', '-name', pat))]
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/cutbuffer.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/cutbuffer.rb
new file mode 100644
index 0000000..1cc39df
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/cutbuffer.rb
@@ -0,0 +1,23 @@
+#
+# tkextlib/blt/cutbuffer.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module CutBuffer
+ TkCommandNames = ['::blt::cutbuffer'.freeze].freeze
+
+ def self.get(num = 0)
+ Tk.tk_call('::blt::cutbuffer', 'get', num)
+ end
+ def self.rotate(count = 1)
+ Tk.tk_call('::blt::cutbuffer', 'rotate', count)
+ end
+ def self.set(val, num = 0)
+ Tk.tk_call('::blt::cutbuffer', 'set', val, num)
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/dragdrop.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/dragdrop.rb
new file mode 100644
index 0000000..aa5c565
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/dragdrop.rb
@@ -0,0 +1,269 @@
+#
+# tkextlib/blt/dragdrop.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/itemconfig'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module DragDrop
+ extend TkCore
+
+ TkCommandNames = ['::blt::drag&drop'.freeze].freeze
+
+ class Token < TkWindow
+ WidgetClassName = 'DragDropToken'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ def initialize(arg)
+ if arg.kind_of?(Hash) # arg is a hash includes the widgetpath of token
+ arg = _symbolkey2str(arg)
+ install_win(nil, arg['widgetname'])
+ else # arg is a drag&drop source
+ tk_call('::blt::drag&drop', 'source', arg)
+ install_win(nil, tk_call('::blt::drag&drop', 'token', arg))
+ end
+ end
+ end
+
+ ###################################
+
+ extend TkItemConfigMethod
+ extend Tk::ValidateConfigure
+
+ class << self
+ def __item_config_cmd(id) # id := ['source'|'target', win]
+ ['::blt::drag&drop', id[0], id[1]]
+ end
+ private :__item_config_cmd
+
+ def __item_boolval_optkeys(id)
+ super(id) << 'selftarget'
+ end
+ private :__item_boolval_optkeys
+
+ def __item_listval_optkeys(id)
+ super(id) << 'send'
+ end
+ private :__item_listval_optkeys
+
+ def __item_strval_optkeys(id)
+ super(id) << 'rejectbg' << 'rejectfg' << 'tokenbg'
+ end
+ private :__item_strval_optkeys
+
+ undef itemcget
+ undef itemcget_tkstring
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ def source_configure(win, slot, value=None)
+ itemconfigure(['source', win], slot, value)
+ end
+ def source_configinfo(win, slot=nil)
+ itemconfiginfo(['source', win], slot)
+ end
+ def current_source_configinfo(win, slot=nil)
+ current_itemconfiginfo(['source', win], slot)
+ end
+ end
+
+ class PackageCommand < TkValidateCommand
+ class ValidateArgs < TkUtil::CallbackSubst
+ KEY_TBL = [
+ [ ?t, ?w, :token ],
+ [ ?W, ?w, :widget ],
+ nil
+ ]
+
+ PROC_TBL = [
+ [ ?w, TkComm.method(:window) ],
+ nil
+ ]
+
+=begin
+ # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
+ KEY_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
+ end
+ inf
+ }
+
+ PROC_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ end
+ inf
+ }
+=end
+
+ _setup_subst_table(KEY_TBL, PROC_TBL)
+
+ def self.ret_val(val)
+ val
+ end
+ end
+
+ def self._config_keys
+ ['packagecmd']
+ end
+ end
+
+ class SiteCommand < TkValidateCommand
+ class ValidateArgs < TkUtil::CallbackSubst
+ KEY_TBL = [
+ [ ?s, ?b, :compatible ],
+ [ ?t, ?w, :token ],
+ nil
+ ]
+
+ PROC_TBL = [
+ [ ?b, TkComm.method(:bool) ],
+ [ ?w, TkComm.method(:window) ],
+ nil
+ ]
+
+=begin
+ # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
+ KEY_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
+ end
+ inf
+ }
+
+ PROC_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ end
+ inf
+ }
+=end
+
+ _setup_subst_table(KEY_TBL, PROC_TBL)
+
+ def self.ret_val(val)
+ val
+ end
+ end
+
+ def self._config_keys
+ ['sitecmd']
+ end
+ end
+
+ def self.__validation_class_list
+ super() << PackageCommand << SiteCommand
+ end
+
+ class << self
+ Tk::ValidateConfigure.__def_validcmd(binding, PackageCommand)
+ Tk::ValidateConfigure.__def_validcmd(binding, SiteCommand)
+ end
+
+ ###################################
+
+ class DnD_Handle < TkUtil::CallbackSubst
+ KEY_TBL = [
+ [ ?i, ?s, :ip_name ],
+ [ ?v, ?v, :value ],
+ [ ?W, ?w, :widget ],
+ nil
+ ]
+
+ PROC_TBL = [
+ [ ?i, TkComm.method(:string) ],
+ [ ?v, TkComm.method(:tk_tcl2ruby) ],
+ [ ?w, TkComm.method(:window) ],
+ nil
+ ]
+
+=begin
+ # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
+ KEY_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
+ end
+ inf
+ }
+
+ PROC_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ end
+ inf
+ }
+=end
+
+ _setup_subst_table(KEY_TBL, PROC_TBL)
+ end
+
+ def self.source_handler(win, datatype, cmd=Proc.new, *args)
+ _bind_for_event_class(DnD_Handle,
+ ['::blt::drag&drop', 'source', win, 'handler'],
+ cmd, *args)
+ end
+
+ def self.target_handler(win, datatype, cmd=Proc.new, *args)
+ _bind_for_event_class(DnD_Handle,
+ ['::blt::drag&drop', 'target', win, 'handler'],
+ cmd, *args)
+ end
+
+ ###################################
+
+ def self.init_source(win)
+ tk_call('::blt::drag&drop', 'source', win)
+ end
+
+ def self.source()
+ list(tk_call('::blt::drag&drop', 'source'))
+ end
+
+ def self.source_handler_list(win)
+ simplelist(tk_call('::blt::drag&drop', 'source', win, 'handler'))
+ end
+ def self.source_handler_info(win, type)
+ tk_tcl2ruby(tk_call('::blt::drag&drop', 'source', win, 'handler', type))
+ end
+
+ def self.target
+ list(tk_call('::blt::drag&drop', 'target'))
+ end
+ def self.target_handler_list(win)
+ simplelist(tk_call('::blt::drag&drop', 'target', win, 'handler'))
+ end
+
+ def self.handle_target(win, type, val=None)
+ tk_call('::blt::drag&drop', 'target', win, 'handle', type, val)
+ end
+
+ def self.token(win)
+ window(tk_call('::blt::drag&drop', 'token', win))
+ end
+
+ def self.drag(win, x, y)
+ tk_call('::blt::drag&drop', 'drag', win, x, y)
+ end
+ def self.drop(win, x, y)
+ tk_call('::blt::drag&drop', 'drop', win, x, y)
+ end
+
+ def self.errors(cmd=Proc.new)
+ tk_call('::blt::drag&drop', 'errors', cmd)
+ end
+
+ def self.active
+ bool(tk_call('::blt::drag&drop', 'active'))
+ end
+
+ def self.location(x=None, y=None)
+ list(tk_call('::blt::drag&drop', 'location', x, y))
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/eps.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/eps.rb
new file mode 100644
index 0000000..0dba87a
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/eps.rb
@@ -0,0 +1,32 @@
+#
+# tkextlib/blt/eps.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/canvas'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class EPS < TkcItem
+ CItemTypeName = 'eps'.freeze
+ CItemTypeToClass[CItemTypeName] = self
+ end
+end
+
+class Tk::Canvas
+ alias __BLT_EPS_item_strval_optkeys __item_strval_optkeys
+ def __item_strval_optkeys(id)
+ __BLT_EPS_item_strval_optkeys(id) + [
+ 'shadowcolor', 'title', 'titlecolor'
+ ]
+ end
+ private :__item_strval_optkeys
+
+ alias __BLT_EPS_item_boolval_optkeys __item_boolval_optkeys
+ def __item_boolval_optkeys(id)
+ __BLT_EPS_item_boolval_optkeys(id) + ['showimage']
+ end
+ private :__item_boolval_optkeys
+end
+
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/graph.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/graph.rb
new file mode 100644
index 0000000..6bd4424
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/graph.rb
@@ -0,0 +1,67 @@
+#
+# tkextlib/blt/graph.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+require 'tkextlib/blt/component.rb'
+
+module Tk::BLT
+ class Graph < TkWindow
+ TkCommandNames = ['::blt::graph'.freeze].freeze
+ WidgetClassName = 'Graph'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ include PlotComponent
+ include GraphCommand
+
+ def __boolval_optkeys
+ ['bufferelements', 'invertxy']
+ end
+ private :__boolval_optkeys
+
+ def __strval_optkeys
+ ['text', 'label', 'title', 'file', 'plotbackground']
+ end
+ private :__strval_optkeys
+
+=begin
+ BarElement_ID = ['blt_graph_bar'.freeze, TkUtil.untrust('00000')].freeze
+
+ def bar(elem=nil, keys={})
+ if elem.kind_of?(Hash)
+ keys = elem
+ elem = nil
+ end
+ unless elem
+ elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze
+ BarElement_ID[1].succ!
+ end
+ tk_send('bar', elem, keys)
+ Element.new(self, elem, :without_creating=>true)
+ end
+=end
+
+ def extents(item)
+ num_or_str(tk_send_without_enc('extents', item))
+ end
+
+ def invtransform(x, y)
+ list(tk_send_without_enc('invtransform', x, y))
+ end
+
+ def inside(x, y)
+ bool(tk_send_without_enc('inside', x, y))
+ end
+
+ def snap(output, keys={})
+ tk_send_without_enc('snap', *(hash_kv(keys, false) + output))
+ self
+ end
+
+ def transform(x, y)
+ list(tk_send_without_enc('transform', x, y))
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/htext.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/htext.rb
new file mode 100644
index 0000000..878bd99
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/htext.rb
@@ -0,0 +1,112 @@
+#
+# tkextlib/blt/htext.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/itemconfig.rb'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Htext<TkWindow
+ Htext_Var = TkVarAccess.new_hash('htext')
+ Htext_Widget = TkVarAccess.new('htext(widget)', :window)
+ Htext_File = TkVarAccess.new('htext(file)')
+ Htext_Line = TkVarAccess.new('htext(line)')
+
+ include TkItemConfigMethod
+ include Scrollable
+
+ TkCommandNames = ['::blt::htext'.freeze].freeze
+ WidgetClassName = 'Htext'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ alias window_cget_tkstring itemcget_tkstring
+ alias window_cget itemcget
+ alias window_cget_strict itemcget_strict
+ alias window_configure itemconfigure
+ alias window_configuinfo itemconfiginfo
+ alias current_window_configuinfo current_itemconfiginfo
+
+ def __strval_optkeys
+ super() << 'filename'
+ end
+ private :__strval_optkeys
+
+ def append(win, keys={})
+ tk_send('append', _epath(win), keys)
+ self
+ end
+
+ def goto_line(idx)
+ tk_send_without_enc('gotoline', idx)
+ self
+ end
+ def current_line
+ number(tk_send_without_enc('gotoline'))
+ end
+
+ def index(str)
+ number(tk_send('index', str))
+ end
+
+ def line_pos(str)
+ tk_send('linepos', str)
+ end
+
+ def range(from=None, to=None)
+ tk_send_without_enc('range', from, to)
+ end
+
+ def scan_mark(pos)
+ tk_send_without_enc('scan', 'mark', pos)
+ self
+ end
+
+ def scan_dragto(pos)
+ tk_send_without_enc('scan', 'dragto', pos)
+ self
+ end
+
+ def search(pat, from=None, to=None)
+ num = number(tk_send('search', pat, from, to))
+ (num < 0)? nil: num
+ 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_line(index)
+ tk_send_without_enc('selection', 'line', index)
+ self
+ end
+ def selection_present()
+ bool(tk_send_without_enc('selection', 'present'))
+ end
+ def selection_range(first, last)
+ tk_send_without_enc('selection', 'range', first, last)
+ self
+ end
+ def selection_to(index)
+ tk_send_without_enc('selection', 'to', index)
+ self
+ end
+ def selection_word(index)
+ tk_send_without_enc('selection', 'word', index)
+ self
+ end
+
+ def windows(pat=None)
+ list(tk_send('windows', pat))
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/setup.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/setup.rb
new file mode 100644
index 0000000..ee406c6
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/setup.rb
@@ -0,0 +1,8 @@
+#
+# setup.rb -- setup script before calling TkPackage.require()
+#
+# If you need some setup operations (for example, add a library path
+# to the library search path) before using Tcl/Tk library packages
+# wrapped by Ruby scripts in this directory, please write the setup
+# operations in this file.
+#
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/spline.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/spline.rb
new file mode 100644
index 0000000..9f75a0b
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/spline.rb
@@ -0,0 +1,23 @@
+#
+# tkextlib/blt/spline.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module Spline
+ extend TkCore
+
+ TkCommandNames = ['::blt::spline'.freeze].freeze
+
+ def self.natural(x, y, sx, sy)
+ tk_call('::blt::spline', 'natural', x, y, sx, sy)
+ end
+
+ def self.quadratic(x, y, sx, sy)
+ tk_call('::blt::spline', 'quadratic', x, y, sx, sy)
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/stripchart.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/stripchart.rb
new file mode 100644
index 0000000..74093f1
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/stripchart.rb
@@ -0,0 +1,74 @@
+#
+# tkextlib/blt/stripchart.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+require 'tkextlib/blt/component.rb'
+
+module Tk::BLT
+ class Stripchart < TkWindow
+ TkCommandNames = ['::blt::stripchart'.freeze].freeze
+ WidgetClassName = 'Stripchart'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ include PlotComponent
+ include GraphCommand
+
+ def __boolval_optkeys
+ ['bufferelements', 'buffergraph', 'invertxy']
+ end
+ private :__boolval_optkeys
+
+ def __strval_optkeys
+ ['text', 'label', 'title', 'file',
+ 'background', 'plotbackground']
+ end
+ private :__strval_optkeys
+
+=begin
+ BarElement_ID = ['blt_stripchart_bar'.freeze, TkUtil.untrust('00000')].freeze
+
+ def bar(elem=nil, keys={})
+ if elem.kind_of?(Hash)
+ keys = elem
+ elem = nil
+ end
+ unless elem
+ elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze
+ BarElement_ID[1].succ!
+ end
+ tk_send('bar', elem, keys)
+ Element.new(self, elem, :without_creating=>true)
+ end
+=end
+
+ def extents(item)
+ num_or_str(tk_send_without_enc('extents', item))
+ end
+
+ def invtransform(x, y)
+ list(tk_send_without_enc('invtransform', x, y))
+ end
+
+ def inside(x, y)
+ bool(tk_send_without_enc('inside', x, y))
+ end
+
+ def metafile(file=None)
+ # Windows only
+ tk_send('metafile', file)
+ self
+ end
+
+ def snap(output, keys={})
+ tk_send_without_enc('snap', *(hash_kv(keys, false) + output))
+ self
+ end
+
+ def transform(x, y)
+ list(tk_send_without_enc('transform', x, y))
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/table.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/table.rb
new file mode 100644
index 0000000..205e29e
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/table.rb
@@ -0,0 +1,412 @@
+#
+# tkextlib/blt/table.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/itemconfig.rb'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module Table
+ include Tk
+ extend Tk
+ extend TkItemConfigMethod
+
+ TkCommandNames = ['::blt::table'.freeze].freeze
+
+ module TableContainer
+ def blt_table_add(*args)
+ Tk::BLT::Table.add(self, *args)
+ self
+ end
+
+ def blt_table_arrange()
+ Tk::BLT::Table.arrange(self)
+ self
+ end
+
+ def blt_table_cget_tkstring(*args)
+ Tk::BLT::Table.cget_tkstring(self, *args)
+ end
+ def blt_table_cget(*args)
+ Tk::BLT::Table.cget(self, *args)
+ end
+ def blt_table_cget_strict(*args)
+ Tk::BLT::Table.cget_strict(self, *args)
+ end
+
+ def blt_table_configure(*args)
+ Tk::BLT::Table.configure(self, *args)
+ self
+ end
+
+ def blt_table_configinfo(*args)
+ Tk::BLT::Table.configinfo(self, *args)
+ end
+
+ def blt_table_current_configinfo(*args)
+ Tk::BLT::Table.current_configinfo(self, *args)
+ end
+
+ def blt_table_locate(x, y)
+ Tk::BLT::Table.locate(self, x, y)
+ end
+
+ def blt_table_delete(*args)
+ Tk::BLT::Table.delete(self, *args)
+ self
+ end
+
+ def blt_table_extents(item)
+ Tk::BLT::Table.extents(self, item)
+ end
+
+ def blt_table_insert(*args)
+ Tk::BLT::Table.insert(self, *args)
+ self
+ end
+
+ def blt_table_insert_before(*args)
+ Tk::BLT::Table.insert_before(self, *args)
+ self
+ end
+
+ def blt_table_insert_after(*args)
+ Tk::BLT::Table.insert_after(self, *args)
+ self
+ end
+
+ def blt_table_join(first, last)
+ Tk::BLT::Table.join(self, first, last)
+ self
+ end
+
+ def blt_table_save()
+ Tk::BLT::Table.save(self)
+ end
+
+ def blt_table_search(*args)
+ Tk::BLT::Table.search(self, *args)
+ end
+
+ def blt_table_split(*args)
+ Tk::BLT::Table.split(self, *args)
+ self
+ end
+
+ def blt_table_itemcget_tkstring(*args)
+ Tk::BLT::Table.itemcget_tkstring(self, *args)
+ end
+ def blt_table_itemcget(*args)
+ Tk::BLT::Table.itemcget(self, *args)
+ end
+ def blt_table_itemcget_strict(*args)
+ Tk::BLT::Table.itemcget_strict(self, *args)
+ end
+
+ def blt_table_itemconfigure(*args)
+ Tk::BLT::Table.itemconfigure(self, *args)
+ self
+ end
+
+ def blt_table_itemconfiginfo(*args)
+ Tk::BLT::Table.itemconfiginfo(self, *args)
+ end
+
+ def blt_table_current_itemconfiginfo(*args)
+ Tk::BLT::Table.current_itemconfiginfo(self, *args)
+ end
+
+ def blt_table_iteminfo(item)
+ Tk::BLT::Table.iteminfo(self, item)
+ end
+ end
+ end
+end
+
+
+############################################
+class << Tk::BLT::Table
+ def __item_cget_cmd(id) # id := [ container, item ]
+ win = (id[0].kind_of?(TkWindow))? id[0].path: id[0].to_s
+ ['::blt::table', 'cget', win, id[1]]
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(id) # id := [ container, item, ... ]
+ container, *items = id
+ win = (container.kind_of?(TkWindow))? container.path: container.to_s
+ ['::blt::table', 'configure', win, *items]
+ end
+ private :__item_config_cmd
+
+ def __item_pathname(id)
+ win = (id[0].kind_of?(TkWindow))? id[0].path: id[0].to_s
+ win + ';'
+ end
+ private :__item_pathname
+
+ alias __itemcget_tkstring itemcget_tkstring
+ alias __itemcget itemcget
+ alias __itemcget_strict itemcget_strict
+ alias __itemconfigure itemconfigure
+ alias __itemconfiginfo itemconfiginfo
+ alias __current_itemconfiginfo current_itemconfiginfo
+
+ private :__itemcget_tkstring, :__itemcget, :__itemcget_strict
+ private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo
+
+ def __boolval_optkeys
+ super() << 'propagate'
+ end
+ private :__boolval_optkeys
+
+ def tagid(tag)
+ if tag.kind_of?(Array)
+ case tag[0]
+ when Integer
+ # [row, col]
+ tag.join(',')
+ when :c, :C, 'c', 'C', :r, :R, 'r', 'R'
+ # c0 or r1 or C*, and so on
+ tag.collect{|elem| elem.to_s}.join('')
+ else
+ tag
+ end
+ elsif tag.kind_of?(TkWindow)
+ _epath(tag)
+ else
+ tag
+ end
+ end
+
+ def tagid2obj(tagid)
+ tagid
+ end
+
+ ############################################
+
+ def cget_tkstring(container, option)
+ __itemcget_tkstring([container], option)
+ end
+ def cget(container, option)
+ __itemcget([container], option)
+ end
+ def cget_strict(container, option)
+ __itemcget_strict([container], option)
+ end
+
+ def configure(container, *args)
+ __itemconfigure([container], *args)
+ end
+
+ def configinfo(container, *args)
+ __itemconfiginfo([container], *args)
+ end
+
+ def current_configinfo(container, *args)
+ __current_itemconfiginfo([container], *args)
+ end
+
+ def itemcget_tkstring(container, item, option)
+ __itemcget_tkstring([container, tagid(item)], option)
+ end
+ def itemcget(container, item, option)
+ __itemcget([container, tagid(item)], option)
+ end
+ def itemcget_strict(container, item, option)
+ __itemcget_strict([container, tagid(item)], option)
+ end
+
+ def itemconfigure(container, *args)
+ if args[-1].kind_of?(Hash)
+ # container, item, item, ... , hash_optkeys
+ keys = args.pop
+ fail ArgumentError, 'no item is given' if args.empty?
+ id = [container]
+ args.each{|item| id << tagid(item)}
+ __itemconfigure(id, keys)
+ else
+ # container, item, item, ... , option, value
+ val = args.pop
+ opt = args.pop
+ fail ArgumentError, 'no item is given' if args.empty?
+ id = [container]
+ args.each{|item| id << tagid(item)}
+ __itemconfigure(id, opt, val)
+ end
+ container
+ end
+
+ def itemconfiginfo(container, *args)
+ slot = args[-1]
+ if slot.kind_of?(String) || slot.kind_of?(Symbol)
+ slot = slot.to_s
+ if slot[0] == ?. || slot =~ /^\d+,\d+$/ || slot =~ /^(c|C|r|R)(\*|\d+)/
+ # widget || row,col || Ci or Ri
+ slot = nil
+ else
+ # option
+ slot = args.pop
+ end
+ else
+ slot = nil
+ end
+
+ fail ArgumentError, 'no item is given' if args.empty?
+
+ id = [container]
+ args.each{|item| id << tagid(item)}
+ __itemconfiginfo(id, slot)
+ end
+
+ def current_itemconfiginfo(container, *args)
+ slot = args[-1]
+ if slot.kind_of?(String) || slot.kind_of?(Symbol)
+ slot = slot.to_s
+ if slot[0] == ?. || slot =~ /^\d+,\d+$/ || slot =~ /^(c|C|r|R)(\*|\d+)/
+ # widget || row,col || Ci or Ri
+ slot = nil
+ else
+ # option
+ slot = args.pop
+ end
+ else
+ slot = nil
+ end
+
+ fail ArgumentError, 'no item is given' if args.empty?
+
+ id = [container]
+ args.each{|item| id << tagid(item)}
+ __current_itemconfiginfo(id, slot)
+ end
+
+ def info(container)
+ ret = {}
+ inf = list(tk_call('::blt::table', 'info', container))
+ until inf.empty?
+ opt = inf.slice!(0..1)
+ ret[opt[1..-1]] = opt[1]
+ end
+ ret
+ end
+
+ def iteminfo(container, item)
+ inf = list(tk_call('::blt::table', 'info', container, tagid(item)).chomp)
+
+ ret = []
+ until inf.empty? || (inf[0].kind_of?(String) && inf[0] =~ /^-/)
+ ret << inf.shift
+ end
+
+ if inf.length > 1
+ keys = {}
+ while inf.length > 1
+ opt = inf.slice!(0..1)
+ keys[opt[0][1..-1]] = opt[1]
+ end
+ ret << keys
+ end
+
+ ret
+ end
+
+ ############################################
+
+ def create_container(container)
+ tk_call('::blt::table', container)
+ begin
+ class << container
+ include Tk::BLT::Table::TableContainer
+ end
+ rescue
+ warn('fail to include TableContainer methods (frozen object?)')
+ end
+ container
+ end
+
+ def add(container, *args)
+ if args.empty?
+ tk_call('::blt::table', container)
+ else
+ args = args.collect{|arg|
+ if arg.kind_of?(TkWindow)
+ _epath(arg)
+ elsif arg.kind_of?(Array) # index
+ arg.join(',')
+ else
+ arg
+ end
+ }
+ tk_call('::blt::table', container, *args)
+ end
+ container
+ end
+
+ def arrange(container)
+ tk_call('::blt::table', 'arrange', container)
+ container
+ end
+
+ def delete(container, *args)
+ tk_call('::blt::table', 'delete', container, *args)
+ end
+
+ def extents(container, item)
+ ret = []
+ inf = list(tk_call('::blt::table', 'extents', container, item))
+ ret << inf.slice!(0..4) until inf.empty?
+ ret
+ end
+
+ def forget(*wins)
+ wins = wins.collect{|win| _epath(win)}
+ tk_call('::blt::table', 'forget', *wins)
+ end
+
+ def insert(container, *args)
+ tk_call('::blt::table', 'insert', container, *args)
+ end
+
+ def insert_before(container, *args)
+ tk_call('::blt::table', 'insert', container, '-before', *args)
+ end
+
+ def insert_after(container, *args)
+ tk_call('::blt::table', 'insert', container, '-after', *args)
+ end
+
+ def join(container, first, last)
+ tk_call('::blt::table', 'join', container, first, last)
+ end
+
+ def locate(container, x, y)
+ tk_call('::blt::table', 'locate', container, x, y)
+ end
+
+ def containers(arg={})
+ list(tk_call('::blt::table', 'containers', *hash_kv(arg)))
+ end
+
+ def containers_pattern(pat)
+ list(tk_call('::blt::table', 'containers', '-pattern', pat))
+ end
+
+ def containers_slave(win)
+ list(tk_call('::blt::table', 'containers', '-slave', win))
+ end
+
+ def save(container)
+ tk_call('::blt::table', 'save', container)
+ end
+
+ def search(container, keys={})
+ list(tk_call('::blt::table', 'containers', *hash_kv(keys)))
+ end
+
+ def split(container, *args)
+ tk_call('::blt::table', 'split', container, *args)
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tabnotebook.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tabnotebook.rb
new file mode 100644
index 0000000..82936c6
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tabnotebook.rb
@@ -0,0 +1,110 @@
+#
+# tkextlib/blt/tabnotebook.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+require 'tkextlib/blt/tabset.rb'
+
+module Tk::BLT
+ class Tabnotebook < Tabset
+ TkCommandNames = ['::blt::tabnotebook'.freeze].freeze
+ WidgetClassName = 'Tabnotebook'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ class Tab < Tk::BLT::Tabset::Tab
+ def self.new(parent, pos=nil, name=nil, keys={})
+ if pos.kind_of?(Hash)
+ keys = pos
+ name = nil
+ pos = nil
+ end
+ if name.kind_of?(Hash)
+ keys = name
+ name = nil
+ end
+ obj = nil
+ TabID_TBL.mutex.synchronize{
+ if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]
+ obj = TabID_TBL[parent.path][name]
+ if pos
+ if pos.to_s == 'end'
+ obj.move_after('end')
+ else
+ obj.move_before(pos)
+ end
+ end
+ obj.configure if keys && ! keys.empty?
+ else
+ (obj = self.allocate).instance_eval{
+ initialize(parent, pos, name, keys)
+ TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
+ TabID_TBL[@tpath][@id] = self
+ }
+ end
+ }
+ obj
+ end
+
+ def initialize(parent, pos, name, keys)
+ @t = parent
+ @tpath = parent.path
+ if name
+ @path = @id = name
+ unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?)
+ if pos
+ idx = tk_call(@tpath, 'index', @id)
+ if pos.to_s == 'end'
+ tk_call(@tpath, 'move', idx, 'after', 'end')
+ else
+ tk_call(@tpath, 'move', idx, 'before', pos)
+ end
+ end
+ tk_call(@tpath, 'tab', 'configure', @id, keys)
+ else
+ fail ArgumentError, "can't find tab \"#{@id}\" in #{@t}"
+ end
+ else
+ pos = 'end' unless pos
+ @path = @id = tk_call(@tpath, 'insert', pos, keys)
+ end
+ end
+ end
+
+ #######################################
+
+ def get_tab(index)
+ if (idx = tk_send_without_enc('id', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabset::Tab.id2obj(self, idx)
+ end
+ end
+ alias get_id get_tab
+
+ def get_tabobj(index)
+ if (idx = tk_send_without_enc('id', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabnotebook::Tab.new(self, nil, idx)
+ end
+ end
+
+ alias index_name index
+
+ def insert(pos=nil, keys={})
+ if pos.kind_of?(Hash)
+ keys = pos
+ pos = nil
+ end
+ pos = 'end' if pos.nil?
+ Tk::BLT::Tabnotebook::Tab.new(self, nil,
+ tk_send('insert', tagindex(pos), keys))
+
+ end
+ undef :insert_tabs
+
+ undef :tab_pageheight, :tab_pagewidth
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tabset.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tabset.rb
new file mode 100644
index 0000000..c4716c7
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tabset.rb
@@ -0,0 +1,504 @@
+#
+# tkextlib/blt/tabset.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Tabset < TkWindow
+ class Tab < TkObject
+ include TkTreatItemFont
+
+ TabID_TBL = TkCore::INTERP.create_table
+
+ (TabsetTab_ID = ['blt_tabset_tab'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ TkCore::INTERP.init_ip_env{
+ TabID_TBL.mutex.synchronize{ TabID_TBL.clear }
+ }
+
+ def self.id2obj(tabset, id)
+ tpath = tabset.path
+ TabID_TBL.mutex.synchronize{
+ if TabID_TBL[tpath]
+ TabID_TBL[tpath][id]? TabID_TBL[tpath][id]: id
+ else
+ id
+ end
+ }
+ end
+
+ def self.new(parent, pos=nil, name=nil, keys={})
+ if pos.kind_of?(Hash)
+ keys = pos
+ name = nil
+ pos = nil
+ end
+ if name.kind_of?(Hash)
+ keys = name
+ name = nil
+ end
+ obj = nil
+ TabID_TBL.mutex.synchronize{
+ if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]
+ obj = TabID_TBL[parent.path][name]
+ if pos
+ if pos.to_s == 'end'
+ obj.move_after('end')
+ else
+ obj.move_before(pos)
+ end
+ end
+ obj.configure if keys && ! keys.empty?
+ else
+ (obj = self.allocate).instance_eval{
+ initialize(parent, pos, name, keys)
+ TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
+ TabID_TBL[@tpath][@id] = self
+ }
+ end
+ }
+ obj
+ end
+
+ def initialize(parent, pos, name, keys)
+ @t = parent
+ @tpath = parent.path
+ if name
+ @path = @id = name
+ unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?)
+ if pos
+ idx = tk_call(@tpath, 'index', '-name', @id)
+ if pos.to_s == 'end'
+ tk_call(@tpath, 'move', idx, 'after', 'end')
+ else
+ tk_call(@tpath, 'move', idx, 'before', pos)
+ end
+ end
+ tk_call(@tpath, 'tab', 'configure', @id, keys)
+ else
+ pos = 'end' unless pos
+ tk_call(@tpath, 'insert', pos, @id, keys)
+ end
+ else
+ pos = 'end' unless pos
+ TabsetTab_ID.mutex.synchronize{
+ @path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_)
+ TabsetTab_ID[1].succ!
+ }
+ tk_call(@tpath, 'insert', pos, @id, keys)
+ end
+ end
+
+ #def bind(context, cmd=Proc.new, *args)
+ # @t.tab_bind(@id, context, cmd, *args)
+ # self
+ #end
+ def bind(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
+ @t.tab_bind(@id, context, cmd, *args)
+ self
+ end
+ #def bind_append(context, cmd=Proc.new, *args)
+ # @t.tab_bind_append(@id, context, cmd, *args)
+ # self
+ #end
+ def bind_append(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
+ @t.tab_bind_append(@id, context, cmd, *args)
+ self
+ end
+ def bind_remove(context)
+ @t.tab_bind_remove(@id, context)
+ self
+ end
+ def bindinfo(context=nil)
+ @t.tab_bindinfo(@id, context)
+ end
+
+ def cget_tkstring(*args)
+ @t.tab_cget_tkstring(@id, *args)
+ end
+ def cget(*args)
+ @t.tab_cget(@id, *args)
+ end
+ def cget_strict(*args)
+ @t.tab_cget_strict(@id, *args)
+ end
+ def configure(*args)
+ @t.tab_configure(@id, *args)
+ end
+ def configinfo(*args)
+ @t.tab_configinfo(@id, *args)
+ end
+ def current_configinfo(*args)
+ @t.current_tab_configinfo(@id, *args)
+ end
+
+ def delete()
+ @t.delete(@id)
+ TabID_TBL.mutex.synchronize{
+ TabID_TBL[@tpath].delete(@id)
+ }
+ self
+ end
+
+ def get_name()
+ @id.dup
+ end
+
+ def focus()
+ @t.focus(self.index)
+ end
+
+ def index()
+ @t.index_name(@id)
+ end
+
+ def invoke()
+ @t.invoke(self.index)
+ end
+
+ def move_before(idx)
+ @t.move_before(self.index, idx)
+ end
+ def move_after(idx)
+ @t.move_after(self.index, idx)
+ end
+
+ def perforation_highlight(mode)
+ @t.perforation_highlight(self.index, mode)
+ end
+ def perforation_invoke()
+ @t.perforation_invoke(self.index)
+ end
+
+ def see()
+ @t.see(self.index)
+ end
+
+ def tearoff(name=None)
+ @t.tab_tearoff(self.index, *args)
+ end
+ end
+
+ ########################################
+
+ class NamedTab < Tab
+ def self.new(parent, name)
+ super(parent, nil, name, {})
+ end
+ end
+
+ ########################################
+
+ include X_Scrollable
+ include TkItemConfigMethod
+
+ TkCommandNames = ['::blt::tabset'.freeze].freeze
+ WidgetClassName = 'Tabset'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ def __destroy_hook__
+ Tk::BLT::Tabset::Tab::TabID_TBL.mutex.synchronize{
+ Tk::BLT::Tabset::Tab::TabID_TBL.delete(@path)
+ }
+ end
+
+ ########################################
+
+ def __boolval_optkeys
+ super() << 'samewidth' << 'tearoff'
+ end
+ private :__strval_optkeys
+
+ def __strval_optkeys
+ super() << 'tabbackground' << 'tabforeground'
+ end
+ private :__strval_optkeys
+
+ def __item_cget_cmd(id)
+ [self.path, 'tab', 'cget', id]
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(id)
+ [self.path, 'tab', 'configure', id]
+ end
+ private :__item_config_cmd
+
+ def __item_pathname(tagOrId)
+ if tagOrId.kind_of?(Tk::BLT::Tabset::Tab)
+ self.path + ';' + tagOrId.id.to_s
+ else
+ self.path + ';' + tagOrId.to_s
+ end
+ end
+ private :__item_pathname
+
+ alias tab_cget_tkstring itemcget_tkstring
+ alias tab_cget itemcget
+ alias tab_cget_strict itemcget_strict
+ alias tab_configure itemconfigure
+ alias tab_configinfo itemconfiginfo
+ alias current_tab_configinfo current_itemconfiginfo
+
+ def __item_strval_optkeys(id)
+ super(id) << 'shadow'
+ end
+ private :__item_strval_optkeys
+
+ def tagid(tab)
+ if tab.kind_of?(Tk::BLT::Tabset::Tab)
+ tab.id
+ else
+ tab
+ end
+ end
+
+ def tagindex(tab)
+ if tab.kind_of?(Tk::BLT::Tabset::Tab)
+ tab.index
+ else
+ tab
+ end
+ end
+
+ ########################################
+
+ def activate(index)
+ tk_send('activate', tagindex(index))
+ self
+ end
+ alias highlight activate
+
+ #def tabbind(tag, context, cmd=Proc.new, *args)
+ # _bind([path, "bind", tagid(tag)], context, cmd, *args)
+ # self
+ #end
+ def tabbind(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 tabbind_append(tag, context, cmd=Proc.new, *args)
+ # _bind_append([path, "bind", tagid(tag)], context, cmd, *args)
+ # self
+ #end
+ def tabbind_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 tabbind_remove(tag, context)
+ _bind_remove([path, "bind", tagid(tag)], context)
+ self
+ end
+ def tabbindinfo(tag, context=nil)
+ _bindinfo([path, "bind", tagid(tag)], context)
+ end
+
+ def delete(first, last=None)
+ tk_send('delete', tagindex(first), tagindex(last))
+ if first.kind_of?(Tk::BLT::Tabset::Tab)
+ TabID_TBL.mutex.synchronize{
+ TabID_TBL[@path].delete(first.id)
+ }
+ end
+ # middle tabs of the range are unknown
+ if last.kind_of?(Tk::BLT::Tabset::Tab)
+ TabID_TBL.mutex.synchronize{
+ TabID_TBL[@path].delete(last.id)
+ }
+ end
+ self
+ end
+
+ def focus(index)
+ tk_send('focus', tagindex(index))
+ self
+ end
+
+ def get_tab(index)
+ if (idx = tk_send_without_enc('get', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabset::Tab.id2obj(self, idx)
+ end
+ end
+ def get_tabobj(index)
+ if (idx = tk_send_without_enc('get', tagindex(index))).empty?
+ nil
+ else
+ Tk::BLT::Tabset::Tab.new(self, nil, name, {})
+ end
+ end
+
+ def index(str)
+ num_or_str(tk_send('index', str))
+ end
+ def index_name(tab)
+ num_or_str(tk_send('index', '-name', tagid(tab)))
+ end
+
+ def insert(pos, tab, keys={})
+ pos = 'end' if pos.nil?
+ Tk::BLT::Tabset::Tab.new(self, tagindex(pos), tagid(tab), keys)
+ end
+ def insert_tabs(pos, *tabs)
+ pos = 'end' if pos.nil?
+ if tabs[-1].kind_of?(Hash)
+ keys = tabs.pop
+ else
+ keys = {}
+ end
+ fail ArgumentError, 'no tabs is given' if tabs.empty?
+ tabs.map!{|tab| tagid(tab)}
+ tk_send('insert', tagindex(pos), *(tabs + [keys]))
+ tabs.collect{|tab| Tk::BLT::Tabset::Tab.new(self, nil, tagid(tab))}
+ end
+
+ def invoke(index)
+ tk_send('invoke', tagindex(index))
+ end
+
+ def move_before(index, base_idx)
+ tk_send('move', tagindex(index), 'before', tagindex(base_idx))
+ self
+ end
+ def move_after(index, base_idx)
+ tk_send('move', tagindex(index), 'after', tagindex(base_idx))
+ self
+ end
+
+ def nearest(x, y)
+ Tk::BLT::Tabset::Tab.id2obj(self, num_or_str(tk_send_without_enc('nearest', x, y)))
+ end
+
+ def perforation_activate(mode)
+ tk_send('perforation', 'activate', mode)
+ self
+ end
+ def perforation_highlight(index, *args)
+ if args.empty?
+ # index --> mode
+ tk_send('perforation', 'highlight', index)
+ elsif args.size == 1
+ # args[0] --> mode
+ tk_send('perforation', 'highlight', tagindex(index), args[0])
+ else # Error: call to get Tcl's error message
+ tk_send('perforation', 'highlight', tagindex(index), *args)
+ end
+ self
+ end
+ def perforation_invoke(index=nil)
+ if index
+ tk_send('perforation', 'invoke', tagindex(index))
+ else
+ tk_send('perforation', 'invoke')
+ end
+ 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('see', tagindex(index))
+ self
+ end
+
+ def size()
+ number(tk_send_without_enc('size'))
+ end
+
+ def select(index)
+ tk_send('select', tagindex(index))
+ self
+ end
+
+ def tab_dockall
+ tk_send('tab', 'dockall')
+ self
+ end
+
+ def tab_names(pat=None)
+ simplelist(tk_send('tab', 'names', pat)).collect{|name|
+ Tk::BLT::Tabset::Tab.id2obj(self, name)
+ }
+ end
+
+ def tab_objs(pat=None)
+ simplelist(tk_send('tab', 'names', pat)).collect{|name|
+ Tk::BLT::Tabset::Tab.new(self, nil, name, {})
+ }
+ end
+
+ def tab_ids(pat=None)
+ simplelist(tk_send('tab', 'names', pat))
+ end
+
+ def tab_pageheight
+ number(tk_send('tab', 'pageheight'))
+ end
+
+ def tab_pagewidth
+ number(tk_send('tab', 'pagewidth'))
+ end
+
+ def tab_tearoff(index, parent=None)
+ window(tk_send('tab', 'tearoff', tagindex(index), parent))
+ end
+
+ def xscrollcommand(cmd=Proc.new)
+ configure_cmd 'scrollcommand', cmd
+ self
+ end
+ alias scrollcommand xscrollcommand
+
+ def xview(*index)
+ if index.empty?
+ list(tk_send_without_enc('view'))
+ else
+ tk_send_without_enc('view', *index)
+ self
+ end
+ end
+ alias view xview
+ alias view_moveto xview_moveto
+ alias view_scroll xview_scroll
+
+ alias scrollbar xscrollbar
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/ted.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/ted.rb
new file mode 100644
index 0000000..53ab9ac
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/ted.rb
@@ -0,0 +1,68 @@
+#
+# tkextlib/blt/ted.rb
+#
+# *** This is alpha version, because there is no document on BLT. ***
+#
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module Ted
+ extend TkCore
+
+ TkCommandNames = ['::blt::ted'.freeze].freeze
+
+ ##############################
+
+ extend TkItemConfigMethod
+
+ class << self
+ def __item_cget_cmd(id)
+ ['::blt::ted', 'cget', id]
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(id)
+ ['::blt::ted', 'configure', id]
+ end
+ private :__item_config_cmd
+
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ def cget_tkstring(master, option)
+ itemcget_tkstring(master, option)
+ end
+ def cget(master, option)
+ itemcget(master, option)
+ end
+ def cget_strict(master, option)
+ itemcget_strict(master, option)
+ end
+ def configure(master, slot, value=None)
+ itemconfigure(master, slot, value)
+ end
+ def configinfo(master, slot=nil)
+ itemconfiginfo(master, slot)
+ end
+ def current_configinfo(master, slot=nil)
+ current_itemconfiginfo(master, slot)
+ end
+ end
+
+ ##############################
+
+ def self.edit(master, *args)
+ tk_call('::blt::ted', 'edit', master, *args)
+ end
+ def self.rep(master, *args)
+ tk_call('::blt::ted', 'rep', master, *args)
+ end
+ def self.select(master, *args)
+ tk_call('::blt::ted', 'select', master, *args)
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile.rb
new file mode 100644
index 0000000..c67cafd
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile.rb
@@ -0,0 +1,25 @@
+#
+# tkextlib/blt/tile.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module Tile
+ TkComm::TkExtlibAutoloadModule.unshift(self)
+ # Require autoload-symbols which is a same name as widget classname.
+ # Those are used at TkComm._genobj_for_tkwidget method.
+
+ autoload :Button, 'tkextlib/blt/tile/button.rb'
+ autoload :CheckButton, 'tkextlib/blt/tile/checkbutton.rb'
+ autoload :Checkbutton, 'tkextlib/blt/tile/checkbutton.rb'
+ autoload :Radiobutton, 'tkextlib/blt/tile/radiobutton.rb'
+ autoload :RadioButton, 'tkextlib/blt/tile/radiobutton.rb'
+ autoload :Frame, 'tkextlib/blt/tile/frame.rb'
+ autoload :Label, 'tkextlib/blt/tile/label.rb'
+ autoload :Scrollbar, 'tkextlib/blt/tile/scrollbar.rb'
+ autoload :Toplevel, 'tkextlib/blt/tile/toplevel.rb'
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile/button.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/button.rb
new file mode 100644
index 0000000..2e0863c
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/button.rb
@@ -0,0 +1,16 @@
+#
+# tkextlib/blt/tile/button.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/button'
+require 'tkextlib/blt/tile.rb'
+
+module Tk::BLT
+ module Tile
+ class Button < Tk::Button
+ TkCommandNames = ['::blt::tile::button'.freeze].freeze
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb
new file mode 100644
index 0000000..da230b5
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb
@@ -0,0 +1,17 @@
+#
+# tkextlib/blt/tile/checkbutton.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/checkbutton'
+require 'tkextlib/blt/tile.rb'
+
+module Tk::BLT
+ module Tile
+ class CheckButton < Tk::CheckButton
+ TkCommandNames = ['::blt::tile::checkbutton'.freeze].freeze
+ end
+ Checkbutton = CheckButton
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile/frame.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/frame.rb
new file mode 100644
index 0000000..5434af4
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/frame.rb
@@ -0,0 +1,16 @@
+#
+# tkextlib/blt/tile/frame.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/frame'
+require 'tkextlib/blt/tile.rb'
+
+module Tk::BLT
+ module Tile
+ class Frame < Tk::Frame
+ TkCommandNames = ['::blt::tile::frame'.freeze].freeze
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile/label.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/label.rb
new file mode 100644
index 0000000..f370c14
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/label.rb
@@ -0,0 +1,16 @@
+#
+# tkextlib/blt/tile/label.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/label'
+require 'tkextlib/blt/tile.rb'
+
+module Tk::BLT
+ module Tile
+ class Label < Tk::Label
+ TkCommandNames = ['::blt::tile::label'.freeze].freeze
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb
new file mode 100644
index 0000000..814f9a5
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb
@@ -0,0 +1,17 @@
+#
+# tkextlib/blt/tile/radiobutton.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/radiobutton'
+require 'tkextlib/blt/tile.rb'
+
+module Tk::BLT
+ module Tile
+ class RadioButton < Tk::RadioButton
+ TkCommandNames = ['::blt::tile::radiobutton'.freeze].freeze
+ end
+ Radiobutton = RadioButton
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb
new file mode 100644
index 0000000..2ae871d
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb
@@ -0,0 +1,16 @@
+#
+# tkextlib/blt/tile/scrollbar.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/scrollbar'
+require 'tkextlib/blt/tile.rb'
+
+module Tk::BLT
+ module Tile
+ class Scrollbar < Tk::Scrollbar
+ TkCommandNames = ['::blt::tile::scrollbar'.freeze].freeze
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tile/toplevel.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/toplevel.rb
new file mode 100644
index 0000000..76d5f86
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tile/toplevel.rb
@@ -0,0 +1,16 @@
+#
+# tkextlib/blt/tile/toplevel.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tk/toplevel'
+require 'tkextlib/blt/tile.rb'
+
+module Tk::BLT
+ module Tile
+ class Toplevel < Tk::Toplevel
+ TkCommandNames = ['::blt::tile::toplevel'.freeze].freeze
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/tree.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/tree.rb
new file mode 100644
index 0000000..1a3563e
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/tree.rb
@@ -0,0 +1,1058 @@
+#
+# tkextlib/blt/tree.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Tree < TkObject
+ TkCommandNames = ['::blt::tree'.freeze].freeze
+
+ ###################################
+
+ class Node < TkObject
+ TreeNodeID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ TreeNodeID_TBL.mutex.synchronize{ TreeNodeID_TBL.clear }
+ }
+
+ def self.id2obj(tree, id)
+ tpath = tree.path
+ TreeNodeID_TBL.mutex.synchronize{
+ if TreeNodeID_TBL[tpath]
+ if TreeNodeID_TBL[tpath][id]
+ TreeNodeID_TBL[tpath][id]
+ else
+ begin
+ # self.new(tree, nil, 'node'=>Integer(id))
+ id = Integer(id)
+ if bool(tk_call(@tpath, 'exists', id))
+ (obj = self.allocate).instance_eval{
+ @parent = @tree = tree
+ @tpath = tpath
+ @path = @id = id
+ TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath]
+ TreeNodeID_TBL[@tpath][@id] = self
+ }
+ obj
+ else
+ id
+ end
+ rescue
+ id
+ end
+ end
+ else
+ id
+ end
+ }
+ end
+
+ def self.new(tree, parent, keys={})
+ keys = _symbolkey2str(keys)
+ tpath = tree.path
+
+ TreeNodeID_TBL.mutex.synchronize{
+ TreeNodeID_TBL[tpath] ||= {}
+ if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id])
+ keys.delete('node')
+ tk_call(tree.path, 'move', id, parent, keys) if parent
+ return obj
+ end
+
+ (obj = self.allocate).instance_eval{
+ initialize(tree, parent, keys)
+ TreeNodeID_TBL[tpath][@id] = self
+ }
+ obj
+ }
+ end
+
+ def initialize(tree, parent, keys={})
+ @parent = @tree = tree
+ @tpath = @parent.path
+
+ if (id = keys['node']) && bool(tk_call(@tpath, 'exists', id))
+ @path = @id = id
+ keys.delete('node')
+ tk_call(@tpath, 'move', @id, parent, keys) if parent
+ else
+ parent = tk_call(@tpath, 'root') unless parent
+ @path = @id = tk_call(@tpath, 'insert', parent, keys)
+ end
+ end
+
+ def id
+ @id
+ end
+
+ def apply(keys={})
+ @tree.apply(@id, keys)
+ self
+ end
+
+ def children()
+ @tree.children(@id)
+ end
+
+ def copy(parent, keys={})
+ @tree.copy(@id, parent, keys)
+ end
+ def copy_to(dest_tree, parent, keys={})
+ @tree.copy_to(@id, dest_tree, parent, keys)
+ end
+
+ def degree()
+ @tree.degree(@id)
+ end
+
+ def delete()
+ @tree.delete(@id)
+ self
+ end
+
+ def depth()
+ @tree.depth(@id)
+ end
+
+ def dump()
+ @tree.dump(@id)
+ end
+
+ def dump_to_file(file)
+ @tree.dump_to_file(@id, file)
+ self
+ end
+
+ def exist?(keys={})
+ @tree.exist?(@id, keys)
+ end
+
+ def find(keys={})
+ @tree.find(@id, keys)
+ end
+
+ def find_child(label)
+ @tree.find_child(@id, label)
+ end
+
+ def first_child()
+ @tree.first_child(@id)
+ end
+
+ def get()
+ @tree.get(@id)
+ end
+ def get_value(key, default_val=None)
+ @tree.get_value(@id, key, default_val)
+ end
+
+ def index()
+ @tree.index(@id)
+ end
+
+ def leaf?()
+ @tree.leaf?(@id)
+ end
+ def link?()
+ @tree.link?(@id)
+ end
+ def root?()
+ @tree.root?(@id)
+ end
+
+ def keys()
+ @tree.keys(@id)
+ end
+
+ def label(text = nil)
+ @tree.label(@id, nil)
+ end
+ def label=(text)
+ @tree.label(@id, text)
+ end
+
+ def last_child()
+ @tree.last_child(@id)
+ end
+
+ def move(dest, keys={})
+ @tree.keys(@id, dest, keys)
+ self
+ end
+
+ def next()
+ @tree.next(@id)
+ end
+
+ def next_sibling()
+ @tree.next_sibling(@id)
+ end
+
+ def parent()
+ @tree.parent(@id)
+ end
+
+ def fullpath()
+ @tree.fullpath(@id)
+ end
+
+ def position()
+ @tree.position(@id)
+ end
+
+ def previous()
+ @tree.previous(@id)
+ end
+
+ def prev_sibling()
+ @tree.prev_sibling(@id)
+ end
+
+ def restore(str, keys={})
+ @tree.restore(@id, str, keys)
+ self
+ end
+ def restore_overwrite(str, keys={})
+ @tree.restore_overwrite(@id, str, keys)
+ self
+ end
+
+ def restore_from_file(file, keys={})
+ @tree.restore_from_file(@id, file, keys)
+ self
+ end
+ def restore_overwrite_from_file(file, keys={})
+ @tree.restore_overwrite_from_file(@id, file, keys)
+ self
+ end
+
+ def root()
+ @tree.root(@id)
+ self
+ end
+
+ def set(data)
+ @tree.set(@id, data)
+ self
+ end
+
+ def size()
+ @tree.size(@id)
+ end
+
+ def sort(keys={})
+ @tree.sort(@id, keys)
+ self
+ end
+
+ def type(key)
+ @tree.type(@id, key)
+ end
+
+ def unset(*keys)
+ @tree.unset(@id, *keys)
+ self
+ end
+
+ def values(key=None)
+ @tree.values(@id, key)
+ end
+ end
+
+ ###################################
+
+ class Tag < TkObject
+ TreeTagID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }
+ }
+
+ (TreeTag_ID = ['blt_tree_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ def self.id2obj(tree, id)
+ tpath = tree.path
+ TreeTagID_TBL.mutex.synchronize{
+ if TreeTagID_TBL[tpath]
+ if TreeTagID_TBL[tpath][id]
+ TreeTagID_TBL[tpath][id]
+ else
+ begin
+ # self.new(tree, id)
+ (obj = self.allocate).instance_eval{
+ @parent = @tree = tree
+ @tpath = @parent.path
+ @path = @id = id.dup.freeze if id
+ TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
+ TreeTagID_TBL[@tpath][@id] = self
+ }
+ obj
+ rescue
+ id
+ end
+ end
+ else
+ id
+ end
+ }
+ end
+
+ def initialize(tree, tag_str = nil)
+ @parent = @tree = tree
+ @tpath = @parent.path
+
+ if tag_str
+ @path = @id = tag_str.dup.freeze
+ else
+ TreeTag_ID.mutex.synchronize{
+ @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_)
+ TreeTag_ID[1].succ!
+ }
+ end
+ TreeTagID_TBL.mutex.synchronize{
+ TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
+ TreeTagID_TBL[@tpath][@id] = self
+ }
+ end
+
+ def id
+ @id
+ end
+
+ def add(*nodes)
+ tk_call(@tpath, 'tag', 'add', @id, *nodes)
+ self
+ end
+
+ def delete(*nodes)
+ tk_call(@tpath, 'tag', 'delete', @id, *nodes)
+ self
+ end
+
+ def forget()
+ tk_call(@tpath, 'tag', 'forget', @id)
+ TreeTagID_TBL.mutex.synchronize{
+ TreeTagID_TBL[@tpath].delete(@id)
+ }
+ self
+ end
+
+ def nodes()
+ simplelist(tk_call(@tpath, 'tag', 'nodes', @id)).collect{|node|
+ Tk::BLT::Tree::Node.id2obj(@path, node)
+ }
+ end
+
+ def set(node)
+ tk_call(@tpath, 'tag', 'set', node, @id)
+ self
+ end
+
+ def unset(node)
+ tk_call(@tpath, 'tag', 'unset', node, @id)
+ self
+ end
+ end
+
+ ###################################
+
+ class Notify < TkObject
+ NotifyID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ NotifyID_TBL.mutex.synchronize{ NotifyID_TBL.clear }
+ }
+
+ def self.id2obj(tree, id)
+ tpath = tree.path
+ NotifyID_TBL.mutex.synchronize{
+ if NotifyID_TBL[tpath]
+ if NotifyID_TBL[tpath][id]
+ NotifyID_TBL[tpath][id]
+ else
+ (obj = self.allocate).instance_eval{
+ @parent = @tree = tree
+ @tpath = @parent.path
+ @path = @id = id
+ NotifyID_TBL[@tpath] ||= {}
+ NotifyID_TBL[@tpath][@id] = self
+ }
+ obj
+ end
+ else
+ return id
+ end
+ }
+ end
+
+ def self.new(tree, *args, &b)
+ NotifyID_TBL.mutex.synchronize{
+ if tree.kind_of?(Array)
+ # not create
+ tpath = tree[0].path
+ NotifyID_TBL[tpath] ||= {}
+ unless (obj = NotifyID_TBL[tpath][tree[1]])
+ (NotifyID_TBL[tpath][tree[1]] =
+ obj = self.allocate).instance_eval{
+ @parent = @tree = tree[0]
+ @tpath = @parent.path
+ @path = @id = tree[1]
+ }
+ end
+ return obj
+ end
+
+ (obj = self.allocate).instance_eval{
+ initialize(tree, *args, &b)
+ NotifyID_TBL[@tpath] ||= {}
+ NotifyID_TBL[@tpath][@id] = self
+ }
+ return obj
+ }
+ end
+
+ def initialize(tree, *args, &b)
+ @parent = @tree = tree
+ @tpath = @parent.path
+
+ # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
+ if TkComm._callback_entry?(args[0])
+ cmd = args.shift
+ # elsif args[-1].kind_of?(Proc) || args[-1].kind_of?(Method)
+ elsif TkComm._callback_entry?(args[-1])
+ cmd = args.pop
+ elsif b
+ cmd = Proc.new(&b)
+ else
+ fail ArgumentError, "lack of 'command' argument"
+ end
+
+ args = args.collect{|arg| '-' << arg.to_s}
+
+ args << proc{|id, type|
+ cmd.call(Tk::BLT::Tree::Node.id2obj(@tree, id),
+ ((type[0] == ?-)? type[1..-1]: type))
+ }
+
+ @path = @id = tk_call(@tpath, 'notify', 'create', *args)
+ end
+
+ def id
+ @id
+ end
+
+ def delete()
+ tk_call(@tpath, 'notify', 'delete', @id)
+ NotifyID_TBL.mutex.synchronize{
+ NotifyID_TBL[@tpath].delete(@id)
+ }
+ self
+ end
+
+ def info()
+ lst = simplelist(tk_call(@tpath, 'notify', 'info', id))
+ lst[0] = Tk::BLT::Tree::Notify.id2obj(@tree, lst[0])
+ lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]}
+ lst[2] = tk_tcl2ruby(lst[2])
+ lst
+ end
+ end
+
+ ###################################
+
+ class Trace < TkObject
+ TraceID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ TraceID_TBL.mutex.synchronize{ TraceID_TBL.clear }
+ }
+
+ def self.id2obj(tree, id)
+ tpath = tree.path
+ TraceID_TBL.mutex.synchronize{
+ if TraceID_TBL[tpath]
+ if TraceID_TBL[tpath][id]
+ TraceID_TBL[tpath][id]
+ else
+ begin
+ # self.new([tree, id])
+ (obj = self.allocate).instance_eval{
+ @parent = @tree = tree
+ @tpath = @parent.path
+ @path = @id = node # == traceID
+ TraceID_TBL[@tpath] ||= {}
+ TraceID_TBL[@tpath][@id] = self
+ }
+ obj
+ rescue
+ id
+ end
+ end
+ else
+ id
+ end
+ }
+ end
+
+ def self.new(tree, *args, &b)
+ TraceID_TBL.mutex.synchronize{
+ if tree.kind_of?(Array)
+ # not create
+ tpath = tree[0].path
+ TraceID_TBL[tpath] ||= {}
+ unless (obj = TraceID_TBL[tpath][tree[1]])
+ (TraceID_TBL[tpath][tree[1]] =
+ obj = self.allocate).instance_eval{
+ @parent = @tree = tree
+ @tpath = @parent.path
+ @path = @id = tree[1] # == traceID
+ }
+ end
+ return obj
+ end
+
+ # super(true, tree, *args, &b)
+ (obj = self.allocate).instance_eval{
+ initialize(tree, *args, &b)
+ TraceID_TBL[@tpath] ||= {}
+ TraceID_TBL[@tpath][@id] = self
+ }
+ return obj
+ }
+ end
+
+ def initialize(tree, node, key, opts, cmd=nil, &b)
+ @parent = @tree = tree
+ @tpath = @parent.path
+
+ if !cmd
+ if b
+ cmd = Proc.new(&b)
+ else
+ fail ArgumentError, "lack of 'command' argument"
+ end
+ end
+
+ @path = @id = tk_call(@tpath, 'trace', 'create', node, key, opts,
+ proc{|t, id, k, ops|
+ tobj = Tk::BLT::Tree.id2obj(t)
+ if tobj.kind_of?(Tk::BLT::Tree)
+ nobj = Tk::BLT::Tree::Node.id2obj(tobj, id)
+ else
+ nobj = id
+ end
+ cmd.call(tobj, nobj, k, ops)
+ })
+ end
+
+ def id
+ @id
+ end
+
+ def delete()
+ tk_call(@tpath, 'trace', 'delete', @id)
+ TraceID_TBL.mutex.synchronize{
+ TraceID_TBL[tpath].delete(@id)
+ }
+ self
+ end
+
+ def info()
+ lst = simplelist(tk_call(@tpath, 'trace', 'info', id))
+ lst[0] = Tk::BLT::Tree::Trace.id2obj(@tree, lst[0])
+ lst[2] = simplelist(lst[2])
+ lst[3] = tk_tcl2ruby(lst[3])
+ lst
+ end
+ end
+
+ ###################################
+
+ TreeID_TBL = TkCore::INTERP.create_table
+
+ (Tree_ID = ['blt_tree'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ def __keyonly_optkeys
+ {
+ # apply / find command
+ 'invert'=>nil, 'leafonly'=>nil, 'nocase'=>nil,
+
+ # apply / find / sort command
+ 'path'=>nil,
+
+ # copy / restore / restorefile command
+ 'overwrite'=>nil,
+
+ # copy command
+ 'recurse'=>nil, 'tags'=>nil,
+
+ # sort command
+ 'ascii'=>nil, 'decreasing'=>nil, 'disctionary'=>nil,
+ 'integer'=>nil, 'real'=>nil, 'recurse'=>nil, 'reorder'=>nil,
+ }
+ end
+
+ def self.id2obj(id)
+ TreeID_TBL.mutex.synchronize{
+ TreeID_TBL[id]? TreeID_TBL[id]: id
+ }
+ end
+
+ def self.names(pat = None)
+ simplelist(tk_call('::blt::tree', 'names', pat)).collect{|name|
+ id2obj(name)
+ }
+ end
+
+ def self.destroy(*names)
+ tk_call('::blt::tree', 'destroy',
+ *(names.collect{|n| (n.kind_of?(Tk::BLT::Tree))? n.id: n }) )
+ end
+
+ def self.new(name = nil)
+ TreeID_TBL.mutex.synchronize{
+ if name && TreeID_TBL[name]
+ TreeID_TBL[name]
+ else
+ (obj = self.allocate).instance_eval{
+ initialize(name)
+ TreeID_TBL[@id] = self
+ }
+ obj
+ end
+ }
+ end
+
+ def initialzie(name = nil)
+ if name
+ @path = @id = name
+ else
+ Tree_ID.mutex.synchronize{
+ @path = @id = Tree_ID.join(TkCore::INTERP._ip_id_)
+ Tree_ID[1].succ!
+ }
+ end
+
+ tk_call('::blt::tree', 'create', @id)
+ end
+
+ def __destroy_hook__
+ Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{
+ Tk::BLT::Tree::Node::TreeNodeID_TBL.delete(@path)
+ }
+ Tk::BLT::Tree::Tag::TreeTagID_TBL.mutex.synchronize{
+ Tk::BLT::Tree::Tag::TreeTagID_TBL.delete(@path)
+ }
+ Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{
+ Tk::BLT::Tree::Notify::NotifyID_TBL.delete(@path)
+ }
+ Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{
+ Tk::BLT::Tree::Trace::TraceID_TBL.delete(@path)
+ }
+ end
+
+ def tagid(tag)
+ if tag.kind_of?(Tk::BLT::Tree::Node) ||
+ tag.kind_of?(Tk::BLT::Tree::Tag) ||
+ tag.kind_of?(Tk::BLT::Tree::Notify) ||
+ tag.kind_of?(Tk::BLT::Tree::Trace)
+ tag.id
+ else
+ tag # maybe an Array of configure parameters
+ end
+ end
+
+ def destroy()
+ tk_call('::blt::tree', 'destroy', @id)
+ self
+ end
+
+ def ancestor(node1, node2)
+ Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'ancestor',
+ tagid(node1), tagid(node2)))
+ end
+
+ def apply(node, keys={})
+ tk_call('::blt::tree', 'apply', tagid(node), __conv_keyonly_opts(keys))
+ self
+ end
+
+ def attach(tree_obj)
+ tk_call('::blt::tree', 'attach', tree_obj)
+ self
+ end
+
+ def children(node)
+ simplelist(tk_call('::blt::tree', 'children', tagid(node))).collect{|n|
+ Tk::BLT::Tree::Node.id2obj(self, n)
+ }
+ end
+
+ def copy(src, parent, keys={})
+ id = tk_call('::blt::tree', 'copy', tagid(src), tagid(parent),
+ __conv_keyonly_opts(keys))
+ Tk::BLT::Tree::Node.new(self, nil, 'node'=>id)
+ end
+ def copy_to(src, dest_tree, parent, keys={})
+ return copy(src, parent, keys={}) unless dest_tree
+
+ id = tk_call('::blt::tree', 'copy', tagid(src), dest_tree,
+ tagid(parent), __conv_keyonly_opts(keys))
+ Tk::BLT::Tree::Node.new(dest_tree, nil, 'node'=>id)
+ end
+
+ def degree(node)
+ number(tk_call('::blt::tree', 'degree', tagid(node)))
+ end
+
+ def delete(*nodes)
+ tk_call('::blt::tree', 'delete', *(nodes.collect{|node| tagid(node)}))
+ Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{
+ nodes.each{|node|
+ if node.kind_of?(Tk::BLT::Tree::Node)
+ Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.id)
+ else
+ Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.to_s)
+ end
+ }
+ }
+ self
+ end
+
+ def depth(node)
+ number(tk_call('::blt::tree', 'depth', tagid(node)))
+ end
+
+ def dump(node)
+ simplelist(tk_call('::blt::tree', 'dump', tagid(node))).collect{|n|
+ simplelist(n)
+ }
+ end
+
+ def dump_to_file(node, file)
+ tk_call('::blt::tree', 'dumpfile', tagid(node), file)
+ self
+ end
+
+ def exist?(node, key=None)
+ bool(tk_call('::blt::tree', 'exists', tagid(node), key))
+ end
+
+ def find(node, keys={})
+ simplelist(tk_call('::blt::tree', 'find', tagid(node),
+ __conv_keyonly_opts(keys))).collect{|n|
+ Tk::BLT::Tree::Node.id2obj(self, n)
+ }
+ end
+
+ def find_child(node, label)
+ ret = tk_call('::blt::tree', 'findchild', tagid(node), label)
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def first_child(node)
+ ret = tk_call('::blt::tree', 'firstchild', tagid(node))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def get(node)
+ Hash[*simplelist(tk_call('::blt::tree', 'get', tagid(node)))]
+ end
+ def get_value(node, key, default_val=None)
+ tk_call('::blt::tree', 'get', tagid(node), key, default_val)
+ end
+
+ def index(node)
+ Tk::BLT::Tree::Node.id2obj(self,
+ tk_call('::blt::tree', 'index', tagid(node)))
+ end
+
+ def insert(parent, keys={})
+ id = tk_call('::blt::tree', 'insert', tagid(parent), keys)
+ Tk::BLT::Tree::Node.new(self, nil, 'node'=>id)
+ end
+
+ def ancestor?(node1, node2)
+ bool(tk_call('::blt::tree', 'is', 'ancestor',
+ tagid(node1), tagid(node2)))
+ end
+ def before?(node1, node2)
+ bool(tk_call('::blt::tree', 'is', 'before',
+ tagid(node1), tagid(node2)))
+ end
+ def leaf?(node)
+ bool(tk_call('::blt::tree', 'is', 'leaf', tagid(node)))
+ end
+ def link?(node)
+ bool(tk_call('::blt::tree', 'is', 'link', tagid(node)))
+ end
+ def root?(node)
+ bool(tk_call('::blt::tree', 'is', 'root', tagid(node)))
+ end
+
+ def keys(node, *nodes)
+ if nodes.empty?
+ simplelist(tk_call('blt::tree', 'keys', tagid(node)))
+ else
+ simplelist(tk_call('blt::tree', 'keys', tagid(node),
+ *(nodes.collect{|n| tagid(n)}))).collect{|lst|
+ simplelist(lst)
+ }
+ end
+ end
+
+ def label(node, text=nil)
+ if text
+ tk_call('::blt::tree', 'label', tagid(node), text)
+ text
+ else
+ tk_call('::blt::tree', 'label', tagid(node))
+ end
+ end
+
+ def last_child(node)
+ ret = tk_call('::blt::tree', 'lastchild', tagid(node))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def link(parent, node, keys={})
+ ret = tk_call('::blt::tree', 'link', tagid(parent), tagid(node),
+ __conv_keyonly_opts(keys))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def move(node, dest, keys={})
+ tk_call('::blt::tree', 'move', tagid(node), tagid(dest), keys)
+ self
+ end
+
+ def next(node)
+ ret = tk_call('::blt::tree', 'next', tagid(node))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def next_sibling(node)
+ ret = tk_call('::blt::tree', 'nextsibling', tagid(node))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def notify_create(*args, &b)
+ Tk::BLT::Tree::Notify.new(self, *args, &b)
+ end
+
+ def notify_delete(id)
+ if id.kind_of?(Tk::BLT::Tree::Notify)
+ id.delete
+ else
+ tk_call(@path, 'notify', 'delete', id)
+ Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{
+ Tk::BLT::Tree::Notify::NotifyID_TBL[@path].delete(id.to_s)
+ }
+ end
+ self
+ end
+
+ def notify_info(id)
+ lst = simplelist(tk_call(@path, 'notify', 'info', tagid(id)))
+ lst[0] = Tk::BLT::Tree::Notify.id2obj(self, lst[0])
+ lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]}
+ lst[2] = tk_tcl2ruby(lst[2])
+ lst
+ end
+
+ def notify_names()
+ tk_call(@path, 'notify', 'names').collect{|id|
+ Tk::BLT::Tree::Notify.id2obj(self, id)
+ }
+ end
+
+ def parent(node)
+ ret = tk_call('::blt::tree', 'parent', tagid(node))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def fullpath(node)
+ tk_call('::blt::tree', 'path', tagid(node))
+ end
+
+ def position(node)
+ number(tk_call('::blt::tree', 'position', tagid(node)))
+ end
+
+ def previous(node)
+ ret = tk_call('::blt::tree', 'previous', tagid(node))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def prev_sibling(node)
+ ret = tk_call('::blt::tree', 'prevsibling', tagid(node))
+ (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)
+ end
+
+ def restore(node, str, keys={})
+ tk_call('::blt::tree', 'restore', tagid(node), str,
+ __conv_keyonly_opts(keys))
+ self
+ end
+ def restore_overwrite(node, str, keys={})
+ keys = __conv_keyonly_opts(keys)
+ keys.delete('overwrite')
+ keys.delete(:overwrite)
+ tk_call('::blt::tree', 'restore', tagid(node), str, '-overwrite', keys)
+ self
+ end
+
+ def restore_from_file(node, file, keys={})
+ tk_call('::blt::tree', 'restorefile', tagid(node), file,
+ __conv_keyonly_opts(keys))
+ self
+ end
+ def restore_overwrite_from_file(node, file, keys={})
+ keys = __conv_keyonly_opts(keys)
+ keys.delete('overwrite')
+ keys.delete(:overwrite)
+ tk_call('::blt::tree', 'restorefile', tagid(node), file,
+ '-overwrite', keys)
+ self
+ end
+
+ def root(node=None)
+ Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'root',
+ tagid(node)))
+ end
+
+ def set(node, data)
+ unless data.kind_of?(Hash)
+ fail ArgumentError, 'Hash is expected for data'
+ end
+ args = []
+ data.each{|k, v| args << k << v}
+ tk_call('::blt::tree', 'set', tagid(node), *args)
+ self
+ end
+
+ def size(node)
+ number(tk_call('::blt::tree', 'size', tagid(node)))
+ end
+
+ def sort(node, keys={})
+ tk_call('::blt::tree', 'sort', tagid(node), __conv_keyonly_opts(keys))
+ self
+ end
+
+ def tag_add(tag, *nodes)
+ tk_call(@path, 'tag', 'add', tagid(tag), *(nodes.collect{|n| tagid(n)}))
+ self
+ end
+
+ def tag_delete(tag, *nodes)
+ tk_call(@path, 'tag', 'delete', tagid(tag),
+ *(nodes.collect{|n| tagid(n)}))
+ self
+ end
+
+ def tag_forget(tag)
+ tag = tag.id if tag.kind_of?(Tk::BLT::Tree::Tag)
+ tk_call(@path, 'tag', 'forget', tag)
+ TreeTagID_TBL.mutex.synchronize{
+ TreeTagID_TBL[@path].delete(tag)
+ }
+ self
+ end
+
+ def tag_get(node, *patterns)
+ simplelist(tk_call(@tpath, 'tag', 'get', tagid(node),
+ *(patterns.collect{|pat| tagid(pat)}))).collect{|str|
+ Tk::BLT::Tree::Tag.id2obj(self, str)
+ }
+ end
+
+ def tag_names(node = None)
+ simplelist(tk_call(@tpath, 'tag', 'names', tagid(node))).collect{|str|
+ Tk::BLT::Tree::Tag.id2obj(self, str)
+ }
+ end
+
+ def tag_nodes(tag)
+ simplelist(tk_call(@tpath, 'tag', 'nodes', tagid(tag))).collect{|node|
+ Tk::BLT::Tree::Node.id2obj(self, node)
+ }
+ end
+
+ def tag_set(node, *tags)
+ tk_call(@path, 'tag', 'set', tagid(node), *(tags.collect{|t| tagid(t)}))
+ self
+ end
+
+ def tag_unset(node, *tags)
+ tk_call(@path, 'tag', 'unset', tagid(node),
+ *(tags.collect{|t| tagid(t)}))
+ self
+ end
+
+ def trace_create(*args, &b)
+ Tk::BLT::Tree::Trace.new(self, *args, &b)
+ end
+
+=begin
+ def trace_delete(*args)
+ args.each{|id|
+ if id.kind_of?(Tk::BLT::Tree::Trace)
+ id.delete
+ else
+ tk_call(@path, 'trace', 'delete', id)
+ Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)
+ end
+ self
+ }
+ end
+=end
+ def trace_delete(*args)
+ args = args.collect{|id| tagid(id)}
+ tk_call(@path, 'trace', 'delete', *args)
+ Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{
+ args.each{|id| Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)}
+ }
+ self
+ end
+
+ def trace_info(id)
+ lst = simplelist(tk_call(@path, 'trace', 'info', tagid(id)))
+ lst[0] = Tk::BLT::Tree::Trace.id2obj(self, lst[0])
+ lst[2] = simplelist(lst[2])
+ lst[3] = tk_tcl2ruby(lst[3])
+ lst
+ end
+
+ def trace_names()
+ tk_call(@path, 'trace', 'names').collect{|id|
+ Tk::BLT::Tree::Trace.id2obj(self, id)
+ }
+ end
+
+ def type(node, key)
+ tk_call('::blt::tree', 'type', tagid(node), key)
+ end
+
+ def unset(node, *keys)
+ tk_call('::blt::tree', 'unset', tagid(node), *keys)
+ self
+ end
+
+ def values(node, key=None)
+ simplelist(tk_call('::blt::tree', 'values', tagid(node), key))
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/treeview.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/treeview.rb
new file mode 100644
index 0000000..38d9041
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/treeview.rb
@@ -0,0 +1,1287 @@
+#
+# tkextlib/blt/treeview.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+require 'tk/validation.rb'
+
+module Tk::BLT
+ class Treeview < TkWindow
+ module ConfigMethod
+ end
+
+ module TagOrID_Methods
+ end
+
+ class Node < TkObject
+ end
+
+ class Tag < TkObject
+ end
+ end
+
+ class Hiertable < Treeview
+ end
+end
+
+######################################
+
+module Tk::BLT::Treeview::ConfigMethod
+ include TkItemConfigMethod
+
+ def __item_boolval_optkeys(id)
+ case id
+ when Array
+ # id := [ 'column', name ]
+ ['edit', 'hide']
+ when 'sort'
+ ['decreasing']
+ else
+ []
+ end
+ end
+ private :__item_boolval_optkeys
+
+ def __item_strval_optkeys(id)
+ case id
+ when Array
+ # id := [ 'column', name ]
+ super() << 'titleforeground' << 'titleshadow'
+ when 'sort'
+ ['decreasing']
+ else
+ []
+ end
+ end
+ private :__item_strval_optkeys
+
+ def __item_listval_optkeys(id)
+ case id
+ when 'entry'
+ ['bindtags']
+ else
+ []
+ end
+ end
+ private :__item_listval_optkeys
+
+ def __item_cget_cmd(id)
+ if id.kind_of?(Array)
+ # id := [ type, name ]
+ [self.path, id[0], 'cget', id[1]]
+ else
+ [self.path, id, 'cget']
+ end
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(id)
+ if id.kind_of?(Array)
+ # id := [ type, name ]
+ [self.path, id[0], 'configure', id[1]]
+ else
+ [self.path, id, 'configure']
+ end
+ 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 column_cget_tkstring(name, option)
+ itemcget_tkstring(['column', name], option)
+ end
+ def column_cget(name, option)
+ itemcget(['column', name], option)
+ end
+ def column_cget_strict(name, option)
+ itemcget_strict(['column', name], option)
+ end
+ def column_configure(name, slot, value=None)
+ itemconfigure(['column', name], slot, value)
+ end
+ def column_configinfo(name, slot=nil)
+ itemconfiginfo(['column', name], slot)
+ end
+ def current_column_configinfo(name, slot=nil)
+ current_itemconfiginfo(['column', name], slot)
+ end
+
+ def button_cget_tkstring(option)
+ itemcget_tkstring('button', option)
+ end
+ def button_cget(option)
+ itemcget('button', option)
+ end
+ def button_cget_strict(option)
+ itemcget_strict('button', option)
+ end
+ def button_configure(slot, value=None)
+ itemconfigure('button', slot, value)
+ end
+ def button_configinfo(slot=nil)
+ itemconfiginfo('button', slot)
+ end
+ def current_button_configinfo(slot=nil)
+ current_itemconfiginfo('button', slot)
+ end
+
+ def entry_cget_tkstring(option)
+ itemcget_tkstring('entry', option)
+ end
+ def entry_cget(option)
+ ret = itemcget('entry', option)
+ if option == 'bindtags' || option == :bindtags
+ ret.collect{|tag| TkBindTag.id2obj(tag)}
+ else
+ ret
+ end
+ end
+ def entry_cget_strict(option)
+ ret = itemcget_strict('entry', option)
+ if option == 'bindtags' || option == :bindtags
+ ret.collect{|tag| TkBindTag.id2obj(tag)}
+ else
+ ret
+ end
+ end
+ def entry_configure(slot, value=None)
+ itemconfigure('entry', slot, value)
+ end
+ def entry_configinfo(slot=nil)
+ ret = itemconfiginfo('entry', slot)
+
+ if TkComm::GET_CONFIGINFO_AS_ARRAY
+ if slot
+ if slot == 'bindtags' || slot == :bindtags
+ ret[-2] = ret[-2].collect{|tag| TkBindTag.id2obj(tag)}
+ ret[-1] = ret[-1].collect{|tag| TkBindTag.id2obj(tag)}
+ end
+ else
+ inf = ret.assoc('bindtags')
+ inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}
+ inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}
+ end
+
+ else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
+ if (inf = ret['bindtags'])
+ inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}
+ inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}
+ ret['bindtags'] = inf
+ end
+ end
+
+ ret
+ end
+ def current_entry_configinfo(slot=nil)
+ ret = current_itemconfiginfo('entry', slot)
+
+ if (val = ret['bindtags'])
+ ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)}
+ end
+
+ ret
+ end
+
+ def sort_cget_tkstring(option)
+ itemcget_tkstring('sort', option)
+ end
+ def sort_cget(option)
+ itemcget('sort', option)
+ end
+ def sort_cget_strict(option)
+ itemcget_strict('sort', option)
+ end
+ def sort_configure(slot, value=None)
+ itemconfigure('sort', slot, value)
+ end
+ def sort_configinfo(slot=nil)
+ itemconfiginfo('sort', slot)
+ end
+ def current_sort_configinfo(slot=nil)
+ current_itemconfiginfo('sort', slot)
+ end
+
+ def text_cget_tkstring(option)
+ itemcget_tkstring('text', option)
+ end
+ def text_cget(option)
+ itemcget('text', option)
+ end
+ def text_cget_strict(option)
+ itemcget_strict('text', option)
+ end
+ def text_configure(slot, value=None)
+ itemconfigure('text', slot, value)
+ end
+ def text_configinfo(slot=nil)
+ itemconfiginfo('text', slot)
+ end
+ def current_text_configinfo(slot=nil)
+ current_itemconfiginfo('text', slot)
+ end
+
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+end
+
+class Tk::BLT::Treeview
+ TkCommandNames = ['::blt::treeview'.freeze].freeze
+ WidgetClassName = 'TreeView'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ include Scrollable
+ include ValidateConfigure
+ include ItemValidateConfigure
+ include Tk::BLT::Treeview::ConfigMethod
+
+ ########################
+
+ def __boolval_optkeys
+ ['autocreate', 'allowduplicates', 'exportselection', 'flat', 'hideroot',
+ 'newtags', 'showtitles', 'sortselection']
+ end
+ private :__boolval_optkeys
+
+ def __strval_optkeys
+ super() + ['focusforeground', 'linecolor', 'separator', 'trim']
+ end
+ private :__strval_optkeys
+
+ ########################
+
+ class OpenCloseCommand < TkValidateCommand
+ class ValidateArgs < TkUtil::CallbackSubst
+ KEY_TBL = [
+ [ ?W, ?w, :widget ],
+ [ ?p, ?s, :name ],
+ [ ?P, ?s, :fullpath ],
+ [ ?#, ?x, :node_id ],
+ nil
+ ]
+
+ PROC_TBL = [
+ [ ?x, TkComm.method(:num_or_str) ],
+ [ ?s, TkComm.method(:string) ],
+ [ ?w, TkComm.method(:window) ],
+ nil
+ ]
+
+=begin
+ # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
+ KEY_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
+ end
+ inf
+ }
+
+ PROC_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ end
+ inf
+ }
+=end
+
+ _setup_subst_table(KEY_TBL, PROC_TBL);
+
+ def self.ret_val(val)
+ val
+ end
+ end
+
+ def self._config_keys
+ ['opencommand', 'closecomand']
+ end
+ end
+
+ def __validation_class_list
+ super() << OpenCloseCommand
+ end
+
+ Tk::ValidateConfigure.__def_validcmd(binding, OpenCloseCommand)
+
+ ########################
+
+ def __item_validation_class_list(id)
+ case id
+ when 'entry'
+ super(id) << OpenCloseCommand
+ else
+ super(id)
+ end
+ end
+
+ Tk::ItemValidateConfigure.__def_validcmd(binding, OpenCloseCommand)
+
+ ########################
+
+ def __destroy_hook__
+ Tk::BLT::Treeview::Node::TreeNodeID_TBL.mutex.synchronize{
+ Tk::BLT::Treeview::Node::TreeNodeID_TBL.delete(@path)
+ }
+ Tk::BLT::Treeview::Tag::TreeTagID_TBL.mutex.synchronize{
+ Tk::BLT::Treeview::Tag::TreeTagID_TBL.delete(@path)
+ }
+ end
+
+ def tagid(tag)
+ if tag.kind_of?(Tk::BLT::Treeview::Node) \
+ || tag.kind_of?(Tk::BLT::Treeview::Tag)
+ tag.id
+ else
+ tag # maybe an Array of configure parameters
+ end
+ end
+ private :tagid
+
+ def tagid2obj(tagid)
+ if tagid.kind_of?(Integer)
+ Tk::BLT::Treeview::Node.id2obj(self, tagid.to_s)
+ elsif tagid.kind_of?(String)
+ if tagid =~ /^\d+$/
+ Tk::BLT::Treeview::Node.id2obj(self, tagid)
+ else
+ Tk::BLT::Treeview::Tag.id2obj(self, tagid)
+ end
+ else
+ tagid
+ end
+ end
+
+ def bbox(*tags)
+ list(tk_send('bbox', *(tags.collect{|tag| tagid(tag)})))
+ end
+
+ def screen_bbox(*tags)
+ list(tk_send('bbox', '-screen', *(tags.collect{|tag| tagid(tag)})))
+ end
+
+ def tag_bind(tag, seq, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind([@path, 'bind', tagid(tag)], seq, cmd, *args)
+ self
+ end
+ def tag_bind_append(tag, seq, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append([@path, 'bind', tagid(tag)], seq, cmd, *args)
+ self
+ end
+ def tag_bind_remove(tag, seq)
+ _bind_remove([@path, 'bind', tagid(tag)], seq)
+ self
+ end
+ def tag_bindinfo(tag, seq=nil)
+ _bindinfo([@path, 'bind', tagid(tag)], seq)
+ end
+
+ def button_activate(tag)
+ tk_send('button', 'activate', tagid(tag))
+ self
+ end
+
+ def button_bind(tag, seq, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind([@path, 'button', 'bind', tagid(tag)], seq, cmd, *args)
+ self
+ end
+ def button_bind_append(tag, seq, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append([@path, 'button', 'bind', tagid(tag)], seq, cmd, *args)
+ self
+ end
+ def button_bind_remove(tag, seq)
+ _bind_remove([@path, 'button', 'bind', tagid(tag)], seq)
+ self
+ end
+ def button_bindinfo(tag, seq=nil)
+ _bindinfo([@path, 'button', 'bind', tagid(tag)], seq)
+ end
+
+ def close(*tags)
+ tk_send('close', *(tags.collect{|tag| tagid(tag)}))
+ self
+ end
+ def close_recurse(*tags)
+ tk_send('close', '-recurse', *(tags.collect{|tag| tagid(tag)}))
+ self
+ end
+
+ def column_activate(column=None)
+ if column == None
+ tk_send('column', 'activate')
+ else
+ tk_send('column', 'activate', column)
+ self
+ end
+ end
+
+ def column_delete(*fields)
+ tk_send('column', 'delete', *fields)
+ self
+ end
+ def column_insert(pos, field, *opts)
+ tk_send('column', 'insert', pos, field, *opts)
+ self
+ end
+ def column_invoke(field)
+ tk_send('column', 'invoke', field)
+ self
+ end
+ def column_move(name, dest)
+ tk_send('column', 'move', name, dest)
+ self
+ end
+ def column_names()
+ simplelist(tk_send('column', 'names'))
+ end
+ def column_nearest(x, y=None)
+ tk_send('column', 'nearest', x, y)
+ end
+
+ def curselection
+ simplelist(tk_send('curselection')).collect{|id| tagid2obj(id)}
+ end
+
+ def delete(*tags)
+ tk_send('delete', *(tags.collect{|tag| tagid(tag)}))
+ self
+ end
+
+ def entry_activate(tag)
+ tk_send('entry', 'activate', tagid(tag))
+ self
+ end
+ def entry_children(tag, first=None, last=None)
+ simplelist(tk_send('entry', 'children', tagid(tag),
+ first, last)).collect{|id| tagid2obj(id)}
+ end
+ def entry_delete(tag, first=None, last=None)
+ tk_send('entry', 'delete', tagid(tag), first, last)
+ end
+ def entry_before?(tag1, tag2)
+ bool(tk_send('entry', 'isbefore', tagid(tag1), tagid(tag2)))
+ end
+ def entry_hidden?(tag)
+ bool(tk_send('entry', 'ishidden', tagid(tag)))
+ end
+ def entry_open?(tag)
+ bool(tk_send('entry', 'isopen', tagid(tag)))
+ end
+
+ def entry_size(tag)
+ number(tk_send('entry', 'size', tagid(tag)))
+ end
+ def entry_size_recurse(tag)
+ number(tk_send('entry', 'size', '-recurse', tagid(tag)))
+ end
+
+ def _search_flags(keys)
+ keys = _symbolkey2str(keys)
+ keys['exact'] = None if keys.delete('exact')
+ keys['glob'] = None if keys.delete('glob')
+ keys['regexp'] = None if keys.delete('regexp')
+ keys['nonmatching'] = None if keys.delete('nonmatching')
+ end
+ private :_search_flags
+
+ ################################
+
+ class FindExecFlagValue < TkValidateCommand
+ class ValidateArgs < TkUtil::CallbackSubst
+ KEY_TBL = [
+ [ ?W, ?w, :widget ],
+ [ ?p, ?s, :name ],
+ [ ?P, ?s, :fullpath ],
+ [ ?#, ?x, :node_id ],
+ nil
+ ]
+
+ PROC_TBL = [
+ [ ?x, TkComm.method(:num_or_str) ],
+ [ ?s, TkComm.method(:string) ],
+ [ ?w, TkComm.method(:window) ],
+ nil
+ ]
+
+=begin
+ # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
+ KEY_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
+ end
+ inf
+ }
+
+ PROC_TBL.map!{|inf|
+ if inf.kind_of?(Array)
+ inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
+ end
+ inf
+ }
+=end
+
+ _setup_subst_table(KEY_TBL, PROC_TBL);
+
+ def self.ret_val(val)
+ val
+ end
+ end
+
+ def self._config_keys
+ []
+ end
+ end
+
+ def _find_exec_flag_value(val)
+ if val.kind_of?(Array)
+ cmd, *args = val
+ #FindExecFlagValue.new(cmd, args.join(' '))
+ FindExecFlagValue.new(cmd, *args)
+ elsif TkComm._callback_entry?(val)
+ FindExecFlagValue.new(val)
+ else
+ val
+ end
+ end
+
+ ################################
+
+ def find(first, last, keys={})
+ keys = _search_flags(keys)
+ keys['exec'] = _find_exec_flag_value(keys['exec']) if keys.key?('exec')
+ args = hash_kv(keys) << '--' << tagid(first) << tagid(last)
+ simplelist(tk_send('find', *args)).collect{|id| tagid2obj(id)}
+ end
+
+ def tag_focus(tag)
+ tk_send('focus', tagid(tag))
+ self
+ end
+ def get(*tags)
+ simplelist(tk_send('get', *(tags.collect{|tag| tagid(tag)})))
+ end
+ def get_full(*tags)
+ simplelist(tk_send('get', '-full', *(tags.collect{|tag| tagid(tag)})))
+ end
+
+ def hide(*tags)
+ if tags[-1].kind_of?(Hash)
+ keys = tags.pop
+ else
+ keys = {}
+ end
+ keys = _search_flags(keys)
+ args = hash_kv(keys) << '--'
+ args.concat(tags.collect{|t| tagid(t)})
+ tk_send('hide', *args)
+ self
+ end
+
+ def index(str)
+ tagid2obj(tk_send('index', str))
+ end
+ def index_at(tag, str)
+ tagid2obj(tk_send('index', '-at', tagid(tag), str))
+ end
+ def index_at_path(tag, str)
+ tagid2obj(tk_send('index', '-at', tagid(tag), '-path', str))
+ end
+
+ def insert(pos, parent=nil, keys={})
+ Tk::BLT::Treeview::Node.new(pos, parent, keys)
+ end
+ def insert_at(tag, pos, parent=nil, keys={})
+ if parent.kind_of?(Hash)
+ keys = parent
+ parent = nil
+ end
+
+ keys = _symbolkey2str(keys)
+ keys['at'] = tagid(tag)
+
+ Tk::BLT::Treeview::Node.new(pos, parent, keys)
+ end
+
+ def move_before(tag, dest)
+ tk_send('move', tagid(tag), 'before', tagid(dest))
+ self
+ end
+ def move_after(tag, dest)
+ tk_send('move', tagid(tag), 'after', tagid(dest))
+ self
+ end
+ def move_into(tag, dest)
+ tk_send('move', tagid(tag), 'into', tagid(dest))
+ self
+ end
+
+ def nearest(x, y, var=None)
+ tagid2obj(tk_send('nearest', x, y, var))
+ end
+
+ def open(*tags)
+ tk_send('open', *(tags.collect{|tag| tagid(tag)}))
+ self
+ end
+ def open_recurse(*tags)
+ tk_send('open', '-recurse', *(tags.collect{|tag| tagid(tag)}))
+ self
+ end
+
+ def range(first, last)
+ simplelist(tk_send('range', tagid(first), tagid(last))).collect{|id|
+ tagid2obj(id)
+ }
+ end
+ def range_open(first, last)
+ simplelist(tk_send('range', '-open',
+ tagid(first), tagid(last))).collect{|id|
+ tagid2obj(id)
+ }
+ 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(tag)
+ tk_send_without_enc('see', tagid(tag))
+ self
+ end
+ def see_anchor(anchor, tag)
+ tk_send_without_enc('see', '-anchor', anchor, tagid(tag))
+ self
+ end
+
+ def selection_anchor(tag)
+ tk_send_without_enc('selection', 'anchor', tagid(tag))
+ self
+ end
+ def selection_cancel()
+ tk_send_without_enc('selection', 'cancel')
+ self
+ end
+ def selection_clear(first, last=None)
+ tk_send_without_enc('selection', 'clear', tagid(first), tagid(last))
+ self
+ end
+ def selection_clear_all()
+ tk_send_without_enc('selection', 'clearall')
+ self
+ end
+ def selection_mark(tag)
+ tk_send_without_enc('selection', 'mark', tagid(tag))
+ self
+ end
+ def selection_include?(tag)
+ bool(tk_send('selection', 'include', tagid(tag)))
+ end
+ def selection_present?()
+ bool(tk_send('selection', 'present'))
+ end
+ def selection_set(first, last=None)
+ tk_send_without_enc('selection', 'set', tagid(first), tagid(last))
+ self
+ end
+ def selection_toggle(first, last=None)
+ tk_send_without_enc('selection', 'toggle', tagid(first), tagid(last))
+ self
+ end
+
+ def show(*tags)
+ if tags[-1].kind_of?(Hash)
+ keys = tags.pop
+ else
+ keys = {}
+ end
+ keys = _search_flags(keys)
+ args = hash_kv(keys) << '--'
+ args.concat(tags.collect{|t| tagid(t)})
+ tk_send('show', *args)
+ self
+ end
+
+ def sort_auto(mode)
+ tk_send('sort', 'auto', mode)
+ self
+ end
+ def sort_auto=(mode)
+ tk_send('sort', 'auto', mode)
+ mode
+ end
+ def sort_auto?
+ bool(tk_send('sort', 'auto'))
+ end
+ def sort_once(*tags)
+ tk_send('sort', 'once', *(tags.collect{|tag| tagid(tag)}))
+ self
+ end
+ def sort_once_recurse(*tags)
+ tk_send('sort', 'once', '-recurse', *(tags.collect{|tag| tagid(tag)}))
+ self
+ end
+
+ def tag_add(tag, *ids)
+ tk_send('tag', 'add', tagid(tag), *ids)
+ self
+ end
+ def tag_delete(tag, *ids)
+ tk_send('tag', 'delete', tagid(tag), *ids)
+ self
+ end
+ def tag_forget(tag)
+ tk_send('tag', 'forget', tagid(tag))
+ self
+ end
+ def tag_names(id=nil)
+ id = (id)? tagid(id): None
+
+ simplelist(tk_send('tag', 'nodes', id)).collect{|tag|
+ Tk::BLT::Treeview::Tag.id2obj(self, tag)
+ }
+ end
+ def tag_nodes(tag)
+ simplelist(tk_send('tag', 'nodes', tagid(tag))).collect{|id|
+ Tk::BLT::Treeview::Node.id2obj(self, id)
+ }
+ end
+
+ def text_apply
+ tk_send('text', 'apply')
+ self
+ end
+ def text_cancel
+ tk_send('text', 'cancel')
+ self
+ end
+
+ def text_delete(first, last)
+ tk_send('text', 'delete', first, last)
+ self
+ end
+ def text_get(x, y)
+ tk_send('text', 'get', x, y)
+ end
+ def text_get_root(x, y)
+ tk_send('text', 'get', '-root', x, y)
+ end
+ def text_icursor(idx)
+ tk_send('text', 'icursor', idx)
+ self
+ end
+ def text_index(idx)
+ num_or_str(tk_send('text', 'index', idx))
+ end
+ def text_insert(idx, str)
+ tk_send('text', 'insert', idx, str)
+ self
+ end
+
+ def text_selection_adjust(idx)
+ tk_send('text', 'selection', 'adjust', idx)
+ self
+ end
+ def text_selection_clear
+ tk_send('text', 'selection', 'clear')
+ self
+ end
+ def text_selection_from(idx)
+ tk_send('text', 'selection', 'from', idx)
+ self
+ end
+ def text_selection_present
+ num_or_str(tk_send('text', 'selection', 'present'))
+ end
+ def text_selection_range(start, last)
+ tk_send('text', 'selection', 'range', start, last)
+ self
+ end
+ def text_selection_to(idx)
+ tk_send('text', 'selection', 'to', idx)
+ self
+ end
+
+ def toggle(tag)
+ tk_send('toggle', tagid(tag))
+ self
+ end
+end
+
+######################################
+
+module Tk::BLT::Treeview::TagOrID_Methods
+ def bbox
+ @tree.bbox(self)
+ end
+ def screen_bbox
+ @tree.screen_bbox(self)
+ end
+
+ def bind(seq, *args)
+ @tree.tag_bind(self, seq, *args)
+ self
+ end
+ def bind_append(seq, *args)
+ @tree.tag_bind_append(self, seq, *args)
+ self
+ end
+ def bind_remove(seq)
+ @tree.tag_bind_remove(self, seq)
+ self
+ end
+ def bindinfo(seq=nil)
+ @tree.tag_bindinfo(self, seq)
+ end
+
+ def button_activate
+ @tree.button_activate(self)
+ self
+ end
+
+ def button_bind(seq, *args)
+ @tree.button_bind(self, seq, *args)
+ self
+ end
+ def button_bind_append(seq, *args)
+ @tree.button_bind_append(self, seq, *args)
+ self
+ end
+ def button_bind_remove(seq)
+ @tree.button_bind_remove(self, seq)
+ self
+ end
+ def button_bindinfo(seq=nil)
+ @tree.button_bindinfo(self, seq)
+ end
+
+ def close
+ @tree.close(self)
+ self
+ end
+ def close_recurse
+ @tree.close_recurse(self)
+ self
+ end
+
+ def delete
+ @tree.delete(self)
+ self
+ end
+
+ def entry_activate
+ @tree.entry_activate(self)
+ self
+ end
+ def entry_children(first=None, last=None)
+ @tree.entry_children(self, first, last)
+ end
+ def entry_delete(first=None, last=None)
+ @tree.entry_delete(self, first, last)
+ end
+ def entry_before?(tag)
+ @tree.entry_before?(self, tag)
+ end
+ def entry_hidden?
+ @tree.entry_before?(self)
+ end
+ def entry_open?
+ @tree.entry_open?(self)
+ end
+
+ def entry_size
+ @tree.entry_size(self)
+ end
+ def entry_size_recurse
+ @tree.entry_size_recurse(self)
+ end
+
+ def focus
+ @tree.tag_focus(self)
+ self
+ end
+
+ def get
+ @tree.get(self)
+ end
+ def get_full
+ @tree.get_full(self)
+ end
+
+ def hide
+ @tree.hide(self)
+ self
+ end
+
+ def index(str)
+ @tree.index_at(self, str)
+ end
+ def index_path(str)
+ @tree.index_at_path(self, str)
+ end
+
+ def insert(pos, parent=nil, keys={})
+ @tree.insert_at(self, pos, parent, keys)
+ end
+
+ def move_before(dest)
+ @tree.move_before(self, dest)
+ self
+ end
+ def move_after(dest)
+ @tree.move_after(self, dest)
+ self
+ end
+ def move_into(dest)
+ @tree.move_into(self, dest)
+ self
+ end
+
+ def open
+ @tree.open(self)
+ self
+ end
+ def open_recurse
+ @tree.open_recurse(self)
+ self
+ end
+
+ def range_to(tag)
+ @tree.range(self, tag)
+ end
+ def range_open_to(tag)
+ @tree.range(self, tag)
+ end
+
+ def see
+ @tree.see(self)
+ self
+ end
+ def see_anchor(anchor)
+ @tree.see_anchor(anchor, self)
+ self
+ end
+
+ def selection_anchor
+ @tree.selection_anchor(self)
+ self
+ end
+ def selection_clear
+ @tree.selection_clear(self)
+ self
+ end
+ def selection_mark
+ @tree.selection_mark(self)
+ self
+ end
+ def selection_include?
+ @tree.selection_include?(self)
+ end
+ def selection_set
+ @tree.selection_set(self)
+ self
+ end
+ def selection_toggle
+ @tree.selection_toggle(self)
+ self
+ end
+
+ def show
+ @tree.show(self)
+ self
+ end
+
+ def sort_once
+ @tree.sort_once(self)
+ self
+ end
+ def sort_once_recurse
+ @tree.sort_once_recurse(self)
+ self
+ end
+
+ def toggle
+ @tree.toggle(self)
+ self
+ end
+end
+
+######################################
+
+class Tk::BLT::Treeview::Node < TkObject
+ include Tk::BLT::Treeview::TagOrID_Methods
+
+ TreeNodeID_TBL = TkCore::INTERP.create_table
+
+ (TreeNode_ID = ['blt_treeview_node'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ TkCore::INTERP.init_ip_env{
+ TreeNodeID_TBL.mutex.synchronize{ TreeNodeID_TBL.clear }
+ }
+
+ def self.id2obj(tree, id)
+ tpath = tree.path
+ TreeNodeID_TBL.mutex.synchronize{
+ if TreeNodeID_TBL[tpath]
+ if TreeNodeID_TBL[tpath][id]
+ TreeNodeID_TBL[tpath][id]
+ else
+ begin
+ # self.new(tree, nil, nil, 'node'=>Integer(id))
+ unless (tk_call(@tpath, 'get', id)).empty?
+ id = Integer(id)
+ (obj = self.allocate).instance_eval{
+ @parent = @tree = tree
+ @tpath = @parent.path
+ @path = @id = id
+ TreeNodeID_TBL[@tpath] ||= {}
+ TreeNodeID_TBL[@tpath][@id] = self
+ }
+ obj
+ else
+ id
+ end
+ rescue
+ id
+ end
+ end
+ else
+ id
+ end
+ }
+ end
+
+ def self.new(tree, pos, parent=nil, keys={})
+ if parent.kind_of?(Hash)
+ keys = parent
+ parent = nil
+ end
+
+ keys = _symbolkey2str(keys)
+ tpath = tree.path
+
+ TreeNodeID_TBL.mutex.synchronize{
+ TreeNodeID_TBL[tpath] ||= {}
+ if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id])
+ keys.delete('node')
+ tk_call(tree.path, 'move', id, pos, parent) if parent
+ return obj
+ end
+
+ #super(tree, pos, parent, keys)
+ (obj = self.allocate).instance_eval{
+ initialize(tree, pos, parent, keys)
+ TreeNodeID_TBL[tpath][@id] = self
+ }
+ obj
+ }
+ end
+
+ def initialize(tree, pos, parent, keys)
+ @parent = @tree = tree
+ @tpath = @parent.path
+
+ if (id = keys['node'])
+ # if tk_call(@tpath, 'get', id).empty?
+ # fail RuntimeError, "not exist the node '#{id}'"
+ # end
+ @path = @id = id
+ tk_call(@tpath, 'move', @id, pos, tagid(parent)) if parent
+ configure(keys) if keys && ! keys.empty?
+ else
+ name = nil
+ TreeNode_ID.mutex.synchronize{
+ name = TreeNode_ID.join(TkCore::INTERP._ip_id_).freeze
+ TreeNode_ID[1].succ!
+ }
+
+ at = keys.delete['at']
+
+ if parent
+ if parent.kind_of?(Tk::BLT::Treeview::Node) ||
+ parent.kind_of?(Tk::BLT::Treeview::Tag)
+ path = [get_full(parent.id)[0], name]
+ at = nil # ignore 'at' option
+ else
+ path = [parent.to_s, name]
+ end
+ else
+ path = name
+ end
+
+ if at
+ @id = tk_call(@tpath, 'insert', '-at', tagid(at), pos, path, keys)
+ else
+ @id = tk_call(@tpath, 'insert', pos, path, keys)
+ end
+ @path = @id
+ end
+ end
+
+ def id
+ @id
+ end
+end
+
+######################################
+
+class Tk::BLT::Treeview::Tag < TkObject
+ include Tk::BLT::Treeview::TagOrID_Methods
+
+ TreeTagID_TBL = TkCore::INTERP.create_table
+
+ (TreeTag_ID = ['blt_treeview_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ TkCore::INTERP.init_ip_env{
+ TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }
+ }
+
+ def self.id2obj(tree, name)
+ tpath = tree.path
+ TreeTagID_TBL.mutex.synchronize{
+ if TreeTagID_TBL[tpath]
+ if TreeTagID_TBL[tpath][name]
+ TreeTagID_TBL[tpath][name]
+ else
+ #self.new(tree, name)
+ (obj = self.allocate).instance_eval{
+ @parent = @tree = tree
+ @tpath = @parent.path
+ @path = @id = name
+ TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
+ TreeTagID_TBL[@tpath][@id] = self
+ }
+ obj
+ end
+ else
+ id
+ end
+ }
+ end
+
+ def self.new_by_name(tree, name, *ids)
+ TreeTagID_TBL.mutex.synchronize{
+ unless (obj = TreeTagID_TBL[tree.path][name])
+ (obj = self.allocate).instance_eval{
+ initialize(tree, name, ids)
+ TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
+ TreeTagID_TBL[@tpath][@id] = self
+ }
+ end
+ obj
+ }
+ end
+
+ def self.new(tree, *ids)
+ TreeTagID_TBL.mutex.synchronize{
+ (obj = self.allocate).instance_eval{
+ if tree.kind_of?(Array)
+ initialize(tree[0], tree[1], ids)
+ else
+ initialize(tree, nil, ids)
+ end
+ TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
+ TreeTagID_TBL[@tpath][@id] = self
+ }
+ obj
+ }
+ end
+
+ def initialize(tree, name, ids)
+ @parent = @tree = tree
+ @tpath = @parent.path
+
+ if name
+ @path = @id = name
+ else
+ TreeTag_ID.mutex.synchronize{
+ @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_).freeze
+ TreeTag_ID[1].succ!
+ }
+ end
+
+ unless ids.empty?
+ tk_call(@tpath, 'tag', 'add', @id, *(ids.collect{|id| tagid(id)}))
+ end
+ end
+
+ def tagid(tag)
+ if tag.kind_of?(Tk::BLT::Treeview::Node) \
+ || tag.kind_of?(Tk::BLT::Treeview::Tag)
+ tag.id
+ else
+ tag
+ end
+ end
+ private :tagid
+
+ def id
+ @id
+ end
+
+ def add(*ids)
+ tk_call(@tpath, 'tag', 'add', @id, *(ids{|id| tagid(id)}))
+ self
+ end
+
+ def remove(*ids)
+ tk_call(@tpath, 'tag', 'delete', @id, *(ids{|id| tagid(id)}))
+ self
+ end
+
+ def forget
+ tk_call(@tpath, 'tag', 'forget', @id)
+ self
+ end
+
+ def nodes
+ simplelist(tk_call(@tpath, 'tag', 'nodes', @id)).collect{|id|
+ Tk::BLT::Treeview::Node.id2obj(@tree, id)
+ }
+ end
+end
+
+class Tk::BLT::Hiertable
+ TkCommandNames = ['::blt::hiertable'.freeze].freeze
+ WidgetClassName = 'Hiertable'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/unix_dnd.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/unix_dnd.rb
new file mode 100644
index 0000000..8996f7c
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/unix_dnd.rb
@@ -0,0 +1,141 @@
+#
+# tkextlib/blt/unix_dnd.rb
+#
+# *** This is alpha version, because there is no document on BLT. ***
+#
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module DnD
+ extend TkCore
+
+ TkCommandNames = ['::blt::dnd'.freeze].freeze
+
+ ##############################
+
+ extend TkItemConfigMethod
+
+ class << self
+ def __item_cget_cmd(id)
+ ['::blt::dnd', *id]
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(id)
+ ['::blt::dnd', *id]
+ end
+ private :__item_config_cmd
+
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ def cget_tkstring(win, option)
+ itemcget_tkstring(['cget', win], option)
+ end
+ def cget(win, option)
+ itemcget(['cget', win], option)
+ end
+ def cget_strict(win, option)
+ itemcget_strict(['cget', win], option)
+ end
+ def configure(win, slot, value=None)
+ itemconfigure(['configure', win], slot, value)
+ end
+ def configinfo(win, slot=nil)
+ itemconfiginfo(['configure', win], slot)
+ end
+ def current_configinfo(win, slot=nil)
+ current_itemconfiginfo(['configure', win], slot)
+ end
+
+ def token_cget_tkstring(win, option)
+ itemcget_tkstring(['token', 'cget', win], option)
+ end
+ def token_cget(win, option)
+ itemcget(['token', 'cget', win], option)
+ end
+ def token_cget_strict(win, option)
+ itemcget_strict(['token', 'cget', win], option)
+ end
+ def token_configure(win, slot, value=None)
+ itemconfigure(['token', 'configure', win], slot, value)
+ end
+ def token_configinfo(win, slot=nil)
+ itemconfiginfo(['token', 'configure', win], slot)
+ end
+ def current_token_configinfo(win, slot=nil)
+ current_itemconfiginfo(['token', 'configure', win], slot)
+ end
+
+ def token_windowconfigure(win, slot, value=None)
+ itemconfigure(['token', 'window', win], slot, value)
+ end
+ def token_windowconfiginfo(win, slot=nil)
+ itemconfiginfo(['token', 'window', win], slot)
+ end
+ def current_token_windowconfiginfo(win, slot=nil)
+ current_itemconfiginfo(['token', 'window', win], slot)
+ end
+ end
+
+ ##############################
+
+ def self.cancel(win)
+ tk_call('::blt::dnd', 'cancel', *wins)
+ end
+ def self.delete(*wins)
+ tk_call('::blt::dnd', 'delete', *wins)
+ end
+ def self.delete_source(*wins)
+ tk_call('::blt::dnd', 'delete', '-source', *wins)
+ end
+ def self.delete_target(*wins)
+ tk_call('::blt::dnd', 'delete', '-target', *wins)
+ end
+ def self.drag(win, x, y, token=None)
+ tk_call('::blt::dnd', 'drag', win, x, y, token)
+ end
+ def self.drop(win, x, y, token=None)
+ tk_call('::blt::dnd', 'drop', win, x, y, token)
+ end
+ def self.get_data(win, fmt=nil, cmd=nil)
+ if fmt
+ tk_call('::blt::dnd', 'getdata', win, fmt, cmd)
+ else
+ list(tk_call('::blt::dnd', 'getdata', win))
+ end
+ end
+ def self.names(pat=None)
+ list(tk_call('::blt::dnd', 'names', pat))
+ end
+ def self.source_names(pat=None)
+ list(tk_call('::blt::dnd', 'names', '-source', pat))
+ end
+ def self.target_names(pat=None)
+ list(tk_call('::blt::dnd', 'names', '-target', pat))
+ end
+ def self.pull(win, fmt)
+ tk_call('::blt::dnd', 'pull', win, fmt)
+ end
+ def self.register(win, keys={})
+ tk_call('::blt::dnd', 'register', win, keys)
+ end
+ def self.select(win, x, y, timestamp)
+ tk_call('::blt::dnd', 'select', win, x, y, timestamp)
+ end
+ def self.set_data(win, fmt=nil, cmd=nil)
+ if fmt
+ tk_call('::blt::dnd', 'setdata', win, fmt, cmd)
+ else
+ list(tk_call('::blt::dnd', 'setdata', win))
+ end
+ end
+ def self.token(*args)
+ tk_call('::blt::dnd', 'token', *args)
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/vector.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/vector.rb
new file mode 100644
index 0000000..742e901
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/vector.rb
@@ -0,0 +1,256 @@
+#
+# tkextlib/blt/vector.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Vector < TkVariable
+ TkCommandNames = ['::blt::vector'.freeze].freeze
+
+ def self.create(*args)
+ tk_call('::blt::vector', 'create', *args)
+ end
+
+ def self.destroy(*args)
+ tk_call('::blt::vector', 'destroy', *args)
+ end
+
+ def self.expr(expression)
+ tk_call('::blt::vector', 'expr', expression)
+ end
+
+ def self.names(pat=None)
+ list = simplelist(tk_call('::blt::vector', 'names', pat))
+ TkVar_ID_TBL.mutex.synchronize{
+ list.collect{|name|
+ if TkVar_ID_TBL[name]
+ TkVar_ID_TBL[name]
+ elsif name[0..1] == '::' && TkVar_ID_TBL[name[2..-1]]
+ TkVar_ID_TBL[name[2..-1]]
+ else
+ name
+ end
+ }
+ }
+ end
+
+ ####################################
+
+ def initialize(size=nil, keys={})
+ if size.kind_of?(Hash)
+ keys = size
+ size = nil
+ end
+ if size.kind_of?(Array)
+ # [first, last]
+ size = size.join(':')
+ end
+ if size
+ @id = TkCore::INTERP._invoke('::blt::vector', 'create',
+ "#auto(#{size})", *hash_kv(keys))
+ else
+ @id = TkCore::INTERP._invoke('::blt::vector', 'create',
+ "#auto", *hash_kv(keys))
+ end
+
+ TkVar_ID_TBL.mutex.synchronize{
+ TkVar_ID_TBL[@id] = self
+ }
+
+ @def_default = false
+ @default_val = nil
+
+ @trace_var = nil
+ @trace_elem = nil
+ @trace_opts = nil
+
+ # teach Tk-ip that @id is global var
+ TkCore::INTERP._invoke_without_enc('global', @id)
+ end
+
+ def destroy
+ tk_call('::blt::vector', 'destroy', @id)
+ end
+
+ def inspect
+ '#<Tk::BLT::Vector: ' + @id + '>'
+ end
+
+ def to_s
+ @id
+ end
+
+ def *(item)
+ list(tk_call(@id, '*', item))
+ end
+
+ def +(item)
+ list(tk_call(@id, '+', item))
+ end
+
+ def -(item)
+ list(tk_call(@id, '-', item))
+ end
+
+ def /(item)
+ list(tk_call(@id, '/', item))
+ end
+
+ def append(*vectors)
+ tk_call(@id, 'append', *vectors)
+ end
+
+ def binread(channel, len=None, keys={})
+ if len.kind_of?(Hash)
+ keys = len
+ len = None
+ end
+ keys = _symbolkey2str(keys)
+ keys['swap'] = None if keys.delete('swap')
+ tk_call(@id, 'binread', channel, len, keys)
+ end
+
+ def clear()
+ tk_call(@id, 'clear')
+ self
+ end
+
+ def delete(*indices)
+ tk_call(@id, 'delete', *indices)
+ self
+ end
+
+ def dup_vector(vec)
+ tk_call(@id, 'dup', vec)
+ self
+ end
+
+ def expr(expression)
+ tk_call(@id, 'expr', expression)
+ self
+ end
+
+ def index(idx, val=None)
+ number(tk_call(@id, 'index', idx, val))
+ end
+
+ def [](idx)
+ index(idx)
+ end
+
+ def []=(idx, val)
+ index(idx, val)
+ end
+
+ def length()
+ number(tk_call(@id, 'length'))
+ end
+
+ def length=(size)
+ number(tk_call(@id, 'length', size))
+ end
+
+ def merge(*vectors)
+ tk_call(@id, 'merge', *vectors)
+ self
+ end
+
+ def normalize(vec=None)
+ tk_call(@id, 'normalize', vec)
+ self
+ end
+
+ def notify(keyword)
+ tk_call(@id, 'notify', keyword)
+ self
+ end
+
+ def offset()
+ number(tk_call(@id, 'offset'))
+ end
+
+ def offset=(val)
+ number(tk_call(@id, 'offset', val))
+ end
+
+ def random()
+ tk_call(@id, 'random')
+ end
+
+ def populate(vector, density=None)
+ tk_call(@id, 'populate', vector, density)
+ self
+ end
+
+ def range(first, last=None)
+ list(tk_call(@id, 'range', first, last))
+ end
+
+ def search(val1, val2=None)
+ list(tk_call(@id, 'search', val1, val2))
+ end
+
+ def set(item)
+ tk_call(@id, 'set', item)
+ self
+ end
+
+ def seq(start, finish=None, step=None)
+ tk_call(@id, 'seq', start, finish, step)
+ self
+ end
+
+ def sort(*vectors)
+ tk_call(@id, 'sort', *vectors)
+ self
+ end
+
+ def sort_reverse(*vectors)
+ tk_call(@id, 'sort', '-reverse', *vectors)
+ self
+ end
+
+ def split(*vectors)
+ tk_call(@id, 'split', *vectors)
+ self
+ end
+
+ def variable(var)
+ tk_call(@id, 'variable', var)
+ self
+ end
+ end
+
+ class VectorAccess < Vector
+ def self.new(name)
+ TkVar_ID_TBL.mutex.synchronize{
+ if TkVar_ID_TBL[name]
+ TkVar_ID_TBL[name]
+ else
+ (obj = self.allocate).instance_eval{
+ initialize(name)
+ TkVar_ID_TBL[@id] = self
+ }
+ obj
+ end
+ }
+ end
+
+ def initialize(vec_name)
+ @id = vec_name
+
+ @def_default = false
+ @default_val = nil
+
+ @trace_var = nil
+ @trace_elem = nil
+ @trace_opts = nil
+
+ # teach Tk-ip that @id is global var
+ TkCore::INTERP._invoke_without_enc('global', @id)
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/watch.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/watch.rb
new file mode 100644
index 0000000..292623f
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/watch.rb
@@ -0,0 +1,175 @@
+#
+# tkextlib/blt/watch.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Watch < TkObject
+ extend TkCore
+
+ TkCommandNames = ['::blt::watch'.freeze].freeze
+
+ WATCH_ID_TBL = TkCore::INTERP.create_table
+
+ (BLT_WATCH_ID = ['blt_watch_id'.freeze, TkUtil.untrust('00000')]).instance_eval{
+ @mutex = Mutex.new
+ def mutex; @mutex; end
+ freeze
+ }
+
+ TkCore::INTERP.init_ip_env{
+ WATCH_ID_TBL.mutex.synchronize{ WATCH_ID_TBL.clear }
+ }
+
+ def self.names(state = None)
+ lst = tk_split_list(tk_call('::blt::watch', 'names', state))
+ WATCH_ID_TBL.mutex.synchronize{
+ lst.collect{|name|
+ WATCH_ID_TBL[name] || name
+ }
+ }
+ end
+
+ def __numval_optkeys
+ ['maxlevel']
+ end
+ private :__numval_optkeys
+
+ def __boolval_optkeys
+ ['active']
+ end
+ private :__boolval_optkeys
+
+ def __config_cmd
+ ['::blt::watch', 'configure', self.path]
+ end
+ private :__config_cmd
+
+ def initialize(name = nil, keys = {})
+ if name.kind_of?(Hash)
+ keys = name
+ name = nil
+ end
+
+ if name
+ @id = name.to_s
+ else
+ BLT_WATCH_ID.mutex.synchronize{
+ @id = BLT_WATCH_ID.join(TkCore::INTERP._ip_id_)
+ BLT_WATCH_ID[1].succ!
+ }
+ end
+
+ @path = @id
+
+ WATCH_ID_TBL.mutex.synchronize{
+ WATCH_ID_TBL[@id] = self
+ }
+ tk_call('::blt::watch', 'create', @id, *hash_kv(keys))
+ end
+
+ def activate
+ tk_call('::blt::watch', 'activate', @id)
+ self
+ end
+ def deactivate
+ tk_call('::blt::watch', 'deactivate', @id)
+ self
+ end
+ def delete
+ tk_call('::blt::watch', 'delete', @id)
+ self
+ end
+ def info
+ ret = []
+ lst = tk_split_simplelist(tk_call('::blt::watch', 'info', @id))
+ until lst.empty?
+ k, v, *lst = lst
+ k = k[1..-1]
+ case k
+ when /^(#{__strval_optkeys.join('|')})$/
+ # do nothing
+
+ when /^(#{__numval_optkeys.join('|')})$/
+ begin
+ v = number(v)
+ rescue
+ v = nil
+ end
+
+ when /^(#{__numstrval_optkeys.join('|')})$/
+ v = num_or_str(v)
+
+ when /^(#{__boolval_optkeys.join('|')})$/
+ begin
+ v = bool(v)
+ rescue
+ v = nil
+ end
+
+ when /^(#{__listval_optkeys.join('|')})$/
+ v = simplelist(v)
+
+ when /^(#{__numlistval_optkeys.join('|')})$/
+ v = list(v)
+
+ else
+ if v.index('{')
+ v = tk_split_list(v)
+ else
+ v = tk_tcl2ruby(v)
+ end
+ end
+
+ ret << [k, v]
+ end
+
+ ret
+ end
+ def configinfo(slot = nil)
+ if slot
+ slot = slot.to_s
+ v = cget(slot)
+ if TkComm::GET_CONFIGINFO_AS_ARRAY
+ [slot, v]
+ else
+ {slot=>v}
+ end
+ else
+ if TkComm::GET_CONFIGINFO_AS_ARRAY
+ info
+ else
+ Hash[*(info.flatten)]
+ end
+ end
+ end
+ def cget_strict(key)
+ key = key.to_s
+ begin
+ info.assoc(key)[1]
+ rescue
+ fail ArgumentError, "unknown option '#{key}'"
+ end
+ end
+ def cget(key)
+ unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
+ cget_strict(key)
+ else
+ begin
+ cget_strict(key)
+ rescue => e
+ if current_configinfo.has_key?(key.to_s)
+ # error on known option
+ fail e
+ else
+ # unknown option
+ nil
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/win_printer.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/win_printer.rb
new file mode 100644
index 0000000..7ac6a0d
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/win_printer.rb
@@ -0,0 +1,61 @@
+#
+# tkextlib/blt/win_printer.rb
+#
+# *** Windows only ***
+#
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ class Printer < TkObject
+ extend TkCore
+
+ TkCommandNames = ['::blt::printer'.freeze].freeze
+
+ def self.enum(attribute)
+ simplelist(tk_call('::blt::printer', 'enum', attribute))
+ end
+
+ def self.names(pat=None)
+ simplelist(tk_call('::blt::printer', 'names', pat))
+ end
+
+ def self.open(printer)
+ self.new(printer)
+ end
+
+ #################################
+
+ def initialize(printer)
+ @printer_id = tk_call('::blt::printer', 'open', printer)
+ end
+
+ def close
+ tk_call('::blt::print', 'close', @printer_id)
+ self
+ end
+ def get_attrs(var)
+ tk_call('::blt::print', 'getattrs', @printer_id, var)
+ var
+ end
+ def set_attrs(var)
+ tk_call('::blt::print', 'setattrs', @printer_id, var)
+ self
+ end
+ def snap(win)
+ tk_call('::blt::print', 'snap', @printer_id, win)
+ self
+ end
+ def write(str)
+ tk_call('::blt::print', 'write', @printer_id, str)
+ self
+ end
+ def write_with_title(title, str)
+ tk_call('::blt::print', 'write', @printer_id, title, str)
+ self
+ end
+ end
+end
diff --git a/jni/ruby/ext/tk/lib/tkextlib/blt/winop.rb b/jni/ruby/ext/tk/lib/tkextlib/blt/winop.rb
new file mode 100644
index 0000000..03bdb60
--- /dev/null
+++ b/jni/ruby/ext/tk/lib/tkextlib/blt/winop.rb
@@ -0,0 +1,107 @@
+#
+# tkextlib/blt/winop.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+
+require 'tk'
+require 'tkextlib/blt.rb'
+
+module Tk::BLT
+ module Winop
+ extend TkCore
+
+ TkCommandNames = ['::blt::winop'.freeze].freeze
+ end
+ WinOp = Winop
+end
+
+class << Tk::BLT::Winop
+ def changes(win)
+ tk_call('::blt::winop', 'changes', win)
+ end
+
+ def colormap(win)
+ Hash[*list(tk_call('::blt::winop', 'colormap', win))]
+ end
+
+ def convolve(src, dest, filter)
+ tk_call('::blt::winop', 'convolve', src, dest, filter)
+ end
+
+ def image_convolve(src, dest, filter)
+ tk_call('::blt::winop', 'image', 'convolve', src, dest, filter)
+ end
+ def image_gradient(photo, left, right, type)
+ tk_call('::blt::winop', 'image', 'gradient', photo, left, right, type)
+ end
+ def image_read_jpeg(file, photo)
+ tk_call('::blt::winop', 'image', 'readjpeg', file, photo)
+ end
+ def image_resample(src, dest, horiz_filter=None, vert_filter=None)
+ tk_call('::blt::winop', 'image', 'resample',
+ src, dest, horiz_filter, vert_filter)
+ end
+ def image_rotate(src, dest, angle)
+ tk_call('::blt::winop', 'image', 'rotate', src, dest, angle)
+ end
+ def image_snap(win, photo, width=None, height=None)
+ tk_call('::blt::winop', 'image', 'snap', win, photo, width, height)
+ end
+ def image_subsample(src, dest, x, y, width, height,
+ horiz_filter=None, vert_filter=None)
+ tk_call('::blt::winop', 'image', 'subsample',
+ src, dest, x, y, width, height, horiz_filter, vert_filter)
+ end
+
+ def quantize(src, dest, colors)
+ tk_call('::blt::winop', 'quantize', src, dest, colors)
+ end
+
+ def query()
+ tk_call('::blt::winop', 'query')
+ end
+
+ def read_jpeg(file, photo)
+ tk_call('::blt::winop', 'readjpeg', file, photo)
+ end
+
+ def resample(src, dest, horiz_filter=None, vert_filter=None)
+ tk_call('::blt::winop', 'resample',
+ src, dest, horiz_filter, vert_filter)
+ end
+
+ def subsample(src, dest, x, y, width, height,
+ horiz_filter=None, vert_filter=None)
+ tk_call('::blt::winop', 'subsample',
+ src, dest, x, y, width, height, horiz_filter, vert_filter)
+ end
+
+ def raise(*wins)
+ tk_call('::blt::winop', 'raise', *wins)
+ end
+
+ def lower(*wins)
+ tk_call('::blt::winop', 'lower', *wins)
+ end
+
+ def map(*wins)
+ tk_call('::blt::winop', 'map', *wins)
+ end
+
+ def unmap(*wins)
+ tk_call('::blt::winop', 'unmap', *wins)
+ end
+
+ def move(win, x, y)
+ tk_call('::blt::winop', 'move', win, x, y)
+ end
+
+ def snap(win, photo)
+ tk_call('::blt::winop', 'snap', win, photo)
+ end
+
+ def warpto(win = None)
+ tk_call('::blt::winop', 'warpto', win)
+ end
+ alias warp_to warpto
+end