Mercurial > fife-parpg
comparison tools/editor/plugins/ObjectEdit.py @ 378:64738befdf3b
bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author | vtchill@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Mon, 11 Jan 2010 23:34:52 +0000 |
parents | |
children | fa1373b9fa16 |
comparison
equal
deleted
inserted
replaced
377:fe6fb0e0ed23 | 378:64738befdf3b |
---|---|
1 # coding: utf-8 | |
2 # ################################################### | |
3 # Copyright (C) 2008 The Zero-Projekt team | |
4 # http://zero-projekt.net | |
5 # info@zero-projekt.net | |
6 # This file is part of Zero "Was vom Morgen blieb" | |
7 # | |
8 # The Zero-Projekt codebase is free software; you can redistribute it and/or modify | |
9 # it under the terms of the GNU General Public License as published by | |
10 # the Free Software Foundation; either version 2 of the License, or | |
11 # (at your option) any later version. | |
12 # | |
13 # This program is distributed in the hope that it will be useful, | |
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 # GNU General Public License for more details. | |
17 # | |
18 # You should have received a copy of the GNU General Public License | |
19 # along with this program; if not, write to the | |
20 # Free Software Foundation, Inc., | |
21 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
22 # ################################################### | |
23 | |
24 """ a tool for FIFEdit to edit object and instance attributes """ | |
25 | |
26 from fife import fife | |
27 from fife.extensions import pychan | |
28 import fife.extensions.pychan.widgets as widgets | |
29 from fife.extensions.pychan.tools import callbackWithArguments as cbwa | |
30 | |
31 from fife.extensions.fife_timer import Timer | |
32 | |
33 import scripts | |
34 import scripts.plugin as plugin | |
35 from scripts.events import * | |
36 from scripts.gui.action import Action | |
37 | |
38 | |
39 import os | |
40 try: | |
41 import xml.etree.cElementTree as ET | |
42 except: | |
43 import xml.etree.ElementTree as ET | |
44 | |
45 import math | |
46 | |
47 WHITE = { | |
48 "r" : 205, | |
49 "g" : 205, | |
50 "b" : 205 | |
51 } | |
52 OUTLINE_SIZE = 1 | |
53 | |
54 class ObjectEdit(plugin.Plugin): | |
55 """ The B{ObjectEdit} module is a plugin for FIFedit and allows to edit | |
56 attributes of an selected instance - like offset, instance id or rotation | |
57 (namespaces and object id editing is excluded) | |
58 | |
59 current features: | |
60 - click instance and get all known data | |
61 - edit offsets, rotation, instance id | |
62 - save offsets to object file | |
63 - outline highlighting of the selected object | |
64 - animation viewer | |
65 | |
66 FIXME: | |
67 - add static and blocking flag to save routine | |
68 - fix animation rotation (FIFE has no method yet to export all | |
69 angles of an animation to python) | |
70 """ | |
71 def __init__(self): | |
72 self.active = False | |
73 self._camera = None | |
74 self._layer = None | |
75 self._anim_timer = None | |
76 | |
77 self._enabled = False | |
78 | |
79 self.imagepool = None | |
80 self._animationpool = None | |
81 | |
82 self.guidata = {} | |
83 self.objectdata = {} | |
84 | |
85 def _reset(self): | |
86 """ | |
87 resets all dynamic vars, but leaves out static ones (e.g. camera, layer) | |
88 | |
89 """ | |
90 if self._anim_timer: | |
91 self._anim_timer.stop() | |
92 # reset the ToggleButton | |
93 if self._gui_anim_playback._isToggled(): | |
94 self._gui_anim_playback._setToggled(0) | |
95 self._anim_timer = None | |
96 | |
97 self._object = None | |
98 self._instances = None | |
99 self._image = None | |
100 self._image_default_x_offset = None | |
101 self._image_default_y_offset = None | |
102 self._animation = False | |
103 self._anim_data = {} | |
104 self._rotation = None | |
105 self._avail_rotations = [] | |
106 self._namespace = None | |
107 self._blocking = 0 | |
108 self._static = 0 | |
109 self._object_id = None | |
110 self._instance_id = None | |
111 self._fixed_rotation = None | |
112 | |
113 if self._camera is not None: | |
114 self.renderer.removeAllOutlines() | |
115 | |
116 def enable(self): | |
117 """ plugin method """ | |
118 if self._enabled is True: | |
119 return | |
120 | |
121 self._editor = scripts.editor.getEditor() | |
122 self.engine = self._editor.getEngine() | |
123 | |
124 self.imagepool = self.engine.getImagePool() | |
125 self._animationpool = self.engine.getAnimationPool() | |
126 | |
127 self._showAction = Action(unicode(self.getName(),"utf-8"), checkable=True) | |
128 scripts.gui.action.activated.connect(self.toggle_gui, sender=self._showAction) | |
129 | |
130 self._editor._tools_menu.addAction(self._showAction) | |
131 | |
132 events.onInstancesSelected.connect(self.input) | |
133 | |
134 self._reset() | |
135 self.create_gui() | |
136 | |
137 def disable(self): | |
138 """ plugin method """ | |
139 if self._enabled is False: | |
140 return | |
141 | |
142 self._reset() | |
143 self.container.hide() | |
144 self.removeAllChildren() | |
145 | |
146 events.onInstancesSelected.disconnect(self.input) | |
147 | |
148 self._editor._tools_menu.removeAction(self._showAction) | |
149 | |
150 def isEnabled(self): | |
151 """ plugin method """ | |
152 return self._enabled; | |
153 | |
154 def getName(self): | |
155 """ plugin method """ | |
156 return "Object editor v2" | |
157 | |
158 def create_gui(self): | |
159 """ | |
160 - creates the gui skeleton by loading the xml file | |
161 - finds some important childs and saves their widget in the object | |
162 | |
163 FIXME: | |
164 - move all dynamic widgets to dict | |
165 """ | |
166 self.container = pychan.loadXML('gui/objectedit.xml') | |
167 self.container.mapEvents({ | |
168 'x_offset_up' : cbwa(self.change_offset_x, 1), | |
169 'x_offset_dn' : cbwa(self.change_offset_x, -1), | |
170 | |
171 'y_offset_up' : cbwa(self.change_offset_y, 1), | |
172 'y_offset_dn' : cbwa(self.change_offset_y, -1), | |
173 | |
174 'use_data' : self.use_user_data, | |
175 'change_data' : self.save_user_data, | |
176 | |
177 'anim_left' : self.previous_anim_frame, | |
178 'anim_right' : self.next_anim_frame, | |
179 'anim_start_pos' : self.anim_start_frame, | |
180 'anim_end_pos' : self.anim_end_frame, | |
181 }) | |
182 | |
183 self._gui_anim_panel_wrapper = self.container.findChild(name="animation_panel_wrapper") | |
184 self._gui_anim_panel = self._gui_anim_panel_wrapper.findChild(name="animation_panel") | |
185 | |
186 self._gui_rotation_dropdown = self.container.findChild(name="select_rotations") | |
187 self._gui_rotation_dropdown.capture(self.gui_rotate_instance,"mouseWheelMovedUp") | |
188 self._gui_rotation_dropdown.capture(self.gui_rotate_instance,"mouseWheelMovedDown") | |
189 self._gui_rotation_dropdown.capture(self.gui_rotate_instance,"action") | |
190 | |
191 self._gui_anim_actions_dropdown = self._gui_anim_panel_wrapper.findChild(name="select_actions") | |
192 self._gui_anim_actions_dropdown.capture(self.eval_gui_anim_action,"mouseWheelMovedUp") | |
193 self._gui_anim_actions_dropdown.capture(self.eval_gui_anim_action,"mouseWheelMovedDown") | |
194 self._gui_anim_actions_dropdown.capture(self.eval_gui_anim_action,"action") | |
195 | |
196 self._gui_anim_playback = self._gui_anim_panel_wrapper.findChild(name="anim_playback") | |
197 self._gui_anim_playback.capture(self.anim_playback, "mousePressed") | |
198 self._gui_anim_loop = self._gui_anim_panel_wrapper.findChild(name="anim_loop") | |
199 | |
200 self._gui_current_frame = self._gui_anim_panel_wrapper.findChild(name="anim_current_frame") | |
201 self._gui_current_frame.capture(self.previous_anim_frame,"mouseWheelMovedUp") | |
202 self._gui_current_frame.capture(self.next_anim_frame,"mouseWheelMovedDown") | |
203 | |
204 self._gui_xoffset_textfield = self.container.findChild(name="x_offset") | |
205 self._gui_yoffset_textfield = self.container.findChild(name="y_offset") | |
206 | |
207 self._gui_instance_id_textfield = self.container.findChild(name="instance_id") | |
208 | |
209 def anim_playback(self, widget): | |
210 """ start / stop playback of an animation due to status of a gui ToggleButton | |
211 Sets also two ivars of timer object (active & loop) | |
212 """ | |
213 if widget._isToggled(): | |
214 self._anim_timer.stop() | |
215 self._anim_timer.active = False | |
216 else: | |
217 frame_delay = self._anim_data['obj'].getFrameDuration(self._anim_data['current']) | |
218 self._anim_timer = Timer(delay=frame_delay,callback=self.next_anim_frame) | |
219 self._anim_timer.active = True | |
220 self._anim_timer.loop = self._gui_anim_loop._isMarked() | |
221 self._anim_timer.start() | |
222 | |
223 def previous_anim_frame(self): | |
224 """ show previous anim frame """ | |
225 if self._anim_data['current'] > 0: | |
226 self._anim_data['current'] -= 1 | |
227 self.update_gui() | |
228 | |
229 def next_anim_frame(self): | |
230 """ show next anim frame and reset animation frame to 0 if playback looping is active""" | |
231 if self._anim_timer.loop and (self._anim_data['current'] == self._anim_data['frames']): | |
232 self._anim_data['current'] = 0 | |
233 | |
234 if self._anim_data['current'] < self._anim_data['frames']: | |
235 self._anim_data['current'] += 1 | |
236 self.update_gui() | |
237 | |
238 def anim_start_frame(self): | |
239 """ set start frame of animation """ | |
240 self._anim_data['current'] = 0 | |
241 self.update_gui() | |
242 | |
243 def anim_end_frame(self): | |
244 """ set end frame of animation """ | |
245 self._anim_data['current'] = self._anim_data['frames'] | |
246 self.update_gui() | |
247 | |
248 def set_default_offset(self, axis): | |
249 """ set default image offset for given axis """ | |
250 if axis == 'x': | |
251 self.set_offset(x=self._image_default_x_offset) | |
252 elif axis == 'y': | |
253 self.set_offset(y=self._image_default_y_offset) | |
254 | |
255 def update_gui(self): | |
256 """ | |
257 updates the gui widgets with current instance data | |
258 | |
259 """ | |
260 # show the image we retrieved from an animated object | |
261 if self._animation: | |
262 if not self._gui_anim_panel_wrapper.findChild(name="animation_panel"): | |
263 self._gui_anim_panel_wrapper.addChild(self._gui_anim_panel) | |
264 | |
265 # get current selected image and update the icon widget | |
266 dur = 0 | |
267 for i in range(self._anim_data['frames']): | |
268 dur += self._anim_data['obj'].getFrameDuration(i) | |
269 | |
270 # set new duration for the playback timer | |
271 if self._anim_timer: | |
272 frame_delay = self._anim_data['obj'].getFrameDuration(self._anim_data['current']) | |
273 | |
274 if i == self._anim_data['current']: | |
275 # set new duration for the playback timer | |
276 if self._anim_timer and self._anim_timer.active: | |
277 self._anim_timer.setPeriod(self._anim_data['obj'].getFrameDuration(self._anim_data['current'])) | |
278 break | |
279 | |
280 image = self._anim_data['obj'].getFrameByTimestamp(dur) | |
281 self.container.findChild(name="animTest").image = image.getResourceFile() | |
282 self.container.findChild(name="animTest").size= (250,250) | |
283 self.container.findChild(name="animTest").min_size= (250,250) | |
284 | |
285 self.container.distributeInitialData({ | |
286 'anim_current_frame' : unicode(str(self._anim_data['current'])), | |
287 'anim_rotation' : unicode(str(self._anim_data['obj'].getDirection())), | |
288 }) | |
289 | |
290 else: | |
291 if self._gui_anim_panel_wrapper.findChild(name="animation_panel"): | |
292 self._gui_anim_panel_wrapper.removeChild(self._gui_anim_panel) | |
293 | |
294 if self._image is not None: | |
295 x_offset = unicode( self._image.getXShift() ) | |
296 y_offset = unicode( self._image.getYShift() ) | |
297 else: | |
298 x_offset = unicode( 0 ) | |
299 y_offset = unicode( 0 ) | |
300 | |
301 self.container.distributeInitialData({ | |
302 'select_rotations' : self._avail_rotations, | |
303 'instance_id' : unicode( self._instances[0].getId() ), | |
304 'object_id' : unicode( self._object_id ), | |
305 'x_offset' : x_offset, | |
306 'y_offset' : y_offset, | |
307 'instance_rotation' : unicode( self._instances[0].getRotation() ), | |
308 'object_namespace' : unicode( self._namespace ), | |
309 'object_blocking' : unicode( self._blocking ), | |
310 'object_static' : unicode( self._static ), | |
311 }) | |
312 | |
313 if not self._animation: | |
314 if self._fixed_rotation in self._avail_rotations: | |
315 index = self._avail_rotations.index( self._fixed_rotation ) | |
316 self._gui_rotation_dropdown._setSelected(index) | |
317 else: | |
318 print "Internal FIFE rotation: ", self._instances[0].getRotation() | |
319 print "Fixed rotation (cam rot) ", self._fixed_rotation + int(abs(self._camera.getRotation())) | |
320 print "Collected rots from object ", self._avail_rotations | |
321 | |
322 | |
323 self.container.adaptLayout(False) | |
324 | |
325 def toggle_gui(self): | |
326 """ | |
327 show / hide the gui | |
328 """ | |
329 if self.active is True: | |
330 self.active = False | |
331 if self.container.isVisible() or self.container.isDocked(): | |
332 self.container.setDocked(False) | |
333 self.container.hide() | |
334 self._showAction.setChecked(False) | |
335 else: | |
336 self.active = True | |
337 self._showAction.setChecked(True) | |
338 | |
339 def highlight_selected_instance(self): | |
340 """ highlights selected instance """ | |
341 self.renderer.removeAllOutlines() | |
342 self.renderer.addOutlined(self._instances[0], WHITE["r"], WHITE["g"], WHITE["b"], OUTLINE_SIZE) | |
343 | |
344 def change_offset_x(self, value=1): | |
345 """ | |
346 - callback for changing x offset | |
347 - changes x offset of current instance (image) | |
348 - updates gui | |
349 | |
350 @type value: int | |
351 @param value: the modifier for the x offset | |
352 """ | |
353 if self._animation: | |
354 print "Offset changes of animations are not supported yet" | |
355 return | |
356 | |
357 if self._image is not None: | |
358 self._image.setXShift(self._image.getXShift() + value) | |
359 self.update_gui() | |
360 | |
361 def change_offset_y(self, value=1): | |
362 """ | |
363 - callback for changing y offset | |
364 - changes y offset of current instance (image) | |
365 - updates gui | |
366 | |
367 @type value: int | |
368 @param value: the modifier for the y offset | |
369 """ | |
370 if self._animation: | |
371 print "Offset changes of animations are not supported yet" | |
372 return | |
373 | |
374 if self._image is not None: | |
375 self._image.setYShift(self._image.getYShift() + value) | |
376 self.update_gui() | |
377 | |
378 def use_user_data(self): | |
379 """ | |
380 - takes the users values and applies them directly to the current ._instance | |
381 - writes current data record | |
382 - writes previous data record | |
383 - updates gui | |
384 | |
385 FIXME: | |
386 - parse user data in case user think strings are considered to be integer offset values... | |
387 """ | |
388 if self._animation: | |
389 print "Editing animated instances is not supported yet" | |
390 return | |
391 | |
392 xoffset = self._gui_xoffset_textfield._getText() | |
393 yoffset = self._gui_yoffset_textfield._getText() | |
394 | |
395 instance_id = str(self._gui_instance_id_textfield._getText()) | |
396 | |
397 if instance_id == "": | |
398 instance_id = "None" | |
399 | |
400 if instance_id is not None and instance_id is not "None": | |
401 existing_instances = self._editor.getActiveMapView().getController()._layer.getInstances(instance_id) | |
402 if len(existing_instances) <= 0: | |
403 self._instances[0].setId(instance_id) | |
404 print "Set new instance id: ", instance_id | |
405 else: | |
406 print "Instance ID is already in use." | |
407 | |
408 # update rotation | |
409 angle = self.eval_gui_rotation() | |
410 self.set_rotation(angle) | |
411 | |
412 # update offsets | |
413 self.set_offset(int(xoffset), int(yoffset)) | |
414 | |
415 self.update_gui() | |
416 | |
417 def save_user_data(self): | |
418 """ saves the current object to its xml file | |
419 | |
420 NOTE: | |
421 - animations can't be saved for now | |
422 | |
423 FIXME: | |
424 - add missing object attributes to saving routine | |
425 """ | |
426 if self._object is None: | |
427 return | |
428 if self._animation: | |
429 return | |
430 | |
431 file = self._object.getResourceFile() | |
432 self.tree = ET.parse(file) | |
433 | |
434 img_lst = self.tree.findall("image") | |
435 | |
436 # apply changes to the XML structure due to current user settings in the gui | |
437 for img_tag in img_lst: | |
438 if img_tag.attrib["direction"] == self._avail_rotations[self._gui_rotation_dropdown._getSelected()]: | |
439 img_tag.attrib["x_offset"] = self._gui_xoffset_textfield._getText() | |
440 img_tag.attrib["y_offset"] = self._gui_yoffset_textfield._getText() | |
441 break | |
442 | |
443 xmlcontent = ET.tostring(self.tree.getroot()) | |
444 | |
445 # save xml data beneath the <?fife type="object"?> definition into the object file | |
446 tmp = open(file, 'w') | |
447 tmp.write('<?fife type="object"?>\n') | |
448 tmp.write(xmlcontent + "\n") | |
449 tmp.close() | |
450 | |
451 def gui_rotate_instance(self): | |
452 """ rotate an instance due to selected angle """ | |
453 angle = self.eval_gui_rotation() | |
454 self.set_rotation(angle) | |
455 | |
456 def eval_gui_rotation(self): | |
457 """ prepare rotation from gui and apply it to the current selected instance """ | |
458 index = self._gui_rotation_dropdown._getSelected() | |
459 angle = int( self._avail_rotations[index] ) | |
460 | |
461 if angle == 360: | |
462 angle = 0 | |
463 | |
464 return angle | |
465 | |
466 def eval_gui_anim_action(self): | |
467 """ check the selected action of an animation and update the gui accordingly """ | |
468 if not self._anim_data['actions']: return | |
469 | |
470 index = self._gui_anim_actions_dropdown._getSelected() | |
471 action = self._anim_data['actions'][index] | |
472 | |
473 self.update_anim_data(action) | |
474 self.update_gui() | |
475 | |
476 def set_rotation(self, angle): | |
477 """ set the rotation of the current instance """ | |
478 # print "...setting instance rotation from %s to %s" % (self._rotation, angle) | |
479 self._instances[0].setRotation(angle) | |
480 self.get_instance_data(None, None, angle) | |
481 self.update_gui() | |
482 # print "...new internal FIFE rotation ", int(self._instances[0].getRotation()) | |
483 | |
484 def set_offset(self, x=None, y=None): | |
485 """ set x/y offset of current selected instance """ | |
486 if x is not None: | |
487 self._image.setXShift(x) | |
488 if y is not None: | |
489 self._image.setYShift(y) | |
490 | |
491 def update_anim_data(self, action=None): | |
492 """ update animation data for the current selected instance from FIFE's data structure | |
493 | |
494 @type animation FIFE animation | |
495 @return animation current selected animation | |
496 """ | |
497 if action: | |
498 animation_id = action.get2dGfxVisual().getAnimationIndexByAngle(self._fixed_rotation) | |
499 animation = self._animationpool.getAnimation(animation_id) | |
500 | |
501 action_ids = [] | |
502 actions = [] | |
503 | |
504 try: | |
505 action_ids = self._object.getActionIds() | |
506 for id in action_ids: | |
507 actions.append(self._object.getAction(id)) | |
508 except: | |
509 pass | |
510 | |
511 self._anim_data = {} | |
512 self._anim_data['obj'] = animation | |
513 self._anim_data['id'] = animation_id | |
514 self._anim_data['frames'] = animation.getNumFrames() | |
515 self._anim_data['current'] = 0 | |
516 self._anim_data['actions'] = actions | |
517 self._anim_data['action_ids'] = action_ids | |
518 self._anim_data['default_action'] = self._object.getDefaultAction() | |
519 self._anim_data['action'] = action | |
520 | |
521 return animation | |
522 | |
523 def get_instance_data(self, timestamp=None, frame=None, angle=-1, instance=None): | |
524 """ | |
525 - grabs all available data from both object and instance | |
526 | |
527 FIXME: | |
528 1.) we need to fix the instance rotation / rotation issue | |
529 """ | |
530 visual = None | |
531 self._avail_rotations = [] | |
532 | |
533 if instance is None: | |
534 instance = self._instances[0] | |
535 | |
536 object = instance.getObject() | |
537 self._object = object | |
538 self._namespace = object.getNamespace() | |
539 self._object_id = object.getId() | |
540 | |
541 self._instance_id = instance.getId() | |
542 | |
543 if self._instance_id == '': | |
544 self._instance_id = 'None' | |
545 | |
546 if angle == -1: | |
547 angle = int(instance.getRotation()) | |
548 else: | |
549 angle = int(angle) | |
550 | |
551 self._rotation = angle | |
552 | |
553 if object.isBlocking(): | |
554 self._blocking = 1 | |
555 | |
556 if object.isStatic(): | |
557 self._static = 1 | |
558 | |
559 try: | |
560 visual = object.get2dGfxVisual() | |
561 except: | |
562 print 'Fetching visual of object - failed. :/' | |
563 raise | |
564 | |
565 # print "Camera tilt: ", self._camera.getTilt() | |
566 # print "Camera rotation: ", self._camera.getRotation() | |
567 # print "Instance rotation: ", instance.getRotation() | |
568 | |
569 # self._fixed_rotation = int(instance.getRotation() + abs( self._camera.getRotation() ) ) | |
570 self._fixed_rotation = instance.getRotation() | |
571 # self._fixed_rotation = visual.getClosestMatchingAngle(self._fixed_rotation) | |
572 | |
573 index = visual.getStaticImageIndexByAngle(self._fixed_rotation) | |
574 | |
575 if index is -1: | |
576 # object is an animation | |
577 self._animation = True | |
578 self._image = None | |
579 | |
580 # no static image available, try default action | |
581 action = object.getDefaultAction() | |
582 | |
583 if action: | |
584 animation = self.update_anim_data(action) | |
585 | |
586 # update gui | |
587 if animation: | |
588 self._gui_anim_actions_dropdown._setItems(self._anim_data['action_ids']) | |
589 self._gui_anim_actions_dropdown._setSelected(0) | |
590 | |
591 if timestamp is None and frame is not None: | |
592 self._image = animation.getFrame(frame) | |
593 elif timestamp is not None and frame is None: | |
594 self._image = animation.getFrameByTimestamp(timestamp) | |
595 else: | |
596 self._image = animation.getFrameByTimestamp(0) | |
597 elif index is not -1: | |
598 # object is a static image | |
599 self._animation = False | |
600 self._image = self.imagepool.getImage(index) | |
601 | |
602 if not self._animation: | |
603 rotations = visual.getStaticImageAngles() | |
604 for angle in rotations: | |
605 # angle += int(abs( self._camera.getRotation() )) | |
606 self._avail_rotations.append(angle) | |
607 | |
608 self._image_default_x_offset = self._image.getXShift() | |
609 self._image_default_y_offset = self._image.getYShift() | |
610 else: | |
611 # these doesn't work correctly | |
612 # rotations = [0,60,120,180,240,300] | |
613 | |
614 # testbench to get valid angles | |
615 # angle = 0 | |
616 # rotations = [] | |
617 # while angle != 360: | |
618 # angle += 10 | |
619 # rotations.append(angle) | |
620 | |
621 # estimated angles (for hex!) to make things work - use testbench to test | |
622 # various angles and note down the working ones (watch instance | |
623 # rotation and the animation rotations shown in the gui; valid | |
624 # angles are given once the rotations are in sync | |
625 self._avail_rotations = [9,69,139,169,249,319] | |
626 | |
627 def input(self, instances): | |
628 """ | |
629 if called _and_ the user wishes to edit offsets, | |
630 gets instance data and show gui | |
631 | |
632 """ | |
633 if instances != self._instances: | |
634 if self.active is True: | |
635 self._reset() | |
636 self._instances = instances | |
637 | |
638 if self._camera is None: | |
639 self._camera = self._editor.getActiveMapView().getCamera() | |
640 self.renderer = fife.InstanceRenderer.getInstance(self._camera) | |
641 | |
642 self._layer = self._editor.getActiveMapView().getController()._layer | |
643 | |
644 if self._instances != (): | |
645 self.highlight_selected_instance() | |
646 self.get_instance_data() | |
647 self.update_gui() | |
648 self.container.show() | |
649 else: | |
650 self._reset() | |
651 self.container.hide() | |
652 | |
653 self.container.adaptLayout(False) |