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.
- 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
|