rbcurse 0.1.3 → 1.1.1
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 +126 -0
- data/Manifest.txt +53 -20
- data/README.markdown +423 -0
- data/Rakefile +3 -1
- data/examples/keytest.rb +177 -0
- data/examples/mpad2.rb +156 -0
- data/examples/newtesttabp.rb +121 -0
- data/examples/rfe.rb +48 -10
- data/examples/rfe_renderer.rb +4 -4
- data/examples/rvimsplit.rb +376 -0
- data/examples/sqlc.rb +97 -106
- data/examples/sqlm.rb +446 -0
- data/examples/test1.rb +4 -4
- data/examples/test2.rb +12 -12
- data/examples/testchars.rb +140 -0
- data/examples/testkeypress.rb +9 -4
- data/examples/testmulticomp.rb +72 -0
- data/examples/testscroller.rb +136 -0
- data/examples/testscrolllb.rb +86 -0
- data/examples/testscrollp.rb +87 -0
- data/examples/testscrollta.rb +80 -0
- data/examples/testscrolltable.rb +166 -0
- data/examples/testsplit.rb +87 -0
- data/examples/testsplit2.rb +123 -0
- data/examples/testsplit3.rb +215 -0
- data/examples/testsplit3_1.rb +244 -0
- data/examples/testsplit3a.rb +215 -0
- data/examples/testsplit3b.rb +237 -0
- data/examples/testsplitta.rb +148 -0
- data/examples/testsplittv.rb +142 -0
- data/examples/testsplittvv.rb +144 -0
- data/examples/testtable.rb +1 -1
- data/examples/testtabp.rb +3 -2
- data/examples/testtestw.rb +69 -0
- data/examples/testtodo.rb +5 -3
- data/examples/testtpane.rb +203 -0
- data/examples/testtpane2.rb +145 -0
- data/examples/testtpanetable.rb +199 -0
- data/examples/viewtodo.rb +5 -3
- data/lib/rbcurse.rb +1 -1
- data/lib/rbcurse/celleditor.rb +2 -2
- data/lib/rbcurse/colormap.rb +5 -5
- data/lib/rbcurse/defaultlistselectionmodel.rb +3 -3
- data/lib/rbcurse/io.rb +663 -0
- data/lib/rbcurse/listeditable.rb +306 -0
- data/lib/rbcurse/listkeys.rb +15 -15
- data/lib/rbcurse/listscrollable.rb +168 -27
- data/lib/rbcurse/mapper.rb +35 -13
- data/lib/rbcurse/rchangeevent.rb +28 -0
- data/lib/rbcurse/rform.rb +845 -0
- data/lib/rbcurse/rlistbox.rb +144 -34
- data/lib/rbcurse/rmessagebox.rb +10 -5
- data/lib/rbcurse/rmulticontainer.rb +325 -0
- data/lib/rbcurse/rmultitextview.rb +306 -0
- data/lib/rbcurse/rscrollform.rb +369 -0
- data/lib/rbcurse/rscrollpane.rb +511 -0
- data/lib/rbcurse/rsplitpane.rb +820 -0
- data/lib/rbcurse/rtabbedpane.rb +737 -109
- data/lib/rbcurse/rtabbedwindow.rb +326 -0
- data/lib/rbcurse/rtable.rb +220 -64
- data/lib/rbcurse/rtextarea.rb +340 -181
- data/lib/rbcurse/rtextview.rb +237 -101
- data/lib/rbcurse/rviewport.rb +203 -0
- data/lib/rbcurse/rwidget.rb +919 -95
- data/lib/rbcurse/scrollable.rb +7 -7
- data/lib/rbcurse/selectable.rb +4 -4
- data/lib/rbcurse/table/tablecellrenderer.rb +3 -0
- data/lib/rbcurse/undomanager.rb +181 -0
- data/lib/rbcurse/vieditable.rb +100 -0
- data/lib/ver/window.rb +471 -21
- metadata +66 -22
- data/README.txt +0 -312
- data/examples/testd.db +0 -0
- data/examples/todocsv.csv +0 -28
data/examples/viewtodo.rb
CHANGED
@@ -2,14 +2,16 @@ $LOAD_PATH << "/Users/rahul/work/projects/rbcurse/"
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'ncurses'
|
4
4
|
require 'logger'
|
5
|
-
#require 'ver/keyboard'
|
6
5
|
require 'rbcurse'
|
7
6
|
require 'rbcurse/rcombo'
|
8
7
|
require 'rbcurse/rtable'
|
9
|
-
#require 'rbcurse/table/tablecellrenderer'
|
10
8
|
require 'rbcurse/keylabelprinter'
|
11
9
|
require 'rbcurse/applicationheader'
|
12
10
|
require 'rbcurse/action'
|
11
|
+
require 'yaml' # 1.9 2009-10-05 13:11
|
12
|
+
###############################
|
13
|
+
## THIS WONT WORK SINCE I've changed to format of yaml file to array from hash
|
14
|
+
##############################
|
13
15
|
|
14
16
|
class TodoList
|
15
17
|
def initialize file
|
@@ -379,7 +381,7 @@ class TodoApp
|
|
379
381
|
@window.wrefresh
|
380
382
|
Ncurses::Panel.update_panels
|
381
383
|
begin
|
382
|
-
while((ch = @window.getchar()) != ?\C-q )
|
384
|
+
while((ch = @window.getchar()) != ?\C-q.getbyte(0) )
|
383
385
|
colcount = tcm.column_count-1
|
384
386
|
s = keycode_tos ch
|
385
387
|
#status_row.text = "Pressed #{ch} , #{s}"
|
data/lib/rbcurse.rb
CHANGED
data/lib/rbcurse/celleditor.rb
CHANGED
@@ -11,8 +11,7 @@ require 'logger'
|
|
11
11
|
# so it can display itself. Otherwise it is not added to the forms widget list, so the
|
12
12
|
# form has no idea tha this widget exists.
|
13
13
|
#
|
14
|
-
# Tested with Field, combo and checkbox
|
15
|
-
# TODO test and integrate with tables.
|
14
|
+
# Tested with Field, combo and checkbox, tables.
|
16
15
|
#
|
17
16
|
module RubyCurses
|
18
17
|
class CellEditor
|
@@ -98,6 +97,7 @@ module RubyCurses
|
|
98
97
|
widget.visible = true
|
99
98
|
widget.form = parent.form
|
100
99
|
#$log.debug " prepare editor value #{widget.display_length} displlen #{widget.maxlen}"
|
100
|
+
$log.debug " prepare editor form: #{widget.form} "
|
101
101
|
#widget.display_length = widget.display_length -1
|
102
102
|
widget.bgcolor = 'yellow'
|
103
103
|
widget.color = 'black'
|
data/lib/rbcurse/colormap.rb
CHANGED
@@ -91,15 +91,15 @@ include ColorMap
|
|
91
91
|
|
92
92
|
while((ch = @window.getchar()) != KEY_F1 )
|
93
93
|
next if ch == -1
|
94
|
-
break if ch == ?q
|
94
|
+
break if ch == ?q.getbyte(0)
|
95
95
|
case ch
|
96
|
-
when ?r
|
96
|
+
when ?r.getbyte(0)
|
97
97
|
attr |= Ncurses::A_REVERSE
|
98
|
-
when ?b
|
98
|
+
when ?b.getbyte(0)
|
99
99
|
attr |= Ncurses::A_BOLD
|
100
|
-
when ?n
|
100
|
+
when ?n.getbyte(0)
|
101
101
|
attr = Ncurses::A_NORMAL
|
102
|
-
when ?u
|
102
|
+
when ?u.getbyte(0)
|
103
103
|
attr |= Ncurses::A_UNDERLINE
|
104
104
|
else
|
105
105
|
i = ch.chr.to_i
|
@@ -11,7 +11,7 @@ module RubyCurses
|
|
11
11
|
@selected_indices=[]
|
12
12
|
@anchor_selection_index = -1
|
13
13
|
@lead_selection_index = -1
|
14
|
-
@selection_mode =
|
14
|
+
@selection_mode = 'multiple'
|
15
15
|
$log.debug " created DefaultListSelectionModel XXX"
|
16
16
|
end
|
17
17
|
|
@@ -36,8 +36,8 @@ module RubyCurses
|
|
36
36
|
end
|
37
37
|
## TODO should go in sorted, and no dupes
|
38
38
|
def add_selection_interval ix0, ix1
|
39
|
-
$log.debug " def add_selection_interval #{ix0}, ix1"
|
40
|
-
if @selection_mode !=
|
39
|
+
$log.debug " def add_selection_interval #{ix0}, #{ix1}, mode: #{@selection_mode} "
|
40
|
+
if @selection_mode != 'multiple'
|
41
41
|
clear_selection
|
42
42
|
end
|
43
43
|
@anchor_selection_index = ix0
|
data/lib/rbcurse/io.rb
ADDED
@@ -0,0 +1,663 @@
|
|
1
|
+
#*******************************************************
|
2
|
+
# Some common io routines for getting data or putting
|
3
|
+
# at some point
|
4
|
+
# Arunachalesha
|
5
|
+
# 2010-03-06 12:10
|
6
|
+
# Some are outdated.
|
7
|
+
# Current are:
|
8
|
+
# * rbgetstr (and those it calls)
|
9
|
+
# * display_cmenu and create_mitem
|
10
|
+
#*******************************************************#
|
11
|
+
module Io
|
12
|
+
|
13
|
+
# from which line to print in footer_win
|
14
|
+
LINEONE = 1
|
15
|
+
FOOTER_COLOR_PAIR = 6
|
16
|
+
MAIN_WINDOW_COLOR_PAIR = 5
|
17
|
+
ERROR_COLOR_PAIR = 7
|
18
|
+
|
19
|
+
|
20
|
+
# complex version of get_string that allows for trappng of control character
|
21
|
+
# such as C-c and C-h and TAB for completion
|
22
|
+
# validints contains int codes not chars.
|
23
|
+
# TODO We should put a field there, make it visible and mv it to after the prompt
|
24
|
+
# and handle all editing events on it.
|
25
|
+
# @return status_code, string (0 if okay, 7 if help asked for, -1 for abort
|
26
|
+
#def rbgetstr(win, r, c, prompt, maxlen, default, labels, validints=[], helptext="")
|
27
|
+
def rbgetstr(win, r, c, prompt, maxlen, config={})
|
28
|
+
#win ||= @target_window
|
29
|
+
$log.debug " inside rbgetstr #{win} r:#{r} c:#{c} p:#{prompt} m:#{maxlen} "
|
30
|
+
raise "rbgetstr got no window. io.rb" if win.nil?
|
31
|
+
ins_mode = false
|
32
|
+
default = config[:default] || ""
|
33
|
+
prompt = "#{prompt} [#{default}]: " unless default
|
34
|
+
len = prompt.length
|
35
|
+
|
36
|
+
# clear the area of len+maxlen
|
37
|
+
color = $datacolor
|
38
|
+
str = default
|
39
|
+
clear_this win, r, c, color, len+maxlen+1
|
40
|
+
print_this(win, prompt+str, color, r, c)
|
41
|
+
len = prompt.length + str.length
|
42
|
+
#x mylabels=["^G~Help ", "^C~Cancel"]
|
43
|
+
#x mylabels += labels if !labels.nil?
|
44
|
+
begin
|
45
|
+
Ncurses.echo();
|
46
|
+
#x print_key_labels( 0, 0, mylabels)
|
47
|
+
#curpos = 0
|
48
|
+
curpos = str.length
|
49
|
+
prevchar = 0
|
50
|
+
entries = nil
|
51
|
+
#win.mvwgetnstr(LINEONE-3,askstr.length,yn,maxlen)
|
52
|
+
while true
|
53
|
+
#ch=win.mvwgetch(r, len) # get to right of prompt - WHY NOT WORKING ???
|
54
|
+
ch=win.getchar()
|
55
|
+
$log.debug " rbgetstr got ch:#{ch}, str:#{str}. "
|
56
|
+
case ch
|
57
|
+
when 3 # -1 # C-c
|
58
|
+
return -1, nil
|
59
|
+
when 10, 13
|
60
|
+
break
|
61
|
+
when ?\C-h.getbyte(0), ?\C-?.getbyte(0), 127 # delete previous character/backspace
|
62
|
+
len -= 1 if len > prompt.length
|
63
|
+
curpos -= 1 if curpos > 0
|
64
|
+
str.slice!(curpos)
|
65
|
+
clear_this win, r, c, color, len+maxlen+1
|
66
|
+
#print_this(win, prompt+str, color, r, c)
|
67
|
+
when 330 # delete character on cursor
|
68
|
+
#len -= 1 if len > prompt.length
|
69
|
+
#curpos -= 1 if curpos > 0
|
70
|
+
str.slice!(curpos) #rescue next
|
71
|
+
clear_this win, r, c, color, len+maxlen+1
|
72
|
+
when ?\C-g.getbyte(0)
|
73
|
+
#x print_footer_help(helptext)
|
74
|
+
helptext = config[:helptext] || "No help provided"
|
75
|
+
print_help(win, r, c, color, helptext)
|
76
|
+
return 7, nil
|
77
|
+
when KEY_LEFT
|
78
|
+
curpos -= 1 if curpos > 0
|
79
|
+
len -= 1 if len > prompt.length
|
80
|
+
win.wmove r, c+len # since getchar is not going back on del and bs
|
81
|
+
next
|
82
|
+
when KEY_RIGHT
|
83
|
+
if curpos < str.length
|
84
|
+
curpos += 1 #if curpos < str.length
|
85
|
+
len += 1
|
86
|
+
win.wmove r, c+len # since getchar is not going back on del and bs
|
87
|
+
end
|
88
|
+
next
|
89
|
+
when ?\M-i.getbyte(0)
|
90
|
+
ins_mode = !ins_mode
|
91
|
+
next
|
92
|
+
when 9 # TAB
|
93
|
+
if config
|
94
|
+
if prevchar == 9
|
95
|
+
if !entries.nil? and !entries.empty?
|
96
|
+
str = entries.delete_at(0)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
tabc = config[:tab_completion] unless tabc
|
100
|
+
next unless tabc
|
101
|
+
entries = tabc.call(str)
|
102
|
+
$log.debug " tab got #{entries} "
|
103
|
+
str = entries.delete_at(0) unless entries.nil? or entries.empty?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
else
|
107
|
+
#if validints.include?ch
|
108
|
+
#print_status("Found in validints")
|
109
|
+
#return ch, nil
|
110
|
+
#else
|
111
|
+
if ch < 0 || ch > 255
|
112
|
+
Ncurses.beep
|
113
|
+
next
|
114
|
+
end
|
115
|
+
# if control char, beep
|
116
|
+
if ch.chr =~ /[[:cntrl:]]/
|
117
|
+
Ncurses.beep
|
118
|
+
next
|
119
|
+
end
|
120
|
+
# we need to trap KEY_LEFT and RIGHT and what of UP for history ?
|
121
|
+
#end
|
122
|
+
#str << ch.chr
|
123
|
+
if ins_mode
|
124
|
+
str[curpos] = ch.chr
|
125
|
+
else
|
126
|
+
str.insert(curpos, ch.chr)
|
127
|
+
end
|
128
|
+
len += 1
|
129
|
+
curpos += 1
|
130
|
+
break if str.length > maxlen
|
131
|
+
end
|
132
|
+
print_this(win, prompt+str, color, r, c)
|
133
|
+
win.wmove r, c+len # more for arrow keys, curpos may not be end
|
134
|
+
prevchar = ch
|
135
|
+
end
|
136
|
+
str = default if str == ""
|
137
|
+
ensure
|
138
|
+
Ncurses.noecho();
|
139
|
+
#x restore_application_key_labels # must be done after using print_key_labels
|
140
|
+
end
|
141
|
+
return 0, str
|
142
|
+
end
|
143
|
+
def clear_this win, r, c, color, len
|
144
|
+
print_this(win, "%-*s" % [len," "], color, r, c)
|
145
|
+
end
|
146
|
+
def print_help(win, r, c, color, helptext)
|
147
|
+
print_this(win, "%-*s" % [helptext.length+2," "], color, r, c)
|
148
|
+
print_this(win, "%s" % helptext, color, r, c)
|
149
|
+
sleep(5)
|
150
|
+
end
|
151
|
+
# @table_width is a constant in caller based on which we decide where to show
|
152
|
+
# key_labels and error messages.
|
153
|
+
# WHEN WE CREATE A PANEL BWLOW we can do away wit that. FIXME XXX
|
154
|
+
# return true for y, false for n
|
155
|
+
# e.g.
|
156
|
+
# <code>
|
157
|
+
# ret = @main.askyesno(nil, "Are you sure you wish to proceed?")
|
158
|
+
# </code>
|
159
|
+
# 2008-10-09 18:27 added call to print_footer_help
|
160
|
+
def askyesno(win, askstr, default = "N", helptext="Helptext for this question")
|
161
|
+
win ||= @footer_win
|
162
|
+
askstr = "#{askstr} [#{default}]: "
|
163
|
+
len = askstr.length
|
164
|
+
|
165
|
+
clear_error # 2008-10-13 20:26
|
166
|
+
print_this(win, askstr, 4, LINEONE, 0)
|
167
|
+
labels=["?~Help "," ~ ", "N~No ", "Y~Yes "]
|
168
|
+
print_key_labels( 0, 0, labels)
|
169
|
+
win.refresh
|
170
|
+
#Ncurses.echo();
|
171
|
+
yn=''
|
172
|
+
#win.mvwgetnstr(Ncurses.LINES-3,askstr.length,yn,maxlen)
|
173
|
+
while true
|
174
|
+
ch=win.mvwgetch(LINEONE,askstr.length)
|
175
|
+
if ch < 0 || ch > 255
|
176
|
+
next
|
177
|
+
end
|
178
|
+
yn = ch.chr
|
179
|
+
yn = default if yn == '' or ch == 10 # KEY_ENTER
|
180
|
+
yn.downcase!
|
181
|
+
break if yn =~/[yn]/
|
182
|
+
if yn == '?'
|
183
|
+
print_footer_help(helptext)
|
184
|
+
print_key_labels( 0, 0, labels)
|
185
|
+
next
|
186
|
+
end
|
187
|
+
Ncurses.beep
|
188
|
+
end
|
189
|
+
#Ncurses.noecho();
|
190
|
+
clear_error # 2008-11-06 19:27
|
191
|
+
restore_application_key_labels # must be done after using print_key_labels
|
192
|
+
win.refresh
|
193
|
+
return yn == 'y'
|
194
|
+
end
|
195
|
+
|
196
|
+
# return y or n or c
|
197
|
+
|
198
|
+
def askyesnocancel(win, askstr, default = "N")
|
199
|
+
win ||= @footer_win
|
200
|
+
askstr = "#{askstr} [#{default}]: "
|
201
|
+
len = askstr.length
|
202
|
+
|
203
|
+
clear_error # 2008-10-13 20:26
|
204
|
+
print_this(win, askstr, 4, LINEONE, 0)
|
205
|
+
labels=["N~No ", "Y~Yes ","C~Cancel"," ~ "]
|
206
|
+
print_key_labels( 0, 0, labels)
|
207
|
+
win.refresh
|
208
|
+
yn=''
|
209
|
+
#win.mvwgetnstr(LINEONE,askstr.length,yn,maxlen)
|
210
|
+
while true
|
211
|
+
ch=win.mvwgetch(LINEONE,askstr.length)
|
212
|
+
yn = ch.chr
|
213
|
+
yn = default if yn == '' or ch == 10 # KEY_ENTER
|
214
|
+
yn.downcase!
|
215
|
+
break if yn =~/[ync]/
|
216
|
+
Ncurses.beep
|
217
|
+
end
|
218
|
+
restore_application_key_labels # must be done after using print_key_labels
|
219
|
+
return yn
|
220
|
+
end
|
221
|
+
|
222
|
+
# return single digit from given choices
|
223
|
+
# e.g.
|
224
|
+
# <code>
|
225
|
+
# labels=["N~No ", "Y~Yes ","C~Cancel"," ~ ","S~SurpiseMe","G~GoAway! "]
|
226
|
+
# ret = @main.askchoice(nil, "Are you sure you wish to proceed?","N",labels,"NYCSG")
|
227
|
+
# @main.clear_error
|
228
|
+
# </code>
|
229
|
+
|
230
|
+
def askchoice(win, askstr, default, labels, validchars, config={})
|
231
|
+
win ||= @footer_win
|
232
|
+
askstr = "#{askstr} [#{default}]: "
|
233
|
+
len = askstr.length
|
234
|
+
helptext = config.fetch("helptext", "No helptext provided for this action")
|
235
|
+
|
236
|
+
clear_error # 2008-10-13 20:26
|
237
|
+
print_this(win, askstr, 4, LINEONE, 0)
|
238
|
+
#labels=["N~No ", "Y~Yes ","C~Cancel"," ~ "]
|
239
|
+
print_key_labels( 0, 0, labels)
|
240
|
+
yn=''
|
241
|
+
validchars.downcase!
|
242
|
+
#win.mvwgetnstr(LINEONE-3,askstr.length,yn,maxlen)
|
243
|
+
while true
|
244
|
+
ch=win.mvwgetch(LINEONE,askstr.length)
|
245
|
+
yn = ch.chr
|
246
|
+
# 2008-10-31 18:08
|
247
|
+
if ch == ?\C-g or yn == '?'
|
248
|
+
print_footer_help(helptext)
|
249
|
+
print_key_labels( 0, 0, labels)
|
250
|
+
next
|
251
|
+
end
|
252
|
+
yn = default if yn == '' or ch == 10 # KEY_ENTER
|
253
|
+
yn.downcase!
|
254
|
+
break if validchars.include?yn
|
255
|
+
Ncurses.beep
|
256
|
+
end
|
257
|
+
restore_application_key_labels # must be done after using print_key_labels
|
258
|
+
return yn
|
259
|
+
end
|
260
|
+
def get_string(win, askstr, maxlen=20, default="", labels=nil )
|
261
|
+
win ||= @footer_win
|
262
|
+
askstr = "#{askstr} [#{default}]: "
|
263
|
+
len = askstr.length
|
264
|
+
|
265
|
+
clear_error # 2008-11-06 19:25
|
266
|
+
print_this(win, askstr, 4, LINEONE, 0)
|
267
|
+
#labels=["N~No ", "Y~Yes ","C~Cancel"," ~ "]
|
268
|
+
mylabels = ["^G~Help ", "^C~Cancel"]
|
269
|
+
mylabels = (mylabels + labels) if !labels.nil?
|
270
|
+
|
271
|
+
print_key_labels( 0, 0, mylabels)
|
272
|
+
Ncurses.echo();
|
273
|
+
yn=''
|
274
|
+
begin
|
275
|
+
Signal.trap("INT"){ return nil }
|
276
|
+
win.mvwgetnstr(LINEONE,askstr.length,yn,maxlen)
|
277
|
+
rescue
|
278
|
+
yn=''
|
279
|
+
ensure
|
280
|
+
Ncurses.noecho();
|
281
|
+
clear_error # 2008-11-02 11:51
|
282
|
+
restore_application_key_labels # must be done after using print_key_labels
|
283
|
+
end
|
284
|
+
yn = default if yn == "" # 2008-10-31 18:59
|
285
|
+
return yn
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
##
|
290
|
+
# prints given text to window, in color at x and y coordinates
|
291
|
+
# @param [Window] window to write to
|
292
|
+
# @param [String] text to print
|
293
|
+
# @param [int] color such as $datacolor or $promptcolor
|
294
|
+
# @param [int] x
|
295
|
+
# @param [int] y
|
296
|
+
# @see Window#printstring
|
297
|
+
# Consider using Window#printstring
|
298
|
+
def print_this(win, text, color, x, y)
|
299
|
+
if(win == nil)
|
300
|
+
raise "win nil in printthis"
|
301
|
+
end
|
302
|
+
#$log.debug " printthis #{win} , #{text} , #{x} , #{y} "
|
303
|
+
color=Ncurses.COLOR_PAIR(color);
|
304
|
+
win.attron(color);
|
305
|
+
#win.mvprintw(x, y, "%-40s" % text);
|
306
|
+
win.mvprintw(x, y, "%s" % text);
|
307
|
+
win.attroff(color);
|
308
|
+
win.refresh
|
309
|
+
end
|
310
|
+
# prints error in footer_win only
|
311
|
+
def print_error(text)
|
312
|
+
clear_error
|
313
|
+
print_in_middle(@footer_win, LINEONE, 10, 80, text, Ncurses.COLOR_PAIR(ERROR_COLOR_PAIR))
|
314
|
+
end
|
315
|
+
# prints status in footer_win only
|
316
|
+
def print_status(text)
|
317
|
+
text = text[text.length-80..-1] if text.length > 80
|
318
|
+
print_error(text)
|
319
|
+
end
|
320
|
+
# clear previous error, call inside getch loop after each ch.
|
321
|
+
def clear_error
|
322
|
+
print_this(@footer_win, "%-*s" % [Ncurses.COLS," "], 5, LINEONE, 0)
|
323
|
+
end
|
324
|
+
# This is only for the menu program, in which we print current action/menu string in the
|
325
|
+
# key labels below.
|
326
|
+
# Its a dirty hack edpending on:
|
327
|
+
# * String CurRow present in key labels
|
328
|
+
# * field_init_proc called this method to set it.
|
329
|
+
def print_action(text)
|
330
|
+
print_this(@footer_win, " %-10s" % ("["+text+"]"), FOOTER_COLOR_PAIR, @action_posy, @action_posx)
|
331
|
+
end
|
332
|
+
|
333
|
+
# the old historical program which prints a string in middle of whereever
|
334
|
+
# thanks to this i was using stdscr which must never be used
|
335
|
+
|
336
|
+
def print_in_middle(win, starty, startx, width, string, color)
|
337
|
+
if(win == nil)
|
338
|
+
raise "window is nil"
|
339
|
+
end
|
340
|
+
x = Array.new
|
341
|
+
y = Array.new
|
342
|
+
Ncurses.getyx(win, y, x);
|
343
|
+
if(startx != 0)
|
344
|
+
x[0] = startx;
|
345
|
+
end
|
346
|
+
if(starty != 0)
|
347
|
+
y[0] = starty;
|
348
|
+
end
|
349
|
+
if(width == 0)
|
350
|
+
width = 80;
|
351
|
+
end
|
352
|
+
length = string.length;
|
353
|
+
temp = (width - length)/ 2;
|
354
|
+
x[0] = startx + temp.floor;
|
355
|
+
win.attron(color);
|
356
|
+
win.mvprintw(y[0], x[0], "%s", string);
|
357
|
+
win.attroff(color);
|
358
|
+
win.refresh();
|
359
|
+
end
|
360
|
+
# splits that bad hack array into even and odd arrays
|
361
|
+
# and prints on last 2 lines
|
362
|
+
|
363
|
+
def print_key_labels(posy, posx, arr)
|
364
|
+
## paint so-called key bindings from key_labels
|
365
|
+
posx = 0
|
366
|
+
even = []
|
367
|
+
odd = []
|
368
|
+
arr.each_index { |i|
|
369
|
+
if i % 2 == 0
|
370
|
+
even << arr[i]
|
371
|
+
else
|
372
|
+
odd << arr[i]
|
373
|
+
end
|
374
|
+
}
|
375
|
+
posy = LINEONE+1
|
376
|
+
print_key_labels_row(posy, posx, even)
|
377
|
+
posy = LINEONE+2
|
378
|
+
print_key_labels_row(posy, posx, odd)
|
379
|
+
# 2008-09-29 21:58
|
380
|
+
@footer_win.wrefresh # needed else secod row not shown after askchoice XXX
|
381
|
+
end
|
382
|
+
|
383
|
+
def print_key_labels_row(posy, posx, arr)
|
384
|
+
#clear first
|
385
|
+
my_form_win = @footer_win
|
386
|
+
# first clear the line
|
387
|
+
print_this(my_form_win, "%-*s" % [Ncurses.COLS," "], FOOTER_COLOR_PAIR, posy, 0)
|
388
|
+
padding = 8
|
389
|
+
padding = 4 if arr.length > 5
|
390
|
+
padding = 0 if arr.length > 7
|
391
|
+
arr.each_index { |i|
|
392
|
+
kl = arr[i].split('~')
|
393
|
+
if kl[0].strip !="" # don't print that white blank space for fillers
|
394
|
+
color_pair=2
|
395
|
+
my_form_win.attron(Ncurses.COLOR_PAIR(color_pair))
|
396
|
+
my_form_win.mvprintw(posy, posx, "%s" % kl[0] );
|
397
|
+
my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair))
|
398
|
+
end
|
399
|
+
color_pair=FOOTER_COLOR_PAIR
|
400
|
+
posx = posx + kl[0].length
|
401
|
+
my_form_win.attron(Ncurses.COLOR_PAIR(color_pair))
|
402
|
+
lab = sprintf(" %s %*s" , kl[1], padding, " ");
|
403
|
+
# hack
|
404
|
+
if kl[1].strip == "CurRow"
|
405
|
+
@action_posx = posx
|
406
|
+
@action_posy = posy
|
407
|
+
end
|
408
|
+
my_form_win.mvprintw(posy, posx, lab)
|
409
|
+
my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair))
|
410
|
+
posx = posx + lab.length
|
411
|
+
}
|
412
|
+
end
|
413
|
+
|
414
|
+
# since it must always be @header_win, we should remove the first param
|
415
|
+
# why should user have any direct access to those 2 windows.
|
416
|
+
def old_print_header(win, htext, posy = 0, posx = 0)
|
417
|
+
win.attron(Ncurses.COLOR_PAIR(6))
|
418
|
+
win.mvprintw(posy, posx, "%-*s" % [Ncurses.COLS, htext] );
|
419
|
+
win.attroff(Ncurses.COLOR_PAIR(6))
|
420
|
+
end
|
421
|
+
def print_header(htext, posy = 0, posx = 0)
|
422
|
+
win = @header_win
|
423
|
+
win.attron(Ncurses.COLOR_PAIR(6))
|
424
|
+
win.mvprintw(posy, posx, "%-*s" % [Ncurses.COLS, htext] );
|
425
|
+
win.attroff(Ncurses.COLOR_PAIR(6))
|
426
|
+
end
|
427
|
+
|
428
|
+
# since it must always be @header_win, we should remove the first param
|
429
|
+
# why should user have any direct access to those 2 windows.
|
430
|
+
def old_print_top_right(win, htext)
|
431
|
+
hlen = htext.length
|
432
|
+
win.attron(Ncurses.COLOR_PAIR(6))
|
433
|
+
win.mvprintw(0, Ncurses.COLS-hlen, htext );
|
434
|
+
win.attroff(Ncurses.COLOR_PAIR(6))
|
435
|
+
#win.refresh
|
436
|
+
end
|
437
|
+
def print_top_right(htext)
|
438
|
+
hlen = htext.length
|
439
|
+
win = @header_win
|
440
|
+
win.attron(Ncurses.COLOR_PAIR(6))
|
441
|
+
win.mvprintw(0, Ncurses.COLS-hlen, htext );
|
442
|
+
win.attroff(Ncurses.COLOR_PAIR(6))
|
443
|
+
#win.refresh
|
444
|
+
end
|
445
|
+
# prints labels defined by user in the DSL.
|
446
|
+
#
|
447
|
+
# Array of labels with:
|
448
|
+
#
|
449
|
+
# * position = [y,x] i.e, row, column
|
450
|
+
# * text = "label text"
|
451
|
+
# * color_pair = 6 (optional, default 6)
|
452
|
+
|
453
|
+
def print_screen_labels(my_form_win, labelarr)
|
454
|
+
table_width = @table_width || Ncurses.LINES-1
|
455
|
+
return if labelarr.nil?
|
456
|
+
labelarr.each{ |lhash|
|
457
|
+
posy, posx = lhash["position"]
|
458
|
+
posy = table_width + posy if posy < 0
|
459
|
+
posx = Ncurses.COLS + posy if posx < 0
|
460
|
+
|
461
|
+
text = lhash["text"]
|
462
|
+
color_pair = lhash["color_pair"] || 6
|
463
|
+
my_form_win.attron(Ncurses.COLOR_PAIR(color_pair))
|
464
|
+
my_form_win.mvprintw(posy, posx, "%-s" % text );
|
465
|
+
my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair))
|
466
|
+
}
|
467
|
+
end
|
468
|
+
|
469
|
+
@deprecated
|
470
|
+
def print_headers(form_hash)
|
471
|
+
header = form_hash["header"]
|
472
|
+
header_top_left = form_hash["header_top_left"] || ""
|
473
|
+
header_top_center = form_hash["header_top_center"] || ""
|
474
|
+
header_top_right = form_hash["header_top_right"] || ""
|
475
|
+
posy = 0
|
476
|
+
posx = 0
|
477
|
+
htext = " <APP NAME> <VERSION> MAIN MENU"
|
478
|
+
|
479
|
+
posy, posx, htext = header if !header.nil?
|
480
|
+
print_header(htext + " %15s " % header_top_left + " %20s" % header_top_center , posy, posx)
|
481
|
+
print_top_right(header_top_right)
|
482
|
+
@header_win.wrefresh();
|
483
|
+
end
|
484
|
+
|
485
|
+
|
486
|
+
# 2008-10-09 18:27 askyesno and ask_string can be passed some text
|
487
|
+
# to be popped up when a user enters ?
|
488
|
+
@deprecated
|
489
|
+
def print_footer_help(helptext)
|
490
|
+
print_this(@footer_win, "%-*s" % [Ncurses.COLS," "], 6, LINEONE+1, 0)
|
491
|
+
print_this(@footer_win, "%-*s" % [Ncurses.COLS," "], 6, LINEONE+2, 0)
|
492
|
+
print_this(@footer_win, "%s" % helptext, 6, LINEONE+1, 0)
|
493
|
+
sleep(5)
|
494
|
+
end
|
495
|
+
def print_help_page(filename = "TODO")
|
496
|
+
#require 'transactionviewer'
|
497
|
+
#tp = TransactionViewer.new(nil)
|
498
|
+
#tp.run
|
499
|
+
require 'panelreader'
|
500
|
+
tp = PanelReader.new()
|
501
|
+
tp.view_file(filename)
|
502
|
+
|
503
|
+
#require 'padreader'
|
504
|
+
#tp = PadReader.new()
|
505
|
+
#tp.view_file(filename)
|
506
|
+
end
|
507
|
+
#def newaskyesno(win, askstr, default = "N", helptext="Helptext for this question")
|
508
|
+
##
|
509
|
+
# user may pass in actions for each key along with other config values in config hash.
|
510
|
+
# config can contain default, helptext, labels and 'y', 'n'
|
511
|
+
@deprecated
|
512
|
+
def newaskyesno(win, askstr, config = {})
|
513
|
+
win ||= @footer_win
|
514
|
+
default = config.fetch("default", "N")
|
515
|
+
helptext = config.fetch("helptext", "This is helptext for this action")
|
516
|
+
askstr = "#{askstr} [#{default}]: "
|
517
|
+
len = askstr.length
|
518
|
+
|
519
|
+
clear_error # 2008-10-13 20:26
|
520
|
+
print_this(win, askstr, 4, LINEONE, 0)
|
521
|
+
labels=config.fetch("labels", ["?~Help "," ~ ", "N~No ", "Y~Yes "])
|
522
|
+
print_key_labels( 0, 0, labels)
|
523
|
+
win.refresh
|
524
|
+
yn=''
|
525
|
+
#win.mvwgetnstr(Ncurses.LINES-3,askstr.length,yn,maxlen)
|
526
|
+
while true
|
527
|
+
ch=win.mvwgetch(LINEONE,askstr.length)
|
528
|
+
if ch < 0 || ch > 255
|
529
|
+
next
|
530
|
+
end
|
531
|
+
yn = ch.chr
|
532
|
+
yn = default if yn == '' or ch == 10 # KEY_ENTER
|
533
|
+
yn.downcase!
|
534
|
+
break if yn =~/[yn]/
|
535
|
+
if yn == '?'
|
536
|
+
print_footer_help(helptext)
|
537
|
+
print_key_labels( 0, 0, labels)
|
538
|
+
next
|
539
|
+
end
|
540
|
+
Ncurses.beep
|
541
|
+
end # while
|
542
|
+
|
543
|
+
begin
|
544
|
+
config[yn].call if config.include? yn
|
545
|
+
ensure
|
546
|
+
restore_application_key_labels # must be done after using print_key_labels
|
547
|
+
win.refresh
|
548
|
+
end
|
549
|
+
|
550
|
+
return yn == 'y'
|
551
|
+
end
|
552
|
+
|
553
|
+
#def add_item hotkey, label, desc,action
|
554
|
+
#
|
555
|
+
## A *simple* way of creating menus that will appear in a single row.
|
556
|
+
# This copies the menu at the bottom of "most" upon pressing ":".
|
557
|
+
# hotkey is the key to invoke an item (a single digit letter)
|
558
|
+
#
|
559
|
+
# label is an action name
|
560
|
+
#
|
561
|
+
# desc is a description displayed after an item is chosen. Usually, its like:
|
562
|
+
#+ "Folding has been enabled" or "Searches will now be case sensitive"
|
563
|
+
#
|
564
|
+
# action may be a Proc or a symbol which will be called if item selected
|
565
|
+
#+ action may be another menu, so recursive menus can be built, but each
|
566
|
+
#+ should fit in a line, its a simple system.
|
567
|
+
|
568
|
+
CMenuItem = Struct.new( :hotkey, :label, :desc, :action )
|
569
|
+
|
570
|
+
|
571
|
+
## An encapsulated form of yesterday's Most Menu
|
572
|
+
# It keeps the internals away from the user.
|
573
|
+
# Its not really OOP in the sense that the PromptMenu is not a MenuItem. That's how it is in
|
574
|
+
# our Menu system, and that led to a lot of painful coding (at least for me). This is quite
|
575
|
+
# simple. A submenu contains a PromptMenu in its action object and is evaluated in a switch.
|
576
|
+
# A recursive loop handles submenus.
|
577
|
+
#
|
578
|
+
# Prompting of menu options with suboptions etc.
|
579
|
+
# A block of code or symbol or proc is executed for any leaf node
|
580
|
+
# This allows us to define different menus for different objects on the screen, and not have to map
|
581
|
+
# all kinds of control keys for operations, and have the user remember them. Only one key invokes the menu
|
582
|
+
# and the rest are ordinary characters.
|
583
|
+
class PromptMenu
|
584
|
+
include Io
|
585
|
+
attr_reader :text
|
586
|
+
attr_reader :options
|
587
|
+
def initialize caller, text="Choose:"
|
588
|
+
@caller = caller
|
589
|
+
@text = text
|
590
|
+
@options = []
|
591
|
+
end
|
592
|
+
def add menuitem
|
593
|
+
@options << menuitem
|
594
|
+
end
|
595
|
+
def create_mitem *args
|
596
|
+
item = CMenuItem.new(*args.flatten)
|
597
|
+
end
|
598
|
+
# Display the top level menu and accept user input
|
599
|
+
# Calls actions or symbols upon selection, or traverses submenus
|
600
|
+
# @return retvalue of last call or send, or 0
|
601
|
+
# @param win window
|
602
|
+
# @param r, c row and col to display on
|
603
|
+
# @param color text color (use $datacolor if in doubt)
|
604
|
+
# @param menu array of CMenuItem structs
|
605
|
+
def display win, r, c, color
|
606
|
+
menu = @options
|
607
|
+
$log.debug " DISP MENU "
|
608
|
+
ret = 0
|
609
|
+
while true
|
610
|
+
str = @text.dup
|
611
|
+
h = {}
|
612
|
+
valid = []
|
613
|
+
menu.each{ |item|
|
614
|
+
str << "(%c) %s " % [ item.hotkey, item.label ]
|
615
|
+
h[item.hotkey] = item
|
616
|
+
valid << item.hotkey
|
617
|
+
}
|
618
|
+
#$log.debug " valid are #{valid} "
|
619
|
+
color = $datacolor
|
620
|
+
print_this(win, str, color, r, c)
|
621
|
+
ch=win.getchar()
|
622
|
+
#$log.debug " got ch #{ch} "
|
623
|
+
next if ch < 0 or ch > 255
|
624
|
+
ch = ch.chr
|
625
|
+
index = valid.index ch
|
626
|
+
if index.nil?
|
627
|
+
clear_this win, r, c, color, str.length
|
628
|
+
print_this(win, "Not valid. Valid are #{valid}", color, r,c)
|
629
|
+
sleep 1
|
630
|
+
next
|
631
|
+
end
|
632
|
+
#$log.debug " index is #{index} "
|
633
|
+
item = h[ch]
|
634
|
+
desc = item.desc
|
635
|
+
#desc ||= "Could not find desc for #{ch} "
|
636
|
+
desc ||= ""
|
637
|
+
clear_this win, r, c, color, str.length
|
638
|
+
print_this(win, desc, color, r,c)
|
639
|
+
action = item.action
|
640
|
+
case action
|
641
|
+
#when Array
|
642
|
+
when PromptMenu
|
643
|
+
# submenu
|
644
|
+
menu = action.options
|
645
|
+
str = "%s: " % action.text
|
646
|
+
when Proc
|
647
|
+
ret = action.call
|
648
|
+
break
|
649
|
+
when Symbol
|
650
|
+
ret = @caller.send(action)
|
651
|
+
break
|
652
|
+
else
|
653
|
+
$log.debug " Unidentified flying class #{action.class} "
|
654
|
+
break
|
655
|
+
end
|
656
|
+
end # while
|
657
|
+
return ret # ret val of last send or call
|
658
|
+
end
|
659
|
+
end # class PromptMenu
|
660
|
+
|
661
|
+
### ADD HERE ###
|
662
|
+
|
663
|
+
end # module
|