rbcurse-core 0.0.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.
Files changed (94) hide show
  1. data/README.md +69 -0
  2. data/VERSION +1 -0
  3. data/examples/abasiclist.rb +151 -0
  4. data/examples/alpmenu.rb +46 -0
  5. data/examples/app.sample +17 -0
  6. data/examples/atree.rb +100 -0
  7. data/examples/common/file.rb +45 -0
  8. data/examples/data/README.markdown +9 -0
  9. data/examples/data/brew.txt +38 -0
  10. data/examples/data/color.2 +37 -0
  11. data/examples/data/gemlist.txt +60 -0
  12. data/examples/data/lotr.txt +12 -0
  13. data/examples/data/ports.txt +136 -0
  14. data/examples/data/table.txt +37 -0
  15. data/examples/data/tasks.csv +88 -0
  16. data/examples/data/tasks.txt +27 -0
  17. data/examples/data/todo.txt +10 -0
  18. data/examples/data/todocsv.csv +28 -0
  19. data/examples/data/unix1.txt +21 -0
  20. data/examples/data/unix2.txt +11 -0
  21. data/examples/dbdemo.rb +487 -0
  22. data/examples/dirtree.rb +90 -0
  23. data/examples/newtabbedwindow.rb +100 -0
  24. data/examples/newtesttabp.rb +92 -0
  25. data/examples/tabular.rb +132 -0
  26. data/examples/tasks.rb +167 -0
  27. data/examples/term2.rb +83 -0
  28. data/examples/testkeypress.rb +72 -0
  29. data/examples/testlistbox.rb +158 -0
  30. data/examples/testmessagebox.rb +140 -0
  31. data/examples/testree.rb +106 -0
  32. data/examples/testwsshortcuts.rb +66 -0
  33. data/examples/testwsshortcuts2.rb +127 -0
  34. data/lib/rbcurse.rb +8 -0
  35. data/lib/rbcurse/core/docs/index.txt +73 -0
  36. data/lib/rbcurse/core/include/action.rb +40 -0
  37. data/lib/rbcurse/core/include/appmethods.rb +112 -0
  38. data/lib/rbcurse/core/include/bordertitle.rb +41 -0
  39. data/lib/rbcurse/core/include/chunk.rb +182 -0
  40. data/lib/rbcurse/core/include/io.rb +953 -0
  41. data/lib/rbcurse/core/include/listcellrenderer.rb +140 -0
  42. data/lib/rbcurse/core/include/listeditable.rb +317 -0
  43. data/lib/rbcurse/core/include/listscrollable.rb +590 -0
  44. data/lib/rbcurse/core/include/listselectable.rb +264 -0
  45. data/lib/rbcurse/core/include/multibuffer.rb +83 -0
  46. data/lib/rbcurse/core/include/orderedhash.rb +77 -0
  47. data/lib/rbcurse/core/include/ractionevent.rb +67 -0
  48. data/lib/rbcurse/core/include/rchangeevent.rb +27 -0
  49. data/lib/rbcurse/core/include/rhistory.rb +62 -0
  50. data/lib/rbcurse/core/include/rinputdataevent.rb +47 -0
  51. data/lib/rbcurse/core/include/vieditable.rb +170 -0
  52. data/lib/rbcurse/core/system/colormap.rb +163 -0
  53. data/lib/rbcurse/core/system/keyboard.rb +150 -0
  54. data/lib/rbcurse/core/system/keydefs.rb +30 -0
  55. data/lib/rbcurse/core/system/ncurses.rb +218 -0
  56. data/lib/rbcurse/core/system/panel.rb +162 -0
  57. data/lib/rbcurse/core/system/window.rb +901 -0
  58. data/lib/rbcurse/core/util/ansiparser.rb +117 -0
  59. data/lib/rbcurse/core/util/app.rb +1235 -0
  60. data/lib/rbcurse/core/util/basestack.rb +407 -0
  61. data/lib/rbcurse/core/util/bottomline.rb +1850 -0
  62. data/lib/rbcurse/core/util/colorparser.rb +71 -0
  63. data/lib/rbcurse/core/util/focusmanager.rb +31 -0
  64. data/lib/rbcurse/core/util/padreader.rb +189 -0
  65. data/lib/rbcurse/core/util/rcommandwindow.rb +587 -0
  66. data/lib/rbcurse/core/util/rdialogs.rb +619 -0
  67. data/lib/rbcurse/core/util/viewer.rb +149 -0
  68. data/lib/rbcurse/core/util/widgetshortcuts.rb +505 -0
  69. data/lib/rbcurse/core/widgets/applicationheader.rb +102 -0
  70. data/lib/rbcurse/core/widgets/box.rb +58 -0
  71. data/lib/rbcurse/core/widgets/divider.rb +310 -0
  72. data/lib/rbcurse/core/widgets/keylabelprinter.rb +178 -0
  73. data/lib/rbcurse/core/widgets/rcombo.rb +238 -0
  74. data/lib/rbcurse/core/widgets/rcontainer.rb +415 -0
  75. data/lib/rbcurse/core/widgets/rlink.rb +30 -0
  76. data/lib/rbcurse/core/widgets/rlist.rb +723 -0
  77. data/lib/rbcurse/core/widgets/rmenu.rb +939 -0
  78. data/lib/rbcurse/core/widgets/rmenulink.rb +22 -0
  79. data/lib/rbcurse/core/widgets/rmessagebox.rb +373 -0
  80. data/lib/rbcurse/core/widgets/rprogress.rb +118 -0
  81. data/lib/rbcurse/core/widgets/rtabbedpane.rb +615 -0
  82. data/lib/rbcurse/core/widgets/rtabbedwindow.rb +68 -0
  83. data/lib/rbcurse/core/widgets/rtextarea.rb +920 -0
  84. data/lib/rbcurse/core/widgets/rtextview.rb +780 -0
  85. data/lib/rbcurse/core/widgets/rtree.rb +787 -0
  86. data/lib/rbcurse/core/widgets/rwidget.rb +3040 -0
  87. data/lib/rbcurse/core/widgets/scrollbar.rb +143 -0
  88. data/lib/rbcurse/core/widgets/statusline.rb +94 -0
  89. data/lib/rbcurse/core/widgets/tabular.rb +264 -0
  90. data/lib/rbcurse/core/widgets/tabularwidget.rb +1211 -0
  91. data/lib/rbcurse/core/widgets/textpad.rb +516 -0
  92. data/lib/rbcurse/core/widgets/tree/treecellrenderer.rb +150 -0
  93. data/lib/rbcurse/core/widgets/tree/treemodel.rb +428 -0
  94. metadata +156 -0
