rbhex-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG +2000 -0
  4. data/LICENSE +56 -0
  5. data/README.md +44 -0
  6. data/examples/abasiclist.rb +179 -0
  7. data/examples/alpmenu.rb +50 -0
  8. data/examples/app.sample +19 -0
  9. data/examples/atree.rb +100 -0
  10. data/examples/bline.rb +136 -0
  11. data/examples/common/file.rb +45 -0
  12. data/examples/data/README.markdown +9 -0
  13. data/examples/data/brew.txt +38 -0
  14. data/examples/data/color.2 +37 -0
  15. data/examples/data/gemlist.txt +60 -0
  16. data/examples/data/lotr.txt +12 -0
  17. data/examples/data/ports.txt +136 -0
  18. data/examples/data/table.txt +37 -0
  19. data/examples/data/tasks.csv +88 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/data/todo.txt +10 -0
  22. data/examples/data/todo.txt.bak +10 -0
  23. data/examples/data/todocsv.csv +28 -0
  24. data/examples/data/unix1.txt +21 -0
  25. data/examples/data/unix2.txt +11 -0
  26. data/examples/dbdemo.rb +502 -0
  27. data/examples/dirtree.rb +94 -0
  28. data/examples/newtabbedwindow.rb +100 -0
  29. data/examples/newtesttabp.rb +92 -0
  30. data/examples/tabular.rb +146 -0
  31. data/examples/tasks.rb +178 -0
  32. data/examples/term2.rb +84 -0
  33. data/examples/testbuttons.rb +296 -0
  34. data/examples/testcombo.rb +102 -0
  35. data/examples/testfields.rb +195 -0
  36. data/examples/testkeypress.rb +72 -0
  37. data/examples/testlistbox.rb +170 -0
  38. data/examples/testmessagebox.rb +140 -0
  39. data/examples/testprogress.rb +116 -0
  40. data/examples/testree.rb +106 -0
  41. data/examples/testwsshortcuts.rb +66 -0
  42. data/examples/testwsshortcuts2.rb +128 -0
  43. data/lib/rbhex.rb +6 -0
  44. data/lib/rbhex/core/docs/index.txt +73 -0
  45. data/lib/rbhex/core/include/action.rb +80 -0
  46. data/lib/rbhex/core/include/actionmanager.rb +49 -0
  47. data/lib/rbhex/core/include/appmethods.rb +214 -0
  48. data/lib/rbhex/core/include/bordertitle.rb +48 -0
  49. data/lib/rbhex/core/include/chunk.rb +203 -0
  50. data/lib/rbhex/core/include/io.rb +553 -0
  51. data/lib/rbhex/core/include/listbindings.rb +74 -0
  52. data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
  53. data/lib/rbhex/core/include/listeditable.rb +317 -0
  54. data/lib/rbhex/core/include/listscrollable.rb +663 -0
  55. data/lib/rbhex/core/include/listselectable.rb +271 -0
  56. data/lib/rbhex/core/include/multibuffer.rb +83 -0
  57. data/lib/rbhex/core/include/orderedhash.rb +77 -0
  58. data/lib/rbhex/core/include/ractionevent.rb +73 -0
  59. data/lib/rbhex/core/include/rchangeevent.rb +27 -0
  60. data/lib/rbhex/core/include/rhistory.rb +95 -0
  61. data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
  62. data/lib/rbhex/core/include/vieditable.rb +172 -0
  63. data/lib/rbhex/core/include/widgetmenu.rb +66 -0
  64. data/lib/rbhex/core/system/colormap.rb +165 -0
  65. data/lib/rbhex/core/system/keyboard.rb +150 -0
  66. data/lib/rbhex/core/system/keydefs.rb +30 -0
  67. data/lib/rbhex/core/system/ncurses.rb +236 -0
  68. data/lib/rbhex/core/system/panel.rb +162 -0
  69. data/lib/rbhex/core/system/window.rb +913 -0
  70. data/lib/rbhex/core/util/ansiparser.rb +119 -0
  71. data/lib/rbhex/core/util/app.rb +1228 -0
  72. data/lib/rbhex/core/util/basestack.rb +410 -0
  73. data/lib/rbhex/core/util/bottomline.rb +1859 -0
  74. data/lib/rbhex/core/util/colorparser.rb +77 -0
  75. data/lib/rbhex/core/util/focusmanager.rb +31 -0
  76. data/lib/rbhex/core/util/padreader.rb +192 -0
  77. data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
  78. data/lib/rbhex/core/util/rdialogs.rb +574 -0
  79. data/lib/rbhex/core/util/viewer.rb +149 -0
  80. data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
  81. data/lib/rbhex/core/version.rb +5 -0
  82. data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
  83. data/lib/rbhex/core/widgets/box.rb +58 -0
  84. data/lib/rbhex/core/widgets/divider.rb +310 -0
  85. data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
  86. data/lib/rbhex/core/widgets/rcombo.rb +253 -0
  87. data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
  88. data/lib/rbhex/core/widgets/rlink.rb +30 -0
  89. data/lib/rbhex/core/widgets/rlist.rb +696 -0
  90. data/lib/rbhex/core/widgets/rmenu.rb +958 -0
  91. data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
  92. data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
  93. data/lib/rbhex/core/widgets/rprogress.rb +118 -0
  94. data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
  95. data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
  96. data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
  97. data/lib/rbhex/core/widgets/rtextview.rb +739 -0
  98. data/lib/rbhex/core/widgets/rtree.rb +768 -0
  99. data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
  100. data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
  101. data/lib/rbhex/core/widgets/statusline.rb +113 -0
  102. data/lib/rbhex/core/widgets/tabular.rb +264 -0
  103. data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
  104. data/lib/rbhex/core/widgets/textpad.rb +995 -0
  105. data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
  106. data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
  107. data/rbhex-core.gemspec +32 -0
  108. metadata +172 -0
