rbcurse 1.1.5 → 1.2.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/CHANGELOG +45 -0
  2. data/Makefile +1 -1
  3. data/Manifest.txt +91 -0
  4. data/NOTES +349 -2
  5. data/README.markdown +12 -0
  6. data/VERSION +1 -1
  7. data/examples/abasiclist.rb +25 -0
  8. data/examples/alpmenu.rb +42 -0
  9. data/examples/app.rb +883 -0
  10. data/examples/appcombo.rb +17 -0
  11. data/examples/appdirtree.rb +73 -0
  12. data/examples/appemail.rb +164 -0
  13. data/examples/appemaillb.rb +308 -0
  14. data/examples/appgcompose.rb +303 -0
  15. data/examples/appgmail.rb +951 -0
  16. data/examples/atree.rb +56 -0
  17. data/examples/dirtree.rb +78 -0
  18. data/examples/focusmanager.rb +31 -0
  19. data/examples/imap.rb +48 -0
  20. data/examples/menu1.rb +79 -0
  21. data/examples/multispl.rb +86 -0
  22. data/examples/rfe.rb +3 -4
  23. data/examples/rmail.rb +188 -0
  24. data/examples/s.rb +10 -0
  25. data/examples/scrollbar.rb +104 -0
  26. data/examples/splitp.rb +56 -0
  27. data/examples/table1.rb +30 -0
  28. data/examples/term.rb +48 -0
  29. data/examples/term2.rb +54 -0
  30. data/examples/test1.rb +4 -2
  31. data/examples/test2.rb +9 -9
  32. data/examples/testapp.rb +44 -0
  33. data/examples/testapp2.rb +51 -0
  34. data/examples/testcombo.rb +2 -2
  35. data/examples/testgmail.rb +46 -0
  36. data/examples/testlistbox.rb +0 -1
  37. data/examples/testmultispl.rb +199 -0
  38. data/examples/testree.rb +127 -0
  39. data/examples/testscroller.rb +0 -1
  40. data/examples/testscrolllb.rb +1 -1
  41. data/examples/testscrollp.rb +2 -1
  42. data/examples/testscrollta.rb +1 -1
  43. data/examples/testscrolltable.rb +1 -2
  44. data/examples/testsplit.rb +1 -1
  45. data/examples/testsplit2.rb +1 -1
  46. data/examples/testsplit3.rb +1 -1
  47. data/examples/testsplit3_1.rb +1 -1
  48. data/examples/testsplit3a.rb +1 -1
  49. data/examples/testsplit3b.rb +1 -1
  50. data/examples/testsplitta.rb +1 -1
  51. data/examples/testsplittv.rb +1 -1
  52. data/examples/testsplittvv.rb +1 -1
  53. data/examples/testtodo.rb +491 -488
  54. data/examples/testvimsplit.rb +111 -0
  55. data/examples/todo.db +0 -0
  56. data/examples/todocsv.csv +28 -0
  57. data/examples/viewtodo.rb +408 -403
  58. data/lib/rbcurse/action.rb +1 -0
  59. data/lib/rbcurse/app.rb +1294 -0
  60. data/lib/rbcurse/applicationheader.rb +7 -2
  61. data/lib/rbcurse/checkboxcellrenderer.rb +0 -12
  62. data/lib/rbcurse/colormap.rb +34 -8
  63. data/lib/rbcurse/comboboxcellrenderer.rb +0 -11
  64. data/lib/rbcurse/defaultlistselectionmodel.rb +23 -7
  65. data/lib/rbcurse/extras/bottomline.rb +1681 -0
  66. data/lib/rbcurse/extras/directorylist.rb +445 -0
  67. data/lib/rbcurse/extras/directorytree.rb +69 -0
  68. data/lib/rbcurse/extras/divider.rb +310 -0
  69. data/lib/rbcurse/extras/focusmanager.rb +31 -0
  70. data/lib/rbcurse/extras/listselectable.rb +222 -0
  71. data/lib/rbcurse/extras/masterdetail.rb +164 -0
  72. data/lib/rbcurse/extras/menutree.rb +63 -0
  73. data/lib/rbcurse/extras/rlink.rb +27 -0
  74. data/lib/rbcurse/extras/rmenulink.rb +21 -0
  75. data/lib/rbcurse/extras/scrollbar.rb +134 -0
  76. data/lib/rbcurse/extras/stdscrwindow.rb +247 -0
  77. data/lib/rbcurse/extras/tabular.rb +258 -0
  78. data/lib/rbcurse/extras/tabularwidget.rb +1070 -0
  79. data/lib/rbcurse/extras/viewer.rb +106 -0
  80. data/lib/rbcurse/io.rb +137 -80
  81. data/lib/rbcurse/keylabelprinter.rb +4 -0
  82. data/lib/rbcurse/listcellrenderer.rb +91 -59
  83. data/lib/rbcurse/listscrollable.rb +93 -95
  84. data/lib/rbcurse/listselectable.rb +60 -7
  85. data/lib/rbcurse/ractionevent.rb +67 -0
  86. data/lib/rbcurse/rbasiclistbox.rb +688 -0
  87. data/lib/rbcurse/rcombo.rb +5 -5
  88. data/lib/rbcurse/rcommandwindow.rb +555 -0
  89. data/lib/rbcurse/rinputdataevent.rb +12 -0
  90. data/lib/rbcurse/rlistbox.rb +305 -124
  91. data/lib/rbcurse/rmenu.rb +99 -46
  92. data/lib/rbcurse/rmessagebox.rb +13 -6
  93. data/lib/rbcurse/rmulticontainer.rb +54 -93
  94. data/lib/rbcurse/rmultisplit.rb +731 -0
  95. data/lib/rbcurse/rmultitextview.rb +3 -2
  96. data/lib/rbcurse/rpopupmenu.rb +0 -1
  97. data/lib/rbcurse/rprogress.rb +117 -0
  98. data/lib/rbcurse/rscrollpane.rb +2 -1
  99. data/lib/rbcurse/rsplitpane.rb +94 -20
  100. data/lib/rbcurse/rsplitpane2.rb +1009 -0
  101. data/lib/rbcurse/rtabbedpane.rb +3 -2
  102. data/lib/rbcurse/rtabbedwindow.rb +0 -1
  103. data/lib/rbcurse/rtable.rb +92 -64
  104. data/lib/rbcurse/rtextarea.rb +91 -57
  105. data/lib/rbcurse/rtextview.rb +223 -70
  106. data/lib/rbcurse/rtree.rb +723 -0
  107. data/lib/rbcurse/rviewport.rb +2 -1
  108. data/lib/rbcurse/rvimsplit.rb +768 -0
  109. data/lib/rbcurse/rwidget.rb +524 -325
  110. data/lib/rbcurse/table/tablecellrenderer.rb +1 -1
  111. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -1
  112. data/lib/rbcurse/tree/treecellrenderer.rb +137 -0
  113. data/lib/rbcurse/tree/treemodel.rb +428 -0
  114. data/lib/rbcurse/vieditable.rb +14 -13
  115. data/lib/ver/ncurses.rb +6 -0
  116. data/lib/ver/window.rb +67 -32
  117. metadata +99 -23
  118. data/bin/rbcurse +0 -0
  119. data/examples/rvimsplit.rb +0 -376
  120. data/examples/todo.rb +0 -1
  121. data/lib/rbcurse/rform.rb +0 -845
  122. data/lib/rbcurse/selectable.rb +0 -94
  123. data/rbcurse.gemspec +0 -188
