rbcurse 1.3.0 → 1.4.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 (70) hide show
  1. data/CHANGELOG +33 -0
  2. data/README.markdown +7 -1
  3. data/TODO2.txt +21 -15
  4. data/VERSION +1 -1
  5. data/examples/abasiclist.rb +2 -2
  6. data/examples/alpmenu.rb +1 -1
  7. data/examples/app.rb +0 -1
  8. data/examples/appdirtree.rb +4 -2
  9. data/examples/appemail.rb +7 -3
  10. data/examples/appemaillb.rb +1 -1
  11. data/examples/appgcompose.rb +2 -2
  12. data/examples/appgmail.rb +1 -1
  13. data/examples/appmethods.rb +20 -2
  14. data/examples/atree.rb +9 -1
  15. data/examples/dbdemo.rb +460 -0
  16. data/examples/dirtree.rb +1 -1
  17. data/examples/menu1.rb +37 -5
  18. data/examples/multispl.rb +1 -1
  19. data/examples/rfe.rb +9 -2
  20. data/examples/splitp.rb +1 -1
  21. data/examples/sqlc.rb +6 -10
  22. data/examples/sqlm.rb +2 -20
  23. data/examples/sqlt.rb +408 -0
  24. data/examples/term2.rb +1 -1
  25. data/examples/test2.rb +169 -97
  26. data/examples/testapp.rb +1 -1
  27. data/examples/testapp2.rb +1 -1
  28. data/examples/testkeypress.rb +4 -2
  29. data/examples/testtable.rb +6 -0
  30. data/examples/testtpane.rb +35 -23
  31. data/examples/testvimsplit.rb +3 -2
  32. data/lib/rbcurse.rb +1 -1
  33. data/lib/rbcurse/action.rb +8 -0
  34. data/lib/rbcurse/app.rb +39 -23
  35. data/lib/rbcurse/extras/bottomline.rb +101 -13
  36. data/lib/rbcurse/extras/directorylist.rb +14 -5
  37. data/lib/rbcurse/extras/divider.rb +1 -1
  38. data/lib/rbcurse/extras/listselectable.rb +42 -8
  39. data/lib/rbcurse/extras/masterdetail.rb +2 -2
  40. data/lib/rbcurse/extras/scrollbar.rb +11 -2
  41. data/lib/rbcurse/extras/statusline.rb +56 -0
  42. data/lib/rbcurse/extras/stdscrwindow.rb +11 -0
  43. data/lib/rbcurse/extras/tabular.rb +2 -1
  44. data/lib/rbcurse/extras/tabularwidget.rb +60 -17
  45. data/lib/rbcurse/extras/viewer.rb +16 -4
  46. data/lib/rbcurse/keylabelprinter.rb +34 -4
  47. data/lib/rbcurse/listeditable.rb +5 -1
  48. data/lib/rbcurse/listkeys.rb +1 -1
  49. data/lib/rbcurse/listscrollable.rb +15 -8
  50. data/lib/rbcurse/rbasiclistbox.rb +44 -23
  51. data/lib/rbcurse/rcommandwindow.rb +8 -14
  52. data/lib/rbcurse/rdialogs.rb +187 -2
  53. data/lib/rbcurse/rlistbox.rb +38 -19
  54. data/lib/rbcurse/rmenu.rb +313 -93
  55. data/lib/rbcurse/rmessagebox.rb +3 -2
  56. data/lib/rbcurse/rmulticontainer.rb +5 -3
  57. data/lib/rbcurse/rmultisplit.rb +2 -11
  58. data/lib/rbcurse/rmultitextview.rb +4 -5
  59. data/lib/rbcurse/rtabbedpane.rb +223 -69
  60. data/lib/rbcurse/rtable.rb +6 -10
  61. data/lib/rbcurse/rtextarea.rb +57 -36
  62. data/lib/rbcurse/rtextview.rb +12 -15
  63. data/lib/rbcurse/rtree.rb +79 -22
  64. data/lib/rbcurse/rvimsplit.rb +16 -25
  65. data/lib/rbcurse/rwidget.rb +376 -523
  66. data/lib/rbcurse/tree/treecellrenderer.rb +24 -11
  67. data/lib/rbcurse/tree/treemodel.rb +1 -1
  68. data/lib/ver/window.rb +130 -66
  69. metadata +5 -3
  70. data/examples/term.rb +0 -48
@@ -71,7 +71,7 @@ module RubyCurses
71
71
  else
72
72
  @form.window = @window
73
73
  end
74
- acolor = get_color $reversecolor
74
+ acolor = get_color $reversecolor # this implicitly uses color and bgcolor fooling me often
75
75
  $log.debug " MESSAGE BOX #{@bgcolor} , #{@color} , #{acolor}"
76
76
  @window.bkgd(Ncurses.COLOR_PAIR(acolor));
