diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb |
Fresh start
Diffstat (limited to 'jni/ruby/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb')
-rw-r--r-- | jni/ruby/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb | 2522 |
1 files changed, 2522 insertions, 0 deletions
diff --git a/jni/ruby/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb b/jni/ruby/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb new file mode 100644 index 0000000..1879a53 --- /dev/null +++ b/jni/ruby/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb @@ -0,0 +1,2522 @@ +# +# tkextlib/treectrl/tktreectrl.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/treectrl/setup.rb' + +# TkPackage.require('treectrl', '1.0') +# TkPackage.require('treectrl', '1.1') +TkPackage.require('treectrl') + +module Tk + class TreeCtrl < TkWindow + BindTag_FileList = TkBindTag.new_by_name('TreeCtrlFileList') + + PACKAGE_NAME = 'treectrl'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('treectrl') + rescue + '' + end + end + + HasColumnCreateCommand = + (TkPackage.vcompare(self.package_version, '1.1') >= 0) + + # dummy :: + # pkgIndex.tcl of TreeCtrl-1.0 doesn't support auto_load for + # 'loupe' command (probably it is bug, I think). + # So, calling a 'treectrl' command for loading the dll with + # the auto_load facility. + begin + tk_call('treectrl') + rescue + end + def self.loupe(img, x, y, w, h, zoom) + # NOTE: platform == 'unix' only + + # img => TkPhotoImage + # x, y => screen coords + # w, h => magnifier width and height + # zoom => zooming rate + Tk.tk_call_without_enc('loupe', img, x, y, w, h, zoom) + end + + def self.text_layout(font, text, keys={}) + TkComm.list(Tk.tk_call_without_enc('textlayout', font, text, keys)) + end + + def self.image_tint(img, color, alpha) + Tk.tk_call_without_enc('imagetint', img, color, alpha) + end + + class NotifyEvent < TkUtil::CallbackSubst + end + + module ConfigMethod + end + end + TreeCtrl_Widget = TreeCtrl +end + +############################################## + +class Tk::TreeCtrl::NotifyEvent + # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>] + KEY_TBL = [ + [ ?c, ?n, :item_num ], + [ ?d, ?s, :detail ], + [ ?D, ?l, :items ], + [ ?e, ?e, :event ], + [ ?I, ?n, :id ], + [ ?l, ?n, :lower_bound ], + [ ?p, ?n, :active_id ], + [ ?P, ?e, :pattern ], + [ ?S, ?l, :sel_items ], + [ ?T, ?w, :widget ], + [ ?u, ?n, :upper_bound ], + [ ?W, ?o, :object ], + [ ??, ?x, :parm_info ], + nil + ] + + # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>] + PROC_TBL = [ + [ ?n, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?l, TkComm.method(:list) ], + [ ?w, TkComm.method(:window) ], + + [ ?e, proc{|val| + case val + when /^<<[^<>]+>>$/ + TkVirtualEvent.getobj(val[1..-2]) + when /^<[^<>]+>$/ + val[1..-2] + else + val + end + } + ], + + [ ?o, proc{|val| TkComm.tk_tcl2ruby(val)} ], + + [ ?x, proc{|val| + begin + inf = {} + Hash[*(TkComm.list(val))].each{|k, v| + if keyinfo = KEY_TBL.assoc(k[0]) + if cmd = PROC_TBL.assoc(keyinfo[1]) + begin + new_v = cmd.call(v) + v = new_v + rescue + end + end + end + inf[k] = v + } + inf + rescue + val + end + } ], + + nil + ] + +=begin + # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) ) + KEY_TBL.map!{|inf| + if inf.kind_of?(Array) + inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String) + inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String) + end + inf + } + + PROC_TBL.map!{|inf| + if inf.kind_of?(Array) + inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String) + end + inf + } +=end + + # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys + # + # _get_subst_key() and _get_all_subst_keys() generates key-string + # which describe how to convert callback arguments to ruby objects. + # When binding parameters are given, use _get_subst_key(). + # But when no parameters are given, use _get_all_subst_keys() to + # create a Event class object as a callback parameter. + # + # scan_args() is used when doing callback. It convert arguments + # ( which are Tcl strings ) to ruby objects based on the key string + # that is generated by _get_subst_key() or _get_all_subst_keys(). + # + _setup_subst_table(KEY_TBL, PROC_TBL); +end + +############################################## + +module Tk::TreeCtrl::ConfigMethod + include TkItemConfigMethod + + def treectrl_tagid(key, obj) + if key.kind_of?(Array) + key = key.join(' ') + else + key = key.to_s + end + + if (obj.kind_of?(Tk::TreeCtrl::Column) || + obj.kind_of?(Tk::TreeCtrl::Element) || + obj.kind_of?(Tk::TreeCtrl::Item) || + obj.kind_of?(Tk::TreeCtrl::Style)) + obj = obj.id + end + + case key + when 'column' + obj + + when 'debug' + None + + when 'dragimage' + None + + when 'element' + obj + + when 'item element' + obj + + when 'marquee' + None + + when 'notify' + obj + + when 'style' + obj + + else + obj + end + end + + def tagid(mixed_id) + if mixed_id == 'debug' + ['debug', None] + elsif mixed_id == 'dragimage' + ['dragimage', None] + elsif mixed_id == 'marquee' + ['marquee', None] + elsif mixed_id.kind_of?(Array) + [mixed_id[0], treectrl_tagid(*mixed_id)] + else + tagid(mixed_id.split(':')) + end + end + + def __item_cget_cmd(mixed_id) + if mixed_id[0] == 'column' && mixed_id[1] == 'drag' + return [self.path, 'column', 'dragcget'] + end + + if mixed_id[1].kind_of?(Array) + id = mixed_id[1] + else + id = [mixed_id[1]] + end + + if mixed_id[0].kind_of?(Array) + ([self.path].concat(mixed_id[0]) << 'cget').concat(id) + else + [self.path, mixed_id[0], 'cget'].concat(id) + end + end + private :__item_cget_cmd + + def __item_config_cmd(mixed_id) + if mixed_id[0] == 'column' && mixed_id[1] == 'drag' + return [self.path, 'column', 'dragconfigure'] + end + + if mixed_id[1].kind_of?(Array) + id = mixed_id[1] + else + id = [mixed_id[1]] + end + + if mixed_id[0].kind_of?(Array) + ([self.path].concat(mixed_id[0]) << 'configure').concat(id) + else + [self.path, mixed_id[0], 'configure'].concat(id) + end + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + key = id[0] + if key.kind_of?(Array) + key = key.join(' ') + end + + tag = id[1] + if tag.kind_of?(Array) + tag = tag.join(' ') + end + + id = [key, tag].join(':') + end + [self.path, id].join(';') + end + private :__item_pathname + + def __item_configinfo_struct(id) + if id.kind_of?(Array) && id[0].to_s == 'notify' + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>nil, :current_value=>1} + else + {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, + :default_value=>3, :current_value=>4} + end + end + private :__item_configinfo_struct + + + def __item_font_optkeys(id) + if id.kind_of?(Array) && (id[0] == 'element' || + (id[0].kind_of?(Array) && id[0][1] == 'element')) + [] + else + ['font'] + end + end + private :__item_font_optkeys + + def __item_numstrval_optkeys(id) + if id == 'debug' + ['displaydelay'] + else + super(id) + end + end + private :__item_numstrval_optkeys + + def __item_boolval_optkeys(id) + if id == 'debug' + ['data', 'display', 'enable', 'span', 'textlayout'] + elsif id == 'dragimage' + ['visible'] + elsif id == 'marquee' + ['visible'] + elsif id.kind_of?(Array) + case id[0] + when 'item' + ['visible', 'wrap', 'open', 'returnid', 'visible'] + when 'column' + if id[1] == 'drag' + ['enable'] + else + ['button', 'expand', 'resize', 'squeeze', 'sunken', + 'visible', 'widthhack'] + end + when 'element' + ['draw', 'filled', 'showfocus', 'clip', 'destroy'] + when 'notify' + ['active'] + when 'style' + ['detach', 'indent', 'visible'] + else + if id[0].kind_of?(Array) && id[0][1] == 'element' + ['filled', 'showfocus'] + else + super(id) + end + end + else + super(id) + end + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + if id == 'debug' + ['erasecolor'] + elsif id.kind_of?(Array) + case id[0] + when 'column' + if id[1] == 'drag' + ['indicatorcolor'] + else + super(id) << 'textcolor' + end + when 'element' + super(id) << 'fill' << 'outline' << 'format' + else + super(id) + end + else + super(id) + end + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + if id.kind_of?(Array) + case id[0] + when 'column' + ['itembackground'] + when 'element' + ['relief'] + when 'style' + ['union'] + else + if id[0].kind_of?(Array) && id[0][1] == 'element' + ['relief'] + else + [] + end + end + else + [] + end + end + private :__item_listval_optkeys + + def __item_val2ruby_optkeys(id) + if id.kind_of?(Array) + case id[0] + when 'item' + { 'button' => proc{|id,val| (val == 'auto')? val: TkComm.bool(val)} } + else + [] + end + else + [] + end + end + private :__item_val2ruby_optkeys + + def __item_keyonly_optkeys(id) # { def_key=>(undef_key|nil), ... } + { + 'notreally'=>nil, + 'increasing'=>'decreasing', + 'decreasing'=>'increasing', + 'ascii'=>nil, + 'dictionary'=>nil, + 'integer'=>nil, + 'real'=>nil + } + end + private :__item_keyonly_optkeys + + def column_cget_tkstring(tagOrId, option) + itemcget_tkstring(['column', tagOrId], option) + end + def column_cget(tagOrId, option) + itemcget(['column', tagOrId], option) + end + def column_cget_strict(tagOrId, option) + itemcget_strict(['column', tagOrId], option) + end + def column_configure(tagOrId, slot, value=None) + itemconfigure(['column', tagOrId], slot, value) + end + def column_configinfo(tagOrId, slot=nil) + itemconfiginfo(['column', tagOrId], slot) + end + def current_column_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['column', tagOrId], slot) + end + + def column_dragcget_tkstring(option) + itemcget_tkstring(['column', 'drag'], option) + end + def column_dragcget(option) + itemcget(['column', 'drag'], option) + end + def column_dragcget_strict(option) + itemcget_strict(['column', 'drag'], option) + end + def column_dragconfigure(slot, value=None) + itemconfigure(['column', 'drag'], slot, value) + end + def column_dragconfiginfo(slot=nil) + itemconfiginfo(['column', 'drag'], slot) + end + def current_column_dragconfiginfo(slot=nil) + current_itemconfiginfo(['column', 'drag'], slot) + end + + def debug_cget_tkstring(option) + itemcget_tkstring('debug', option) + end + def debug_cget(option) + itemcget('debug', option) + end + def debug_cget_strict(option) + itemcget_strict('debug', option) + end + def debug_configure(slot, value=None) + itemconfigure('debug', slot, value) + end + def debug_configinfo(slot=nil) + itemconfiginfo('debug', slot) + end + def current_debug_configinfo(slot=nil) + current_itemconfiginfo('debug', slot) + end + + def dragimage_cget_tkstring(option) + itemcget_tkstring('dragimage', option) + end + def dragimage_cget(option) + itemcget('dragimage', option) + end + def dragimage_cget_strict(option) + itemcget_strict('dragimage', option) + end + def dragimage_configure(slot, value=None) + itemconfigure('dragimage', slot, value) + end + def dragimage_configinfo(slot=nil) + itemconfiginfo('dragimage', slot) + end + def current_dragimage_configinfo(slot=nil) + current_itemconfiginfo('dragimage', slot) + end + + def element_cget_tkstring(tagOrId, option) + itemcget_tkstring(['element', tagOrId], option) + end + def element_cget(tagOrId, option) + itemcget(['element', tagOrId], option) + end + def element_cget_strict(tagOrId, option) + itemcget_strict(['element', tagOrId], option) + end + def element_configure(tagOrId, slot, value=None) + itemconfigure(['element', tagOrId], slot, value) + end + def element_configinfo(tagOrId, slot=nil) + itemconfiginfo(['element', tagOrId], slot) + end + def current_element_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['element', tagOrId], slot) + end + + def item_cget_tkstring(tagOrId, option) + itemcget_tkstring(['item', tagOrId], option) + end + def item_cget(tagOrId, option) + itemcget(['item', tagOrId], option) + end + def item_cget_strict(tagOrId, option) + itemcget_strict(['item', tagOrId], option) + end + def item_configure(tagOrId, slot, value=None) + itemconfigure(['item', tagOrId], slot, value) + end + def item_configinfo(tagOrId, slot=nil) + itemconfiginfo(['item', tagOrId], slot) + end + def current_item_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['item', tagOrId], slot) + end + + def item_element_cget_tkstring(item, column, elem, option) + itemcget_tkstring([['item', 'element'], [item, column, elem]], option) + end + def item_element_cget(item, column, elem, option) + itemcget([['item', 'element'], [item, column, elem]], option) + end + def item_element_cget_strict(item, column, elem, option) + itemcget_strict([['item', 'element'], [item, column, elem]], option) + end + def item_element_configure(item, column, elem, slot, value=None) + itemconfigure([['item', 'element'], [item, column, elem]], slot, value) + end + def item_element_configinfo(item, column, elem, slot=nil) + itemconfiginfo([['item', 'element'], [item, column, elem]], slot) + end + def current_item_element_configinfo(item, column, elem, slot=nil) + current_itemconfiginfo([['item', 'element'], [item, column, elem]], slot) + end + + def marquee_cget_tkstring(option) + itemcget_tkstring('marquee', option) + end + def marquee_cget(option) + itemcget('marquee', option) + end + def marquee_cget_strict(option) + itemcget_strict('marquee', option) + end + def marquee_configure(slot, value=None) + itemconfigure('marquee', slot, value) + end + def marquee_configinfo(slot=nil) + itemconfiginfo('marquee', slot) + end + def current_marquee_configinfo(slot=nil) + current_itemconfiginfo('marquee', slot) + end + + def notify_cget_tkstring(win, pattern, option) + pattern = "<#{pattern}>" + # "notify" doesn't have cget subcommand. + tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(['notify', [win, pattern]])) << "-#{option}")), false, true)[-1] + end + def notify_cget(win, pattern, option) + pattern = "<#{pattern}>" + # "notify" doesn't have cget subcommand. + current_itemconfiginfo(['notify', [win, pattern]])[option.to_s] + end + def notify_cget_strict(win, pattern, option) + pattern = "<#{pattern}>" + # "notify" doesn't have cget subcommand. + info = current_itemconfiginfo(['notify', [win, pattern]]) + option = option.to_s + unless info.has_key?(option) + fail RuntimeError, "unknown option \"#{option}\"" + else + info[option] + end + end + def notify_configure(win, pattern, slot, value=None) + pattern = "<#{pattern}>" + itemconfigure(['notify', [win, pattern]], slot, value) + end + def notify_configinfo(win, pattern, slot=nil) + pattern = "<#{pattern}>" + itemconfiginfo(['notify', [win, pattern]], slot) + end + def current_notify_configinfo(tagOrId, slot=nil) + pattern = "<#{pattern}>" + current_itemconfiginfo(['notify', [win, pattern]], slot) + end + + def style_cget_tkstring(tagOrId, option) + itemcget_tkstring(['style', tagOrId], option) + end + def style_cget(tagOrId, option) + itemcget(['style', tagOrId], option) + end + def style_cget_strict(tagOrId, option) + itemcget_strict(['style', tagOrId], option) + end + def style_configure(tagOrId, slot, value=None) + itemconfigure(['style', tagOrId], slot, value) + end + def style_configinfo(tagOrId, slot=nil) + itemconfiginfo(['style', tagOrId], slot) + end + def current_style_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['style', tagOrId], slot) + end + + private :itemcget_tkstring, :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo +end + +############################################## + +class Tk::TreeCtrl + include Tk::TreeCtrl::ConfigMethod + include Scrollable + + TkCommandNames = ['treectrl'.freeze].freeze + WidgetClassName = 'TreeCtrl'.freeze + WidgetClassNames[WidgetClassName] ||= self + + ######################### + + def __destroy_hook__ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.delete(@path) + } + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.delete(@path) + } + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.delete(@path) + } + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.delete(@path) + } + end + + ######################### + + def __strval_optkeys + super() + [ + 'buttoncolor', 'columnprefix', 'itemprefix', 'linecolor' + ] + end + private :__strval_optkeys + + def __boolval_optkeys + [ + 'itemwidthequal', 'usetheme', + 'showbuttons', 'showheader', 'showlines', 'showroot', + 'showrootbutton', 'showrootlines', 'showrootchildbuttons' + ] + end + private :__boolval_optkeys + + def __listval_optkeys + [ 'defaultstyle' ] + end + private :__listval_optkeys + + ######################### + + def install_bind(cmd, *args) + install_bind_for_event_class(Tk::TreeCtrl::NotifyEvent, cmd, *args) + end + + ######################### + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + ######################### + + def activate(desc) + tk_send('activate', desc) + self + end + + def canvasx(x) + number(tk_send('canvasx', x)) + end + + def canvasy(y) + number(tk_send('canvasy', y)) + end + + def collapse(*dsc) + tk_send_without_enc('collapse', *(dsc.map!{|d| _get_eval_string(d, true)})) + self + end + + def collapse_recurse(*dsc) + tk_send_without_enc('collapse', '-recurse', + *(dsc.map!{|d| _get_eval_string(d, true)})) + self + end + + def column_bbox(idx) + list(tk_send('column', 'bbox', idx)) + end + + def column_compare(column1, op, column2) + bool(tk_send('column', 'compare', column1, op, column2)) + end + + def column_count + num_or_str(tk_send('column', 'count')) + end + + def column_create(keys=nil) + if keys && keys.kind_of?(Hash) + num_or_str(tk_send('column', 'create', *hash_kv(keys))) + else + num_or_str(tk_send('column', 'create')) + end + end + + def column_delete(idx) + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[self.path] + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[self.path].delete(idx) + end + } + tk_send('column', 'delete', idx) + self + end + + def column_index(idx) + num_or_str(tk_send('column', 'index', idx)) + end + + def column_id(idx) + tk_send('column', 'id', idx) + end + + def column_list(visible=false) + if visible + simplelist(tk_send('column', 'list', '-visible')) + else + simplelist(tk_send('column', 'list')) + end + end + def column_visible_list + column_list(true) + end + + def column_move(idx, before) + tk_send('column', 'move', idx, before) + self + end + + def column_needed_width(idx) + num_or_str(tk_send('column', 'neededwidth', idx)) + end + alias column_neededwidth column_needed_width + + def column_order(column, visible=false) + if visible + num_or_str(tk_send('column', 'order', column, '-visible')) + else + num_or_str(tk_send('column', 'order', column)) + end + end + def column_visible_order(column) + column_order(column, true) + end + + def column_width(idx) + num_or_str(tk_send('column', 'width', idx)) + end + + def compare(item1, op, item2) + bool(tk_send('compare', item1, op, item2)) + end + + def contentbox() + list(tk_send('contentbox')) + end + + def depth(item=None) + num_or_str(tk_send_without_enc('depth', _get_eval_string(item, true))) + end + + def dragimage_add(item, *args) + tk_send('dragimage', 'add', item, *args) + self + end + + def dragimage_clear() + tk_send('dragimage', 'clear') + self + end + + def dragimage_offset(*args) # x, y + if args.empty? + list(tk_send('dragimage', 'offset')) + else + tk_send('dragimage', 'offset', *args) + self + end + end + + def dragimage_visible(*args) # mode + if args..empty? + bool(tk_send('dragimage', 'visible')) + else + tk_send('dragimage', 'visible', *args) + self + end + end + def dragimage_visible? + dragimage_visible() + end + + def debug_dinfo + tk_send('debug', 'dinfo') + self + end + + def debug_scroll + tk_send('debug', 'scroll') + end + + def element_create(elem, type, keys=nil) + if keys && keys.kind_of?(Hash) + tk_send('element', 'create', elem, type, *hash_kv(keys)) + else + tk_send('element', 'create', elem, type) + end + end + + def element_delete(*elems) + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[self.path] + elems.each{|elem| + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[self.path].delete(elem) + } + end + } + tk_send('element', 'delete', *elems) + self + end + + def element_names() + list(tk_send('element', 'names')).collect!{|elem| + Tk::TreeCtrl::Element.id2obj(self, elem) + } + end + + def _conv_element_perstate_val(opt, val) + case opt + when 'background', 'foreground', 'fill', 'outline', 'format' + val + when 'draw', 'filled', 'showfocus', 'destroy' + bool(val) + else + tk_tcl2ruby(val) + end + end + private :_conv_element_perstate_val + + def element_perstate(elem, opt, st_list) + tk_send('element', 'perstate', elem, "-{opt}", st_list) + end + + def element_type(elem) + tk_send('element', 'type', elem) + end + + def element_class(elem) + Tk::TreeCtrl::Element.type2class(element_type(elem)) + end + + def expand(*dsc) + tk_send('expand', *dsc) + self + end + + def expand_recurse(*dsc) + tk_send('expand', '-recurse', *dsc) + self + end + + def identify(x, y) + lst = list(tk_send('identify', x, y)) + + if lst[0] == 'item' + lst[1] = Tk::TreeCtrl::Item.id2obj(self, lst[1]) + size = lst.size + i = 2 + while i < size + case lst[i] + when 'line' + i += 1 + lst[i] = Tk::TreeCtrl::Item.id2obj(self, lst[i]) + i += 1 + + when 'button' + i += 1 + + when 'column' + i += 2 + + when 'elem' + i += 1 + lst[i] = Tk::TreeCtrl::Element.id2obj(self, lst[i]) + i += 1 + + else + i += 1 + end + end + end + + lst + end + + def index(idx) + num_or_str(tk_send('index', idx)) + end + + def item_ancestors(item) + list(tk_send('item', 'ancestors', item)).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def item_bbox(item, *args) + list(tk_send('item', 'bbox', item, *args)) + end + + def item_children(item) + list(tk_send('item', 'children', item)).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def item_collapse(item) + tk_send_without_enc('item', 'collapse', _get_eval_string(item, true)) + self + end + + def item_collapse_recurse(item) + tk_send_without_enc('item', 'collapse', + _get_eval_string(item, true), '-recurse') + self + end + + def item_compare(item1, op, item2) + bool(tk_send('item', 'compare', item1, op, item2)) + end + + def item_complex(item, *args) + tk_send_without_enc('item', 'complex', + _get_eval_string(item, true), + *(args.map!{|arg| _get_eval_string(arg, true)})) + self + end + + def item_count + num_or_str(tk_send('item', 'count')) + end + + def item_create(keys={}) + num_or_str(tk_send_without_enc('item', 'create', *hash_kv(keys, true))) + end + + def _erase_children(item) + item_children(item).each{|i| _erase_children(i)} + # table is already locked + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path].delete(item) + end + private :_erase_children + + def item_delete(first, last=None) + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path] + if first == 'all' || first == :all || last == 'all' || last == :all + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path].clear + elsif last == None + _erase_children(first) + else + self.range(first, last).each{|id| + _erase_children(id) + } + end + end + } + tk_send('item', 'delete', first, last) + self + end + + def item_dump(item) + list(tk_send('item', 'dump', item)) + end + + def item_dump_hash(item) + Hash[*list(tk_send('item', 'dump', item))] + end + + def item_element_actual(item, column, elem, key) + tk_send('item', 'element', 'actual', item, column, elem, "-#{key}") + end + + def item_element_perstate(elem, opt, st_list) + tk_send('item', 'element', 'perstate', elem, "-{opt}", st_list) + end + + def item_expand(item) + tk_send('item', 'expand', item) + self + end + + def item_expand_recurse(item) + tk_send('item', 'expand', item, '-recurse') + self + end + + def item_firstchild(parent, child=nil) + if child + tk_send_without_enc('item', 'firstchild', + _get_eval_string(parent, true), + _get_eval_string(child, true)) + self + else + id = num_or_str(tk_send_without_enc('item', 'firstchild', + _get_eval_string(parent, true))) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_first_child item_firstchild + + def item_hasbutton(item, st=None) + if st == None + bool(tk_send_without_enc('item', 'hasbutton', + _get_eval_string(item, true))) + else + tk_send_without_enc('item', 'hasbutton', + _get_eval_string(item, true), + _get_eval_string(st)) + self + end + end + alias item_has_button item_hasbutton + + def item_hasbutton?(item) + item_hasbutton(item) + end + alias item_has_button? item_hasbutton? + + def item_id(item) + tk_send('item', 'id', item) + end + + def item_image(item, column=nil, *args) + if args.empty? + if column + img = tk_send('item', 'image', item, column) + TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img + else + simplelist(tk_send('item', 'image', item)).collect!{|img| + TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img + } + end + else + tk_send('item', 'image', item, column, *args) + self + end + end + def get_item_image(item, column=nil) + item_image(item, column) + end + def set_item_image(item, col, img, *args) + item_image(item, col, img, *args) + end + + def item_index(item) + list(tk_send('item', 'index', item)) + end + + def item_isancestor(item, des) + bool(tk_send('item', 'isancestor', item, des)) + end + alias item_is_ancestor item_isancestor + alias item_isancestor? item_isancestor + alias item_is_ancestor? item_isancestor + + def item_isopen(item) + bool(tk_send('item', 'isopen', item)) + end + alias item_is_open item_isopen + alias item_isopen? item_isopen + alias item_is_open? item_isopen + alias item_isopened? item_isopen + alias item_is_opened? item_isopen + + def item_lastchild(parent, child=nil) + if child + tk_send_without_enc('item', 'lastchild', + _get_eval_string(parent, true), + _get_eval_string(child, true)) + self + else + id = num_or_str(tk_send_without_enc('item', 'lastchild', + _get_eval_string(parent, true))) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_last_child item_lastchild + + def item_nextsibling(sibling, nxt=nil) + if nxt + tk_send('item', 'nextsibling', sibling, nxt) + self + else + id = num_or_str(tk_send('item', 'nextsibling', sibling)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_next_sibling item_nextsibling + + def item_numchildren(item) + number(tk_send_without_enc('item', 'numchildren', + _get_eval_string(item, true))) + end + alias item_num_children item_numchildren + alias item_children_size item_numchildren + + def item_order(item, visible=false) + if visible + ret = num_or_str(tk_send('item', 'order', item, '-visible')) + else + ret = num_or_str(tk_send('item', 'order', item)) + end + + (ret.kind_of?(Fixnum) && ret < 0)? nil: ret + end + def item_visible_order(item) + item_order(item, true) + end + + def item_parent(item) + id = num_or_str(tk_send('item', 'parent', item)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + + def item_prevsibling(sibling, prev=nil) + if prev + tk_send('item', 'prevsibling', sibling, prev) + self + else + id = num_or_str(tk_send('item', 'prevsibling', sibling)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_prev_sibling item_prevsibling + + def item_range(first, last) + simplelist(tk_send('item', 'range', first, last)) + end + + def item_remove(item) + tk_send('item', 'remove', item) + self + end + + def item_rnc(item) + list(tk_send('item', 'rnc', item)) + end + + def _item_sort_core(real_sort, item, *opts) + # opts ::= sort_param [, sort_param, ... ] + # sort_param ::= {key=>val, ...} + # [type, desc, {key=>val, ...}] + # param + opts = opts.collect{|param| + if param.kind_of?(Hash) + param = _symbolkey2str(param) + if param.key?('column') + key = '-column' + desc = param.delete('column') + elsif param.key?('element') + key = '-element' + desc = param.delete('element') + else + key = nil + end + + if param.empty? + param = None + else + param = hash_kv(__conv_item_keyonly_opts(item, param)) + end + + if key + [key, desc].concat(param) + else + param + end + + elsif param.kind_of?(Array) + if param[2].kind_of?(Hash) + param[2] = hash_kv(__conv_item_keyonly_opts(item, param[2])) + end + param + + elsif param.kind_of?(String) && param =~ /\A[a-z]+\Z/ + '-' << param + + elsif param.kind_of?(Symbol) + '-' << param.to_s + + else + param + end + }.flatten + + if real_sort + tk_send('item', 'sort', item, *opts) + self + else + list(tk_send('item', 'sort', item, '-notreally', *opts)) + end + end + private :_item_sort_core + + def item_sort(item, *opts) + _item_sort_core(true, item, *opts) + end + def item_sort_not_really(item, *opts) + _item_sort_core(false, item, *opts) + end + + def item_span(item, column=nil, *args) + if args.empty? + if column + list(tk_send('item', 'span', item, column)) + else + simplelist(tk_send('item', 'span', item)).collect!{|elem| list(elem)} + end + else + tk_send('item', 'span', item, column, *args) + self + end + end + def get_item_span(item, column=nil) + item_span(item, column) + end + def set_item_span(item, col, num, *args) + item_span(item, col, num, *args) + end + + def item_state_forcolumn(item, column, *args) + tk_send('item', 'state', 'forcolumn', item, column, *args) + end + alias item_state_for_column item_state_forcolumn + + def item_state_get(item, *args) + if args.empty? + list(tk_send('item', 'state', 'get', item *args)) + else + bool(tk_send('item', 'state', 'get', item)) + end + end + + def item_state_set(item, *args) + tk_send('item', 'state', 'set', item, *args) + end + + def item_style_elements(item, column) + list(tk_send('item', 'style', 'elements', item, column)).collect!{|id| + Tk::TreeCtrl::Style.id2obj(self, id) + } + end + + def item_style_map(item, column, style, map) + tk_send('item', 'style', 'map', item, column, style, map) + self + end + + def item_style_set(item, column=nil, *args) + if args.empty? + if column + id = tk_send_without_enc('item', 'style', 'set', + _get_eval_string(item, true), + _get_eval_string(column, true)) + Tk::TreeCtrl::Style.id2obj(self, id) + else + list(tk_send_without_enc('item', 'style', 'set', + _get_eval_string(item, true))).collect!{|id| + Tk::TreeCtrl::Style.id2obj(self, id) + } + end + else + tk_send_without_enc('item', 'style', 'set', + _get_eval_string(item, true), + _get_eval_string(column, true), + *(args.flatten.map!{|arg| + _get_eval_string(arg, true) + })) + self + end + end + + def item_text(item, column, txt=nil, *args) + if args.empty? + if txt + tk_send('item', 'text', item, column, txt) + self + else + tk_send('item', 'text', item, column) + end + else + tk_send('item', 'text', item, column, txt, *args) + self + end + end + + def item_toggle(item) + tk_send('item', 'toggle', item) + self + end + + def item_toggle_recurse(item) + tk_send('item', 'toggle', item, '-recurse') + self + end + + def item_visible(item, st=None) + if st == None + bool(tk_send('item', 'visible', item)) + else + tk_send('item', 'visible', item, st) + self + end + end + def item_visible?(item) + item_visible(item) + end + + def marquee_anchor(*args) + if args.empty? + list(tk_send('marquee', 'anchor')) + else + tk_send('marquee', 'anchor', *args) + self + end + end + + def marquee_coords(*args) + if args.empty? + list(tk_send('marquee', 'coords')) + else + tk_send('marquee', 'coords', *args) + self + end + end + + def marquee_corner(*args) + if args.empty? + tk_send('marquee', 'corner') + else + tk_send('marquee', 'corner', *args) + self + end + end + + def marquee_identify() + list(tk_send('marquee', 'identify')).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def marquee_visible(st=None) + if st == None + bool(tk_send('marquee', 'visible')) + else + tk_send('marquee', 'visible', st) + self + end + end + def marquee_visible?() + marquee_visible() + end + + #def notify_bind(obj, event, cmd=Proc.new, *args) + # _bind([@path, 'notify', 'bind', obj], event, cmd, *args) + # self + #end + def notify_bind(obj, event, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'notify', 'bind', obj], event, cmd, *args) + self + end + + #def notify_bind_append(obj, event, cmd=Proc.new, *args) + # _bind_append([@path, 'notify', 'bind', obj], event, cmd, *args) + # self + #end + def notify_bind_append(obj, event, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'notify', 'bind', obj], event, cmd, *args) + self + end + + def notify_bind_remove(obj, event) + _bind_remove([@path, 'notify', 'bind', obj], event) + self + end + + def notify_bindinfo(obj, event=nil) + _bindinfo([@path, 'notify', 'bind', obj], event) + end + + def notify_detailnames(event) + list(tk_send('notify', 'detailnames', event)) + end + + def notify_eventnames() + list(tk_send('notify', 'eventnames')) + end + + def notify_generate(pattern, char_map=None, percents_cmd=None) + pattern = "<#{pattern}>" + tk_send('notify', 'generate', pattern, char_map, percents_cmd) + self + end + + def notify_install(pattern, percents_cmd=nil, &b) + pattern = "<#{pattern}>" + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + procedure(tk_send('notify', 'install', pattern, percents_cmd)) + else + procedure(tk_send('notify', 'install', pattern)) + end + end + + def notify_install_detail(event, detail, percents_cmd=nil, &b) + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + tk_send('notify', 'install', 'detail', event, detail, percents_cmd) + else + tk_send('notify', 'install', 'detail', event, detail) + end + end + + def notify_install_event(event, percents_cmd=nil, &b) + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + tk_send('notify', 'install', 'event', event, percents_cmd) + else + tk_send('notify', 'install', 'event', event) + end + end + + def notify_linkage(pattern, detail=None) + if detail != None + tk_send('notify', 'linkage', pattern, detail) + else + begin + if pattern.to_s.index(?-) + # TreeCtrl 1.1 format? + begin + tk_send('notify', 'linkage', "<#{pattern}>") + rescue + # TreeCtrl 1.0? + tk_send('notify', 'linkage', pattern) + end + else + # TreeCtrl 1.0 format? + begin + tk_send('notify', 'linkage', pattern) + rescue + # TreeCtrl 1.1? + tk_send('notify', 'linkage', "<#{pattern}>") + end + end + end + end + end + + def notify_unbind(pattern=nil) + if pattern + tk_send('notify', 'unbind', "<#{pattern}>") + else + tk_send('notify', 'unbind') + end + self + end + + def notify_uninstall(pattern) + pattern = "<#{pattern}>" + tk_send('notify', 'uninstall', pattern) + self + end + + def notify_uninstall_detail(event, detail) + tk_send('notify', 'uninstall', 'detail', event, detail) + self + end + + def notify_uninstall_event(event) + tk_send('notify', 'uninstall', 'event', event) + self + end + + def numcolumns() + num_or_str(tk_send('numcolumns')) + end + alias num_columns numcolumns + alias columns_size numcolumns + + def numitems() + num_or_str(tk_send('numitems')) + end + alias num_items numitems + alias items_size numitems + + def orphans() + list(tk_send('orphans')).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def range(first, last) + list(tk_send('range', first, last)).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def state_define(name) + tk_send('state', 'define', name) + self + end + + def state_linkage(name) + tk_send('state', 'linkage', name) + end + + def state_names() + list(tk_send('state', 'names')) + end + + def state_undefine(*names) + tk_send('state', 'undefine', *names) + self + end + + def see(item, column=None, keys={}) + tk_send('see', item, column, *hash_kv(keys)) + self + end + + def selection_add(first, last=None) + tk_send('selection', 'add', first, last) + self + end + + def selection_anchor(item=None) + id = num_or_str(tk_send('selection', 'anchor', item)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + + def selection_clear(*args) # first, last + tk_send('selection', 'clear', *args) + self + end + + def selection_count() + number(tk_send('selection', 'count')) + end + + def selection_get() + list(tk_send('selection', 'get')).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def selection_includes(item) + bool(tk_send('selection', 'includes', item)) + end + + def selection_modify(sel, desel) + tk_send('selection', 'modify', sel, desel) + self + end + + def style_create(style, keys=None) + if keys && keys != None + tk_send('style', 'create', style, *hash_kv(keys)) + else + tk_send('style', 'create', style) + end + end + + def style_delete(*args) + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[self.path] + args.each{|sty| + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[self.path].delete(sty) + } + end + } + tk_send('style', 'delete', *args) + self + end + + def style_elements(style, *elems) + if elems.empty? + list(tk_send('style', 'elements', style)).collect!{|id| + Tk::TreeCtrl::Element.id2obj(self, id) + } + else + tk_send('style', 'elements', style, elems.flatten) + self + end + end + + def _conv_style_layout_val(sty, val) + case sty.to_s + when 'padx', 'pady', 'ipadx', 'ipady' + lst = list(val) + (lst.size == 1)? lst[0]: lst + when 'detach', 'indent' + bool(val) + when 'union' + simplelist(val).collect!{|elem| + Tk::TreeCtrl::Element.id2obj(self, elem) + } + else + val + end + end + private :_conv_style_layout_val + + def style_layout(style, elem, keys=None) + if keys && keys != None + if keys.kind_of?(Hash) + tk_send('style', 'layout', style, elem, *hash_kv(keys)) + self + else + _conv_style_layout_val(keys, + tk_send('style', 'layout', + style, elem, "-#{keys}")) + end + else + ret = Hash.new + Hash[*simplelist(tk_send('style', 'layout', style, elem))].each{|k, v| + k = k[1..-1] + ret[k] = _conv_style_layout_val(k, v) + } + ret + end + end + def get_style_layout(style, elem, opt=None) + style_layout(style, elem, opt) + end + def set_style_layout(style, elem, slot, value=None) + if slot.kind_of?(Hash) + style_layout(style, elem, slot) + else + style_layout(style, elem, {slot=>value}) + end + end + + def style_names() + list(tk_send('style', 'names')).collect!{|id| + Tk::TreeCtrl::Style.id2obj(self, id) + } + end + + def toggle(*items) + tk_send('toggle', *items) + self + end + + def toggle_recurse() + tk_send('toggle', '-recurse', *items) + self + end +end + +##################### + +class Tk::TreeCtrl::Column < TkObject + TreeCtrlColumnID_TBL = TkCore::INTERP.create_table + + (TreeCtrlColumnID = ['treectrl_column'.freeze, TkUtil.untrust('00000')]).instance_eval{ + @mutex = Mutex.new + def mutex; @mutex; end + freeze + } + + TkCore::INTERP.init_ip_env{ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.clear + } + } + + def self.id2obj(tree, id) + tpath = tree.path + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath] + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath][id]? \ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath][id] : id + else + id + end + } + end + + def initialize(parent, keys={}) + @tree = parent + @tpath = parent.path + + keys = _symbolkey2str(keys) + + Tk::TreeCtrl::Column::TreeCtrlColumnID.mutex.synchronize{ + @path = @id = + keys.delete('tag') || + Tk::TreeCtrl::Column::TreeCtrlColumnID.join(TkCore::INTERP._ip_id_) + Tk::TreeCtrl::Column::TreeCtrlColumnID[1].succ! + } + + keys['tag'] = @id + + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[@tpath] ||= {} + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[@tpath][@id] = self + } + + @tree.column_create(keys) + end + + def id + @id + end + + def to_s + @id.to_s.dup + end + + def cget_tkstring(opt) + @tree.column_cget_tkstring(@tree.column_index(@id), opt) + end + def cget(opt) + @tree.column_cget(@tree.column_index(@id), opt) + end + def cget_strict(opt) + @tree.column_cget_strict(@tree.column_index(@id), opt) + end + + def configure(*args) + @tree.column_configure(@tree.column_index(@id), *args) + end + + def configinfo(*args) + @tree.column_configinfo(@tree.column_index(@id), *args) + end + + def current_configinfo(*args) + @tree.current_column_configinfo(@tree.column_index(@id), *args) + end + + def delete + @tree.column_delete(@tree.column_index(@id)) + self + end + + def index + @tree.column_index(@id) + end + + def move(before) + @tree.column_move(@tree.column_index(@id), before) + self + end + + def needed_width + @tree.column_needed_width(@tree.column_index(@id)) + end + alias neededwidth needed_width + + def current_width + @tree.column_width(@tree.column_index(@id)) + end +end + +##################### + +class Tk::TreeCtrl::Element < TkObject + TreeCtrlElementID_TBL = TkCore::INTERP.create_table + + (TreeCtrlElementID = ['treectrl_element'.freeze, TkUtil.untrust('00000')]).instance_eval{ + @mutex = Mutex.new + def mutex; @mutex; end + freeze + } + TreeCtrlElemTypeToClass = {} + + TkCore::INTERP.init_ip_env{ + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.clear + } + } + + def self.type2class(type) + TreeCtrlElemTypeToClass[type] || type + end + + def self.id2obj(tree, id) + tpath = tree.path + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath] + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath][id]? \ + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath][id] : id + else + id + end + } + end + + def initialize(parent, type, keys=nil) + @tree = parent + @tpath = parent.path + @type = type.to_s + Tk::TreeCtrl::Element::TreeCtrlElementID.mutex.synchronize{ + @path = @id = + Tk::TreeCtrl::Element::TreeCtrlElementID.join(TkCore::INTERP._ip_id_) + Tk::TreeCtrl::Element::TreeCtrlElementID[1].succ! + } + + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[@tpath] ||= {} + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[@tpath][@id] = self + } + + @tree.element_create(@id, @type, keys) + end + + def id + @id + end + + def to_s + @id.dup + end + + def cget_tkstring(opt) + @tree.element_cget_tkstring(@id, opt) + end + def cget(opt) + @tree.element_cget(@id, opt) + end + def cget_strict(opt) + @tree.element_cget_strict(@id, opt) + end + + def configure(*args) + @tree.element_configure(@id, *args) + end + + def configinfo(*args) + @tree.element_configinfo(@id, *args) + end + + def current_configinfo(*args) + @tree.current_element_configinfo(@id, *args) + end + + def delete + @tree.element_delete(@id) + self + end + + def element_type + @tree.element_type(@id) + end + + def element_class + @tree.element_class(@id) + end +end + +class Tk::TreeCtrl::BitmapElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['bitmap'] = self + + def initialize(parent, keys=nil) + super(parent, 'bitmap', keys) + end +end + +class Tk::TreeCtrl::BorderElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['border'] = self + + def initialize(parent, keys=nil) + super(parent, 'border', keys) + end +end + +class Tk::TreeCtrl::ImageElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['image'] = self + + def initialize(parent, keys=nil) + super(parent, 'image', keys) + end +end + +class Tk::TreeCtrl::RectangleElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['rect'] = self + + def initialize(parent, keys=nil) + super(parent, 'rect', keys) + end +end + +##################### + +class Tk::TreeCtrl::Item < TkObject + TreeCtrlItemID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.clear + } + } + + def self.id2obj(tree, id) + tpath = tree.path + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath] + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath][id]? \ + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath][id] : id + else + id + end + } + end + + def initialize(parent, keys={}) + @tree = parent + @tpath = parent.path + @path = @id = @tree.item_create(keys) + + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[@tpath] ||= {} + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[@tpath][@id] = self + } + end + + def id + @id + end + + def to_s + @id.to_s.dup + end + + def ancestors + @tree.item_ancestors(@id) + end + + def bbox(*args) + @tree.item_bbox(@id, *args) + end + + def children + @tree.item_children(@id) + end + + def collapse + @tree.item_collapse(@id) + self + end + + def collapse_recurse + @tree.item_collapse_recurse(@id) + self + end + + def complex(*args) + @tree.item_complex(@id, *args) + self + end + + def cget_tkstring(opt) + @tree.item_cget_tkstring(@id, opt) + end + def cget(opt) + @tree.item_cget(@id, opt) + end + def cget_strict(opt) + @tree.item_cget_strict(@id, opt) + end + + def configure(*args) + @tree.item_configure(@id, *args) + end + + def configinfo(*args) + @tree.item_configinfo(@id, *args) + end + + def current_configinfo(*args) + @tree.current_item_configinfo(@id, *args) + end + + def delete + @tree.item_delete(@id) + self + end + + def element_dump + @tree.item_dump(@id) + end + + def element_dump_hash + @tree.item_dump_hash(@id) + end + + def element_actual(column, elem, key) + @tree.item_element_actual(@id, column, elem, key) + end + + def element_cget_tkstring(opt) + @tree.item_element_cget(@id, opt) + end + def element_cget_tkstring(opt) + @tree.item_element_cget(@id, opt) + end + def element_cget_strict(opt) + @tree.item_element_cget_strict(@id, opt) + end + + def element_configure(*args) + @tree.item_element_configure(@id, *args) + end + + def element_configinfo(*args) + @tree.item_element_configinfo(@id, *args) + end + + def current_element_configinfo(*args) + @tree.current_item_element_configinfo(@id, *args) + end + + def expand + @tree.item_expand(@id) + self + end + + def expand_recurse + @tree.item_expand_recurse(@id) + self + end + + def firstchild(child=nil) + if child + @tree.item_firstchild(@id, child) + self + else + @tree.item_firstchild(@id) + end + end + alias first_child firstchild + + def hasbutton(st=None) + if st == None + @tree.item_hasbutton(@id) + else + @tree.item_hasbutton(@id, st) + self + end + end + alias has_button hasbutton + + def hasbutton? + @tree.item_hasbutton(@id) + end + alias has_button? hasbutton? + + def index + @tree.item_index(@id) + end + + def isancestor(des) + @tree.item_isancestor(@id, des) + end + alias is_ancestor isancestor + alias isancestor? isancestor + alias is_ancestor? isancestor + alias ancestor? isancestor + + def isopen + @tree.item_isopen(@id) + end + alias is_open isopen + alias isopen? isopen + alias is_open? isopen + alias isopened? isopen + alias is_opened? isopen + alias open? isopen + + def lastchild(child=nil) + if child + @tree.item_lastchild(@id, child) + self + else + @tree.item_lastchild(@id) + end + end + alias last_child lastchild + + def nextsibling(nxt=nil) + if nxt + @tree.item_nextsibling(@id, nxt) + self + else + @tree.item_nextsibling(@id) + end + end + alias next_sibling nextsibling + + def numchildren + @tree.item_numchildren(@id) + end + alias num_children numchildren + alias children_size numchildren + + def parent_index + @tree.item_parent(@id) + end + + def prevsibling(nxt=nil) + if nxt + @tree.item_prevsibling(@id, nxt) + self + else + @tree.item_prevsibling(@id) + end + end + alias prev_sibling prevsibling + + def remove + @tree.item_remove(@id) + end + + def rnc + @tree.item_rnc(@id) + end + + def sort(*opts) + @tree.item_sort(@id, *opts) + end + def sort_not_really(*opts) + @tree.item_sort_not_really(@id, *opts) + self + end + + def state_forcolumn(column, *args) + @tree.item_state_forcolumn(@id, column, *args) + self + end + alias state_for_column state_forcolumn + + def state_get(*args) + @tree.item_state_get(@id, *args) + end + + def state_set(*args) + @tree.item_state_set(@id, *args) + self + end + + def style_elements(column) + @tree.item_style_elements(@id, column) + end + + def style_map(column, style, map) + @tree.item_style_map(@id, column, style, map) + self + end + + def style_set(column=nil, *args) + if args.empty? + @tree.item_style_set(@id, column) + else + @tree.item_style_set(@id, column, *args) + self + end + end + + def item_text(column, txt=nil, *args) + if args.empty? + if txt + @tree.item_text(@id, column, txt) + self + else + @tree.item_text(@id, column) + end + else + @tree.item_text(@id, column, txt, *args) + self + end + end + + def toggle + @tree.item_toggle(@id) + self + end + + def toggle_recurse + @tree.item_toggle_recurse(@id) + self + end + + def visible(st=None) + if st == None + @tree.item_visible(@id) + else + @tree.item_visible(@id, st) + self + end + end +end + +##################### + +class Tk::TreeCtrl::Style < TkObject + TreeCtrlStyleID_TBL = TkCore::INTERP.create_table + + (TreeCtrlStyleID = ['treectrl_style'.freeze, TkUtil.untrust('00000')]).instance_eval{ + @mutex = Mutex.new + def mutex; @mutex; end + freeze + } + + TkCore::INTERP.init_ip_env{ + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.clear + } + } + + def self.id2obj(tree, id) + tpath = tree.path + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{ + if Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath] + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath][id]? \ + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath][id] : id + else + id + end + } + end + + def initialize(parent, keys=nil) + @tree = parent + @tpath = parent.path + + Tk::TreeCtrl::Style::TreeCtrlStyleID.mutex.synchronize{ + @path = @id = + Tk::TreeCtrl::Style::TreeCtrlStyleID.join(TkCore::INTERP._ip_id_) + Tk::TreeCtrl::Style::TreeCtrlStyleID[1].succ! + } + + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{ + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[@tpath] ||= {} + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[@tpath][@id] = self + } + + @tree.style_create(@id, keys) + end + + def id + @id + end + + def to_s + @id.dup + end + + def cget_tkstring(opt) + @tree.style_cget_tkstring(@id, opt) + end + def cget(opt) + @tree.style_cget(@id, opt) + end + def cget_strict(opt) + @tree.style_cget_strict(@id, opt) + end + + def configure(*args) + @tree.style_configure(@id, *args) + end + + def configinfo(*args) + @tree.style_configinfo(@id, *args) + end + + def current_configinfo(*args) + @tree.current_style_configinfo(@id, *args) + end + + def delete + @tree.style_delete(@id) + self + end + + def elements(*elems) + if elems.empty? + @tree.style_elements(@id) + else + @tree.style_elements(@id, *elems) + self + end + end + + def layout(elem, keys=None) + if keys && keys != None && keys.kind_of?(Hash) + @tree.style_layout(@id, elem, keys) + self + else + @tree.style_layout(@id, elem, keys) + end + end +end + +module Tk::TreeCtrl::BindCallback + include Tk + extend Tk +end + +class << Tk::TreeCtrl::BindCallback + def percentsCmd(*args) + tk_call('::TreeCtrl::PercentsCmd', *args) + end + def cursorCheck(w, x, y) + tk_call('::TreeCtrl::CursorCheck', w, x, y) + end + def cursorCheckAux(w) + tk_call('::TreeCtrl::CursorCheckAux', w) + end + def cursorCancel(w) + tk_call('::TreeCtrl::CursorCancel', w) + end + def buttonPress1(w, x, y) + tk_call('::TreeCtrl::ButtonPress1', w, x, y) + end + def doubleButton1(w, x, y) + tk_call('::TreeCtrl::DoubleButton1', w, x, y) + end + def motion1(w, x, y) + tk_call('::TreeCtrl::Motion1', w, x, y) + end + def leave1(w, x, y) + tk_call('::TreeCtrl::Leave1', w, x, y) + end + def release1(w, x, y) + tk_call('::TreeCtrl::Release1', w, x, y) + end + def beginSelect(w, el) + tk_call('::TreeCtrl::BeginSelect', w, el) + end + def motion(w, le) + tk_call('::TreeCtrl::Motion', w, el) + end + def beginExtend(w, el) + tk_call('::TreeCtrl::BeginExtend', w, el) + end + def beginToggle(w, el) + tk_call('::TreeCtrl::BeginToggle', w, el) + end + def cancelRepeat + tk_call('::TreeCtrl::CancelRepeat') + end + def autoScanCheck(w, x, y) + tk_call('::TreeCtrl::AutoScanCheck', w, x, y) + end + def autoScanCheckAux(w) + tk_call('::TreeCtrl::AutoScanCheckAux', w) + end + def autoScanCancel(w) + tk_call('::TreeCtrl::AutoScanCancel', w) + end + def up_down(w, n) + tk_call('::TreeCtrl::UpDown', w, n) + end + def left_right(w, n) + tk_call('::TreeCtrl::LeftRight', w, n) + end + def setActiveItem(w, idx) + tk_call('::TreeCtrl::SetActiveItem', w, idx) + end + def extendUpDown(w, amount) + tk_call('::TreeCtrl::ExtendUpDown', w, amount) + end + def dataExtend(w, el) + tk_call('::TreeCtrl::DataExtend', w, el) + end + def cancel(w) + tk_call('::TreeCtrl::Cancel', w) + end + def selectAll(w) + tk_call('::TreeCtrl::selectAll', w) + end + def marqueeBegin(w, x, y) + tk_call('::TreeCtrl::MarqueeBegin', w, x, y) + end + def marqueeUpdate(w, x, y) + tk_call('::TreeCtrl::MarqueeUpdate', w, x, y) + end + def marqueeEnd(w, x, y) + tk_call('::TreeCtrl::MarqueeEnd', w, x, y) + end + def scanMark(w, x, y) + tk_call('::TreeCtrl::ScanMark', w, x, y) + end + def scanDrag(w, x, y) + tk_call('::TreeCtrl::ScanDrag', w, x, y) + end + + # filelist-bindings + def fileList_button1(w, x, y) + tk_call('::TreeCtrl::FileListButton1', w, x, y) + end + def fileList_motion1(w, x, y) + tk_call('::TreeCtrl::FileListMotion1', w, x, y) + end + def fileList_motion(w, x, y) + tk_call('::TreeCtrl::FileListMotion', w, x, y) + end + def fileList_leave1(w, x, y) + tk_call('::TreeCtrl::FileListLeave1', w, x, y) + end + def fileList_release1(w, x, y) + tk_call('::TreeCtrl::FileListRelease1', w, x, y) + end + def fileList_edit(w, i, s, e) + tk_call('::TreeCtrl::FileListEdit', w, i, s, e) + end + def fileList_editCancel(w) + tk_call('::TreeCtrl::FileListEditCancel', w) + end + def fileList_autoScanCheck(w, x, y) + tk_call('::TreeCtrl::FileListAutoScanCheck', w, x, y) + end + def fileList_autoScanCheckAux(w) + tk_call('::TreeCtrl::FileListAutoScanCheckAux', w) + end + + def entryOpen(w, item, col, elem) + tk_call('::TreeCtrl::EntryOpen', w, item, col, elem) + end + def entryExpanderOpen(w, item, col, elem) + tk_call('::TreeCtrl::EntryExpanderOpen', w, item, col, elem) + end + def entryClose(w, accept) + tk_call('::TreeCtrl::EntryClose', w, accept) + end + def entryExpanderKeypress(w) + tk_call('::TreeCtrl::EntryExpanderKeypress', w) + end + def textOpen(w, item, col, elem, width=0, height=0) + tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width, height) + end + def textExpanderOpen(w, item, col, elem, width) + tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width) + end + def textClose(w, accept) + tk_call('::TreeCtrl::TextClose', w, accept) + end + def textExpanderKeypress(w) + tk_call('::TreeCtrl::TextExpanderKeypress', w) + end +end |