rkumar-rbcurse 0.1.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 (52) hide show
  1. data/CHANGELOG +1577 -0
  2. data/README.txt +310 -0
  3. data/examples/qdfilechooser.rb +68 -0
  4. data/examples/rfe.rb +853 -0
  5. data/examples/rfe_renderer.rb +69 -0
  6. data/examples/test1.rb +242 -0
  7. data/examples/test2.rb +498 -0
  8. data/examples/testcombo.rb +95 -0
  9. data/examples/testkeypress.rb +61 -0
  10. data/examples/testmenu.rb +105 -0
  11. data/examples/testtable.rb +266 -0
  12. data/examples/testtabp.rb +106 -0
  13. data/examples/testtodo.rb +532 -0
  14. data/examples/viewtodo.rb +512 -0
  15. data/lib/rbcurse.rb +7 -0
  16. data/lib/rbcurse/action.rb +31 -0
  17. data/lib/rbcurse/applicationheader.rb +57 -0
  18. data/lib/rbcurse/celleditor.rb +120 -0
  19. data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
  20. data/lib/rbcurse/colormap.rb +133 -0
  21. data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
  22. data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
  23. data/lib/rbcurse/keylabelprinter.rb +143 -0
  24. data/lib/rbcurse/listcellrenderer.rb +99 -0
  25. data/lib/rbcurse/listkeys.rb +33 -0
  26. data/lib/rbcurse/listscrollable.rb +216 -0
  27. data/lib/rbcurse/listselectable.rb +67 -0
  28. data/lib/rbcurse/mapper.rb +108 -0
  29. data/lib/rbcurse/orderedhash.rb +77 -0
  30. data/lib/rbcurse/rcombo.rb +243 -0
  31. data/lib/rbcurse/rdialogs.rb +183 -0
  32. data/lib/rbcurse/rform.rb +845 -0
  33. data/lib/rbcurse/rinputdataevent.rb +36 -0
  34. data/lib/rbcurse/rlistbox.rb +804 -0
  35. data/lib/rbcurse/rmenu.rb +666 -0
  36. data/lib/rbcurse/rmessagebox.rb +325 -0
  37. data/lib/rbcurse/rpopupmenu.rb +754 -0
  38. data/lib/rbcurse/rtabbedpane.rb +259 -0
  39. data/lib/rbcurse/rtable.rb +1296 -0
  40. data/lib/rbcurse/rtextarea.rb +673 -0
  41. data/lib/rbcurse/rtextview.rb +335 -0
  42. data/lib/rbcurse/rwidget.rb +1731 -0
  43. data/lib/rbcurse/scrollable.rb +301 -0
  44. data/lib/rbcurse/selectable.rb +94 -0
  45. data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
  46. data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
  47. data/lib/ver/keyboard.rb +150 -0
  48. data/lib/ver/keyboard2.rb +170 -0
  49. data/lib/ver/ncurses.rb +102 -0
  50. data/lib/ver/window.rb +369 -0
  51. data/test/test_rbcurse.rb +0 -0
  52. metadata +117 -0