77
77
  @window.wrefresh
@@ -241,7 +241,7 @@ module RubyCurses
241
241
  $log.debug " print_message: dl:#{display_length} "
242
242
  # XXX this needs to go up and decide height of window
243
243
  if @message_height.nil?
244
- @message_height = (message.length/display_length)+1
244
+ @message_height = (message.length/display_length)+2
245
245
  #$log.debug " print_message: mh:#{@message_height}, ml: #{message.length}"
246
246
  end
247
247
  @message_height ||= 1
@@ -346,6 +346,7 @@ module RubyCurses
346
346
  #Ncurses::Panel.del_panel(panel) if !panel.nil?
347
347
  panel.del_panel if !panel.nil?
348
348
  @window.delwin if !@window.nil?
349
+ Ncurses::Panel.update_panels # 2011-10-1 so window below doesn't have a black rectangle
349
350
  end
350
351
  end
351
352
  end
@@ -77,10 +77,11 @@ module RubyCurses
77
77
  end
78
78
  rescue => err
79
79
  # $error_message = err # changed 2010 dts
80
- $error_message.value = err
80
+ $error_message.value = err.to_s
81
81
  #@form.window.print_error_message PLEASE CREATE LABEL
82
82
  $log.error " Multicomponent process_key #{err} "
83
83
  $log.debug(err.backtrace.join("\n"))
84
+ alert err.to_s
84
85
  end
85
86
  return :UNHANDLED if ret == :UNHANDLED
86
87
  end
@@ -192,8 +193,9 @@ module RubyCurses
192
193
  @current_title = @current_component.title
193
194
  @current_component.repaint_all true
194
195
  end
195
- def perror errmess=$error_message
196
- @form.window.print_error_message errmess
196
+ def perror errmess
197
+ alert errmess
198
+ #@form.window.print_error_message errmess
197
199
  end
198
200
  def list_components
199
201
  $log.debug " TODO buffers_list: #{@bmanager.size} "
@@ -164,10 +164,6 @@ module RubyCurses
164
164
  @components << comp
165
165
  #comp.height = nil # nuking listboxes height since it gets calculated
166
166
  comp.parent_component = self
167
- comp.should_create_buffer = @_child_buffering
168
- # next 2 not sure, is it for first only
169
- comp.ext_row_offset += @ext_row_offset + @row #- @subform1.window.top #0# screen_row
170
- comp.ext_col_offset += @ext_col_offset + @col #-@subform1.window.left # 0# screen_col
171
167
  # dang ! this can go out of bounds ! XXX tab goes out
172
168
  index = @components.size - 1 # expected as base 0 in compute
173
169
  #index = @max_visible - 1 if index > @max_visible - 1
@@ -183,8 +179,7 @@ module RubyCurses
183
179
  else
184
180
  compute_component comp, index
185
181
  end
186
- comp.set_buffering(:target_window => @target_window || @form.window, :bottom => comp.height-1, :right => comp.width-1, :form => @form )
187
- comp.set_buffering(:screen_top => @row, :screen_left => @col)
182
+ comp.set_buffering(:target_window => @target_window || @form.window, :bottom => comp.height-1, :right => comp.width-1, :form => @form ) # removed on 2011-09-29
188
183
  comp.min_height ||= 5
189
184
  comp.min_width ||= 5
190
185
  return self
@@ -339,12 +334,10 @@ module RubyCurses
339
334
  if @orientation == :VERTICAL_SPLIT
340
335
  @components.each do |e|
341
336
  e.height += delta
342
- e.set_buffering(:bottom => e.height-1)
343
337
  end
344
338
  else
345
339
  e = @components.first
346
340
  e.height += delta
347
- e.set_buffering(:bottom => e.height-1)
348
341
  end
349
342
  end
350
343
  end
@@ -370,7 +363,6 @@ module RubyCurses
370
363
  if @orientation == :HORIZONTAL_SPLIT
371
364
  @components.each do |e|
372
365
  e.width += delta
373
- e.set_buffering(:right => e.width-1)
374
366
  end
375
367
  else
376
368
  # any change in width must effect col of others too ! 2010-08-31 21:57 AUG2010
@@ -402,9 +394,8 @@ module RubyCurses
402
394
  next if index < @_first_column_print
403
395
  break if index > @_last_column_print
404
396
  compute_component comp, index
405
- #comp.set_buffering(:target_window => @target_window || @form.window, :bottom => comp.height-1, :right => comp.width-1, :form => @form )
397
+ comp.set_buffering(:target_window => @target_window || @form.window, :form => @form ) # 2011-09-29
406
398
  #comp.set_buffering(:target_window => @target_window || @form.window, :bottom => comp.height-1, :right => comp.width-1, :form => @form )
407
- comp.set_buffering(:screen_top => comp.row, :screen_left => comp.col)
408
399
  comp.repaint
