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.
- data/CHANGELOG +1577 -0
- data/README.txt +310 -0
- data/examples/qdfilechooser.rb +68 -0
- data/examples/rfe.rb +853 -0
- data/examples/rfe_renderer.rb +69 -0
- data/examples/test1.rb +242 -0
- data/examples/test2.rb +498 -0
- data/examples/testcombo.rb +95 -0
- data/examples/testkeypress.rb +61 -0
- data/examples/testmenu.rb +105 -0
- data/examples/testtable.rb +266 -0
- data/examples/testtabp.rb +106 -0
- data/examples/testtodo.rb +532 -0
- data/examples/viewtodo.rb +512 -0
- data/lib/rbcurse.rb +7 -0
- data/lib/rbcurse/action.rb +31 -0
- data/lib/rbcurse/applicationheader.rb +57 -0
- data/lib/rbcurse/celleditor.rb +120 -0
- data/lib/rbcurse/checkboxcellrenderer.rb +69 -0
- data/lib/rbcurse/colormap.rb +133 -0
- data/lib/rbcurse/comboboxcellrenderer.rb +45 -0
- data/lib/rbcurse/defaultlistselectionmodel.rb +49 -0
- data/lib/rbcurse/keylabelprinter.rb +143 -0
- data/lib/rbcurse/listcellrenderer.rb +99 -0
- data/lib/rbcurse/listkeys.rb +33 -0
- data/lib/rbcurse/listscrollable.rb +216 -0
- data/lib/rbcurse/listselectable.rb +67 -0
- data/lib/rbcurse/mapper.rb +108 -0
- data/lib/rbcurse/orderedhash.rb +77 -0
- data/lib/rbcurse/rcombo.rb +243 -0
- data/lib/rbcurse/rdialogs.rb +183 -0
- data/lib/rbcurse/rform.rb +845 -0
- data/lib/rbcurse/rinputdataevent.rb +36 -0
- data/lib/rbcurse/rlistbox.rb +804 -0
- data/lib/rbcurse/rmenu.rb +666 -0
- data/lib/rbcurse/rmessagebox.rb +325 -0
- data/lib/rbcurse/rpopupmenu.rb +754 -0
- data/lib/rbcurse/rtabbedpane.rb +259 -0
- data/lib/rbcurse/rtable.rb +1296 -0
- data/lib/rbcurse/rtextarea.rb +673 -0
- data/lib/rbcurse/rtextview.rb +335 -0
- data/lib/rbcurse/rwidget.rb +1731 -0
- data/lib/rbcurse/scrollable.rb +301 -0
- data/lib/rbcurse/selectable.rb +94 -0
- data/lib/rbcurse/table/tablecellrenderer.rb +85 -0
- data/lib/rbcurse/table/tabledatecellrenderer.rb +102 -0
- data/lib/ver/keyboard.rb +150 -0
- data/lib/ver/keyboard2.rb +170 -0
- data/lib/ver/ncurses.rb +102 -0
- data/lib/ver/window.rb +369 -0
- data/test/test_rbcurse.rb +0 -0
- metadata +117 -0
@@ -0,0 +1,325 @@
|
|
1
|
+
=begin
|
2
|
+
* Name: rmessagebox: creates messageboxes
|
3
|
+
* Description
|
4
|
+
* Author: rkumar (arunachalesha)
|
5
|
+
* Date: 2008-11-19 12:49
|
6
|
+
* License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
7
|
+
* file separated on 2009-01-13 22:39
|
8
|
+
|
9
|
+
=end
|
10
|
+
require 'rbcurse/rwidget'
|
11
|
+
require 'rbcurse/rlistbox'
|
12
|
+
|
13
|
+
module RubyCurses
|
14
|
+
##
|
15
|
+
# dimensions of window should be derived on content
|
16
|
+
#
|
17
|
+
class MessageBox
|
18
|
+
include DSL
|
19
|
+
include RubyCurses::Utils
|
20
|
+
dsl_accessor :title
|
21
|
+
dsl_accessor :message
|
22
|
+
dsl_accessor :type # :ok, :ok_cancel :yes_no :yes_no_cancel :custom
|
23
|
+
dsl_accessor :default_button # TODO - currently first
|
24
|
+
dsl_accessor :layout
|
25
|
+
dsl_accessor :buttons # used if type :custom
|
26
|
+
dsl_accessor :underlines # offsets of each button to underline
|
27
|
+
attr_reader :config
|
28
|
+
attr_reader :selected_index # button index selected by user
|
29
|
+
attr_reader :window # required for keyboard
|
30
|
+
dsl_accessor :list_selection_mode # true or false allow multiple selection
|
31
|
+
dsl_accessor :list # 2009-01-05 23:59
|
32
|
+
dsl_accessor :button_type # ok, ok_cancel, yes_no
|
33
|
+
dsl_accessor :default_value #
|
34
|
+
dsl_accessor :default_values # # 2009-01-06 00:05 after removing meth missing
|
35
|
+
dsl_accessor :height, :width, :top, :left # 2009-01-06 00:05 after removing meth missing
|
36
|
+
|
37
|
+
dsl_accessor :message_height
|
38
|
+
|
39
|
+
|
40
|
+
def initialize form=nil, aconfig={}, &block
|
41
|
+
@form = form
|
42
|
+
@config = aconfig
|
43
|
+
@buttons = []
|
44
|
+
#@keys = {}
|
45
|
+
@bcol = 5
|
46
|
+
@selected_index = -1
|
47
|
+
@config.each_pair { |k,v| instance_variable_set("@#{k}",v) }
|
48
|
+
instance_eval &block if block_given?
|
49
|
+
if @layout.nil?
|
50
|
+
case @type.to_s
|
51
|
+
when "input"
|
52
|
+
layout(10,60, 10, 20)
|
53
|
+
when "list"
|
54
|
+
height = [5, @list.length].min
|
55
|
+
layout(10+height, 60, 5, 20)
|
56
|
+
when "field_list"
|
57
|
+
height = @field_list.length
|
58
|
+
layout(10+height, 60, 5, 20)
|
59
|
+
when "override"
|
60
|
+
$log.debug " override: #{@height},#{@width}, #{@top}, #{@left} "
|
61
|
+
layout(@height,@width, @top, @left)
|
62
|
+
$log.debug " override: #{@layout.inspect}"
|
63
|
+
else
|
64
|
+
height = @form && @form.widgets.length ## quick fix. FIXME
|
65
|
+
height ||= 0
|
66
|
+
layout(10+height,60, 10, 20)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
@window = VER::Window.new(@layout)
|
70
|
+
if @form.nil?
|
71
|
+
@form = RubyCurses::Form.new @window
|
72
|
+
else
|
73
|
+
@form.window = @window
|
74
|
+
end
|
75
|
+
acolor = get_color $reversecolor
|
76
|
+
$log.debug " MESSAGE BOX #{@bgcolor} , #{@color} , #{acolor}"
|
77
|
+
@window.bkgd(Ncurses.COLOR_PAIR(acolor));
|
78
|
+
@window.wrefresh
|
79
|
+
@panel = @window.panel
|
80
|
+
Ncurses::Panel.update_panels
|
81
|
+
process_field_list
|
82
|
+
print_borders
|
83
|
+
print_title
|
84
|
+
print_message unless @message.nil?
|
85
|
+
print_input
|
86
|
+
create_buttons
|
87
|
+
@form.repaint
|
88
|
+
@window.wrefresh
|
89
|
+
handle_keys
|
90
|
+
end
|
91
|
+
##
|
92
|
+
# takes care of a field list sent in
|
93
|
+
def process_field_list
|
94
|
+
return if @field_list.nil? or @field_list.length == 0
|
95
|
+
@field_list.each do |f|
|
96
|
+
f.set_form @form
|
97
|
+
end
|
98
|
+
end
|
99
|
+
def default_button offset0
|
100
|
+
@selected_index = offset0
|
101
|
+
end
|
102
|
+
##
|
103
|
+
# value entered by user if type = input
|
104
|
+
def input_value
|
105
|
+
return @input.buffer if !@input.nil?
|
106
|
+
return @listbox.getvalue if !@listbox.nil?
|
107
|
+
end
|
108
|
+
def create_buttons
|
109
|
+
case @button_type.to_s.downcase
|
110
|
+
when "ok"
|
111
|
+
make_buttons ["&OK"]
|
112
|
+
when "ok_cancel" #, "input", "list", "field_list"
|
113
|
+
make_buttons %w[&OK &Cancel]
|
114
|
+
when "yes_no"
|
115
|
+
make_buttons %w[&Yes &No]
|
116
|
+
when "yes_no_cancel"
|
117
|
+
make_buttons ["&Yes", "&No", "&Cancel"]
|
118
|
+
when "custom"
|
119
|
+
raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
|
120
|
+
make_buttons @buttons
|
121
|
+
else
|
122
|
+
$log.debug "No type passed for creating messagebox. Using default (OK)"
|
123
|
+
make_buttons ["&OK"]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
def make_buttons names
|
127
|
+
total = names.inject(0) {|total, item| total + item.length + 4}
|
128
|
+
bcol = center_column total
|
129
|
+
|
130
|
+
brow = @layout[:height]-3
|
131
|
+
button_ct=0
|
132
|
+
names.each_with_index do |bname, ix|
|
133
|
+
text = bname
|
134
|
+
#underline = @underlines[ix] if !@underlines.nil?
|
135
|
+
|
136
|
+
button = Button.new @form do
|
137
|
+
text text
|
138
|
+
name bname
|
139
|
+
row brow
|
140
|
+
col bcol
|
141
|
+
#underline underline
|
142
|
+
highlight_background $datacolor
|
143
|
+
color $reversecolor
|
144
|
+
bgcolor $reversecolor
|
145
|
+
end
|
146
|
+
index = button_ct
|
147
|
+
button.command { |form| @selected_index = index; @stop = true; $log.debug "Pressed Button #{bname}";}
|
148
|
+
button_ct += 1
|
149
|
+
bcol += text.length+6
|
150
|
+
end
|
151
|
+
end
|
152
|
+
## message box
|
153
|
+
def stopping?
|
154
|
+
@stop
|
155
|
+
end
|
156
|
+
def handle_keys
|
157
|
+
begin
|
158
|
+
while((ch = @window.getchar()) != 999 )
|
159
|
+
case ch
|
160
|
+
when -1
|
161
|
+
next
|
162
|
+
else
|
163
|
+
press ch
|
164
|
+
break if @stop
|
165
|
+
end
|
166
|
+
end
|
167
|
+
ensure
|
168
|
+
destroy
|
169
|
+
end
|
170
|
+
return @selected_index
|
171
|
+
end
|
172
|
+
def press ch
|
173
|
+
#$log.debug "message box handle_keys : #{ch}" if ch != -1
|
174
|
+
case ch
|
175
|
+
when -1
|
176
|
+
return
|
177
|
+
when KEY_F1, 27, ?\C-q
|
178
|
+
@selected_index = -1
|
179
|
+
@stop = true
|
180
|
+
return
|
181
|
+
when KEY_ENTER, 10, 13
|
182
|
+
field = @form.get_current_field
|
183
|
+
if field.respond_to? :fire
|
184
|
+
field.fire
|
185
|
+
end
|
186
|
+
$log.debug "popup ENTER : #{@selected_index} "
|
187
|
+
$log.debug "popup ENTER : #{field.name}" if !field.nil?
|
188
|
+
@stop = true
|
189
|
+
return
|
190
|
+
when 9
|
191
|
+
@form.select_next_field
|
192
|
+
else
|
193
|
+
# fields must return unhandled else we will miss hotkeys.
|
194
|
+
# On messageboxes, often if no edit field, then O and C are hot.
|
195
|
+
field = @form.get_current_field
|
196
|
+
handled = field.handle_key ch
|
197
|
+
|
198
|
+
if handled == :UNHANDLED
|
199
|
+
ret = @form.process_key ch, self ## trying out trigger button
|
200
|
+
end
|
201
|
+
end
|
202
|
+
@form.repaint
|
203
|
+
Ncurses::Panel.update_panels();
|
204
|
+
Ncurses.doupdate();
|
205
|
+
@window.wrefresh
|
206
|
+
end
|
207
|
+
def print_borders
|
208
|
+
width = @layout[:width]
|
209
|
+
height = @layout[:height]
|
210
|
+
@window.print_border_mb 1,2, height, width, $normalcolor, A_REVERSE
|
211
|
+
=begin
|
212
|
+
start = 2
|
213
|
+
hline = "+%s+" % [ "-"*(width-((start+1)*2)) ]
|
214
|
+
hline2 = "|%s|" % [ " "*(width-((start+1)*2)) ]
|
215
|
+
@window.printstring(row=1, col=start, hline, color=$reversecolor)
|
216
|
+
(start).upto(height-2) do |row|
|
217
|
+
@window.printstring row, col=start, hline2, color=$normalcolor, A_REVERSE
|
218
|
+
end
|
219
|
+
@window.printstring(height-2, col=start, hline, color=$reversecolor)
|
220
|
+
=end
|
221
|
+
end
|
222
|
+
def print_title title=@title
|
223
|
+
width = @layout[:width]
|
224
|
+
title = " "+title+" "
|
225
|
+
@window.printstring(row=1,col=(width-title.length)/2,title, color=$normalcolor)
|
226
|
+
end
|
227
|
+
def center_column textlen
|
228
|
+
width = @layout[:width]
|
229
|
+
return (width-textlen)/2
|
230
|
+
end
|
231
|
+
def print_message message=@message, row=nil
|
232
|
+
@message_row = @message_col = 2
|
233
|
+
display_length = @layout[:width]-8
|
234
|
+
# XXX this needs to go up and decide height of window
|
235
|
+
if @message_height.nil?
|
236
|
+
@message_height = (message.length/display_length)+1
|
237
|
+
$log.debug " print_message: mh:#{@message_height}"
|
238
|
+
end
|
239
|
+
@message_height ||= 1
|
240
|
+
width = @layout[:width]
|
241
|
+
return if message.nil?
|
242
|
+
case @type.to_s
|
243
|
+
when "input"
|
244
|
+
row=(@layout[:height]/3) if row.nil?
|
245
|
+
@message_col = 4
|
246
|
+
when "list"
|
247
|
+
row=3
|
248
|
+
@message_col = 4
|
249
|
+
else
|
250
|
+
row=(@layout[:height]/3) if row.nil?
|
251
|
+
@message_col = (width-message.length)/2
|
252
|
+
end
|
253
|
+
@message_row = row
|
254
|
+
#@window.printstring( row, @message_col , message, color=$reversecolor)
|
255
|
+
# 2008-12-30 19:45 experimenting with label so we can get justify and wrapping.
|
256
|
+
#@window.printstring( row, @message_col , message, color=$reversecolor)
|
257
|
+
message_label = RubyCurses::Label.new @form, {'text' => message, "name"=>"message_label","row" => row, "col" => @message_col, "display_length" => display_length, "height" => @message_height, "attr"=>"reverse"}
|
258
|
+
|
259
|
+
end
|
260
|
+
def print_input
|
261
|
+
#return if @type.to_s != "input"
|
262
|
+
@message_height ||= 0
|
263
|
+
@message_row ||= 2
|
264
|
+
@message_col ||= 2
|
265
|
+
r = @message_row + @message_height + 1
|
266
|
+
c = @message_col
|
267
|
+
defaultvalue = @default_value || ""
|
268
|
+
input_config = @config["input_config"] || {}
|
269
|
+
case @type.to_s
|
270
|
+
when "input"
|
271
|
+
@input = RubyCurses::Field.new @form, input_config do
|
272
|
+
name "input"
|
273
|
+
row r
|
274
|
+
col c
|
275
|
+
display_length 30
|
276
|
+
set_buffer defaultvalue
|
277
|
+
end
|
278
|
+
when "list"
|
279
|
+
list = @list
|
280
|
+
selection_mode = @list_selection_mode
|
281
|
+
default_values = @default_values
|
282
|
+
$log.debug " value of select_mode #{selection_mode}"
|
283
|
+
@listbox = RubyCurses::Listbox.new @form do
|
284
|
+
name "input"
|
285
|
+
row r
|
286
|
+
col c
|
287
|
+
# attr 'reverse'
|
288
|
+
color 'black'
|
289
|
+
bgcolor 'white'
|
290
|
+
width 30
|
291
|
+
height 6
|
292
|
+
list list
|
293
|
+
# ?? display_length 30
|
294
|
+
#set_buffer defaultvalue
|
295
|
+
selection_mode selection_mode
|
296
|
+
default_values default_values
|
297
|
+
is_popup false
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
def configure(*val , &block)
|
302
|
+
case val.size
|
303
|
+
when 1
|
304
|
+
return @config[val[0]]
|
305
|
+
when 2
|
306
|
+
@config[val[0]] = val[1]
|
307
|
+
instance_variable_set("@#{val[0]}", val[1])
|
308
|
+
end
|
309
|
+
instance_eval &block if block_given?
|
310
|
+
end
|
311
|
+
def cget param
|
312
|
+
@config[param]
|
313
|
+
end
|
314
|
+
|
315
|
+
def layout(height=0, width=0, top=0, left=0)
|
316
|
+
@layout = { :height => height, :width => width, :top => top, :left => left }
|
317
|
+
end
|
318
|
+
def destroy
|
319
|
+
$log.debug "DESTROY : widget"
|
320
|
+
panel = @window.panel
|
321
|
+
Ncurses::Panel.del_panel(panel) if !panel.nil?
|
322
|
+
@window.delwin if !@window.nil?
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
@@ -0,0 +1,754 @@
|
|
1
|
+
=begin
|
2
|
+
* Name: rpopupmenu - this is based on the crappy menubar code and needs a rewrite.
|
3
|
+
* Description
|
4
|
+
* Author: rkumar
|
5
|
+
TODO
|
6
|
+
- Action: may have to listen to Action property changes so enabled, name etc change can be reflected
|
7
|
+
- menu bar : what to do if adding a menu, or option later.
|
8
|
+
we dnt show disabld options in a way that user can know its disabled
|
9
|
+
- separate file created on 2008-12-24 17:58
|
10
|
+
|
11
|
+
Mnemonic should highlight the row if its a menu.
|
12
|
+
NOTE : this program works but is one of the first programs and is untouched. It needs to be rewritten
|
13
|
+
since its quite crappy.
|
14
|
+
Also, we should move to Action classes as against just blokcs of code. And action class would have
|
15
|
+
a user friendly string to identifiy the action, as well as a disabled option.
|
16
|
+
|
17
|
+
--------
|
18
|
+
* Date: 2008-11-14 23:43
|
19
|
+
* License:
|
20
|
+
Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
|
21
|
+
|
22
|
+
=end
|
23
|
+
require 'rubygems'
|
24
|
+
require 'ncurses'
|
25
|
+
require 'logger'
|
26
|
+
require 'rbcurse'
|
27
|
+
require 'rbcurse/action'
|
28
|
+
|
29
|
+
include Ncurses
|
30
|
+
include RubyCurses
|
31
|
+
module RubyCurses
|
32
|
+
extend self
|
33
|
+
|
34
|
+
|
35
|
+
class MenuSeparator
|
36
|
+
attr_accessor :enabled
|
37
|
+
attr_accessor :parent
|
38
|
+
attr_accessor :row
|
39
|
+
attr_accessor :col
|
40
|
+
attr_accessor :width
|
41
|
+
def initialize
|
42
|
+
@enable = false
|
43
|
+
end
|
44
|
+
def repaint
|
45
|
+
@parent.window.printstring( @row, 0, "|%s|" % ("-"*@width), $reversecolor)
|
46
|
+
end
|
47
|
+
def destroy
|
48
|
+
end
|
49
|
+
def on_enter
|
50
|
+
end
|
51
|
+
def on_leave
|
52
|
+
end
|
53
|
+
def to_s
|
54
|
+
""
|
55
|
+
end
|
56
|
+
end
|
57
|
+
##
|
58
|
+
class MenuItem
|
59
|
+
attr_accessor :parent
|
60
|
+
# attr_accessor :window
|
61
|
+
attr_accessor :row
|
62
|
+
attr_accessor :col
|
63
|
+
attr_accessor :width
|
64
|
+
attr_accessor :accelerator
|
65
|
+
attr_accessor :enabled
|
66
|
+
attr_accessor :mnemonic # changed reader to accessor
|
67
|
+
def initialize txt, mnemonic=nil, &block
|
68
|
+
@mnemonic = mnemonic
|
69
|
+
text txt
|
70
|
+
@enabled = true
|
71
|
+
instance_eval &block if block_given?
|
72
|
+
end
|
73
|
+
##
|
74
|
+
# changed so ampersand can be mnemonic esp when action comes in
|
75
|
+
def text s
|
76
|
+
s = s.dup # since actions are being shared
|
77
|
+
if (( ix = s.index('&')) != nil)
|
78
|
+
s.slice!(ix,1)
|
79
|
+
#@underline = ix unless @form.nil? # this setting a fake underline in messageboxes
|
80
|
+
@mnemonic = s[ix,1]
|
81
|
+
end
|
82
|
+
@text = s
|
83
|
+
end
|
84
|
+
def to_s
|
85
|
+
"#{@text} #{@accelerator}"
|
86
|
+
end
|
87
|
+
def command *args, &block
|
88
|
+
$log.debug ">>>command : #{@text} "
|
89
|
+
@command = block if block_given?
|
90
|
+
@args = args
|
91
|
+
end
|
92
|
+
def on_enter
|
93
|
+
$log.debug ">>>on enter menuitem : #{@text} #{@row} #{@width} "
|
94
|
+
highlight
|
95
|
+
end
|
96
|
+
def on_leave
|
97
|
+
$log.debug ">>>on leave menuitem : #{@text} "
|
98
|
+
highlight false
|
99
|
+
end
|
100
|
+
## XXX it could be a menu again
|
101
|
+
def fire
|
102
|
+
$log.debug ">>>fire menuitem : #{@text} #{@command} "
|
103
|
+
@command.call self, *@args if !@command.nil?
|
104
|
+
@parent.clear_menus
|
105
|
+
return :CLOSE # added 2009-01-02 00:09 to close only actions, not submenus
|
106
|
+
end
|
107
|
+
def highlight tf=true
|
108
|
+
if tf
|
109
|
+
color = $datacolor
|
110
|
+
#@parent.window.mvchgat(y=@row, x=1, @width, Ncurses::A_NORMAL, color, nil)
|
111
|
+
# above line did not work in vt100, 200 terminals, next works.
|
112
|
+
@parent.window.mvchgat(y=@row, x=1, @width, Ncurses::A_REVERSE, $reversecolor, nil)
|
113
|
+
else
|
114
|
+
repaint
|
115
|
+
end
|
116
|
+
@parent.window.wrefresh
|
117
|
+
end
|
118
|
+
def repaint # menuitem.repaint
|
119
|
+
if @parent.nil? or @parent.window.nil?
|
120
|
+
$log.debug " #{self} parent nil"
|
121
|
+
return
|
122
|
+
end
|
123
|
+
r = @row
|
124
|
+
acolor = $reversecolor
|
125
|
+
acolor = get_color($reversecolor, 'green', 'white') if !@enabled
|
126
|
+
@parent.window.printstring( @row, 0, "|%-*s|" % [@width, @text], acolor)
|
127
|
+
if !@accelerator.nil?
|
128
|
+
@parent.window.printstring( r, (@width+1)-@accelerator.length, @accelerator, acolor)
|
129
|
+
else
|
130
|
+
#@parent.window.printstring( r, (@width+1)-1, ".", acolor)
|
131
|
+
end
|
132
|
+
if !@mnemonic.nil?
|
133
|
+
m = @mnemonic
|
134
|
+
ix = @text.index(m) || @text.index(m.swapcase)
|
135
|
+
charm = @text[ix,1]
|
136
|
+
#@parent.window.printstring( r, ix+1, charm, $datacolor) if !ix.nil?
|
137
|
+
# prev line changed since not working in vt100 and vt200
|
138
|
+
#@parent.window.printstring( r, ix+1, charm, $reversecolor, 'reverse') if !ix.nil?
|
139
|
+
@parent.window.mvchgat(y=r, x=ix+1, max=1, Ncurses::A_BOLD|Ncurses::A_UNDERLINE, acolor, nil)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
def destroy
|
143
|
+
$log.debug "DESTRY menuitem #{@text}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
class Menu < MenuItem
|
147
|
+
attr_accessor :parent
|
148
|
+
attr_accessor :row
|
149
|
+
attr_accessor :col
|
150
|
+
attr_accessor :width
|
151
|
+
attr_accessor :enabled
|
152
|
+
#attr_reader :text
|
153
|
+
attr_reader :items
|
154
|
+
attr_reader :window
|
155
|
+
attr_reader :panel
|
156
|
+
attr_reader :current_menu
|
157
|
+
attr_reader :row_margin
|
158
|
+
@@menus = []
|
159
|
+
@@row = 0
|
160
|
+
@@col = 0
|
161
|
+
|
162
|
+
def initialize text, &block
|
163
|
+
super text, nil, &block
|
164
|
+
@items = []
|
165
|
+
@enabled = true
|
166
|
+
@current_menu = []
|
167
|
+
instance_eval &block if block_given?
|
168
|
+
@row ||=10
|
169
|
+
@col ||=10
|
170
|
+
@@menus ||= []
|
171
|
+
end
|
172
|
+
def to_s
|
173
|
+
@text
|
174
|
+
end
|
175
|
+
def clear_menus
|
176
|
+
@@menus = []
|
177
|
+
end
|
178
|
+
# create a Menuitem given an Action
|
179
|
+
# if menuitem.kind_of? RubyCurses::Action
|
180
|
+
def create_action_component action
|
181
|
+
m = MenuItem.new(action.name, action.mnemonic)
|
182
|
+
m.command { action.call }
|
183
|
+
m.accelerator = action.accelerator
|
184
|
+
return m
|
185
|
+
end
|
186
|
+
# item could be menuitem or another menu or a string or a Action
|
187
|
+
# support for action added 2009-01-21 18:08
|
188
|
+
def add menuitem
|
189
|
+
insert menuitem, @items.size
|
190
|
+
return self
|
191
|
+
end
|
192
|
+
##
|
193
|
+
# added 2009-01-20 13:28 NEW
|
194
|
+
def insert menuitem, ix
|
195
|
+
if menuitem.kind_of? RubyCurses::Action
|
196
|
+
menuitem = create_action_component menuitem
|
197
|
+
end
|
198
|
+
@items.insert ix, menuitem
|
199
|
+
return self
|
200
|
+
end
|
201
|
+
def insert_separator ix
|
202
|
+
@items.insert ix, MenuSeparator.new
|
203
|
+
end
|
204
|
+
def add_separator
|
205
|
+
@items << MenuSeparator.new
|
206
|
+
end
|
207
|
+
def get_item i
|
208
|
+
@items[i]
|
209
|
+
end
|
210
|
+
def remove n
|
211
|
+
if n.is_a? Fixnum
|
212
|
+
@items.delete_at n
|
213
|
+
else
|
214
|
+
@items.delete n
|
215
|
+
end
|
216
|
+
end
|
217
|
+
# menu -
|
218
|
+
def fire
|
219
|
+
$log.debug "menu fire called: #{@text} "
|
220
|
+
if @window.nil?
|
221
|
+
#repaint
|
222
|
+
create_window
|
223
|
+
if !@parent.is_a? RubyCurses::MenuBar
|
224
|
+
$log.debug " ADDING self to current menu: #{self}"
|
225
|
+
# xxx highlight true
|
226
|
+
@parent.current_menu << self
|
227
|
+
@@menus << self
|
228
|
+
|
229
|
+
$log.debug "DDD #{@@menus} << #{self}"
|
230
|
+
end
|
231
|
+
else
|
232
|
+
### shouod this not just show ?
|
233
|
+
$log.debug "menu fire called: #{@text} ELSE XXX WHEN IS THIS CALLED ? 658 "
|
234
|
+
return @items[@active_index].fire # this should happen if selected. else selected()
|
235
|
+
end
|
236
|
+
#@action.call if !@action.nil?
|
237
|
+
end
|
238
|
+
# user has clicked down, we shoud display items
|
239
|
+
# DRAW menuitems
|
240
|
+
def repaint # menu.repaint
|
241
|
+
return if @items.nil? or @items.empty?
|
242
|
+
$log.debug "menu repaint: #{@text} row #{@row} col #{@col} "
|
243
|
+
if !@parent.is_a? RubyCurses::MenuBar
|
244
|
+
@parent.window.printstring( @row, 0, "|%-*s>|" % [@width-1, @text], $reversecolor)
|
245
|
+
# added 2009-01-23 00:49
|
246
|
+
if !@mnemonic.nil?
|
247
|
+
m = @mnemonic
|
248
|
+
ix = @text.index(m) || @text.index(m.swapcase)
|
249
|
+
charm = @text[ix,1]
|
250
|
+
#@parent.window.printstring( r, ix+1, charm, $datacolor) if !ix.nil?
|
251
|
+
# prev line changed since not working in vt100 and vt200
|
252
|
+
#@parent.window.printstring( @row, ix+1, charm, $reversecolor, 'reverse') if !ix.nil?
|
253
|
+
# 2009-01-23 13:03 replaced reverse with ul
|
254
|
+
@parent.window.mvchgat(y=@row, x=ix+1, max=1, Ncurses::A_BOLD|Ncurses::A_UNDERLINE, $reversecolor, nil)
|
255
|
+
end
|
256
|
+
@parent.window.refresh
|
257
|
+
end
|
258
|
+
if @window.nil?
|
259
|
+
#create_window
|
260
|
+
else
|
261
|
+
@window.show
|
262
|
+
select_item 0
|
263
|
+
@window.refresh
|
264
|
+
end
|
265
|
+
end
|
266
|
+
##
|
267
|
+
# recursive if given one not enabled goes to next enabled
|
268
|
+
def select_item ix0
|
269
|
+
return if @items.nil? or @items.empty?
|
270
|
+
$log.debug "insdie select item : #{ix0}"
|
271
|
+
if !@active_index.nil?
|
272
|
+
@items[@active_index].on_leave
|
273
|
+
end
|
274
|
+
previtem = @active_index
|
275
|
+
@active_index = ix0
|
276
|
+
if @items[ix0].enabled
|
277
|
+
@items[ix0].on_enter
|
278
|
+
else
|
279
|
+
$log.debug "insdie sele nxt item ENABLED FALSE : #{ix0}"
|
280
|
+
if @active_index > previtem
|
281
|
+
select_next_item
|
282
|
+
else
|
283
|
+
select_prev_item
|
284
|
+
end
|
285
|
+
end
|
286
|
+
@window.refresh
|
287
|
+
end
|
288
|
+
def select_next_item
|
289
|
+
return if @items.nil? or @items.empty?
|
290
|
+
$log.debug "insdie sele nxt item : #{@active_index}"
|
291
|
+
@active_index = -1 if @active_index.nil?
|
292
|
+
if @active_index < @items.length-1
|
293
|
+
select_item @active_index + 1
|
294
|
+
else
|
295
|
+
# select_item 0
|
296
|
+
end
|
297
|
+
end
|
298
|
+
def select_prev_item
|
299
|
+
return if @items.nil? or @items.empty?
|
300
|
+
$log.debug "insdie sele prv item : #{@active_index}"
|
301
|
+
if @active_index > 0
|
302
|
+
select_item @active_index - 1
|
303
|
+
else
|
304
|
+
#select_item @items.length-1
|
305
|
+
end
|
306
|
+
end
|
307
|
+
def on_enter # menu.on_enter
|
308
|
+
$log.debug "menu onenter: #{@text} #{@row} #{@col} "
|
309
|
+
# call parent method. XXX
|
310
|
+
if @parent.is_a? RubyCurses::MenuBar
|
311
|
+
@parent.window.printstring( @row, @col, " %s " % @text, $datacolor)
|
312
|
+
else
|
313
|
+
highlight
|
314
|
+
end
|
315
|
+
if !@window.nil? #and @parent.selected
|
316
|
+
$log.debug "menu onenter: #{@text} calling window,show"
|
317
|
+
@window.show
|
318
|
+
select_item 0
|
319
|
+
elsif @parent.is_a? RubyCurses::MenuBar and @parent.selected
|
320
|
+
# only on the top level do we open a window if a previous one was opened
|
321
|
+
$log.debug "menu onenter: #{@text} calling repaint CLASS: #{@parent.class}"
|
322
|
+
# repaint
|
323
|
+
create_window
|
324
|
+
end
|
325
|
+
end
|
326
|
+
def on_leave # menu.on_leave
|
327
|
+
$log.debug "menu onleave: #{@text} #{@row} #{@col} "
|
328
|
+
# call parent method. XXX
|
329
|
+
if @parent.is_a? RubyCurses::MenuBar
|
330
|
+
@parent.window.printstring( @row, @col, " %s " % @text, $reversecolor)
|
331
|
+
@window.hide if !@window.nil?
|
332
|
+
else
|
333
|
+
$log.debug "MENU SUBMEN. menu onleave: #{@text} #{@row} #{@col} will pop !! "
|
334
|
+
# parent is a menu
|
335
|
+
highlight false
|
336
|
+
#@parent.current_menu.pop
|
337
|
+
#@@menus.pop
|
338
|
+
#destroy
|
339
|
+
end
|
340
|
+
end
|
341
|
+
def highlight tf=true # menu
|
342
|
+
$log.debug "MENU SUBMENU menu highlight: #{@text} #{@row} #{@col}, PW #{@parent.width} "
|
343
|
+
color = tf ? $datacolor : $reversecolor
|
344
|
+
att = tf ? Ncurses::A_REVERSE : Ncurses::A_NORMAL
|
345
|
+
#@parent.window.mvchgat(y=@row, x=1, @width, Ncurses::A_NORMAL, color, nil)
|
346
|
+
#@parent.window.mvchgat(y=@row, x=1, @parent.width, Ncurses::A_NORMAL, color, nil)
|
347
|
+
# above line did not work with vt100/vt200 next does
|
348
|
+
@parent.window.mvchgat(y=@row, x=1, @parent.width, att, $reversecolor, nil)
|
349
|
+
@parent.window.wrefresh
|
350
|
+
end
|
351
|
+
def create_window # menu XXX
|
352
|
+
margin = 3
|
353
|
+
@width = array_width @items
|
354
|
+
$log.debug "create window menu #{@text}: #{@row} ,#{@col},parent: #{@parent}, wd #{@width} "
|
355
|
+
#$log.debug "create window menu parent: #{@parent.row}, " unless @parent.nil?
|
356
|
+
@row_margin = 1 #+ @@row
|
357
|
+
@row_margin = @parent.row+@parent.row_margin unless @parent.nil?
|
358
|
+
#@row = @parent.row unless @parent.nil?
|
359
|
+
@layout = { :height => @items.length+3, :width => @width+margin, :top => @row+@row_margin, :left => @col }
|
360
|
+
@win = VER::Window.new(@layout)
|
361
|
+
@window = @win
|
362
|
+
@win.bkgd(Ncurses.COLOR_PAIR($datacolor));
|
363
|
+
@panel = @win.panel
|
364
|
+
@window.printstring( 0, 0, "+%s+" % ("-"*@width), $reversecolor)
|
365
|
+
r = 1
|
366
|
+
@items.each do |item|
|
367
|
+
item.row = r
|
368
|
+
item.col = 0
|
369
|
+
item.col = @col+@width+margin # margins???
|
370
|
+
item.width = @width
|
371
|
+
#item.window = @window
|
372
|
+
item.parent = self
|
373
|
+
item.repaint
|
374
|
+
#end
|
375
|
+
r+=1
|
376
|
+
end
|
377
|
+
@window.printstring( r, 0, "+%s+" % ("-"*@width), $reversecolor)
|
378
|
+
select_item 0
|
379
|
+
@window.refresh
|
380
|
+
return @window
|
381
|
+
end
|
382
|
+
# private
|
383
|
+
def array_width a
|
384
|
+
longest = a.max {|a,b| a.to_s.length <=> b.to_s.length }
|
385
|
+
$log.debug "array width #{longest}"
|
386
|
+
longest.to_s.length
|
387
|
+
end
|
388
|
+
def destroy
|
389
|
+
$log.debug "DESTRY menu #{@text}"
|
390
|
+
return if @window.nil?
|
391
|
+
@visible = false
|
392
|
+
panel = @window.panel
|
393
|
+
Ncurses::Panel.del_panel(panel) if !panel.nil?
|
394
|
+
@window.delwin if !@window.nil?
|
395
|
+
@items.each do |item|
|
396
|
+
#next if item == :SEPARATOR
|
397
|
+
item.destroy
|
398
|
+
end
|
399
|
+
@window = nil
|
400
|
+
end
|
401
|
+
# menu LEFT, RIGHT, DOWN, UP, ENTER
|
402
|
+
# item could be menuitem or another menu
|
403
|
+
#
|
404
|
+
def handle_key ch
|
405
|
+
#if !@current_menu.empty?
|
406
|
+
# cmenu = @current_menu.last
|
407
|
+
#else
|
408
|
+
# cmenu = self
|
409
|
+
#end
|
410
|
+
if !@@menus.empty?
|
411
|
+
cmenu = @@menus.last
|
412
|
+
else
|
413
|
+
cmenu = self
|
414
|
+
end
|
415
|
+
$log.debug " CMENU is #{cmenu}: #{@@menus} "
|
416
|
+
case ch
|
417
|
+
when KEY_DOWN
|
418
|
+
cmenu.select_next_item
|
419
|
+
when KEY_UP
|
420
|
+
cmenu.select_prev_item
|
421
|
+
when KEY_ENTER, 10, 13, 32 # added 32 2008-11-28 23:50
|
422
|
+
return cmenu.fire
|
423
|
+
when KEY_LEFT
|
424
|
+
if cmenu.parent.is_a? RubyCurses::Menu
|
425
|
+
$log.debug "LEFT IN MENU : #{cmenu.parent.class} len: #{cmenu.parent.current_menu.length}"
|
426
|
+
$log.debug "left IN MENU : #{cmenu.parent.class} len: #{cmenu.current_menu.length}"
|
427
|
+
end
|
428
|
+
if cmenu.parent.is_a? RubyCurses::Menu and !cmenu.parent.current_menu.empty?
|
429
|
+
$log.debug " ABOU TO DESTROY DUE TO LEFT"
|
430
|
+
cmenu.parent.current_menu.pop
|
431
|
+
@@menus.pop
|
432
|
+
cmenu.destroy
|
433
|
+
else
|
434
|
+
$log.debug " returning UNHANDLED 370"
|
435
|
+
return :UNHANDLED
|
436
|
+
end
|
437
|
+
when KEY_RIGHT
|
438
|
+
$log.debug "RIGHTIN MENU : "
|
439
|
+
if cmenu.parent.is_a? RubyCurses::Menu
|
440
|
+
$log.debug "right IN MENU : #{cmenu.parent.class} len: #{cmenu.parent.current_menu.length}"
|
441
|
+
$log.debug "right IN MENU : #{cmenu.parent.class} len: #{cmenu.current_menu.length}"
|
442
|
+
end
|
443
|
+
if cmenu.parent.is_a? RubyCurses::Menu and !cmenu.parent.current_menu.empty?
|
444
|
+
$log.debug " ABOU TO DESTROY DUE TO RIGHT"
|
445
|
+
cmenu.parent.current_menu.pop
|
446
|
+
@@menus.pop
|
447
|
+
cmenu.destroy
|
448
|
+
end
|
449
|
+
return :UNHANDLED
|
450
|
+
else
|
451
|
+
ret = check_mnemonics cmenu, ch
|
452
|
+
return ret
|
453
|
+
end
|
454
|
+
end
|
455
|
+
##
|
456
|
+
# checks given key against current menu's items and fires key if
|
457
|
+
# added on 2008-11-27 12:07
|
458
|
+
def check_mnemonics cmenu, ch
|
459
|
+
# $log.debug "inside check_mnemonics #{ch}"
|
460
|
+
key = ch.chr.downcase rescue ""
|
461
|
+
cmenu.items.each_with_index do |item, ix|
|
462
|
+
next if !item.respond_to? :mnemonic or item.mnemonic.nil?
|
463
|
+
# $log.debug "inside check_mnemonics #{item.mnemonic}"
|
464
|
+
if key == item.mnemonic.downcase
|
465
|
+
cmenu.select_item ix # 2009-01-23 13:32 so focus moves to menu
|
466
|
+
ret = item.fire
|
467
|
+
return ret # 0 # 2009-01-23 00:43 menuitem returns CLOSE, menu 0
|
468
|
+
end
|
469
|
+
end
|
470
|
+
return :UNHANDLED
|
471
|
+
end
|
472
|
+
## menu
|
473
|
+
def show # menu.show
|
474
|
+
$log.debug "show (menu) : #{@text} "
|
475
|
+
if @window.nil?
|
476
|
+
create_window
|
477
|
+
end
|
478
|
+
@window.show
|
479
|
+
select_item 0
|
480
|
+
end
|
481
|
+
end
|
482
|
+
class PopupMenu < Menu
|
483
|
+
def initialize text, &block
|
484
|
+
@row_margin = 0
|
485
|
+
@@row = 0
|
486
|
+
@@col = 0
|
487
|
+
super
|
488
|
+
instance_eval &block if block_given?
|
489
|
+
end
|
490
|
+
def show component, x, y
|
491
|
+
@component = component
|
492
|
+
@@row = component.row
|
493
|
+
@@col = component.col
|
494
|
+
create_window
|
495
|
+
handle_keys
|
496
|
+
end
|
497
|
+
def handle_keys # popup
|
498
|
+
@toggle_key ||= 27 # default switch off with ESC, if nothing else defined
|
499
|
+
begin
|
500
|
+
catch(:menubarclose) do
|
501
|
+
while((ch = @window.getchar()) != @toggle_key )
|
502
|
+
case ch
|
503
|
+
when -1
|
504
|
+
next
|
505
|
+
else
|
506
|
+
ret = handle_key ch
|
507
|
+
$log.debug " POPUP got #{ret} added 2009-01-21 18:18 "
|
508
|
+
break if ret == :CLOSE
|
509
|
+
end
|
510
|
+
Ncurses::Panel.update_panels();
|
511
|
+
Ncurses.doupdate();
|
512
|
+
|
513
|
+
@window.wrefresh
|
514
|
+
end
|
515
|
+
end # catch
|
516
|
+
ensure
|
517
|
+
#ensure is required becos one can throw a :close
|
518
|
+
@@menus = [] # added 2009-01-23 13:21
|
519
|
+
destroy # Note that we destroy the menu bar upon exit
|
520
|
+
end
|
521
|
+
end
|
522
|
+
def destroy
|
523
|
+
$log.debug "DESTRY popup "
|
524
|
+
@visible = false
|
525
|
+
panel = @window.panel
|
526
|
+
Ncurses::Panel.del_panel(panel) if !panel.nil?
|
527
|
+
@window.delwin if !@window.nil?
|
528
|
+
@items.each do |item|
|
529
|
+
item.destroy
|
530
|
+
end
|
531
|
+
@window = nil
|
532
|
+
end
|
533
|
+
end # class
|
534
|
+
##
|
535
|
+
# An application related menubar.
|
536
|
+
# Currently, I am adding this to a form. But should this not be application specific ?
|
537
|
+
# It should popup no matter which window you are on ?? XXX
|
538
|
+
class MenuBar
|
539
|
+
attr_reader :items
|
540
|
+
attr_reader :window
|
541
|
+
attr_reader :panel
|
542
|
+
attr_reader :selected
|
543
|
+
attr_accessor :visible
|
544
|
+
attr_accessor :active_index
|
545
|
+
attr_accessor :state # normal, selected, highlighted
|
546
|
+
attr_accessor :toggle_key # key used to popup, should be set prior to attaching to form
|
547
|
+
def initialize &block
|
548
|
+
@window = nil
|
549
|
+
@active_index = 0
|
550
|
+
@items = []
|
551
|
+
@visible = false
|
552
|
+
@cols = Ncurses.COLS-1
|
553
|
+
instance_eval &block if block_given?
|
554
|
+
end
|
555
|
+
def focusable
|
556
|
+
false
|
557
|
+
end
|
558
|
+
def add menu
|
559
|
+
@items << menu
|
560
|
+
return self
|
561
|
+
end
|
562
|
+
def next_menu
|
563
|
+
$log.debug "next meu: #{@active_index} "
|
564
|
+
if @active_index < @items.length-1
|
565
|
+
set_menu @active_index + 1
|
566
|
+
else
|
567
|
+
set_menu 0
|
568
|
+
end
|
569
|
+
end
|
570
|
+
def prev_menu
|
571
|
+
$log.debug "prev meu: #{@active_index} "
|
572
|
+
if @active_index > 0
|
573
|
+
set_menu @active_index-1
|
574
|
+
else
|
575
|
+
set_menu @items.length-1
|
576
|
+
end
|
577
|
+
end
|
578
|
+
def set_menu index
|
579
|
+
$log.debug "set meu: #{@active_index} #{index}"
|
580
|
+
menu = @items[@active_index]
|
581
|
+
menu.on_leave # hide its window, if open
|
582
|
+
@active_index = index
|
583
|
+
menu = @items[@active_index]
|
584
|
+
menu.on_enter #display window, if previous was displayed
|
585
|
+
@window.wmove menu.row, menu.col
|
586
|
+
# menu.show
|
587
|
+
# menu.window.wrefresh # XXX we need this
|
588
|
+
end
|
589
|
+
# menubar LEFT, RIGHT, DOWN
|
590
|
+
def handle_keys
|
591
|
+
@selected = false
|
592
|
+
@toggle_key ||= 27 # default switch off with ESC, if nothing else defined
|
593
|
+
set_menu 0
|
594
|
+
begin
|
595
|
+
catch(:popupclose) do
|
596
|
+
while((ch = @window.getchar()) != @toggle_key )
|
597
|
+
$log.debug "menuubar inside handle_keys : #{ch}" if ch != -1
|
598
|
+
case ch
|
599
|
+
when -1
|
600
|
+
next
|
601
|
+
when KEY_DOWN
|
602
|
+
$log.debug "insdie keyDOWN : #{ch}"
|
603
|
+
if !@selected
|
604
|
+
current_menu.fire
|
605
|
+
else
|
606
|
+
current_menu.handle_key ch
|
607
|
+
end
|
608
|
+
|
609
|
+
@selected = true
|
610
|
+
when KEY_ENTER, 10, 13, 32
|
611
|
+
@selected = true
|
612
|
+
$log.debug " mb insdie ENTER : #{current_menu}"
|
613
|
+
ret = current_menu.handle_key ch
|
614
|
+
$log.debug "ret = #{ret} mb insdie ENTER : #{current_menu}"
|
615
|
+
#break; ## 2008-12-29 18:00 This will close after firing
|
616
|
+
#anything
|
617
|
+
break if ret == :CLOSE
|
618
|
+
when KEY_UP
|
619
|
+
$log.debug " mb insdie keyUPP : #{ch}"
|
620
|
+
current_menu.handle_key ch
|
621
|
+
when KEY_LEFT
|
622
|
+
$log.debug " mb insdie KEYLEFT : #{ch}"
|
623
|
+
ret = current_menu.handle_key ch
|
624
|
+
prev_menu if ret == :UNHANDLED
|
625
|
+
#display_items if @selected
|
626
|
+
when KEY_RIGHT
|
627
|
+
$log.debug " mb insdie KEYRIGHT : #{ch}"
|
628
|
+
ret = current_menu.handle_key ch
|
629
|
+
next_menu if ret == :UNHANDLED
|
630
|
+
else
|
631
|
+
$log.debug " mb insdie ELSE : #{ch}"
|
632
|
+
ret = current_menu.handle_key ch
|
633
|
+
if ret == :UNHANDLED
|
634
|
+
Ncurses.beep
|
635
|
+
else
|
636
|
+
break # we handled a menu action, close menubar (THIS WORKS FOR MNEMONICS ONLY and always)
|
637
|
+
end
|
638
|
+
end
|
639
|
+
Ncurses::Panel.update_panels();
|
640
|
+
Ncurses.doupdate();
|
641
|
+
|
642
|
+
@window.wrefresh
|
643
|
+
end
|
644
|
+
end # catch
|
645
|
+
ensure
|
646
|
+
#ensure is required becos one can throw a :close
|
647
|
+
destroy # Note that we destroy the menu bar upon exit
|
648
|
+
end
|
649
|
+
end
|
650
|
+
def current_menu
|
651
|
+
@items[@active_index]
|
652
|
+
end
|
653
|
+
def toggle
|
654
|
+
@visible = !@visible
|
655
|
+
if !@visible
|
656
|
+
hide
|
657
|
+
else
|
658
|
+
show
|
659
|
+
end
|
660
|
+
end
|
661
|
+
def hide
|
662
|
+
@visible = false
|
663
|
+
@window.hide if !@window.nil?
|
664
|
+
end
|
665
|
+
def show
|
666
|
+
@visible = true
|
667
|
+
if @window.nil?
|
668
|
+
repaint # XXX FIXME
|
669
|
+
else
|
670
|
+
@window.show
|
671
|
+
end
|
672
|
+
end
|
673
|
+
## menubar
|
674
|
+
def repaint
|
675
|
+
return if !@visible
|
676
|
+
@window ||= create_window
|
677
|
+
@window.printstring( 0, 0, "%-*s" % [@cols," "], $reversecolor)
|
678
|
+
c = 1; r = 0;
|
679
|
+
@items.each do |item|
|
680
|
+
item.row = r; item.col = c; item.parent = self
|
681
|
+
@window.printstring( r, c, " %s " % item.text, $reversecolor)
|
682
|
+
c += (item.text.length + 2)
|
683
|
+
end
|
684
|
+
@window.wrefresh
|
685
|
+
end
|
686
|
+
def create_window
|
687
|
+
@layout = { :height => 1, :width => 0, :top => 0, :left => 0 }
|
688
|
+
@win = VER::Window.new(@layout)
|
689
|
+
@window = @win
|
690
|
+
@win.bkgd(Ncurses.COLOR_PAIR(5));
|
691
|
+
@panel = @win.panel
|
692
|
+
return @window
|
693
|
+
end
|
694
|
+
def destroy
|
695
|
+
$log.debug "DESTRY menubar "
|
696
|
+
@visible = false
|
697
|
+
panel = @window.panel
|
698
|
+
Ncurses::Panel.del_panel(panel) if !panel.nil?
|
699
|
+
@window.delwin if !@window.nil?
|
700
|
+
@items.each do |item|
|
701
|
+
item.destroy
|
702
|
+
end
|
703
|
+
@window = nil
|
704
|
+
end
|
705
|
+
end # menubar
|
706
|
+
|
707
|
+
class CheckBoxMenuItem < MenuItem
|
708
|
+
include DSL
|
709
|
+
attr_reader :checkbox
|
710
|
+
def initialize text, mnemonic=nil, &block
|
711
|
+
@checkbox = CheckBox.new nil
|
712
|
+
@checkbox.text text
|
713
|
+
super
|
714
|
+
end
|
715
|
+
def onvalue
|
716
|
+
@checkbox.onvalue onvalue
|
717
|
+
end
|
718
|
+
def offvalue
|
719
|
+
@checkbox.onvalue offvalue
|
720
|
+
end
|
721
|
+
def text=(t) # stack level too deep if no = .????
|
722
|
+
@checkbox.text t
|
723
|
+
end
|
724
|
+
## added @ with text, else crashing on testmenu.rb
|
725
|
+
def to_s
|
726
|
+
" #{@text} "
|
727
|
+
end
|
728
|
+
def getvalue
|
729
|
+
checkbox.getvalue
|
730
|
+
end
|
731
|
+
def getvalue_for_paint
|
732
|
+
"|%-*s|" % [@width, checkbox.getvalue_for_paint]
|
733
|
+
end
|
734
|
+
def fire
|
735
|
+
checkbox.toggle
|
736
|
+
super
|
737
|
+
repaint
|
738
|
+
highlight true
|
739
|
+
end
|
740
|
+
def repaint
|
741
|
+
@parent.window.printstring( row, 0, getvalue_for_paint, $reversecolor)
|
742
|
+
parent.window.wrefresh
|
743
|
+
end
|
744
|
+
def method_missing(sym, *args)
|
745
|
+
if checkbox.respond_to? sym
|
746
|
+
$log.debug("calling CHECKBOXMENU #{sym} called #{args[0]}")
|
747
|
+
checkbox.send(sym, args)
|
748
|
+
else
|
749
|
+
$log.error("ERROR CHECKBOXMENU #{sym} called")
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
end
|
754
|
+
end # modul
|