rbcurse 1.3.0 → 1.4.0

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