diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-15 19:08:43 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-15 19:08:43 +0000 |
commit | d464704f111d211c1f1ff9ef23ef1d755054be00 (patch) | |
tree | b58b17b645dc463322e5fca57fe282360db659c9 /ruby_1_8_5/ext/tk/lib/tkextlib/blt/tree.rb | |
parent | e4f06b3f2dec4b5d6334c5e9907e1cecbf649fc4 (diff) |
add tag v1_8_5_54
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_5_54@12952 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ruby_1_8_5/ext/tk/lib/tkextlib/blt/tree.rb')
-rw-r--r-- | ruby_1_8_5/ext/tk/lib/tkextlib/blt/tree.rb | 923 |
1 files changed, 923 insertions, 0 deletions
diff --git a/ruby_1_8_5/ext/tk/lib/tkextlib/blt/tree.rb b/ruby_1_8_5/ext/tk/lib/tkextlib/blt/tree.rb new file mode 100644 index 0000000000..07dc7ef7e8 --- /dev/null +++ b/ruby_1_8_5/ext/tk/lib/tkextlib/blt/tree.rb @@ -0,0 +1,923 @@ +# +# 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 id + @id + end + + def add(*nodes) + tk_call(@tpath, 'tag', 'add', @id, *nodes) + self + end + + def delete(*nodes) + tk_call(@tpath, 'tag', 'delete', @id, *nodes) + self + end + + def forget() + tk_call(@tpath, 'tag', 'forget', @id) + TreeTagID_TBL[@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 id + @id + 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 id + @id + 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 tagid(tag) + if tag.kind_of?(Tk::BLT::Tree::Node) || + tag.kind_of?(Tk::BLT::Tree::Tag) || + tag.kind_of?(Tk::BLT::Tree::Notify) || + tag.kind_of?(Tk::BLT::Tree::Trace) + tag.id + else + tag # maybe an Array of configure paramters + end + end + + def destroy() + tk_call('::blt::tree', 'destroy', @id) + self + end + + def ancestor(node1, node2) + Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'ancestor', + tagid(node1), tagid(node2))) + end + + def apply(node, keys={}) + tk_call('::blt::tree', 'apply', tagid(node), __conv_keyonly_opts(keys)) + self + end + + def attach(tree_obj) + tk_call('::blt::tree', 'attach', tree_obj) + self + end + + def children(node) + simplelist(tk_call('::blt::tree', 'children', tagid(node))).collect{|n| + Tk::BLT::Tree::Node.id2obj(self, n) + } + end + + def copy(src, parent, keys={}) + id = tk_call('::blt::tree', 'copy', tagid(src), tagid(parent), + __conv_keyonly_opts(keys)) + Tk::BLT::Tree::Node.new(self, nil, 'node'=>id) + end + def copy_to(src, dest_tree, parent, keys={}) + return copy(src, parent, keys={}) unless dest_tree + + id = tk_call('::blt::tree', 'copy', tagid(src), dest_tree, + tagid(parent), __conv_keyonly_opts(keys)) + Tk::BLT::Tree::Node.new(dest_tree, nil, 'node'=>id) + end + + def degree(node) + number(tk_call('::blt::tree', 'degree', tagid(node))) + end + + def delete(*nodes) + tk_call('::blt::tree', 'delete', *(nodes.collect{|node| tagid(node)})) + nodes.each{|node| + if node.kind_of?(Tk::BLT::Tree::Node) + Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.id) + else + Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.to_s) + end + } + self + end + + def depth(node) + number(tk_call('::blt::tree', 'depth', tagid(node))) + end + + def dump(node) + simplelist(tk_call('::blt::tree', 'dump', tagid(node))).collect{|n| + simplelist(n) + } + end + + def dump_to_file(node, file) + tk_call('::blt::tree', 'dumpfile', tagid(node), file) + self + end + + def exist?(node, key=None) + bool(tk_call('::blt::tree', 'exists', tagid(node), key)) + end + + def find(node, keys={}) + simplelist(tk_call('::blt::tree', 'find', tagid(node), + __conv_keyonly_opts(keys))).collect{|n| + Tk::BLT::Tree::Node.id2obj(self, n) + } + end + + def find_child(node, label) + ret = tk_call('::blt::tree', 'findchild', tagid(node), label) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def first_child(node) + ret = tk_call('::blt::tree', 'firstchild', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def get(node) + Hash[*simplelist(tk_call('::blt::tree', 'get', tagid(node)))] + end + def get_value(node, key, default_val=None) + tk_call('::blt::tree', 'get', tagid(node), key, default_val) + end + + def index(node) + Tk::BLT::Tree::Node.id2obj(self, + tk_call('::blt::tree', 'index', tagid(node))) + end + + def insert(parent, keys={}) + id = tk_call('::blt::tree', 'insert', tagid(parent), keys) + Tk::BLT::Tree::Node.new(self, nil, 'node'=>id) + end + + def ancestor?(node1, node2) + bool(tk_call('::blt::tree', 'is', 'ancestor', + tagid(node1), tagid(node2))) + end + def before?(node1, node2) + bool(tk_call('::blt::tree', 'is', 'before', + tagid(node1), tagid(node2))) + end + def leaf?(node) + bool(tk_call('::blt::tree', 'is', 'leaf', tagid(node))) + end + def link?(node) + bool(tk_call('::blt::tree', 'is', 'link', tagid(node))) + end + def root?(node) + bool(tk_call('::blt::tree', 'is', 'root', tagid(node))) + end + + def keys(node, *nodes) + if nodes.empty? + simplelist(tk_call('blt::tree', 'keys', tagid(node))) + else + simplelist(tk_call('blt::tree', 'keys', tagid(node), + *(nodes.collect{|n| tagid(n)}))).collect{|lst| + simplelist(lst) + } + end + end + + def label(node, text=nil) + if text + tk_call('::blt::tree', 'label', tagid(node), text) + text + else + tk_call('::blt::tree', 'label', tagid(node)) + end + end + + def last_child(node) + ret = tk_call('::blt::tree', 'lastchild', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def link(parent, node, keys={}) + ret = tk_call('::blt::tree', 'link', tagid(parent), tagid(node), + __conv_keyonly_opts(keys)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def move(node, dest, keys={}) + tk_call('::blt::tree', 'move', tagid(node), tagid(dest), keys) + self + end + + def next(node) + ret = tk_call('::blt::tree', 'next', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def next_sibling(node) + ret = tk_call('::blt::tree', 'nextsibling', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def notify_create(*args, &b) + Tk::BLT::Tree::Notify.new(self, *args, &b) + end + + def notify_delete(id) + if id.kind_of?(Tk::BLT::Tree::Notify) + id.delete + else + tk_call(@path, 'notify', 'delete', id) + Tk::BLT::Tree::Notify::NotifyID_TBL[@path].delete(id.to_s) + end + self + end + + def notify_info(id) + lst = simplelist(tk_call(@path, 'notify', 'info', tagid(id))) + lst[0] = Tk::BLT::Tree::Notify.id2obj(self, lst[0]) + lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]} + lst[2] = tk_tcl2ruby(lst[2]) + lst + end + + def notify_names() + tk_call(@path, 'notify', 'names').collect{|id| + Tk::BLT::Tree::Notify.id2obj(self, id) + } + end + + def parent(node) + ret = tk_call('::blt::tree', 'parent', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def fullpath(node) + tk_call('::blt::tree', 'path', tagid(node)) + end + + def position(node) + number(tk_call('::blt::tree', 'position', tagid(node))) + end + + def previous(node) + ret = tk_call('::blt::tree', 'previous', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def prev_sibling(node) + ret = tk_call('::blt::tree', 'prevsibling', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def restore(node, str, keys={}) + tk_call('::blt::tree', 'restore', tagid(node), str, + __conv_keyonly_opts(keys)) + self + end + def restore_overwrite(node, str, keys={}) + keys = __conv_keyonly_opts(keys) + keys.delete('overwrite') + keys.delete(:overwrite) + tk_call('::blt::tree', 'restore', tagid(node), str, '-overwrite', keys) + self + end + + def restore_from_file(node, file, keys={}) + tk_call('::blt::tree', 'restorefile', tagid(node), file, + __conv_keyonly_opts(keys)) + self + end + def restore_overwrite_from_file(node, file, keys={}) + keys = __conv_keyonly_opts(keys) + keys.delete('overwrite') + keys.delete(:overwrite) + tk_call('::blt::tree', 'restorefile', tagid(node), file, + '-overwrite', keys) + self + end + + def root(node=None) + Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'root', + tagid(node))) + end + + def set(node, data) + unless data.kind_of?(Hash) + fail ArgumentError, 'Hash is expected for data' + end + args = [] + data.each{|k, v| args << k << v} + tk_call('::blt::tree', 'set', tagid(node), *args) + self + end + + def size(node) + number(tk_call('::blt::tree', 'size', tagid(node))) + end + + def sort(node, keys={}) + tk_call('::blt::tree', 'sort', tagid(node), __conv_keyonly_opts(keys)) + self + end + + def tag_add(tag, *nodes) + tk_call(@path, 'tag', 'add', tagid(tag), *(nodes.collect{|n| tagid(n)})) + self + end + + def tag_delete(tag, *nodes) + tk_call(@path, 'tag', 'delete', tagid(tag), + *(nodes.collect{|n| tagid(n)})) + self + end + + def tag_forget(tag) + tag = tag.id if tag.kind_of?(Tk::BLT::Tree::Tag) + tk_call(@path, 'tag', 'forget', tag) + TreeTagID_TBL[@path].delete(tag) + self + end + + def tag_get(node, *patterns) + simplelist(tk_call(@tpath, 'tag', 'get', tagid(node), + *(patterns.collect{|pat| tagid(pat)}))).collect{|str| + Tk::BLT::Tree::Tag.id2obj(self, str) + } + end + + def tag_names(node = None) + simplelist(tk_call(@tpath, 'tag', 'names', tagid(node))).collect{|str| + Tk::BLT::Tree::Tag.id2obj(self, str) + } + end + + def tag_nodes(tag) + simplelist(tk_call(@tpath, 'tag', 'nodes', tagid(tag))).collect{|node| + Tk::BLT::Tree::Node.id2obj(self, node) + } + end + + def tag_set(node, *tags) + tk_call(@path, 'tag', 'set', tagid(node), *(tags.collect{|t| tagid(t)})) + self + end + + def tag_unset(node, *tags) + tk_call(@path, 'tag', 'unset', tagid(node), + *(tags.collect{|t| tagid(t)})) + self + end + + def trace_create(*args, &b) + Tk::BLT::Tree::Trace.new(self, *args, &b) + end + +=begin + def trace_delete(*args) + args.each{|id| + if id.kind_of?(Tk::BLT::Tree::Trace) + id.delete + else + tk_call(@path, 'trace', 'delete', id) + Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s) + end + self + } + end +=end + def trace_delete(*args) + args = args.collect{|id| tagid(id)} + tk_call(@path, 'trace', 'delete', *args) + args.each{|id| Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)} + self + end + + def trace_info(id) + lst = simplelist(tk_call(@path, 'trace', 'info', tagid(id))) + lst[0] = Tk::BLT::Tree::Trace.id2obj(self, lst[0]) + lst[2] = simplelist(lst[2]) + lst[3] = tk_tcl2ruby(lst[3]) + lst + end + + def trace_names() + tk_call(@path, 'trace', 'names').collect{|id| + Tk::BLT::Tree::Trace.id2obj(self, id) + } + end + + def type(node, key) + tk_call('::blt::tree', 'type', tagid(node), key) + end + + def unset(node, *keys) + tk_call('::blt::tree', 'unset', tagid(node), *keys) + self + end + + def values(node, key=None) + simplelist(tk_call('::blt::tree', 'values', tagid(node), key)) + end + end +end |