rbcurse-core 0.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 (94) hide show
  1. data/README.md +69 -0
  2. data/VERSION +1 -0
  3. data/examples/abasiclist.rb +151 -0
  4. data/examples/alpmenu.rb +46 -0
  5. data/examples/app.sample +17 -0
  6. data/examples/atree.rb +100 -0
  7. data/examples/common/file.rb +45 -0
  8. data/examples/data/README.markdown +9 -0
  9. data/examples/data/brew.txt +38 -0
  10. data/examples/data/color.2 +37 -0
  11. data/examples/data/gemlist.txt +60 -0
  12. data/examples/data/lotr.txt +12 -0
  13. data/examples/data/ports.txt +136 -0
  14. data/examples/data/table.txt +37 -0
  15. data/examples/data/tasks.csv +88 -0
  16. data/examples/data/tasks.txt +27 -0
  17. data/examples/data/todo.txt +10 -0
  18. data/examples/data/todocsv.csv +28 -0
  19. data/examples/data/unix1.txt +21 -0
  20. data/examples/data/unix2.txt +11 -0
  21. data/examples/dbdemo.rb +487 -0
  22. data/examples/dirtree.rb +90 -0
  23. data/examples/newtabbedwindow.rb +100 -0
  24. data/examples/newtesttabp.rb +92 -0
  25. data/examples/tabular.rb +132 -0
  26. data/examples/tasks.rb +167 -0
  27. data/examples/term2.rb +83 -0
  28. data/examples/testkeypress.rb +72 -0
  29. data/examples/testlistbox.rb +158 -0
  30. data/examples/testmessagebox.rb +140 -0
  31. data/examples/testree.rb +106 -0
  32. data/examples/testwsshortcuts.rb +66 -0
  33. data/examples/testwsshortcuts2.rb +127 -0
  34. data/lib/rbcurse.rb +8 -0
  35. data/lib/rbcurse/core/docs/index.txt +73 -0
  36. data/lib/rbcurse/core/include/action.rb +40 -0
  37. data/lib/rbcurse/core/include/appmethods.rb +112 -0
  38. data/lib/rbcurse/core/include/bordertitle.rb +41 -0
  39. data/lib/rbcurse/core/include/chunk.rb +182 -0
  40. data/lib/rbcurse/core/include/io.rb +953 -0
  41. data/lib/rbcurse/core/include/listcellrenderer.rb +140 -0
  42. data/lib/rbcurse/core/include/listeditable.rb +317 -0
  43. data/lib/rbcurse/core/include/listscrollable.rb +590 -0
  44. data/lib/rbcurse/core/include/listselectable.rb +264 -0
  45. data/lib/rbcurse/core/include/multibuffer.rb +83 -0
  46. data/lib/rbcurse/core/include/orderedhash.rb +77 -0
  47. data/lib/rbcurse/core/include/ractionevent.rb +67 -0
  48. data/lib/rbcurse/core/include/rchangeevent.rb +27 -0
  49. data/lib/rbcurse/core/include/rhistory.rb +62 -0
  50. data/lib/rbcurse/core/include/rinputdataevent.rb +47 -0
  51. data/lib/rbcurse/core/include/vieditable.rb +170 -0
  52. data/lib/rbcurse/core/system/colormap.rb +163 -0
  53. data/lib/rbcurse/core/system/keyboard.rb +150 -0
  54. data/lib/rbcurse/core/system/keydefs.rb +30 -0
  55. data/lib/rbcurse/core/system/ncurses.rb +218 -0
  56. data/lib/rbcurse/core/system/panel.rb +162 -0
  57. data/lib/rbcurse/core/system/window.rb +901 -0
  58. data/lib/rbcurse/core/util/ansiparser.rb +117 -0
  59. data/lib/rbcurse/core/util/app.rb +1235 -0
  60. data/lib/rbcurse/core/util/basestack.rb +407 -0
  61. data/lib/rbcurse/core/util/bottomline.rb +1850 -0
  62. data/lib/rbcurse/core/util/colorparser.rb +71 -0
  63. data/lib/rbcurse/core/util/focusmanager.rb +31 -0
  64. data/lib/rbcurse/core/util/padreader.rb +189 -0
  65. data/lib/rbcurse/core/util/rcommandwindow.rb +587 -0
  66. data/lib/rbcurse/core/util/rdialogs.rb +619 -0
  67. data/lib/rbcurse/core/util/viewer.rb +149 -0
  68. data/lib/rbcurse/core/util/widgetshortcuts.rb +505 -0
  69. data/lib/rbcurse/core/widgets/applicationheader.rb +102 -0
  70. data/lib/rbcurse/core/widgets/box.rb +58 -0
  71. data/lib/rbcurse/core/widgets/divider.rb +310 -0
  72. data/lib/rbcurse/core/widgets/keylabelprinter.rb +178 -0
  73. data/lib/rbcurse/core/widgets/rcombo.rb +238 -0
  74. data/lib/rbcurse/core/widgets/rcontainer.rb +415 -0
  75. data/lib/rbcurse/core/widgets/rlink.rb +30 -0
  76. data/lib/rbcurse/core/widgets/rlist.rb +723 -0
  77. data/lib/rbcurse/core/widgets/rmenu.rb +939 -0
  78. data/lib/rbcurse/core/widgets/rmenulink.rb +22 -0
  79. data/lib/rbcurse/core/widgets/rmessagebox.rb +373 -0
  80. data/lib/rbcurse/core/widgets/rprogress.rb +118 -0
  81. data/lib/rbcurse/core/widgets/rtabbedpane.rb +615 -0
  82. data/lib/rbcurse/core/widgets/rtabbedwindow.rb +68 -0
  83. data/lib/rbcurse/core/widgets/rtextarea.rb +920 -0
  84. data/lib/rbcurse/core/widgets/rtextview.rb +780 -0
  85. data/lib/rbcurse/core/widgets/rtree.rb +787 -0
  86. data/lib/rbcurse/core/widgets/rwidget.rb +3040 -0
  87. data/lib/rbcurse/core/widgets/scrollbar.rb +143 -0
  88. data/lib/rbcurse/core/widgets/statusline.rb +94 -0
  89. data/lib/rbcurse/core/widgets/tabular.rb +264 -0
  90. data/lib/rbcurse/core/widgets/tabularwidget.rb +1211 -0
  91. data/lib/rbcurse/core/widgets/textpad.rb +516 -0
  92. data/lib/rbcurse/core/widgets/tree/treecellrenderer.rb +150 -0
  93. data/lib/rbcurse/core/widgets/tree/treemodel.rb +428 -0
  94. metadata +156 -0
