Ruby GTK3移行後のメインリポジトリ
Revisão | a392642ca1c344b1a47c5ec4894e6e2a8b4a06c7 (tree) |
---|---|
Hora | 2014-06-29 22:11:10 |
Autor | Shyouzou Sugitani <shy@user...> |
Commiter | Shyouzou Sugitani |
add menu.rb
@@ -0,0 +1,1016 @@ | ||
1 | +# -*- coding: utf-8 -*- | |
2 | +# | |
3 | +# Copyright (C) 2003-2014 by Shyouzou Sugitani <shy@users.sourceforge.jp> | |
4 | +# Copyright (C) 2003 by Shun-ichi TAHARA <jado@flowernet.gr.jp> | |
5 | +# | |
6 | +# This program is free software; you can redistribute it and/or modify it | |
7 | +# under the terms of the GNU General Public License (version 2) as | |
8 | +# published by the Free Software Foundation. It is distributed in the | |
9 | +# hope that it will be useful, but WITHOUT ANY WARRANTY; without even the | |
10 | +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
11 | +# PURPOSE. See the GNU General Public License for more details. | |
12 | +# | |
13 | + | |
14 | +require 'gettext' | |
15 | +require "gtk3" | |
16 | + | |
17 | +require "ninix/pix" | |
18 | + | |
19 | +module Menu | |
20 | + | |
21 | + class Menu | |
22 | + include GetText | |
23 | + | |
24 | + bindtextdomain("ninix-aya") | |
25 | + | |
26 | + def initialize | |
27 | +# self.request_parent = lambda *a: None # dummy | |
28 | + @parent = nil | |
29 | + ui_info = " | |
30 | + <ui> | |
31 | + <popup name='popup'> | |
32 | + <menu action='Recommend'> | |
33 | + </menu> | |
34 | + <menu action='Portal'> | |
35 | + </menu> | |
36 | + <separator/> | |
37 | + <menu action='Plugin'> | |
38 | + </menu> | |
39 | + <menuitem action='Stick'/> | |
40 | + <separator/> | |
41 | + <menu action='Options'> | |
42 | + <menuitem action='Update'/> | |
43 | + <menuitem action='Vanish'/> | |
44 | + <menuitem action='Preferences'/> | |
45 | + <menuitem action='Console'/> | |
46 | + <menuitem action='Manager'/> | |
47 | + </menu> | |
48 | + <separator/> | |
49 | + <menu action='Change'> | |
50 | + </menu> | |
51 | + <menu action='Summon'> | |
52 | + </menu> | |
53 | + <menu action='Shell'> | |
54 | + </menu> | |
55 | + <menu action='Costume'> | |
56 | + </menu> | |
57 | + <menu action='Balloon'> | |
58 | + </menu> | |
59 | + <separator/> | |
60 | + <menu action='Information'> | |
61 | + <menuitem action='Usage'/> | |
62 | + <menuitem action='Version'/> | |
63 | + </menu> | |
64 | + <separator/> | |
65 | + <menu action='Nekodorif'> | |
66 | + </menu> | |
67 | + <menu action='Kinoko'> | |
68 | + </menu> | |
69 | + <separator/> | |
70 | + <menuitem action='Close'/> | |
71 | + <menuitem action='Quit'/> | |
72 | + </popup> | |
73 | + </ui> | |
74 | + " | |
75 | + @__menu_list = { | |
76 | + 'Portal' => { | |
77 | + 'entry' => ['Portal', nil, _('Portal sites(_P)'), nil], | |
78 | + 'visible' => 1}, | |
79 | + 'Recommend' => { | |
80 | + 'entry' => ['Recommend', nil, _('Recommend sites(_R)'), nil], | |
81 | + 'visible' => 1}, | |
82 | + 'Options' => { | |
83 | + 'entry' => ['Options', nil, _('Options(_F)'), nil], | |
84 | + 'visible' => 1}, | |
85 | + 'Options/Update' => { | |
86 | + 'entry' => ['Update', nil, _('Network Update(_U)'), nil, | |
87 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'network_update')}], | |
88 | + 'visible' => 1}, | |
89 | + 'Options/Vanish' => { | |
90 | + 'entry' => ['Vanish', nil, _('Vanish(_F)'), nil, | |
91 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'vanish')}], | |
92 | + 'visible' => 1}, | |
93 | + 'Options/Preferences' => { | |
94 | + 'entry' => ['Preferences', nil, _('Preferences...(_O)'), nil, | |
95 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'edit_preferences')}], | |
96 | + 'visible' => 1}, | |
97 | + 'Options/Console' => { | |
98 | + 'entry' => ['Console', nil, _('Console(_C)'), nil, | |
99 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'open_console')}], | |
100 | + 'visible' => 1}, | |
101 | + 'Options/Manager' => { | |
102 | + 'entry' => ['Manager', nil, _('Ghost Manager(_M)'), nil, | |
103 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'open_ghost_manager')}], | |
104 | + 'visible' => 1}, | |
105 | + 'Information' => { | |
106 | + 'entry' => ['Information', nil, _('Information(_I)'), nil], | |
107 | + 'visible' => 1}, | |
108 | + 'Information/Usage' => { | |
109 | + 'entry' => ['Usage', nil, _('Usage graph(_A)'), nil, | |
110 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'show_usage')}], | |
111 | + 'visible' => 1}, | |
112 | + 'Information/Version' => { | |
113 | + 'entry' => ['Version', nil, _('Version(_V)'), nil, | |
114 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'about')}], | |
115 | + 'visible' => 1}, | |
116 | + 'Close' => { | |
117 | + 'entry' => ['Close', nil, _('Close(_W)'), nil, | |
118 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'close_sakura')}], | |
119 | + 'visible' => 1}, | |
120 | + 'Quit' => { | |
121 | + 'entry' => ['Quit', nil, _('Quit(_Q)'), nil, | |
122 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'close_all')}], | |
123 | + 'visible' => 1}, | |
124 | + 'Change' => { | |
125 | + 'entry' => ['Change', nil, _('Change(_G)'), nil], | |
126 | + 'visible' => 1}, | |
127 | + 'Summon' => { | |
128 | + 'entry' => ['Summon', nil, _('Summon(_X)'), nil], | |
129 | + 'visible' => 1}, | |
130 | + 'Shell' => { | |
131 | + 'entry' => ['Shell', nil, _('Shell(_S)'), nil], | |
132 | + 'visible' => 1}, | |
133 | + 'Balloon' => { | |
134 | + 'entry' => ['Balloon', nil, _('Balloon(_B)'), nil], | |
135 | + 'visible' => 1}, | |
136 | + 'Costume' => { | |
137 | + 'entry' => ['Costume', nil, _('Costume(_C)'), nil], | |
138 | + 'visible' => 1}, | |
139 | + 'Stick' => { | |
140 | + 'entry' => ['Stick', nil, _('Stick(_Y)'), nil, | |
141 | + '', lambda {|a, b| @parent.handle_request('NOTIFY', 'stick_window')}, | |
142 | + false], | |
143 | + 'visible' => 1}, | |
144 | + 'Nekodorif' => { | |
145 | + 'entry' => ['Nekodorif', nil, _('Nekodorif(_N)'), nil], | |
146 | + 'visible' => 1}, | |
147 | + 'Kinoko' => { | |
148 | + 'entry' => ['Kinoko', nil, _('Kinoko(_K)'), nil], | |
149 | + 'visible' => 1}, | |
150 | + 'Plugin' => { | |
151 | + 'entry' => ['Plugin', nil, _('Plugin(_P)'), nil], | |
152 | + 'visible' => 1}, | |
153 | + } | |
154 | + @__fontcolor = { | |
155 | + 'normal' => [0, 0, 0], | |
156 | + 'prelight' => [255, 255, 255] | |
157 | + } | |
158 | + @__imagepath = { | |
159 | + 'background' => nil, | |
160 | + 'foreground' => nil, | |
161 | + 'background_with_sidebar' => nil, | |
162 | + 'foreground_with_sidebar' => nil | |
163 | + } | |
164 | + @__align = { | |
165 | + 'background' => nil, | |
166 | + 'foreground' => nil, | |
167 | + 'sidebar' => nil | |
168 | + } | |
169 | + actions = Gtk::ActionGroup.new('Actions') | |
170 | + entry = [] | |
171 | +# for key, value in @__menu_list.items() | |
172 | + for key in @__menu_list.keys | |
173 | + value = @__menu_list[key] | |
174 | + if key != 'Stick' | |
175 | + entry << value['entry'] | |
176 | + end | |
177 | + end | |
178 | + actions.add_actions(entry) | |
179 | + actions.add_toggle_actions([@__menu_list['Stick']['entry']]) | |
180 | + @ui_manager = Gtk::UIManager.new() | |
181 | + @ui_manager.insert_action_group(actions, 0) | |
182 | + @ui_manager.add_ui(ui_info) | |
183 | + @__popup_menu = @ui_manager.get_widget('/popup') | |
184 | + @__popup_menu.signal_connect('realize') do |i, *a| | |
185 | + set_stylecontext_with_sidebar(i, *a) | |
186 | + end | |
187 | + for key in @__menu_list.keys | |
188 | + item = @ui_manager.get_widget(['/popup/', key].join('')) | |
189 | + item.signal_connect('draw') do |i, *a| | |
190 | + set_stylecontext(i, *a) | |
191 | + end | |
192 | + submenu = item.submenu | |
193 | + if submenu | |
194 | + submenu.signal_connect('realize') do |i, *a| | |
195 | + set_stylecontext(i, *a) | |
196 | + end | |
197 | + end | |
198 | + end | |
199 | + end | |
200 | + | |
201 | + def set_responsible(parent) | |
202 | + @parent = parent | |
203 | + end | |
204 | + | |
205 | + def set_fontcolor(background, foreground) | |
206 | + @__fontcolor['normal'] = background | |
207 | + @__fontcolor['prelight'] = foreground | |
208 | + end | |
209 | + | |
210 | + def set_pixmap(path_background, path_sidebar, path_foreground, | |
211 | + align_background, align_sidebar, align_foreground) | |
212 | + @__imagepath['background'] = nil | |
213 | + @__imagepath['foreground'] = nil | |
214 | + @__imagepath['background_with_sidebar'] = nil | |
215 | + @__imagepath['foreground_with_sidebar'] = nil | |
216 | + @__align['background'] = align_background | |
217 | + @__align['foreground'] = align_foreground | |
218 | + @__align['sidebar'] = align_sidebar | |
219 | + if path_background != nil and os.path.exists(path_background) | |
220 | + begin | |
221 | + color = ninix.pix.get_png_lastpix(path_background) | |
222 | + @__imagepath['background'] = ["background-image: url('", | |
223 | + path_background, "');\n", | |
224 | + "background-color: ", | |
225 | + color, ";\n"].join('') | |
226 | + if path_sidebar != nil and os.path.exists(path_sidebar) | |
227 | + sidebar_width, sidebar_height = ninix.pix.get_png_size(path_sidebar) | |
228 | + @__imagepath['background_with_sidebar'] = ["background-image: url('", | |
229 | + path_sidebar, | |
230 | + "'),url('", | |
231 | + path_background, "');\n", | |
232 | + "background-repeat: no-repeat, repeat-x;\n", | |
233 | + "background-color: ", color, ";\n"].join('') | |
234 | + @sidebar_width = sidebar_width | |
235 | + else | |
236 | + @sidebar_width = 0 | |
237 | + end | |
238 | + rescue #except: | |
239 | + # pass | |
240 | + end | |
241 | + end | |
242 | + if @__imagepath['background'] == nil | |
243 | + @__imagepath['background'] = ["background-image: none;\n", | |
244 | + "background-color: transparent;\n"].join('') | |
245 | + end | |
246 | + if path_foreground != nil and os.path.exists(path_foreground) | |
247 | + begin | |
248 | + color = ninix.pix.get_png_lastpix(path_foreground) | |
249 | + @__imagepath['foreground'] = ["background-image: url('", | |
250 | + path_foreground, "');\n", | |
251 | + "background-color: ", | |
252 | + color, ";\n"].join('') | |
253 | + if path_sidebar != nil and os.path.exists(path_sidebar) | |
254 | + sidebar_width, sidebar_height = ninix.pix.get_png_size(path_sidebar) | |
255 | + @__imagepath['foreground_with_sidebar'] = ["background-image: url('", | |
256 | + path_sidebar, "'),url('", | |
257 | + path_foreground, "');\n", | |
258 | + "background-repeat: no-repeat, repeat-x;\n", | |
259 | + "background-color: ", color, ";\n"].join('') | |
260 | + @sidebar_width = sidebar_width | |
261 | + else | |
262 | + @sidebar_width = 0 | |
263 | + end | |
264 | + rescue # except: | |
265 | + @pass | |
266 | + end | |
267 | + end | |
268 | + if @__imagepath['foreground'] == nil | |
269 | + @__imagepath['foreground'] = ["background-image: none;\n", | |
270 | + "background-color: transparent;\n"].join('') | |
271 | + end | |
272 | + end | |
273 | + | |
274 | + def __set_mayuna_menu(side) | |
275 | + if @__mayuna_menu.length > side and @__mayuna_menu[side] != nil | |
276 | + menuitem = @ui_manager.get_widget(['/popup/', 'Costume'].join('')) | |
277 | + menuitem.set_submenu(@__mayuna_menu[side]) | |
278 | + __set_visible('Costume', 1) | |
279 | + else | |
280 | + __set_visible('Costume', 0) | |
281 | + end | |
282 | + end | |
283 | + | |
284 | + def create_mayuna_menu(mayuna_menu) | |
285 | + @__mayuna_menu = [] | |
286 | + for side in mayuna_menu | |
287 | + if side == 'sakura' | |
288 | + index = 0 | |
289 | + elsif side == 'kero' | |
290 | + index = 1 | |
291 | + elsif side.startswith('char') | |
292 | + begin | |
293 | + index = int(side[4, side.length]) | |
294 | + rescue #except: | |
295 | + next | |
296 | + end | |
297 | + else | |
298 | + next | |
299 | + end | |
300 | + for _ in range(@__mayuna_menu.length, index + 1) | |
301 | + @__mayuna_menu << nil | |
302 | + end | |
303 | + if mayuna_menu[side] | |
304 | + @__mayuna_menu[index] = Gtk::Menu.new() | |
305 | + item = Gtk::TearoffMenuItem.new() | |
306 | + item.show() | |
307 | + @__mayuna_menu[index] << item | |
308 | + for j in range(mayuna_menu[side].length) | |
309 | + key, name, state = mayuna_menu[side][j] | |
310 | + if key != '-' | |
311 | + item = Gtk::CheckMenuItem.new(name) | |
312 | + item.set_name('popup menu item') | |
313 | + item.set_active(bool(state)) | |
314 | + item.signal_connect('activate') do |a, k| | |
315 | + @parent.handle_request( | |
316 | + 'NOTIFY', 'toggle_bind', index, key) | |
317 | + end | |
318 | + item.signal_connect('draw') do |i, *a| | |
319 | + set_stylecontext(i, *a) | |
320 | + end | |
321 | + else | |
322 | + item = Gtk::SeparatorMenuItem.new() | |
323 | + end | |
324 | + item.show() | |
325 | + @__mayuna_menu[index] << item | |
326 | + end | |
327 | + @__mayuna_menu[index].signal_connect('realize') do |i, *a| | |
328 | + set_stylecontext(i, *a) | |
329 | + end | |
330 | + end | |
331 | + end | |
332 | + end | |
333 | + | |
334 | + __re_shortcut = Regexp.new('&(?=[\x21-\x7e])') | |
335 | + | |
336 | + def __modify_shortcut(caption) | |
337 | + return self.__re_shortcut.sub('_', caption) | |
338 | + end | |
339 | + | |
340 | + __re_mnemonic = Regexp.new('\(_.\)|_') | |
341 | + | |
342 | + def __cut_mnemonic(caption) | |
343 | + return self.__re_mnemonic.sub('', caption) | |
344 | + end | |
345 | + | |
346 | + def __update_ui(side) | |
347 | + @__ui = { | |
348 | + 'Options/Update' => [[['updatebuttoncaption', 'updatebutton.caption'], | |
349 | + ['updatebuttoncaption', 'updatebutton.caption']], | |
350 | + '(_U)', [[],[]]], | |
351 | + 'Options/Vanish' => [[['vanishbuttoncaption', 'vanishbutton.caption'], | |
352 | + ['vanishbuttoncaption', 'vanishbutton.caption']], | |
353 | + '(_F)', | |
354 | + [['vanishbuttonvisible', 'vanishbutton.visible'], | |
355 | + ['vanishbuttonvisible', 'vanishbutton.visible']]], | |
356 | + 'Portal' => [[['sakura.portalbuttoncaption', | |
357 | + 'portalrootbutton.caption'], []], '(_P)', [[], nil]], | |
358 | + 'Recommend' => [[['sakura.recommendbuttoncaption', | |
359 | + 'recommendrootbutton.caption'], | |
360 | + ['kero.recommendbuttoncaption']], '(_R)', [[], []]], | |
361 | + } | |
362 | + for key in @__ui.keys | |
363 | + #assert @__menu_list.include?(key) | |
364 | + if side > 1 | |
365 | + if ['Options/Update', 'Options/Vanish'].include?(key) | |
366 | + name_list = @__ui[key][0][1] # same as 'kero' | |
367 | + elsif key == 'Portal' | |
368 | + name_list = [] # same as 'kero' | |
369 | + elsif key == 'Recommend' | |
370 | + name_list = ['char{0:d}.recommendbuttoncaption'.format(side)] | |
371 | + else | |
372 | + name_list = @__ui[key][0][side] | |
373 | + end | |
374 | + if name_list # caption | |
375 | + for name in name_list | |
376 | + caption = @parent.handle_request('GET', 'getstring', name) | |
377 | + if caption | |
378 | + break | |
379 | + end | |
380 | + if caption | |
381 | + caption = __modify_shortcut(caption) | |
382 | + if caption == __cut_mnemonic(caption) | |
383 | + caption = [caption, @__ui[key][1]].join('') | |
384 | + end | |
385 | + __set_caption(key, caption) | |
386 | + end | |
387 | + end | |
388 | + end | |
389 | + end | |
390 | + if side > 1 | |
391 | + name_list = @__ui[key][2][1] # same as 'kero' | |
392 | + else | |
393 | + name_list = @__ui[key][2][side] | |
394 | + end | |
395 | + if name_list # visible | |
396 | + for name in name_list | |
397 | + visible = @parent.handle_request('GET', 'getstring', name) | |
398 | + if visible != nil | |
399 | + break | |
400 | + end | |
401 | + if visible == '0' | |
402 | + __set_visible(key, 0) | |
403 | + else | |
404 | + __set_visible(key, 1) | |
405 | + end | |
406 | + end | |
407 | + elsif name_list == nil | |
408 | + __set_visible(key, 0) | |
409 | + end | |
410 | + end | |
411 | + end | |
412 | + | |
413 | + def popup(button, side) | |
414 | + @__popup_menu.unrealize() | |
415 | + for key in @__menu_list.keys | |
416 | + item = @ui_manager.get_widget(['/popup/', key].join('')) | |
417 | + submenu = item.submenu | |
418 | + if submenu | |
419 | + submenu.unrealize() | |
420 | + end | |
421 | + end | |
422 | + if side > 1 | |
423 | + string = 'char{0:d}'.format(side) | |
424 | + else | |
425 | + #assert [0, 1].include?(side) ## FIXME | |
426 | + string = ['sakura', 'kero'][side] | |
427 | + end | |
428 | + string = [string, '.popupmenu.visible'].join('') | |
429 | + if @parent.handle_request('GET', 'getstring', string) == '0' | |
430 | + return | |
431 | + end | |
432 | + __update_ui(side) | |
433 | + if side == 0 | |
434 | + portal = @parent.handle_request( | |
435 | + 'GET', 'getstring', 'sakura.portalsites') | |
436 | + else | |
437 | + portal = nil | |
438 | + end | |
439 | + __set_portal_menu(side, portal) | |
440 | + if side > 1 | |
441 | + string = 'char{0:d}'.format(side) | |
442 | + else | |
443 | + #assert [0, 1].include?(side) ## FIXME | |
444 | + string = ['sakura', 'kero'][side] | |
445 | + end | |
446 | + string = [string, '.recommendsites'].join('') | |
447 | + recommend = @parent.handle_request('GET', 'getstring', string) | |
448 | + __set_recommend_menu(recommend) | |
449 | + __set_ghost_menu() | |
450 | + __set_shell_menu() | |
451 | + __set_balloon_menu() | |
452 | + __set_plugin_menu() | |
453 | + __set_mayuna_menu(side) | |
454 | + __set_nekodorif_menu() | |
455 | + __set_kinoko_menu() | |
456 | + for key in @__menu_list.keys | |
457 | + item = @ui_manager.get_widget(['/popup/', key].join('')) | |
458 | + visible = @__menu_list[key]['visible'] | |
459 | + if item | |
460 | + if visible | |
461 | + item.show() | |
462 | + else | |
463 | + item.hide() | |
464 | + end | |
465 | + end | |
466 | + end | |
467 | + @__popup_menu.popup(nil, nil, button, | |
468 | + Gtk.current_event_time()) | |
469 | + end | |
470 | + | |
471 | + def __set_caption(name, caption) | |
472 | + #assert @__menu_list.include?(name) | |
473 | + #assert isinstance(caption, str) | |
474 | + item = @ui_manager.get_widget(['/popup/', name].join('')) | |
475 | + if item | |
476 | + label = item.get_children()[0] | |
477 | + label.set_text_with_mnemonic(caption) | |
478 | + end | |
479 | + end | |
480 | + | |
481 | + def __set_visible(name, visible) | |
482 | + #assert @__menu_list.include?(name) | |
483 | + #assert [0, 1].include?(visible) | |
484 | + @__menu_list[name]['visible'] = visible | |
485 | + end | |
486 | + | |
487 | + def __set_portal_menu(side, portal) | |
488 | + if side >= 1 | |
489 | + __set_visible('Portal', 0) | |
490 | + else | |
491 | + if portal | |
492 | + menu = Gtk::Menu.new() | |
493 | + portal_list = portal.split(chr(2)) | |
494 | + for site in portal_list | |
495 | + entry = site.split(chr(1)) | |
496 | + if not entry | |
497 | + continue | |
498 | + end | |
499 | + title = entry[0] | |
500 | + if title == '-' | |
501 | + item = Gtk::SeparatorMenuItem.new() | |
502 | + else | |
503 | + item = Gtk::MenuItem.new(title) | |
504 | + if entry.length < 2 | |
505 | + item.set_sensitive(false) | |
506 | + end | |
507 | + if entry.length > 1 | |
508 | + url = entry[1] | |
509 | + end | |
510 | + if entry.length > 2 | |
511 | + base_path = @parent.handle_request( | |
512 | + 'GET', 'get_prefix') | |
513 | + filename = entry[2].lower() | |
514 | + head, tail = os.path.splitext(filename) | |
515 | + if not tail | |
516 | + for ext in ['.png', '.jpg', '.gif'] | |
517 | + filename = [filename, ext].join('') | |
518 | + banner = os.path.join( | |
519 | + base_path, 'ghost/master/banner', | |
520 | + os.fsencode(filename)) | |
521 | + if not os.path.exists(banner) | |
522 | + banner = nil | |
523 | + else | |
524 | + break | |
525 | + end | |
526 | + end | |
527 | + else | |
528 | + banner = os.path.join( | |
529 | + base_path, 'ghost/master/banner', | |
530 | + os.fsencode(filename)) | |
531 | + if not os.path.exists(banner) | |
532 | + banner = nil | |
533 | + end | |
534 | + end | |
535 | + else | |
536 | + banner = nil | |
537 | + end | |
538 | + if entry.length > 1 | |
539 | + item.signal_connect('activate') do |a, i| | |
540 | + @parent.handle_request( | |
541 | + 'NOTIFY', 'notify_site_selection', title, url) | |
542 | + end | |
543 | + item.set_has_tooltip(true) | |
544 | + item.signal_connect('query-tooltip') do || | |
545 | + on_tooltip(banner) | |
546 | + end | |
547 | + end | |
548 | + end | |
549 | + item.signal_connect('draw') do |i, *a| | |
550 | + set_stylecontext(i, *a) | |
551 | + end | |
552 | + menu.add(item) | |
553 | + item.show() | |
554 | + end | |
555 | + menuitem = @ui_manager.get_widget(['/popup/', 'Portal'].join('')) | |
556 | + menuitem.set_submenu(menu) | |
557 | + menu.signal_connect('realize') do |i, *a| | |
558 | + set_stylecontext(i, *a) | |
559 | + end | |
560 | + menu.show() | |
561 | + __set_visible('Portal', 1) | |
562 | + else | |
563 | + __set_visible('Portal', 0) | |
564 | + end | |
565 | + end | |
566 | + end | |
567 | + | |
568 | + def __set_recommend_menu(recommend) | |
569 | + if recommend | |
570 | + menu = Gtk::Menu.new() | |
571 | + recommend_list = recommend.split(chr(2)) | |
572 | + for site in recommend_list | |
573 | + entry = site.split(chr(1)) | |
574 | + if not entry | |
575 | + continue | |
576 | + end | |
577 | + title = entry[0] | |
578 | + if title == '-' | |
579 | + item = Gtk::SeparatorMenuItem.new() | |
580 | + else | |
581 | + item = Gtk::MenuItem.new(title) | |
582 | + if entry.length < 2 | |
583 | + item.set_sensitive(false) | |
584 | + end | |
585 | + if entry.length > 1 | |
586 | + url = entry[1] | |
587 | + end | |
588 | + if entry.length > 2 | |
589 | + base_path = @parent.handle_request('GET', 'get_prefix') | |
590 | + filename = entry[2].lower() | |
591 | + head, tail = os.path.splitext(filename) | |
592 | + if not tail | |
593 | + for ext in ['.png', '.jpg', '.gif'] | |
594 | + filename = [filename, ext].join('') | |
595 | + banner = os.path.join( | |
596 | + base_path, 'ghost/master/banner', | |
597 | + os.fsencode(filename)) | |
598 | + if not os.path.exists(banner) | |
599 | + banner = nil | |
600 | + else | |
601 | + break | |
602 | + end | |
603 | + end | |
604 | + else | |
605 | + banner = os.path.join( | |
606 | + base_path, 'ghost/master/banner', | |
607 | + os.fsencode(filename)) | |
608 | + if not os.path.exists(banner) | |
609 | + banner = nil | |
610 | + end | |
611 | + end | |
612 | + else | |
613 | + banner = nil | |
614 | + end | |
615 | + if entry.length > 1 | |
616 | + item.signal_connect('activate') do |a, i| | |
617 | + @parent.handle_request('NOTIFY', 'notify_site_selection', title, url) | |
618 | + end | |
619 | + item.set_has_tooltip(true) | |
620 | + item.signal_connect('query-tooltip') do || | |
621 | + on_tooltip(banner) | |
622 | + end | |
623 | + end | |
624 | + end | |
625 | + item.signal_connect('draw') do |i, *a| | |
626 | + set_stylecontext(i, *a) | |
627 | + end | |
628 | + menu.add(item) | |
629 | + item.show() | |
630 | + end | |
631 | + menuitem = @ui_manager.get_widget(['/popup/', 'Recommend'].join('')) | |
632 | + menuitem.set_submenu(menu) | |
633 | + menu.signal_connect('realize') do |i, *a| | |
634 | + set_stylecontext(i, *a) | |
635 | + end | |
636 | + menu.show() | |
637 | + __set_visible('Recommend', 1) | |
638 | + else | |
639 | + __set_visible('Recommend', 0) | |
640 | + end | |
641 | + end | |
642 | + | |
643 | + def create_ghost_menuitem(name, icon, key, handler, thumbnail) | |
644 | + if icon != nil | |
645 | + pixbuf = ninix.pix.create_icon_pixbuf(icon) | |
646 | + if pixbuf == nil | |
647 | + item = Gtk::MenuItem.new(name) | |
648 | + else | |
649 | + image = Gtk::Image.new() | |
650 | + image.set_from_pixbuf(pixbuf) | |
651 | + image.show() | |
652 | + item = Gtk::ImageMenuItem.new(name) | |
653 | + item.set_image(image) | |
654 | + item.set_always_show_image(true) # XXX | |
655 | + end | |
656 | + else | |
657 | + item = Gtk::MenuItem.new(name) | |
658 | + end | |
659 | + item.set_name('popup menu item') | |
660 | + item.show() | |
661 | + item.signal_connect('activate') do |a, v| | |
662 | + handler(key) | |
663 | + end | |
664 | + item.set_has_tooltip(true) | |
665 | + item.signal_connect('query-tooltip') do || | |
666 | + on_tooltip(thumbnail) | |
667 | + end | |
668 | + item.signal_connect('draw') do |i, *a| | |
669 | + set_stylecontext(i, *a) | |
670 | + end | |
671 | + return item | |
672 | + end | |
673 | + | |
674 | + def set_stylecontext(item, *args) | |
675 | + _, offset_y = item.translate_coordinates(item.parent, 0, 0) | |
676 | + style_context = item.style_context | |
677 | + provider = Gtk::CssProvider.new() | |
678 | + provider.load(data: ["GtkMenu {\n", | |
679 | + @__imagepath['background'], | |
680 | + "background-repeat: repeat-y;\n", | |
681 | + "color: ", | |
682 | + "\#", | |
683 | + sprintf("%02x", @__fontcolor['normal'][0]), | |
684 | + sprintf("%02x", @__fontcolor['normal'][1]), | |
685 | + sprintf("%02x", @__fontcolor['normal'][2]), | |
686 | + ";\n", | |
687 | + ["background-position: ", @__align['background'], " ", (-offset_y).to_s, "px;\n"].join(''), | |
688 | + "}\n", | |
689 | + "\n", | |
690 | + "GtkMenu :insensitive {\n", | |
691 | + @__imagepath['background'], | |
692 | + "background-repeat: repeat-y;\n", | |
693 | + ["background-position: ", @__align['background'], " ", (-offset_y).to_s, "px;\n"].join(''), | |
694 | + "}\n", | |
695 | + "\n", | |
696 | + "GtkMenu :prelight {\n", | |
697 | + @__imagepath['foreground'], | |
698 | + "background-repeat: repeat-y;\n", | |
699 | + "color: ", | |
700 | + "\#", | |
701 | + sprintf("%02x", @__fontcolor['prelight'][0]), | |
702 | + sprintf("%02x", @__fontcolor['prelight'][1]), | |
703 | + sprintf("%02x", @__fontcolor['prelight'][2]), | |
704 | + ";\n", | |
705 | + ["background-position: ", @__align['foreground'], " ", (-offset_y).to_s, "px;\n"].join(''), | |
706 | + "}" | |
707 | + ].join("")) | |
708 | + style_context.add_provider(provider, 800) # STYLE_PROVIDER_PRIORITY_USER | |
709 | + end | |
710 | + | |
711 | + def set_stylecontext_with_sidebar(item, *args) | |
712 | + if @__imagepath['background_with_sidebar'] == nil or \ | |
713 | + @__imagepath['foreground_with_sidebar'] == nil or \ | |
714 | + @sidebar_width <= 0 | |
715 | + set_stylecontext(item, *args) | |
716 | + return | |
717 | + end | |
718 | + _, offset_y = item.translate_coordinates(item.parent, 0, 0) | |
719 | + style_context = item.style_context | |
720 | + provider = Gtk::CssProvider.new() | |
721 | + provider.load(data: ["GtkMenu {\n", | |
722 | + @__imagepath['background_with_sidebar'], | |
723 | + "background-repeat: repeat-y;\n", | |
724 | + "color: ", | |
725 | + "\#", | |
726 | + sprintf("%02x", @__fontcolor['normal'][0]), | |
727 | + sprintf("%02x", @__fontcolor['normal'][1]), | |
728 | + sprintf("%02x", @__fontcolor['normal'][2]), | |
729 | + ";\n", | |
730 | + ["background-position: ", "0px ", (-offset_y).to_s, "px", ", ", | |
731 | + @sidebar_width.to_s, "px", " ", (-offset_y).to_s, "px;\n"].join(''), | |
732 | + ["padding-left: ", @sidebar_width.to_s, "px;\n"].join(''), | |
733 | + "}\n", | |
734 | + "\n", | |
735 | + "GtkMenu :insensitive {\n", | |
736 | + @__imagepath['background_with_sidebar'], | |
737 | + "background-repeat: repeat-y;\n", | |
738 | + ["background-position: ", "0px ", (-offset_y).to_s, "px", ", ", | |
739 | + @sidebar_width.to_s, "px", " ", (-offset_y).to_s, "px;\n"].join(''), | |
740 | + ["padding-left: ", @sidebar_width.to_s, "px;\n"].join(''), | |
741 | + "}\n", | |
742 | + "\n", | |
743 | + "GtkMenu :prelight {\n", | |
744 | + @__imagepath['foreground_with_sidebar'], | |
745 | + "background-repeat: repeat-y;\n", | |
746 | + "color: ", | |
747 | + "\#", | |
748 | + sprintf("%02x", @__fontcolor['prelight'][0]), | |
749 | + sprintf("%02x", @__fontcolor['prelight'][1]), | |
750 | + sprintf("%02x", @__fontcolor['prelight'][2]), | |
751 | + ";\n", | |
752 | + ["background-position: ", "0px ", (-offset_y).to_s, "px", ", ", | |
753 | + @sidebar_width.to_s, "px", " ", (-offset_y).to_s, "px;\n"].join(''), | |
754 | + ["padding-left: ", @sidebar_width.to_s, "px;\n"].join(''), | |
755 | + "}" | |
756 | + ].join('')) | |
757 | + style_context.add_provider(provider, 800) # STYLE_PROVIDER_PRIORITY_USER | |
758 | + end | |
759 | + | |
760 | + def on_tooltip(widget, x, y, keyboard_mode, tooltip, thumbnail) | |
761 | + if thumbnail == nil | |
762 | + return false | |
763 | + end | |
764 | + pixbuf = ninix.pix.create_pixbuf_from_file(thumbnail, is_pnr=false) | |
765 | + tooltip.set_icon(pixbuf) | |
766 | + return true | |
767 | + end | |
768 | + | |
769 | + def __set_ghost_menu | |
770 | + for path in ['Summon', 'Change'] | |
771 | + ghost_menu = Gtk::Menu.new() | |
772 | + for items in @parent.handle_request('GET', 'get_ghost_menus') | |
773 | + item = items[path] | |
774 | + if item.get_parent() | |
775 | + item.reparent(ghost_menu) | |
776 | + else | |
777 | + ghost_menu << item | |
778 | + end | |
779 | + end | |
780 | + menuitem = @ui_manager.get_widget(['/popup/', path].join('')) | |
781 | + menuitem.set_submenu(ghost_menu) | |
782 | + ghost_menu.signal_connect('realize') do |i, *a| | |
783 | + set_stylecontext(i, *a) | |
784 | + end | |
785 | + end | |
786 | + end | |
787 | + | |
788 | + def __set_shell_menu | |
789 | + shell_menu = @parent.handle_request('GET', 'get_shell_menu') | |
790 | + menuitem = @ui_manager.get_widget(['/popup/', 'Shell'].join('')) | |
791 | + menuitem.set_submenu(shell_menu) | |
792 | + end | |
793 | + | |
794 | + def __set_balloon_menu | |
795 | + balloon_menu = @parent.handle_request('GET', 'get_balloon_menu') | |
796 | + menuitem = @ui_manager.get_widget(['/popup/', 'Balloon'].join('')) | |
797 | + menuitem.set_submenu(balloon_menu) | |
798 | + end | |
799 | + | |
800 | + def create_meme_menu(menuitem) | |
801 | + menu = Gtk::Menu.new() | |
802 | + for item in menuitem.values() | |
803 | + if item.get_parent() | |
804 | + item.reparent(menu) | |
805 | + else | |
806 | + menu << item | |
807 | + end | |
808 | + end | |
809 | + menu.signal_connect('realize') do |i, *a| | |
810 | + set_stylecontext(i, *a) | |
811 | + end | |
812 | + return menu | |
813 | + end | |
814 | + | |
815 | + def create_meme_menuitem(name, value, handler, thumbnail) | |
816 | + item = Gtk::MenuItem.new(name) | |
817 | + item.set_name('popup menu item') | |
818 | + item.show() | |
819 | + item.signal_connect('activate') do |a, v| | |
820 | + handler(value) | |
821 | + end | |
822 | + item.set_has_tooltip(true) | |
823 | + item.signal_connect('query-tooltip') do || | |
824 | + on_tooltip(thumbnail) | |
825 | + end | |
826 | + item.signal_connect('draw') do |i, *a| | |
827 | + set_stylecontext(i, *a) | |
828 | + end | |
829 | + return item | |
830 | + end | |
831 | + | |
832 | + def __set_plugin_menu | |
833 | + plugin_list = @parent.handle_request('GET', 'get_plugin_list') | |
834 | + plugin_menu = Gtk::Menu.new() | |
835 | + for i in 0..(plugin_list.length - 1) | |
836 | + name = plugin_list[i]['name'] | |
837 | + item = Gtk::MenuItem.new(name) | |
838 | + item.set_name('popup menu item') | |
839 | + item.signal_connect('draw') do |i, *a| | |
840 | + set_stylecontext(i, *a) | |
841 | + end | |
842 | + item.show() | |
843 | + plugin_menu << item | |
844 | + item_list = plugin_list[i]['items'] | |
845 | + if item_list.length <= 1 | |
846 | + label, value = item_list[0] | |
847 | + item.signal_connect('activate') do |a, v| | |
848 | + @parent.handle_request('NOTIFY', 'select_plugin', value) | |
849 | + end | |
850 | + item.signal_connect('draw') do |i, *a| | |
851 | + set_stylecontext(i, *a) | |
852 | + end | |
853 | + ##if working: | |
854 | + ## item.set_sensitive(false) | |
855 | + else | |
856 | + submenu = Gtk::Menu.new() | |
857 | + submenu.set_name('popup menu') | |
858 | + item.set_submenu(submenu) | |
859 | + for label, value in item_list | |
860 | + item = Gtk::MenuItem.new(label) | |
861 | + item.set_name('popup menu item') | |
862 | + item.signal_connect('activate') do |a, v| | |
863 | + @parent.handle_request('NOTIFY', 'select_plugin', value) | |
864 | + end | |
865 | + item.signal_connect('draw') do |i, *a| | |
866 | + set_stylecontext(i, *a) | |
867 | + end | |
868 | + item.show() | |
869 | + ##if working: | |
870 | + ## item.set_sensitive(false) | |
871 | + submenu << item | |
872 | + end | |
873 | + submenu.signal_connect('realize') do |i, *a| | |
874 | + set_stylecontext(i, *a) | |
875 | + end | |
876 | + end | |
877 | + end | |
878 | + menuitem = @ui_manager.get_widget(['/popup/', 'Plugin'].join('')) | |
879 | + menuitem.set_submenu(plugin_menu) | |
880 | + plugin_menu.signal_connect('realize') do |i, *a| | |
881 | + set_stylecontext(i, *a) | |
882 | + end | |
883 | + end | |
884 | + | |
885 | + def __set_nekodorif_menu | |
886 | + nekodorif_list = @parent.handle_request('GET', 'get_nekodorif_list') | |
887 | + nekodorif_menu = Gtk::Menu.new() | |
888 | + for i in 0..(nekodorif_list.length - 1) | |
889 | + name = nekodorif_list[i]['name'] | |
890 | + item = Gtk::MenuItem.new(name) | |
891 | + item.set_name('popup menu item') | |
892 | + item.show() | |
893 | + nekodorif_menu << item | |
894 | + item.signal_connect('activate') do |a, n| | |
895 | + @parent.handle_request('NOTIFY', 'select_nekodorif', nekodorif_list[i]['dir']) | |
896 | + end | |
897 | + item.signal_connect('draw') do |i, *a| | |
898 | + set_stylecontext(i, *a) | |
899 | + end | |
900 | + ##if working: | |
901 | + ## item.set_sensitive(false) | |
902 | + end | |
903 | + menuitem = @ui_manager.get_widget(['/popup/', 'Nekodorif'].join('')) | |
904 | + menuitem.set_submenu(nekodorif_menu) | |
905 | + nekodorif_menu.signal_connect('realize') do |i, *a| | |
906 | + set_stylecontext(i, *a) | |
907 | + end | |
908 | + end | |
909 | + | |
910 | + def __set_kinoko_menu | |
911 | + kinoko_list = @parent.handle_request('GET', 'get_kinoko_list') | |
912 | + kinoko_menu = Gtk::Menu.new() | |
913 | + for i in 0..(kinoko_list.length - 1) | |
914 | + name = kinoko_list[i]['title'] | |
915 | + item = Gtk::MenuItem.new(name) | |
916 | + item.set_name('popup menu item') | |
917 | + item.show() | |
918 | + kinoko_menu << item | |
919 | + item.signal_connect('activate') do |a, k| | |
920 | + @parent.handle_request( | |
921 | + 'NOTIFY', 'select_kinoko', kinoko_list[i]) | |
922 | + end | |
923 | + item.signal_connect('draw') do |i, *a| | |
924 | + set_stylecontext(i, *a) | |
925 | + end | |
926 | + ##if working: | |
927 | + ## item.set_sensitive(false) | |
928 | + end | |
929 | + menuitem = @ui_manager.get_widget(['/popup/', 'Kinoko'].join('')) | |
930 | + menuitem.set_submenu(kinoko_menu) | |
931 | + kinoko_menu.signal_connect('realize') do |i, *a| | |
932 | + set_stylecontext(i, *a) | |
933 | + end | |
934 | + end | |
935 | + | |
936 | + def get_stick | |
937 | + item = @ui_manager.get_widget(['/popup/', 'Stick'].join('')) | |
938 | + if item != nil and item.get_active() | |
939 | + return 1 #true | |
940 | + else | |
941 | + return 0 #false | |
942 | + end | |
943 | + end | |
944 | + end | |
945 | + | |
946 | + class TEST | |
947 | + | |
948 | + def initialize | |
949 | + @test_menu = Menu.new() | |
950 | + @test_menu.set_responsible(self) | |
951 | + @test_menu.create_mayuna_menu([]) # XXX | |
952 | + @test_menu.set_pixmap(nil, nil, nil, "left", "left", "left") # XXX | |
953 | + @window = Pix::TransparentWindow.new() | |
954 | + @image_surface = Pix.create_surface_from_file('test1.png') | |
955 | + @window.signal_connect('delete_event') do |w, e| | |
956 | + # delete(w, e) | |
957 | + Gtk.main_quit | |
958 | + end | |
959 | + @darea = @window.darea # @window.get_child() | |
960 | + @darea.set_events(Gdk::Event::EXPOSURE_MASK| | |
961 | + Gdk::Event::BUTTON_PRESS_MASK| | |
962 | + Gdk::Event::BUTTON_RELEASE_MASK| | |
963 | + Gdk::Event::POINTER_MOTION_MASK| | |
964 | + Gdk::Event::POINTER_MOTION_HINT_MASK| | |
965 | + Gdk::Event::LEAVE_NOTIFY_MASK) | |
966 | + @darea.signal_connect('button_press_event') do |w, e| | |
967 | + button_press(w, e) | |
968 | + end | |
969 | + @darea.signal_connect('draw') do |w, cr| | |
970 | + redraw(w, cr) | |
971 | + end | |
972 | + @window.set_default_size(@image_surface.width, @image_surface.height) | |
973 | + @window.show_all() | |
974 | + Gtk.main | |
975 | + end | |
976 | + | |
977 | + def redraw(widget, cr) | |
978 | + #scale = @__scale | |
979 | + scale = 100.0 | |
980 | + cr.scale(scale / 100.0, scale / 100.0) | |
981 | + cr.set_source(@image_surface, 0, 0) | |
982 | + cr.set_operator(Cairo::OPERATOR_SOURCE) | |
983 | + cr.paint() | |
984 | + end | |
985 | + | |
986 | + def button_press(widget, event) | |
987 | + if event.button == 1 | |
988 | + if event.event_type == Gdk::Event::BUTTON_PRESS | |
989 | + @test_menu.popup(event.button, 0) | |
990 | + end | |
991 | + elsif event.button == 3 | |
992 | + if event.event_type == Gdk::Event::BUTTON_PRESS | |
993 | + @test_menu.popup(event.button, 1) | |
994 | + end | |
995 | + end | |
996 | + return true | |
997 | + end | |
998 | + | |
999 | + def handle_request(type, event, *a) # dummy | |
1000 | + if event == 'get_ghost_menus' | |
1001 | + return [] | |
1002 | + end | |
1003 | + if event == 'get_plugin_list' | |
1004 | + return [] | |
1005 | + end | |
1006 | + if event == 'get_nekodorif_list' | |
1007 | + return [] | |
1008 | + end | |
1009 | + if event == 'get_kinoko_list' | |
1010 | + return [] | |
1011 | + end | |
1012 | + end | |
1013 | + end | |
1014 | +end | |
1015 | + | |
1016 | +Menu::TEST.new |