@@ -3,7 +3,7 @@ require 'ncurses'
3
3
  require 'logger'
4
4
  module RubyCurses
5
5
  class TableCellRenderer
6
- include DSL
6
+ #include DSL
7
7
  #include EventHandler
8
8
  include ConfigSetup
9
9
  include RubyCurses::Utils
@@ -3,7 +3,6 @@ require 'ncurses'
3
3
  require 'logger'
4
4
  module RubyCurses
5
5
  class TableDateCellRenderer
6
- include DSL
7
6
  #include EventHandler
8
7
  include ConfigSetup
9
8
  include RubyCurses::Utils
@@ -0,0 +1,137 @@
1
+ # 2010-09-18 15:35
2
+ require 'rbcurse'
3
+ require 'rbcurse/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
+
24
+ def initialize text="", config={}, &block
25
+ @text = text
26
+ @editable = false
27
+ @focusable = false
28
+ config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
29
+ instance_eval &block if block_given?
30
+ init_vars
31
+ end
32
+ def init_vars
33
+ @justify ||= :left
34
+ @display_length ||= 10
35
+ end
36
+ def getvalue
37
+ @text
38
+ end
39
+ ##
40
+ # sets @color_pair and @attr
41
+ def prepare_default_colors focussed, selected
42
+ @color_pair = get_color $datacolor
43
+ @attr = @row_attr || Ncurses::A_NORMAL
44
+
45
+
46
+ ## determine bg and fg and attr
47
+ if selected
48
+ #@attr = Ncurses::A_BOLD if selected
49
+ ## 2010-09-18 18:32 making selected row reverse
50
+ @attr |= Ncurses::A_REVERSE
51
+
52
+ # 2010-09-18 18:33 maybe not required, just confuses the whole thing and uglifies it
53
+ #@color_pair =get_color $selectedcolor, @parent.selected_color, @parent.selected_bgcolor unless @parent.nil?
54
+ end
55
+ case focussed
56
+ when :SOFT_FOCUS
57
+ @attr |= Ncurses::A_BOLD
58
+ when true
59
+ # earlier focussed row showed up in reverse, which was confusing since it looked selected
60
+ # now focussed row has cursor on side, and can be bold. that's enough.
61
+ @attr |= Ncurses::A_BOLD
62
+ #@attr |= Ncurses::A_REVERSE
63
+ when false
64
+ end
65
+ end
66
+
67
+ ##
68
+ # paint a list box cell
69
+ # 2010-09-02 15:38 changed focussed to take true, false and :SOFT_FOCUS
70
+ # SOFT_FOCUS means the form focus is no longer on this field, but this row
71
+ # was focussed when use was last on this field. This row will take focus
72
+ # when field is focussed again
73
+ #
74
+ # @param [Buffer] window or buffer object used for printing
75
+ # @param [Fixnum] row
76
+ # @param [Fixnum] column
77
+ # @param [Fixnum] actual index into data, some lists may have actual data elsewhere and
78
+ # display data separate. e.g. rfe_renderer (directory listing)
79
+ # @param [String] text to print in cell
80
+ # @param [Boolean, :SOFT_FOCUS] cell focussed, not focussed, cell focussed but field is not focussed
81
+ # @param [Boolean] cell selected or not
82
+ #renderer.repaint @graphic, r+hh, c+@left_margin, crow, object, content, focus_type, selected, expanded, leaf
83
+ def repaint graphic, r=@row,c=@col, row_index=-1, treearraynode=nil, value=@text, leaf=nil, focussed=false, selected=false, expanded=false
84
+ #$log.debug "label :#{@text}, #{value}, #{r}, #{c} col= #{@color}, #{@bgcolor} acolor= #{acolor} j:#{@justify} dlL: #{@display_length} "
85
+
86
+ prepare_default_colors focussed, selected
87
+
88
+ value=value.to_s # ??
89
+ if @height && @height > 1
90
+ else
91
+ # ensure we do not exceed
92
+ if !@display_length.nil?
93
+ if value.length > @display_length
94
+ value = value[0..@display_length-1]
95
+ end
96
+ end
97
+ #lablist << value
98
+ end
99
+ len = @display_length || value.length
100
+ #icon = object.is_leaf? ? "-" : "+"
101
+ #icon = leaf ? "-" : "+"
102
+
103
+ #level = treearraynode.level
104
+ #node = treearraynode.node
105
+ level = treearraynode.level
106
+ node = treearraynode
107
+ if parent.node_expanded? node
108
+ icon = PLUS_MINUS # can collapse
109
+ else
110
+ icon = PLUS_PLUS # can expand
111
+ end
112
+ if node.children.size == 0
113
+ icon = PLUS_Q # either no children or not visited yet
114
+ if parent.has_been_expanded node
115
+ icon = PLUS_MINUS # definitely no children, we've visited
116
+ end
117
+ end
118
+ # adding 2 to level, that's the size of icon
119
+ _value = "%*s %s" % [ level+2, icon, node.user_object ]
120
+ graphic.printstring r, c, "%-*s" % [len, _value], @color_pair,@attr
121
+ #_height = @height || 1
122
+ #0.upto(_height-1) { |i|
123
+ #graphic.printstring r+i, c, ( " " * len) , @color_pair,@attr
124
+ #}
125
+ #lablist.each_with_index do |_value, ix|
126
+ #break if ix >= _height
127
+ #if @justify.to_sym == :center
128
+ #padding = (@display_length - _value.length)/2
129
+ #_value = " "*padding + _value + " "*padding # so its cleared if we change it midway
130
+ #end
131
+ #graphic.printstring r, c, str % [len, _value], @color_pair,@attr
132
+ #r += 1
133
+ #end
134
+ end
135
+ # ADD HERE
136
+ end
137
+ 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 'rbcurse'
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("view.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