409
400
  end
410
401
  #@balance = 0
@@ -175,9 +175,7 @@ module RubyCurses
175
175
  $log.debug " file edit got cb : #{@current_buffer} "
176
176
  set_current_buffer
177
177
  rescue => err
178
- # $error_message = "Error: #{err} " # changed 2010 dts
179
- $error_message.value = "Error: #{err} "
180
- #@form.window.print_error_message
178
+ alert err.to_s
181
179
  Ncurses.beep
182
180
  return -1
183
181
  end
@@ -193,8 +191,9 @@ module RubyCurses
193
191
  @title = @current_buffer.title
194
192
  @list = @current_buffer.list
195
193
  end
196
- def perror errmess=$error_message
197
- @form.window.print_error_message errmess
194
+ def perror errmess
195
+ #@form.window.print_error_message errmess
196
+ alert errmess
198
197
  end
199
198
  end # class multitextview
200
199
  ##
@@ -24,8 +24,6 @@ NOTE:
24
24
  #
25
25
  # TODO : disable/hide tab ???
26
26
  =end
27
- require 'rubygems'
28
- #require 'ncurses'
29
27
  require 'logger'
30
28
  require 'rbcurse'
31
29
 
@@ -40,6 +38,7 @@ module RubyCurses
40
38
 
41
39
  # Multiple independent overlapping forms using the tabbed metaphor.
42
40
  class TabbedButton < RubyCurses::RadioButton
41
+ attr_accessor :display_tab_on_traversal
43
42
  def getvalue_for_paint
44
43
  @text
45
44
  end
@@ -54,16 +53,16 @@ module RubyCurses
54
53
  r,c = rowcol
55
54
  attribs = @attrs
56
55
  @highlight_foreground ||= $reversecolor
57
- @highlight_background ||= 0
56
+ @highlight_background ||= $reversecolor # 0
58
57
  _state = @state
59
58
  _state = :SELECTED if @variable.value == @value
60
59
  case _state
61
60
  when :HIGHLIGHTED
62
- $log.debug("TabbedBUTTon repaint : HIGHLIGHTED #{bgcolor}, #{color}, v: #{@value}" )
61
+ $log.debug("TabbedBUTTon repaint : HIGHLIGHTED #{bgcolor}, #{color}, v: #{@value}" )
63
62
  bgcolor = @highlight_background
64
63
  color = @highlight_foreground
65
- bgcolor = @bgcolor
66
- color = @color
64
+ bgcolor = @bgcolor
65
+ color = "red" #@color
67
66
  attribs = Ncurses::A_BOLD
68
67
  setrowcol r,c # show cursor on highlighted as we tab through
69
68
  ## but when tabbing thru selected one, then selected one doesn't show cursor
@@ -92,6 +91,16 @@ module RubyCurses
92
91
  #@form.window.printstring r, c, "%-*s" % [len, value], color, attribs
93
92
  #@graphic.printstring r+@graphic.top, c+@graphic.left, "%-*s" % [len, value], color, attribs
94
93
  #@graphic.printstring r-@graphic.top, c-@graphic.left, "%-*s" % [len, value], color, attribs
94
+
95
+ # add bar character on sides of selected 2011-10-5
96
+ # mvwaddch was not doing anything ??
97
+ if _state == :HIGHLIGHTED
98
+ @graphic.printstring r, c-1, ">", color, @attrs unless c-1 < @graphic.left
99
+ #@graphic.printstring r, c+len+1, "<", color, @attrs
100
+ else
101
+ @graphic.printstring r, c-1, " ", color, @attrs unless c-1 < @graphic.left
102
+ #@graphic.printstring r, c+len+1, " ", color, @attrs
103
+ end
95
104
  @graphic.printstring r, c, "%-*s" % [len, value], color, attribs
96
105
  @graphic.modified = true
97
106
  # @form.window.mvchgat(y=r, x=c, max=len, Ncurses::A_NORMAL, bgcolor, nil)
@@ -108,9 +117,11 @@ module RubyCurses
108
117
  # fire takes the focus into tab area so the next TAB goes back to first button
109
118
  # due to current_tab = tab (so next key stroke goes to tab)
110
119
  def on_enter
111
- $log.debug " overridden on_enter of tabbedbutton #{@name} "
120
+ $log.debug " overridden on_enter of tabbedbutton #{@name}, foc #{@focussed} "
112
121
  super
113
- $log.debug " calling fire overridden on_enter of tabbedbutton"
122
+ #@state = :HIGHLIGHTED if @focussed
123
+ $log.debug " overridden on_enter of tabbedbutton #{@name} state #{@state}, foc #{@focussed} "
124
+ $log.debug " calling fire overridden on_enter of tabbedbutton" if @display_tab_on_traversal
114
125
  fire if @display_tab_on_traversal
115
126
  end
