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.
Files changed (74) hide show
  1. data/CHANGELOG +126 -0
  2. data/Manifest.txt +53 -20
  3. data/README.markdown +423 -0
  4. data/Rakefile +3 -1
  5. data/examples/keytest.rb +177 -0
  6. data/examples/mpad2.rb +156 -0
  7. data/examples/newtesttabp.rb +121 -0
  8. data/examples/rfe.rb +48 -10
  9. data/examples/rfe_renderer.rb +4 -4
  10. data/examples/rvimsplit.rb +376 -0
  11. data/examples/sqlc.rb +97 -106
  12. data/examples/sqlm.rb +446 -0
  13. data/examples/test1.rb +4 -4
  14. data/examples/test2.rb +12 -12
  15. data/examples/testchars.rb +140 -0
  16. data/examples/testkeypress.rb +9 -4
  17. data/examples/testmulticomp.rb +72 -0
  18. data/examples/testscroller.rb +136 -0
  19. data/examples/testscrolllb.rb +86 -0
  20. data/examples/testscrollp.rb +87 -0
  21. data/examples/testscrollta.rb +80 -0
  22. data/examples/testscrolltable.rb +166 -0
  23. data/examples/testsplit.rb +87 -0
  24. data/examples/testsplit2.rb +123 -0
  25. data/examples/testsplit3.rb +215 -0
  26. data/examples/testsplit3_1.rb +244 -0
  27. data/examples/testsplit3a.rb +215 -0
  28. data/examples/testsplit3b.rb +237 -0
  29. data/examples/testsplitta.rb +148 -0
  30. data/examples/testsplittv.rb +142 -0
  31. data/examples/testsplittvv.rb +144 -0
  32. data/examples/testtable.rb +1 -1
  33. data/examples/testtabp.rb +3 -2
  34. data/examples/testtestw.rb +69 -0
  35. data/examples/testtodo.rb +5 -3
  36. data/examples/testtpane.rb +203 -0
  37. data/examples/testtpane2.rb +145 -0
  38. data/examples/testtpanetable.rb +199 -0
  39. data/examples/viewtodo.rb +5 -3
  40. data/lib/rbcurse.rb +1 -1
  41. data/lib/rbcurse/celleditor.rb +2 -2
  42. data/lib/rbcurse/colormap.rb +5 -5
  43. data/lib/rbcurse/defaultlistselectionmodel.rb +3 -3
  44. data/lib/rbcurse/io.rb +663 -0
  45. data/lib/rbcurse/listeditable.rb +306 -0
  46. data/lib/rbcurse/listkeys.rb +15 -15
  47. data/lib/rbcurse/listscrollable.rb +168 -27
  48. data/lib/rbcurse/mapper.rb +35 -13
  49. data/lib/rbcurse/rchangeevent.rb +28 -0
  50. data/lib/rbcurse/rform.rb +845 -0
  51. data/lib/rbcurse/rlistbox.rb +144 -34
  52. data/lib/rbcurse/rmessagebox.rb +10 -5
  53. data/lib/rbcurse/rmulticontainer.rb +325 -0
  54. data/lib/rbcurse/rmultitextview.rb +306 -0
  55. data/lib/rbcurse/rscrollform.rb +369 -0
  56. data/lib/rbcurse/rscrollpane.rb +511 -0
  57. data/lib/rbcurse/rsplitpane.rb +820 -0
  58. data/lib/rbcurse/rtabbedpane.rb +737 -109
  59. data/lib/rbcurse/rtabbedwindow.rb +326 -0
  60. data/lib/rbcurse/rtable.rb +220 -64
  61. data/lib/rbcurse/rtextarea.rb +340 -181
  62. data/lib/rbcurse/rtextview.rb +237 -101
  63. data/lib/rbcurse/rviewport.rb +203 -0
  64. data/lib/rbcurse/rwidget.rb +919 -95
  65. data/lib/rbcurse/scrollable.rb +7 -7
  66. data/lib/rbcurse/selectable.rb +4 -4
  67. data/lib/rbcurse/table/tablecellrenderer.rb +3 -0
  68. data/lib/rbcurse/undomanager.rb +181 -0
  69. data/lib/rbcurse/vieditable.rb +100 -0
  70. data/lib/ver/window.rb +471 -21
  71. metadata +66 -22
  72. data/README.txt +0 -312
  73. data/examples/testd.db +0 -0
  74. data/examples/todocsv.csv +0 -28
@@ -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}"
@@ -3,5 +3,5 @@ require 'ver/window'
3
3
  require 'rbcurse/rwidget'
4
4
  require 'rbcurse/rdialogs'
5
5
  class Rbcurse
6
- VERSION = '0.1.3'
6
+ VERSION = '1.1.1'
7
7
  end
@@ -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'
@@ -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 = :MULTIPLE
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 != :MULTIPLE
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
@@ -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