Commit | Line | Data |
---|---|---|
ee65fee0 | 1 | from collections import namedtuple |
3466af49 | 2 | from logging import info |
c48bfe58 | 3 | from panda3d.core import Texture, TextNode, LPoint3f |
ee65fee0 | 4 | from direct.gui.OnscreenImage import OnscreenImage |
2aeb9f68 | 5 | from direct.gui.DirectGui import DirectButton, DirectFrame, DirectEntry, DirectOptionMenu, OkDialog |
ee65fee0 FC |
6 | from direct.gui.DirectGuiGlobals import FLAT, NORMAL |
7 | from direct.gui.OnscreenText import OnscreenText | |
8 | from direct.showbase.DirectObject import DirectObject | |
9f095a28 | 9 | from pmachines.items.item import FixedStrategy, StillStrategy |
2aeb9f68 FC |
10 | from pmachines.items.box import HitStrategy |
11 | from pmachines.items.domino import DownStrategy, UpStrategy | |
c617fd93 | 12 | from pmachines.editor.augmented_frame import AugmentedDirectFrame |
9199c6aa | 13 | from ya2.utils.gui.base_page import DirectOptionMenuTestable |
a810a9ed | 14 | from ya2.utils.gfx import DirectGuiMixin |
ee65fee0 FC |
15 | |
16 | ||
17 | class Inspector(DirectObject): | |
18 | ||
fd2a4e5d | 19 | def __init__(self, item, all_items, pos_mgr, strategy_items): |
ee65fee0 FC |
20 | super().__init__() |
21 | self.__item = item | |
2aeb9f68 | 22 | self.__all_items = all_items |
3466af49 | 23 | self.__pos_mgr = pos_mgr |
ee65fee0 FC |
24 | self._font = base.loader.load_font( |
25 | '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) | |
30 | self._common = { | |
31 | 'scale': .046, | |
32 | 'text_font': self._font, | |
33 | 'text_fg': (.9, .9, .9, 1), | |
34 | 'relief': FLAT, | |
35 | 'frameColor': (.4, .4, .4, .14), | |
36 | 'rolloverSound': loader.load_sfx( | |
37 | 'assets/audio/sfx/rollover.ogg'), | |
38 | 'clickSound': loader.load_sfx( | |
39 | 'assets/audio/sfx/click.ogg')} | |
a810a9ed | 40 | tooltip_args = self._common['text_font'], self._common['scale'], self._common['text_fg'] |
2aeb9f68 | 41 | w, h = .8, 1.04 |
c617fd93 | 42 | self._frm = AugmentedDirectFrame(frameColor=(.4, .4, .4, .06), |
c48bfe58 FC |
43 | frameSize=(0, w, -h, 0), |
44 | parent=base.a2dTopRight, | |
45 | pos=(-w, 0, 0), | |
c617fd93 | 46 | delta_drag=LPoint3f(-w, 0, -h), |
3466af49 FC |
47 | collapse_pos=(w - .06, 1, -h + .06), |
48 | pos_mgr=pos_mgr, | |
49 | frame_name='inspector') | |
ee65fee0 FC |
50 | self.__z = -.08 |
51 | p = self.__item._np.get_pos() | |
52 | r = self.__item._np.get_r() | |
53 | s = self.__item._np.get_scale()[0] | |
54 | m = self.__item._mass | |
55 | restitution = self.__item._restitution | |
56 | f = self.__item._friction | |
2aeb9f68 FC |
57 | _id = '' |
58 | if 'id' in self.__item.json: | |
59 | _id = self.__item.json['id'] | |
60 | _strategy = '' | |
61 | if 'strategy' in self.__item.json: | |
62 | _strategy = self.__item.json['strategy'] | |
63 | _strategy_args = '' | |
64 | if 'strategy_args' in self.__item.json: | |
7ab60451 | 65 | _strategy_args = ' '.join(map(str, self.__item.json['strategy_args'])) |
3466af49 FC |
66 | t, pos_entry = self.__add_row('position', _('position'), f'{round(p.x, 3)} {round(p.z, 3)}', self.on_edit_position, _('position (e.g. 0.1 2.3 4.5)')) |
67 | t, rot_entry = self.__add_row('roll', _('roll'), f'{round(r, 3)}', self.on_edit_roll, _('roll (e.g. 90)')) | |
68 | t, scale_entry = self.__add_row('scale', _('scale'), f'{round(s, 3)}', self.on_edit_scale, _('scale (e.g. 1.2)')) | |
69 | t, mass_entry = self.__add_row('mass', _('mass'), f'{round(m, 3)}', self.on_edit_mass, _('mass (default 1; 0 if fixed)')) | |
70 | t, restitution_entry = self.__add_row('restitution', _('restitution'), f'{round(restitution, 3)}', self.on_edit_restitution, _('restitution (default 0.5)')) | |
71 | t, friction_entry = self.__add_row('friction', _('friction'), f'{round(f, 3)}', self.on_edit_friction, _('friction (default 0.5)')) | |
72 | t, id_entry = self.__add_row('id', _('id'), _id, self.on_edit_id, _('id of the item (for the strategies)')) | |
fd2a4e5d FC |
73 | # item_modules = glob('pmachines/items/*.py') |
74 | # item_modules = [basename(i)[:-3] for i in item_modules] | |
75 | # strategy_items = [''] | |
76 | # for item_module in item_modules: | |
77 | # mod_name = 'pmachines.items.' + item_module | |
78 | # for member in import_module(mod_name).__dict__.values(): | |
79 | # if isclass(member) and issubclass(member, ItemStrategy) and \ | |
80 | # member != ItemStrategy: | |
81 | # strategy_items = list(set(strategy_items + [member.__name__])) | |
82 | strategy_names = [s.__name__ for s in strategy_items] | |
83 | t, strategy_entry = self.__add_row_option(_('strategy'), _strategy, strategy_names, self.on_edit_strategy, _('the strategy of the item')) | |
3466af49 FC |
84 | |
85 | def strategy_set(comps): | |
fd2a4e5d | 86 | strategy_labels = [f'inspector_strategy_{i.lower()}' for i in strategy_names] |
3466af49 FC |
87 | for i in strategy_labels: |
88 | if i in self.__pos_mgr: | |
89 | del self.__pos_mgr[i] | |
90 | for l, b in zip(strategy_labels, comps): | |
91 | b.__class__ = type('DirectFrameMixed', (DirectFrame, DirectGuiMixin), {}) | |
92 | p = b.pos_pixel() | |
93 | self.__pos_mgr[l] = (p[0] + 5, p[1]) | |
94 | strategy_entry._show_cb = strategy_set | |
95 | p = strategy_entry.pos_pixel() | |
96 | self.__pos_mgr['editor_inspector_strategy'] = (p[0] + 5, p[1]) | |
97 | ||
98 | t, strategy_args_entry = self.__add_row('strategy_args', _('strategy_args'), _strategy_args, self.on_edit_strategy_args, _('the arguments of the strategy')) | |
2aeb9f68 | 99 | fields = ['position', 'roll', 'scale', 'mass', 'restitution', 'friction', 'id', 'strategy', 'strategy_args'] |
ee65fee0 | 100 | Entries = namedtuple('Entries', fields) |
2aeb9f68 | 101 | self.__entries = Entries(pos_entry, rot_entry, scale_entry, mass_entry, restitution_entry, friction_entry, id_entry, strategy_entry, strategy_args_entry) |
ee65fee0 FC |
102 | def load_images_btn(path, col): |
103 | colors = { | |
104 | 'gray': [ | |
105 | (.6, .6, .6, 1), # ready | |
106 | (1, 1, 1, 1), # press | |
107 | (.8, .8, .8, 1), # rollover | |
108 | (.4, .4, .4, .4)], | |
109 | 'green': [ | |
110 | (.1, .68, .1, 1), | |
111 | (.1, 1, .1, 1), | |
112 | (.1, .84, .1, 1), | |
113 | (.4, .1, .1, .4)]}[col] | |
114 | return [self.__load_img_btn(path, col) for col in colors] | |
115 | fcols = (.4, .4, .4, .14), (.3, .3, .3, .05) | |
a810a9ed | 116 | b = DirectButton( |
ee65fee0 FC |
117 | image=load_images_btn('exitRight', 'gray'), scale=.05, |
118 | pos=(.06, 1, -h + .06), | |
119 | parent=self._frm, command=self.destroy, state=NORMAL, relief=FLAT, | |
120 | frameColor=fcols[0], | |
121 | rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'), | |
122 | clickSound=loader.load_sfx('assets/audio/sfx/click.ogg')) | |
a810a9ed | 123 | b.__class__ = type('DirectButtonMixed', (DirectButton, DirectGuiMixin), {}) |
3466af49 | 124 | pos_mgr['editor_inspector_close'] = b.pos_pixel() |
a810a9ed | 125 | b.set_tooltip(_('Close'), *tooltip_args) |
ee65fee0 | 126 | self.accept('item-rototranslated', self.__on_item_rototranslated) |
a810a9ed | 127 | b = DirectButton( |
2aeb9f68 FC |
128 | image=load_images_btn('trashcan', 'gray'), scale=.05, |
129 | pos=(.18, 1, -h + .06), | |
130 | parent=self._frm, command=self.__delete_item, state=NORMAL, relief=FLAT, | |
131 | frameColor=fcols[0], | |
132 | rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'), | |
133 | clickSound=loader.load_sfx('assets/audio/sfx/click.ogg')) | |
a810a9ed | 134 | b.__class__ = type('DirectButtonMixed', (DirectButton, DirectGuiMixin), {}) |
3466af49 | 135 | pos_mgr['editor_inspector_delete'] = b.pos_pixel() |
a810a9ed | 136 | b.set_tooltip(_('Delete the item'), *tooltip_args) |
ee65fee0 | 137 | |
3466af49 | 138 | def __add_row(self, id_, label, text, callback, tooltip): |
ee65fee0 | 139 | tw = 10 |
a810a9ed | 140 | tooltip_args = self._common['text_font'], self._common['scale'], self._common['text_fg'] |
ee65fee0 FC |
141 | t = OnscreenText( |
142 | label, | |
143 | pos=(.03, self.__z), parent=self._frm, | |
144 | font=self._common['text_font'], | |
145 | scale=self._common['scale'], | |
146 | fg=self._common['text_fg'], | |
147 | wordwrap=20, align=TextNode.ALeft) | |
148 | e = DirectEntry( | |
149 | scale=self._common['scale'], | |
150 | pos=(.30, 1, self.__z), | |
151 | entryFont=self._font, | |
152 | width=tw, | |
153 | cursorKeys=True, | |
154 | frameColor=self._common['frameColor'], | |
155 | initialText=text, | |
156 | parent=self._frm, | |
157 | text_fg=self._common['text_fg'], | |
158 | command=callback) | |
a810a9ed FC |
159 | e.__class__ = type('DirectEntryMixed', (DirectEntry, DirectGuiMixin), {}) |
160 | e.set_tooltip(tooltip, *tooltip_args) | |
3466af49 | 161 | self.__pos_mgr[f'editor_inspector_{id_}'] = e.pos_pixel() |
ee65fee0 FC |
162 | self.__z -= .1 |
163 | return t, e | |
164 | ||
3466af49 | 165 | def __add_row_option(self, label, text, items, callback, tooltip): |
a810a9ed | 166 | tooltip_args = self._common['text_font'], self._common['scale'], self._common['text_fg'] |
2aeb9f68 FC |
167 | t = OnscreenText( |
168 | label, | |
169 | pos=(.03, self.__z), parent=self._frm, | |
170 | font=self._common['text_font'], | |
171 | scale=self._common['scale'], | |
172 | fg=self._common['text_fg'], | |
173 | wordwrap=20, align=TextNode.ALeft) | |
3466af49 | 174 | e = DirectOptionMenuTestable( |
2aeb9f68 FC |
175 | scale=self._common['scale'], |
176 | initialitem=text, | |
177 | pos=(.30, 1, self.__z), | |
3466af49 | 178 | items=items, |
2aeb9f68 FC |
179 | parent=self._frm, |
180 | command=callback, | |
181 | state=NORMAL, | |
182 | relief=FLAT, | |
183 | item_relief=FLAT, | |
184 | frameColor=self._common['frameColor'], | |
185 | item_frameColor=self._common['frameColor'], | |
186 | popupMenu_frameColor=self._common['frameColor'], | |
187 | popupMarker_frameColor=self._common['frameColor'], | |
188 | text_font=self._font, | |
189 | text_fg=self._common['text_fg'], | |
190 | highlightColor=(.9, .9, .9, .9), | |
191 | item_text_font=self._font, | |
192 | item_text_fg=self._common['text_fg'], | |
193 | rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'), | |
194 | clickSound=loader.load_sfx('assets/audio/sfx/click.ogg')) | |
a810a9ed FC |
195 | e.__class__ = type('DirectOptionMenuMixed', (DirectOptionMenu, DirectGuiMixin), {}) |
196 | e.set_tooltip(tooltip, *tooltip_args) | |
2aeb9f68 FC |
197 | self.__z -= .1 |
198 | return t, e | |
199 | ||
ee65fee0 FC |
200 | def __load_img_btn(self, path, col): |
201 | img = OnscreenImage('assets/images/buttons/%s.dds' % path) | |
202 | img.set_transparency(True) | |
203 | img.set_color(col) | |
204 | img.detach_node() | |
205 | return img | |
206 | ||
207 | def __on_item_rototranslated(self, np): | |
208 | pos = np.get_pos() | |
209 | r = np.get_r() | |
210 | self.__entries.position.set('%s %s' % (str(round(pos.x, 3)), str(round(pos.z, 3)))) | |
211 | self.__entries.roll.set('%s' % str(round(r, 3))) | |
2aeb9f68 FC |
212 | self.__item.json['position'] = list(pos) |
213 | self.__item.json['roll'] = round(r, 3) | |
214 | ||
215 | def __delete_item(self): | |
216 | messenger.send('editor-inspector-delete', [self.__item]) | |
217 | self.destroy() | |
ee65fee0 FC |
218 | |
219 | @property | |
220 | def item(self): | |
221 | return self.__item | |
222 | ||
223 | def on_edit_position(self, txt): | |
224 | x, z = map(float, txt.split()) | |
225 | self.__item.position = [x, 0, z] | |
226 | ||
227 | def on_edit_roll(self, txt): | |
228 | self.__item.roll = float(txt) | |
229 | ||
230 | def on_edit_scale(self, txt): | |
231 | self.__item.scale = float(txt) | |
232 | ||
233 | def on_edit_mass(self, txt): | |
234 | self.__item.mass = float(txt) | |
235 | ||
236 | def on_edit_restitution(self, txt): | |
237 | self.__item.restitution = float(txt) | |
238 | ||
239 | def on_edit_friction(self, txt): | |
240 | self.__item.friction = float(txt) | |
241 | ||
2aeb9f68 FC |
242 | def on_edit_id(self, txt): |
243 | self.__item.id = txt | |
244 | ||
245 | def on_edit_strategy(self, txt): | |
246 | if not txt: | |
247 | self.__entries.strategy_args.set('') | |
248 | return | |
249 | name2class = { | |
250 | 'StillStrategy': StillStrategy, | |
251 | 'UpStrategy': UpStrategy, | |
252 | 'HitStrategy': HitStrategy, | |
253 | 'DownStrategy': DownStrategy, | |
254 | 'FixedStrategy': FixedStrategy} | |
255 | class_ = name2class[txt] | |
256 | args = [] | |
257 | error = False | |
258 | if txt == 'StillStrategy': | |
259 | args += [self.__item._np] | |
260 | if txt in ['UpStrategy', 'DownStrategy']: | |
261 | args += [self.__item._np] | |
262 | try: | |
263 | args += [float(self.__entries.strategy_args.get())] | |
264 | except ValueError: | |
265 | error = True | |
266 | if txt == 'HitStrategy': | |
267 | for item in self.__all_items: | |
268 | if item.id == self.__entries.strategy_args.get(): | |
269 | args += [item] | |
270 | args += [self.__item.node] | |
271 | args += [self.__item._world] | |
272 | if not error: | |
273 | self.__item.strategy = class_(*args) | |
274 | self.__item.strategy_json = txt | |
275 | else: | |
276 | self.__show_error_popup() | |
277 | ||
278 | def on_edit_strategy_args(self, txt): | |
279 | self.__item.strategy_args_json = txt | |
280 | ||
281 | def __show_error_popup(self): | |
282 | self.__dialog = OkDialog(dialogName='Strategy args errors', | |
283 | text=_('There are errors in the strategy args.'), | |
284 | command=self.__actually_close) | |
285 | self.__dialog['frameColor'] = (.4, .4, .4, .14) | |
286 | self.__dialog['relief'] = FLAT | |
287 | self.__dialog.component('text0')['fg'] = (.9, .9, .9, 1) | |
288 | self.__dialog.component('text0')['font'] = self._font | |
289 | for b in self.__dialog.buttonList: | |
290 | b['frameColor'] = (.4, .4, .4, .14) | |
291 | b.component('text0')['fg'] = (.9, .9, .9, 1) | |
292 | b.component('text0')['font'] = self._font | |
293 | b.component('text1')['fg'] = (.9, .1, .1, 1) | |
294 | b.component('text1')['font'] = self._font | |
295 | b.component('text2')['fg'] = (.9, .9, .1, 1) | |
296 | b.component('text2')['font'] = self._font | |
297 | ||
298 | def __actually_close(self, arg): | |
299 | self.__entries.strategy.set('') | |
300 | self.__entries.strategy_args.set('') | |
301 | self.__dialog.cleanup() | |
302 | ||
ee65fee0 FC |
303 | def destroy(self): |
304 | self._frm.destroy() | |
305 | self.ignore('item-rototranslated') | |
306 | messenger.send('editor-inspector-destroy') | |
3133e30f FC |
307 | |
308 | ||
309 | class PixelSpaceInspector(DirectObject): | |
310 | ||
311 | def __init__(self, item, all_items): | |
3466af49 | 312 | info('PixelSpaceInspector') |
3133e30f FC |
313 | super().__init__() |
314 | self.__item = item | |
315 | self.__all_items = all_items | |
316 | self._font = base.loader.load_font( | |
317 | 'assets/fonts/Hanken-Book.ttf') | |
318 | self._font.clear() | |
319 | self._font.set_pixels_per_unit(60) | |
320 | self._font.set_minfilter(Texture.FTLinearMipmapLinear) | |
321 | self._font.set_outline((0, 0, 0, 1), .8, .2) | |
322 | self._common = { | |
323 | 'scale': .046, | |
324 | 'text_font': self._font, | |
325 | 'text_fg': (.9, .9, .9, 1), | |
326 | 'relief': FLAT, | |
327 | 'frameColor': (.4, .4, .4, .14), | |
328 | 'rolloverSound': loader.load_sfx( | |
329 | 'assets/audio/sfx/rollover.ogg'), | |
330 | 'clickSound': loader.load_sfx( | |
331 | 'assets/audio/sfx/click.ogg')} | |
332 | w, h = .8, .36 | |
333 | self._frm = DirectFrame(frameColor=(.4, .4, .4, .06), | |
334 | frameSize=(0, w, -h, 0), | |
335 | parent=base.a2dTopRight, | |
336 | pos=(-w, 0, 0)) | |
337 | self.__z = -.08 | |
338 | p = self.__item._np.get_pos() | |
339 | _id = '' | |
340 | if 'id' in self.__item.json: | |
341 | _id = self.__item.json['id'] | |
342 | t, pos_entry = self.__add_row(_('position'), f'{round(p.x, 3)}, {round(p.z, 3)}', self.on_edit_position) | |
343 | t, id_entry = self.__add_row(_('id'), _id, self.on_edit_id) | |
344 | fields = ['position', 'id'] | |
345 | Entries = namedtuple('Entries', fields) | |
346 | self.__entries = Entries(pos_entry, id_entry) | |
347 | def load_images_btn(path, col): | |
348 | colors = { | |
349 | 'gray': [ | |
350 | (.6, .6, .6, 1), # ready | |
351 | (1, 1, 1, 1), # press | |
352 | (.8, .8, .8, 1), # rollover | |
353 | (.4, .4, .4, .4)], | |
354 | 'green': [ | |
355 | (.1, .68, .1, 1), | |
356 | (.1, 1, .1, 1), | |
357 | (.1, .84, .1, 1), | |
358 | (.4, .1, .1, .4)]}[col] | |
359 | return [self.__load_img_btn(path, col) for col in colors] | |
360 | fcols = (.4, .4, .4, .14), (.3, .3, .3, .05) | |
361 | DirectButton( | |
362 | image=load_images_btn('exitRight', 'gray'), scale=.05, | |
363 | pos=(.06, 1, -h + .06), | |
364 | parent=self._frm, command=self.destroy, state=NORMAL, relief=FLAT, | |
365 | frameColor=fcols[0], | |
366 | rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'), | |
367 | clickSound=loader.load_sfx('assets/audio/sfx/click.ogg')) | |
368 | self.accept('item-rototranslated', self.__on_item_rototranslated) | |
369 | DirectButton( | |
370 | image=load_images_btn('trashcan', 'gray'), scale=.05, | |
371 | pos=(.18, 1, -h + .06), | |
372 | parent=self._frm, command=self.__delete_item, state=NORMAL, relief=FLAT, | |
373 | frameColor=fcols[0], | |
374 | rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'), | |
375 | clickSound=loader.load_sfx('assets/audio/sfx/click.ogg')) | |
376 | ||
377 | def __add_row(self, label, text, callback): | |
378 | tw = 10 | |
379 | t = OnscreenText( | |
380 | label, | |
381 | pos=(.03, self.__z), parent=self._frm, | |
382 | font=self._common['text_font'], | |
383 | scale=self._common['scale'], | |
384 | fg=self._common['text_fg'], | |
385 | wordwrap=20, align=TextNode.ALeft) | |
386 | e = DirectEntry( | |
387 | scale=self._common['scale'], | |
388 | pos=(.30, 1, self.__z), | |
389 | entryFont=self._font, | |
390 | width=tw, | |
391 | cursorKeys=True, | |
392 | frameColor=self._common['frameColor'], | |
393 | initialText=text, | |
394 | parent=self._frm, | |
395 | text_fg=self._common['text_fg'], | |
396 | command=callback) | |
397 | self.__z -= .1 | |
398 | return t, e | |
399 | ||
400 | def __load_img_btn(self, path, col): | |
401 | img = OnscreenImage('assets/images/buttons/%s.dds' % path) | |
402 | img.set_transparency(True) | |
403 | img.set_color(col) | |
404 | img.detach_node() | |
405 | return img | |
406 | ||
407 | def __on_item_rototranslated(self, np): | |
bf77b5d5 | 408 | pos = np.pos2d_pixel() |
3133e30f FC |
409 | self.__entries.position.set('%s %s' % (str(round(pos[0], 3)), str(round(pos[1], 3)))) |
410 | self.__item.json['position'] = list(pos) | |
411 | ||
412 | def __delete_item(self): | |
413 | messenger.send('editor-inspector-delete', [self.__item]) | |
414 | self.destroy() | |
415 | ||
416 | @property | |
417 | def item(self): | |
418 | return self.__item | |
419 | ||
420 | def on_edit_position(self, txt): | |
421 | x, z = map(float, txt.split()) | |
422 | self.__item.position = [x, 0, z] | |
423 | ||
424 | def on_edit_id(self, txt): | |
425 | self.__item.id = txt | |
426 | ||
427 | def __actually_close(self, arg): | |
428 | self.__entries.strategy.set('') | |
429 | self.__entries.strategy_args.set('') | |
430 | self.__dialog.cleanup() | |
431 | ||
432 | def destroy(self): | |
433 | self._frm.destroy() | |
434 | self.ignore('item-rototranslated') | |
435 | messenger.send('editor-inspector-destroy') | |
436 | ||
437 | ||
438 | class WorldSpaceInspector(DirectObject): | |
439 | ||
3466af49 FC |
440 | def __init__(self, item, all_items, pos_mgr): |
441 | info('WorldSpaceInspector') | |
3133e30f FC |
442 | super().__init__() |
443 | self.__item = item | |
444 | self.__all_items = all_items | |
3466af49 | 445 | self.__pos_mgr = pos_mgr |
3133e30f FC |
446 | self._font = base.loader.load_font( |
447 | 'assets/fonts/Hanken-Book.ttf') | |
448 | self._font.clear() | |
449 | self._font.set_pixels_per_unit(60) | |
450 | self._font.set_minfilter(Texture.FTLinearMipmapLinear) | |
451 | self._font.set_outline((0, 0, 0, 1), .8, .2) | |
452 | self._common = { | |
453 | 'scale': .046, | |
454 | 'text_font': self._font, | |
455 | 'text_fg': (.9, .9, .9, 1), | |
456 | 'relief': FLAT, | |
457 | 'frameColor': (.4, .4, .4, .14), | |
458 | 'rolloverSound': loader.load_sfx( | |
459 | 'assets/audio/sfx/rollover.ogg'), | |
460 | 'clickSound': loader.load_sfx( | |
461 | 'assets/audio/sfx/click.ogg')} | |
3466af49 | 462 | tooltip_args = self._common['text_font'], self._common['scale'], self._common['text_fg'] |
3133e30f FC |
463 | w, h = .8, .36 |
464 | self._frm = DirectFrame(frameColor=(.4, .4, .4, .06), | |
465 | frameSize=(0, w, -h, 0), | |
466 | parent=base.a2dTopRight, | |
467 | pos=(-w, 0, 0)) | |
468 | self.__z = -.08 | |
469 | p = self.__item._np.get_pos() | |
470 | _id = '' | |
471 | if 'id' in self.__item.json: | |
472 | _id = self.__item.json['id'] | |
3466af49 FC |
473 | t, pos_entry = self.__add_row('position', _('position'), f'{round(p.x, 3)} {round(p.z, 3)}', self.on_edit_position, _('position (e.g. 0.1 2.3 4.5)')) |
474 | t, id_entry = self.__add_row('id', _('id'), _id, self.on_edit_id, _('id of the item (for the strategies)')) | |
3133e30f FC |
475 | fields = ['position', 'id'] |
476 | Entries = namedtuple('Entries', fields) | |
477 | self.__entries = Entries(pos_entry, id_entry) | |
478 | def load_images_btn(path, col): | |
479 | colors = { | |
480 | 'gray': [ | |
481 | (.6, .6, .6, 1), # ready | |
482 | (1, 1, 1, 1), # press | |
483 | (.8, .8, .8, 1), # rollover | |
484 | (.4, .4, .4, .4)], | |
485 | 'green': [ | |
486 | (.1, .68, .1, 1), | |
487 | (.1, 1, .1, 1), | |
488 | (.1, .84, .1, 1), | |
489 | (.4, .1, .1, .4)]}[col] | |
490 | return [self.__load_img_btn(path, col) for col in colors] | |
491 | fcols = (.4, .4, .4, .14), (.3, .3, .3, .05) | |
3466af49 | 492 | b = DirectButton( |
3133e30f FC |
493 | image=load_images_btn('exitRight', 'gray'), scale=.05, |
494 | pos=(.06, 1, -h + .06), | |
495 | parent=self._frm, command=self.destroy, state=NORMAL, relief=FLAT, | |
496 | frameColor=fcols[0], | |
497 | rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'), | |
498 | clickSound=loader.load_sfx('assets/audio/sfx/click.ogg')) | |
3466af49 FC |
499 | b.__class__ = type('DirectButtonMixed', (DirectButton, DirectGuiMixin), {}) |
500 | pos_mgr['editor_inspector_test_close'] = b.pos_pixel() | |
501 | b.set_tooltip(_('Close'), *tooltip_args) | |
3133e30f | 502 | self.accept('item-rototranslated', self.__on_item_rototranslated) |
3466af49 | 503 | b = DirectButton( |
3133e30f FC |
504 | image=load_images_btn('trashcan', 'gray'), scale=.05, |
505 | pos=(.18, 1, -h + .06), | |
506 | parent=self._frm, command=self.__delete_item, state=NORMAL, relief=FLAT, | |
507 | frameColor=fcols[0], | |
508 | rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'), | |
509 | clickSound=loader.load_sfx('assets/audio/sfx/click.ogg')) | |
3466af49 FC |
510 | b.__class__ = type('DirectButtonMixed', (DirectButton, DirectGuiMixin), {}) |
511 | pos_mgr['editor_inspector_test_delete'] = b.pos_pixel() | |
512 | b.set_tooltip(_('Delete the item'), *tooltip_args) | |
3133e30f | 513 | |
3466af49 | 514 | def __add_row(self, id_, label, text, callback, tooltip): |
3133e30f | 515 | tw = 10 |
3466af49 | 516 | tooltip_args = self._common['text_font'], self._common['scale'], self._common['text_fg'] |
3133e30f FC |
517 | t = OnscreenText( |
518 | label, | |
519 | pos=(.03, self.__z), parent=self._frm, | |
520 | font=self._common['text_font'], | |
521 | scale=self._common['scale'], | |
522 | fg=self._common['text_fg'], | |
523 | wordwrap=20, align=TextNode.ALeft) | |
524 | e = DirectEntry( | |
525 | scale=self._common['scale'], | |
526 | pos=(.30, 1, self.__z), | |
527 | entryFont=self._font, | |
528 | width=tw, | |
529 | cursorKeys=True, | |
530 | frameColor=self._common['frameColor'], | |
531 | initialText=text, | |
532 | parent=self._frm, | |
533 | text_fg=self._common['text_fg'], | |
534 | command=callback) | |
3466af49 FC |
535 | e.__class__ = type('DirectEntryMixed', (DirectEntry, DirectGuiMixin), {}) |
536 | e.set_tooltip(tooltip, *tooltip_args) | |
537 | self.__pos_mgr[f'editor_inspector_test_{id_}'] = e.pos_pixel() | |
3133e30f FC |
538 | self.__z -= .1 |
539 | return t, e | |
540 | ||
541 | def __load_img_btn(self, path, col): | |
542 | img = OnscreenImage('assets/images/buttons/%s.dds' % path) | |
543 | img.set_transparency(True) | |
544 | img.set_color(col) | |
545 | img.detach_node() | |
546 | return img | |
547 | ||
548 | def __on_item_rototranslated(self, np): | |
549 | pos = np.get_pos() | |
550 | self.__entries.position.set('%s %s' % (str(round(pos.x, 3)), str(round(pos.z, 3)))) | |
551 | self.__item.json['position'] = list(pos) | |
552 | ||
553 | def __delete_item(self): | |
554 | messenger.send('editor-inspector-delete', [self.__item]) | |
555 | self.destroy() | |
556 | ||
557 | @property | |
558 | def item(self): | |
559 | return self.__item | |
560 | ||
561 | def on_edit_position(self, txt): | |
562 | x, z = map(float, txt.split()) | |
563 | self.__item.position = [x, 0, z] | |
564 | ||
565 | def on_edit_id(self, txt): | |
566 | self.__item.id = txt | |
567 | ||
568 | def __actually_close(self, arg): | |
569 | self.__entries.strategy.set('') | |
570 | self.__entries.strategy_args.set('') | |
571 | self.__dialog.cleanup() | |
572 | ||
573 | def destroy(self): | |
574 | self._frm.destroy() | |
575 | self.ignore('item-rototranslated') | |
576 | messenger.send('editor-inspector-destroy') |