ya2 · news · projects · code · about

inspector
[pmachines.git] / pmachines / editor / inspector.py
CommitLineData
ee65fee0
FC
1from collections import namedtuple
2from panda3d.core import Texture, TextNode
3from direct.gui.OnscreenImage import OnscreenImage
4from direct.gui.DirectGui import DirectButton, DirectFrame, DirectEntry
5from direct.gui.DirectGuiGlobals import FLAT, NORMAL
6from direct.gui.OnscreenText import OnscreenText
7from direct.showbase.DirectObject import DirectObject
8
9
10class 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')