@@ -0,0 +1,150 @@
1
+ # 2010-09-18 15:35
2
+ require 'rbhex'
3
+ require 'rbhex/core/widgets/rwidget'
4
+ module RubyCurses
5
+
6
+ ##
7
+ # This is a basic list cell renderer that will render the to_s value of anything.
8
+ #
9
+ # TODO upgrade as per new listcellrenderer
10
+ class TreeCellRenderer
11
+ PLUS_PLUS = "++"
12
+ PLUS_MINUS = "+-"
13
+ PLUS_Q = "+?"
14
+ include RubyCurses::ConfigSetup
15
+ include RubyCurses::Utils
16
+ dsl_accessor :justify # :right, :left, :center # added 2008-12-22 19:02
17
+ dsl_accessor :display_length # please give this to ensure the we only print this much
18
+ dsl_accessor :height # if you want a multiline label.
19
+ dsl_accessor :text # text of label
20
+ dsl_accessor :color, :bgcolor
21
+ dsl_accessor :row, :col
22
+ dsl_accessor :parent #usuall the table to get colors and other default info
23
+ attr_reader :actual_length
24
+ attr_accessor :pcol
25
+
26
+ def initialize text="", config={}, &block
27
+ @text = text
28
+ @editable = false
29
+ @focusable = false
30
+ @actual_length = 0
31
+ config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
32
+ instance_eval &block if block_given?
33
+ init_vars
34
+ end
35
+ def init_vars
36
+ @justify ||= :left
37
+ @display_length ||= 10
38
+ end
39
+ def getvalue
40
+ @text
41
+ end
42
+ ##
43
+ # sets @color_pair and @attr
44
+ def prepare_default_colors focussed, selected
45
+ @color_pair = get_color $datacolor
46
+ @attr = @row_attr || Ncurses::A_NORMAL
47
+
48
+
49
+ ## determine bg and fg and attr
50
+ if selected
51
+ #@attr = Ncurses::A_BOLD if selected
52
+ ## 2010-09-18 18:32 making selected row reverse
53
+ @attr |= Ncurses::A_REVERSE
54
+
55
+ # 2010-09-18 18:33 maybe not required, just confuses the whole thing and uglifies it
56
+ #@color_pair =get_color $selectedcolor, @parent.selected_color, @parent.selected_bgcolor unless @parent.nil?
57
+ end
58
+ case focussed
59
+ when :SOFT_FOCUS
60
+ @attr |= Ncurses::A_BOLD
61
+ when true
62
+ # earlier focussed row showed up in reverse, which was confusing since it looked selected
63
+ # now focussed row has cursor on side, and can be bold. that's enough.
64
+ @attr |= Ncurses::A_BOLD
65
+ #@attr |= Ncurses::A_REVERSE
66
+ when false
67
+ end
68
+ end
69
+
70
+ ##
71
+ # paint a list box cell
72
+ # 2010-09-02 15:38 changed focussed to take true, false and :SOFT_FOCUS
73
+ # SOFT_FOCUS means the form focus is no longer on this field, but this row
74
+ # was focussed when use was last on this field. This row will take focus
75
+ # when field is focussed again
76
+ #
77
+ # @param [Buffer] window or buffer object used for printing
78
+ # @param [Fixnum] row
79
+ # @param [Fixnum] column
80
+ # @param [Fixnum] actual index into data, some lists may have actual data elsewhere and
81
+ # display data separate. e.g. rfe_renderer (directory listing)
82
+ # @param [String] text to print in cell
83
+ # @param [Boolean, :SOFT_FOCUS] cell focussed, not focussed, cell focussed but field is not focussed
84
+ # @param [Boolean] cell selected or not
85
+ #renderer.repaint @graphic, r+hh, c+@left_margin, crow, object, content, focus_type, selected, expanded, leaf
86
+ def repaint graphic, r=@row,c=@col, row_index=-1, treearraynode=nil, value=@text, leaf=nil, focussed=false, selected=false, expanded=false
87
+ #$log.debug "label :#{@text}, #{value}, #{r}, #{c} col= #{@color}, #{@bgcolor} acolor= #{acolor} j:#{@justify} dlL: #{@display_length} "
88
+
89
+ prepare_default_colors focussed, selected
90
+
91
+ value=value.to_s # ??
92
+ #icon = object.is_leaf? ? "-" : "+"
93
+ #icon = leaf ? "-" : "+"
94
+
95
+ #level = treearraynode.level
96
+ #node = treearraynode.node
97
+ level = treearraynode.level
98
+ node = treearraynode
99
+ if parent.node_expanded? node
100
+ icon = PLUS_MINUS # can collapse
101
+ else
102
+ icon = PLUS_PLUS # can expand
103
+ end
104
+ if node.children.size == 0
105
+ icon = PLUS_Q # either no children or not visited yet
106
+ if parent.has_been_expanded node
107
+ icon = PLUS_MINUS # definitely no children, we've visited
108
+ end
109
+ end
110
+ # adding 2 to level, that's the size of icon
111
+ # XXX FIXME if we put the icon here, then when we scroll right, the icon will show, it shoud not
112
+ # FIXME we ignore truncation etc on previous level and take the object as is !!!
113
+ _value = "%*s %s" % [ level+2, icon, node.user_object ]
114
+ @actual_length = _value.length
115
+ pcol = @pcol
116
+ if pcol > 0
117
+ _len = @display_length || @parent.width-2
118
+ _value = _value[@pcol..@pcol+_len-1]
119
+ end
120
+ _value ||= ""
121
+ if @height && @height > 1
122
+ else
123
+ # ensure we do not exceed
124
+ if !@display_length.nil?
125
+ if _value.length > @display_length
126
+ @actual_length = _value.length
127
+ _value = _value[0..@display_length-1]
128
+ end
129
+ end
130
+ #lablist << value
131
+ end
132
+ len = @display_length || _value.length
133
+ graphic.printstring r, c, "%-*s" % [len, _value], @color_pair,@attr
134
+ #_height = @height || 1
135
+ #0.upto(_height-1) { |i|
136
+ #graphic.printstring r+i, c, ( " " * len) , @color_pair,@attr
137
+ #}
138
+ #lablist.each_with_index do |_value, ix|
139
+ #break if ix >= _height
140
+ #if @justify.to_sym == :center
141
+ #padding = (@display_length - _value.length)/2
142
+ #_value = " "*padding + _value + " "*padding # so its cleared if we change it midway
143
+ #end
144
+ #graphic.printstring r, c, str % [len, _value], @color_pair,@attr
145
+ #r += 1
146
+ #end
147
+ end
148
+ # ADD HERE
149
+ end
150
+ end
@@ -0,0 +1,428 @@
1
+ # File TreeModel
2
+ # (c) rkumar arunachalesha
3
+ # Created on: Fri Sep 17 20:03:10 IST 2010
4
+ require 'rbhex'
5
+
6
+ module RubyCurses
7
+ class IllegalStateException < Exception
8
+ end
9
+
10
+ class DefaultTreeModel #< TreeModel
11
+ include RubyCurses::EventHandler
12
+ attr_reader :asks_allow_children
13
+ attr_accessor :root_visible
14
+ def initialize node=nil, asks_allow_children=false, &block
15
+ @root_visible = true
16
+ root(node, asks_allow_children) if node
17
+ instance_eval &block if block_given?
18
+ end
19
+ # insert a node the old sucky java pain in the butt way
20
+ # private
21
+ # sets node as root
22
+ #def root node, asks_allow_children=false, &block
23
+ def root *args, &block
24
+ return @root if args.empty?
25
+ node = args[0]
26
+ @asks_allow_children = args[1]
27
+ if !node.is_a? TreeNode
28
+ n = TreeNode.new node
29
+ node = n
30
+ end
31
+ @root = node
32
+ $log.debug " XXX def root created root with #{node} "
33
+ #add node, true, &block
34
+ instance_eval &block if block_given?
35
+ end
36
+ def insert_node_into nodechild, nodeparent, index
37
+ $log.debug " TODO remove from existing parent to avoid bugs XXX"
38
+ nodeparent.insert nodechild, index
39
+ if @handler # only if someone is listening, won't fire when being prepared
40
+ tme = TreeModelEvent.new(row, row,:ALL_COLUMNS, self, :INSERT)
41
+ fire_handler :TREE_MODEL_EVENT, tme
42
+ end
43
+ self
44
+ end
45
+ # add a node to root passing a block optionally
46
+ # @param [String, TreeNode, Array, Hash] node/s to add
47
+ # @param [Boolean] allow children to be added
48
+ # @see TreeNode.add
49
+ # @return [TreeNode] node just added to root (NOT self)
50
+ def add nodechild, allows_children=true, &block
51
+ # calling TreeNode.add
52
+ $log.debug " XXX def add of DTM #{nodechild} to root "
53
+ node = @root.add nodechild, allows_children, &block
54
+ if @handler # only if someone is listening, won't fire when being prepared
55
+ tme = TreeModelEvent.new(row, row,:ALL_COLUMNS, self, :INSERT)
56
+ fire_handler :TREE_MODEL_EVENT, tme
57
+ end
58
+ #return @root
59
+ return node
60
+ end
61
+ def leaf node, &block
62
+ add node, false, &block
63
+ end
64
+ def branch node, &block
65
+ add node, true, &block
66
+ end
67
+ alias :<< :add
68
+ def insert row, obj
69
+ @data.insert row, obj
70
+ if @handler # only if someone is listening, won't fire when being prepared
71
+ tme = TreeModelEvent.new(row, row,:ALL_COLUMNS, self, :INSERT)
72
+ fire_handler :TREE_MODEL_EVENT, tme
73
+ end
74
+ def child_at parent, index
75
+ end
76
+ def index_of_child parent, child
77
+ end
78
+ def child_count node
79
+ node.children.size
80
+ end
81
+
82
+ def row_count
83
+ @data.length
84
+ end
85
+ #
86
+ def set_value_at row, col, val
87
+ # if editing allowed
88
+ raise "not yet used"
89
+ @data[row][col] = val
90
+ tme = TreeModelEvent.new(row, row, col, self, :UPDATE)
91
+ fire_handler :TREE_MODEL_EVENT, tme
92
+ end
93
+ ##
94
+ # please avoid directly hitting this. Suggested to use get_value_at of jtable
95
+ # since columns could have been switched.
96
+ def get_value_at row, col
97
+ raise "not yet used"
98
+ #$log.debug " def get_value_at #{row}, #{col} "
99
+
100
+ raise "IndexError get_value_at #{row}, #{col}" if @data.nil? or row >= @data.size
101
+ return @data[row][ col]
102
+ end
103
+ #def << obj
104
+ #@data << obj
105
+ #tme = TreeModelEvent.new(@data.length-1,@data.length-1, :ALL_COLUMNS, self, :INSERT)
106
+ #fire_handler :TREE_MODEL_EVENT, tme
107
+ #end
108
+ # create tablemodelevent and fire_table_changed for all listeners
109
+ end
110
+ def delete obj
111
+ raise "not yet used"
112
+ row = @data.index obj
113
+ return if row.nil?
114
+ ret = @data.delete obj
115
+ tme = TreeModelEvent.new(row, row,:ALL_COLUMNS, self, :DELETE)
116
+ fire_handler :TREE_MODEL_EVENT, tme
117
+ # create tablemodelevent and fire_table_changed for all listeners
118
+ return ret
119
+ end
120
+ def delete_at row
121
+ raise "not yet used"
122
+ if !$multiplier or $multiplier == 0
123
+ @delete_buffer = @data.delete_at row
124
+ else
125
+ @delete_buffer = @data.slice!(row, $multiplier)
126
+ end
127
+ $multiplier = 0
128
+ #ret = @data.delete_at row
129
+ # create tablemodelevent and fire_table_changed for all listeners
130
+ # we don;t pass buffer to event as in listeditable. how to undo later?
131
+ tme = TreeModelEvent.new(row, row+@delete_buffer.length,:ALL_COLUMNS, self, :DELETE)
132
+ fire_handler :TREE_MODEL_EVENT, tme
133
+ return @delete_buffer
134
+ end
135
+ # a quick method to undo deletes onto given row. More like paste
136
+ def undo where
137
+ raise "not yet used"
138
+ return unless @delete_buffer
139
+ case @delete_buffer[0]
140
+ when Array
141
+ @delete_buffer.each do |r|
142
+ insert where, r
143
+ end
144
+ else
145
+ insert where, @delete_buffer
146
+ end
147
+ end
148
+ ##
149
+ # added 2009-01-17 21:36
150
+ # Use with caution, does not call events per row
151
+ def delete_all
152
+ raise "not yet used"
153
+ len = @data.length-1
154
+ @data=[]
155
+ tme = TreeModelEvent.new(0, len,:ALL_COLUMNS, self, :DELETE)
156
+ fire_handler :TREE_MODEL_EVENT, tme
157
+ end
158
+ ##
159
+ # for those quick cases when you wish to replace all the data
160
+ # and not have an event per row being generated
161
+ def data=(data)
162
+ raise "not yet used"
163
+ raise "Data nil or invalid" if data.nil? or data.size == 0
164
+ delete_all
165
+ @data = data
166
+ tme = TreeModelEvent.new(0, @data.length-1,:ALL_COLUMNS, self, :INSERT)
167
+ fire_handler :TREE_MODEL_EVENT, tme
168
+ end
169
+ #def ask_search_forward
170
+ #regex = get_string "Enter regex to search for:"
171
+ #ix = get_list_data_model.find_match regex
172
+ #if ix.nil?
173
+ #alert("No matching data for: #{regex}")
174
+ #else
175
+ #set_focus_on(ix)
176
+ #end
177
+ #end
178
+ ## continues previous search
179
+ ###
180
+ #def find_match regex, ix0=0, ix1=row_count()
181
+ #$log.debug " find_match got #{regex} #{ix0} #{ix1}"
182
+ #@last_regex = regex
183
+ #@search_start_ix = ix0
184
+ #@search_end_ix = ix1
185
+ #@data.each_with_index do |row, ix|
186
+ #next if ix < ix0
187
+ #break if ix > ix1
188
+ #if row.grep(/#{regex}/) != []
189
+ ##if !row.match(regex).nil?
190
+ #@search_found_ix = ix
191
+ #return ix
192
+ #end
193
+ #end
194
+ #return nil
195
+ #end
196
+ #def find_prev regex=@last_regex, start = @search_found_ix
197
+ #raise "No previous search" if @last_regex.nil?
198
+ #$log.debug " find_prev #{@search_found_ix} : #{@current_index}"
199
+ #start -= 1 unless start == 0
200
+ #@last_regex = regex
201
+ #@search_start_ix = start
202
+ #start.downto(0) do |ix|
203
+ #row = @data[ix]
204
+ #if row.grep(/#{regex}/) != []
205
+ #@search_found_ix = ix
206
+ #return ix
207
+ #end
208
+ #end
209
+ #return nil
210
+ ##return find_match @last_regex, start, @search_end_ix
211
+ #end
212
+ ### dtm findnext
213
+ #def find_next
214
+ #raise "No more search" if @last_regex.nil?
215
+ #start = @search_found_ix && @search_found_ix+1 || 0
216
+ #return find_match @last_regex, start, @search_end_ix
217
+ #end
218
+ # just a test program
219
+ def traverse node=@root, level=0
220
+ icon = node.is_leaf? ? "-" : "+"
221
+ puts "%*s %s" % [ level+1, icon, node.user_object ]
222
+ node.children.each do |e|
223
+ traverse e, level+1
224
+ end
225
+ end
226
+ end # class DTM
227
+ # When an event is fired by TableModel, contents are changed, then this object will be passed
228
+ # to trigger
229
+ # type is :INSERT :UPDATE :DELETE :HEADER_ROW
230
+ # columns: number or :ALL_COLUMNS
231
+ class TreeModelEvent
232
+ attr_accessor :firstrow, :lastrow, :source, :type
233
+ def initialize firstrow, lastrow, source, type
234
+ @firstrow = firstrow
235
+ @lastrow = lastrow
236
+ @source = source
237
+ @type = type
238
+ end
239
+ def to_s
240
+ "#{@type.to_s}, firstrow: #{@firstrow}, lastrow: #{@lastrow}, source: #{@source}"
241
+ end
242
+ def inspect
243
+ to_s
244
+ end
245
+ end
246
+ class TreeNode
247
+ #extend Forwardable
248
+
249
+ attr_accessor :parent
250
+ attr_reader :children
251
+ attr_reader :user_object
252
+ attr_reader :allows_children
253
+ def initialize user_object=nil, allows_children=true, &block #form, config={}, &block
254
+ @allows_children = allows_children
255
+ @user_object = user_object
256
+ @children = []
257
+ #super
258
+ instance_eval &block if block_given?
259
+ init_vars
260
+ end
261
+ # private
262
+ #@return [TreeNode] just creates node
263
+ def _add node, allows_children=true, &block
264
+ #raise ArgumentError, "Argument should be a node" if !node.is_a? TreeNode
265
+ $log.debug " TODO remove from existing parent to avoid bugs XXX"
266
+ if !node.is_a? TreeNode
267
+ n = TreeNode.new node, allows_children, &block
268
+ node = n
269
+ end
270
+ node.parent = self
271
+ @children << node
272
+ node
273
+ end
274
+ # add a node to this node, optionally passing a block for further adding
275
+ # add a node as child to existing node
276
+ # If node is not a TreeNode it will be converted to one.
277
+ # @param [TreeNode, Array, Hash] node/s to add
278
+ # @param [boolean] should children be allowed
279
+ # @return [TreeNode] node last added (*NOT* self)
280
+ def add node, allows_children=true, &block
281
+ raise IllegalStateException, "Cannot add a child to this node" unless @allows_children
282
+ $log.debug " XXX def add of TreeNode #{node} parent #{self} "
283
+ case node
284
+ when Array
285
+ node.each do |e|
286
+ add e, allows_children, &block
287
+ end
288
+ when Hash
289
+ node.each_pair { |name, val|
290
+ n = _add name, allows_children, &block
291
+ n.add val, allows_children, &block
292
+ }
293
+ else
294
+ return _add node, allows_children, &block
295
+ end
296
+ self
297
+ end
298
+ def leaf node, &block
299
+ add node, false, &block
300
+ end
301
+ def branch node, &block
302
+ add node, true, &block
303
+ end
304
+ alias :<< :add
305
+ def insert node, index
306
+ raise ArgumentError, "Argument should be a node. it is #{node.class} " if !node.is_a? TreeNode
307
+ @children.insert index, node
308
+ self
309
+ end
310
+ def child_after node
311
+ end
312
+ def child_before node
313
+ end
314
+ def child_at node
315
+ end
316
+ def next_node node
317
+ end
318
+ def remove
319
+ end
320
+ def remove_all_children
321
+ end
322
+ def remove_from_parent
323
+ end
324
+ def is_leaf?
325
+ @children.size == 0
326
+ end
327
+ def leaf_count
328
+ end
329
+ def level
330
+ level = 0
331
+ nodeparent = parent()
332
+ while( nodeparent != nil )
333
+ level += 1
334
+ nodeparent = nodeparent.parent()
335
+ end
336
+ return level
337
+ end
338
+ def leaf_count
339
+ end
340
+ def traverse_up &block
341
+ nodeparent = parent()
342
+ while ( nodeparent != nil )
343
+ yield nodeparent
344
+ nodeparent = nodeparent.parent()
345
+ end
346
+ end
347
+ # returns an array of user_objects for the current node
348
+ # starting from root, ending in the current one. The last node
349
+ # represents this node.
350
+ # @return [Array] Strings[]
351
+ def user_object_path
352
+ arr = []
353
+ arr << self.user_object.to_s
354
+ traverse_up do |e|
355
+ arr << e.user_object.to_s
356
+ end
357
+ arr.reverse!
358
+ end
359
+ # returns an array of nodes for the current node
360
+ # starting from root, ending in the current one. The last node
361
+ # represents this node.
362
+ # @return [Array] TreeNode[]
363
+ def tree_path
364
+ arr = []
365
+ arr << self
366
+ traverse_up do |e|
367
+ arr << e
368
+ end
369
+ arr.reverse!
370
+ end
371
+ # http://github.com/evolve75/RubyTree/blob/master/lib/tree.rb
372
+ def breadth_each(max_depth=999,&block)
373
+ node_queue = [self] # Create a queue with self as the initial entry
374
+
375
+ # Use a queue to do breadth traversal
376
+ until node_queue.empty?
377
+ node_to_traverse = node_queue.shift
378
+ yield node_to_traverse
379
+ # Enqueue the children from left to right.
380
+ node_to_traverse.children { |child| node_queue.push child }
381
+ max_depth -= 1
382
+ break if max_depth == 0
383
+ end
384
+ end
385
+ def to_s
386
+ @user_object.to_s
387
+ end
388
+ def init_vars
389
+ @repaint_required = true
390
+ end
391
+ end
392
+ end # module
393
+
394
+ if $0 == __FILE__
395
+ $log = Logger.new("rbc13.log")
396
+ $log.level = Logger::DEBUG
397
+
398
+ include RubyCurses
399
+ root = TreeNode.new "ROOT"
400
+ subroot = TreeNode.new "subroot"
401
+ leaf1 = TreeNode.new "leaf 1"
402
+ leaf2 = TreeNode.new "leaf 2"
403
+
404
+ model = DefaultTreeModel.new root
405
+ #model.insert_node_into(subroot, root, 0)
406
+ #model.insert_node_into(leaf1, subroot, 0)
407
+ #model.insert_node_into(leaf2, subroot, 1)
408
+ root << subroot
409
+ # this will allow us to do a recursive add
410
+ #subroot << leaf1 << leaf2
411
+ subroot << leaf1
412
+ subroot << leaf2
413
+ leaf1 << "leaf11" << "leaf111"
414
+ leaf1 << "leaf12" << "leaf121"
415
+
416
+ root.add "blocky", true do
417
+ add "block2"
418
+ add "block3" do
419
+ add "block31"
420
+ end
421
+ end
422
+
423
+ model.traverse root
424
+ puts "tree path: ..."
425
+ puts leaf2.tree_path
426
+ puts "object path: ..."
427
+ puts leaf2.user_object_path
428
+ end