rbcurse-core 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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