• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Ruby GTK3移行後のメインリポジトリ


コミットメタ情報

リビジョンa392642ca1c344b1a47c5ec4894e6e2a8b4a06c7 (tree)
日時2014-06-29 22:11:10
作者Shyouzou Sugitani <shy@user...>
コミッターShyouzou Sugitani

ログメッセージ

add menu.rb

変更サマリ

差分

--- /dev/null
+++ b/lib/ninix/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