@@ -0,0 +1,666 @@
1
+ =begin
2
+ * Name: menu and related classes
3
+ * Description
4
+ * Author: rkumar
5
+ TODO
6
+ FIXME : works with 2 levels, but focus does not go into third level. This has been fixed in rpopupmenu
7
+ and needs to be fixed here. DONE 2009-01-21 12:50
8
+ - menu bar : what to do if adding a menu, or option later.
9
+ we dnt show disabld options in a way that user can know its disabled
10
+ - separate file created on 2008-12-24 17:58
11
+ NOTE : this program works but is one of the first programs and is untouched. It needs to be rewritten
12
+ since its quite crappy.
13
+ Also, we should move to Action classes as against just blokcs of code. And action class would have
14
+ a user friendly string to identifiy the action, as well as a disabled option.
15
+
16
+ --------
17
+ * Date: 2008-11-14 23:43
18
+ * License:
19
+ Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
20
+
21
+ =end
22
+ require 'rubygems'
23
+ require 'ncurses'
24
+ require 'logger'
25
+ require 'rbcurse'
26
+
27
+ include Ncurses
28
+ include RubyCurses
29
+ module RubyCurses
30
+ extend self
31
+
32
+
33
+ class MenuSeparator
34
+ attr_accessor :enabled
35
+ attr_accessor :parent
36
+ attr_accessor :row
37
+ attr_accessor :col
38
+ attr_accessor :width
39
+ def initialize
40
+ @enable = false
41
+ end
42
+ def repaint
43
+ @parent.window.printstring( @row, 0, "|%s|" % ("-"*@width), $reversecolor)
44
+ end
45
+ def destroy
46
+ end
47
+ def on_enter
48
+ end
49
+ def on_leave
50
+ end
51
+ def to_s
52
+ ""
53
+ end
54
+ end
55
+ ##
56
+ class MenuItem
57
+ attr_accessor :parent
58
+ # attr_accessor :window
59
+ attr_accessor :row
60
+ attr_accessor :col
61
+ attr_accessor :width
62
+ attr_accessor :accelerator
63
+ attr_accessor :enabled
64
+ attr_accessor :text, :mnemonic # changed reader to accessor
65
+ def initialize text, mnemonic=nil, &block
66
+ @text = text
67
+ @enabled = true
68
+ @mnemonic = mnemonic
69
+ instance_eval &block if block_given?
70
+ end
71
+ def to_s
72
+ "#{@text} #{@accelerator}"
73
+ end
74
+ def command *args, &block
75
+ $log.debug ">>>command : #{@text} "
76
+ @command = block if block_given?
77
+ @args = args
78
+ end
79
+ def on_enter
80
+ $log.debug ">>>on enter menuitem : #{@text} #{@row} #{@width} "
81
+ highlight
82
+ end
83
+ def on_leave
84
+ $log.debug ">>>on leave menuitem : #{@text} "
85
+ highlight false
86
+ end
87
+ ## XXX it could be a menu again
88
+ def fire
89
+ $log.debug ">>>fire menuitem : #{@text} #{@command} "
90
+ @command.call self, *@args if !@command.nil?
91
+ @parent.clear_menus
92
+ return :CLOSE # added 2009-01-02 00:09 to close only actions, not submenus
93
+ end
94
+ def highlight tf=true
95
+ if @parent.nil? or @parent.window.nil?
96
+ $log.debug "HL XXX #{self} parent nil"
97
+ $log.debug "HL XXX #{self} - > #{@parent} parent nil"
98
+ end
99
+ if tf
100
+ color = $datacolor
101
+ #@parent.window.mvchgat(y=@row, x=1, @width, Ncurses::A_NORMAL, color, nil)
102
+ # above line did not work in vt100, 200 terminals, next works.
103
+ @parent.window.mvchgat(y=@row, x=1, @width, Ncurses::A_REVERSE, $reversecolor, nil)
104
+ else
105
+ repaint
106
+ end
107
+ @parent.window.wrefresh unless @parent.window.nil? ## XXX 2009-01-21 22:00
108
+ end
109
+ def repaint # menuitem.repaint
110
+ if @parent.nil? or @parent.window.nil?
111
+ $log.debug "repaint #{self} parent nil"
112
+ # return
113
+ end
114
+ r = @row
115
+ acolor = $reversecolor
116
+ acolor = get_color($reversecolor, 'green', 'white') if !@enabled
117
+ @parent.window.printstring( @row, 0, "|%-*s|" % [@width, text], acolor)
118
+ if !@accelerator.nil?
119
+ @parent.window.printstring( r, (@width+1)-@accelerator.length, @accelerator, acolor)
120
+ elsif !@mnemonic.nil?
121
+ m = @mnemonic
122
+ ix = text.index(m) || text.index(m.swapcase)
123
+ charm = text[ix,1]
124
+ #@parent.window.printstring( r, ix+1, charm, $datacolor) if !ix.nil?
125
+ # prev line changed since not working in vt100 and vt200
126
+ @parent.window.printstring( r, ix+1, charm, $reversecolor, 'reverse') if !ix.nil?
127
+ end
128
+ end
129
+ def destroy
130
+ $log.debug "DESTRY menuitem #{@text}"
131
+ end
132
+ end
133
+ ##class Menu
134
+ class Menu < MenuItem ## NEW
135
+ attr_accessor :parent
136
+ attr_accessor :row
137
+ attr_accessor :col
138
+ attr_accessor :width
139
+ attr_accessor :enabled
140
+ attr_reader :text
141
+ attr_reader :items
142
+ attr_reader :window
143
+ attr_reader :panel
144
+ attr_reader :current_menu
145
+ attr_reader :row_margin ## 2009-01-21 12:06 NEW
146
+ ## this keeps a stack of menus. if we coud somehow put this in
147
+ # menubar would be great.
148
+ @@menus = []
149
+ @@row = 0
150
+ @@col = 0
151
+
152
+ def initialize text, &block
153
+ super text, nil, &block
154
+ @text = text
155
+ @items = []
156
+ @enabled = true
157
+ @current_menu = []
158
+ instance_eval &block if block_given?
159
+ @row ||=10
160
+ @col ||=10
161
+ @@menus ||= []
162
+ end
163
+ ## called upon firing so when we next show menubar there are not any left overs in here.
164
+ def clear_menus
165
+ @@menus = []
166
+ end
167
+ def to_s
168
+ @text
169
+ end
170
+ # item could be menuitem or another menu
171
+ def add menuitem
172
+ @items << menuitem
173
+ return self
174
+ end
175
+ def insert_separator ix
176
+ @items.insert ix, MenuSeparator.new
177
+ end
178
+ def add_separator
179
+ @items << MenuSeparator.new
180
+ end
181
+ ## added 2009-01-21 12:09 NEW
182
+ def get_item i
183
+ @items[i]
184
+ end
185
+ ## added 2009-01-21 12:09 NEW
186
+ def remove n
187
+ if n.is_a? Fixnum
188
+ @items.delete_at n
189
+ else
190
+ @items.delete n
191
+ end
192
+ end
193
+ # menu -
194
+ def fire
195
+ $log.debug "menu fire called: #{text} "
196
+ if @window.nil?
197
+ #repaint
198
+ create_window
199
+ if !@parent.is_a? RubyCurses::MenuBar
200
+ @parent.current_menu << self
201
+ @@menus << self # NEW
202
+ end
203
+ else
204
+ ### shouod this not just show ?
205
+ $log.debug "menu fire called: #{text} ELSE XXX WHEN IS THIS CALLED ? 658 "
206
+ return @items[@active_index].fire # this should happen if selected. else selected()
207
+ end
208
+ #@action.call if !@action.nil?
209
+ end
210
+ # user has clicked down, we shoud display items
211
+ # DRAW menuitems
212
+ def repaint # menu.repaint
213
+ return if @items.nil? or @items.empty?
214
+ $log.debug "menu repaint: #{text} row #{@row} col #{@col} "
215
+ if !@parent.is_a? RubyCurses::MenuBar
216
+ @parent.window.printstring( @row, 0, "|%-*s>|" % [@width-1, text], $reversecolor)
217
+ @parent.window.refresh
218
+ end
219
+ if @window.nil?
220
+ #create_window
221
+ else
222
+ @window.show
223
+ select_item 0
224
+ @window.refresh
225
+ end
226
+ end
227
+ ##
228
+ # recursive if given one not enabled goes to next enabled
229
+ def select_item ix0
230
+ return if @items.nil? or @items.empty?
231
+ $log.debug "insdie select item : #{ix0} active: #{@active_index}"
232
+ if !@active_index.nil?
233
+ @items[@active_index].on_leave
234
+ end
235
+ previtem = @active_index
236
+ @active_index = ix0
237
+ if @items[ix0].enabled
238
+ @items[ix0].on_enter
239
+ else
240
+ $log.debug "insdie sele nxt item ENABLED FALSE : #{ix0}"
241
+ if @active_index > previtem
242
+ select_next_item
243
+ else
244
+ select_prev_item
245
+ end
246
+ end
247
+ @window.refresh
248
+ end
249
+ def select_next_item
250
+ return if @items.nil? or @items.empty?
251
+ $log.debug "insdie sele nxt item : #{@active_index}"
252
+ @active_index = -1 if @active_index.nil?
253
+ if @active_index < @items.length-1
254
+ select_item @active_index + 1
255
+ else
256
+ # select_item 0
257
+ end
258
+ end
259
+ def select_prev_item
260
+ return if @items.nil? or @items.empty?
261
+ $log.debug "insdie sele prv item : #{@active_index}"
262
+ if @active_index > 0
263
+ select_item @active_index - 1
264
+ else
265
+ #select_item @items.length-1
266
+ end
267
+ end
268
+ def on_enter # menu.on_enter
269
+ $log.debug "menu onenter: #{text} #{@row} #{@col} "
270
+ # call parent method. XXX
271
+ if @parent.is_a? RubyCurses::MenuBar
272
+ @parent.window.printstring( @row, @col, " %s " % text, $datacolor)
273
+ else
274
+ highlight
275
+ end
276
+ if !@window.nil? #and @parent.selected
277
+ $log.debug "menu onenter: #{text} calling window,show"
278
+ @window.show
279
+ select_item 0
280
+ elsif @parent.is_a? RubyCurses::MenuBar and @parent.selected
281
+ # only on the top level do we open a window if a previous one was opened
282
+ $log.debug "menu onenter: #{text} calling repaint CLASS: #{@parent.class}"
283
+ # repaint
284
+ create_window
285
+ end
286
+ end
287
+ def on_leave # menu.on_leave
288
+ $log.debug "menu onleave: #{text} #{@row} #{@col} "
289
+ # call parent method. XXX
290
+ if @parent.is_a? RubyCurses::MenuBar
291
+ @parent.window.printstring( @row, @col, " %s " % text, $reversecolor)
292
+ @window.hide if !@window.nil?
293
+ else
294
+ $log.debug "MENU SUBMEN. menu onleave: #{text} #{@row} #{@col} "
295
+ # parent is a menu
296
+ highlight false
297
+ #@parent.current_menu.pop
298
+ #@@menus.pop
299
+ #destroy
300
+ end
301
+ end
302
+ def highlight tf=true # menu
303
+ $log.debug "MENU SUBMENU menu highlight: #{text} #{@row} #{@col}, PW #{@parent.width} "
304
+ color = tf ? $datacolor : $reversecolor
305
+ att = tf ? Ncurses::A_REVERSE : Ncurses::A_NORMAL
306
+ #@parent.window.mvchgat(y=@row, x=1, @width, Ncurses::A_NORMAL, color, nil)
307
+ #@parent.window.mvchgat(y=@row, x=1, @parent.width, Ncurses::A_NORMAL, color, nil)
308
+ # above line did not work with vt100/vt200 next does
309
+ @parent.window.mvchgat(y=@row, x=1, @parent.width, att, $reversecolor, nil)
310
+ @parent.window.wrefresh
311
+ end
312
+ def create_window # menu
313
+ margin = 3
314
+ @width = array_width @items
315
+ $log.debug "create window menu #{@text}: #{@row} ,#{@col},wd #{@width} "
316
+ @layout = { :height => @items.length+3, :width => @width+margin, :top => @row+1, :left => @col }
317
+ @win = VER::Window.new(@layout)
318
+ @window = @win
319
+ @win.bkgd(Ncurses.COLOR_PAIR($datacolor));
320
+ @panel = @win.panel
321
+ @window.printstring( 0, 0, "+%s+" % ("-"*@width), $reversecolor)
322
+ r = 1
323
+ @items.each do |item|
324
+ #if item == :SEPARATOR
325
+ # @window.printstring( r, 0, "|%s|" % ("-"*@width), $reversecolor)
326
+ #else
327
+ item.row = r
328
+ item.col = 0
329
+ item.col = @col+@width+margin # margins???
330
+ # $log.debug "create window menu loop passing col : #{item.col} "
331
+ item.width = @width
332
+ #item.window = @window
333
+ item.parent = self
334
+ item.repaint
335
+ #end
336
+ r+=1
337
+ end
338
+ @window.printstring( r, 0, "+%s+" % ("-"*@width), $reversecolor)
339
+ select_item 0
340
+ @window.refresh
341
+ return @window
342
+ end
343
+ # private
344
+ def array_width a
345
+ longest = a.max {|a,b| a.to_s.length <=> b.to_s.length }
346
+ $log.debug "array width #{longest}"
347
+ longest.to_s.length
348
+ end
349
+ def destroy
350
+ $log.debug "DESTRY menu #{@text}"
351
+ return if @window.nil?
352
+ @visible = false
353
+ panel = @window.panel
354
+ Ncurses::Panel.del_panel(panel) if !panel.nil?
355
+ @window.delwin if !@window.nil?
356
+ @items.each do |item|
357
+ #next if item == :SEPARATOR
358
+ item.destroy
359
+ end
360
+ @window = nil
361
+ end
362
+ # menu LEFT, RIGHT, DOWN, UP, ENTER
363
+ # item could be menuitem or another menu
364
+ #
365
+ def handle_key ch
366
+ if !@current_menu.empty?
367
+ cmenu = @current_menu.last
368
+ else
369
+ cmenu = self
370
+ end
371
+ if !@@menus.empty?
372
+ cmenu = @@menus.last
373
+ else
374
+ cmenu = self
375
+ end
376
+ case ch
377
+ when KEY_DOWN
378
+ cmenu.select_next_item
379
+ when KEY_UP
380
+ cmenu.select_prev_item
381
+ when KEY_ENTER, 10, 13, 32 # added 32 2008-11-27 23:50
382
+ return cmenu.fire
383
+ when KEY_LEFT
384
+ if cmenu.parent.is_a? RubyCurses::Menu
385
+ $log.debug "LEFT IN MENU : #{cmenu.parent.class} len: #{cmenu.parent.current_menu.length}"
386
+ $log.debug "left IN MENU : #{cmenu.parent.class} len: #{cmenu.current_menu.length}"
387
+ end
388
+ if cmenu.parent.is_a? RubyCurses::Menu and !cmenu.parent.current_menu.empty?
389
+ $log.debug " ABOU TO DESTROY DUE TO LEFT"
390
+ cmenu.parent.current_menu.pop
391
+ @@menus.pop ## NEW
392
+ cmenu.destroy
393
+ else
394
+ return :UNHANDLED
395
+ end
396
+ when KEY_RIGHT
397
+ $log.debug "RIGHTIN MENU : "
398
+ if cmenu.parent.is_a? RubyCurses::Menu
399
+ $log.debug "right IN MENU : #{cmenu.parent.class} len: #{cmenu.parent.current_menu.length}"
400
+ $log.debug "right IN MENU : #{cmenu.parent.class} len: #{cmenu.current_menu.length}"
401
+ end
402
+ if cmenu.parent.is_a? RubyCurses::Menu and !cmenu.parent.current_menu.empty?
403
+ $log.debug " ABOU TO DESTROY DUE TO RIGHT"
404
+ cmenu.parent.current_menu.pop
405
+ @@menus.pop
406
+ cmenu.destroy
407
+ end
408
+ return :UNHANDLED
409
+ else
410
+ ret = check_mnemonics cmenu, ch
411
+ return ret
412
+ end
413
+ end
414
+ ##
415
+ # checks given key against current menu's items and fires key if
416
+ # added on 2008-11-27 12:07
417
+ def check_mnemonics cmenu, ch
418
+ # $log.debug "inside check_mnemonics #{ch}"
419
+ key = ch.chr.downcase rescue ""
420
+ cmenu.items.each do |item|
421
+ next if !item.respond_to? :mnemonic or item.mnemonic.nil?
422
+ # $log.debug "inside check_mnemonics #{item.mnemonic}"
423
+ if key == item.mnemonic.downcase
424
+ ret = item.fire
425
+ return ret #0 2009-01-23 00:45
426
+ end
427
+ end
428
+ return :UNHANDLED
429
+ end
430
+ ## menu
431
+ def show # menu.show
432
+ $log.debug "show (menu) : #{@text} "
433
+ if @window.nil?
434
+ create_window
435
+ end
436
+ @window.show
437
+ select_item 0
438
+ end
439
+ end
440
+ ##
441
+ # An application related menubar.
442
+ # Currently, I am adding this to a form. But should this not be application specific ?
443
+ # It should popup no matter which window you are on ?? XXX
444
+ class MenuBar
445
+ attr_reader :items
446
+ attr_reader :window
447
+ attr_reader :panel
448
+ attr_reader :selected
449
+ attr_accessor :visible
450
+ attr_accessor :active_index
451
+ attr_accessor :state # normal, selected, highlighted
452
+ attr_accessor :toggle_key # key used to popup, should be set prior to attaching to form
453
+ def initialize &block
454
+ @window = nil
455
+ @items = []
456
+ init_vars
457
+ @visible = false
458
+ @cols = Ncurses.COLS-1
459
+ instance_eval &block if block_given?
460
+ end
461
+ def init_vars
462
+ @active_index = 0
463
+ end
464
+ def focusable
465
+ false
466
+ end
467
+ def add menu
468
+ @items << menu
469
+ return self
470
+ end
471
+ def next_menu
472
+ $log.debug "next meu: #{@active_index} "
473
+ if @active_index < @items.length-1
474
+ set_menu @active_index + 1
475
+ else
476
+ set_menu 0
477
+ end
478
+ end
479
+ def prev_menu
480
+ $log.debug "prev meu: #{@active_index} "
481
+ if @active_index > 0
482
+ set_menu @active_index-1
483
+ else
484
+ set_menu @items.length-1
485
+ end
486
+ end
487
+ def set_menu index
488
+ $log.debug "set meu: #{@active_index} #{index}"
489
+ menu = @items[@active_index]
490
+ menu.on_leave # hide its window, if open
491
+ @active_index = index
492
+ menu = @items[@active_index]
493
+ menu.on_enter #display window, if previous was displayed
494
+ @window.wmove menu.row, menu.col
495
+ # menu.show
496
+ # menu.window.wrefresh # XXX we need this
497
+ end
498
+ # menubar LEFT, RIGHT, DOWN
499
+ def handle_keys
500
+ @selected = false
501
+ @toggle_key ||= 27 # default switch off with ESC, if nothing else defined
502
+ set_menu 0
503
+ begin
504
+ catch(:menubarclose) do
505
+ while((ch = @window.getchar()) != @toggle_key )
506
+ $log.debug "menuubar inside handle_keys : #{ch}" if ch != -1
507
+ case ch
508
+ when -1
509
+ next
510
+ when KEY_DOWN
511
+ $log.debug "insdie keyDOWN : #{ch}"
512
+ if !@selected
513
+ current_menu.fire
514
+ else
515
+ current_menu.handle_key ch
516
+ end
517
+
518
+ @selected = true
519
+ when KEY_ENTER, 10, 13, 32
520
+ @selected = true
521
+ $log.debug " mb insdie ENTER : #{current_menu}"
522
+ ret = current_menu.handle_key ch
523
+ $log.debug "ret = #{ret} mb insdie ENTER : #{current_menu}"
524
+ #break; ## 2008-12-29 18:00 This will close after firing
525
+ #anything
526
+ break if ret == :CLOSE
527
+ when KEY_UP
528
+ $log.debug " mb insdie keyUPP : #{ch}"
529
+ current_menu.handle_key ch
530
+ when KEY_LEFT
531
+ $log.debug " mb insdie KEYLEFT : #{ch}"
532
+ ret = current_menu.handle_key ch
533
+ prev_menu if ret == :UNHANDLED
534
+ #display_items if @selected
535
+ when KEY_RIGHT
536
+ $log.debug " mb insdie KEYRIGHT : #{ch}"
537
+ ret = current_menu.handle_key ch
538
+ next_menu if ret == :UNHANDLED
539
+ else
540
+ $log.debug " mb insdie ELSE : #{ch}"
541
+ ret = current_menu.handle_key ch
542
+ if ret == :UNHANDLED
543
+ Ncurses.beep
544
+ else
545
+ break # we handled a menu action, close menubar (THIS WORKS FOR MNEMONICS ONLY and always)
546
+ end
547
+ end
548
+ Ncurses::Panel.update_panels();
549
+ Ncurses.doupdate();
550
+
551
+ @window.wrefresh
552
+ end
553
+ end # catch
554
+ ensure
555
+ #ensure is required becos one can throw a :close
556
+ $log.debug " DESTROY IN ENSURE"
557
+ current_menu.clear_menus #@@menus = [] # added 2009-01-23 13:21
558
+ destroy # Note that we destroy the menu bar upon exit
559
+ end
560
+ end
561
+ def current_menu
562
+ @items[@active_index]
563
+ end
564
+ def toggle
565
+ @items.each { |i| $log.debug " ITEM DDD : #{i.text}" }
566
+ @visible = !@visible
567
+ if !@visible
568
+ hide
569
+ else
570
+ init_vars
571
+ show
572
+ end
573
+ end
574
+ def hide
575
+ @visible = false
576
+ @window.hide if !@window.nil?
577
+ end
578
+ def show
579
+ @visible = true
580
+ if @window.nil?
581
+ repaint # XXX FIXME
582
+ else
583
+ @window.show
584
+ end
585
+ end
586
+ ## menubar
587
+ def repaint
588
+ return if !@visible
589
+ @window ||= create_window
590
+ @window.printstring( 0, 0, "%-*s" % [@cols," "], $reversecolor)
591
+ c = 1; r = 0;
592
+ @items.each do |item|
593
+ item.row = r; item.col = c; item.parent = self
594
+ @window.printstring( r, c, " %s " % item.text, $reversecolor)
595
+ c += (item.text.length + 2)
596
+ end
597
+ @window.wrefresh
598
+ end
599
+ def create_window
600
+ @layout = { :height => 1, :width => 0, :top => 0, :left => 0 }
601
+ @win = VER::Window.new(@layout)
602
+ @window = @win
603
+ @win.bkgd(Ncurses.COLOR_PAIR(5));
604
+ @panel = @win.panel
605
+ return @window
606
+ end
607
+ def destroy
608
+ $log.debug "DESTRY menubar "
609
+ @visible = false
610
+ panel = @window.panel
611
+ Ncurses::Panel.del_panel(panel) if !panel.nil?
612
+ @window.delwin if !@window.nil?
613
+ @items.each do |item|
614
+ item.destroy
615
+ end
616
+ @window = nil
617
+ end
618
+ end # menubar
619
+
620
+ class CheckBoxMenuItem < MenuItem
621
+ include DSL
622
+ attr_reader :checkbox
623
+ def initialize text, mnemonic=nil, &block
624
+ @checkbox = CheckBox.new nil
625
+ @checkbox.text text
626
+ super
627
+ end
628
+ def onvalue
629
+ @checkbox.onvalue onvalue
630
+ end
631
+ def offvalue
632
+ @checkbox.onvalue offvalue
633
+ end
634
+ def text=(t) # stack level too deep if no = .????
635
+ @checkbox.text t
636
+ end
637
+ def to_s
638
+ " #{text} "
639
+ end
640
+ def getvalue
641
+ checkbox.getvalue
642
+ end
643
+ def getvalue_for_paint
644
+ "|%-*s|" % [@width, checkbox.getvalue_for_paint]
645
+ end
646
+ def fire
647
+ checkbox.toggle
648
+ super
649
+ repaint
650
+ highlight true
651
+ end
652
+ def repaint
653
+ @parent.window.printstring( row, 0, getvalue_for_paint, $reversecolor)
654
+ parent.window.wrefresh
655
+ end
656
+ def method_missing(sym, *args)
657
+ if checkbox.respond_to? sym
658
+ $log.debug("calling CHECKBOXMENU #{sym} called #{args[0]}")
659
+ checkbox.send(sym, args)
660
+ else
661
+ $log.error("ERROR CHECKBOXMENU #{sym} called")
662
+ end
663
+ end
664
+
665
+ end
666
+ end # modul