canis 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/CHANGES +52 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +24 -0
  7. data/Rakefile +2 -0
  8. data/canis.gemspec +25 -0
  9. data/examples/alpmenu.rb +46 -0
  10. data/examples/app.sample +19 -0
  11. data/examples/appemail.rb +191 -0
  12. data/examples/atree.rb +105 -0
  13. data/examples/bline.rb +181 -0
  14. data/examples/common/devel.rb +319 -0
  15. data/examples/common/file.rb +93 -0
  16. data/examples/data/README.markdown +9 -0
  17. data/examples/data/brew.txt +38 -0
  18. data/examples/data/color.2 +37 -0
  19. data/examples/data/gemlist.txt +59 -0
  20. data/examples/data/lotr.txt +12 -0
  21. data/examples/data/ports.txt +136 -0
  22. data/examples/data/table.txt +37 -0
  23. data/examples/data/tasks.csv +88 -0
  24. data/examples/data/tasks.txt +27 -0
  25. data/examples/data/todo.txt +16 -0
  26. data/examples/data/todocsv.csv +28 -0
  27. data/examples/data/unix1.txt +21 -0
  28. data/examples/data/unix2.txt +11 -0
  29. data/examples/dbdemo.rb +506 -0
  30. data/examples/dirtree.rb +177 -0
  31. data/examples/newtabbedwindow.rb +100 -0
  32. data/examples/newtesttabp.rb +92 -0
  33. data/examples/tabular.rb +212 -0
  34. data/examples/tasks.rb +179 -0
  35. data/examples/term2.rb +88 -0
  36. data/examples/testbuttons.rb +307 -0
  37. data/examples/testcombo.rb +102 -0
  38. data/examples/testdb.rb +182 -0
  39. data/examples/testfields.rb +208 -0
  40. data/examples/testflowlayout.rb +43 -0
  41. data/examples/testkeypress.rb +98 -0
  42. data/examples/testlistbox.rb +187 -0
  43. data/examples/testlistbox1.rb +199 -0
  44. data/examples/testmessagebox.rb +144 -0
  45. data/examples/testprogress.rb +116 -0
  46. data/examples/testree.rb +107 -0
  47. data/examples/testsplitlayout.rb +53 -0
  48. data/examples/testsplitlayout1.rb +49 -0
  49. data/examples/teststacklayout.rb +48 -0
  50. data/examples/testwsshortcuts.rb +68 -0
  51. data/examples/testwsshortcuts2.rb +129 -0
  52. data/lib/canis.rb +16 -0
  53. data/lib/canis/core/docs/index.txt +104 -0
  54. data/lib/canis/core/docs/list.txt +16 -0
  55. data/lib/canis/core/docs/style_help.yml +34 -0
  56. data/lib/canis/core/docs/tabbedpane.txt +15 -0
  57. data/lib/canis/core/docs/table.txt +31 -0
  58. data/lib/canis/core/docs/textpad.txt +48 -0
  59. data/lib/canis/core/docs/tree.txt +23 -0
  60. data/lib/canis/core/include/.DS_Store +0 -0
  61. data/lib/canis/core/include/action.rb +83 -0
  62. data/lib/canis/core/include/actionmanager.rb +49 -0
  63. data/lib/canis/core/include/appmethods.rb +179 -0
  64. data/lib/canis/core/include/bordertitle.rb +49 -0
  65. data/lib/canis/core/include/canisparser.rb +100 -0
  66. data/lib/canis/core/include/colorparser.rb +437 -0
  67. data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
  68. data/lib/canis/core/include/io.rb +320 -0
  69. data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
  70. data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
  71. data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
  72. data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
  73. data/lib/canis/core/include/listbindings.rb +89 -0
  74. data/lib/canis/core/include/listeditable.rb +319 -0
  75. data/lib/canis/core/include/listoperations.rb +61 -0
  76. data/lib/canis/core/include/listselectionmodel.rb +388 -0
  77. data/lib/canis/core/include/multibuffer.rb +173 -0
  78. data/lib/canis/core/include/ractionevent.rb +73 -0
  79. data/lib/canis/core/include/rchangeevent.rb +27 -0
  80. data/lib/canis/core/include/rhistory.rb +95 -0
  81. data/lib/canis/core/include/rinputdataevent.rb +47 -0
  82. data/lib/canis/core/include/textdocument.rb +111 -0
  83. data/lib/canis/core/include/vieditable.rb +175 -0
  84. data/lib/canis/core/include/widgetmenu.rb +66 -0
  85. data/lib/canis/core/system/colormap.rb +165 -0
  86. data/lib/canis/core/system/keydefs.rb +32 -0
  87. data/lib/canis/core/system/ncurses.rb +237 -0
  88. data/lib/canis/core/system/panel.rb +129 -0
  89. data/lib/canis/core/system/window.rb +1081 -0
  90. data/lib/canis/core/util/ansiparser.rb +119 -0
  91. data/lib/canis/core/util/app.rb +696 -0
  92. data/lib/canis/core/util/basestack.rb +412 -0
  93. data/lib/canis/core/util/defaultcolorparser.rb +84 -0
  94. data/lib/canis/core/util/extras/README +5 -0
  95. data/lib/canis/core/util/extras/bottomline.rb +1815 -0
  96. data/lib/canis/core/util/extras/padreader.rb +192 -0
  97. data/lib/canis/core/util/focusmanager.rb +31 -0
  98. data/lib/canis/core/util/helpmanager.rb +160 -0
  99. data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
  100. data/lib/canis/core/util/promptmenu.rb +235 -0
  101. data/lib/canis/core/util/rcommandwindow.rb +933 -0
  102. data/lib/canis/core/util/rdialogs.rb +520 -0
  103. data/lib/canis/core/util/textutils.rb +74 -0
  104. data/lib/canis/core/util/viewer.rb +238 -0
  105. data/lib/canis/core/util/widgetshortcuts.rb +508 -0
  106. data/lib/canis/core/widgets/applicationheader.rb +103 -0
  107. data/lib/canis/core/widgets/box.rb +58 -0
  108. data/lib/canis/core/widgets/divider.rb +310 -0
  109. data/lib/canis/core/widgets/extras/README.md +12 -0
  110. data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
  111. data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
  112. data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
  113. data/lib/canis/core/widgets/listbox.rb +326 -0
  114. data/lib/canis/core/widgets/listfooter.rb +86 -0
  115. data/lib/canis/core/widgets/rcombo.rb +210 -0
  116. data/lib/canis/core/widgets/rcontainer.rb +415 -0
  117. data/lib/canis/core/widgets/rlink.rb +30 -0
  118. data/lib/canis/core/widgets/rmenu.rb +970 -0
  119. data/lib/canis/core/widgets/rmenulink.rb +30 -0
  120. data/lib/canis/core/widgets/rmessagebox.rb +400 -0
  121. data/lib/canis/core/widgets/rprogress.rb +118 -0
  122. data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
  123. data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
  124. data/lib/canis/core/widgets/rwidget.rb +3634 -0
  125. data/lib/canis/core/widgets/scrollbar.rb +147 -0
  126. data/lib/canis/core/widgets/statusline.rb +113 -0
  127. data/lib/canis/core/widgets/table.rb +1072 -0
  128. data/lib/canis/core/widgets/tabular.rb +264 -0
  129. data/lib/canis/core/widgets/textpad.rb +1674 -0
  130. data/lib/canis/core/widgets/tree.rb +690 -0
  131. data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
  132. data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
  133. data/lib/canis/version.rb +3 -0
  134. metadata +229 -0
