rbcurse 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +33 -0
- data/README.markdown +7 -1
- data/TODO2.txt +21 -15
- data/VERSION +1 -1
- data/examples/abasiclist.rb +2 -2
- data/examples/alpmenu.rb +1 -1
- data/examples/app.rb +0 -1
- data/examples/appdirtree.rb +4 -2
- data/examples/appemail.rb +7 -3
- data/examples/appemaillb.rb +1 -1
- data/examples/appgcompose.rb +2 -2
- data/examples/appgmail.rb +1 -1
- data/examples/appmethods.rb +20 -2
- data/examples/atree.rb +9 -1
- data/examples/dbdemo.rb +460 -0
- data/examples/dirtree.rb +1 -1
- data/examples/menu1.rb +37 -5
- data/examples/multispl.rb +1 -1
- data/examples/rfe.rb +9 -2
- data/examples/splitp.rb +1 -1
- data/examples/sqlc.rb +6 -10
- data/examples/sqlm.rb +2 -20
- data/examples/sqlt.rb +408 -0
- data/examples/term2.rb +1 -1
- data/examples/test2.rb +169 -97
- data/examples/testapp.rb +1 -1
- data/examples/testapp2.rb +1 -1
- data/examples/testkeypress.rb +4 -2
- data/examples/testtable.rb +6 -0
- data/examples/testtpane.rb +35 -23
- data/examples/testvimsplit.rb +3 -2
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/action.rb +8 -0
- data/lib/rbcurse/app.rb +39 -23
- data/lib/rbcurse/extras/bottomline.rb +101 -13
- data/lib/rbcurse/extras/directorylist.rb +14 -5
- data/lib/rbcurse/extras/divider.rb +1 -1
- data/lib/rbcurse/extras/listselectable.rb +42 -8
- data/lib/rbcurse/extras/masterdetail.rb +2 -2
- data/lib/rbcurse/extras/scrollbar.rb +11 -2
- data/lib/rbcurse/extras/statusline.rb +56 -0
- data/lib/rbcurse/extras/stdscrwindow.rb +11 -0
- data/lib/rbcurse/extras/tabular.rb +2 -1
- data/lib/rbcurse/extras/tabularwidget.rb +60 -17
- data/lib/rbcurse/extras/viewer.rb +16 -4
- data/lib/rbcurse/keylabelprinter.rb +34 -4
- data/lib/rbcurse/listeditable.rb +5 -1
- data/lib/rbcurse/listkeys.rb +1 -1
- data/lib/rbcurse/listscrollable.rb +15 -8
- data/lib/rbcurse/rbasiclistbox.rb +44 -23
- data/lib/rbcurse/rcommandwindow.rb +8 -14
- data/lib/rbcurse/rdialogs.rb +187 -2
- data/lib/rbcurse/rlistbox.rb +38 -19
- data/lib/rbcurse/rmenu.rb +313 -93
- data/lib/rbcurse/rmessagebox.rb +3 -2
- data/lib/rbcurse/rmulticontainer.rb +5 -3
- data/lib/rbcurse/rmultisplit.rb +2 -11
- data/lib/rbcurse/rmultitextview.rb +4 -5
- data/lib/rbcurse/rtabbedpane.rb +223 -69
- data/lib/rbcurse/rtable.rb +6 -10
- data/lib/rbcurse/rtextarea.rb +57 -36
- data/lib/rbcurse/rtextview.rb +12 -15
- data/lib/rbcurse/rtree.rb +79 -22
- data/lib/rbcurse/rvimsplit.rb +16 -25
- data/lib/rbcurse/rwidget.rb +376 -523
- data/lib/rbcurse/tree/treecellrenderer.rb +24 -11
- data/lib/rbcurse/tree/treemodel.rb +1 -1
- data/lib/ver/window.rb +130 -66
- metadata +5 -3
- data/examples/term.rb +0 -48
data/lib/rbcurse/rmessagebox.rb
CHANGED
@@ -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)+
|
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
|
196
|
-
|
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} "
|
data/lib/rbcurse/rmultisplit.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
197
|
-
|
194
|
+
def perror errmess
|
195
|
+
#@form.window.print_error_message errmess
|
196
|
+
alert errmess
|
198
197
|
end
|
199
198
|
end # class multitextview
|
200
199
|
##
|
data/lib/rbcurse/rtabbedpane.rb
CHANGED
@@ -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
|
-
|
61
|
+
$log.debug("TabbedBUTTon repaint : HIGHLIGHTED #{bgcolor}, #{color}, v: #{@value}" )
|
63
62
|
bgcolor = @highlight_background
|
64
63
|
color = @highlight_foreground
|
65
|
-
bgcolor =
|
66
|
-
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
|
-
|
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
|
-
|
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
|
-
|
288
|
-
|
289
|
-
component.
|
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.
|
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
|
-
|
448
|
-
|
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
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
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
|
-
|
515
|
-
|
516
|
-
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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 ==
|
677
|
-
$log.debug "
|
678
|
-
|
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
|
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
|
-
#
|
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
|
-
|
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
|
-
|
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
|