ya2 · news · projects · code · about

better arrangement of the side panel
[pmachines.git] / pmachines / scene.py
CommitLineData
1be87278 1from panda3d.core import AmbientLight, DirectionalLight, Point3
36099535
FC
2from panda3d.bullet import BulletPlaneShape, BulletGhostNode
3from direct.gui.OnscreenImage import OnscreenImage
4from direct.gui.DirectGui import DirectButton
5from direct.gui.DirectGuiGlobals import FLAT, DISABLED, NORMAL
1be87278
FC
6from direct.showbase.DirectObject import DirectObject
7from pmachines.items.background import Background
8from pmachines.items.box import Box
a5dc83f4 9from pmachines.sidepanel import SidePanel
79f81d48 10from lib.engine.gui.cursor import MouseCursor
13263131 11from lib.lib.p3d.gfx import P3dGfxMgr
1be87278
FC
12
13
14class Scene(DirectObject):
15
16 def __init__(self, world):
17 super().__init__()
18 self._world = world
19 self._set_camera()
79f81d48
FC
20 self._cursor = MouseCursor(
21 'assets/buttons/arrowUpLeft.png', (.04, 1, .04), (.5, .5, .5, 1),
22 (.01, .01))
36099535 23 self._set_gui()
1be87278
FC
24 self._set_lights()
25 self._set_input()
c8d8653f 26 self._set_mouse_plane()
1be87278 27 Background()
7850ccc4 28 self.items = [Box(world, self._mouse_plane_node, 3, self.cb_inst)]
a5dc83f4 29 self._side_panel = SidePanel(world, self._mouse_plane_node, (-5, 4), (-3, 1), 1)
37ba71d8 30 taskMgr.add(self.on_frame, 'on_frame')
1be87278
FC
31
32 def _set_camera(self):
33 base.camera.set_pos(0, -20, 0)
34 base.camera.look_at(0, 0, 0)
35
36099535
FC
36 def _set_gui(self):
37 def load_img_btn(path, col):
38 img = OnscreenImage('assets/buttons/%s.png' % path)
39 img.set_transparency(True)
40 img.set_color(col)
41 img.detach_node()
42 return img
01b221a6
FC
43 def load_images_btn(path, col):
44 colors = {
45 'gray': [
46 (.6, .6, .6, 1), # ready
47 (1, 1, 1, 1), # press
48 (.8, .8, .8, 1), # rollover
49 (.4, .4, .4, .4)],
50 'green': [
51 (.1, .68, .1, 1),
52 (.1, 1, .1, 1),
53 (.1, .84, .1, 1),
54 (.4, .1, .1, .4)]}[col]
36099535
FC
55 return [load_img_btn(path, col) for col in colors]
56 abl, abr = base.a2dBottomLeft, base.a2dBottomRight
57 btn_info = [
01b221a6
FC
58 ('home', self.on_home, DISABLED, abl, 'gray'),
59 ('information', self.on_information, DISABLED, abl, 'gray'),
60 ('right', self.on_play, NORMAL, abr, 'green'),
61 ('next', self.on_next, DISABLED, abr, 'gray'),
62 ('previous', self.on_prev, DISABLED, abr, 'gray'),
63 ('rewind', self.on_rewind, DISABLED, abr, 'gray')]
36099535
FC
64 num_l = num_r = 0
65 for binfo in btn_info:
01b221a6 66 imgs = load_images_btn(binfo[0], binfo[4])
36099535
FC
67 if binfo[3] == base.a2dBottomLeft:
68 sign, num = 1, num_l
69 num_l += 1
70 else:
71 sign, num = -1, num_r
72 num_r += 1
73 fcols = (.4, .4, .4, .14), (.3, .3, .3, .05)
74 btn = DirectButton(
75 image=imgs, scale=.05, pos=(sign * (.06 + .11 * num), 1, .06),
76 parent=binfo[3], command=binfo[1], state=binfo[2], relief=FLAT,
54a1397e
FC
77 frameColor=fcols[0] if binfo[2] == NORMAL else fcols[1],
78 rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'),
79 clickSound=loader.load_sfx('assets/audio/sfx/click.ogg'))
36099535
FC
80 btn.set_transparency(True)
81
1be87278
FC
82 def _set_directional_light(self, name, hpr, color):
83 light = DirectionalLight(name)
84 light_np = render.attach_new_node(light)
85 light_np.set_hpr(*hpr)
86 light.set_color(color)
87 render.set_light(light_np)
88
89 def _set_lights(self):
90 alight = AmbientLight('alight') # for ao
91 alight.set_color((.4, .4, .4, 1))
92 alnp = render.attach_new_node(alight)
93 render.set_light(alnp)
94 self._set_directional_light('key light', (315, -60, 0),
95 (3.6, 3.6, 3.6, 1))
96 self._set_directional_light('fill light', (195, -30, 0),
97 (.4, .4, .4, 1))
98 self._set_directional_light('rim light', (75, -30, 0), (.3, .3, .3, 1))
99
100 def _set_input(self):
49c79300 101 self.accept('mouse1', self.on_click_l)
c8d8653f 102 self.accept('mouse1-up', self.on_release)
49c79300
FC
103 self.accept('mouse3', self.on_click_r)
104 self.accept('mouse3-up', self.on_release)
c8d8653f
FC
105
106 def _set_mouse_plane(self):
651713a9 107 shape = BulletPlaneShape((0, -1, 0), 0)
c8d8653f
FC
108 #self._mouse_plane_node = BulletRigidBodyNode('mouse plane')
109 self._mouse_plane_node = BulletGhostNode('mouse plane')
110 self._mouse_plane_node.addShape(shape)
111 #np = render.attachNewNode(self._mouse_plane_node)
112 #self._world.attachRigidBody(self._mouse_plane_node)
113 self._world.attachGhost(self._mouse_plane_node)
1be87278 114
37ba71d8
FC
115 def _get_hits(self):
116 if not base.mouseWatcherNode.has_mouse(): return []
13263131 117 p_from, p_to = P3dGfxMgr.world_from_to(base.mouseWatcherNode.get_mouse())
37ba71d8
FC
118 return self._world.ray_test_all(p_from, p_to).get_hits()
119
49c79300 120 def _on_click(self, method):
c8d8653f
FC
121 for hit in self._get_hits():
122 if hit.get_node() == self._mouse_plane_node:
123 pos = hit.get_hit_pos()
37ba71d8 124 for hit in self._get_hits():
1be87278 125 for item in [i for i in self.items if hit.get_node() == i.node]:
49c79300 126 getattr(item, method)(pos)
79f81d48
FC
127 img = 'move' if method == 'on_click_l' else 'rotate'
128 self._cursor.set_image('assets/buttons/%s.png' % img)
49c79300
FC
129
130 def on_click_l(self):
131 self._on_click('on_click_l')
132
133 def on_click_r(self):
134 self._on_click('on_click_r')
c8d8653f
FC
135
136 def on_release(self):
49c79300 137 [item.on_release() for item in self.items]
79f81d48 138 self._cursor.set_image('assets/buttons/arrowUpLeft.png')
37ba71d8 139
651713a9
FC
140 def on_aspect_ratio_changed(self):
141 [item.on_aspect_ratio_changed() for item in self.items]
a5dc83f4 142 self._side_panel.update(self.items)
651713a9 143
37ba71d8 144 def on_frame(self, task):
c8d8653f
FC
145 hits = self._get_hits()
146 pos = None
147 for hit in self._get_hits():
148 if hit.get_node() == self._mouse_plane_node:
149 pos = hit.get_hit_pos()
150 hit_nodes = [hit.get_node() for hit in hits]
37ba71d8
FC
151 items_hit = [itm for itm in self.items if itm.node in hit_nodes]
152 items_no_hit = [itm for itm in self.items if itm not in items_hit]
153 [itm.on_mouse_on() for itm in items_hit]
154 [itm.on_mouse_off() for itm in items_no_hit]
c8d8653f
FC
155 if pos:
156 [itm.on_mouse_move(pos) for itm in self.items]
37ba71d8 157 return task.cont
c8d8653f 158
7850ccc4
FC
159 def cb_inst(self, item):
160 self.items += [item]
161
c8d8653f
FC
162 def on_play(self):
163 [itm.play() for itm in self.items]
36099535
FC
164
165 def on_next(self):
166 print('on_next')
167
168 def on_prev(self):
169 print('on_prev')
170
171 def on_rewind(self):
172 print('on_rewind')
173
174 def on_home(self):
175 print('on_home')
176
177 def on_information(self):
178 print('on_information')