From 532e34fcd243eaa906880c5c5a9fb77f19e0b7c1 Mon Sep 17 00:00:00 2001 From: nagai Date: Thu, 23 Dec 2004 16:23:30 +0000 Subject: * ext/tk/lib/tkextlib/blt.rb: add BLT extension support * ext/tk/lib/tkextlib/blt/*.rb: ditto * ext/tk/lib/tkextlib/blt/tile/*.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7645 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/tk/ChangeLog.tkextlib | 4 + ext/tk/lib/tk.rb | 2 +- ext/tk/lib/tkextlib/SUPPORT_STATUS | 10 +- ext/tk/lib/tkextlib/blt.rb | 142 +++ ext/tk/lib/tkextlib/blt/barchart.rb | 70 ++ ext/tk/lib/tkextlib/blt/bitmap.rb | 84 ++ ext/tk/lib/tkextlib/blt/busy.rb | 82 ++ ext/tk/lib/tkextlib/blt/component.rb | 1285 +++++++++++++++++++++++++++ ext/tk/lib/tkextlib/blt/container.rb | 23 + ext/tk/lib/tkextlib/blt/cutbuffer.rb | 23 + ext/tk/lib/tkextlib/blt/dragdrop.rb | 199 +++++ ext/tk/lib/tkextlib/blt/eps.rb | 15 + ext/tk/lib/tkextlib/blt/graph.rb | 64 ++ ext/tk/lib/tkextlib/blt/htext.rb | 100 +++ ext/tk/lib/tkextlib/blt/setup.rb | 8 + ext/tk/lib/tkextlib/blt/spline.rb | 23 + ext/tk/lib/tkextlib/blt/stripchart.rb | 70 ++ ext/tk/lib/tkextlib/blt/table.rb | 330 +++++++ ext/tk/lib/tkextlib/blt/tabnotebook.rb | 21 + ext/tk/lib/tkextlib/blt/tabset.rb | 386 ++++++++ ext/tk/lib/tkextlib/blt/ted.rb | 62 ++ ext/tk/lib/tkextlib/blt/tile.rb | 21 + ext/tk/lib/tkextlib/blt/tile/button.rb | 16 + ext/tk/lib/tkextlib/blt/tile/checkbutton.rb | 17 + ext/tk/lib/tkextlib/blt/tile/frame.rb | 16 + ext/tk/lib/tkextlib/blt/tile/label.rb | 16 + ext/tk/lib/tkextlib/blt/tile/radiobutton.rb | 17 + ext/tk/lib/tkextlib/blt/tile/scrollbar.rb | 16 + ext/tk/lib/tkextlib/blt/tile/toplevel.rb | 16 + ext/tk/lib/tkextlib/blt/tree.rb | 881 ++++++++++++++++++ ext/tk/lib/tkextlib/blt/treeview.rb | 1116 +++++++++++++++++++++++ ext/tk/lib/tkextlib/blt/unix_dnd.rb | 129 +++ ext/tk/lib/tkextlib/blt/vector.rb | 243 +++++ ext/tk/lib/tkextlib/blt/watch.rb | 142 +++ ext/tk/lib/tkextlib/blt/win_printer.rb | 61 ++ ext/tk/lib/tkextlib/blt/winop.rb | 107 +++ 36 files changed, 5811 insertions(+), 6 deletions(-) create mode 100644 ext/tk/lib/tkextlib/blt.rb create mode 100644 ext/tk/lib/tkextlib/blt/barchart.rb create mode 100644 ext/tk/lib/tkextlib/blt/bitmap.rb create mode 100644 ext/tk/lib/tkextlib/blt/busy.rb create mode 100644 ext/tk/lib/tkextlib/blt/component.rb create mode 100644 ext/tk/lib/tkextlib/blt/container.rb create mode 100644 ext/tk/lib/tkextlib/blt/cutbuffer.rb create mode 100644 ext/tk/lib/tkextlib/blt/dragdrop.rb create mode 100644 ext/tk/lib/tkextlib/blt/eps.rb create mode 100644 ext/tk/lib/tkextlib/blt/graph.rb create mode 100644 ext/tk/lib/tkextlib/blt/htext.rb create mode 100644 ext/tk/lib/tkextlib/blt/setup.rb create mode 100644 ext/tk/lib/tkextlib/blt/spline.rb create mode 100644 ext/tk/lib/tkextlib/blt/stripchart.rb create mode 100644 ext/tk/lib/tkextlib/blt/table.rb create mode 100644 ext/tk/lib/tkextlib/blt/tabnotebook.rb create mode 100644 ext/tk/lib/tkextlib/blt/tabset.rb create mode 100644 ext/tk/lib/tkextlib/blt/ted.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile/button.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile/checkbutton.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile/frame.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile/label.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile/radiobutton.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile/scrollbar.rb create mode 100644 ext/tk/lib/tkextlib/blt/tile/toplevel.rb create mode 100644 ext/tk/lib/tkextlib/blt/tree.rb create mode 100644 ext/tk/lib/tkextlib/blt/treeview.rb create mode 100644 ext/tk/lib/tkextlib/blt/unix_dnd.rb create mode 100644 ext/tk/lib/tkextlib/blt/vector.rb create mode 100644 ext/tk/lib/tkextlib/blt/watch.rb create mode 100644 ext/tk/lib/tkextlib/blt/win_printer.rb create mode 100644 ext/tk/lib/tkextlib/blt/winop.rb (limited to 'ext') diff --git a/ext/tk/ChangeLog.tkextlib b/ext/tk/ChangeLog.tkextlib index 83989c1a8e..653c6ef7dd 100644 --- a/ext/tk/ChangeLog.tkextlib +++ b/ext/tk/ChangeLog.tkextlib @@ -1,3 +1,7 @@ +2004-12-24 Hidetoshi NAGAI + + * add BLT extension support + 2004-12-16 Hidetoshi NAGAI * bwidget/labelentry.rb: use TkCore.callback_obj?() diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index 69f2b4f2f7..ab0c1a098b 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -3940,7 +3940,7 @@ end #Tk.freeze module Tk - RELEASE_DATE = '2004-12-23'.freeze + RELEASE_DATE = '2004-12-24'.freeze autoload :AUTO_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable' diff --git a/ext/tk/lib/tkextlib/SUPPORT_STATUS b/ext/tk/lib/tkextlib/SUPPORT_STATUS index 6bc87bab98..99da9dc9ea 100644 --- a/ext/tk/lib/tkextlib/SUPPORT_STATUS +++ b/ext/tk/lib/tkextlib/SUPPORT_STATUS @@ -83,6 +83,10 @@ Tile http://tktable.sourceforge.net/tile/ ==> tile ===< possibly available (not tested; alpha quality) >========================= +BLT http://sourceforge.net/projects/blt + * see tcltk-ext library on RAA (http://raa.ruby-lang.org/) + ==> blt + winico http://tktable.sourceforge.net ==> winico (win32 only) @@ -95,9 +99,6 @@ TkDND http://sourceforge.net/projects/tkdnd ==> tkDND ===< plan to support (alpha quality libraries may be included) >============== -BLT http://sourceforge.net/projects/blt - * see tcltk-ext library on RAA (http://raa.ruby-lang.org/) - GraphViz http://www.graphviz.org/ Tkgeomap http://tkgeomap.sourceforge.net/index.html @@ -169,5 +170,4 @@ Memchan http://memchan.sourceforge.net/ tbcload/tclcompiler http://www.tcl.tk/software/tclpro/ - -(End of List) \ No newline at end of file +(End of List) diff --git a/ext/tk/lib/tkextlib/blt.rb b/ext/tk/lib/tkextlib/blt.rb new file mode 100644 index 0000000000..965886762e --- /dev/null +++ b/ext/tk/lib/tkextlib/blt.rb @@ -0,0 +1,142 @@ +# +# BLT support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/variable' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/blt/setup.rb' + +# load all image format handlers +#TkPackage.require('BLT', '2.4') +TkPackage.require('BLT') + +module Tk + module BLT + TkComm::TkExtlibAutoloadModule.unshift(self) + + extend TkCore + + VERSION = tk_call('set', 'blt_version') + PATCH_LEVEL = tk_call('set', 'blt_patchLevel') + + begin + lib = INTERP._invoke('set', 'blt_library') + rescue + lib = '' + end + LIBRARY = TkVarAccess.new('blt_library', lib) + + begin + lib = INTERP._invoke('set', 'blt_libPath') + rescue + lib = '' + end + LIB_PATH = TkVarAccess.new('blt_libPath', lib) + + + def self.package_version + begin + TkPackage.require('BLT') + rescue + '' + end + end + + #################################################### + + def self.beep(percent = 50) + tk_call('::blt::beep', percent) + end + + def self.bgexec(*args) + if args[0].kind_of?(TkVariable) + var = args.shift + else + var = TkVariable.new + end + params = [var] + + params.concat(hash_kv(args.shift, true)) if args[0].kind_of?(Hash) + + params << '--' + params.concat(args) + + tk_call('::blt::bgexec', *params) + var + end + + def self.detach_bgexec(*args) + if args[0].kind_of?(TkVariable) + var = args.shift + else + var = TkVariable.new + end + params = [var] + + params.concat(hash_kv(args.shift, true)) if args[0].kind_of?(Hash) + + params << '--' + params.concat(args) + params << '&' + + [var, tk_split_list(tk_call('::blt::bgexec', *params))] + end + + def self.bltdebug(lvl = nil) + if lvl + tk_call('::blt::bltdebug', lvl) + else + number(tk_call('::blt::bltdebug')) + end + end + + def self.crc32_file(name) + tk_call_without_enc('::blt::crc32', name) + end + def self.crc32_data(dat) + tk_call_without_enc('::blt::crc32', '-data', dat) + end + + #################################################### + + autoload :PlotComponent,'tkextlib/blt/component.rb' + + autoload :Barchart, 'tkextlib/blt/barchart.rb' + autoload :Bitmap, 'tkextlib/blt/bitmap.rb' + autoload :Busy, 'tkextlib/blt/busy.rb' + autoload :Container, 'tkextlib/blt/container.rb' + autoload :CutBuffer, 'tkextlib/blt/cutbuffer.rb' + autoload :DragDrop, 'tkextlib/blt/dragdrop.rb' + autoload :EPS, 'tkextlib/blt/eps.rb' + autoload :Htext, 'tkextlib/blt/htext.rb' + autoload :Graph, 'tkextlib/blt/graph.rb' + autoload :Spline, 'tkextlib/blt/spline.rb' + autoload :Stripchart, 'tkextlib/blt/stripchart.rb' + autoload :Table, 'tkextlib/blt/table.rb' + autoload :Tabnotebook, 'tkextlib/blt/tabnotebook.rb' + autoload :Tabset, 'tkextlib/blt/tabset.rb' + autoload :Ted, 'tkextlib/blt/ted.rb' + autoload :Tile, 'tkextlib/blt/tile.rb' + autoload :Tree, 'tkextlib/blt/tree.rb' + autoload :TreeView, 'tkextlib/blt/treeview.rb' + autoload :Hiertable, 'tkextlib/blt/treeview.rb' + # Hierbox is obsolete + autoload :Vector, 'tkextlib/blt/vector.rb' + autoload :VectorAccess, 'tkextlib/blt/vector.rb' + autoload :Watch, 'tkextlib/blt/watch.rb' + autoload :Winop, 'tkextlib/blt/winop.rb' + autoload :WinOp, 'tkextlib/blt/winop.rb' + + # Unix only + autoload :DnD, 'tkextlib/blt/unix_dnd.rb' + + # Windows only + autoload :Printer, 'tkextlib/blt/win_printer.rb' + end +end diff --git a/ext/tk/lib/tkextlib/blt/barchart.rb b/ext/tk/lib/tkextlib/blt/barchart.rb new file mode 100644 index 0000000000..624906b8bd --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/barchart.rb @@ -0,0 +1,70 @@ +# +# 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 + + def __boolval_optkeys + ['bufferelements', 'invertxy'] + end + private :__boolval_optkeys + + def __strval_optkeys + ['text', 'label', 'title', 'file'] + end + private :__strval_optkeys + + BarElement_ID = ['blt_barchart_bar'.freeze, '00000'.taint].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 + + 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/ext/tk/lib/tkextlib/blt/bitmap.rb b/ext/tk/lib/tkextlib/blt/bitmap.rb new file mode 100644 index 0000000000..11ad5883d0 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/bitmap.rb @@ -0,0 +1,84 @@ +# +# 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, '00000'.taint].freeze + + 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, data, keys) + end + alias define new + + def compose(text, keys={}) + _new(:text, text, keys) + end + end + + def initialize(type, data, keys = {}) + @id = BITMAP_ID.join(TkCore::INTERP._ip_id_) + BITMAP_ID[1].succ! + BITMAP_ID_TBL[@id] = self + + @path = @id + + if type == :text + tk_call('::blt::bitmap', 'compose', @id, *hash_kv(keys)) + else # :data + tk_call('::blt::bitmap', 'define', @id, *hash_kv(keys)) + 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/ext/tk/lib/tkextlib/blt/busy.rb b/ext/tk/lib/tkextlib/blt/busy.rb new file mode 100644 index 0000000000..c0740dc2d7 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/busy.rb @@ -0,0 +1,82 @@ +# +# 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 + end +end + +class << Tk::BLT::Busy + def __item_config_cmd(win) + ['::blt::busy', 'configure', win] + end + private :__item_config_cmd + + undef itemcget + alias configure itemconfigure + alias configinfo itemconfiginfo + alias current_configinfo current_itemconfiginfo + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo + + ################################## + + class Shield < TkWindow + def self.shield_path(win) + win = window(win) unless win.kind_of?(TkWindow) + if win.kind_of?(TkToplevel) + win.path + '._Busy' + else + win.path + '_Busy' + end + end + + def initialize(win) + @path = self.class.shield_path(win) + end + end + + def shield_path(win) + Tk::BLT::Busy::Shield.shield_path(win) + end + + ################################## + + 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/ext/tk/lib/tkextlib/blt/component.rb b/ext/tk/lib/tkextlib/blt/component.rb new file mode 100644 index 0000000000..417c1d454b --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/component.rb @@ -0,0 +1,1285 @@ +# +# 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'] + end + private :__item_strval_optkeys + + def _item_listval_optkeys(id) + ['bindtags'] + end + private :__item_listval_optkeys + + def __item_numlistval_optkeys(id) + ['dashes'] + end + private :__item_numlistval_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 ] + [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 axis_cget(id, option) + ret = itemcget(['axis', id], option) + end + def axis_configure(id, slot, value=None) + itemconfigure(['axis', id], slot, value) + end + def axis_configinfo(id, slot=nil) + itemconfiginfo(['axis', id], slot) + end + def current_axis_configinfo(id, slot=nil) + current_itemconfiginfo(['axis', id], slot) + end + + def crosshairs_cget(option) + itemcget('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(id, option) + itemcget(['element', id], option) + end + def element_configure(id, slot, value=None) + itemconfigure(['element', id], slot, value) + end + def element_configinfo(id, slot=nil) + itemconfiginfo(['element', id], slot) + end + def current_element_configinfo(id, slot=nil) + current_itemconfiginfo(['element', id], slot) + end + + def gridline_cget(option) + itemcget('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(option) + itemcget('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(id, option) + itemcget(['pen', id], option) + end + def pen_configure(id, slot, value=None) + itemconfigure(['pen', id], slot, value) + end + def pen_configinfo(id, slot=nil) + itemconfiginfo(['pen', id], slot) + end + def current_pen_configinfo(id, slot=nil) + current_itemconfiginfo(['pen', id], slot) + end + + def postscript_cget(option) + itemcget('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(id, option) + itemcget(['marker', id], option) + end + def marker_configure(id, slot, value=None) + itemconfigure(['marker', id], slot, value) + end + def marker_configinfo(id, slot=nil) + itemconfiginfo(['marker', id], slot) + end + def current_marker_configinfo(id, slot=nil) + current_itemconfiginfo(['marker', id], slot) + end + + alias __itemcget itemcget + alias __itemconfiginfo itemconfiginfo + alias __current_itemconfiginfo current_itemconfiginfo + private :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo + + def itemcget(tagOrId, option) + ret = __itemcget(tagOrId, option) + if option == 'bindtags' || option == :bindtags + ret.collect{|tag| TkBindTag.id2obj(tag)} + else + ret + end + end + def itemconfiginfo(tagOrId, slot = nil) + ret = __itemconfiginfo(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 + 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_itemconfiginfo(tagOrId, slot = nil) + ret = __current_itemconfiginfo(tagOrId, slot) + + if (val = ret['bindtags']) + ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)} + end + + ret + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + ################# + + class Axis < TkObject + OBJ_ID = ['blt_chart_axis'.freeze, '00000'.taint].freeze + OBJ_TBL={} + + def self.id2obj(chart, id) + cpath = chart.path + return id unless OBJ_TBL[cpath] + OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id + end + + def self.new(chart, axis=nil, keys={}) + if axis.kind_of?(Hash) + keys = axis + axis = nil + end + OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] + return OBJ_TBL[chart.path][axis] if axis && OBJ_TBL[chart.path][axis] + super(chart, axis, keys) + end + + def initialize(chart, axis=nil, keys={}) + if axis.kind_of?(Hash) + keys = axis + axis = nil + end + if axis + @axis = @id = axis.to_s + else + @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze + OBJ_ID[1].succ! + end + @parent = @chart = chart + @cpath = @chart.path + Axis::OBJ_TBL[@cpath][@axis] = self + keys = _symbolkey2str(keys) + unless keys.delete['without_creating'] + @chart.axis_create(@axis, keys) + end + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.axis_cget(@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 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 + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + Crosshairs::OBJ_TBL[@cpath] = self + @chart.crosshair_configure(keys) unless keys.empty? + end + + def id + 'crosshairs' + end + + def to_eval + 'crosshairs' + end + + def cget(option) + @chart.crosshair_cget(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 + OBJ_ID = ['blt_chart_element'.freeze, '00000'.taint].freeze + OBJ_TBL={} + + def self.id2obj(chart, id) + cpath = chart.path + return id unless OBJ_TBL[cpath] + OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id + end + + def self.new(chart, element=nil, keys={}) + if element.kind_of?(Hash) + keys = element + element = nil + end + OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] + if element && OBJ_TBL[chart.path][element] + return OBJ_TBL[chart.path][element] + end + super(chart, element, keys) + end + + def initialize(chart, element=nil, keys={}) + if element.kind_of?(Hash) + keys = element + element = nil + end + if element + @element = @id = element.to_s + else + @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze + OBJ_ID[1].succ! + end + @parent = @chart = chart + @cpath = @chart.path + Element::OBJ_TBL[@cpath][@element] = self + keys = _symbolkey2str(keys) + unless keys.delete['without_creating'] + @chart.element_create(@element, keys) + end + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.element_cget(@id, option) + end + def configure(key, value=None) + @chart.element_configure(@id, key, value) + self + end + def configinfo(key=nil) + @chart.element_configinfo(@id, key) + end + def current_configinfo(key=nil) + @chart.current_element_configinfo(@id, key) + end + + def activate(*args) + @chart.element_activate(@id, *args) + self + end + + def closest(x, y, var, keys={}) + @chart.element_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 GridLine < TkObject + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + GridLine::OBJ_TBL[@cpath] = self + @chart.gridline_configure(keys) unless keys.empty? + end + + def id + 'grid' + end + + def to_eval + 'grid' + end + + def cget(option) + @chart.gridline_cget(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 + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + Crosshairs::OBJ_TBL[@cpath] = self + @chart.crosshair_configure(keys) unless keys.empty? + end + + def id + 'legend' + end + + def to_eval + 'legend' + end + + def cget(option) + @chart.legend_cget(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) + self + end + + def deactivate(*args) + @chart.legend_deactivate(*args) + self + end + + def get(pos, y=nil) + @chart.legend_get(pos, y) + end + end + + ################# + + class Pen < TkObject + OBJ_ID = ['blt_chart_pen'.freeze, '00000'.taint].freeze + OBJ_TBL={} + + def self.id2obj(chart, id) + cpath = chart.path + return id unless OBJ_TBL[cpath] + OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id + end + + def self.new(chart, pen=nil, keys={}) + if pen.kind_of?(Hash) + keys = pen + pen = nil + end + OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] + return OBJ_TBL[chart.path][pen] if pen && OBJ_TBL[chart.path][pen] + super(chart, pen, keys) + 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 + @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze + OBJ_ID[1].succ! + end + @parent = @chart = chart + @cpath = @chart.path + Pen::OBJ_TBL[@cpath][@pen] = self + keys = _symbolkey2str(keys) + unless keys.delete['without_creating'] + @chart.pen_create(@pen, keys) + end + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.pen_cget(@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 + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + Postscript::OBJ_TBL[@cpath] = self + @chart.postscript_configure(keys) unless keys.empty? + end + + def id + 'postscript' + end + + def to_eval + 'postscript' + end + + def cget(option) + @chart.postscript_cget(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.clear } + + def Marker.type2class(type) + MarkerTypeToClass[type] + end + + def Marker.id2obj(chart, id) + cpath = chart.path + return id unless MarkerID_TBL[cpath] + MarkerID_TBL[cpath][id]? MarkerID_TBL[cpath][id]: id + 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_methodcall_optkeys(nil).each{|key| + key = key.to_s + methodkeys[key] = keys.delete(key) if keys.key?(key) + } + + args = itemconfig_hash_kv(nil, keys) + else + args = [] + end + + [args, fontkeys] + 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 = _parse_create_args(keys) + idnum = tk_call_without_enc(chart.path, 'create', + self::MarkerTypeName, *args) + chart.marker_configure(idnum, fontkeys) unless fontkeys.empty? + idnum.to_i # 'item id' is an integer number + end + + def initialize(parent, *args) + @parent = @chart = parent + @path = parent.path + + @id = create_self(*args) # an integer number as 'item id' + unless Tk::BLT::PlotComponent::MarkerID_TBL[@path] + Tk::BLT::PlotComponent::MarkerID_TBL[@path] = {} + end + Tk::BLT::PlotComponent::MarkerID_TBL[@path][@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(option) + @chart.marker_cget(@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::OBJ_TBL.delete(@path) + Crosshairs::OBJ_TBL.delete(@path) + Element::OBJ_TBL.delete(@path) + GridLine::OBJ_TBL.delete(@path) + Legend::OBJ_TBL.delete(@path) + Pen::OBJ_TBL.delete(@path) + Postscript::OBJ_TBL.delete(@path) + Marker::OBJ_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 paramters + end + end + + def _component_bind(target, tag, context, *args) + if TkComm._callback_entry?(args[0]) + 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]) + 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 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 marker_create(type, *args) + type.create(self, *args) + 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{|axis| + 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 + Axis.id2obj(self, tk_send('axis', 'use', tagid(id), tagid(target))) + else + 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_activate(id, *indices) + tk_send('element', 'activate', tagid(id), *indices) + self + end + def element_closest(x, y, var, *args) + if args[-1].kind_of?(Hash) + keys = args.pop + bool(tk_send('element', 'activate', x, y, var, + *(hash_kv(keys).concat(args)))) + else + bool(tk_send('element', 'activate', x, y, var, *args)) + 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{|elem| + Element.id2obj(self, elem) + } + end + def element_show(*names) + if names.empty? + simplelist(tk_send('element', 'show')) + else + tk_send('element', 'show', *names) + self + end + end + def element_type(id) + tk_send('element', '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_activate(*pats) + tk_send('legend', 'activate', *pats) + self + end + def legend_deactivate(*pats) + tk_send('legend', 'deactivate', *pats) + self + end + def legend_get(pos, y=nil) + if y + Element.id2obj(self, tk_send('legend', 'get', _at(pos, y))) + else + Element.id2obj(self, tk_send('legend', 'get', pos)) + end + 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{|pen| + 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_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{|id| + Marker.id2obj(self, id) + } + end + def marker_type(id) + tk_send('marker', 'type', tagid(id)) + end + + ################### + + alias line_cget element_cget + alias line_configure element_configure + alias line_configinfo element_configinfo + alias current_line_configinfo current_element_configinfo + alias line_bind element_bind + alias line_bind_append element_bind_append + alias line_bind_remove element_bind_remove + alias line_bindinfo element_bindinfo + + ################### + + def xaxis_cget(option) + axis_cget('xaxis', option) + end + def xaxis_configure(slot, value=None) + axis_configure('xaxis', slot, value) + end + def xaxis_configinfo(slot=nil) + axis_configinfo('xaxis', slot) + end + def current_xaxis_configinfo(slot=nil) + current_axis_configinfo('xaxis', slot) + end + def xaxis_invtransform(val) + axis_invtransform('xaxis', val) + end + def xaxis_limits + axis_limits('xaxis') + end + def xaxis_transform(val) + axis_transform('xaxis', val) + end + def xaxis_use(target=nil) + axis_use('xaxis', target) + end + + def x2axis_cget(option) + axis_cget('x2axis', option) + end + def x2axis_configure(slot, value=None) + axis_configure('x2axis', slot, value) + end + def x2axis_configinfo(slot=nil) + axis_configinfo('x2axis', slot) + end + def current_x2axis_configinfo(slot=nil) + current_axis_configinfo('x2axis', slot) + end + def x2axis_invtransform(val) + axis_invtransform('x2axis', val) + end + def x2axis_limits + axis_limits('x2axis') + end + def x2axis_transform(val) + axis_transform('x2axis', val) + end + def x2axis_use(target=nil) + axis_use('x2axis', target) + end + + def yaxis_cget(option) + axis_cget('yaxis', option) + end + def yaxis_configure(slot, value=None) + axis_configure('yaxis', slot, value) + end + def yaxis_configinfo(slot=nil) + axis_configinfo('yaxis', slot) + end + def current_yaxis_configinfo(slot=nil) + current_axis_configinfo('yaxis', slot) + end + def yaxis_invtransform(val) + axis_invtransform('yaxis', val) + end + def yaxis_limits + axis_limits('yaxis') + end + def yaxis_transform(val) + axis_transform('yaxis', val) + end + def yaxis_use(target=nil) + axis_use('yaxis', target) + end + + def y2axis_cget(option) + axis_cget('y2axis', option) + end + def y2axis_configure(slot, value=None) + axis_configure('y2axis', slot, value) + end + def y2axis_configinfo(slot=nil) + axis_configinfo('y2axis', slot) + end + def current_y2axis_configinfo(slot=nil) + current_axis_configinfo('y2axis', slot) + end + def y2axis_invtransform(val) + axis_invtransform('y2axis', val) + end + def y2axis_limits + axis_limits('y2axis') + end + def y2axis_transform(val) + axis_transform('y2axis', val) + end + def y2axis_use(target=nil) + axis_use('y2axis', target) + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/container.rb b/ext/tk/lib/tkextlib/blt/container.rb new file mode 100644 index 0000000000..ef711bbcc6 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/container.rb @@ -0,0 +1,23 @@ +# +# 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 + end + + def find_command(pat) + list(tk_send_without_enc(tk_call(self.path, 'find', '-command', pat))) + end + + def find_name(pat) + list(tk_send_without_enc(tk_call(self.path, 'find', '-name', pat))) + end +end diff --git a/ext/tk/lib/tkextlib/blt/cutbuffer.rb b/ext/tk/lib/tkextlib/blt/cutbuffer.rb new file mode 100644 index 0000000000..1cc39dfb94 --- /dev/null +++ b/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/ext/tk/lib/tkextlib/blt/dragdrop.rb b/ext/tk/lib/tkextlib/blt/dragdrop.rb new file mode 100644 index 0000000000..7636c9999e --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/dragdrop.rb @@ -0,0 +1,199 @@ +# +# 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 + + undef itemcget + 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 + ] + + _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 + ] + + _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 + ] + + _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/ext/tk/lib/tkextlib/blt/eps.rb b/ext/tk/lib/tkextlib/blt/eps.rb new file mode 100644 index 0000000000..43b2f8adc0 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/eps.rb @@ -0,0 +1,15 @@ +# +# 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 diff --git a/ext/tk/lib/tkextlib/blt/graph.rb b/ext/tk/lib/tkextlib/blt/graph.rb new file mode 100644 index 0000000000..0c49a70ec4 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/graph.rb @@ -0,0 +1,64 @@ +# +# 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 + + def __boolval_optkeys + ['bufferelements', 'invertxy'] + end + private :__boolval_optkeys + + def __strval_optkeys + ['text', 'label', 'title', 'file'] + end + private :__strval_optkeys + + BarElement_ID = ['blt_graph_bar'.freeze, '00000'.taint].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 + + 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/ext/tk/lib/tkextlib/blt/htext.rb b/ext/tk/lib/tkextlib/blt/htext.rb new file mode 100644 index 0000000000..29da9aa87f --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/htext.rb @@ -0,0 +1,100 @@ +# +# 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 Htexttrue) + 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/ext/tk/lib/tkextlib/blt/table.rb b/ext/tk/lib/tkextlib/blt/table.rb new file mode 100644 index 0000000000..c80e9ac55c --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/table.rb @@ -0,0 +1,330 @@ +# +# 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(@path, *args) + self + end + + def blt_table_arrange() + Tk::BLT::Table.arrange(@path) + self + end + + def blt_table_cget(*args) + Tk::BLT::Table.cget(@path, *args) + end + + def blt_table_configure(*args) + Tk::BLT::Table.configure(@path, *args) + self + end + + def blt_table_configinfo(*args) + Tk::BLT::Table.configinfo(@path, *args) + end + + def blt_table_current_configinfo(*args) + Tk::BLT::Table.current_configinfo(@path, *args) + end + + def blt_table_locate(x, y) + Tk::BLT::Table.locate(@path, x, y) + end + + def blt_table_delete(*args) + Tk::BLT::Table.delete(@path, *args) + self + end + + def blt_table_extents(item) + Tk::BLT::Table.extents(@path, item) + end + + def blt_table_insert(*args) + Tk::BLT::Table.insert(@path, *args) + self + end + + def blt_table_insert_before(*args) + Tk::BLT::Table.insert_before(@path, *args) + self + end + + def blt_table_insert_after(*args) + Tk::BLT::Table.insert_after(@path, *args) + self + end + + def blt_table_join(first, last) + Tk::BLT::Table.join(@path, first, last) + self + end + + def blt_table_save() + Tk::BLT::Table.save(@path) + end + + def blt_table_search(*args) + Tk::BLT::Table.search(@path, *args) + end + + def blt_table_split(*args) + Tk::BLT::Table.split(@path, *args) + self + end + + def blt_table_itemcget(*args) + Tk::BLT::Table.itemcget(@path, *args) + end + + def blt_table_itemconfigure(*args) + Tk::BLT::Table.itemconfigure(@path, *args) + self + end + + def blt_table_itemconfiginfo(*args) + Tk::BLT::Table.itemconfiginfo(@path, *args) + end + + def blt_table_current_itemconfiginfo(*args) + Tk::BLT::Table.current_itemconfiginfo(@path, *args) + end + + def blt_table_iteminfo(item) + Tk::BLT::Table.iteminfo(@path, item) + end + end + end +end + + +############################################ +class << Tk::BLT::Table + def __item_cget_cmd(id) # id := [ container, item ] + ['::blt::table', 'cget', id[0].path, id[1]] + end + private :__item_cget_cmd + + def __item_config_cmd(id) # id := [ container, item, ... ] + container, *items = id + ['::blt::table', 'configure', container.path, *items] + end + private :__item_config_cmd + + def __item_pathname(id) + id[0].path + ';' + end + private :__item_pathname + + alias __itemcget itemcget + alias __itemconfigure itemconfigure + alias __itemconfiginfo itemconfiginfo + alias __current_itemconfiginfo current_itemconfiginfo + + private :__itemcget, :__itemconfigure + private :__itemconfiginfo, :__current_itemconfiginfo + + 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(container, option) + __itemcget([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(container, item, option) + __itemcget([container, tagid(item)], option) + end + + def itemconfigure(container, *args) + if args[-1].kind_of?(Hash) + # container, item, item, ... , hash_optkeys + keys = args.pop + id = [container] + args.each{|item| id << tagid(item)} + __itemconfigure(id, keys) + else + # container, item, item, ... , option, value + val = args.pop + opt = args.pop + id = [container] + args.each{|item| id << tagid(item)} + __itemconfigure(id, opt, val) + end + 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 + + id = [container] + args.each{|item| id << tagid(item)} + __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) + ret = {} + inf = list(tk_call('::blt::table', 'info', container, tagid(item))) + until inf.empty? + opt = inf.slice!(0..1) + ret[opt[1..-1]] = opt[1] + 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, win=nil, *args) + if win + tk_call('::blt::table', container, _epath(win), *args) + else + tk_call('::blt::table', container) + end + end + + def arrange(container) + tk_call('::blt::table', 'arrange', 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/ext/tk/lib/tkextlib/blt/tabnotebook.rb b/ext/tk/lib/tkextlib/blt/tabnotebook.rb new file mode 100644 index 0000000000..508fa2b82f --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/tabnotebook.rb @@ -0,0 +1,21 @@ +# +# 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 + + def get_tab(index) + Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('id', tagindex(index))) + end + alias get_id get_tab + end +end diff --git a/ext/tk/lib/tkextlib/blt/tabset.rb b/ext/tk/lib/tkextlib/blt/tabset.rb new file mode 100644 index 0000000000..063460f163 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/tabset.rb @@ -0,0 +1,386 @@ +# +# 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, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TabID_TBL.clear } + + def self.id2obj(tabset, id) + tpath = tabset.path + return id unless TabID_TBL[tpath] + TabID_TBL[tpath][id]? TabID_TBL[tpath]: id + 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 + + if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name] + TabID_TBL[parent.path][name] + else + super(parent, pos, name, keys) + end + end + + def initialize(parent, pos, name, keys) + @t = parent + @tpath = parent.path + if name + @path = @id = name + TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath] + TabID_TBL[@tpath][@id] = self + + 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, idx, 'moveto', 'after', 'end') + else + tk_call(@tpath, idx, 'moveto', 'before', pos) + end + end + tk_call(@tpath, 'tab', 'configure', @id, keys) + return + end + + else + @path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_) + TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath] + TabID_TBL[@tpath][@id] = self + TabsetTab_ID[1].succ! + end + + pos = 'end' unless pos + tk_call(@tpath, 'insert', pos, @id, keys) + 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]) + 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]) + 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(*args) + @t.tab_cget(@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[@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.delete(@path) + end + + ######################################## + + 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 itemcget + alias tab_configure itemconfigure + alias tab_configinfo itemconfiginfo + alias current_tab_configinfo current_itemconfiginfo + + 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]) + 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]) + 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[@path].delete(first.id) + end + # middle tabs of the range are unknown + if last.kind_of?(Tk::BLT::Tabset::Tab) + TabID_TBL[@path].delete(last.id) + end + self + end + + def focus(index) + tk_send('focus', tagindex(index)) + self + end + + def get_tab(index) + Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('get', tagindex(index))) + end + + def index(str) + num_or_str(tk_send('index', str)) + end + def index_name(tab) + num_or_str(tk_send('index', '-mame', tagid(tab))) + end + + def insert(pos, tab, keys={}) + Tk::BLT::Tabset::Tab.new(self, tagindex(pos), tagid(tab), keys) + 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(num_or_str(tk_send_without_enc('nearest', x, y))) + end + + def perforation_highlight(index, mode) + tk_send('perforation', 'highlight', tagindex(index), mode) + self + end + def perforation_invoke(index) + tk_send('perforation', 'invoke', tagindex(index)) + 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_names(pat=None) + simplelist(tk_send('tab', 'names', pat)).collect{|name| + Tk::BLT::Tabset::Tab.id2obj(name) + } + end + + def tab_tearoff(index, name=None) + window(tk_send('tab', 'tearoff', tagindex(index), name)) + 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/ext/tk/lib/tkextlib/blt/ted.rb b/ext/tk/lib/tkextlib/blt/ted.rb new file mode 100644 index 0000000000..39495842b4 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/ted.rb @@ -0,0 +1,62 @@ +# +# 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, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + def cget(master, option) + itemconfigure(master, slot, value) + 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/ext/tk/lib/tkextlib/blt/tile.rb b/ext/tk/lib/tkextlib/blt/tile.rb new file mode 100644 index 0000000000..5f5242f299 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/tile.rb @@ -0,0 +1,21 @@ +# +# tkextlib/blt/tile.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module Tile + 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/ext/tk/lib/tkextlib/blt/tile/button.rb b/ext/tk/lib/tkextlib/blt/tile/button.rb new file mode 100644 index 0000000000..dd715c8b98 --- /dev/null +++ b/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 < TkButton + TkCommandNames = ['::blt::tile::button'.freeze].freeze + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb b/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb new file mode 100644 index 0000000000..ebe79179a5 --- /dev/null +++ b/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 < TkCheckbutton + TkCommandNames = ['::blt::tile::checkbutton'.freeze].freeze + end + CheckButton = Checkbutton + end +end diff --git a/ext/tk/lib/tkextlib/blt/tile/frame.rb b/ext/tk/lib/tkextlib/blt/tile/frame.rb new file mode 100644 index 0000000000..10469fd35f --- /dev/null +++ b/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 < TkFrame + TkCommandNames = ['::blt::tile::frame'.freeze].freeze + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/tile/label.rb b/ext/tk/lib/tkextlib/blt/tile/label.rb new file mode 100644 index 0000000000..ec67babd58 --- /dev/null +++ b/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 < TkLabel + TkCommandNames = ['::blt::tile::label'.freeze].freeze + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb b/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb new file mode 100644 index 0000000000..7573aa08d6 --- /dev/null +++ b/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 < TkRadiobutton + TkCommandNames = ['::blt::tile::radiobutton'.freeze].freeze + end + RadioButton = Radiobutton + end +end diff --git a/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb b/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb new file mode 100644 index 0000000000..ba3bf316f0 --- /dev/null +++ b/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 < TkScrollbar + TkCommandNames = ['::blt::tile::scrollbar'.freeze].freeze + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/tile/toplevel.rb b/ext/tk/lib/tkextlib/blt/tile/toplevel.rb new file mode 100644 index 0000000000..6cc2c91415 --- /dev/null +++ b/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 < TkToplevel + TkCommandNames = ['::blt::tile::toplevel'.freeze].freeze + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/tree.rb b/ext/tk/lib/tkextlib/blt/tree.rb new file mode 100644 index 0000000000..a5975898e9 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/tree.rb @@ -0,0 +1,881 @@ +# +# 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.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeNodeID_TBL[tpath] + if TreeNodeID_TBL[tpath][id] + TreeNodeID_TBL[tpath][id] + else + begin + self.new(tree, nil, 'node'=>Integer(id)) + rescue + id + end + end + end + + def self.new(tree, parent, keys={}) + keys = _symbolkey2str(keys) + tpath = tree.path + + 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 + + super(tree, parent, keys) + end + + def initialize(tree, parent, keys={}) + @parent = @tree = tree + @tpath = @parent.path + + parent = tk_call(@tpath, 'root') unless parent + + 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 + @path = @id = tk_call(@tpath, 'insert', parent, keys) + end + + TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath] + TreeNodeID_TBL[@tpath][@id] = self + 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.clear } + TreeTag_ID = ['blt_tree_tag'.freeze, '00000'.taint].freeze + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeTagID_TBL[tpath] + if TreeTagID_TBL[tpath][id] + TreeTagID_TBL[tpath][id] + else + self.new(tree, 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 + @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_) + TreeTagID_TBL[@id] = self + TreeTag_ID[1].succ! + end + TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath] + TreeTagID_TBL[@tpath][@id] = self + 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[@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.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless NotifyID_TBL[tpath] + if NotifyID_TBL[tpath][id] + NotifyID_TBL[tpath][id] + else + begin + self.new([tree, id]) + rescue + id + end + end + end + + def self.new(tree, *args, &b) + if tree.kind_of?(Array) + # not create + if obj = NotifyID_TBL[tree[0].path][tree[1]] + return obj + else + return super(false, tree[0], tree[1]) + end + end + + super(true, tree, *args, &b) + end + + def initialize(create, tree, *args, &b) + @parent = @tree = tree + @tpath = @parent.path + + unless create + @path = @id = args[0] + return + end + + # 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 delete() + tk_call(@tpath, 'notify', 'delete', @id) + 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.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TraceID_TBL[tpath] + if TraceID_TBL[tpath][id] + TraceID_TBL[tpath][id] + else + begin + self.new([tree, id]) + rescue + id + end + end + end + + def self.new(tree, *args, &b) + if tree.kind_of?(Array) + # not create + if obj = TraceID_TBL[tree[0].path][tree[1]] + return obj + else + return super(false, tree[0], tree[1]) + end + end + + super(true, tree, *args, &b) + end + + def initialize(create, tree, node, key, opts, cmd=nil, &b) + @parent = @tree = tree + @tpath = @parent.path + + unless create + @path = @id = node # == traceID + return + end + + 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 delete() + tk_call(@tpath, 'trace', 'delete', @id) + 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, '00000'.taint].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[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) + return TreeID_TBL[name] if name && TreeID_TBL[name] + super(name) + end + + def initialzie(name = nil) + if name + @path = @id = name + else + @path = @id = Tree_ID.join(TkCore::INTERP._ip_id_) + TreeID_TBL[@id] = self + Tree_ID[1].succ! + end + TreeID_TBL[@id] = self + tk_call('::blt::tree', 'create', @id) + end + + def __destroy_hook__ + Tk::BLT::Tree::Node::TreeNodeID_TBL.delete(@path) + Tk::BLT::Tree::Tag::TreeTagID_TBL.delete(@path) + Tk::BLT::Tree::Notify::NotifyID_TBL.delete(@path) + Tk::BLT::Tree::Trace::TraceID_TBL.delete(@path) + 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', + node1, node2)) + end + + def apply(node, keys={}) + tk_call('::blt::tree', 'apply', 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', node)).collect{|n| + Tk::BLT::Tree::Node.id2obj(self, n) + } + end + + def copy(src, parent, keys={}) + id = tk_call('::blt::tree', 'copy', src, 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', src, dest_tree, 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', node)) + end + + def delete(*nodes) + tk_call('::blt::tree', 'delete', *nodes) + 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', node)) + end + + def dump(node) + simplelist(tk_call('::blt::tree', 'dump', node)).collect{|n| + simplelist(n) + } + end + + def dump_to_file(node, file) + tk_call('::blt::tree', 'dumpfile', node, file) + self + end + + def exist?(node, key=None) + bool(tk_call('::blt::tree', 'exists', node, key)) + end + + def find(node, keys={}) + simplelist(tk_call('::blt::tree', 'find', 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', node, label) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def first_child(node) + ret = tk_call('::blt::tree', 'firstchild', node) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def get(node) + Hash[*simplelist(tk_call('::blt::tree', 'get', node))] + end + def get_value(node, key, default_val=None) + tk_call('::blt::tree', 'get', node, key, default_val) + end + + def index(node) + Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'index', node)) + end + + def insert(parent, keys={}) + id = tk_call('::blt::tree', 'insert', parent, keys) + Tk::BLT::Tree::Node.new(self, nil, 'node'=>id) + end + + def ancestor?(node1, node2) + bool(tk_call('::blt::tree', 'is', 'ancestor', node1, node2)) + end + def before?(node1, node2) + bool(tk_call('::blt::tree', 'is', 'before', node1, node2)) + end + def leaf?(node) + bool(tk_call('::blt::tree', 'is', 'leaf', node)) + end + def link?(node) + bool(tk_call('::blt::tree', 'is', 'link', node)) + end + def root?(node) + bool(tk_call('::blt::tree', 'is', 'root', node)) + end + + def keys(node, *nodes) + if nodes.empty? + simplelist(tk_call('blt::tree', 'keys', node)) + else + simplelist(tk_call('blt::tree', 'keys', node, *nodes)).collect{|lst| + simplelist(lst) + } + end + end + + def label(node, text=nil) + if text + tk_call('::blt::tree', 'label', node, text) + text + else + tk_call('::blt::tree', 'label', node) + end + end + + def last_child(node) + ret = tk_call('::blt::tree', 'lastchild', node) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def link(parent, node, keys={}) + ret = tk_call('::blt::tree', 'link', parent, 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', node, dest, keys) + self + end + + def next(node) + ret = tk_call('::blt::tree', 'next', node) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def next_sibling(node) + ret = tk_call('::blt::tree', 'nextsibling', 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[@path].delete(id.to_s) + end + self + end + + def notify_info(id) + lst = simplelist(tk_call(@path, 'notify', 'info', 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', node) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def fullpath(node) + tk_call('::blt::tree', 'path', node) + end + + def position(node) + number(tk_call('::blt::tree', 'position', node)) + end + + def previous(node) + ret = tk_call('::blt::tree', 'previous', node) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def prev_sibling(node) + ret = tk_call('::blt::tree', 'prevsibling', node) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def restore(node, str, keys={}) + tk_call('::blt::tree', 'restore', 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', node, str, '-overwrite', keys) + self + end + + def restore_from_file(node, file, keys={}) + tk_call('::blt::tree', 'restorefile', 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', node, file, '-overwrite', keys) + self + end + + def root(node=None) + Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'root', 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', node, *args) + self + end + + def size(node) + number(tk_call('::blt::tree', 'size', node)) + end + + def sort(node, keys={}) + tk_call('::blt::tree', 'sort', node, __conv_keyonly_opts(keys)) + self + end + + def tag_add(tag, *nodes) + tk_call(@path, 'tag', 'add', tag, *nodes) + self + end + + def tag_delete(tag, *nodes) + tk_call(@path, 'tag', 'delete', tag, *nodes) + 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[@path].delete(tag) + self + end + + def tag_get(node, *patterns) + simplelist(tk_call(@tpath, 'tag', 'get', node, *patterns)).collect{|str| + Tk::BLT::Tree::Tag.id2obj(self, str) + } + end + + def tag_names(node = None) + simplelist(tk_call(@tpath, 'tag', 'names', node)).collect{|str| + Tk::BLT::Tree::Tag.id2obj(self, str) + } + end + + def tag_nodes(tag) + simplelist(tk_call(@tpath, 'tag', 'nodes',tag)).collect{|node| + Tk::BLT::Tree::Node.id2obj(self, node) + } + end + + def tag_set(node, *tags) + tk_call(@path, 'tag', 'set', node, *tags) + self + end + + def tag_unset(node, *tags) + tk_call(@path, 'tag', 'unset', node, *tags) + self + end + + def trace_create(*args, &b) + Tk::BLT::Tree::Trace.new(self, *args, &b) + end + + def trace_delete(*args) + 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 + + def trace_info(*args) + lst = simplelist(tk_call(@path, 'trace', 'info', 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', node, key) + end + + def unset(node, *keys) + tk_call('::blt::tree', 'unset', node, *keys) + self + end + + def values(node, key=None) + simplelist(tk_call('::blt::tree', 'values', node, key)) + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/treeview.rb b/ext/tk/lib/tkextlib/blt/treeview.rb new file mode 100644 index 0000000000..8001472484 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/treeview.rb @@ -0,0 +1,1116 @@ +# +# 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_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(name, option) + itemcget(['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(option) + itemcget('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(option) + ret = itemcget('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(option) + itemcget('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(option) + itemcget('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, :itemconfigure + private :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', 'exportselection', 'flat', 'hideroot', + 'newtags', 'showtitles', 'sortselection'] + end + private :__boolval_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 + ] + + _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.delete(@path) + 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 paramters + 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]) + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'bind', tag], seq, cmd, *args) + self + end + def tag_bind_append(tag, seq, *args) + if TkComm._callback_entry?(args[0]) + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'bind', tag], seq, cmd, *args) + self + end + def tag_bind_remove(tag, seq) + _bind_remove([@path, 'bind', tag], seq) + self + end + def tag_bindinfo(tag, seq=nil) + _bindinfo([@path, 'bind', 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]) + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'button', 'bind', tag], seq, cmd, *args) + self + end + def button_bind_append(tag, seq, *args) + if TkComm._callback_entry?(args[0]) + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'button', 'bind', tag], seq, cmd, *args) + self + end + def button_bind_remove(tag, seq) + _bind_remove([@path, 'button', 'bind', tag], seq) + self + end + def button_bindinfo(tag, seq=nil) + _bindinfo([@path, 'button', 'bind', 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 + ] + + _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(' ')) + 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) << '--' << first << 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) + 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'] = 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) + 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, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TreeNodeID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeNodeID_TBL[tpath] + if TreeNodeID_TBL[tpath][id] + TreeNodeID_TBL[tpath][id] + else + begin + self.new(tree, nil, nil, 'node'=>Integer(id)) + rescue + id + end + 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 + + 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) + end + + def initialize(tree, pos, parent, keys) + @parent = @tree = tree + @tpath = @parent.path + + if (id = keys['node']) + @path = @id = id + tk_call(@tpath, 'move', @id, pos, parent) if parent + else + 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, 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 + + TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath] + TreeNodeID_TBL[@tpath][@id] = self + 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, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TreeTagID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeTagID_TBL[tpath] + if TreeTagID_TBL[tpath][id] + TreeTagID_TBL[tpath][id] + else + begin + self.new(tree, nil, nil, 'name'=>Integer(id)) + rescue + id + end + end + end + + def self.new_by_name(tree, name, *ids) + if (obj = TreeTagID_TBL[tree.path][name]) + return obj + end + new([tree, name], ids) + end + + def self.new(tree, *ids) + if tree.kind_of?(Array) + super(tree[0], tree[1], ids) + else + super(tree, nil, ids) + end + end + + def initialize(tree, name, ids) + @parent = @tree = tree + @tpath = @parent.path + + if name + @path = @id = name + else + @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_).freeze + TreeTag_ID[1].succ! + end + + TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath] + TreeTagID_TBL[@tpath][@id] = self + + tk_call(@tpath, 'tag', 'add', @id, *ids) unless ids.empty? + end + + def id + @id + end + + def add(*ids) + tk_call(@tpath, 'tag', 'add', @id, *ids) + self + end + + def remove(*ids) + tk_call(@tpath, 'tag', 'delete', @id, *ids) + 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/ext/tk/lib/tkextlib/blt/unix_dnd.rb b/ext/tk/lib/tkextlib/blt/unix_dnd.rb new file mode 100644 index 0000000000..3130c1e56f --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/unix_dnd.rb @@ -0,0 +1,129 @@ +# +# 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, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + def cget(win, option) + itemconfigure(['cget', win], slot, value) + 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 tokwn_cget(win, option) + itemconfigure(['token', 'cget', win], slot, value) + 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/ext/tk/lib/tkextlib/blt/vector.rb b/ext/tk/lib/tkextlib/blt/vector.rb new file mode 100644 index 0000000000..540b6b9102 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/vector.rb @@ -0,0 +1,243 @@ +# +# 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) + simplelist(tk_call('::blt::vector', 'names', pat)).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 = INTERP._invoke('::blt::vector', 'create', + "#auto(#{size})", *hash_kv(keys)) + else + @id = INTERP._invoke('::blt::vector', 'create', + "#auto", *hash_kv(keys)) + end + + 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 + INTERP._invoke_without_enc('global', @id) + end + + def destroy + tk_call('::blt::vector', 'destroy', @id) + end + + def inspect + '#' + 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) + return TkVar_ID_TBL[name] if TkVar_ID_TBL[name] + super(name, size=nil, keys={}) + end + + def initialize(vec_name) + @id = vec_name + 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 + INTERP._invoke_without_enc('global', @id) + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/watch.rb b/ext/tk/lib/tkextlib/blt/watch.rb new file mode 100644 index 0000000000..ae5e50f126 --- /dev/null +++ b/ext/tk/lib/tkextlib/blt/watch.rb @@ -0,0 +1,142 @@ +# +# 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, '00000'.taint].freeze + + def self.names(state = None) + tk_split_list(tk_call('::blt::watch', 'names', state)).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 + @id = BLT_WATCH_ID.join(TkCore::INTERP._ip_id_) + BLT_WATCH_ID[1].succ! + end + + @path = @id + + 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(key) + key = key.to_s + begin + info.assoc(key)[1] + rescue + fail ArgumentError, "unknown option '#{key}'" + end + end + end +end diff --git a/ext/tk/lib/tkextlib/blt/win_printer.rb b/ext/tk/lib/tkextlib/blt/win_printer.rb new file mode 100644 index 0000000000..7ac6a0dcfc --- /dev/null +++ b/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/ext/tk/lib/tkextlib/blt/winop.rb b/ext/tk/lib/tkextlib/blt/winop.rb new file mode 100644 index 0000000000..38656b1daa --- /dev/null +++ b/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_subample(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 -- cgit v1.2.3