116
127
  # In order to get tab display as we traverse buttons, we need to tamper with KEY_DOWN
@@ -119,11 +130,17 @@ module RubyCurses
119
130
  case ch
120
131
  when KEY_DOWN
121
132
  # form will not do a next_field, it will ignore this
133
+ @state = :NORMAL # 2011-10-5
134
+ @form.repaint
122
135
  return :NO_NEXT_FIELD
123
136
  when KEY_RIGHT
124
- @form.select_next_field
137
+ ret = @form.select_next_field
138
+ ret = @form.select_first_field if ret == :NO_NEXT_FIELD
139
+ return ret
125
140
  when KEY_LEFT
126
- @form.select_prev_field
141
+ ret = @form.select_prev_field
142
+ ret = @form.select_last_field if ret == :NO_PREV_FIELD
143
+ return ret
127
144
  when KEY_ENTER, 10, 13, 32 # added space bar also
128
145
  if respond_to? :fire
129
146
  fire
@@ -133,7 +150,7 @@ module RubyCurses
133
150
  return :UNHANDLED
134
151
  end
135
152
  end
136
-
153
+ 0
137
154
  end
138
155
  ##
139
156
  # extending Widget from 2009-10-08 18:45
@@ -145,6 +162,10 @@ module RubyCurses
145
162
  TAB_COL_OFFSET = 0 # what col should tab start on (to save space, flush on left)
146
163
  dsl_accessor :button_type # ok, ok_cancel, yes_no
147
164
  dsl_accessor :buttons # used if type :custom
165
+
166
+ # set to true if you want tabs to show as you traverse the tab buttons
167
+ dsl_accessor :display_tab_on_traversal
168
+
148
169
  attr_reader :selected_index
149
170
  attr_reader :current_tab
150
171
  attr_reader :window
@@ -164,6 +185,7 @@ module RubyCurses
164
185
  @recreate_buttons = true
165
186
  install_keys
166
187
  @_events.push(*[:OPEN, :INSERT, :DELETE])
188
+ @on_main_form = true # 2011-10-4 we need to know this i think
167
189
  end
168
190
  def install_keys
169
191
  @form.bind_key([?d, ?d]) { ix = highlighted_tab_index; repeatm { remove_tab(ix) } }
@@ -184,13 +206,27 @@ module RubyCurses
184
206
  return tab
185
207
  end
186
208
  alias :add :add_tab
209
+
187
210
  ## insert a component at given index
188
211
  # index cannnot be greater than size of tab count
189
212
  def insert_tab text, component, index, aconfig={}, &block
190
213
  $log.debug " TAB insert #{text} at #{index} "
191
214
  @tabs[index] = Tab.new(text, self, aconfig, &block)
192
215
  tab = @tabs[index]
193
- tab.component = component unless component.nil?
216
+
217
+ # trying out setting current tab when created 2011-10-4
218
+ # This situation happens when someone externally is setting data
219
+ # in a tab and calling its repaint. When user presses DOWN from button
220
+ # it was crashing. Old tab is the tab you see below. current_tab takes on
221
+ # either form or old_tab to distinguish whether we are on top buttons or
222
+ # inside a tab.
223
+ @old_tab = tab
224
+
225
+ tform = form(tab) # this could go inside Tab constructor now 2011-10-4
226
+ #tab.component = component unless component.nil? # changed on 2011-10-3 CLEAN
227
+ #component.form = tform unless component.nil? # changed on 2011-10-3 CLEAN
228
+ component.set_form( tform) unless component.nil? # changed on 2011-10-3
229
+ configure_component component unless component.nil?
194
230
  tab.index = index # so i can undelete !!!
195
231
  fire_event tab, index, :INSERT
196
232
  @recreate_buttons = true
@@ -281,12 +317,16 @@ module RubyCurses
281
317
  # private - can't use externally
282
318
  def configure_component component
283
319
  #component.set_form @parent <<--- definitely NOT
284
- component.form = @parent
320
+ #component.form = @parent # changed on 2011-10-2
285
321
  component.rows_panned = component.cols_panned = 0
286
322
  component.parent_component = self # added 2010-02-27 so offsets can go down ?
287
- component.should_create_buffer = true
288
- component.row = @row + TAB_ROW_OFFSET # 2
289
- component.col = @col + TAB_COL_OFFSET
323
+
324
+ $log.debug "XXX: TABBED #{@row} #{@col} #{@height} #{@width} "
325
+ component.row ||= 0 # 2011-10-3 @row + TAB_ROW_OFFSET # 2
326
+ component.col ||= 0 #@col + TAB_COL_OFFSET
327
+ component.width ||= @width #@col + TAB_COL_OFFSET
328
+ component.height ||= @height - 2 #@col + TAB_COL_OFFSET
329
+ $log.debug "XXX: TABBED #{component.row} #{component.col} #{component.height} #{component.width} "
290
330
 