@@ -0,0 +1,615 @@
1
+ =begin
2
+ * Name: newtabbedpane.rb
3
+ * Description : This is radically simplified tabbedpane. The earlier version
4
+ was too complex with multiple forms and pads, and a scrollform. This uses
5
+ the external form and has some very simple programming to handle the whole thing.
6
+ * Author: rkumar (http://github.com/rkumar/rbcurse/)
7
+ * Date: 2011-10-20
8
+ * License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
9
+ * Last update: Sat Oct 22 18:40:49 IST 2011
10
+
11
+ == CHANGES
12
+ As of 1.5.0, this replaces the earlier TabbedPane which
13
+ now lies in lib/rbcurse/deprecated/widgets
14
+ in the rbcurse repo.
15
+ == TODO
16
+ on start first buttons bottom should not be lined.
17
+ Alt-1-9 to goto tabs
18
+ add remove tabs at any time - started, untested
19
+ events for tab add/remove/etc
20
+ =end
21
+ require 'rbcurse'
22
+ ##
23
+ module RubyCurses
24
+ class TabbedPane < Widget
25
+ dsl_property :title, :title_attrib
26
+ # what kind of buttons, if this is a window, :ok :ok_camcel :ok_apply_cancel
27
+ dsl_accessor :button_type
28
+ attr_reader :button_row
29
+ # index of tab that is currently open
30
+ attr_reader :current_tab
31
+
32
+
33
+ def initialize form=nil, config={}, &block
34
+ @_events ||= []
35
+ @_events.push(:PRESS)
36
+ @button_gap = 2
37
+ init_vars
38
+ super
39
+ @focusable = true
40
+ @editable = true
41
+ @col_offset = 2
42
+ raise ArgumentError, "NewTabbedPane : row or col not set: r: #{@row} c: #{@col} " unless @row && @col
43
+ end
44
+
45
+ # Add a tab
46
+ def tab title, config={}, &block
47
+ #@tab_components[title]=[]
48
+ #@tabs << Tab.new(title, self, config, &block)
49
+ insert_tab @tabs.count, title, config, &block
50
+ self
51
+ end
52
+ alias :add_tab :tab
53
+
54
+ # a shortcut for binding a command to a press of an action button
55
+ # The block will be passed
56
+ # This is only relevant if you have asked for buttons to be created, which is
57
+ # only relevant in a TabbedWindow
58
+ # ActionEvent has source event and action_command
59
+ def command *args, &block
60
+ bind :PRESS, *args, &block
61
+ end
62
+
63
+ # -------------- tab maintenance commands ------------------ #
64
+
65
+ def insert_tab index, title, config={}, &block
66
+ @tabs.insert(index, Tab.new(title, self, config, &block) )
67
+ end
68
+ def remove_tab tab
69
+ @tabs.delete tab
70
+ self
71
+ end
72
+ def remove_all
73
+ @tabs = []
74
+ self
75
+ end
76
+ def remove_tab_at index = @current_tab
77
+ @tabs.delete_at index
78
+ end
79
+
80
+ def repaint
81
+ @current_tab ||= 0
82
+ @button_row ||= @row + 2
83
+ @separator_row = @button_row + 1 # hope we have it by now, where to print separator
84
+ @separator_row0 = @button_row - 1 unless @button_row == @row + 1
85
+ @separator_row2 = @row + @height - 3 # hope we have it by now, where to print separator
86
+ #return unless @repaint_required
87
+ if @buttons.empty?
88
+ _create_buttons
89
+ @components = @buttons.dup
90
+ @components.push(*@tabs[@current_tab].items)
91
+ create_action_buttons
92
+ @components.push(*@action_buttons)
93
+ elsif @tab_changed
94
+ @components = @buttons.dup
95
+ @components.push(*@tabs[@current_tab].items)
96
+ @components.push(*@action_buttons)
97
+ @tab_changed = false
98
+ end
99
+ # if some major change has happened then repaint everything
100
+ if @repaint_required
101
+ $log.debug " NEWTAB repaint graphic #{@graphic} "
102
+ print_borders unless @suppress_borders # do this once only, unless everything changes
103
+ print_separator1
104
+ @components.each { |e| e.repaint_all(true); e.repaint }
105
+ else
106
+ @components.each { |e| e.repaint }
107
+ end # if repaint_required
108
+ print_border if (@suppress_borders == false && @repaint_all) # do this once only, unless everything changes
109
+ @repaint_required = false
110
+ end
111
+ def handle_key ch
112
+ $log.debug " NEWTABBED handle_key #{ch} "
113
+ return if @components.empty?
114
+ _multiplier = ($multiplier == 0 ? 1 : $multiplier )
115
+
116
+ # should this go here 2011-10-19
117
+ unless @_entered
118
+ $log.warn "WARN: calling ON_ENTER since in this situation it was not called"
119
+ on_enter
120
+ end
121
+ #if ch == KEY_TAB
122
+ #$log.debug "NEWTABBED GOTO NEXT"
123
+ #return goto_next_component
124
+ #elsif ch == KEY_BTAB
125
+ #return goto_prev_component
126
+ #end
127
+ comp = @current_component
128
+ $log.debug " NEWTABBED handle_key #{ch}: #{comp}"
129
+ if comp
130
+ ret = comp.handle_key(ch)
131
+ $log.debug " NEWTABBED handle_key#{ch}: #{comp} returned #{ret} "
132
+ if ret != :UNHANDLED
133
+ comp.repaint # NOTE: if we don;t do this, then it won't get repainted. I will have to repaint ALL
134
+ # in repaint of this.
135
+ return ret
136
+ end
137
+ $log.debug "XXX NEWTABBED key unhandled by comp #{comp.name} "
138
+ else
139
+ Ncurses.beep
140
+ $log.warn "XXX NEWTABBED key unhandled NULL comp"
141
+ end
142
+ case ch
143
+ when ?\C-c.getbyte(0)
144
+ $multiplier = 0
145
+ return 0
146
+ when ?0.getbyte(0)..?9.getbyte(0)
147
+ $log.debug " VIM coming here to set multiplier #{$multiplier} "
148
+ $multiplier *= 10 ; $multiplier += (ch-48)
149
+ return 0
150
+ end
151
+ ret = process_key ch, self
152
+ # allow user to map left and right if he wants
153
+ if ret == :UNHANDLED
154
+ case ch
155
+ when KEY_UP, KEY_BTAB
156
+ # form will pick this up and do needful
157
+ return goto_prev_component #unless on_first_component?
158
+ when KEY_LEFT
159
+ # if i don't check for first component, key will go back to form,
160
+ # but not be processes. so focussed remain here, but be false.
161
+ # In case of returnign an unhandled TAB, on_leave will happen and cursor will move to
162
+ # previous component outside of this.
163
+ return goto_prev_component unless on_first_component?
164
+ when KEY_RIGHT, KEY_TAB
165
+ return goto_next_component #unless on_last_component?
166
+ when KEY_DOWN
167
+ if on_a_button?
168
+ return goto_first_item
169
+ else
170
+ return goto_next_component #unless on_last_component?
171
+ end
172
+ else
173
+ #@_entered = false
174
+ return :UNHANDLED
175
+ end
176
+ end
177
+
178
+ $multiplier = 0
179
+ return 0
180
+ end
181
+ # on enter processing
182
+ # Very often the first may be a label !
183
+ def on_enter
184
+ # if BTAB, the last comp
185
+ if $current_key == KEY_BTAB
186
+ @current_component = @components.last
187
+ else
188
+ @current_component = @components.first
189
+ end
190
+ return unless @current_component
191
+ $log.debug " NEWTABBED came to ON_ENTER #{@current_component} "
192
+ set_form_row
193
+ @_entered = true
194
+ end
195
+ def on_leave
196
+ @_entered = false
197
+ super
198
+ end
199
+ # takes focus to first item (after buttons)
200
+ def goto_first_item
201
+ bc = @buttons.count
202
+ @components[bc..-1].each { |c|
203
+ if c.focusable
204
+ leave_current_component
205
+ @current_component = c
206
+ set_form_row
207
+ break
208
+ end
209
+ }
210
+ end
211
+ def goto_last_item
212
+ bc = @buttons.count
213
+ f = nil
214
+ @components[bc..-1].each { |c|
215
+ if c.focusable
216
+ f = c
217
+ end
218
+ }
219
+ if f
220
+ leave_current_component
221
+ @current_component = f
222
+ set_form_row
223
+ end
224
+ end
225
+ def goto_next_component
226
+ if @current_component != nil
227
+ leave_current_component
228
+ if on_last_component?
229
+ @_entered = false
230
+ return :UNHANDLED
231
+ end
232
+ @current_index = @components.index(@current_component)
233
+ index = @current_index + 1
234
+ index.upto(@components.length-1) do |i|
235
+ f = @components[i]
236
+ if f.focusable
237
+ @current_index = i
238
+ @current_component = f
239
+ return set_form_row
240
+ end
241
+ end
242
+ end
243
+ @_entered = false
244
+ return :UNHANDLED
245
+ end
246
+ def goto_prev_component
247
+ if @current_component != nil
248
+ leave_current_component
249
+ if on_first_component?
250
+ @_entered = false
251
+ return :UNHANDLED
252
+ end
253
+ @current_index = @components.index(@current_component)
254
+ index = @current_index -= 1
255
+ index.downto(0) do |i|
256
+ f = @components[i]
257
+ if f.focusable
258
+ @current_index = i
259
+ @current_component = f
260
+ return set_form_row
261
+ end
262
+ end
263
+ end
264
+ return :UNHANDLED
265
+ end
266
+ # private
267
+ def set_form_row
268
+ return :UNHANDLED if @current_component.nil?
269
+ $log.debug " NEWTABBED on enter sfr #{@current_component} "
270
+ @current_component.on_enter
271
+ @current_component.set_form_row # why was this missing in vimsplit. is it
272
+ # that on_enter does a set_form_row
273
+ @current_component.set_form_col # XXX
274
+ @current_component.repaint
275
+ # XXX compo should do set_form_row and col if it has that
276
+ end
277
+ # private
278
+ def set_form_col
279
+ return if @current_component.nil?
280
+ $log.debug " #{@name} NEWTABBED set_form_col calling sfc for #{@current_component.name} "
281
+ @current_component.set_form_col
282
+ end
283
+ # leave the component we are on.
284
+ # This should be followed by all containers, so that the on_leave action
285
+ # of earlier comp can be displayed, such as dimming components selections
286
+ def leave_current_component
287
+ @current_component.on_leave
288
+ # NOTE this is required, since repaint will just not happen otherwise
289
+ # Some components are erroneously repainting all, after setting this to true so it is
290
+ # working there.
291
+ @current_component.repaint_required true
292
+ $log.debug " after on_leave VIMS XXX #{@current_component.focussed} #{@current_component.name}"
293
+ @current_component.repaint
294
+ end
295
+
296
+ # is focus on first component
297
+ def on_first_component?
298
+ @current_component == @components.first
299
+ end
300
+ # is focus on last component
301
+ def on_last_component?
302
+ @current_component == @components.last
303
+ end
304
+ def on_a_button?
305
+ @components.index(@current_component) < @buttons.count
306
+ end
307
+ # set focus on given component
308
+ # Sometimes you have the handle to component, and you want to move focus to it
309
+ def goto_component comp
310
+ return if comp == @current_component
311
+ leave_current_component
312
+ @current_component = comp
313
+ set_form_row
314
+ end
315
+ def set_current_tab t
316
+ return if @current_tab == t
317
+ @current_tab = t
318
+ goto_component @components[t]
319
+ @tab_changed = true
320
+ @repaint_required = true
321
+ self
322
+ end
323
+
324
+ def DEPRECATED_handle_key ch # :nodoc
325
+ map_keys unless @keys_mapped
326
+ ret = process_key ch, self
327
+ @multiplier = 0
328
+ return :UNHANDLED if ret == :UNHANDLED
329
+ return 0
330
+ end
331
+
332
+ # Put all the housekeeping stuff at the end
333
+ private
334
+ def init_vars
335
+ @buttons = []
336
+ @tabs = []
337
+ #@tab_components = {}
338
+ @bottombuttons = []
339
+ #
340
+ # I'll keep current tabs comps in this to simplify
341
+ @components = []
342
+ @_entered = false
343
+ end
344
+
345
+ def map_keys
346
+ @keys_mapped = true
347
+ #bind_key(?q, :myproc)
348
+ #bind_key(32, :myproc)
349
+ end
350
+
351
+ def _create_buttons
352
+ $log.debug "XXX: INSIDE create_buttons col_offset #{@col_offset} "
353
+ v = Variable.new
354
+ r = @button_row # @row + 1
355
+ col = @col + @col_offset
356
+ @tabs.each_with_index { |t, i|
357
+ txt = t.text
358
+ @buttons << TabButton.new(nil) do
359
+ variable v
360
+ text txt
361
+ name txt
362
+ #value txt
363
+ row r
364
+ col col
365
+ surround_chars ['','']
366
+ selected_background 'green'
367
+ selected_foreground 'white'
368
+
369
+ end
370
+ b = @buttons.last
371
+ b.command do
372
+ set_current_tab i
373
+ end
374
+ b.form = @form
375
+ b.override_graphic @graphic
376
+ col += txt.length + @button_gap
377
+ }
378
+ end # _create_buttons
379
+ private
380
+ def print_borders
381
+ width = @width
382
+ height = @height-1
383
+ window = @graphic
384
+ startcol = @col
385
+ startrow = @row
386
+ @color_pair = get_color($datacolor)
387
+ $log.debug "NTP #{name}: window.print_border #{startrow}, #{startcol} , h:#{height}, w:#{width} , @color_pair, @attr "
388
+ window.print_border startrow, startcol, height, width, @color_pair, @attr
389
+ print_title
390
+ end
391
+ def print_separator1
392
+
393
+ width = @width
394
+ height = @height-1
395
+ window = @graphic
396
+ startcol = @col
397
+ startrow = @row
398
+ @color_pair = get_color($datacolor)
399
+ r = @separator_row
400
+ c = @col + @col_offset
401
+
402
+ urcorner = []
403
+ #window.printstring r, c, '-' * (@width-2), @color_pair, @attr
404
+ window.mvwhline( r, @col+1, Ncurses::ACS_HLINE, @width-2)
405
+ @buttons.each_with_index do |b, i|
406
+ l = b.text.length
407
+ if b.selected?
408
+ if false #c == @col + @col_offset
409
+ cc = c
410
+ ll = l+1
411
+ else
412
+ cc = c-1
413
+ ll = l+2
414
+ end
415
+ #rr = r -1 #unless rr == @col
416
+ window.printstring r, cc, " "*ll, @color_pair, @attr
417
+ #window.printstring r, cc-1, FFI::NCurses::ACS_HLINE.chr*ll, @color_pair, @attr
418
+ #window.printstring r-2, cc, FFI::NCurses::ACS_HLINE.chr*ll, @color_pair, @attr
419
+ window.mvwaddch r, cc-1, FFI::NCurses::ACS_LRCORNER unless cc-1 <= @col
420
+ window.mvwaddch r, c+l+1, FFI::NCurses::ACS_LLCORNER
421
+ else
422
+ window.mvwaddch r, c+l+1, FFI::NCurses::ACS_BTEE
423
+ end
424
+
425
+ #window.printstring r-2, c, FFI::NCurses::ACS_HLINE*l, @color_pair, @attr
426
+ #tt = b.text
427
+ #window.printstring r, c, tt, @color_pair, @attr
428
+ c += l + 1
429
+ #window.mvwaddch r, c, '+'.ord
430
+ window.mvwaddch r-1, c, FFI::NCurses::ACS_VLINE
431
+ window.mvwaddch r-2, c, FFI::NCurses::ACS_URCORNER #ACS_TTEE
432
+ #window.mvwaddch r-2, c+1, '/'.ord
433
+ urcorner << c
434
+ c+=@button_gap
435
+ end
436
+ window.mvwhline( @separator_row0, @col + 1, Ncurses::ACS_HLINE, c-@col-1-@button_gap)
437
+ window.mvwhline( @separator_row2, @col + 1, Ncurses::ACS_HLINE, @width-2)
438
+ urcorner.each do |c|
439
+ window.mvwaddch r-2, c, FFI::NCurses::ACS_URCORNER #ACS_TTEE
440
+ end
441
+ end
442
+ def print_title
443
+ return unless @title
444
+ _title = @title
445
+ if @title.length > @width - 2
446
+ _title = @title[0..@width-2]
447
+ end
448
+ @graphic.printstring( @row, @col+(@width-_title.length)/2, _title,
449
+ @color_pair, @title_attrib) unless @title.nil?
450
+ end
451
+
452
+ #
453
+ # create the buttons at the bottom OK/ APPLY/ CANCEL
454
+
455
+ def create_action_buttons
456
+ return unless @button_type
457
+ case @button_type.to_s.downcase
458
+ when "ok"
459
+ make_buttons ["&OK"]
460
+ when "ok_cancel" #, "input", "list", "field_list"
461
+ make_buttons %w[&OK &Cancel]
462
+ when "ok_apply_cancel" #, "input", "list", "field_list"
463
+ make_buttons %w[&OK &Apply &Cancel]
464
+ when "yes_no"
465
+ make_buttons %w[&Yes &No]
466
+ when "yes_no_cancel"
467
+ make_buttons ["&Yes", "&No", "&Cancel"]
468
+ when "custom"
469
+ raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
470
+ make_buttons @buttons
471
+ else
472
+ $log.warn "No buttontype passed for creating tabbedpane. Not creating any"
473
+ #make_buttons ["&OK"]
474
+ end
475
+ end
476
+ def make_buttons names
477
+ @action_buttons = []
478
+ $log.debug "XXX: came to NTP make buttons FORM= #{@form.name} names #{names} "
479
+ total = names.inject(0) {|total, item| total + item.length + 4}
480
+ bcol = center_column total
481
+
482
+ # this craps out when height is zero
483
+ brow = @row + @height-2
484
+ brow = FFI::NCurses.LINES-2 if brow < 0
485
+ $log.debug "XXX: putting buttons :on #{brow} : #{@row} , #{@height} "
486
+ button_ct=0
487
+ tpp = self
488
+ names.each_with_index do |bname, ix|
489
+ text = bname
490
+ #underline = @underlines[ix] if !@underlines.nil?
491
+
492
+ button = Button.new nil do
493
+ text text
494
+ name bname
495
+ row brow
496
+ col bcol
497
+ #underline underline
498
+ highlight_background $reversecolor
499
+ color $datacolor
500
+ bgcolor $datacolor
501
+ end
502
+ @action_buttons << button
503
+ button.form = @form
504
+ button.override_graphic @graphic
505
+ index = button_ct
506
+ tpp = self
507
+ button.command { |form| @selected_index = index; @stop = true;
508
+ # ActionEvent has source event and action_command
509
+ fire_handler :PRESS, ActionEvent.new(tpp, index, button.text)
510
+ #throw(:close, @selected_index)
511
+ }
512
+ button_ct += 1
513
+ bcol += text.length+6
514
+ end
515
+ end
516
+ def center_column textlen
517
+ width = @col + @width
518
+ return (width-textlen)/2
519
+ end
520
+
521
+ ## ADD ABOVE
522
+ end # class
523
+
524
+ class Tab
525
+ attr_accessor :text
526
+ attr_reader :config
527
+ attr_reader :items
528
+ attr_accessor :parent_component
529
+ attr_accessor :index
530
+ attr_accessor :button # so you can set an event on it 2011-10-4
531
+ attr_accessor :row_offset
532
+ attr_accessor :col_offset
533
+ def initialize text, parent_component, aconfig={}, &block
534
+ @text = text
535
+ @items = []
536
+ @config = aconfig
537
+ @parent_component = parent_component
538
+ @row_offset ||= 2
539
+ @col_offset ||= 2
540
+ @config.each_pair { |k,v| variable_set(k,v) }
541
+ instance_eval &block if block_given?
542
+ end
543
+ def item widget
544
+ widget.form = @parent_component.form
545
+ widget.override_graphic @parent_component.form.window
546
+ # these will fail if TP put inside some other container. NOTE
547
+ widget.row ||= 0
548
+ widget.col ||= 0
549
+ # If we knew it was only widget we could expand it
550
+ if widget.kind_of?(RubyCurses::Container) #|| widget.respond_to?(:width)
551
+ widget.width ||= @parent_component.width-3
552
+ end
553
+ # Darn ! this was setting Label to fully height
554
+ if widget.kind_of?(RubyCurses::Container) #|| widget.respond_to?(:height)
555
+ widget.height ||= @parent_component.height-3
556
+ end
557
+ # i don't know button_offset as yet
558
+ widget.row += @row_offset + @parent_component.row + 1
559
+ widget.col += @col_offset + @parent_component.col
560
+ @items << widget
561
+ end
562
+ end # class tab
563
+ class TabButton < RadioButton
564
+ attr_accessor :display_tab_on_traversal
565
+ def getvalue_for_paint
566
+ @text
567
+ end
568
+ def selected?
569
+ @variable.value == @value
570
+ end
571
+
572
+ end
573
+
574
+ end # module
575
+ if __FILE__ == $PROGRAM_NAME
576
+ require 'rbcurse/core/util/app'
577
+ require 'rbcurse/core/widgets/rcontainer'
578
+ App.new do
579
+ #r = Container.new nil, :row => 1, :col => 2, :width => 40, :height => 10, :title => "A container"
580
+ r = Container.new nil, :suppress_borders => true
581
+ f1 = field "name", :maxlen => 20, :display_length => 20, :bgcolor => :white,
582
+ :color => :black, :text => "abc", :label => ' Name: '
583
+ f2 = field "email", :display_length => 20, :bgcolor => :white,
584
+ :color => :blue, :text => "me@google.com", :label => 'Email: '
585
+ f3 = radio :group => :grp, :text => "red", :value => "RED", :color => :red
586
+ f4 = radio :group => :grp, :text => "blue", :value => "BLUE", :color => :blue
587
+ f5 = radio :group => :grp, :text => "green", :value => "GREEN", :color => :green
588
+ r.add(f1)
589
+ r.add(f2)
590
+ r.add(f3,f4,f5)
591
+ TabbedPane.new @form, :row => 3, :col => 5, :width => 60, :height => 20 do
592
+ title "User Setup"
593
+ button_type :ok_apply_cancel
594
+ tab "&Profile" do
595
+ item Field.new nil, :row => 2, :col => 2, :text => "enter your name", :label => ' Name: '
596
+ item Field.new nil, :row => 3, :col => 2, :text => "enter your email", :label => 'Email: '
597
+ end
598
+ tab "&Settings" do
599
+ item CheckBox.new nil, :row => 2, :col => 2, :text => "Use HTTPS", :mnemonic => 'u'
600
+ item CheckBox.new nil, :row => 3, :col => 2, :text => "Quit with confirm", :mnemonic => 'q'
601
+ end
602
+ tab "&Term" do
603
+ radio = Variable.new
604
+ item RadioButton.new nil, :row => 2, :col => 2, :text => "&xterm", :value => "xterm", :variable => radio
605
+ item RadioButton.new nil, :row => 3, :col => 2, :text => "sc&reen", :value => "screen", :variable => radio
606
+ radio.update_command() {|rb| ENV['TERM']=rb.value }
607
+ end
608
+ tab "Conta&iner" do
609
+ item r
610
+ end
611
+
612
+ end
613
+ end # app
614
+
615
+ end