ya2 · news · projects · code · about

removed shadows of the gui items
[pmachines.git] / pmachines / menu.py
1 from logging import info
2 from sys import platform, exit
3 from os import environ, system
4 from webbrowser import open_new_tab
5 from panda3d.core import Texture, TextNode, WindowProperties, LVector2i, \
6 TextProperties, TextPropertiesManager
7 from direct.gui.DirectGui import DirectButton, DirectCheckButton, \
8 DirectOptionMenu, DirectSlider, DirectCheckButton
9 from direct.gui.DirectGuiGlobals import FLAT
10 from direct.gui.OnscreenText import OnscreenText
11
12
13 class Menu:
14
15 def __init__(self, fsm, lang_mgr, opt_file, music, pipeline):
16 self._fsm = fsm
17 self._lang_mgr = lang_mgr
18 self._opt_file = opt_file
19 self._music = music
20 self._pipeline = pipeline
21 self._font = base.loader.load_font('assets/fonts/Hanken-Book.ttf')
22 self._font.clear()
23 self._font.set_pixels_per_unit(60)
24 self._font.set_minfilter(Texture.FTLinearMipmapLinear)
25 self._font.set_outline((0, 0, 0, 1), .8, .2)
26 self._widgets = []
27 self._common = {
28 'scale': .12,
29 'text_font': self._font,
30 'text_fg': (.9, .9, .9, 1),
31 'relief': FLAT,
32 'frameColor': (.4, .4, .4, .14),
33 'rolloverSound': loader.load_sfx('assets/audio/sfx/rollover.ogg'),
34 'clickSound': loader.load_sfx('assets/audio/sfx/click.ogg')}
35 self._common_btn = {'frameSize': (-3.8, 3.8, -.6, 1.2)} | self._common
36 hlc = self._common_btn['frameColor']
37 hlc = (hlc[0] + .2, hlc[1] + .2, hlc[2] + .2, hlc[3] + .2)
38 self._common_opt = {
39 'item_frameColor': self._common_btn['frameColor'],
40 'popupMarker_frameColor': self._common_btn['frameColor'],
41 'item_relief': self._common_btn['relief'],
42 'item_text_font': self._common_btn['text_font'],
43 'item_text_fg': self._common_btn['text_fg'],
44 'textMayChange': 1,
45 'highlightColor': hlc,
46 'text_align': TextNode.A_center,
47 } | self._common_btn
48 f_s = self._common_opt['frameSize']
49 self._common_opt['frameSize'] = f_s[0], f_s[1] - .56, f_s[2], f_s[3]
50 self._common_slider = self._common | {
51 'range': (0, 1),
52 'thumb_frameColor': (.4, .4, .4, .4),
53 'thumb_scale': 1.6,
54 'scale': .4}
55 del self._common_slider['rolloverSound']
56 del self._common_slider['clickSound']
57 self._set_main()
58
59 def _set_main(self):
60 self._widgets = []
61 self._widgets += [DirectButton(
62 text=_('Play'), pos=(0, 1, .6), command=self.on_play,
63 **self._common_btn)]
64 self._widgets += [DirectButton(
65 text=_('Options'), pos=(0, 1, .2), command=self.on_options,
66 **self._common_btn)]
67 self._widgets += [DirectButton(
68 text=_('Credits'), pos=(0, 1, -.2), command=self.on_credits,
69 **self._common_btn)]
70 self._widgets += [DirectButton(
71 text=_('Exit'), pos=(0, 1, -.6), command=lambda: exit(),
72 **self._common_btn)]
73
74 def _set_options(self):
75 self._widgets = []
76 self._lang_funcs = [lambda: _('English'), lambda: _('Italian')]
77 items = [fnc() for fnc in self._lang_funcs]
78 inititem = {
79 'en': _('English'),
80 'it': _('Italian')
81 }[self._opt_file['settings']['language']]
82 btn = DirectOptionMenu(
83 text=_('Language'), items=items, initialitem=inititem,
84 pos=(0, 1, .8), command=self.on_language, **self._common_opt)
85 btn.popupMenu['frameColor'] = self._common_btn['frameColor']
86 btn.popupMenu['relief'] = self._common_btn['relief']
87 self._widgets += [btn]
88 self._widgets += [OnscreenText(
89 _('Volume'), pos=(-.1, .55), font=self._common['text_font'],
90 scale=self._common['scale'], fg=self._common['text_fg'],
91 align=TextNode.A_right)]
92 self._widgets += [DirectSlider(
93 pos=(.5, 1, .57),
94 value=self._opt_file['settings']['volume'],
95 command=self.on_volume,
96 **self._common_slider)]
97 self._slider = self._widgets[-1]
98 self._widgets += [DirectCheckButton(
99 text=_('Fullscreen'), pos=(0, 1, .3), command=self.on_fullscreen,
100 indicator_frameColor=self._common_opt['highlightColor'],
101 indicator_relief=self._common_btn['relief'],
102 indicatorValue=self._opt_file['settings']['fullscreen'],
103 **self._common_btn)]
104 res = self._opt_file['settings']['resolution']
105 d_i = base.pipe.get_display_information()
106 def _res(idx):
107 return d_i.get_display_mode_width(idx), \
108 d_i.get_display_mode_height(idx)
109 resolutions = [
110 _res(idx) for idx in range(d_i.get_total_display_modes())]
111 resolutions = list(set(resolutions))
112 resolutions = sorted(resolutions)
113 resolutions = [(str(_res[0]), str(_res[1])) for _res in resolutions]
114 resolutions = ['x'.join(_res) for _res in resolutions]
115 if not res:
116 res = resolutions[-1]
117 btn = DirectOptionMenu(
118 text=_('Resolution'), items=resolutions, initialitem=res,
119 pos=(0, 1, .05), command=self.on_resolution, **self._common_opt)
120 btn.popupMenu['frameColor'] = self._common_btn['frameColor']
121 btn.popupMenu['relief'] = self._common_btn['relief']
122 self._widgets += [btn]
123 self._widgets += [DirectCheckButton(
124 text=_('Antialiasing'), pos=(0, 1, -.2), command=self.on_aa,
125 indicator_frameColor=self._common_opt['highlightColor'],
126 indicator_relief=self._common_btn['relief'],
127 indicatorValue=self._opt_file['settings']['antialiasing'],
128 **self._common_btn)]
129 self._widgets += [DirectCheckButton(
130 text=_('Shadows'), pos=(0, 1, -.45), command=self.on_shadows,
131 indicator_frameColor=self._common_opt['highlightColor'],
132 indicator_relief=self._common_btn['relief'],
133 indicatorValue=self._opt_file['settings']['shadows'],
134 **self._common_btn)]
135 self._widgets += [DirectButton(
136 text=_('Back'), pos=(0, 1, -.8), command=self.on_back,
137 **self._common_btn)]
138
139 def _set_credits(self):
140 self._widgets = []
141 tp_scale = TextProperties()
142 tp_scale.set_text_scale(.64)
143 TextPropertiesManager.getGlobalPtr().setProperties('scale', tp_scale)
144 self._widgets += [OnscreenText(
145 _('Code and gfx\n \1scale\1Flavio Calva\2\n\n\nMusic\n \1scale\1Stefan Grossmann\2'),
146 pos=(-.9, .55), font=self._common['text_font'],
147 scale=self._common['scale'], fg=self._common['text_fg'],
148 align=TextNode.A_left)]
149 self._widgets += [DirectButton(
150 text=_('Website'), pos=(-.6, 1, .29), command=self.on_website,
151 **self._common_btn | {'scale': .08})]
152 self._widgets += [OnscreenText(
153 _('Supporters\n \1scale\1rdb\2\n \1scale\1Luisa Tenuta\2\n \1scale\1Damiana Ercolani\2'),
154 pos=(.1, .55), font=self._common['text_font'],
155 scale=self._common['scale'], fg=self._common['text_fg'],
156 align=TextNode.A_left)]
157 self._widgets += [DirectButton(
158 text=_('Back'), pos=(0, 1, -.8), command=self.on_back,
159 **self._common_btn)]
160
161 def on_play(self):
162 self._fsm.demand('Scene')
163
164 def on_options(self):
165 self.destroy()
166 self._set_options()
167
168 def on_credits(self):
169 self.destroy()
170 self._set_credits()
171
172 def on_language(self, arg):
173 lang_code = {
174 _('English'): 'en_EN',
175 _('Italian'): 'it_IT'}[arg]
176 self._lang_mgr.set_lang(lang_code)
177 self._opt_file['settings']['language'] = lang_code[:2]
178 self._opt_file.store()
179 self.on_options()
180
181 def on_volume(self):
182 self._opt_file['settings']['volume'] = self._slider['value']
183 self._music.set_volume(self._slider['value'])
184
185 def on_fullscreen(self, arg):
186 props = WindowProperties()
187 props.set_fullscreen(arg)
188 base.win.request_properties(props)
189 self._opt_file['settings']['fullscreen'] = int(arg)
190 self._opt_file.store()
191
192 def on_resolution(self, arg):
193 props = WindowProperties()
194 props.set_size(LVector2i(*[int(_res) for _res in arg.split('x')]))
195 base.win.request_properties(props)
196 self._opt_file['settings']['resolution'] = arg
197 self._opt_file.store()
198
199 def on_aa(self, arg):
200 self._pipeline.msaa_samples = 4 if arg else 1
201 info(f'msaa: {self._pipeline.msaa_samples}')
202 self._opt_file['settings']['antialiasing'] = int(arg)
203 self._opt_file.store()
204
205 def on_shadows(self, arg):
206 self._pipeline.enable_shadows = int(arg)
207 info(f'shadows: {self._pipeline.enable_shadows}')
208 self._opt_file['settings']['shadows'] = int(arg)
209 self._opt_file.store()
210
211 def on_website(self):
212 if platform.startswith('linux'):
213 environ['LD_LIBRARY_PATH'] = ''
214 system('xdg-open https://www.ya2.it')
215 else:
216 open_new_tab('https://www.ya2.it')
217
218 def on_back(self):
219 self._opt_file.store()
220 self.destroy()
221 self._set_main()
222
223 def destroy(self):
224 [wdg.destroy() for wdg in self._widgets]