291
331
  # current_form likely to be nil XXX
292
332
  scr_top = component.row # for Pad, if Pad passed as in SplitPane
@@ -357,6 +397,9 @@ module RubyCurses
357
397
  r = @row
358
398
  col = @col + 1
359
399
  @buttons ||= []
400
+ #
401
+ # NOTE: since we remove buttons, setting any events on them is useless !
402
+ #
360
403
  if !@buttons.empty?
361
404
  @buttons.each {|e| @form.remove_widget(e) }
362
405
  end
@@ -389,11 +432,19 @@ module RubyCurses
389
432
  form.set_parent_buffer(@window) if form
390
433
 
391
434
  b = @buttons.last
392
- b.command(b) {
435
+ b.display_tab_on_traversal = @display_tab_on_traversal # 2011-10-4
436
+ tab._button(b) # too late, user needs this when tab is created FIXME
437
+ b.command(b, @form) {
393
438
  $log.debug " calling tab.repaint,button_form_repaint from button press #{b.name} #{b.state} "
394
439
  # form.rep essentially sees that buttons get correct attributes
395
440
  # when triggering M-<char>. This button should get highlighted.
396
441
  tab.repaint
442
+
443
+ # the on_leave of current button does not get fired, so it gets
444
+ # left in a HIGHLIGHTED state, so two can show highlighted at the same time 2011-10-5
445
+ #
446
+ @form.widgets.each { |tb| @form.on_leave(tb) if tb.state == :HIGHLIGHTED }
447
+
397
448
  button_form_repaint #( b.state == :HIGHLIGHTED )
398
449
  if @display_tab_on_traversal
399
450
  # set as old tab so ONLY on going down this becomes current_tab
@@ -402,6 +453,9 @@ module RubyCurses
402
453
  # next line means next key is IMMED taken by the tab not main form
403
454
  @current_tab = tab
404
455
  end
456
+ $log.debug "TAB : form #{tab.form}, #{tab.form.widgets.first} "
457
+ c = tab.form.widgets.first
458
+ c.set_form_row; c.set_form_col
405
459
  fire_event tab, tab.index, :OPEN
406
460
  }
407
461
  end
@@ -435,17 +489,48 @@ module RubyCurses
435
489
  $log.debug("TP WINDOW TOP ? PAD MAIN FORM W:#{@window.name}, F:#{@form.name} ")
436
490
  @form.parent_form = @parent ## 2010-01-21 15:55 TRYING OUT BUFFERED
437
491
  @form.navigation_policy = :NON_CYCLICAL
438
- #xx @current_form = @form
439
- #xx color = $datacolor
440
- #xx @window.print_border @row, @col, @height-1, @width, color #, Ncurses::A_REVERSE
441
492
 
442
493
  Ncurses::Panel.update_panels
443
494
  _recreate_buttons
444
495
 
496
+ @old_tab = @tabs.first
497
+ @old_tab.repaint if @old_tab
445
498
  button_form_repaint true
446
499
  @window.wrefresh ## ADDED 2009-11-02 23:29
447
- @old_tab = @tabs.first
448
- @buttons.first().fire unless @buttons.empty? # make the first form active to start with.
500
+ #@buttons.first().fire unless @buttons.empty? # make the first form active to start with.
501
+ #@current_tab = nil # 2011-10-3 otherwise keys go to this form in the beginning
502
+ @current_tab = @form # 2011-10-4 buttons form should be first
503
+ end
504
+ #
505
+ # Handle placing control in first or last button.
506
+ # R
507
+ def on_enter
508
+ if $current_key == KEY_BTAB
509
+ c = @form.widgets.count-1
510
+ @form.select_field c
511
+ else
512
+ @form.select_field 0
513
+ end
514
+ end
515
+ def _on_enter
516
+ # if BTAB the last comp
517
+ if $current_key == KEY_BTAB
518
+ # FIXME last is not focusable, then ??
519
+ current_component = @buttons.last
520
+ @current_tab = @form
521
+ @old_tab = @tabs.last
522
+ #@form.select_last_field
523
+ else
524
+ current_component = @buttons.first
525
+ @current_tab = @form
526
+ @old_tab = @tabs.first
527
+ #@form.select_first_field
528
+ end
529
+ #set_form_row
530
+ current_component.on_enter
531
+ $log.debug " TP came to on_enter #{current_component}, #{current_component.state} "
532
+ current_component.set_form_col # XXX
533
+ current_component.repaint
449
534
  end
450
535
  def button_form_repaint flag = true
451
536
  $log.debug " INSIDE button_form_repaint #{flag} "
@@ -495,8 +580,8 @@ module RubyCurses
495
580
  window.mvprintw(1,1, tab.text.tr('&', '')) if @print_subheader
496
581
  window.name = "Tab::TAB-#{tab.text}" # 2010-02-02 19:59
497
582
  form.name = "Form::TAB-#{tab.text}" # 2010-02-02 19:59
498
- form.add_cols=@col
499
- form.add_rows=@row
583
+ form.add_cols=@col + 0
584
+ form.add_rows=@row + 2 # 2011-10-3 position cursor correctly
500
585
  return form
501
586
  end
502
587
  ##
@@ -504,20 +589,69 @@ module RubyCurses
504
589
  # @form is the top button form
505
590
  # XXX stop this nonsense about current_form and current_tab
506
591
  # TP should only be concerned with tabs. what happens inside is none of its business
507
- def handle_key(ch)
592
+ def handle_key(ch) # tabbed pane TP
593
+
594
+
595
+ if @current_tab == @form # on main form
596
+ return :UNHANDLED if ch == ?\M-\C-i.getbyte(0) # alt-tab to exit
597
+ ret = @form.handle_key ch
598
+ $log.debug "TP HNDLE KEY got ret #{ret}, ch #{ch} "
599
+ ret ||= :UNHANDLED
600
+ if ret == :UNHANDLED
601
+ $log.warn "unhandled key in TP main #{ch} "
602
+ case ch
603
+ when KEY_RIGHT, KEY_LEFT, KEY_TAB, KEY_BTAB
604
+ when KEY_UP
605
+ when KEY_DOWN
606
+ when KEY_TAB
607
+ when KEY_BTAB
608
+ end
609
+ elsif ret == :NO_NEXT_FIELD
610
+ case ch
611
+ when KEY_TAB
612
+ return :UNHANDLED
613
+ when KEY_RIGHT, KEY_DOWN, ?j.getbyte(0)
614
+
615
+ @current_tab = @old_tab
616
+ if @current_tab
617
+ @current_tab.set_focus :FIRST
618
+ else
619
+ alert "Need to press enter on button"
620
+ if @current_tab.nil? ##or @current_tab.is_a? Form
621
+ w = @form.widgets.first
622
+ w.fire if w.respond_to? :fire
623
+ end
624
+ end
625
+ return 0
626
+ when KEY_UP
627
+ when KEY_BTAB
628
+ end
629
+ return ret
630
+ elsif ret == :NO_PREV_FIELD
631
+ case ch
632
+ when KEY_LEFT, KEY_BTAB, ?k.getbyte(0)
633
+ $log.debug "LEFT BTAB when no previous field"
634
+ return :UNHANDLED
635
+ end
636
+ return ret
637
+ end
638
+ return 0
639
+ end
640
+
641
+ $log.debug " handle_key in tabbed pane got : #{ch}, #{@current_tab}, f: #{@form} "
508
642
  @current_tab ||= @form # first we cycle buttons
509
- $log.debug " handle_key in tabbed pane got : #{ch}"
510
- # needs to go to component
511
- ret = @current_tab.handle_key(ch)
512
- $log.debug " -- form.handle_key in tabbed pane got ret : #{ret} , #{@current_tab} , #{ch} "
643
+ $log.debug " handle_key in tabbed pane got : #{ch}, giving to #{@current_tab} "
644
+ # needs to go to component
645
+ ret = @current_tab.handle_key(ch)
646
+ $log.debug " -- form.handle_key in tabbed pane got ret : #{ret} , #{@current_tab} , #{ch} "
513
647
 
514
- # components will usually return UNHANDLED for a tab or btab
515
- # We need to convert it so the main form can use it
516
- if @current_tab != @form
648
+ # components will usually return UNHANDLED for a tab or btab
649
+ # We need to convert it so the main form can use it
650
+ if @current_tab != @form
517
651
  if ret == :UNHANDLED
518
652
  if ch == KEY_TAB #or ch == KEY_DOWN
519
653
  ret = :NO_NEXT_FIELD
520
- elsif ch == KEY_BTAB #or ch == KEY_UP # btab
654
+ elsif ch == KEY_BTAB or ch == ?k.getbyte(0) #or ch == KEY_UP # btab
521
655
  ret = :NO_PREV_FIELD
522
656
  end
523
657
  end
@@ -530,15 +664,18 @@ module RubyCurses
530
664
 
531
665
  case ret
532
666
  when :NO_NEXT_FIELD
667
+ #alert "came to no nex field" # CLEAN
533
668
  if @current_tab != @form
669
+ #alert "case 1 no next field req first" # changed on 2011-10-2 # 2011-10-04 16:12:34
534
670
  ## if no next field on a subform go to first button of main form
535
671
  @old_tab = @current_tab
536
672
  @current_tab = @form
537
673
  @form.req_first_field
538
- #@form.select_next_field
674
+
539
675
  else
540
676
  # on top button panel - no more buttons, go to tabs first field
541
677
  if @old_tab # in case of empty tabbed pane old_tab was nil
678
+ #alert "case 2 no next field set focus" # CLEANUP # 2011-10-04 16:12:46
542
679
  @current_tab = @old_tab
543
680
  @current_tab.set_focus :FIRST
544
681
  end
@@ -637,10 +774,11 @@ module RubyCurses
637
774
  class Tab
638
775
  attr_accessor :text
639
776
  attr_reader :config
640
- attr_reader :component
777
+ attr_reader :component # 2011-10-4 DEPRECATED
641
778
  #attr_accessor :form
642
779
  attr_accessor :parent_component
643
780
  attr_accessor :index
781
+ attr_accessor :button # so you can set an event on it 2011-10-4
644
782
  def initialize text, parent_component, aconfig={}, &block
645
783
  @text = text
646
784
  @config = aconfig
@@ -650,15 +788,19 @@ module RubyCurses
650
788
  end
651
789
  ## add a single component to the tab
652
790
  # Calling this a second time will overwrite the existing component
791
+ # @deprecated since 2011-10-4 1.3.1
653
792
  def component=(component)
793
+ @form.add_widget component
654
794
  raise "Component cannot be null" unless component
655
795
  raise "Component already associated with a form. Do not pass form in constructor." unless component.form.nil?
656
796
  $log.debug " calling configure component "
657
797
  @parent_component.configure_component component
658
- @component = component
798
+ #@component = component # changed on 2011-10-3
659
799
  end
800
+ # @deprecated since 2011-10-4 1.3.1
660
801
  def remove_component
661
- @component = nil
802
+ @form.widgets.pop # 2011-10-4
803
+ #@component = nil
662
804
  end
663
805
  # private
664
806
  def variable_set var, val
@@ -668,20 +810,22 @@ module RubyCurses
668
810
  # tab should handle key instead of TP.
669
811
  # Pass to component or form
670
812
  def handle_key ch # Tab
671
- kh = @component || @form
813
+ #kh = @component || @form 2011-10-4
814
+ kh = @form
815
+ $log.debug "DEBUG : handle_key Tab giving key to ( #{kh} ) "
672
816
  ret = kh.handle_key(ch)
673
- $log.debug "DEBUG : handle_key Tab got ret #{ret} "
817
+ $log.debug "DEBUG : handle_key Tab ( #{kh} )got ret #{ret} "
674
818
  # forms seem to returning a nil when the pad has been updated. We need to copy it
675
819
  ret ||= 0
676
- if ret == 0 || ret == :UNHANDLED
677
- $log.debug "COMPONENT REPAINT CALLING " if $log.debug?
678
- @component.repaint if @component
820
+ if ret == :UNHANDLED
821
+ $log.debug "tab handle_key returns UNHANDLED" if $log.debug?
822
+ #alert "Inside unhandled case, tab's for did not handle key"
823
+ #@component.repaint if @component
679
824
  #@form.window.refresh
680
- #$log.debug "DEBUG calling display form(false) from handle_key XXX" if @form
825
+ #$log.debug "DEBUG calling display form(false) from handle_key XXXX" if @form
681
826
  #display_form false if @form # this caused others to go blank 2011-09-26
682
827
  elsif ret != :UNHANDLED # FFI trying out, since forms with components not displaying changes
683
- # since moving to FFI.
684
- display_form false if @form
828
+ display_form false if @form # required for multi field forms, not single ones
685
829
  end
686
830
  # XXX i need to call repaint of compoent if updated !!
687
831
  return ret
@@ -690,9 +834,6 @@ module RubyCurses
690
834
  if @form
691
835
  $log.debug "DEBUG calling display form(true) from repaint XXX" if $log.debug?
692
836
  display_form
693
- elsif @component
694
- # we ask the component to paint its buffer only, no actual repainting
695
- redraw
696
837
  else
697
838
  # pls use tp.form(tab) to get form explicity.
698
839
  # It could come here if tab precreated and user is yet to assign a component.
@@ -701,20 +842,6 @@ module RubyCurses
701
842
  $log.error "Programmer error. A change in Tabbedpane requires you to create form explicitly using form = tpane.form(tab) syntax"
702
843
  end
703
844
  end
704
- # force a redraw of a component when tabs changed
705
- def redraw
706
- # this kinda stuff should be inside widget or some util class
707
- c = @component
708
- if c.is_double_buffered?
709
- c.set_buffer_modified
710
- c.buffer_to_window
711
- else
712
- # force a repaint, if not buffered object e.g scrollpane.
713
- $log.debug " TP: forcing repaint of non-buffered object #{c} "
714
- c.repaint_all
715
- c.repaint
716
- end
717
- end
718
845
  ## Set focus on a component or form field when a user has tabbed off the last or first button
719
846
  def set_focus first_last
720
847
  if !@form.nil?
@@ -723,11 +850,13 @@ module RubyCurses
723
850
  $log.debug " calling display form(true) from handle_key NO_NEXT_FIELD: #{first_last} "
724
851
  first_last == :FIRST ? @form.req_first_field : @form.req_last_field
725
852
  display_form
853
+ if @form.widgets.count == 1 # not working trying to get cursor to show in first form.
854
+ component = @form.widgets.first
855
+ component.set_form_row
856
+ component.set_form_col
857
+ end
726
858
  else
727
- # move to component
728
- #@current_form = @current_tab.component # temp HACK 2010-02-27 23:24
729
- @component.set_form_row
730
- @component.set_form_col
859
+ raise "Form nil. Component cannot be directly added any longer. Pls use form"
731
860
  end
732
861
  end
733
862
  # On a tabbed button press, this will display the relevant form
@@ -744,7 +873,6 @@ module RubyCurses
744
873
  pad = form.window
745
874
  else
746
875
  return
747
- pad = form.get_buffer() # component
748
876
  end
749
877
  pc = @parent_component
750
878
  form.repaint if flag # added 2009-11-03 23:27 paint widgets in inside form
@@ -759,6 +887,9 @@ module RubyCurses
759
887
  $log.debug " ret = pad.copywin(pc.window.get_window, #{pminr}, #{pminc}, #{r}, #{c}, r+ #{maxr} - border_width, c+ #{maxc} -border_width,0). W:#{pc.window}, #{pc.window.get_window} "
760
888
  ret = pad.copywin(pc.window.get_window, pminr, pminc, r, c, r+maxr-border_width, c+maxc-border_width,0)
761
889
  $log.debug " display form after pad copy #{ret}. #{form.name} "
890
+ #pad.mvhline( 0,0, Ncurses::ACS_HLINE, pad.width-1)
891
+ pad.mvwaddch(0, 0, Ncurses::ACS_LTEE) # beautify the corner 2010-02-06 19:35
892
+ pad.mvwaddch(0, pad.width-1, Ncurses::ACS_RTEE)
762
893
  end
763
894
 
764
895
  # 2011-09-19 @since 1.3.0 changed so that calling form throws an exception
@@ -783,6 +914,11 @@ module RubyCurses
783
914
  def has_form?
784
915
  !@form.nil?
785
916
  end
917
+
918
+ # @private avoid external use
919
+ def _button(b)
920
+ @button = b
921
+ end
786
922
  end # class Tab
787
923
 
788
924
  end # class Tabbedpane
@@ -826,6 +962,7 @@ module RubyCurses
826
962
  end
827
963
  ## ScrollForm handle key, scrolling
828
964
  def handle_key ch
965
+ #alert("SCROLLFORM #{ch} , ai: #{@active_index} , #{get_current_field.name} ")
829
966
  $log.debug " inside ScrollForm handlekey #{ch} "
830
967
  # do the scrolling thing here top left prow and pcol of pad to be done
831
968
  # # XXX TODO check whether we can scroll before incrementing esp cols_panned etc
@@ -857,8 +994,20 @@ module RubyCurses
857
994
  @window.modified = true
858
995
  return 0
859
996
  end
997
+ case ch
998
+ when ?j.getbyte(0)
999
+ ch = KEY_DOWN
1000
+ when ?k.getbyte(0)
1001
+ ch = KEY_BTAB
1002
+ @window.ungetch(KEY_BTAB)
1003
+ return 0
1004
+ when ?h.getbyte(0)
1005
+ ch = KEY_LEFT
1006
+ when ?l.getbyte(0)
1007
+ ch = KEY_RIGHT
1008
+ end
860
1009
 
861
- super
1010
+ super
862
1011
  end
863
1012
  def repaint
864
1013
  $log.debug " scrollForm repaint calling parent"
@@ -919,8 +1068,10 @@ module RubyCurses
919
1068
  return true
920
1069
  end
921
1070
  # when tabbing through buttons, we need to account for all that panning/scrolling goin' on
1071
+ # Either of r or c can be nil (usually one will be)
922
1072
  def setrowcol r, c
923
1073
  # aha ! here's where i can check whether the cursor is falling off the viewable area
1074
+ if c
924
1075
  if c+@cols_panned < @orig_left
925
1076
  # this essentially means this widget (button) is not in view, its off to the left
926
1077
  $log.debug " setrowcol OVERRIDE #{c} #{@cols_panned} < #{@orig_left} "
@@ -933,7 +1084,10 @@ module RubyCurses
933
1084
  $log.debug " aborting settrow col for now"
934
1085
  return
935
1086
  end
936
- super r+@rows_panned, c+@cols_panned
1087
+ end # if c
1088
+ rr = r.nil? ? nil : r+@rows_panned
1089
+ cc = c.nil? ? nil : c+@cols_panned
1090
+ super rr, cc
937
1091
  end
938
1092
  def add_widget w
939
1093
  super