@@ -0,0 +1,520 @@
1
+ =begin
2
+ * Name: dialogs so user can do basic stuff in one line.
3
+ * Description:
4
+ * Author: jkepler
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 'canis/core/widgets/rwidget'
22
+ #require 'canis/deprecated/widgets/rmessagebox'
23
+ require 'canis/core/widgets/rmessagebox'
24
+ require 'canis/core/widgets/listbox'
25
+
26
+ # -- moving to the new Messagebox 2011-11-19 v 1.5.0
27
+ # Alert user with a one line message
28
+ #
29
+ def alert text, config={}
30
+
31
+ if text.is_a? Canis::Variable
32
+ text = text.get_value
33
+ end
34
+ _title = config[:title] || "Alert"
35
+ tp = MessageBox.new config do
36
+ title _title
37
+ button_type :ok
38
+ message text
39
+ #text mess
40
+ end
41
+ tp.run
42
+ end
43
+
44
+ # Alert user with a block of text. This will popup a textview in which the user can scroll
45
+ # Use this if you are not sure of the size of the text, such as printing a stack trace,
46
+ # exception
47
+ # 2011-12-25 just pass in an exceptino object and we do the rest
48
+ def textdialog mess, config={}
49
+ if mess.is_a? Exception
50
+ mess = [mess.to_s, *mess.backtrace]
51
+ config[:title] ||= "Exception"
52
+ end
53
+ config[:title] ||= "Alert"
54
+ tp = MessageBox.new config do
55
+ button_type :ok
56
+ text mess
57
+ end
58
+ tv = tp.form.by_name["message_label"]
59
+ # 2014-04-15 so that ENTER can hit okay without tabbing to button. FIX IN RBC
60
+ tv.unbind_key(KEY_ENTER)
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
+ # @param [String] a label such as "Enter name:"
67
+ # @return [String] value entered by user, nil if cancel pressed
68
+ # @yield [Field] field created by messagebox
69
+ def get_string label, config={} # yield Field
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[:default] ||= config[:default]
82
+ field_config[:default] = field_config[:default].chomp if field_config[:default]
83
+ field_config[:name] = :name
84
+ #field_config[:width] ||= 50 # i want it to extend since i don't know the actual width
85
+ #field_config[:width] ||= 50 # i want it to extend since i don't know the actual width
86
+ field_config[:width] ||= (field_config[:width] || 50)
87
+
88
+ defwid = config[:default].nil? ? 30 : config[:default].size + 13
89
+ w = [label.size + 8, defwid, field_config[:width]+13 ].max
90
+ config[:width] ||= w
91
+ ## added history 2013-03-06 - 14:25 : we could keep history based on prompt
92
+ $get_string_history ||= []
93
+ #$log.debug "XXX: FIELD SIZE #{w} "
94
+ #$log.debug "XXX: FIELD CONFIG #{field_config} "
95
+ tp = MessageBox.new config do
96
+ button_type :ok_cancel
97
+ default_button 0
98
+ item Label.new nil, label_config
99
+ fld = Field.new nil, field_config
100
+ item fld
101
+ ## added field history 2013-03-06 - 14:24
102
+ require 'canis/core/include/rhistory'
103
+ fld.extend(FieldHistory)
104
+ # We need to manually set history each time, since the field is recreated
105
+ # with the messagebox. Otherwise, field can on its own handle history
106
+ fld.history($get_string_history)
107
+ end
108
+ # added yield to override settings
109
+ yield tp.form.by_name[:name] if block_given?
110
+ index = tp.run
111
+ if index == 0 # OK
112
+ ## added field history 2013-03-06 - 14:24
113
+ t = tp.form.by_name[:name].text
114
+ $get_string_history << t if t && !$get_string_history.include?(t)
115
+ return t
116
+ else # CANCEL
117
+ # Should i use nil or blank. I am currently opting for nil, as this may imply to caller
118
+ # that user does not wish to override whatever value is being prompted for.
119
+ return nil
120
+ end
121
+ end
122
+ # new version using new messagebox
123
+ # @param [String] question
124
+ # @return [Boolean] true or false
125
+ # @yield [Label]
126
+ #
127
+ def confirm text, config={}, &block
128
+ title = config['title'] || "Confirm"
129
+ config[:default_button] ||= 0
130
+
131
+ mb = Canis::MessageBox.new config do
132
+ title title
133
+ message text, &block
134
+ button_type :yes_no
135
+ end
136
+ index = mb.run
137
+ return index == 0
138
+ end
139
+ ##
140
+ # pops up a modal box with a message and an OK button.
141
+ # No return value.
142
+ # Usage:
143
+ # alert("You did not enter anything!")
144
+ # alert("You did not enter anything!", "title"=>"Wake Up")
145
+ # alert("You did not enter anything!", {"title"=>"Wake Up", "bgcolor"=>"blue", "color"=>"white"})
146
+ # block currently ignored. don't know what to do, can't pass it to MB since alread sending in a block
147
+ #
148
+
149
+ # ------------------------ We've Moved here from window class ---------------- #
150
+ # #
151
+ # Moving some methods from window. They no longer require having a window. #
152
+ # #
153
+ # ---------------------------------------------------------------------------- #
154
+ #
155
+ #
156
+
157
+ # new version with a window created on 2011-10-1 12:37 AM
158
+ # Now can be separate from window class, needing nothing, just a util class
159
+ # prints a status message and pauses for a char
160
+ # @param [String] text to print
161
+ # @param [Hash] config: :color :bgcolor :color_pair
162
+ # :wait (numbr of seconds to wait for a key press and then close) if not givn
163
+ # will keep waiting for keypress (the default)
164
+ def print_status_message text, aconfig={}, &block
165
+ _print_message :status, text, aconfig, &block
166
+ end
167
+ alias :rb_puts print_status_message
168
+ alias :say print_status_message
169
+
170
+ # new version with a window created on 2011-10-1 12:30 AM
171
+ # Now can be separate from window class, needing nothing, just a util class
172
+ # @param [String] text to print
173
+ # @param [Hash] config: :color :bgcolor :color_pair
174
+ # :wait (numbr of seconds to wait for a key press and then close) if not givn
175
+ # will keep waiting for keypress (the default)
176
+ def print_error_message text, aconfig={}, &block
177
+ _print_message :error, text, aconfig, &block
178
+ end
179
+ private
180
+ def _create_footer_window h = 2 , w = Ncurses.COLS, t = Ncurses.LINES-2, l = 0 #:nodoc:
181
+ ewin = Canis::Window.new(h, w , t, l)
182
+ end
183
+ # @param [:symbol] :error or :status kind of message
184
+ #private
185
+ def _print_message type, text, aconfig={}, &block #:nodoc:
186
+ case text
187
+ when Canis::Variable # added 2011-09-20 incase variable passed
188
+ text = text.get_value
189
+ when Exception
190
+ text = text.to_s
191
+ end
192
+ # NOTE we are polluting global namespace
193
+ # fixed on 2011-12-6 . to test
194
+ #aconfig.each_pair { |k,v| instance_variable_set("@#{k}",v) }
195
+ color = aconfig[:color]
196
+ bgcolor = aconfig[:bgcolor]
197
+ ewin = _create_footer_window #*@layout
198
+ r = 0; c = 1;
199
+ case type
200
+ when :error
201
+ color ||= 'red'
202
+ bgcolor ||= 'black'
203
+ else
204
+ color ||= :white
205
+ bgcolor ||= :black
206
+ end
207
+ color_pair = get_color($promptcolor, color, bgcolor)
208
+ color_pair = aconfig[:color_pair] || color_pair
209
+ ewin.bkgd(Ncurses.COLOR_PAIR(color_pair));
210
+ ewin.printstring r, c, text, color_pair
211
+ ewin.printstring(r+1, c, "Press a key ", color_pair) unless aconfig[:wait]
212
+ ewin.wrefresh
213
+ if aconfig[:wait]
214
+ #try this out, if user wants a wait, then it will wait for 5 seconds, or if a key is pressed sooner
215
+ value = aconfig[:wait]
216
+ if value.is_a? Fixnum
217
+ value = value * 10
218
+ else
219
+ value = 50
220
+ end
221
+ Ncurses::halfdelay(tenths = value)
222
+ ewin.getch
223
+ Ncurses::halfdelay(tenths = 10)
224
+ else
225
+ ewin.getchar
226
+ end
227
+ ewin.destroy
228
+ end
229
+ #
230
+ # Alternative to +confirm+ dialog, if you want this look and feel, at last 2 lines of screen
231
+ # @param [String] text to prompt
232
+ # @return [true, false] 'y' is true, all else if false
233
+ public
234
+ def rb_confirm text, aconfig={}, &block
235
+ # backward compatibility with agree()
236
+ if aconfig == true || aconfig == false
237
+ default = aconfig
238
+ aconfig = {}
239
+ else
240
+ default = aconfig[:default]
241
+ end
242
+ case text
243
+ when Canis::Variable # added 2011-09-20 incase variable passed
244
+ text = text.get_value
245
+ when Exception
246
+ text = text.to_s
247
+ end
248
+ ewin = _create_footer_window
249
+ r = 0; c = 1;
250
+ #aconfig.each_pair { |k,v| instance_variable_set("@#{k}",v) }
251
+ # changed on 2011-12-6
252
+ color = aconfig[:color]
253
+ bgcolor = aconfig[:bgcolor]
254
+ color ||= :white
255
+ bgcolor ||= :black
256
+ color_pair = get_color($promptcolor, color, bgcolor)
257
+ ewin.bkgd(Ncurses.COLOR_PAIR(color_pair));
258
+ ewin.printstring r, c, text, color_pair
259
+ ewin.printstring r+1, c, "[y/n]", color_pair
260
+ ewin.wrefresh
261
+ #retval = :NO # consistent with confirm # CHANGE TO TRUE FALSE NOW
262
+ retval = false
263
+ begin
264
+ ch = ewin.getchar
265
+ retval = (ch == 'y'.ord || ch == 'Y'.ord )
266
+ # if caller passed a default value and user pressed ENTER return that
267
+ # can be true or false so don't change this to "if default". 2011-12-8
268
+ if !default.nil?
269
+ if ch == 13 || ch == KEY_ENTER
270
+ retval = default
271
+ end
272
+ end
273
+ #retval = :YES if ch.chr == 'y'
274
+ ensure
275
+ ewin.destroy
276
+ end
277
+ retval
278
+ end
279
+ alias :agree :rb_confirm
280
+ # class created to display multiple messages without asking for user to hit a key
281
+ # returns a window to which one can keep calling printstring with 0 or 1 as row.
282
+ # destroy when finished.
283
+ # Also, one can pause if one wants, or linger.
284
+ # This is meant to be a replacement for the message_immediate and message_raw
285
+ # I was trying out in App.rb. 2011-10-1 1:27 AM
286
+ # Testing from test2.rb
287
+ # TODO: add option of putting progress_bar
288
+ class StatusWindow # --- {{{
289
+ attr_reader :h, :w, :top, :left # height, width, top row, left col of window
290
+ attr_reader :win
291
+ attr_accessor :color_pair
292
+ def initialize config={}, &block
293
+ @color_pair = config[:color_pair]
294
+ @row_offset = config[:row_offset] || 0
295
+ @col_offset = config[:col_offset] || 0
296
+ create_window *config[:layout]
297
+ end
298
+ def create_window h = 2 , w = Ncurses.COLS-0, t = Ncurses.LINES-2, l = 0
299
+ return @win if @win
300
+ @win = Canis::Window.new(h, w , t, l)
301
+ @h = h ; @w = w; @top = t ; @left = l
302
+ @color_pair ||= get_color($promptcolor, 'white','black')
303
+ @win.bkgd(Ncurses.COLOR_PAIR(@color_pair));
304
+ @win
305
+ end
306
+ # creates a color pair based on given bg and fg colors as strings
307
+ #def set_colors bgcolor, fgcolor='white'
308
+ #@color_pair = get_color($datacolor, 'white','black')
309
+ #end
310
+ # prints a string on given row (0 or 1)
311
+ def printstring r, c, text, color_pair=@color_pair
312
+ create_window unless @win
313
+ show unless @visible
314
+ r = @h-1 if r > @h-1
315
+ #@win.printstring r, c, ' '*@w, @color_pair
316
+ # FIXME this padding overwrites the border and the offset means next line wiped
317
+ # However, now it may now totally clear a long line.
318
+ @win.printstring r+@row_offset, c+@col_offset, "%-*s" % [@w-(@col_offset*2)-c, text], color_pair
319
+ @win.wrefresh
320
+ end
321
+ # print given strings from first first column onwards
322
+ def print *textarray
323
+ create_window unless @win
324
+ show unless @visible
325
+ c = 1
326
+ textarray.each_with_index { |s, i|
327
+ @win.printstring i+@row_offset, c+@col_offset, "%-*s" % [@w-(@col_offset*2)-c, s], @color_pair
328
+ }
329
+ @win.wrefresh
330
+ end
331
+ def pause; @win.getchar; end
332
+ # pauses with the message, but doesn't ask the user to press a key.
333
+ # If he does, the key should be used by underlying window.
334
+ # Do not call destroy if you call linger, it does the destroy.
335
+ def linger caller_window=nil
336
+ begin
337
+ if caller_window
338
+ ch = @win.getchar
339
+ caller_window.ungetch(ch) # will this be available to underlying window XXX i think not !!
340
+ else
341
+ sleep 1
342
+ end
343
+ ensure
344
+ destroy
345
+ end
346
+ end
347
+ # caller must destroy after he's finished printing messages, unless
348
+ # user calls linger
349
+ def destroy; @win.destroy if @win; @win = nil; end
350
+ def hide
351
+ @win.hide
352
+ @visible = false
353
+ end
354
+ def show
355
+ @win.show unless @visible
356
+ @visible = true
357
+ end
358
+ end # }}}
359
+ # returns instance of a status_window for sending multiple
360
+ # statuses during some process
361
+ def status_window aconfig={}, &block
362
+ return StatusWindow.new aconfig
363
+ end
364
+ # this is a popup dialog box on which statuses can be printed as a process is taking place.
365
+ # I am reusing StatusWindow and so there's an issue since I've put a box, so in clearing
366
+ # the line, I might overwrite the box
367
+ def progress_dialog aconfig={}, &block
368
+ aconfig[:layout] = [10,60,10,20]
369
+ window = status_window aconfig
370
+ height = 10; width = 60
371
+ window.win.print_border_mb 1,2, height, width, $normalcolor, FFI::NCurses::A_REVERSE
372
+ return window
373
+ end
374
+ #
375
+ # Display a popup and return the seliected index from list
376
+ # Config includes row and col and title of window
377
+ # You may also pass bgcolor and color
378
+ # Returns index of selected row on pressing ENTER or space
379
+ # In case of multiple selection, returns array of selected indices only on ENTER
380
+ # Returns nil if C-q pressed
381
+ # 2014-04-15 - 17:05 replaced rlist with listbox
382
+ def popuplist list, config={}, &block
383
+ raise ArgumentError, "Nil list received by popuplist" unless list
384
+ #require 'canis/core/widgets/rlist'
385
+
386
+ max_visible_items = config[:max_visible_items]
387
+ # FIXME have to ensure that row and col don't exceed FFI::NCurses.LINES and cols that is the window
388
+ # should not FINISH outside or padrefresh will fail.
389
+ row = config[:row] || 5
390
+ col = config[:col] || 5
391
+ relative_to = config[:relative_to]
392
+ if relative_to
393
+ layout = relative_to.form.window.layout
394
+ row += layout[:top]
395
+ col += layout[:left]
396
+ end
397
+ config.delete :relative_to
398
+ width = config[:width] || longest_in_list(list)+2 # borders take 2
399
+ if config[:title]
400
+ width = config[:title].size + 2 if width < config[:title].size
401
+ end
402
+ height = config[:height]
403
+ height ||= [max_visible_items || 10+2, list.length+2].min
404
+ #layout(1+height, width+4, row, col)
405
+ layout = { :height => 0+height, :width => 0+width, :top => row, :left => col }
406
+ window = Canis::Window.new(layout)
407
+ form = Canis::Form.new window
408
+
409
+ listconfig = config[:listconfig] || {}
410
+ listconfig[:list] = list
411
+ listconfig[:width] = width
412
+ listconfig[:height] = height
413
+ listconfig[:selection_mode] ||= :single
414
+ listconfig.merge!(config)
415
+ listconfig.delete(:row);
416
+ listconfig.delete(:col);
417
+ # trying to pass populists block to listbox
418
+ lb = Canis::Listbox.new form, listconfig, &block
419
+
420
+ # added next line so caller can configure listbox with
421
+ # events such as ENTER_ROW, LEAVE_ROW or LIST_SELECTION_EVENT or PRESS
422
+ # 2011-11-11
423
+ #yield lb if block_given? # No it won't work since this returns
424
+ window.bkgd(Ncurses.COLOR_PAIR($reversecolor));
425
+ window.wrefresh
426
+ Ncurses::Panel.update_panels
427
+ form.repaint
428
+ window.wrefresh
429
+ begin
430
+ while((ch = window.getchar()) != 999 )
431
+ case ch
432
+ when -1
433
+ next
434
+ when ?\C-q.getbyte(0)
435
+ break
436
+ else
437
+ lb.handle_key ch
438
+ form.repaint
439
+ if ch == 13 || ch == 10
440
+ return lb.current_index if lb.selection_mode != :multiple
441
+
442
+ x = lb.selected_indices
443
+ # now returns empty array not nil
444
+ return x if x and !x.empty?
445
+ x = lb.current_index
446
+ return [x]
447
+ # if multiple selection, then return list of selected_indices and don't catch 32
448
+ elsif ch == $row_selector # if single selection, earlier 32
449
+ return lb.current_index if lb.selection_mode != :multiple
450
+ end
451
+ #yield ch if block_given?
452
+ end
453
+ end
454
+ ensure
455
+ window.destroy
456
+ end
457
+ return nil
458
+ end
459
+ # returns length of longest
460
+ def longest_in_list list #:nodoc:
461
+ raise ArgumentError, "rdialog.rb: longest_in_list recvd nil list" unless list
462
+ longest = list.inject(0) do |memo,word|
463
+ memo >= word.length ? memo : word.length
464
+ end
465
+ longest
466
+ end
467
+ # this routine prints help_text for an application
468
+ # If help_text has been set using install_help_text
469
+ # it will be displayed. Else, general help will be
470
+ # displayed. Even when custom help is displayed,
471
+ # user may use <next> to see general help.
472
+ #
473
+ # earlier in app.rb
474
+ def display_app_help form=@form
475
+ raise "This is now deprecated, pls use @form.help_manager.display_help "
476
+ if form
477
+ hm = form.help_manager
478
+ if !hm.help_text
479
+ arr = nil
480
+ # these 2 only made sense from app.rb and should be removed, too implicit
481
+ if respond_to? :help_text
482
+ arr = help_text
483
+ end
484
+ hm.help_text(arr) if arr
485
+ end
486
+ form.help_manager.display_help
487
+ else
488
+ raise "Form needed by display_app_help. Use form.help_manager instead"
489
+ end
490
+ end
491
+ #
492
+ =begin
493
+ http://www.kammerl.de/ascii/AsciiSignature.php
494
+ ___
495
+ |__ \
496
+ ) |
497
+ / /
498
+ |_|
499
+ (_)
500
+
501
+ _
502
+ | |
503
+ | |
504
+ | |
505
+ |_|
506
+ (_)
507
+
508
+
509
+ _____ _ _____
510
+ | __ \ | | / ____|
511
+ | |__) | _| |__ _ _ | | _ _ _ __ ___ ___ ___
512
+ | _ / | | | '_ \| | | | | | | | | | '__/ __|/ _ \/ __|
513
+ | | \ \ |_| | |_) | |_| | | |___| |_| | | \__ \ __/\__ \
514
+ |_| \_\__,_|_.__/ \__, | \_____\__,_|_| |___/\___||___/
515
+ __/ |
516
+ |___/
517
+
518
+ =end
519
+
520
+