ya2 · news · projects · code · about

fb1aeb65ab98a074f7bfb38af68c0ea46b5bdbc6
[pmachines.git] / pmachines / editor / inspector.py
1 from collections import namedtuple
2 from panda3d.core import Texture, TextNode
3 from direct.gui.OnscreenImage import OnscreenImage
4 from direct.gui.DirectGui import DirectButton, DirectFrame, DirectEntry
5 from direct.gui.DirectGuiGlobals import FLAT, NORMAL
6 from direct.gui.OnscreenText import OnscreenText
7 from direct.showbase.DirectObject import DirectObject
8
9
10 class Inspector(DirectObject):
11
12 def __init__(self, item):
13 super().__init__()
14 self.__item = item
15 self._font = base.loader.load_font(
16 'assets/fonts/Hanken-Book.ttf')
17 self._font.clear()
18 self._font.set_pixels_per_unit(60)
19 self._font.set_minfilter(Texture.FTLinearMipmapLinear)
20 self._font.set_outline((0, 0, 0, 1), .8, .2)
21 self._common = {
22 'scale': .046,
23 'text_font': self._font,
24 'text_fg': (.9, .9, .9, 1),
25 'relief': FLAT,
26 'frameColor': (.4, .4, .4, .14),
27 'rolloverSound': loader.load_sfx(
28 'assets/audio/sfx/rollover.ogg'),
29 'clickSound': loader.load_sfx(
30 'assets/audio/sfx/click.ogg')}
31 w, h = .8, .76
32 self._frm = DirectFrame(frameColor=(.4, .4, .4, .06),
33 frameSize=(0, w, -h, 0),
34 parent=base.a2dTopRight,
35 pos=(-w, 0, 0))
36 self.__z = -.08
37 p = self.__item._np.get_pos()
38 r = self.__item._np.get_r()
39 s = self.__item._np.get_scale()[0]
40 m = self.__item._mass
41 restitution = self.__item._restitution
42 f = self.__item._friction
43 t, pos_entry = self.__add_row(_('position'), f'{round(p.x, 3)}, {round(p.z, 3)}', self.on_edit_position)
44 t, rot_entry = self.__add_row(_('roll'), f'{round(r, 3)}', self.on_edit_roll)
45 t, scale_entry = self.__add_row(_('scale'), f'{round(s, 3)}', self.on_edit_scale)
46 t, mass_entry = self.__add_row(_('mass'), f'{round(m, 3)}', self.on_edit_mass)
47 t, restitution_entry = self.__add_row(_('restitution'), f'{round(restitution, 3)}', self.on_edit_restitution)
48 t, friction_entry = self.__add_row(_('friction'), f'{round(f, 3)}', self.on_edit_friction)
49 fields = ['position', 'roll', 'scale', 'mass', 'restitution', 'friction']
50 Entries = namedtuple('Entries', fields)
51 self.__entries = Entries(pos_entry, rot_entry, scale_entry, mass_entry, restitution_entry, friction_entry)
52 def load_images_btn(path, col):
53 colors = {
54 'gray': [
55 (.6, .6, .6, 1), # ready
56 (1, 1, 1, 1), # press
57 (.8, .8, .8, 1), # rollover
58 (.4, .4, .4, .4)],
59 'green': [
60 (.1, .68, .1, 1),
61 (.1, 1, .1, 1),
62 (.1, .84, .1, 1),
63 (.4, .1, .1, .4)]}[col]
64 return [self.__load_img_btn(path, col) for col in colors]
65 fcols = (.4, .4, .4, .14), (.3, .3, .3, .05)
66 DirectButton(
67 image=load_images_btn('exitRight', 'gray'), scale=.05,
68 pos=(.06, 1, -h + .06),
69 parent=self._frm, command=self.destroy, state=NORMAL, relief=FLAT,
70 frameColor=fcols[0],
71 rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'),
72 clickSound=loader.load_sfx('assets/audio/sfx/click.ogg'))
73 self.accept('item-rototranslated', self.__on_item_rototranslated)
74
75 def __add_row(self, label, text, callback):
76 tw = 10
77 t = OnscreenText(
78 label,
79 pos=(.03, self.__z), parent=self._frm,
80 font=self._common['text_font'],
81 scale=self._common['scale'],
82 fg=self._common['text_fg'],
83 wordwrap=20, align=TextNode.ALeft)
84 e = DirectEntry(
85 scale=self._common['scale'],
86 pos=(.30, 1, self.__z),
87 entryFont=self._font,
88 width=tw,
89 cursorKeys=True,
90 frameColor=self._common['frameColor'],
91 initialText=text,
92 parent=self._frm,
93 text_fg=self._common['text_fg'],
94 command=callback)
95 self.__z -= .1
96 return t, e
97
98 def __load_img_btn(self, path, col):
99 img = OnscreenImage('assets/images/buttons/%s.dds' % path)
100 img.set_transparency(True)
101 img.set_color(col)
102 img.detach_node()
103 return img
104
105 def __on_item_rototranslated(self, np):
106 pos = np.get_pos()
107 r = np.get_r()
108 self.__entries.position.set('%s %s' % (str(round(pos.x, 3)), str(round(pos.z, 3))))
109 self.__entries.roll.set('%s' % str(round(r, 3)))
110
111 @property
112 def item(self):
113 return self.__item
114
115 def on_edit_position(self, txt):
116 x, z = map(float, txt.split())
117 self.__item.position = [x, 0, z]
118
119 def on_edit_roll(self, txt):
120 self.__item.roll = float(txt)
121
122 def on_edit_scale(self, txt):
123 self.__item.scale = float(txt)
124
125 def on_edit_mass(self, txt):
126 self.__item.mass = float(txt)
127
128 def on_edit_restitution(self, txt):
129 self.__item.restitution = float(txt)
130
131 def on_edit_friction(self, txt):
132 self.__item.friction = float(txt)
133
134 def destroy(self):
135 self._frm.destroy()
136 self.ignore('item-rototranslated')
137 messenger.send('editor-inspector-destroy')