ya2 · news · projects · code · about

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