rbhex-core 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG +2000 -0
  4. data/LICENSE +56 -0
  5. data/README.md +44 -0
  6. data/examples/abasiclist.rb +179 -0
  7. data/examples/alpmenu.rb +50 -0
  8. data/examples/app.sample +19 -0
  9. data/examples/atree.rb +100 -0
  10. data/examples/bline.rb +136 -0
  11. data/examples/common/file.rb +45 -0
  12. data/examples/data/README.markdown +9 -0
  13. data/examples/data/brew.txt +38 -0
  14. data/examples/data/color.2 +37 -0
  15. data/examples/data/gemlist.txt +60 -0
  16. data/examples/data/lotr.txt +12 -0
  17. data/examples/data/ports.txt +136 -0
  18. data/examples/data/table.txt +37 -0
  19. data/examples/data/tasks.csv +88 -0
  20. data/examples/data/tasks.txt +27 -0
  21. data/examples/data/todo.txt +10 -0
  22. data/examples/data/todo.txt.bak +10 -0
  23. data/examples/data/todocsv.csv +28 -0
  24. data/examples/data/unix1.txt +21 -0
  25. data/examples/data/unix2.txt +11 -0
  26. data/examples/dbdemo.rb +502 -0
  27. data/examples/dirtree.rb +94 -0
  28. data/examples/newtabbedwindow.rb +100 -0
  29. data/examples/newtesttabp.rb +92 -0
  30. data/examples/tabular.rb +146 -0
  31. data/examples/tasks.rb +178 -0
  32. data/examples/term2.rb +84 -0
  33. data/examples/testbuttons.rb +296 -0
  34. data/examples/testcombo.rb +102 -0
  35. data/examples/testfields.rb +195 -0
  36. data/examples/testkeypress.rb +72 -0
  37. data/examples/testlistbox.rb +170 -0
  38. data/examples/testmessagebox.rb +140 -0
  39. data/examples/testprogress.rb +116 -0
  40. data/examples/testree.rb +106 -0
  41. data/examples/testwsshortcuts.rb +66 -0
  42. data/examples/testwsshortcuts2.rb +128 -0
  43. data/lib/rbhex.rb +6 -0
  44. data/lib/rbhex/core/docs/index.txt +73 -0
  45. data/lib/rbhex/core/include/action.rb +80 -0
  46. data/lib/rbhex/core/include/actionmanager.rb +49 -0
  47. data/lib/rbhex/core/include/appmethods.rb +214 -0
  48. data/lib/rbhex/core/include/bordertitle.rb +48 -0
  49. data/lib/rbhex/core/include/chunk.rb +203 -0
  50. data/lib/rbhex/core/include/io.rb +553 -0
  51. data/lib/rbhex/core/include/listbindings.rb +74 -0
  52. data/lib/rbhex/core/include/listcellrenderer.rb +140 -0
  53. data/lib/rbhex/core/include/listeditable.rb +317 -0
  54. data/lib/rbhex/core/include/listscrollable.rb +663 -0
  55. data/lib/rbhex/core/include/listselectable.rb +271 -0
  56. data/lib/rbhex/core/include/multibuffer.rb +83 -0
  57. data/lib/rbhex/core/include/orderedhash.rb +77 -0
  58. data/lib/rbhex/core/include/ractionevent.rb +73 -0
  59. data/lib/rbhex/core/include/rchangeevent.rb +27 -0
  60. data/lib/rbhex/core/include/rhistory.rb +95 -0
  61. data/lib/rbhex/core/include/rinputdataevent.rb +47 -0
  62. data/lib/rbhex/core/include/vieditable.rb +172 -0
  63. data/lib/rbhex/core/include/widgetmenu.rb +66 -0
  64. data/lib/rbhex/core/system/colormap.rb +165 -0
  65. data/lib/rbhex/core/system/keyboard.rb +150 -0
  66. data/lib/rbhex/core/system/keydefs.rb +30 -0
  67. data/lib/rbhex/core/system/ncurses.rb +236 -0
  68. data/lib/rbhex/core/system/panel.rb +162 -0
  69. data/lib/rbhex/core/system/window.rb +913 -0
  70. data/lib/rbhex/core/util/ansiparser.rb +119 -0
  71. data/lib/rbhex/core/util/app.rb +1228 -0
  72. data/lib/rbhex/core/util/basestack.rb +410 -0
  73. data/lib/rbhex/core/util/bottomline.rb +1859 -0
  74. data/lib/rbhex/core/util/colorparser.rb +77 -0
  75. data/lib/rbhex/core/util/focusmanager.rb +31 -0
  76. data/lib/rbhex/core/util/padreader.rb +192 -0
  77. data/lib/rbhex/core/util/rcommandwindow.rb +604 -0
  78. data/lib/rbhex/core/util/rdialogs.rb +574 -0
  79. data/lib/rbhex/core/util/viewer.rb +149 -0
  80. data/lib/rbhex/core/util/widgetshortcuts.rb +506 -0
  81. data/lib/rbhex/core/version.rb +5 -0
  82. data/lib/rbhex/core/widgets/applicationheader.rb +103 -0
  83. data/lib/rbhex/core/widgets/box.rb +58 -0
  84. data/lib/rbhex/core/widgets/divider.rb +310 -0
  85. data/lib/rbhex/core/widgets/keylabelprinter.rb +194 -0
  86. data/lib/rbhex/core/widgets/rcombo.rb +253 -0
  87. data/lib/rbhex/core/widgets/rcontainer.rb +415 -0
  88. data/lib/rbhex/core/widgets/rlink.rb +30 -0
  89. data/lib/rbhex/core/widgets/rlist.rb +696 -0
  90. data/lib/rbhex/core/widgets/rmenu.rb +958 -0
  91. data/lib/rbhex/core/widgets/rmenulink.rb +22 -0
  92. data/lib/rbhex/core/widgets/rmessagebox.rb +387 -0
  93. data/lib/rbhex/core/widgets/rprogress.rb +118 -0
  94. data/lib/rbhex/core/widgets/rtabbedpane.rb +634 -0
  95. data/lib/rbhex/core/widgets/rtabbedwindow.rb +70 -0
  96. data/lib/rbhex/core/widgets/rtextarea.rb +960 -0
  97. data/lib/rbhex/core/widgets/rtextview.rb +739 -0
  98. data/lib/rbhex/core/widgets/rtree.rb +768 -0
  99. data/lib/rbhex/core/widgets/rwidget.rb +3277 -0
  100. data/lib/rbhex/core/widgets/scrollbar.rb +143 -0
  101. data/lib/rbhex/core/widgets/statusline.rb +113 -0
  102. data/lib/rbhex/core/widgets/tabular.rb +264 -0
  103. data/lib/rbhex/core/widgets/tabularwidget.rb +1142 -0
  104. data/lib/rbhex/core/widgets/textpad.rb +995 -0
  105. data/lib/rbhex/core/widgets/tree/treecellrenderer.rb +150 -0
  106. data/lib/rbhex/core/widgets/tree/treemodel.rb +428 -0
  107. data/rbhex-core.gemspec +32 -0
  108. metadata +172 -0
