rbcurse 1.4.0 → 1.4.1.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/NOTES +68 -0
  2. data/README.markdown +73 -330
  3. data/TODO2.txt +2 -2
  4. data/VERSION +1 -1
  5. data/examples/abasiclist.rb +8 -2
  6. data/examples/alpmenu.rb +1 -1
  7. data/examples/app.rb +1 -24
  8. data/examples/appdirtree.rb +1 -1
  9. data/examples/appemail.rb +8 -14
  10. data/examples/appemaillb.rb +2 -2
  11. data/examples/appgcompose.rb +7 -5
  12. data/examples/common/file.rb +40 -0
  13. data/examples/{rmail.rb → common/rmail.rb} +0 -0
  14. data/examples/data/README.markdown +9 -0
  15. data/examples/data/brew.txt +38 -0
  16. data/examples/data/color.2 +37 -0
  17. data/examples/data/gemlist.txt +60 -0
  18. data/examples/data/lotr.txt +12 -0
  19. data/examples/data/ports.txt +136 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/{todocsv.csv → data/todocsv.csv} +0 -0
  22. data/examples/data/unix1.txt +21 -0
  23. data/examples/data/unix2.txt +11 -0
  24. data/examples/dbdemo.rb +49 -14
  25. data/examples/{appgmail.rb → deprecated/appgmail.rb} +1 -1
  26. data/examples/{splitp.rb → deprecated/splitp.rb} +0 -0
  27. data/examples/{testscrolllb.rb → deprecated/testscrolllb.rb} +0 -0
  28. data/examples/{testscrollp.rb → deprecated/testscrollp.rb} +0 -0
  29. data/examples/{testscrollta.rb → deprecated/testscrollta.rb} +0 -0
  30. data/examples/{testscrolltable.rb → deprecated/testscrolltable.rb} +0 -0
  31. data/examples/{testsplit.rb → deprecated/testsplit.rb} +0 -0
  32. data/examples/{testsplit2.rb → deprecated/testsplit2.rb} +0 -0
  33. data/examples/{testsplit3.rb → deprecated/testsplit3.rb} +0 -0
  34. data/examples/{testsplit3_1.rb → deprecated/testsplit3_1.rb} +0 -0
  35. data/examples/{testsplit3a.rb → deprecated/testsplit3a.rb} +0 -0
  36. data/examples/{testsplit3b.rb → deprecated/testsplit3b.rb} +0 -0
  37. data/examples/{testsplitta.rb → deprecated/testsplitta.rb} +0 -0
  38. data/examples/{testsplittv.rb → deprecated/testsplittv.rb} +0 -0
  39. data/examples/{testsplittvv.rb → deprecated/testsplittvv.rb} +0 -0
  40. data/examples/{testtpane.rb → deprecated/testtpane.rb} +0 -0
  41. data/examples/{testtpane2.rb → deprecated/testtpane2.rb} +0 -0
  42. data/examples/{testtpanetable.rb → deprecated/testtpanetable.rb} +0 -0
  43. data/examples/dirtree.rb +17 -7
  44. data/examples/experimental/resultsetdemo.rb +280 -0
  45. data/examples/experimental/testmform.rb +35 -0
  46. data/examples/{testscroller.rb → experimental/testscroller.rb} +1 -19
  47. data/examples/experimental/teststackflow.rb +111 -0
  48. data/examples/menu1.rb +1 -0
  49. data/examples/multispl.rb +4 -4
  50. data/examples/newmessagebox.rb +130 -0
  51. data/examples/newtabbedwindow.rb +100 -0
  52. data/examples/newtesttabp.rb +0 -3
  53. data/examples/qdfilechooser.rb +0 -3
  54. data/examples/rfe.rb +134 -18
  55. data/examples/rfe_renderer.rb +48 -2
  56. data/examples/sqlc.rb +2 -1
  57. data/examples/sqlm.rb +0 -2
  58. data/examples/table1.rb +1 -7
  59. data/examples/term2.rb +4 -1
  60. data/examples/test1.rb +0 -5
  61. data/examples/test2.rb +42 -31
  62. data/examples/testapp2.rb +8 -1
  63. data/examples/testchars.rb +0 -4
  64. data/examples/testcombo.rb +5 -9
  65. data/examples/testkeypress.rb +0 -3
  66. data/examples/testmenu.rb +0 -4
  67. data/examples/testmulticomp.rb +3 -5
  68. data/examples/testmulticontainer.rb +94 -0
  69. data/examples/testtable.rb +0 -5
  70. data/examples/testtabp.rb +16 -18
  71. data/examples/testtodo.rb +1 -5
  72. data/examples/testwsshortcuts.rb +64 -0
  73. data/examples/testwsshortcuts2.rb +126 -0
  74. data/examples/viewtodo.rb +1 -4
  75. data/lib/rbcurse.rb +1 -1
  76. data/lib/rbcurse/app.rb +92 -69
  77. data/lib/rbcurse/applicationheader.rb +46 -6
  78. data/lib/rbcurse/celleditor.rb +1 -9
  79. data/lib/rbcurse/comboboxcellrenderer.rb +0 -4
  80. data/lib/rbcurse/common/ansiparser.rb +117 -0
  81. data/{examples → lib/rbcurse/common}/appmethods.rb +25 -0
  82. data/lib/rbcurse/common/basestack.rb +407 -0
  83. data/lib/rbcurse/common/bordertitle.rb +41 -0
  84. data/lib/rbcurse/common/chunk.rb +177 -0
  85. data/lib/rbcurse/common/colorparser.rb +71 -0
  86. data/lib/rbcurse/common/keydefs.rb +30 -0
  87. data/lib/rbcurse/common/widgetshortcuts.rb +302 -0
  88. data/lib/rbcurse/deprecated/README.markdown +12 -0
  89. data/lib/rbcurse/{rscrollpane.rb → deprecated/rscrollpane.rb} +0 -0
  90. data/lib/rbcurse/{rsplitpane.rb → deprecated/rsplitpane.rb} +0 -0
  91. data/lib/rbcurse/{rsplitpane2.rb → deprecated/rsplitpane2.rb} +0 -0
  92. data/lib/rbcurse/{rviewport.rb → deprecated/rviewport.rb} +0 -0
  93. data/lib/rbcurse/experimental/README.markdown +14 -0
  94. data/lib/rbcurse/experimental/resultsettextview.rb +585 -0
  95. data/lib/rbcurse/experimental/stackflow.rb +478 -0
  96. data/lib/rbcurse/extras/bottomline.rb +85 -16
  97. data/lib/rbcurse/extras/box.rb +58 -0
  98. data/lib/rbcurse/extras/directorylist.rb +1 -1
  99. data/lib/rbcurse/extras/horizlist.rb +203 -0
  100. data/lib/rbcurse/extras/listselectable.rb +8 -0
  101. data/lib/rbcurse/extras/multiform.rb +330 -0
  102. data/lib/rbcurse/extras/multilinelabel.rb +142 -0
  103. data/lib/rbcurse/extras/newmessagebox.rb +328 -0
  104. data/lib/rbcurse/extras/newtabbedpane.rb +612 -0
  105. data/lib/rbcurse/extras/newtabbedwindow.rb +68 -0
  106. data/lib/rbcurse/extras/padreader.rb +189 -0
  107. data/lib/rbcurse/extras/rcomboedit.rb +256 -0
  108. data/lib/rbcurse/extras/resultsetbrowser.rb +281 -0
  109. data/lib/rbcurse/extras/statusline.rb +44 -6
  110. data/lib/rbcurse/extras/tabularwidget.rb +141 -104
  111. data/lib/rbcurse/extras/textpad.rb +516 -0
  112. data/lib/rbcurse/extras/viewer.rb +2 -0
  113. data/lib/rbcurse/io.rb +120 -3
  114. data/lib/rbcurse/listcellrenderer.rb +2 -1
  115. data/lib/rbcurse/listkeys.rb +1 -1
  116. data/lib/rbcurse/listscrollable.rb +72 -7
  117. data/lib/rbcurse/rbasiclistbox.rb +64 -12
  118. data/lib/rbcurse/rchangeevent.rb +0 -1
  119. data/lib/rbcurse/rcombo.rb +54 -59
  120. data/lib/rbcurse/rcommandwindow.rb +46 -10
  121. data/lib/rbcurse/rcontainer.rb +415 -0
  122. data/lib/rbcurse/rdialogs.rb +242 -165
  123. data/lib/rbcurse/rinputdataevent.rb +0 -1
  124. data/lib/rbcurse/rlistbox.rb +19 -9
  125. data/lib/rbcurse/rmessagebox.rb +1 -5
  126. data/lib/rbcurse/rmulticontainer.rb +64 -61
  127. data/lib/rbcurse/rmultitextview.rb +0 -2
  128. data/lib/rbcurse/rpopupmenu.rb +0 -2
  129. data/lib/rbcurse/rscrollform.rb +61 -12
  130. data/lib/rbcurse/rtabbedpane.rb +89 -73
  131. data/lib/rbcurse/rtabbedwindow.rb +53 -211
  132. data/lib/rbcurse/rtable.rb +0 -2
  133. data/lib/rbcurse/rtextarea.rb +14 -14
  134. data/lib/rbcurse/rtextview.rb +165 -50
  135. data/lib/rbcurse/rvimsplit.rb +15 -12
  136. data/lib/rbcurse/rwidget.rb +404 -150
  137. data/lib/rbcurse/table/tablecellrenderer.rb +1 -4
  138. data/lib/rbcurse/table/tabledatecellrenderer.rb +0 -3
  139. data/lib/ver/ncurses.rb +1 -9
  140. data/lib/ver/rpad.rb +375 -0
  141. data/lib/ver/window.rb +262 -440
  142. metadata +73 -31
