2 # tkextlib/bwidget/tree.rb
3 # by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
8 require 'tkextlib/bwidget.rb'
19 class Tk::BWidget::Tree
20 include TkItemConfigMethod
23 TkCommandNames = ['Tree'.freeze].freeze
24 WidgetClassName = 'Tree'.freeze
25 WidgetClassNames[WidgetClassName] = self
27 class Event_for_Items < TkEvent::Event
28 def self._get_extra_args_tbl
30 TkComm.method(:string) # item idenfier
36 super() << 'crossfill' << 'linesfill'
38 private :__strval_optkeys
41 super() << 'dragenabled' << 'dropenabled' <<
42 'redraw' << 'selectfill' << 'showlines'
44 private :__boolval_optkeys
46 def __tkvariable_optkeys
49 private :__tkvariable_optkeys
52 if tag.kind_of?(Tk::BWidget::Tree::Node)
61 # _bind_for_event_class(Event_for_Items, [path, 'bindImage'], *args)
64 def imagebind(context, *args)
65 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
66 if TkComm._callback_entry?(args[0]) || !block_given?
71 _bind_for_event_class(Event_for_Items, [path, 'bindImage'],
76 #def imagebind_append(*args)
77 # _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], *args)
80 def imagebind_append(context, *args)
81 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
82 if TkComm._callback_entry?(args[0]) || !block_given?
87 _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'],
92 def imagebind_remove(*args)
93 _bind_remove_for_event_class(Event_for_Items, [path, 'bindImage'], *args)
97 def imagebindinfo(*args)
98 _bindinfo_for_event_class(Event_for_Items, [path, 'bindImage'], *args)
102 # _bind_for_event_class(Event_for_Items, [path, 'bindText'], *args)
105 def textbind(context, *args)
106 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
107 if TkComm._callback_entry?(args[0]) || !block_given?
112 _bind_for_event_class(Event_for_Items, [path, 'bindText'],
117 #def textbind_append(*args)
118 # _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], *args)
121 def textbind_append(context, *args)
122 #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
123 if TkComm._callback_entry?(args[0]) || !block_given?
128 _bind_append_for_event_class(Event_for_Items, [path, 'bindText'],
133 def textbind_remove(*args)
134 _bind_remove_for_event_class(Event_for_Items, [path, 'bindText'], *args)
138 def textbindinfo(*args)
139 _bindinfo_for_event_class(Event_for_Items, [path, 'bindText'], *args)
142 def close_tree(node, recurse=None)
143 tk_send('closetree', tagid(node), recurse)
148 tk_send('delete', *(args.collect{|node| tagid(node)}))
152 def edit(node, text, *args)
153 tk_send('edit', tagid(node), text, *args)
158 bool(tk_send('exists', tagid(node)))
162 num_or_str(tk_send('index', tagid(node)))
165 def insert(idx, parent, node, keys={})
166 tk_send('insert', idx, tagid(parent), tagid(node), *hash_kv(keys))
170 def move(parent, node, idx)
171 tk_send('move', tagid(parent), tagid(node), idx)
175 def get_node(node, idx)
176 Tk::BWidget::Tree::Node.id2obj(self, tk_send('nodes', tagid(node), idx))
179 def nodes(node, first=None, last=None)
180 simplelist(tk_send('nodes', tagid(node), first, last)).collect{|node|
181 Tk::BWidget::Tree::Node.id2obj(self, node)
186 bool(@tree.itemcget(tagid(node), 'open'))
189 def open_tree(node, recurse=None)
190 tk_send('opentree', tagid(node), recurse)
195 Tk::BWidget::Tree::Node.id2obj(self, tk_send('parent', tagid(node)))
198 def reorder(node, neworder)
199 tk_send('reorder', tagid(node), neworder)
204 tk_send('see', tagid(node))
208 def selection_add(*args)
209 tk_send_without_enc('selection', 'add',
210 *(args.collect{|node| tagid(node)}))
215 tk_send_without_enc('selection', 'clear')
220 list(tk_send_without_enc('selection', 'get'))
223 def selection_include?(*args)
224 bool(tk_send_without_enc('selection', 'get',
225 *(args.collect{|node| tagid(node)})))
228 def selection_range(*args)
229 tk_send_without_enc('selection', 'range',
230 *(args.collect{|node| tagid(node)}))
234 def selection_remove(*args)
235 tk_send_without_enc('selection', 'remove',
236 *(args.collect{|node| tagid(node)}))
240 def selection_set(*args)
241 tk_send_without_enc('selection', 'set',
242 *(args.collect{|node| tagid(node)}))
246 def selection_toggle(*args)
247 tk_send_without_enc('selection', 'toggle',
248 *(args.collect{|node| tagid(node)}))
253 tk_send_without_enc('toggle', tagid(node))
258 bool(tk_send_without_enc('visible', tagid(node)))
262 class Tk::BWidget::Tree::Node
263 include TkTreatTagFont
265 TreeNode_TBL = TkCore::INTERP.create_table
267 (TreeNode_ID = ['bw:node'.freeze, '00000'.taint]).instance_eval{
269 def mutex; @mutex; end
273 TkCore::INTERP.init_ip_env{
274 TreeNode_TBL.mutex.synchronize{ TreeNode_TBL.clear }
277 def self.id2obj(tree, id)
279 TreeNode_TBL.mutex.synchronize{
280 if TreeNode_TBL[tpath]
281 TreeNode_TBL[tpath][id]? TreeNode_TBL[tpath][id]: id
288 def initialize(tree, *args)
289 if tree.kind_of?(Tk::BWidget::Tree)
292 if parent.kind_of?(Tk::BWidget::Tree::Node)
293 if parent.tree.path != @tree.path
294 fail RuntimeError, 'tree of parent node is not match'
297 elsif tree.kind_of?(Tk::BWidget::Tree::Node)
302 "expect Tk::BWidget::Tree or Tk::BWidget::Tree::Node for 1st argument"
305 if args[-1].kind_of?(Hash)
306 keys = _symbolkey2str(args.pop)
311 index = keys.delete('index')
315 index = 'end' unless index
318 fail RuntimeError, 'too much arguments'
323 if keys.key?('nodename')
324 @path = @id = keys.delete('nodename')
326 TreeNode_ID.mutex.synchronize{
327 @path = @id = TreeNode_ID.join(TkCore::INTERP._ip_id_)
332 TreeNode_TBL.mutex.synchronize{
333 TreeNode_TBL[@id] = self
334 TreeNode_TBL[@tpath] = {} unless TreeNode_TBL[@tpath]
335 TreeNode_TBL[@tpath][@id] = self
338 @tree.insert(index, parent, @id, keys)
359 @tree.itemcget(@id, key)
362 @tree.itemcget_strict(@id, key)
365 def configure(key, val=None)
366 @tree.itemconfigure(@id, key, val)
369 def configinfo(key=nil)
370 @tree.itemconfiginfo(@id, key)
373 def current_configinfo(key=nil)
374 @tree.current_itemconfiginfo(@id, key)
377 def close_tree(recurse=None)
378 @tree.close_tree(@id, recurse)
388 @tree.edit(@id, *args)
400 def move(index, parent=nil)
402 @tree.move(parent, @id, index)
404 @tree.move(self.parent, @id, index)
408 def open_tree(recurse=None)
409 @tree.open_tree(@id, recurse)
414 bool(@tree.itemcget(@id, 'open'))
421 def reorder(neworder)
422 @tree.reorder(@id, neworder)
430 @tree.selection_add(@id)
434 @tree.selection_remove(@id)
438 @tree.selection_set(@id)
442 @tree.selection_toggle(@id)