rbcurse 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGELOG +1570 -0
  2. data/History.txt +6 -0
  3. data/Manifest.txt +54 -0
  4. data/README.txt +304 -0
  5. data/Rakefile +28 -0
  6. data/examples/qdfilechooser.rb +68 -0
  7. data/examples/rfe.rb +853 -0
  8. data/examples/rfe_renderer.rb +69 -0
  9. data/examples/test1.rb +242 -0
  10. data/examples/test2.rb +498 -0
  11. data/examples/testcombo.rb +95 -0
  12. data/examples/testkeypress.rb +61 -0
  13. data/examples/testmenu.rb +105 -0
  14. data/examples/testtable.rb +266 -0
  15. data/examples/testtabp.rb +106 -0
  16. data/examples/testtodo.rb +532 -0
  17. data/examples/viewtodo.rb +512 -0
  18. data/lib/rbcurse/action.rb +31 -0
  19. data/lib/rbcurse/applicationheader.rb +57 -0
  20. data/lib/rbcurse/celleditor.rb +120 -0
  21. data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
  22. data/lib/rbcurse/colormap.rb +133 -0
  23. data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
  24. data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
  25. data/lib/rbcurse/keylabelprinter.rb +143 -0
  26. data/lib/rbcurse/listcellrenderer.rb +99 -0
  27. data/lib/rbcurse/listkeys.rb +33 -0
  28. data/lib/rbcurse/listscrollable.rb +216 -0
  29. data/lib/rbcurse/listselectable.rb +67 -0
  30. data/lib/rbcurse/mapper.rb +108 -0
  31. data/lib/rbcurse/orderedhash.rb +77 -0
  32. data/lib/rbcurse/rcombo.rb +243 -0
  33. data/lib/rbcurse/rdialogs.rb +183 -0
  34. data/lib/rbcurse/rform.rb +845 -0
  35. data/lib/rbcurse/rinputdataevent.rb +36 -0
  36. data/lib/rbcurse/rlistbox.rb +804 -0
  37. data/lib/rbcurse/rmenu.rb +666 -0
  38. data/lib/rbcurse/rmessagebox.rb +325 -0
  39. data/lib/rbcurse/rpopupmenu.rb +754 -0
  40. data/lib/rbcurse/rtabbedpane.rb +259 -0
  41. data/lib/rbcurse/rtable.rb +1296 -0
  42. data/lib/rbcurse/rtextarea.rb +673 -0
  43. data/lib/rbcurse/rtextview.rb +335 -0
  44. data/lib/rbcurse/rwidget.rb +1731 -0
  45. data/lib/rbcurse/scrollable.rb +301 -0
  46. data/lib/rbcurse/selectable.rb +94 -0
  47. data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
  48. data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
  49. data/lib/rbcurse.rb +7 -0
  50. data/lib/ver/keyboard.rb +150 -0
  51. data/lib/ver/keyboard2.rb +170 -0
  52. data/lib/ver/ncurses.rb +102 -0
  53. data/lib/ver/window.rb +369 -0
  54. data/test/test_rbcurse.rb +0 -0
  55. metadata +118 -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