|
@@ -1,7 +1,11 @@
|
1
|
1
|
# coding: utf-8
|
|
2
|
+import weakref
|
|
3
|
+
|
2
|
4
|
import cocos
|
3
|
5
|
import pyglet
|
4
|
|
-from pyglet.window import key as wkey
|
|
6
|
+from pyglet.window import key as wkey, mouse
|
|
7
|
+
|
|
8
|
+from cocos import collision_model, euclid
|
5
|
9
|
from cocos.director import director
|
6
|
10
|
from cocos.layer import ScrollableLayer, Layer
|
7
|
11
|
from cocos.sprite import Sprite
|
|
@@ -71,14 +75,462 @@ class GridLayerMixin(object):
|
71
|
75
|
super().__init__(*args, **kwargs)
|
72
|
76
|
|
73
|
77
|
|
|
78
|
+class ProbeQuad(cocos.cocosnode.CocosNode):
|
|
79
|
+
|
|
80
|
+ def __init__(self, r, color4):
|
|
81
|
+ super(ProbeQuad, self).__init__()
|
|
82
|
+ self.color4 = color4
|
|
83
|
+ self.vertexes = [(r, 0, 0), (0, r, 0), (-r, 0, 0), (0, -r, 0)]
|
|
84
|
+
|
|
85
|
+ def draw(self):
|
|
86
|
+ pyglet.gl.glPushMatrix()
|
|
87
|
+ self.transform()
|
|
88
|
+ pyglet.gl.glBegin(pyglet.gl.GL_QUADS)
|
|
89
|
+ pyglet.gl.glColor4ub(*self.color4)
|
|
90
|
+ for v in self.vertexes:
|
|
91
|
+ pyglet.gl.glVertex3i(*v)
|
|
92
|
+ pyglet.gl.glEnd()
|
|
93
|
+ pyglet.gl.glPopMatrix()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+class MinMaxRect(cocos.cocosnode.CocosNode):
|
|
97
|
+ def __init__(self, layer_manager: LayerManager):
|
|
98
|
+ super(MinMaxRect, self).__init__()
|
|
99
|
+ self.layer_manager = layer_manager
|
|
100
|
+ self.color3 = (0, 0, 255)
|
|
101
|
+ self.vertexes = [(0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0)]
|
|
102
|
+ self.visible = False
|
|
103
|
+
|
|
104
|
+ def adjust_from_w_minmax(self, wminx, wmaxx, wminy, wmaxy):
|
|
105
|
+ # asumes world to screen preserves order
|
|
106
|
+ sminx, sminy = self.layer_manager.scrolling_manager.world_to_screen(wminx, wminy)
|
|
107
|
+ smaxx, smaxy = self.layer_manager.scrolling_manager.world_to_screen(wmaxx, wmaxy)
|
|
108
|
+ self.vertexes = [(sminx, sminy), (sminx, smaxy), (smaxx, smaxy), (smaxx, sminy)]
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+class EditLayer(cocos.layer.Layer):
|
|
112
|
+ is_event_handler = True
|
|
113
|
+
|
|
114
|
+ def __init__(
|
|
115
|
+ self,
|
|
116
|
+ layer_manager: LayerManager,
|
|
117
|
+ worldview,
|
|
118
|
+ bindings=None,
|
|
119
|
+ fastness=None,
|
|
120
|
+ autoscroll_border=10,
|
|
121
|
+ autoscroll_fastness=None,
|
|
122
|
+ wheel_multiplier=None,
|
|
123
|
+ zoom_min=None,
|
|
124
|
+ zoom_max=None,
|
|
125
|
+ zoom_fastness=None,
|
|
126
|
+ mod_modify_selection=None,
|
|
127
|
+ mod_restricted_mov=None,
|
|
128
|
+ ):
|
|
129
|
+ super(EditLayer, self).__init__()
|
|
130
|
+
|
|
131
|
+ self.layer_manager = layer_manager
|
|
132
|
+ self.bindings = bindings
|
|
133
|
+ buttons = {}
|
|
134
|
+ modifiers = {}
|
|
135
|
+ for k in bindings:
|
|
136
|
+ buttons[bindings[k]] = 0
|
|
137
|
+ modifiers[bindings[k]] = 0
|
|
138
|
+ self.buttons = buttons
|
|
139
|
+ self.modifiers = modifiers
|
|
140
|
+
|
|
141
|
+ self.fastness = fastness
|
|
142
|
+ self.autoscroll_border = autoscroll_border
|
|
143
|
+ self.autoscroll_fastness = autoscroll_fastness
|
|
144
|
+ self.wheel_multiplier = wheel_multiplier
|
|
145
|
+ self.zoom_min = zoom_min
|
|
146
|
+ self.zoom_max = zoom_max
|
|
147
|
+ self.zoom_fastness = zoom_fastness
|
|
148
|
+ self.mod_modify_selection = mod_modify_selection
|
|
149
|
+ self.mod_restricted_mov = mod_restricted_mov
|
|
150
|
+
|
|
151
|
+ self.weak_scroller = weakref.ref(self.layer_manager.scrolling_manager)
|
|
152
|
+ self.weak_worldview = weakref.ref(worldview)
|
|
153
|
+ self.wwidth = worldview.width
|
|
154
|
+ self.wheight = worldview.height
|
|
155
|
+
|
|
156
|
+ self.autoscrolling = False
|
|
157
|
+ self.drag_selecting = False
|
|
158
|
+ self.drag_moving = False
|
|
159
|
+ self.restricted_mov = False
|
|
160
|
+ self.wheel = 0
|
|
161
|
+ self.dragging = False
|
|
162
|
+ self.keyscrolling = False
|
|
163
|
+ self.keyscrolling_descriptor = (0, 0)
|
|
164
|
+ self.wdrag_start_point = (0, 0)
|
|
165
|
+ self.elastic_box = None # type: MinMaxRect
|
|
166
|
+ self.elastic_box_wminmax = 0, 0, 0, 0
|
|
167
|
+ self.mouse_mark = None # type: ProbeQuad
|
|
168
|
+ self.selection = {}
|
|
169
|
+ self.screen_mouse = (0, 0)
|
|
170
|
+ self.world_mouse = (0, 0)
|
|
171
|
+ self.sleft = None
|
|
172
|
+ self.sright = None
|
|
173
|
+ self.sbottom = None
|
|
174
|
+ self.s_top = None
|
|
175
|
+
|
|
176
|
+ # opers that change cshape must ensure it goes to False,
|
|
177
|
+ # selection opers must ensure it goes to True
|
|
178
|
+ self.selection_in_collman = True
|
|
179
|
+ # TODO: Hardcoded here, should be obtained from level properties or calc
|
|
180
|
+ # from available actors or current actors in worldview
|
|
181
|
+ gsize = 32 * 1.25
|
|
182
|
+ self.collman = collision_model.CollisionManagerGrid(
|
|
183
|
+ -gsize,
|
|
184
|
+ self.wwidth + gsize,
|
|
185
|
+ -gsize,
|
|
186
|
+ self.wheight + gsize,
|
|
187
|
+ gsize,
|
|
188
|
+ gsize,
|
|
189
|
+ )
|
|
190
|
+ for actor in worldview.actors:
|
|
191
|
+ self.collman.add(actor)
|
|
192
|
+
|
|
193
|
+ self.schedule(self.update)
|
|
194
|
+
|
|
195
|
+ def on_enter(self):
|
|
196
|
+ super(EditLayer, self).on_enter()
|
|
197
|
+ scene = self.get_ancestor(cocos.scene.Scene)
|
|
198
|
+ if self.elastic_box is None:
|
|
199
|
+ self.elastic_box = MinMaxRect(self.layer_manager)
|
|
200
|
+ scene.add(self.elastic_box, z=10)
|
|
201
|
+ if self.mouse_mark is None:
|
|
202
|
+ self.mouse_mark = ProbeQuad(4, (0, 0, 0, 255))
|
|
203
|
+ scene.add(self.mouse_mark, z=11)
|
|
204
|
+
|
|
205
|
+ def update(self, dt):
|
|
206
|
+ mx = self.buttons['right'] - self.buttons['left']
|
|
207
|
+ my = self.buttons['up'] - self.buttons['down']
|
|
208
|
+ dz = self.buttons['zoomin'] - self.buttons['zoomout']
|
|
209
|
+
|
|
210
|
+ # scroll
|
|
211
|
+ if self.autoscrolling:
|
|
212
|
+ self.update_autoscroll(dt)
|
|
213
|
+ else:
|
|
214
|
+ # care for keyscrolling
|
|
215
|
+ new_keyscrolling = ((len(self.selection) == 0) and
|
|
216
|
+ (mx != 0 or my != 0))
|
|
217
|
+ new_keyscrolling_descriptor = (mx, my)
|
|
218
|
+ if ((new_keyscrolling != self.keyscrolling) or
|
|
219
|
+ (new_keyscrolling_descriptor != self.keyscrolling_descriptor)):
|
|
220
|
+ self.keyscrolling = new_keyscrolling
|
|
221
|
+ self.keyscrolling_descriptor = new_keyscrolling_descriptor
|
|
222
|
+ fastness = 1.0
|
|
223
|
+ if mx != 0 and my != 0:
|
|
224
|
+ fastness *= 0.707106 # 1/sqrt(2)
|
|
225
|
+ self.autoscrolling_sdelta = (0.5 * fastness * mx, 0.5 * fastness * my)
|
|
226
|
+ if self.keyscrolling:
|
|
227
|
+ self.update_autoscroll(dt)
|
|
228
|
+
|
|
229
|
+ # selection move
|
|
230
|
+ if self.drag_moving:
|
|
231
|
+ # update positions
|
|
232
|
+ wx, wy = self.world_mouse
|
|
233
|
+ dx = wx - self.wdrag_start_point[0]
|
|
234
|
+ dy = wy - self.wdrag_start_point[1]
|
|
235
|
+ if self.restricted_mov:
|
|
236
|
+ if abs(dy) > abs(dx):
|
|
237
|
+ dx = 0
|
|
238
|
+ else:
|
|
239
|
+ dy = 0
|
|
240
|
+ dpos = euclid.Vector2(dx, dy)
|
|
241
|
+ for actor in self.selection:
|
|
242
|
+ old_pos = self.selection[actor].center
|
|
243
|
+ new_pos = old_pos + dpos
|
|
244
|
+ # TODO: clamp new_pos so actor into world boundaries ?
|
|
245
|
+ actor.update_position(new_pos)
|
|
246
|
+
|
|
247
|
+ scroller = self.weak_scroller()
|
|
248
|
+
|
|
249
|
+ # zoom
|
|
250
|
+ zoom_change = (dz != 0 or self.wheel != 0)
|
|
251
|
+ if zoom_change:
|
|
252
|
+ if self.mouse_into_world():
|
|
253
|
+ wzoom_center = self.world_mouse
|
|
254
|
+ szoom_center = self.screen_mouse
|
|
255
|
+ else:
|
|
256
|
+ # decay to scroller unadorned
|
|
257
|
+ wzoom_center = None
|
|
258
|
+ if self.wheel != 0:
|
|
259
|
+ dt_dz = 0.01666666 * self.wheel
|
|
260
|
+ self.wheel = 0
|
|
261
|
+ else:
|
|
262
|
+ dt_dz = dt * dz
|
|
263
|
+ zoom = scroller.scale + dt_dz * self.zoom_fastness
|
|
264
|
+ if zoom < self.zoom_min:
|
|
265
|
+ zoom = self.zoom_min
|
|
266
|
+ elif zoom > self.zoom_max:
|
|
267
|
+ zoom = self.zoom_max
|
|
268
|
+ scroller.scale = zoom
|
|
269
|
+ if wzoom_center is not None:
|
|
270
|
+ # postprocess toward 'world point under mouse the same before
|
|
271
|
+ # and after zoom' ; other restrictions may prevent fully comply
|
|
272
|
+ wx1, wy1 = self.layer_manager.scrolling_manager.screen_to_world(*szoom_center)
|
|
273
|
+ fx = scroller.restricted_fx + (wzoom_center[0] - wx1)
|
|
274
|
+ fy = scroller.restricted_fy + (wzoom_center[1] - wy1)
|
|
275
|
+ scroller.set_focus(fx, fy)
|
|
276
|
+
|
|
277
|
+ def update_mouse_position(self, sx, sy):
|
|
278
|
+ self.screen_mouse = sx, sy
|
|
279
|
+ self.world_mouse = self.layer_manager.scrolling_manager.screen_to_world(sx, sy)
|
|
280
|
+ # handle autoscroll
|
|
281
|
+ border = self.autoscroll_border
|
|
282
|
+ if border is not None:
|
|
283
|
+ # sleft and companions includes the border
|
|
284
|
+ scroller = self.weak_scroller()
|
|
285
|
+ self.update_view_bounds()
|
|
286
|
+ sdx = 0.0
|
|
287
|
+ if sx < self.sleft:
|
|
288
|
+ sdx = sx - self.sleft
|
|
289
|
+ elif sx > self.sright:
|
|
290
|
+ sdx = sx - self.sright
|
|
291
|
+ sdy = 0.0
|
|
292
|
+ if sy < self.sbottom:
|
|
293
|
+ sdy = sy - self.sbottom
|
|
294
|
+ elif sy > self.s_top:
|
|
295
|
+ sdy = sy - self.s_top
|
|
296
|
+ self.autoscrolling = sdx != 0.0 or sdy != 0.0
|
|
297
|
+ if self.autoscrolling:
|
|
298
|
+ self.autoscrolling_sdelta = (sdx / border, sdy / border)
|
|
299
|
+ self.mouse_mark.position = self.layer_manager.scrolling_manager.world_to_screen(*self.world_mouse)
|
|
300
|
+
|
|
301
|
+ def update_autoscroll(self, dt):
|
|
302
|
+ fraction_sdx, fraction_sdy = self.autoscrolling_sdelta
|
|
303
|
+ scroller = self.weak_scroller()
|
|
304
|
+ worldview = self.weak_worldview()
|
|
305
|
+ f = self.autoscroll_fastness
|
|
306
|
+ wdx = (fraction_sdx * f * dt) / scroller.scale / worldview.scale
|
|
307
|
+ wdy = (fraction_sdy * f * dt) / scroller.scale / worldview.scale
|
|
308
|
+ # ask scroller to try scroll (wdx, wdy)
|
|
309
|
+ fx = scroller.restricted_fx + wdx
|
|
310
|
+ fy = scroller.restricted_fy + wdy
|
|
311
|
+ scroller.set_focus(fx, fy)
|
|
312
|
+ self.world_mouse = self.layer_manager.scrolling_manager.screen_to_world(*self.screen_mouse)
|
|
313
|
+ self.adjust_elastic_box()
|
|
314
|
+ # self.update_view_bounds()
|
|
315
|
+
|
|
316
|
+ def update_view_bounds(self):
|
|
317
|
+ scroller = self.weak_scroller()
|
|
318
|
+ scx, scy = self.layer_manager.scrolling_manager.world_to_screen(
|
|
319
|
+ scroller.restricted_fx,
|
|
320
|
+ scroller.restricted_fy,
|
|
321
|
+ )
|
|
322
|
+ hw = scroller.view_w / 2.0
|
|
323
|
+ hh = scroller.view_h / 2.0
|
|
324
|
+ border = self.autoscroll_border
|
|
325
|
+ self.sleft = scx - hw + border
|
|
326
|
+ self.sright = scx + hw - border
|
|
327
|
+ self.sbottom = scy - hh + border
|
|
328
|
+ self.s_top = scy + hh - border
|
|
329
|
+
|
|
330
|
+ def mouse_into_world(self):
|
|
331
|
+ worldview = self.weak_worldview()
|
|
332
|
+ # TODO: allow lower limits != 0 ?
|
|
333
|
+ return ((0 <= self.world_mouse[0] <= worldview.width) and
|
|
334
|
+ (0 <= self.world_mouse[1] <= worldview.height))
|
|
335
|
+
|
|
336
|
+ def on_key_press(self, k, m):
|
|
337
|
+ binds = self.bindings
|
|
338
|
+ if k in binds:
|
|
339
|
+ self.buttons[binds[k]] = 1
|
|
340
|
+ self.modifiers[binds[k]] = 1
|
|
341
|
+ return True
|
|
342
|
+ return False
|
|
343
|
+
|
|
344
|
+ def on_key_release(self, k, m):
|
|
345
|
+ binds = self.bindings
|
|
346
|
+ if k in binds:
|
|
347
|
+ self.buttons[binds[k]] = 0
|
|
348
|
+ self.modifiers[binds[k]] = 0
|
|
349
|
+ return True
|
|
350
|
+ return False
|
|
351
|
+
|
|
352
|
+ def on_mouse_motion(self, sx, sy, dx, dy):
|
|
353
|
+ self.update_mouse_position(sx, sy)
|
|
354
|
+
|
|
355
|
+ def on_mouse_leave(self, sx, sy):
|
|
356
|
+ self.autoscrolling = False
|
|
357
|
+
|
|
358
|
+ def on_mouse_press(self, x, y, buttons, modifiers):
|
|
359
|
+ pass
|
|
360
|
+
|
|
361
|
+ def on_mouse_release(self, sx, sy, button, modifiers):
|
|
362
|
+ # should we handle here mod_restricted_mov ?
|
|
363
|
+ wx, wy = self.layer_manager.scrolling_manager.screen_to_world(sx, sy)
|
|
364
|
+ modify_selection = modifiers & self.mod_modify_selection
|
|
365
|
+ if self.dragging:
|
|
366
|
+ # ignore all buttons except left button
|
|
367
|
+ if button != mouse.LEFT:
|
|
368
|
+ return
|
|
369
|
+ if self.drag_selecting:
|
|
370
|
+ self.end_drag_selection(wx, wy, modify_selection)
|
|
371
|
+ elif self.drag_moving:
|
|
372
|
+ self.end_drag_move(wx, wy)
|
|
373
|
+ self.dragging = False
|
|
374
|
+ else:
|
|
375
|
+ if button == mouse.LEFT:
|
|
376
|
+ self.end_click_selection(wx, wy, modify_selection)
|
|
377
|
+
|
|
378
|
+ def end_click_selection(self, wx, wy, modify_selection):
|
|
379
|
+ under_mouse_unique = self.single_actor_from_mouse()
|
|
380
|
+ if modify_selection:
|
|
381
|
+ # toggle selected status for unique
|
|
382
|
+ if under_mouse_unique in self.selection:
|
|
383
|
+ self.selection_remove(under_mouse_unique)
|
|
384
|
+ elif under_mouse_unique is not None:
|
|
385
|
+ self.selection_add(under_mouse_unique)
|
|
386
|
+ else:
|
|
387
|
+ # new_selected becomes the current selected
|
|
388
|
+ self.selection.clear()
|
|
389
|
+ if under_mouse_unique is not None:
|
|
390
|
+ self.selection_add(under_mouse_unique)
|
|
391
|
+
|
|
392
|
+ def selection_add(self, actor):
|
|
393
|
+ self.selection[actor] = actor.cshape.copy()
|
|
394
|
+
|
|
395
|
+ def selection_remove(self, actor):
|
|
396
|
+ del self.selection[actor]
|
|
397
|
+
|
|
398
|
+ def end_drag_selection(self, wx, wy, modify_selection):
|
|
399
|
+ new_selection = self.collman.objs_into_box(*self.elastic_box_wminmax)
|
|
400
|
+ if not modify_selection:
|
|
401
|
+ # new_selected becomes the current selected
|
|
402
|
+ self.selection.clear()
|
|
403
|
+ for actor in new_selection:
|
|
404
|
+ self.selection_add(actor)
|
|
405
|
+
|
|
406
|
+ self.elastic_box.visible = False
|
|
407
|
+ self.drag_selecting = False
|
|
408
|
+
|
|
409
|
+ def on_mouse_drag(self, sx, sy, dx, dy, buttons, modifiers):
|
|
410
|
+ # TODO: inhibir esta llamada si estamos fuera de la client area / viewport
|
|
411
|
+ self.update_mouse_position(sx, sy)
|
|
412
|
+ if not buttons & mouse.LEFT:
|
|
413
|
+ # ignore except for left-btn-drag
|
|
414
|
+ return
|
|
415
|
+
|
|
416
|
+ if not self.dragging:
|
|
417
|
+ print("begin drag")
|
|
418
|
+ self.begin_drag()
|
|
419
|
+ return
|
|
420
|
+
|
|
421
|
+ if self.drag_selecting:
|
|
422
|
+ # update elastic box
|
|
423
|
+ self.adjust_elastic_box()
|
|
424
|
+ elif self.drag_moving:
|
|
425
|
+ self.restricted_mov = (modifiers & self.mod_restricted_mov)
|
|
426
|
+
|
|
427
|
+ def adjust_elastic_box(self):
|
|
428
|
+ # when elastic_box visible this method needs to be called any time
|
|
429
|
+ # world_mouse changes or screen_to_world results changes (scroll, etc)
|
|
430
|
+ wx0, wy0 = self.wdrag_start_point
|
|
431
|
+ wx1, wy1 = self.world_mouse
|
|
432
|
+ wminx = min(wx0, wx1)
|
|
433
|
+ wmaxx = max(wx0, wx1)
|
|
434
|
+ wminy = min(wy0, wy1)
|
|
435
|
+ wmaxy = max(wy0, wy1)
|
|
436
|
+ self.elastic_box_wminmax = wminx, wmaxx, wminy, wmaxy
|
|
437
|
+ self.elastic_box.adjust_from_w_minmax(*self.elastic_box_wminmax)
|
|
438
|
+
|
|
439
|
+ def begin_drag(self):
|
|
440
|
+ self.dragging = True
|
|
441
|
+ self.wdrag_start_point = self.world_mouse
|
|
442
|
+ under_mouse_unique = self.single_actor_from_mouse()
|
|
443
|
+ if under_mouse_unique is None:
|
|
444
|
+ # begin drag selection
|
|
445
|
+ self.drag_selecting = True
|
|
446
|
+ self.adjust_elastic_box()
|
|
447
|
+ self.elastic_box.visible = True
|
|
448
|
+ print("begin drag selection: drag_selecting, drag_moving",
|
|
449
|
+ self.drag_selecting, self.drag_moving)
|
|
450
|
+
|
|
451
|
+ else:
|
|
452
|
+ # want drag move
|
|
453
|
+ if under_mouse_unique in self.selection:
|
|
454
|
+ # want to move current selection
|
|
455
|
+ pass
|
|
456
|
+ else:
|
|
457
|
+ # change selection before moving
|
|
458
|
+ self.selection.clear()
|
|
459
|
+ self.selection_add(under_mouse_unique)
|
|
460
|
+ self.begin_drag_move()
|
|
461
|
+
|
|
462
|
+ def begin_drag_move(self):
|
|
463
|
+ # begin drag move
|
|
464
|
+ self.drag_moving = True
|
|
465
|
+
|
|
466
|
+ # how-to update collman: remove/add vs clear/add all
|
|
467
|
+ # when total number of actors is low anyone will be fine,
|
|
468
|
+ # with high numbers, most probably we move only a small fraction
|
|
469
|
+ # For simplicity I choose remove/add, albeit a hybrid aproach
|
|
470
|
+ # can be implemented later
|
|
471
|
+ self.set_selection_in_collman(False)
|
|
472
|
+# print "begin drag: drag_selecting, drag_moving", self.drag_selecting, self.drag_moving
|
|
473
|
+
|
|
474
|
+ def end_drag_move(self, wx, wy):
|
|
475
|
+ self.set_selection_in_collman(True)
|
|
476
|
+ for actor in self.selection:
|
|
477
|
+ self.selection[actor] = actor.cshape.copy()
|
|
478
|
+
|
|
479
|
+ self.drag_moving = False
|
|
480
|
+
|
|
481
|
+ def single_actor_from_mouse(self):
|
|
482
|
+ under_mouse = self.collman.objs_touching_point(*self.world_mouse)
|
|
483
|
+ if len(under_mouse) == 0:
|
|
484
|
+ return None
|
|
485
|
+ # return the one with the center most near to mouse, if tie then
|
|
486
|
+ # an arbitrary in the tie
|
|
487
|
+ nearest = None
|
|
488
|
+ near_d = None
|
|
489
|
+ p = euclid.Vector2(*self.world_mouse)
|
|
490
|
+ for actor in under_mouse:
|
|
491
|
+ d = (actor.cshape.center - p).magnitude_squared()
|
|
492
|
+ if nearest is None or (d < near_d):
|
|
493
|
+ nearest = actor
|
|
494
|
+ near_d = d
|
|
495
|
+ return nearest
|
|
496
|
+
|
|
497
|
+ def set_selection_in_collman(self, bool_value):
|
|
498
|
+ if self.selection_in_collman == bool_value:
|
|
499
|
+ return
|
|
500
|
+ self.selection_in_collman = bool_value
|
|
501
|
+ if bool_value:
|
|
502
|
+ for actor in self.selection:
|
|
503
|
+ self.collman.add(actor)
|
|
504
|
+ else:
|
|
505
|
+ for actor in self.selection:
|
|
506
|
+ self.collman.remove_tricky(actor)
|
|
507
|
+
|
|
508
|
+ def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
|
|
509
|
+ # TODO: check if mouse over scroller viewport?
|
|
510
|
+ self.wheel += scroll_y * self.wheel_multiplier
|
|
511
|
+
|
|
512
|
+
|
74
|
513
|
class MainLayer(ScrollableLayer):
|
75
|
514
|
is_event_handler = True
|
76
|
515
|
|
77
|
|
- def __init__(self, scroll_step: int=100):
|
|
516
|
+ def __init__(
|
|
517
|
+ self,
|
|
518
|
+ layer_manager: LayerManager,
|
|
519
|
+ width: int,
|
|
520
|
+ height: int,
|
|
521
|
+ scroll_step: int=100,
|
|
522
|
+ ) -> None:
|
78
|
523
|
super().__init__()
|
|
524
|
+ self.layer_manager = layer_manager
|
79
|
525
|
self.scroll_step = scroll_step
|
80
|
526
|
self.grid_manager = GridManager(self, 32, border=2)
|
81
|
527
|
|
|
528
|
+ self.actors = [] # TODO type list of ? Sprite ?
|
|
529
|
+ self.width = width
|
|
530
|
+ self.height = height
|
|
531
|
+ self.px_width = width
|
|
532
|
+ self.px_height = height
|
|
533
|
+
|
82
|
534
|
# Set scene center on center of screen
|
83
|
535
|
window_size = director.get_window_size()
|
84
|
536
|
self.position = window_size[0] // 2, window_size[1] // 2
|
|
@@ -118,7 +570,12 @@ class Gui(object):
|
118
|
570
|
self._read_queue_interval = read_queue_interval
|
119
|
571
|
self.terminal = terminal
|
120
|
572
|
self.cycle_duration = self.config.core.cycle_duration
|
121
|
|
- cocos.director.director.init()
|
|
573
|
+ cocos.director.director.init(
|
|
574
|
+ width=640,
|
|
575
|
+ height=480,
|
|
576
|
+ vsync=True,
|
|
577
|
+ resizable=True,
|
|
578
|
+ )
|
122
|
579
|
|
123
|
580
|
def run(self):
|
124
|
581
|
self.before_run()
|