@@ -0,0 +1,478 @@
1
+ =begin
2
+ * Name: stackflow.rb
3
+ A version of Container that uses stacks and flows and later grids
4
+ to place components
5
+ This is not a form. Thus it can be safely placed as a widget
6
+ without all the complicatinos of a form embedded inside another.
7
+ NOTE: Still experimental
8
+ * Description
9
+ * Author: rkumar (http://github.com/rkumar/rbcurse/)
10
+ * Date: 23.10.11 - 19:55
11
+ * License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
12
+
13
+ * Last update: 30.10.11 - 12:55
14
+
15
+ == CHANGES
16
+ Have moved most things out to a module ModStack, so this is sort of just
17
+ a skeletal container
18
+ x take care of margins
19
+ Resizing components
20
+ If window or container resized then redo the calc again.
21
+ Flow to have option of right to left orientation
22
+ == TODO
23
+ - If user specifies width, height then to be accounted when calculating weight. Also,
24
+ in such cases we must try not to overwrite h/w when calculating.
25
+ - changing an objects config not easy since it is stored in item, user may not have
26
+ handle to item
27
+ - weightx weighty
28
+ - RESET height only if expandable
29
+ - exceeding 100 will result in exceeding container.
30
+ - C-a C-e misbehaving in examples
31
+
32
+ =end
33
+
34
+ require 'rbcurse'
35
+ require 'rbcurse/common/bordertitle'
36
+ require 'rbcurse/common/basestack'
37
+
38
+ include RubyCurses
39
+ module RubyCurses
40
+ extend self
41
+
42
+ # This is a more advanced version of container
43
+ # which allows user to stack or flow components, including
44
+ # embedding stacks within flows and viceversa.
45
+
46
+
47
+ class StackFlow < Widget
48
+
49
+ include BorderTitle
50
+ include ModStack
51
+ # should container stack objects ignoring users row col
52
+ # this is esp needed since App sets row and col which is too early
53
+ # This is now the default value, till i can redo things
54
+ #dsl_accessor :stack
55
+ attr_reader :current_component
56
+ attr_reader :components
57
+
58
+ def initialize form=nil, config={}, &block
59
+ @suppress_borders = false
60
+ @row_offset = @col_offset = 1
61
+ @_events ||= []
62
+ @focusable = true
63
+ @editable = false
64
+ @components = [] # all components
65
+ @focusables = [] # focusable components, makes checks easier
66
+ @active = []
67
+ super
68
+
69
+ init_vars
70
+ end
71
+ def init_vars
72
+ @repaint_required = true
73
+ @row_offset = @col_offset = 0 if @suppress_borders
74
+ @ctr = 0
75
+
76
+ @internal_width = 2
77
+ @internal_width = 1 if @suppress_borders
78
+ @name ||= "a_stackflow"
79
+ bind_key(?\M-1, :increase_current)
80
+ bind_key(?\M-2, :decrease_current)
81
+ #raise "NO components !" if @components.empty?
82
+ calc_weightages2(@components, self) # FIXME this needs to move to basestack
83
+
84
+ end
85
+
86
+
87
+ # NOTE this is called by basestack so it cannot be here FIXME
88
+
89
+ # NOTE: since we are handling the traversal, we delink the object from any
90
+ # form's widgets array that might have been added. Whenever a form is available,
91
+ # we set it (without adding widget to it) so it can print using the form's window.
92
+ #
93
+ # @param [Widget] to add
94
+ private
95
+ def __add *items
96
+ items.each do |c|
97
+ raise ArgumentError, "Nil component passed to add" unless c
98
+ if c.is_a? Widget
99
+ if c.form && c.form != @form
100
+ $log.debug " removing widget VIMSPLIT #{c.class} wr: #{c.row} row:#{@row} ht:#{@height} "
101
+ c.form.remove_widget c
102
+ c.form = nil
103
+ # or should i just stack them myself and screw what you've asked for
104
+ end
105
+ # take it out of form's control. We will control it.
106
+ if c.form
107
+ c.form.remove_widget c
108
+ end
109
+ # shoot, what if at this point the container does not have a form
110
+ attach_form c if @form
111
+ end
112
+ # most likely if you have created both container and widgets
113
+ # inside app, it would have given row after container
114
+
115
+ #@components << c
116
+ if c.focusable
117
+ @focusables << c
118
+ @current_component ||= c # only the first else cursor falls on last on enter
119
+ end
120
+
121
+ end # items each
122
+ self
123
+ end
124
+
125
+ # When we get a form, we silently attach it to this object, without the form
126
+ # knowing. We don't want form managing this object.
127
+ def attach_form c
128
+ c.form = @form
129
+ c.override_graphic @graphic
130
+ c.parent_component = self
131
+ end
132
+ public
133
+ def widgets; @components; end
134
+ # what of by_name
135
+
136
+
137
+
138
+ # repaint object
139
+ # called by Form, and sometimes parent component (if not form).
140
+ def repaint # stackflow
141
+ my_win = @form ? @form.window : @target_window
142
+ @graphic = my_win unless @graphic
143
+ raise " #{@name} NO GRAPHIC set as yet RCONTAINER paint " unless @graphic
144
+ # actually at this level we don't have margins set -- not yet.
145
+ @margin_left ||= 0
146
+ @margin_right ||= 0
147
+ @margin_top ||= 0
148
+ @margin_bottom ||= 0
149
+ r = @row + @row_offset + @margin_top
150
+ c = @col + @col_offset + @margin_left
151
+ ht = @height-2-(@margin_top + @margin_bottom)
152
+ wd = @width -2-(@margin_left + @margin_right)
153
+ # should this not happen only if repaint_required ?
154
+ @components.each { |e|
155
+ e.parent_component = self
156
+ e.row = r
157
+ e.col = c
158
+ # check that we are not trying to print outside bounds
159
+ # by default we are stacking top level comps regardless of stack or flow
160
+ # otherwise too complicated
161
+ if e.is_a? BaseStack
162
+ # using ||= allows us to use overrides given by user
163
+ # but disallows us from calculating if size changes
164
+ e.height = (ht) * (e.weight * 0.01)
165
+ e.height = e.height.round
166
+ e.width = wd
167
+ if e.row + e.height >= @row + @height
168
+ #alert "is exceeding #{e.row} #{e.height} > #{@row} + #{@height} "
169
+ e.height = @height - e.row - 1
170
+ end
171
+ r += e.height
172
+ $log.debug "XXX: STACK r:#{e.row} e.h: #{e.height} w:#{e.weight} h: #{@height} "
173
+ #if e.type == :flow
174
+ #e.height ||= (@height-2) * (e.weight * 0.01)
175
+ #e.height = e.height.round
176
+ #e.width ||= (@width-2)
177
+ #r += e.height
178
+ #elsif e.type == :stack
179
+ #e.width ||= (@width-2) * (e.weight * 0.01)
180
+ #e.width = e.width.round
181
+ #e.height ||= (@height-2)
182
+ #c += e.width
183
+ #end
184
+ end
185
+ check_coords e
186
+ attach_form e unless e.form
187
+ } # seeme one if printing out
188
+ last = @components.last
189
+ if last.row + last.height < @row + @height
190
+ last.height += 1 # @row + @height - last.row + last.height
191
+ end
192
+
193
+ # if some major change has happened then repaint everything
194
+ # if multiple components then last row and col needs to be stored or else overlap will happen FIXME
195
+ if @repaint_required
196
+ $log.debug " CONT2 repaint graphic #{@graphic}, size:#{@components.size} "
197
+ print_borders unless @suppress_borders # do this once only, unless everything changes
198
+ @components.each { |e| e.repaint_all(true); e.repaint }
199
+ else
200
+ @components.each { |e| e.repaint }
201
+ end # if repaint_required
202
+
203
+ @repaint_required = false
204
+ end
205
+
206
+ private
207
+ def check_coords e # container
208
+ r = e.row
209
+ c = e.col
210
+ if r >= @row + @height
211
+ $log.warn "XXX: WARN #{e.class} is out of bounds row #{r} "
212
+ e.visible = false
213
+ end
214
+ if c >= @col + @width
215
+ $log.warn "XXX: WARN #{e.class} is out of bounds col #{c} "
216
+ e.visible = false
217
+ end
218
+ if e.row + e.height >= @height
219
+ $log.warn "XXX: WARN #{e.class} is out of bounds row #{e.row} + h #{e.height} >= #{@height} "
220
+ #e.visible = false
221
+ end
222
+ if e.col + e.width >= @width
223
+ $log.warn "XXX: WARN #{e.class} is out of bounds col #{e.col} + w #{e.width} >= #{@width} "
224
+ #e.visible = false
225
+ end
226
+ end
227
+
228
+ public
229
+ # called by parent or form, otherwise its private
230
+ def handle_key ch
231
+ $log.debug " RCONTAINER handle_key #{ch} "
232
+ return if @components.empty?
233
+ _multiplier = ($multiplier == 0 ? 1 : $multiplier )
234
+
235
+ # should this go here 2011-10-19
236
+ unless @_entered
237
+ $log.warn "XXX WARN: calling ON_ENTER since in this situation it was not called"
238
+ on_enter
239
+ end
240
+ if ch == KEY_TAB
241
+ $log.debug "RCONTAINER GOTO NEXT TAB"
242
+ return goto_next_component
243
+ elsif ch == KEY_BTAB
244
+ return goto_prev_component
245
+ end
246
+ comp = @current_component
247
+ $log.debug " RCONTAINER handle_key #{ch}: #{comp}"
248
+ if comp
249
+ ret = comp.handle_key(ch)
250
+ $log.debug " RCONTAINER handle_key#{ch}: #{comp} returned #{ret} "
251
+ if ret != :UNHANDLED
252
+ comp.repaint # NOTE: if we don;t do this, then it won't get repainted. I will have to repaint ALL
253
+ # in repaint of this.
254
+ return ret
255
+ end
256
+ $log.debug "XXX RCONTAINER key unhandled by comp #{comp.name} "
257
+ else
258
+ $log.warn "XXX RCONTAINER key unhandled NULL comp"
259
+ end
260
+ case ch
261
+ when ?\C-c.getbyte(0)
262
+ $multiplier = 0
263
+ return 0
264
+ when ?0.getbyte(0)..?9.getbyte(0)
265
+ $log.debug " VIM coming here to set multiplier #{$multiplier} "
266
+ $multiplier *= 10 ; $multiplier += (ch-48)
267
+ return 0
268
+ end
269
+ ret = process_key ch, self
270
+ # allow user to map left and right if he wants
271
+ if ret == :UNHANDLED
272
+ case ch
273
+ when KEY_UP
274
+ # form will pick this up and do needful
275
+ return goto_prev_component #unless on_first_component?
276
+ when KEY_LEFT
277
+ # if i don't check for first component, key will go back to form,
278
+ # but not be processes. so focussed remain here, but be false.
279
+ # In case of returnign an unhandled TAB, on_leave will happen and cursor will move to
280
+ # previous component outside of this.
281
+ return goto_prev_component unless on_first_component?
282
+ when KEY_RIGHT
283
+ return goto_next_component #unless on_last_component?
284
+ when KEY_DOWN
285
+ return goto_next_component #unless on_last_component?
286
+ else
287
+ @_entered = false
288
+ return :UNHANDLED
289
+ end
290
+ end
291
+
292
+ $multiplier = 0
293
+ return 0
294
+ end
295
+ # Actually we should only go to current component if it accepted
296
+ # a key stroke. if user tabbed thru it, then no point going back to
297
+ # it. Go to first or last depending on TAB or BACKTAB otherwise.
298
+ # NOTE: if user comes in using DOWN or UP, last traversed component will get the focus
299
+ #
300
+ def on_enter
301
+ # if BTAB, the last comp XXX they must be focusable FIXME
302
+ if $current_key == KEY_BTAB || $current_key == KEY_UP
303
+ @current_component = @focusables.last
304
+ elsif $current_key == KEY_TAB || $current_key == KEY_DOWN
305
+ @current_component = @focusables.first
306
+ else
307
+ # let current component be, since an unhandled key may have resulted
308
+ # in on_enter being called again
309
+ end
310
+ return unless @current_component
311
+ $log.debug " RCONTAINER came to ON_ENTER #{@current_component} "
312
+ set_form_row
313
+ @_entered = true
314
+ end
315
+ # we cannot be sure that this will be called especially if this is embedded
316
+ # inside some other component
317
+ def on_leave
318
+ @_entered = false
319
+ super
320
+ end
321
+ def goto_next_component
322
+ if @current_component != nil
323
+ leave_current_component
324
+ if on_last_component?
325
+ #@_entered = false
326
+ return :UNHANDLED
327
+ end
328
+ @current_index = @focusables.index(@current_component)
329
+ index = @current_index + 1
330
+ f = @focusables[index]
331
+ if f
332
+ @current_index = index
333
+ @current_component = f
334
+ return set_form_row
335
+ end
336
+ end
337
+ @_entered = false
338
+ return :UNHANDLED
339
+ end
340
+ def goto_prev_component
341
+ if @current_component != nil
342
+ leave_current_component
343
+ if on_first_component?
344
+ @_entered = false
345
+ return :UNHANDLED
346
+ end
347
+ @current_index = @focusables.index(@current_component)
348
+ index = @current_index -= 1
349
+ f = @focusables[index]
350
+ if f
351
+ @current_index = index
352
+ @current_component = f
353
+ return set_form_row
354
+ end
355
+ end
356
+ return :UNHANDLED
357
+ end
358
+ # private
359
+ # XXX why are we calling 3 methods in a row, why not OE manages these 3
360
+ # There's double calling going on.
361
+ def set_form_row
362
+ return :UNHANDLED if @current_component.nil?
363
+ cc = @current_component
364
+ $log.debug "CONT #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} "
365
+ $log.debug " RCONTAINER on enter sfr #{@current_component.name} #{@current_component} "
366
+
367
+ @current_component.on_enter
368
+ @current_component.set_form_row # why was this missing in vimsplit. is it
369
+ $log.debug "CONT2 #{@name} set_form_row calling sfr for #{cc.name}, r #{cc.row} c: #{cc.col} "
370
+ # that on_enter does a set_form_row
371
+ @current_component.set_form_col # XXX
372
+ @current_component.repaint # OMG this could happen before we've set row and col
373
+ # XXX compo should do set_form_row and col if it has that
374
+ end
375
+ #
376
+ def set_form_col
377
+ # override widget
378
+ end
379
+ # leave the component we are on.
380
+ # This should be followed by all containers, so that the on_leave action
381
+ # of earlier comp can be displayed, such as dimming components selections
382
+ def leave_current_component
383
+ begin
384
+ @current_component.on_leave
385
+ rescue FieldValidationException => fve
386
+ alert fve.to_s
387
+ end
388
+ # NOTE this is required, since repaint will just not happen otherwise
389
+ # Some components are erroneously repainting all, after setting this to true so it is
390
+ # working there.
391
+ @current_component.repaint_required true
392
+ $log.debug " after on_leave RCONT XXX #{@current_component.focussed} #{@current_component.name}"
393
+ @current_component.repaint
394
+ end
395
+
396
+ # is focus on first component FIXME check for focusable
397
+ def on_first_component?
398
+ @current_component == @focusables.first
399
+ end
400
+ # is focus on last component FIXME check for focusable
401
+ def on_last_component?
402
+ @current_component == @focusables.last
403
+ end
404
+ # set focus on given component
405
+ # Sometimes you have the handle to component, and you want to move focus to it
406
+ def goto_component comp
407
+ return if comp == @current_component
408
+ leave_current_component
409
+ @current_component = comp
410
+ set_form_row
411
+ end
412
+
413
+ def increase_current
414
+ c = @current_component
415
+ p = c.config[:parent]
416
+ $log.debug "XXX: INC increase current #{c} , #{p} "
417
+ p.increase c
418
+ end
419
+ def decrease_current
420
+ c = @current_component
421
+ p = c.config[:parent]
422
+ $log.debug "XXX: INC increase current #{c} , #{p} "
423
+ p.decrease c
424
+ end
425
+ # ADD HERE ABOVe
426
+ end # class
427
+
428
+ end # module
429
+
430
+ # NOTE this is now giving an error ni basestack.rb 87 reg margin_top.
431
+ # @see teststackflow.rb in examples dir
432
+ #
433
+ if __FILE__ == $PROGRAM_NAME
434
+ require 'rbcurse/app'
435
+ App.new do
436
+
437
+ lb = Listbox.new nil, :list => ["ruby","perl","lisp","jaava", "c-blunt"] , :name => "mylist"
438
+ lb1 = Listbox.new nil, :list => ["roger","borg","haas","tsonga", "kolya","delpotro"] , :name => "mylist1"
439
+
440
+ lb2 = Listbox.new nil, :list => `gem list --local`.split("\n") , :name => "mylist2"
441
+
442
+ alist = %w[ ruby perl python java jruby macruby rubinius rails rack sinatra pylons django cakephp grails]
443
+ str = "Hello people of this world.\nThis is a textbox.\nUse arrow keys, j/k/h/l/gg/G/C-a/C-e/C-n/C-p\n"
444
+ str << alist.join("\n")
445
+ require 'rbcurse/rtextview'
446
+ tv = TextView.new nil, :name => "text"
447
+ tv.set_content str
448
+ =begin
449
+ f1 = field "name", :maxlen => 20, :display_length => 20, :bgcolor => :white,
450
+ :color => :black, :text => "abc", :label => " Name: ", :label_color_pair => @datacolor
451
+ f2 = field "email", :display_length => 20, :bgcolor => :white,
452
+ :color => :blue, :text => "me@google.com", :label => "Email: ", :label_color_pair => @datacolor
453
+ f3 = radio :group => :grp, :text => "red", :value => "RED", :color => :red
454
+ f4 = radio :group => :grp, :text => "blue", :value => "BLUE", :color => :blue
455
+ f5 = radio :group => :grp, :text => "green", :value => "GREEN", :color => :green
456
+ =end
457
+
458
+ f1 = Field.new nil, :maxlen => 20, :display_length => 20, :bgcolor => :white,
459
+ :color => :black, :text => "abc", :label => " Name: ", :label_color_pair => @datacolor
460
+ r = StackFlow.new @form, :row => 1, :col => 2, :width => 80, :height => 25, :title => "A container" do
461
+ stack :margin_left => 1 do
462
+ add tv, :weight => 30, :margin_left => 2
463
+ add lb, :weight => 30
464
+ flow :weight => 30 do
465
+ add lb1, :weight => 40
466
+ add lb2, :weight => 60
467
+ end
468
+ add f1
469
+ end # stack
470
+ end # r
471
+
472
+ #r.add(f1)
473
+ #r.add(f2)
474
+ #r.add(f3,f4,f5)
475
+ #sl = status_line
476
+
477
+ end # app
478
+ end # if