ya2 · news · projects · code · about

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