@@ -0,0 +1,619 @@
1
+ =begin
2
+ * Name: dialogs so user can do basic stuff in one line.
3
+ * Description:
4
+ * Author: rkumar
5
+
6
+ --------
7
+ * Date: 2008-12-30 12:22
8
+ * 2011-10-1 : moving print_error and print_status methods here as alternatives
9
+ to alert and confirm. Anyone who has included those will get these.
10
+ And this file is included in the base file.
11
+
12
+ Shucks, this file has no module. It's bare !
13
+ * License:
14
+ Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
15
+
16
+ # CHANGES:
17
+ # -- moving to the new Messagebox 2011-11-19 v 1.5.0
18
+ TODO:
19
+ Add select_one (message, values, default)
20
+ =end
21
+ require 'rbcurse/core/widgets/rwidget'
22
+ #require 'rbcurse/deprecated/widgets/rmessagebox'
23
+ require 'rbcurse/core/widgets/rmessagebox'
24
+
25
+ # trying out 2011-12-4 so non-apps can get it.
26
+ require 'rbcurse/core/util/bottomline'
27
+ $tt ||= RubyCurses::Bottomline.new
28
+ $tt.name = "$tt"
29
+ require 'forwardable'
30
+ module Kernel
31
+ extend Forwardable
32
+ def_delegators :$tt, :ask, :say, :agree, :choose, :numbered_menu, :display_text, :display_text_interactive, :display_list, :say_with_pause, :hide_bottomline, :say_with_wait
33
+ end
34
+ # -- moving to the new Messagebox 2011-11-19 v 1.5.0
35
+ # Alert user with a one line message
36
+ #
37
+ def alert text, config={}
38
+
39
+ if text.is_a? RubyCurses::Variable
40
+ text = text.get_value
41
+ end
42
+ _title = config[:title] || "Alert"
43
+ tp = MessageBox.new config do
44
+ title _title
45
+ button_type :ok
46
+ message text
47
+ #text mess
48
+ end
49
+ tp.run
50
+ end
51
+
52
+ # Alert user with a block of text. This will popup a textview in which the user can scroll
53
+ # Use this if you are not sure of the size of the text, such as printing a stack trace,
54
+ # exception
55
+ def textdialog mess, config={}
56
+ config[:title] ||= "Alert"
57
+ tp = MessageBox.new config do
58
+ button_type :ok
59
+ text mess
60
+ end
61
+ tp.run
62
+ end
63
+ #
64
+ # This uses the new messagebox 2011-11-19 v 1.5.0
65
+ # NOTE: The earlier get_string had only an OK button, this seems to have a CANCEL
66
+ # Are we doing anyhting to let caller know, cancel was pressed. FIXME
67
+ # @param [String] a label such as "Enter name:"
68
+ # @return [String] value entered by user
69
+ def get_string label, config={}
70
+ config[:title] ||= "Entry"
71
+ label_config = config[:label_config] || {}
72
+ label_config[:row] ||= 2
73
+ label_config[:col] ||= 2
74
+ label_config[:text] = label
75
+
76
+ field_config = config[:field_config] || {}
77
+ field_config[:row] ||= 3
78
+ field_config[:col] ||= 2
79
+ field_config[:attr] = :reverse
80
+ field_config[:maxlen] ||= config[:maxlen]
81
+ field_config[:display_length] ||= config[:display_length]
82
+ field_config[:default] ||= config[:default]
83
+ field_config[:default] = field_config[:default].chomp if field_config[:default]
84
+ field_config[:name] = :name
85
+ #field_config[:display_length] ||= 50 # i want it to extend since i don't know the actual width
86
+ #field_config[:width] ||= 50 # i want it to extend since i don't know the actual width
87
+ field_config[:width] ||= (field_config[:display_length] || 50)
88
+
89
+ defwid = config[:default].nil? ? 30 : config[:default].size + 13
90
+ w = [label.size + 8, defwid, field_config[:width]+13 ].max
91
+ config[:width] ||= w
92
+ $log.debug "XXX: FIELD SIZE #{w} "
93
+ $log.debug "XXX: FIELD CONFIG #{field_config} "
94
+ tp = MessageBox.new config do
95
+ button_type :ok_cancel
96
+ default_button 0
97
+ item Label.new nil, label_config
98
+ item Field.new nil, field_config
99
+ end
100
+ index = tp.run
101
+ if index == 0 # OK
102
+ return tp.form.by_name[:name].text
103
+ else # CANCEL
104
+ # Should i use nil or blank. I am currently opting for nil, as this may imply to caller
105
+ # that user does not wish to override whatever value is being prompted for.
106
+ return nil
107
+ end
108
+ end
109
+ # new version using new messagebox
110
+ # @param [String] question
111
+ # @return [Boolean] true or false
112
+ # FIXME focus hould fall on default button so ENTER does not fire first one.
113
+ def confirm text, config={}, &block
114
+ title = config['title'] || "Confirm"
115
+ config[:default_button] ||= 0
116
+ #instance_eval &block if block_given?
117
+ mb = RubyCurses::MessageBox.new config do
118
+ title title
119
+ message text
120
+ button_type :yes_no
121
+ end
122
+ index = mb.run
123
+ return index == 0
124
+ end
125
+ ##
126
+ # pops up a modal box with a message and an OK button.
127
+ # No return value.
128
+ # Usage:
129
+ # alert("You did not enter anything!")
130
+ # alert("You did not enter anything!", "title"=>"Wake Up")
131
+ # alert("You did not enter anything!", {"title"=>"Wake Up", "bgcolor"=>"blue", "color"=>"white"})
132
+ # block currently ignored. don't know what to do, can't pass it to MB since alread sending in a block
133
+ #
134
+ def DEPalert text, config={}, &block
135
+ title = config['title'] || "Alert"
136
+ #instance_eval &block if block_given?
137
+ if text.is_a? RubyCurses::Variable # added 2011-09-20 incase variable passed
138
+ text = text.get_value
139
+ end
140
+ mb = RubyCurses::MessageBox.new nil, config do
141
+ title title
142
+ message text
143
+ button_type :ok
144
+ end
145
+ end
146
+ # confirms from user returning :YES or :NO
147
+ # Darn, should have returned boolean, now have to live with it.
148
+ def OLDconfirm text, config={}, &block
149
+ title = config['title'] || "Confirm"
150
+ #instance_eval &block if block_given?
151
+ mb = RubyCurses::MessageBox.new nil, config do
152
+ title title
153
+ message text
154
+ button_type :yes_no
155
+ end
156
+ return mb.selected_index == 0 ? :YES : :NO
157
+ end
158
+
159
+ ##
160
+ # allows user entry of a string.
161
+ # In config you may pass Field related properties such as chars_allowed, valid_regex, values, etc.
162
+ def DEPget_string(message, len=50, default="", config={})
163
+
164
+ config["input_config"] = {}
165
+ config["input_config"]["maxlen"] = len
166
+ config["maxlen"]=len
167
+ title = config["title"] || "Input required"
168
+ mb = RubyCurses::MessageBox.new nil, config do
169
+ title title
170
+ message message
171
+ type :input
172
+ button_type :ok
173
+ default_value default
174
+ end
175
+ return mb.input_value
176
+ end
177
+
178
+ ##
179
+ # Added 2009-02-05 13:16
180
+ # get a string from user with some additional checkboxes and optionally supply default values
181
+ # Usage:
182
+ #sel, inp, hash = get_string_with_options("Enter a filter pattern", 20, "*", {"checkboxes" => ["case sensitive","reverse"], "checkbox_defaults"=>[true, false]})
183
+ # sel, inp, hash = get_string_with_options("Enter a filter pattern", 20, "*", {"checkboxes" => ["case sensitive","reverse"]})
184
+ # $log.debug " POPUP: #{sel}: #{inp}, #{hash['case sensitive']}, #{hash['reverse']}"
185
+ #
186
+ # @param: message to print,
187
+ # @param: length of entry field
188
+ # @param: default value of field
189
+ # @param: configuration of box or field
190
+ # checkboxes: array of strings to use as checkboxes
191
+ # checkbox_defaults : array of true/false default values for each cb
192
+ # @return: int 0 OK, 1 cancel pressed
193
+ # @return: string value entered
194
+ # @return: hash of strings and booleans for checkboxes and values
195
+ #
196
+ # @deprecated - user should be able to do this quite easily now.
197
+ def TODOget_string_with_options(message, len=20, default="", config={})
198
+ title = config["title"] || "Input required"
199
+ input_config = config["input_config"] || {}
200
+ checks = config["checkboxes"]
201
+ checkbox_defaults = config["checkbox_defaults"] || []
202
+
203
+ height = config["height"] || 1
204
+ display_length = config["display_length"] || 30
205
+
206
+ r = 3
207
+ c = 4
208
+ mform = RubyCurses::Form.new nil
209
+ message_label = RubyCurses::Label.new mform, {'text' => message, "name"=>"message_label","row" => r, "col" => c, "display_length" => display_length, "height" => height, "attr"=>"reverse"}
210
+
211
+ r += 1
212
+ input = RubyCurses::Field.new mform, input_config do
213
+ name "input"
214
+ row r
215
+ col c
216
+ display_length display_length
217
+ maxlen len
218
+ set_buffer default
219
+ end
220
+ if !checks.nil?
221
+ r += 2
222
+ checks.each_with_index do |cbtext,ix|
223
+ field = RubyCurses::CheckBox.new mform do
224
+ text cbtext
225
+ name cbtext
226
+ value checkbox_defaults[ix]||false
227
+ color 'black'
228
+ bgcolor 'white'
229
+ row r
230
+ col c
231
+ end
232
+ r += 1
233
+ end
234
+ end
235
+ radios = config["radiobuttons"]
236
+ if !radios.nil?
237
+ radio_default = config["radio_default"] || radios[0]
238
+ radio = RubyCurses::Variable.new radio_default
239
+ r += 2
240
+ radios.each_with_index do |cbtext,ix|
241
+ field = RubyCurses::RadioButton.new mform do
242
+ variable radio
243
+ text cbtext
244
+ value cbtext
245
+ color 'black'
246
+ bgcolor 'white'
247
+ row r
248
+ col c
249
+ end
250
+ r += 1
251
+ end
252
+ end
253
+ mb = RubyCurses::MessageBox.new mform do
254
+ title title
255
+ button_type :ok_cancel
256
+ default_button 0
257
+ end
258
+ hash = {}
259
+ if !checks.nil?
260
+ checks.each do |c|
261
+ hash[c] = mform.by_name[c].getvalue
262
+ end
263
+ end
264
+ hash["radio"] = radio.get_value unless radio.nil?
265
+ # returns button index (0 = OK), value of field, hash containing values of checkboxes
266
+ return mb.selected_index, mform.by_name['input'].getvalue, hash
267
+ end
268
+
269
+ # ------------------------ We've Moved here from window class ---------------- #
270
+ # #
271
+ # Moving some methods from window. They no longer require having a window. #
272
+ # #
273
+ # ---------------------------------------------------------------------------- #
274
+ #
275
+ #
276
+
277
+ # new version with a window created on 2011-10-1 12:37 AM
278
+ # Now can be separate from window class, needing nothing, just a util class
279
+ # prints a status message and pauses for a char
280
+ def print_status_message text, aconfig={}, &block
281
+ _print_message :status, text, aconfig, &block
282
+ end
283
+ # new version with a window created on 2011-10-1 12:30 AM
284
+ # Now can be separate from window class, needing nothing, just a util class
285
+ # Why are we dealing with $error_message, that was due to old idea which failed
286
+ # scrap it and send the message.
287
+ def print_error_message text, aconfig={}, &block
288
+ _print_message :error, text, aconfig, &block
289
+ end
290
+ def _create_footer_window h = 2 , w = Ncurses.COLS, t = Ncurses.LINES-2, l = 0
291
+ ewin = VER::Window.new(h, w , t, l)
292
+ end
293
+ # @param [:symbol] :error or :status kind of message
294
+ # @private
295
+ def _print_message type, text, aconfig={}, &block
296
+ case text
297
+ when RubyCurses::Variable # added 2011-09-20 incase variable passed
298
+ text = text.get_value
299
+ when Exception
300
+ text = text.to_s
301
+ end
302
+ # NOTE we are polluting global namespace
303
+ aconfig.each_pair { |k,v| instance_variable_set("@#{k}",v) }
304
+ ewin = _create_footer_window #*@layout
305
+ r = 0; c = 1;
306
+ case type
307
+ when :error
308
+ @color ||= 'red'
309
+ @bgcolor ||= 'black'
310
+ else
311
+ @color ||= :white
312
+ @bgcolor ||= :black
313
+ end
314
+ color_pair = get_color($promptcolor, @color, @bgcolor)
315
+ ewin.bkgd(Ncurses.COLOR_PAIR(color_pair));
316
+ ewin.printstring r, c, text, color_pair
317
+ ewin.printstring r+1, c, "Press a key", color_pair
318
+ ewin.wrefresh
319
+ ewin.getchar
320
+ ewin.destroy
321
+ end
322
+ #
323
+ # Alternative to confirm dialog, if you want this look and feel, at last 2 lines of screen
324
+ # @param [String] text to prompt
325
+ # @return [true, false] 'y' is true, all else if false
326
+ def confirm_window text, aconfig={}, &block
327
+ case text
328
+ when RubyCurses::Variable # added 2011-09-20 incase variable passed
329
+ text = text.get_value
330
+ when Exception
331
+ text = text.to_s
332
+ end
333
+ ewin = _create_footer_window
334
+ r = 0; c = 1;
335
+ aconfig.each_pair { |k,v| instance_variable_set("@#{k}",v) }
336
+ @color ||= :white
337
+ @bgcolor ||= :black
338
+ color_pair = get_color($promptcolor, @color, @bgcolor)
339
+ ewin.bkgd(Ncurses.COLOR_PAIR(color_pair));
340
+ ewin.printstring r, c, text, color_pair
341
+ ewin.printstring r+1, c, "[y/n]", color_pair
342
+ ewin.wrefresh
343
+ #retval = :NO # consistent with confirm # CHANGE TO TRUE FALSE NOW
344
+ retval = false
345
+ begin
346
+ ch = ewin.getchar
347
+ #retval = :YES if ch.chr == 'y'
348
+ retval = (ch.chr == 'y' )
349
+ ensure
350
+ ewin.destroy
351
+ end
352
+ retval
353
+ end
354
+ # class created to display multiple messages without asking for user to hit a key
355
+ # returns a window to which one can keep calling printstring with 0 or 1 as row.
356
+ # destroy when finished.
357
+ # Also, one can pause if one wants, or linger.
358
+ # This is meant to be a replacement for the message_immediate and message_raw
359
+ # I was trying out in App.rb. 2011-10-1 1:27 AM
360
+ # Testing from test2.rb
361
+ # TODO: add option of putting progress_bar
362
+ class StatusWindow
363
+ attr_reader :h, :w, :top, :left # height, width, top row, left col of window
364
+ attr_reader :win
365
+ attr_accessor :color_pair
366
+ def initialize config={}, &block
367
+ @color_pair = config[:color_pair]
368
+ @row_offset = config[:row_offset] || 0
369
+ @col_offset = config[:col_offset] || 0
370
+ create_window *config[:layout]
371
+ end
372
+ def create_window h = 2 , w = Ncurses.COLS-0, t = Ncurses.LINES-2, l = 0
373
+ return @win if @win
374
+ @win = VER::Window.new(h, w , t, l)
375
+ @h = h ; @w = w; @top = t ; @left = l
376
+ @color_pair ||= get_color($promptcolor, 'white','black')
377
+ @win.bkgd(Ncurses.COLOR_PAIR(@color_pair));
378
+ @win
379
+ end
380
+ # creates a color pair based on given bg and fg colors as strings
381
+ #def set_colors bgcolor, fgcolor='white'
382
+ #@color_pair = get_color($datacolor, 'white','black')
383
+ #end
384
+ # prints a string on given row (0 or 1)
385
+ def printstring r, c, text, color_pair=@color_pair
386
+ create_window unless @win
387
+ show unless @visible
388
+ r = @h-1 if r > @h-1
389
+ #@win.printstring r, c, ' '*@w, @color_pair
390
+ # FIXME this padding overwrites the border and the offset means next line wiped
391
+ # However, now it may now totally clear a long line.
392
+ @win.printstring r+@row_offset, c+@col_offset, "%-*s" % [@w-(@col_offset*2)-c, text], color_pair
393
+ @win.wrefresh
394
+ end
395
+ # print given strings from first first column onwards
396
+ def print *textarray
397
+ create_window unless @win
398
+ show unless @visible
399
+ c = 1
400
+ textarray.each_with_index { |s, i|
401
+ @win.printstring i+@row_offset, c+@col_offset, "%-*s" % [@w-(@col_offset*2)-c, s], @color_pair
402
+ }
403
+ @win.wrefresh
404
+ end
405
+ def pause; @win.getchar; end
406
+ # pauses with the message, but doesn't ask the user to press a key.
407
+ # If he does, the key should be used by underlying window.
408
+ # Do not call destroy if you call linger, it does the destroy.
409
+ def linger caller_window=nil
410
+ begin
411
+ if caller_window
412
+ ch = @win.getchar
413
+ caller_window.ungetch(ch) # will this be available to underlying window XXX i think not !!
414
+ else
415
+ sleep 1
416
+ end
417
+ ensure
418
+ destroy
419
+ end
420
+ end
421
+ # caller must destroy after he's finished printing messages, unless
422
+ # user calls linger
423
+ def destroy; @win.destroy if @win; @win = nil; end
424
+ def hide
425
+ @win.hide
426
+ @visible = false
427
+ end
428
+ def show
429
+ @win.show unless @visible
430
+ @visible = true
431
+ end
432
+ end
433
+ # returns instance of a status_window for sending multiple
434
+ # statuses during some process
435
+ def status_window aconfig={}, &block
436
+ return StatusWindow.new aconfig
437
+ end
438
+ # this is a popup dialog box on which statuses can be printed as a process is taking place.
439
+ # I am reusing StatusWindow and so there's an issue since I've put a box, so in clearing
440
+ # the line, I might overwrite the box
441
+ def progress_dialog aconfig={}, &block
442
+ aconfig[:layout] = [10,60,10,20]
443
+ window = status_window aconfig
444
+ height = 10; width = 60
445
+ window.win.print_border_mb 1,2, height, width, $normalcolor, FFI::NCurses::A_REVERSE
446
+ return window
447
+ end
448
+ #
449
+ # Display a popup and return the seliected index from list
450
+ # Config includes row and col and title of window
451
+ # You may also pass bgcolor and color
452
+ # @since 1.4.1 2011-11-1
453
+ def popuplist list, config={}, &block
454
+ require 'rbcurse/core/widgets/rlist'
455
+
456
+ max_visible_items = config[:max_visible_items]
457
+ row = config[:row] || 5
458
+ col = config[:col] || 5
459
+ relative_to = config[:relative_to]
460
+ if relative_to
461
+ layout = relative_to.form.window.layout
462
+ row += layout[:top]
463
+ col += layout[:left]
464
+ end
465
+ config.delete :relative_to
466
+ width = config[:width] || longest_in_list(list)+2 # borders take 2
467
+ height = config[:height]
468
+ height ||= [max_visible_items || 10+2, list.length+2].min
469
+ #layout(1+height, width+4, row, col)
470
+ layout = { :height => 0+height, :width => 0+width, :top => row, :left => col }
471
+ window = VER::Window.new(layout)
472
+ form = RubyCurses::Form.new window
473
+
474
+ listconfig = config[:listconfig] || {}
475
+ listconfig[:list] = list
476
+ listconfig[:width] = width
477
+ listconfig[:height] = height
478
+ listconfig[:selection_mode] ||= :single
479
+ listconfig.merge!(config)
480
+ listconfig.delete(:row);
481
+ listconfig.delete(:col);
482
+ # trying to pass populists block to listbox
483
+ lb = RubyCurses::List.new form, listconfig, &block
484
+ #
485
+ # added next line so caller can configure listbox with
486
+ # events such as ENTER_ROW, LEAVE_ROW or LIST_SELECTION_EVENT or PRESS
487
+ # 2011-11-11
488
+ #yield lb if block_given? # No it won't work since this returns
489
+ window.bkgd(Ncurses.COLOR_PAIR($reversecolor));
490
+ window.wrefresh
491
+ Ncurses::Panel.update_panels
492
+ form.repaint
493
+ window.wrefresh
494
+ begin
495
+ while((ch = window.getchar()) != 999 )
496
+ case ch
497
+ when -1
498
+ next
499
+ when ?\C-q.getbyte(0)
500
+ break
501
+ else
502
+ lb.handle_key ch
503
+ form.repaint
504
+ if ch == 13 || ch == 10
505
+ return lb.current_index if lb.selection_mode != :multiple
506
+
507
+ x = lb.selected_indices
508
+ return x if x
509
+ x = lb.current_index unless x
510
+ return [x]
511
+ # if multiple selection, then return list of selected_indices and don't catch 32
512
+ elsif ch == 32 # if single selection
513
+ return lb.current_index if lb.selection_mode != :multiple
514
+ end
515
+ #yield ch if block_given?
516
+ end
517
+ end
518
+ ensure
519
+ window.destroy
520
+ end
521
+ return nil
522
+ end
523
+ # returns length of longest
524
+ def longest_in_list list #:nodoc:
525
+ longest = list.inject(0) do |memo,word|
526
+ memo >= word.length ? memo : word.length
527
+ end
528
+ longest
529
+ end
530
+ def install_help_text text
531
+ @_help_text = text
532
+ end
533
+ # this routine prints help_text for an application
534
+ # If help_text has been set using install_help_text
535
+ # it will be displayed. Else, general help will be
536
+ # displayed. Even when custom help is displayed,
537
+ # user may use <next> to see general help.
538
+ #
539
+ # earlier in app.rb
540
+ def display_app_help
541
+ filename = File.dirname(__FILE__) + "/../docs/index.txt"
542
+ # defarr contains default help
543
+ if File.exists?(filename)
544
+ defarr = File.open(filename,'r').readlines
545
+ else
546
+ arr = []
547
+ arr << " NO HELP SPECIFIED FOR APP "
548
+ arr << " "
549
+ arr << " --- General help --- "
550
+ arr << " F10 - exit application "
551
+ arr << " Alt-x - select commands "
552
+ arr << " : - select commands "
553
+ arr << " "
554
+ defarr = arr
555
+ end
556
+ defhelp = true
557
+ if respond_to? :help_text
558
+ arr = help_text
559
+ defhelp = false
560
+ elsif @_help_text
561
+ arr = @_help_text
562
+ defhelp = false
563
+ else
564
+ arr = defarr
565
+ end
566
+ case arr
567
+ when String
568
+ arr = arr.split("\n")
569
+ when Array
570
+ end
571
+ #w = arr.max_by(&:length).length
572
+ h = FFI::NCurses.LINES - 4
573
+ w = FFI::NCurses.COLS - 10
574
+
575
+ require 'rbcurse/core/util/viewer'
576
+ RubyCurses::Viewer.view(arr, :layout => [2, 4, h, w],:close_key => KEY_F10, :title => "[ Help ]", :print_footer => true) do |t|
577
+ # you may configure textview further here.
578
+ #t.suppress_borders true
579
+ #t.color = :black
580
+ #t.bgcolor = :white
581
+ # or
582
+ #t.attr = :reverse
583
+
584
+ # help was provided, so default help is provided in second buffer
585
+ unless defhelp
586
+ t.add_content defarr, :title => ' General Help '
587
+ end
588
+ end
589
+ end
590
+ #
591
+ =begin
592
+ http://www.kammerl.de/ascii/AsciiSignature.php
593
+ ___
594
+ |__ \
595
+ ) |
596
+ / /
597
+ |_|
598
+ (_)
599
+
600
+ _
601
+ | |
602
+ | |
603
+ | |
604
+ |_|
605
+ (_)
606
+
607
+
608
+ _____ _ _____
609
+ | __ \ | | / ____|
610
+ | |__) | _| |__ _ _ | | _ _ _ __ ___ ___ ___
611
+ | _ / | | | '_ \| | | | | | | | | | '__/ __|/ _ \/ __|
612
+ | | \ \ |_| | |_) | |_| | | |___| |_| | | \__ \ __/\__ \
613
+ |_| \_\__,_|_.__/ \__, | \_____\__,_|_| |___/\___||___/
614
+ __/ |
615
+ |___/
616
+
617
+ =end
618
+
619
+