Commit | Line | Data |
---|---|---|
7ac52030 | 1 | from logging import info, debug |
9199c6aa FC |
2 | from panda3d.core import WindowProperties, LVector2i |
3 | from direct.showbase.DirectObject import DirectObject | |
4 | from direct.gui.DirectGui import DirectFrame | |
5 | from ya2.utils.gfx import DirectGuiMixin, pos_pixel | |
7ac52030 | 6 | from ya2.utils.audio import AudioTools |
9199c6aa | 7 | from ya2.utils.gui.base_page import BasePage, OptionMenuInfo, TextInfo, SliderInfo, CheckButtonInfo, ButtonInfo |
7ac52030 FC |
8 | |
9 | ||
9199c6aa | 10 | class OptionsPage(BasePage, DirectObject): |
7ac52030 | 11 | |
9199c6aa FC |
12 | def __init__(self, page_info, option_file, set_language, gfx_pipeline): |
13 | DirectObject.__init__(self) | |
14 | self.__option_file = option_file | |
15 | self.__set_language = set_language | |
16 | self.__gfx_pipeline = gfx_pipeline | |
17 | self.__enforced_resolution = '' | |
18 | super().__init__(page_info) | |
7ac52030 | 19 | |
9199c6aa FC |
20 | def _build_widgets(self): |
21 | self.__build_language() | |
22 | self.__build_volume() | |
23 | self.__build_fullscreen() | |
24 | self.__build_resolution() | |
25 | self.__build_aa() | |
26 | self.__build_shadows() | |
27 | self.__build_back() | |
7ac52030 | 28 | |
9199c6aa | 29 | def __build_language(self): |
7ac52030 FC |
30 | self._lang_funcs = [lambda: _('English'), lambda: _('Italian')] |
31 | items = [fnc() for fnc in self._lang_funcs] | |
32 | inititem = { | |
33 | 'en': _('English'), | |
34 | 'it': _('Italian') | |
9199c6aa | 35 | }[self.__option_file['settings']['language']] |
7ac52030 FC |
36 | |
37 | def lang_cb(comps): | |
38 | for element in ['english', 'italian']: | |
9199c6aa FC |
39 | if element in self._page_info.test_positions: |
40 | del self._page_info.test_positions[element] | |
7ac52030 FC |
41 | for lng, btn in zip(['english', 'italian'], comps): |
42 | btn.__class__ = type('DirectFrameMixed', (DirectFrame, DirectGuiMixin), {}) | |
43 | pos = btn.pos_pixel() | |
9199c6aa FC |
44 | self._page_info.test_positions[lng] = (pos[0] + 5, pos[1]) |
45 | language_menu = OptionMenuInfo( | |
46 | id='languages', | |
47 | text=_('Language'), | |
48 | items=items, | |
49 | initial_item=inititem, | |
50 | pos=(0, .8), | |
51 | command=self.on_language) | |
52 | self._add_option_menu(language_menu, lang_cb) | |
53 | ||
54 | def __build_volume(self): | |
55 | t = TextInfo( | |
56 | text=_('Volume'), | |
57 | pos=(-.56, .55), | |
58 | align='left') | |
59 | self._add_text(t) | |
60 | s = SliderInfo( | |
61 | pos=(.3, 1, .57), | |
62 | value=self.__option_file['settings']['volume'], | |
63 | scale=(.28, 1, .5), | |
64 | command=self.on_volume) | |
65 | self._slider = self._add_slider(s) | |
66 | ||
67 | def __build_fullscreen(self): | |
68 | c = CheckButtonInfo( | |
69 | id='fullscreen', | |
70 | text=_('Fullscreen'), | |
71 | pos=(0, .3), | |
72 | command=self.on_fullscreen, | |
73 | value=self.__option_file['settings']['fullscreen']) | |
74 | self._add_check_button(c) | |
75 | ||
76 | def __build_resolution(self): | |
77 | res = self.__option_file['settings']['resolution'] | |
7ac52030 FC |
78 | d_i = base.pipe.get_display_information() |
79 | def _res(idx): | |
80 | return d_i.get_display_mode_width(idx), \ | |
81 | d_i.get_display_mode_height(idx) | |
82 | resolutions = [ | |
83 | _res(idx) for idx in range(d_i.get_total_display_modes())] | |
84 | resolutions = list(set(resolutions)) | |
85 | resolutions = sorted(resolutions) | |
86 | resolutions = [(str(_res[0]), str(_res[1])) for _res in resolutions] | |
87 | resolutions = ['x'.join(_res) for _res in resolutions] | |
88 | if not res: | |
89 | res = resolutions[-1] | |
7ac52030 FC |
90 | def res_cb(comps): |
91 | for element in ['res_1440x900', 'res_1360x768']: | |
9199c6aa FC |
92 | if element in self._page_info.test_positions: |
93 | del self._page_info.test_positions[element] | |
7ac52030 FC |
94 | for tgt_res in ['1440x900', '1360x768']: |
95 | for btn in comps: | |
96 | if btn['text'] == tgt_res: | |
97 | pos = pos_pixel(btn) | |
9199c6aa FC |
98 | self._page_info.test_positions['res_' + tgt_res] = (pos[0] + 5, pos[1]) |
99 | r = OptionMenuInfo( | |
100 | id='resolutions', | |
101 | text=_('Resolution'), | |
102 | items=resolutions, | |
103 | initial_item=res, | |
104 | pos=(0, .05), | |
105 | command=self.on_resolution) | |
106 | o = self._add_option_menu(r, res_cb) | |
107 | pos_res = o.pos_pixel() | |
108 | self._page_info.test_positions['res_1440x900'] = [pos_res[0] + 320, pos_res[1] + 75] | |
109 | self._page_info.test_positions['res_1360x768'] = [pos_res[0] + 430, pos_res[1] -285] | |
110 | ||
111 | def __build_aa(self): | |
112 | c = CheckButtonInfo( | |
113 | id='aa', | |
114 | text=_('Antialiasing'), | |
115 | pos=(0, -.2), | |
116 | command=self.on_aa, | |
117 | value=self.__option_file['settings']['antialiasing']) | |
118 | self._add_check_button(c) | |
119 | ||
120 | def __build_shadows(self): | |
121 | c = CheckButtonInfo( | |
122 | id='shadows', | |
123 | text=_('Shadows'), | |
124 | pos=(0, -.45), | |
125 | command=self.on_shadows, | |
126 | value=self.__option_file['settings']['shadows']) | |
127 | self._add_check_button(c) | |
128 | ||
129 | def __build_back(self): | |
130 | back_button = ButtonInfo( | |
131 | id='back', | |
132 | text=_('Back'), | |
133 | pos=(0, -.8), | |
134 | command=self._set_page, | |
135 | command_args=['main']) | |
136 | self._add_button(back_button) | |
7ac52030 FC |
137 | self.accept('enforce_resolution', self.enforce_resolution) |
138 | ||
9199c6aa FC |
139 | def enforce_resolution(self, resolution): |
140 | self.__enforced_resolution = resolution | |
141 | info('enforced resolution: ' + resolution) | |
142 | ||
7ac52030 FC |
143 | def on_language(self, arg): |
144 | lang_code = { | |
145 | _('English'): 'en_EN', | |
146 | _('Italian'): 'it_IT'}[arg] | |
9199c6aa FC |
147 | self.__set_language(lang_code) |
148 | self.__option_file['settings']['language'] = lang_code[:2] | |
149 | self.__option_file.store() | |
150 | self._set_page('options') | |
7ac52030 FC |
151 | |
152 | def on_volume(self): | |
9199c6aa | 153 | self.__option_file['settings']['volume'] = self._slider['value'] |
7ac52030 FC |
154 | AudioTools.set_volume(self._slider['value']) |
155 | ||
156 | def on_fullscreen(self, arg): | |
157 | props = WindowProperties() | |
158 | props.set_fullscreen(arg) | |
9199c6aa | 159 | if not self._page_info.running_functional_tests: |
7ac52030 FC |
160 | base.win.request_properties(props) |
161 | # if we actually switch to fullscreen during the tests then | |
162 | # exwm inside qemu can't restore the correct resolution | |
163 | # i may re-enable this if/when i run the tests onto a | |
164 | # physical machine | |
9199c6aa FC |
165 | self.__option_file['settings']['fullscreen'] = int(arg) |
166 | self.__option_file.store() | |
7ac52030 FC |
167 | |
168 | def on_resolution(self, arg): | |
9199c6aa FC |
169 | info('on resolution: %s (%s)' % (arg, self.__enforced_resolution)) |
170 | arg = self.__enforced_resolution or arg | |
7ac52030 FC |
171 | info('set resolution: %s' % arg) |
172 | props = WindowProperties() | |
173 | props.set_size(LVector2i(*[int(_res) for _res in arg.split('x')])) | |
174 | base.win.request_properties(props) | |
9199c6aa FC |
175 | self.__option_file['settings']['resolution'] = arg |
176 | self.__option_file.store() | |
7ac52030 FC |
177 | |
178 | def on_aa(self, arg): | |
9199c6aa FC |
179 | self.__gfx_pipeline.msaa_samples = 4 if arg else 1 |
180 | debug(f'msaa: {self.__gfx_pipeline.msaa_samples}') | |
181 | self.__option_file['settings']['antialiasing'] = int(arg) | |
182 | self.__option_file.store() | |
7ac52030 FC |
183 | |
184 | def on_shadows(self, arg): | |
9199c6aa FC |
185 | self.__gfx_pipeline.enable_shadows = int(arg) |
186 | debug(f'shadows: {self.__gfx_pipeline.enable_shadows}') | |
187 | self.__option_file['settings']['shadows'] = int(arg) | |
188 | self.__option_file.store() | |
189 | ||
190 | def on_back(self): | |
191 | self.__option_file.store() | |
192 | super().on_back() | |
193 | ||
194 | def destroy(self): | |
195 | super().destroy() | |
196 | self.ignore('enforce_resolution') |