@@ -0,0 +1,553 @@
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
+ # Changes:
11
+ # 2011-12-6 : removed many old, outdated methods.
12
+ #*******************************************************#
13
+ module RubyCurses
14
+ module Io
15
+
16
+ # create a 2 line window at bottom to accept user input
17
+ #
18
+ def __create_footer_window h = 2 , w = Ncurses.COLS, t = Ncurses.LINES-2, l = 0
19
+ ewin = VER::Window.new(h, w , t, l)
20
+ end
21
+ # 2011-11-27 I have replaced the getting of chars with a field
22
+
23
+ # routine to get a string at bottom of window.
24
+ # The first 3 params are no longer required since we create a window
25
+ # of our own.
26
+ # @param [String] prompt - label to show
27
+ # @param [Fixnum] maxlen - max length of input
28
+ # @param [Hash] config - :default, :display_length of Field, :help_text, :tab_completion
29
+ # help_text is displayed on F1
30
+ # tab_completion is a proc which helps to complete user input
31
+ # This method is now only for backward compatibility
32
+ # rbgetstr had various return codes based on whether user asked for help
33
+ # possibly mimicking alpine, or because i could do nothing about it.
34
+ # Now, rbgets handles that and only returns if the user cancels or enters
35
+ # a string, so rbgets does not need to return other codes.
36
+ def rbgetstr(nolongerused, r, c, prompt, maxlen, config={})
37
+ config[:maxlen] = maxlen
38
+ str = rb_gets(prompt, config)
39
+ if str
40
+ return 0, str
41
+ else
42
+ return -1, nil
43
+ end
44
+ end
45
+
46
+ # get a string at the bottom of the screen
47
+ #
48
+ # @param [String] prompt - label to show
49
+ # @param [Hash] config - :default, :display_length of Field, :help_text, :tab_completion
50
+ # help_text is displayed on F1
51
+ # tab_completion is a proc which helps to complete user input
52
+ # @yield [Field] for overriding or customization
53
+ # @return [String, nil] String if entered, nil if canceled
54
+ def rb_gets(prompt, config={}) # yield field
55
+ if config.is_a? Array
56
+ options = config
57
+ completion_proc = Proc.new{|str|
58
+ options.dup.grep Regexp.new("^#{str}");
59
+ }
60
+ config = {}
61
+ config[:tab_completion] = completion_proc
62
+ end
63
+ begin
64
+ win = __create_footer_window
65
+ form = Form.new win
66
+ r = 0; c = 1;
67
+ default = config[:default] || ""
68
+ prompt = "#{prompt} [#{default}]:" if default.size > 0
69
+ _max = FFI::NCurses.COLS-1-prompt.size-4
70
+ displen = config[:display_length] || [config[:maxlen] || 999, _max].min
71
+ maxlen = config[:maxlen] || _max
72
+ field = Field.new form, :row => r, :col => c, :maxlen => maxlen, :default => default, :label => prompt,
73
+ :display_length => displen
74
+ bg = Ncurses.COLORS >= 236 ? 233 : :blue
75
+ field.bgcolor = bg
76
+ field.cursor_end if default.size > 0
77
+ def field.default=(x); default(x);end
78
+
79
+ # if user wishes to use the yield and say "field.history = [x,y,z] then
80
+ # we should alredy have extended this, so lets make it permanent
81
+ #if config[:history]
82
+ #raise ArgumentError, "Field history must be an array" unless config[:history].is_a? Array
83
+ require 'rbhex/core/include/rhistory'
84
+ field.extend(FieldHistory)
85
+ #field.history_config :row =>
86
+ field.history = config[:history]
87
+ #end
88
+
89
+ yield field if block_given?
90
+ form.repaint
91
+ win.wrefresh
92
+ prevchar = 0
93
+ entries = nil
94
+ oldstr = nil # for tab completion, origal word entered by user
95
+ while ((ch = win.getchar()) != 999)
96
+ break if ch == 10 || ch == 13 || ch == KEY_ENTER
97
+ #return -1, nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
98
+ return nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
99
+ #if ch == ?\M-h.getbyte(0) # HELP KEY
100
+ #help_text = config[:help_text] || "No help provided"
101
+ #color = $datacolor
102
+ #print_help(win, r, c, color, help_text)
103
+ ## this will come over our text
104
+ #end
105
+ # TODO tab completion and help_text print on F1
106
+ # that field objects can extend, same for tab completion and gmail completion
107
+ if ch == KEY_TAB
108
+ if config
109
+ str = field.text
110
+ if prevchar == KEY_TAB
111
+ if !entries.nil? && !entries.empty?
112
+ str = entries.delete_at(0)
113
+ else
114
+ str = oldstr if oldstr
115
+ prevchar = ch = nil # so it can start again completing
116
+ end
117
+ else
118
+ tabc = config[:tab_completion] unless tabc
119
+ next unless tabc
120
+ oldstr = str.dup
121
+ entries = tabc.call(str).dup
122
+ $log.debug " tab got #{entries} for str=#{str}"
123
+ str = entries.delete_at(0) unless entries.nil? || entries.empty?
124
+ str = str.to_s.dup
125
+ end
126
+ if str
127
+ field.text = str
128
+ field.cursor_end
129
+ field.set_form_col # shit why are we doign this, text sets curpos to 0
130
+ end
131
+ form.repaint
132
+ win.wrefresh
133
+ end
134
+
135
+ # tab_completion
136
+ # if previous char was not tab, execute tab_completion_proc and push first entry
137
+ # else push the next entry
138
+ elsif ch == KEY_F1
139
+ help_text = config[:help_text] || "No help provided. C-c/C-g aborts. <TAB> completion. Alt-h history. C-a/e"
140
+ print_status_message help_text, :wait => 7
141
+ else
142
+ form.handle_key ch
143
+ end
144
+ prevchar = ch
145
+ win.wrefresh
146
+ end
147
+ rescue => err
148
+ Ncurses.beep
149
+ textdialog [err.to_s, *err.backtrace], :title => "Exception"
150
+ $log.error "EXC in rbgetsr #{err} "
151
+ $log.error(err.backtrace.join("\n"))
152
+ ensure
153
+ win.destroy if win
154
+ end
155
+ config[:history] << field.text if config[:history] && field.text
156
+ return field.text
157
+ end
158
+
159
+ # get a character.
160
+ # unlike rb_gets allows user to enter control or alt or function character too.
161
+ # @param [String] prompt or label to show.
162
+ # @param [Hash] configuration such as default or regexp for validation
163
+ # @return [Fixnum] nil if canceled, or ret value of getchar which is numeric
164
+ # If default provided, then ENTER returns the default
165
+ def rb_getchar(prompt, config={}) # yield field
166
+ begin
167
+ win = __create_footer_window
168
+ #form = Form.new win
169
+ r = 0; c = 1;
170
+ default = config[:default]
171
+ prompt = "#{prompt} [#{default}] " if default
172
+ win.mvprintw(r, c, "%s: " % prompt);
173
+ bg = Ncurses.COLORS >= 236 ? 236 : :blue
174
+ color_pair = get_color($reversecolor, :white, bg)
175
+ win.printstring r, c + prompt.size + 2, " ", color_pair
176
+
177
+ win.wrefresh
178
+ prevchar = 0
179
+ entries = nil
180
+ while ((ch = win.getchar()) != 999)
181
+ return default.ord if default && (ch == 13 || ch == KEY_ENTER)
182
+ return nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
183
+ if ch == KEY_F1
184
+ help_text = config[:help_text] || "No help provided. C-c/C-g aborts."
185
+ print_status_message help_text, :wait => 7
186
+ win.wrefresh # nevr had to do this with ncurses, but have to with ffi-ncurses ??
187
+ next
188
+ end
189
+ if config[:regexp]
190
+ reg = config[:regexp]
191
+ if ch > 0 && ch < 256
192
+ chs = ch.chr
193
+ return ch if chs =~ reg
194
+ alert "Wrong character. #{reg} "
195
+ else
196
+ alert "Wrong character. #{reg} "
197
+ end
198
+ else
199
+ return ch
200
+ end
201
+ #form.handle_key ch
202
+ win.wrefresh
203
+ end
204
+ rescue => err
205
+ Ncurses.beep
206
+ $log.error "EXC in rbgetsr #{err} "
207
+ $log.error(err.backtrace.join("\n"))
208
+ ensure
209
+ win.destroy if win
210
+ end
211
+ return nil
212
+ end
213
+
214
+ # This is just experimental, trying out tab_completion
215
+ # Prompt user for a file name, allowing him to tab to complete filenames
216
+ # @param [String] label to print before field
217
+ # @param [Fixnum] max length of field
218
+ # @return [String] filename or blank if user cancelled
219
+ def get_file prompt, config={} #:nodoc:
220
+ maxlen = 70
221
+ tabc = Proc.new {|str| Dir.glob(str +"*") }
222
+ config[:tab_completion] ||= tabc
223
+ #config[:default] = "test"
224
+ ret, str = rbgetstr(nil,0,0, prompt, maxlen, config)
225
+ #$log.debug " get_file returned #{ret} , #{str} "
226
+ return "" if ret != 0
227
+ return str
228
+ end
229
+ def clear_this win, r, c, color, len
230
+ print_this(win, "%-*s" % [len," "], color, r, c)
231
+ end
232
+
233
+
234
+
235
+ ##
236
+ # prints given text to window, in color at x and y coordinates
237
+ # @param [Window] window to write to
238
+ # @param [String] text to print
239
+ # @param [int] color pair such as $datacolor or $promptcolor
240
+ # @param [int] x row
241
+ # @param [int] y col
242
+ # @see Window#printstring
243
+ def print_this(win, text, color, x, y)
244
+ raise "win nil in print_this" unless win
245
+ color=Ncurses.COLOR_PAIR(color);
246
+ win.attron(color);
247
+ #win.mvprintw(x, y, "%-40s" % text);
248
+ win.mvprintw(x, y, "%s" % text);
249
+ win.attroff(color);
250
+ win.refresh
251
+ end
252
+
253
+
254
+ #
255
+ # warn user: currently flashes and places error in log file
256
+ # experimental, may change interface later
257
+ # it does not say anything on screen
258
+ # @param [String] text of error/warning to put in log
259
+ # @since 1.1.5
260
+ def warn string
261
+ $log.warn string
262
+ Ncurses.beep
263
+ end
264
+
265
+ #def add_item hotkey, label, desc,action
266
+ #
267
+ ## A *simple* way of creating menus that will appear in a single row.
268
+ # This copies the menu at the bottom of "most" upon pressing ":".
269
+ # hotkey is the key to invoke an item (a single digit letter)
270
+ #
271
+ # label is an action name
272
+ #
273
+ # desc is a description displayed after an item is chosen. Usually, its like:
274
+ #+ "Folding has been enabled" or "Searches will now be case sensitive"
275
+ #
276
+ # action may be a Proc or a symbol which will be called if item selected
277
+ #+ action may be another menu, so recursive menus can be built, but each
278
+ #+ should fit in a line, its a simple system.
279
+
280
+ CMenuItem = Struct.new( :hotkey, :label, :desc, :action )
281
+
282
+
283
+ ## An encapsulated form of yesterday's Most Menu
284
+ # It keeps the internals away from the user.
285
+ # Its not really OOP in the sense that the PromptMenu is not a MenuItem. That's how it is in
286
+ # our Menu system, and that led to a lot of painful coding (at least for me). This is quite
287
+ # simple. A submenu contains a PromptMenu in its action object and is evaluated in a switch.
288
+ # A recursive loop handles submenus.
289
+ #
290
+ # Prompting of menu options with suboptions etc.
291
+ # A block of code or symbol or proc is executed for any leaf node
292
+ # This allows us to define different menus for different objects on the screen, and not have to map
293
+ # all kinds of control keys for operations, and have the user remember them. Only one key invokes the menu
294
+ # and the rest are ordinary characters.
295
+ #
296
+ # == Example
297
+ # menu = PromptMenu.new self do
298
+ # item :s, :goto_start
299
+ # item :b, :goto_bottom
300
+ # item :r, :scroll_backward
301
+ # item :l, :scroll_forward
302
+ # submenu :m, "submenu" do
303
+ # item :p, :goto_last_position
304
+ # item :r, :scroll_backward
305
+ # item :l, :scroll_forward
306
+ # end
307
+ # end
308
+ # menu.display @form.window, $error_message_row, $error_message_col, $datacolor #, menu
309
+
310
+ class PromptMenu
311
+ include Io
312
+ attr_reader :text
313
+ attr_reader :options
314
+ def initialize caller, text="Choose:", &block
315
+ @caller = caller
316
+ @text = text
317
+ @options = []
318
+ yield_or_eval &block if block_given?
319
+ end
320
+ def add *menuitem
321
+ item = nil
322
+ case menuitem.first
323
+ when CMenuItem
324
+ item = menuitem.first
325
+ @options << item
326
+ else
327
+ case menuitem.size
328
+ when 4
329
+ item = CMenuItem.new(*menuitem.flatten)
330
+ when 2
331
+ # if user only sends key and symbol
332
+ menuitem[3] = menuitem[1]
333
+ item = CMenuItem.new(*menuitem.flatten)
334
+ when 1
335
+ if menuitem.first.is_a? Action
336
+ item = menuitem.first
337
+ else
338
+ raise ArgumentError, "Don't know how to handle #{menuitem.size} : #{menuitem} "
339
+ end
340
+ else
341
+ raise ArgumentError, "Don't know how to handle #{menuitem.size} : #{menuitem} "
342
+ end
343
+ @options << item
344
+ end
345
+ return item
346
+ end
347
+ alias :item :add
348
+ def create_mitem *args
349
+ item = CMenuItem.new(*args.flatten)
350
+ end
351
+ # Added this, since actually it could have been like this 2011-12-22
352
+ def self.create_menuitem *args
353
+ item = CMenuItem.new(*args.flatten)
354
+ end
355
+ # create the whole thing using a MenuTree which has minimal information.
356
+ # It uses a hotkey and a code only. We are supposed to resolve the display text
357
+ # and actual proc from the caller using this code.
358
+ def menu_tree mt, pm = self
359
+ mt.each_pair { |ch, code|
360
+ if code.is_a? RubyCurses::MenuTree
361
+ item = pm.add(ch, code.value, "")
362
+ current = PromptMenu.new @caller, code.value
363
+ item.action = current
364
+ menu_tree code, current
365
+ else
366
+ item = pm.add(ch, code.to_s, "", code)
367
+ end
368
+ }
369
+ end
370
+ #
371
+ # To allow a more rubyesque way of defining menus and submenus
372
+ def submenu key, label, &block
373
+ item = CMenuItem.new(key, label)
374
+ @options << item
375
+ item.action = PromptMenu.new @caller, label, &block
376
+ end
377
+ #
378
+ # Display prompt_menu in columns using commandwindow
379
+ # This is an improved way of showing the "most" like menu. The earlier
380
+ # format would only print in one row.
381
+ #
382
+ def display_columns config={}
383
+ prompt = config[:prompt] || "Choose: "
384
+ require 'rbhex/core/util/rcommandwindow'
385
+ layout = { :height => 5, :width => Ncurses.COLS-0, :top => Ncurses.LINES-6, :left => 0 }
386
+ rc = CommandWindow.new nil, :layout => layout, :box => true, :title => config[:title] || "Menu"
387
+ w = rc.window
388
+ r = 4
389
+ c = 1
390
+ color = $datacolor
391
+ begin
392
+ menu = @options
393
+ $log.debug " DISP MENU "
394
+ ret = 0
395
+ len = 80
396
+ while true
397
+ h = {}
398
+ valid = []
399
+ labels = []
400
+ menu.each{ |item|
401
+ if item.respond_to? :hotkey
402
+ hk = item.hotkey.to_s
403
+ else
404
+ raise ArgumentError, "Promptmenu needs hotkey or mnemonic"
405
+ end
406
+ # 187compat 2013-03-20 - 19:00 throws up
407
+ labels << "%c. %s " % [ hk.getbyte(0), item.label ]
408
+ h[hk] = item
409
+ valid << hk
410
+ }
411
+ #$log.debug " valid are #{valid} "
412
+ color = $datacolor
413
+ #print_this(win, str, color, r, c)
414
+ rc.display_menu labels, :indexing => :custom
415
+ ch=w.getchar()
416
+ rc.clear
417
+ #$log.debug " got ch #{ch} "
418
+ next if ch < 0 or ch > 255
419
+ if ch == 3 || ch == ?\C-g.getbyte(0)
420
+ clear_this w, r, c, color, len
421
+ print_this(w, "Aborted.", color, r,c)
422
+ break
423
+ end
424
+ ch = ch.chr
425
+ index = valid.index ch
426
+ if index.nil?
427
+ clear_this w, r, c, color, len
428
+ print_this(w, "Not valid. Valid are #{valid}. C-c/C-g to abort.", color, r,c)
429
+ sleep 1
430
+ next
431
+ end
432
+ #$log.debug " index is #{index} "
433
+ item = h[ch]
434
+ # I don;t think this even shows now, its useless
435
+ if item.respond_to? :desc
436
+ desc = item.desc
437
+ #desc ||= "Could not find desc for #{ch} "
438
+ desc ||= ""
439
+ clear_this w, r, c, color, len
440
+ print_this(w, desc, color, r,c)
441
+ end
442
+ action = item.action
443
+ case action
444
+ #when Array
445
+ when PromptMenu
446
+ # submenu
447
+ menu = action.options
448
+ title = rc.title
449
+ rc.title title +" => " + action.text # set title of window to submenu
450
+ when Proc
451
+ ret = action.call
452
+ break
453
+ when Symbol
454
+ if @caller.respond_to?(action, true)
455
+ $log.debug "XXX: IO caller responds to action #{action} "
456
+ ret = @caller.send(action)
457
+ elsif @caller.respond_to?(:execute_this, true)
458
+ ret = @caller.send(:execute_this, action)
459
+ else
460
+ alert "PromptMenu: unidentified action #{action} for #{@caller.class} "
461
+ raise "PromptMenu: unidentified action #{action} for #{@caller.class} "
462
+ end
463
+
464
+ break
465
+ else
466
+ $log.debug " Unidentified flying class #{action.class} "
467
+ break
468
+ end
469
+ end # while
470
+ ensure
471
+ rc.destroy
472
+ rc = nil
473
+ end
474
+ end
475
+ alias :display_new :display_columns
476
+
477
+ # Display the top level menu and accept user input
478
+ # Calls actions or symbols upon selection, or traverses submenus
479
+ # @return retvalue of last call or send, or 0
480
+ # @param win window
481
+ # @param r, c row and col to display on
482
+ # @param color text color (use $datacolor if in doubt)
483
+ # @see display_new - it presents in a much better manner
484
+ # and is not restricted to one row. Avoid this.
485
+ def display win, r, c, color
486
+ raise "Please use display_new, i've replace this with that"
487
+ # FIXME use a oneline window, user should not have to give all this crap.
488
+ # What about panning if we can;t fit, should we use horiz list to show ?
489
+ menu = @options
490
+ $log.debug " DISP MENU "
491
+ ret = 0
492
+ while true
493
+ str = @text.dup
494
+ h = {}
495
+ valid = []
496
+ menu.each{ |item|
497
+ hk = item.hotkey.to_s
498
+ str << "(%c) %s " % [ hk, item.label ]
499
+ h[hk] = item
500
+ valid << hk
501
+ }
502
+ #$log.debug " valid are #{valid} "
503
+ color = $datacolor
504
+ print_this(win, str, color, r, c)
505
+ ch=win.getchar()
506
+ #$log.debug " got ch #{ch} "
507
+ next if ch < 0 or ch > 255
508
+ if ch == 3 || ch == ?\C-g.getbyte(0)
509
+ clear_this win, r, c, color, str.length
510
+ print_this(win, "Aborted.", color, r,c)
511
+ break
512
+ end
513
+ ch = ch.chr
514
+ index = valid.index ch
515
+ if index.nil?
516
+ clear_this win, r, c, color, str.length
517
+ print_this(win, "Not valid. Valid are #{valid}", color, r,c)
518
+ sleep 1
519
+ next
520
+ end
521
+ #$log.debug " index is #{index} "
522
+ item = h[ch]
523
+ desc = item.desc
524
+ #desc ||= "Could not find desc for #{ch} "
525
+ desc ||= ""
526
+ clear_this win, r, c, color, str.length
527
+ print_this(win, desc, color, r,c)
528
+ action = item.action
529
+ case action
530
+ #when Array
531
+ when PromptMenu
532
+ # submenu
533
+ menu = action.options
534
+ str = "%s: " % action.text
535
+ when Proc
536
+ ret = action.call
537
+ break
538
+ when Symbol
539
+ ret = @caller.send(action)
540
+ break
541
+ else
542
+ $log.debug " Unidentified flying class #{action.class} "
543
+ break
544
+ end
545
+ end # while
546
+ return ret # ret val of last send or call
547
+ end
548
+ end # class PromptMenu
549
+
550
+ ### ADD HERE ###
551
+
552
+ end # module
553
+ end # module