rbcurse 0.1.3 → 1.1.1

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