source: trunk/tools/editor/scripts/gui/mapeditor.py @ 3503

Revision 3503, 21.8 KB checked in by vtchill, 4 years ago (diff)

fixed a minor bug in the editor when trying to switch to INSERTING mode using the keyboard shortcut.

  • Property svn:eol-style set to native
  • Property svn:mergeinfo set to (toggle deleted branches)
    /branches/active/build_system_rework/tools/editor/scripts/gui/mapeditor.py3096-3157
    /branches/active/editor_rewrite/clients/editor/scripts/gui/mapeditor.py2781-2903
    /trunk/clients/editor/scripts/gui/mapeditor.py2779-2780
Line 
1# -*- coding: utf-8 -*-
2
3# ####################################################################
4#  Copyright (C) 2005-2009 by the FIFE team
5#  http://www.fifengine.de
6#  This file is part of FIFE.
7#
8#  FIFE is free software; you can redistribute it and/or
9#  modify it under the terms of the GNU Lesser General Public
10#  License as published by the Free Software Foundation; either
11#  version 2.1 of the License, or (at your option) any later version.
12#
13#  This library 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 GNU
16#  Lesser General Public License for more details.
17#
18#  You should have received a copy of the GNU Lesser General Public
19#  License along with this library; if not, write to the
20#  Free Software Foundation, Inc.,
21#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22# ####################################################################
23
24"""
25Visual Map Editor
26=================
27
28The map editor provides the user with an interface for editing
29maps visually.
30
31To edit a map through code, use MapController.
32
33"""
34
35import math
36import os
37import time
38from datetime import date
39
40from fife import fife
41from fife.extensions import pychan
42import fife.extensions.pychan.widgets as widgets
43from fife.extensions import fife_utils
44
45import scripts
46import scripts.events as events
47import action
48from toolbar import ToolBar
49from menubar import Menu, MenuBar
50from action import Action, ActionGroup
51from scripts.mapcontroller import MapController
52
53class MapEditor:
54   """ This class provides a basic user interface for map editing. It allows the user
55      to visually edit a map.
56   """
57   
58   # Editor states
59   SELECTING      = u"Selecting"
60   INSERTING      = u"Inserting"
61   REMOVING    = u"Removing"
62   MOVING         = u"Moving"
63   OBJECTPICKER   = u"Objectpicking"
64   
65   def __init__(self):
66      """ Set up all variables and call some initial functions """
67      self._ignoreToggles = False # A hack to avoid infinite recursion when toggling a button
68      self._controller = None
69      self._mode = MapEditor.SELECTING
70      self._debug = False # TODO: We should have a central system for activating debug messages
71     
72      # GUI
73      self._editor = scripts.editor.getEditor()
74      self._eventlistener = self._editor.getEventListener()
75      self._statusbar = self._editor.getStatusBar()
76      self._toolbar = self._editor.getToolBar()
77      self._toolbox = self._editor.getToolbox()
78     
79      # Currently selected object type
80      self._object = None
81     
82      # Variables used for moving instances
83      self._last_drag_pos = None
84      self._last_drag_pos_exact = None
85     
86      self._selected_instances = []
87     
88      self._undogroup = False
89     
90      # Variables for scrolling the map
91      self._dragx = 0
92      self._dragy = 0
93      self._scrollX = 0
94      self._scrollY = 0
95     
96      self._initToolboxButtons()
97      self._toolbox.show()
98     
99      events.postMapShown.connect(self._mapChanged)
100      events.preMapClosed.connect(self._mapClosed)
101      events.onObjectSelected.connect(self.setObject)
102     
103   def setObject(self, object):
104      """ Set the object type to be paint onto map """
105      self._object = object
106     
107   def setController(self, controller):
108      """ Set the controller to use. """
109      if self._controller is not None:
110         self._clear()
111         
112      self._controller = controller
113
114      if self._controller is not None:
115         self._init()
116     
117   def _init(self):
118      """ Sets up the mapeditor to work with the selected controller """
119      self._debug = self._controller.debug
120      self._setMode(MapEditor.SELECTING)
121     
122      self._initToolbarbuttons()
123     
124      events.keyPressed.connect(self.keyPressed)
125      events.keyReleased.connect(self.keyReleased)
126     
127      events.mousePressed.connect(self.mousePressed)
128      events.mouseDragged.connect(self.mouseDragged)
129      events.mouseReleased.connect(self.mouseReleased)
130      events.mouseMoved.connect(self.mouseMoved)
131      events.mouseEntered.connect(self.mouseEntered)
132      events.mouseExited.connect(self.mouseExited)
133      events.mouseWheelMovedUp.connect(self.mouseWheelMovedUp)
134      events.mouseWheelMovedDown.connect(self.mouseWheelMovedDown)
135      events.onPump.connect(self.pump)
136     
137   def _clear(self):
138      """ Remove any functionality set up by _init """
139      self._clearToolbarButtons()
140     
141      events.keyPressed.disconnect(self.keyPressed)
142      events.keyReleased.disconnect(self.keyReleased)
143     
144      events.mousePressed.disconnect(self.mousePressed)
145      events.mouseDragged.disconnect(self.mouseDragged)
146      events.mouseReleased.disconnect(self.mouseReleased)
147      events.mouseMoved.disconnect(self.mouseMoved)
148      events.mouseExited.disconnect(self.mouseExited)
149      events.mouseEntered.disconnect(self.mouseEntered)
150      events.mouseWheelMovedUp.disconnect(self.mouseWheelMovedUp)
151      events.mouseWheelMovedDown.disconnect(self.mouseWheelMovedDown)
152      events.onPump.disconnect(self.pump)
153     
154   def _mapChanged(self, sender, mapview):
155      """ Called when a new map is selected.
156         Sets the mapeditor to control the mapcontroller in the new map
157      """
158      self.setController(mapview.getController())
159     
160   def _mapClosed(self, sender, mapview):
161      """ Called when a map is closed. """
162      if mapview.getMap().getId() == self._controller.getMap().getId():
163         self.setController(None)
164     
165   def _updateCursor(self):
166      """ Updates the cursor to reflect the mode of the editor """
167      engine = self._editor.getEngine()
168      cursor = engine.getCursor()
169     
170      id = -1
171      if self._mode == MapEditor.SELECTING:
172         id = engine.getImagePool().addResourceFromFile("gui/icons/select_instance.png")
173         image = engine.getImagePool().getImage(id)
174         image.setXShift(-7)
175         image.setYShift(-7)
176         
177      elif self._mode == MapEditor.INSERTING:
178         id = engine.getImagePool().addResourceFromFile("gui/icons/add_instance.png")
179         image = engine.getImagePool().getImage(id)
180         image.setXShift(-2)
181         image.setYShift(-20)
182         
183      elif self._mode == MapEditor.REMOVING:
184         id = engine.getImagePool().addResourceFromFile("gui/icons/erase_instance.png")
185         image = engine.getImagePool().getImage(id)
186         image.setXShift(-2)
187         image.setYShift(-19)
188         
189      elif self._mode == MapEditor.MOVING:
190         id = engine.getImagePool().addResourceFromFile("gui/icons/move_instance.png")
191         image = engine.getImagePool().getImage(id)
192         image.setXShift(-11)
193         image.setYShift(-11)
194         
195      elif self._mode == MapEditor.OBJECTPICKER:
196         id = engine.getImagePool().addResourceFromFile("gui/icons/objectpicker.png")
197         image = engine.getImagePool().getImage(id)
198         image.setXShift(-0)
199         image.setYShift(-22)
200         
201      if id < 0:
202         self._resetCursor()
203      else:
204         cursor.set(fife.CURSOR_IMAGE, id)
205         
206   def _resetCursor(self):
207      """ Reset the cursor to the standard native one """
208      cursor = self._editor.getEngine().getCursor()
209      cursor.set(fife.CURSOR_NATIVE, fife.NC_ARROW)
210     
211   def _initToolboxButtons(self):
212      """ Sets up and connects buttons related to the toolbox """
213     
214      self._selectAction = Action(text=u"Select", icon="gui/icons/select_instance.png", checkable=True)
215      self._drawAction = Action(text=u"Draw", icon="gui/icons/add_instance.png", checkable=True)
216      self._removeAction = Action(text=u"Remove", icon="gui/icons/erase_instance.png", checkable=True)
217      self._moveAction = Action(text=u"Move", icon="gui/icons/move_instance.png", checkable=True)
218      self._objectpickerAction = Action(text=u"Pick object", icon="gui/icons/objectpicker.png", checkable=True)
219     
220      self._selectAction.helptext = u"Select cells on layer  (S)"
221      self._moveAction.helptext = u"Moves instances   (M)"
222      self._drawAction.helptext = u"Adds new instances based on currently selected object   (I)"
223      self._removeAction.helptext = u"Deletes instances   (R)"
224      self._objectpickerAction.helptext = u"Click an instance to set the current object to the one used by instance"
225     
226      action.toggled.connect(self._buttonToggled, sender=self._selectAction)
227      action.toggled.connect(self._buttonToggled, sender=self._moveAction)
228      action.toggled.connect(self._buttonToggled, sender=self._drawAction)
229      action.toggled.connect(self._buttonToggled, sender=self._removeAction)
230      action.toggled.connect(self._buttonToggled, sender=self._objectpickerAction)
231     
232      self._toolgroup = ActionGroup(exclusive=True, name=u"Tool group")
233      self._toolgroup.addAction(self._selectAction)
234      self._toolgroup.addAction(self._moveAction)
235      self._toolgroup.addAction(self._drawAction)
236      self._toolgroup.addAction(self._removeAction)
237      self._toolgroup.addAction(self._objectpickerAction)
238     
239      self._toolbox.addAction(self._toolgroup)
240      self._toolbox.adaptLayout()
241     
242      self._editor._edit_menu.addAction(self._toolgroup)
243     
244   def _initToolbarbuttons(self):
245      """ Sets up and connects buttons related to the toolbar """
246   
247      rotateLeftAction = Action(text=u"Rotate counterclockwise", icon="gui/icons/rotate_countercw.png")
248      rotateRightAction = Action(text=u"Rotate clockwise", icon="gui/icons/rotate_clockwise.png")
249      zoomInAction = Action(text=u"Zoom in", icon="gui/icons/zoom_in.png")
250      zoomOutAction = Action(text=u"Zoom out", icon="gui/icons/zoom_out.png")
251      zoomResetAction = Action(text=u"Reset zoom", icon="gui/icons/zoom_default.png")
252      screenshotAction = Action(text=u"Take screenshot", icon="gui/icons/take_screenshot.png")
253     
254      rotateLeftAction.helptext = u"Rotate counterclockwise by 90 degrees"
255      rotateRightAction.helptext = u"Rotate clockwise by 90 degrees"
256      zoomInAction.helptext = u"Zoom in   (CTRL + Mousewheel up)"
257      zoomOutAction.helptext = u"Zoom out   (CTRL + Mousewheel down)"
258      zoomResetAction.helptext = u"Reset zoom to default level"
259      screenshotAction.helptext = u"Take screenshot   (F7)"
260     
261      action.activated.connect(self._rotateCounterClockwise, sender=rotateLeftAction)
262      action.activated.connect(self._rotateClockwise, sender=rotateRightAction)
263      action.activated.connect(self._zoomIn, sender=zoomInAction)
264      action.activated.connect(self._zoomOut, sender=zoomOutAction)
265      action.activated.connect(self._resetZoom, sender=zoomResetAction)
266      action.activated.connect(self._captureScreen, sender=screenshotAction)
267   
268      self._viewGroup = ActionGroup(name=u"View group")
269      self._viewGroup.addAction(rotateLeftAction)
270      self._viewGroup.addAction(rotateRightAction)
271      self._viewGroup.addAction(zoomInAction)
272      self._viewGroup.addAction(zoomOutAction)
273      self._viewGroup.addAction(zoomResetAction)
274      self._viewGroup.addAction(screenshotAction)
275     
276      self._toolbar.addAction(self._viewGroup)
277      self._toolbar.adaptLayout()
278     
279   def _clearToolbarButtons(self):
280      """ Remove toolbar buttons """
281      self._toolbar.removeAction(self._viewGroup)
282      self._toolbar.adaptLayout()
283      self._viewGroup = None
284     
285   def _setMode(self, mode):
286      """ Set the editor mode """
287      if (mode == MapEditor.INSERTING) and (not self._object):
288         self._statusbar.setText(u'Please select object first')
289         mode = self._mode
290
291      self._ignoreToggles = True
292      # Update toolbox buttons
293      if (mode == MapEditor.INSERTING):
294         self._drawAction.setChecked(True)
295      elif mode == MapEditor.REMOVING:
296         self._removeAction.setChecked(True)
297      elif mode == MapEditor.MOVING:
298         self._moveAction.setChecked(True)
299      elif mode == MapEditor.OBJECTPICKER:
300         self._objectpickerAction.setChecked(True)
301      else:
302         self._selectAction.setChecked(True)
303      self._ignoreToggles = False
304
305      self._mode = mode
306      if self._debug: print "Entered mode " + mode
307      self._statusbar.setText(mode)
308      self._updateCursor()
309     
310   def _zoomIn(self, zoom=1.10):
311      self._controller.setZoom(self._controller.getZoom()*zoom)
312     
313   def _zoomOut(self, zoom=1.10):
314      self._controller.setZoom(self._controller.getZoom()/zoom)
315     
316   def _resetZoom(self):
317      """ Resets zoom level to 1:1 """
318      self._controller.setZoom(1)
319     
320   def _rotateCounterClockwise(self):
321      """ Rotates map counterclockwise """
322      self._controller.rotateCounterClockwise()
323     
324   def _rotateClockwise(self):
325      """ Rotates map clockwise """
326      self._controller.rotateClockwise()
327     
328   def _captureScreen(self):
329      """ Saves a screenshot to the users data directory """
330      userDir = fife_utils.getUserDataDirectory("fife", "editor")
331      t = userDir+"/screenshots"
332      if not os.path.isdir(t):
333         os.makedirs(t)
334      t += "/screen-%s-%s.png" % (date.today().strftime('%Y-%m-%d'),
335                           time.strftime('%H-%M-%S'))
336     
337      self._editor.getEngine().getRenderBackend().captureScreen(t)
338      print "Saved screenshot to:", t     
339     
340   def _buttonToggled(self, sender, toggled):
341      """ Called when a button controlling the editor mode was activated """
342      if self._controller is None: return
343      if self._ignoreToggles is True: return
344   
345      mode = MapEditor.SELECTING
346     
347      if toggled:
348         if sender == self._selectAction:
349            mode = MapEditor.SELECTING
350         elif sender == self._moveAction:
351            mode = MapEditor.MOVING
352         elif sender == self._drawAction:
353            mode = MapEditor.INSERTING
354         elif sender == self._removeAction:
355            mode = MapEditor.REMOVING
356         elif sender == self._objectpickerAction:
357            mode = MapEditor.OBJECTPICKER
358
359      self._setMode(mode)
360     
361   def mousePressed(self, sender, event):
362      if event.isConsumedByWidgets():
363         return
364         
365      if not self._controller._layer:
366         if self._debug: print 'No layers active. Cancelling map action'
367         return
368
369      realCoords = self._getRealCoords(sender, event)
370
371      if event.getButton() == fife.MouseEvent.MIDDLE:
372         self._dragx = realCoords[0]
373         self._dragy = realCoords[1]
374         
375      else:
376         if event.getButton() == fife.MouseEvent.RIGHT:
377            self._controller.deselectSelection()
378           
379         if self._mode == MapEditor.SELECTING:
380            if event.getButton() == fife.MouseEvent.LEFT:
381               if self._eventlistener.shiftPressed:
382                  self._controller.deselectCell(realCoords[0], realCoords[1])
383               else:
384                  if self._eventlistener.controlPressed is False:
385                     self._controller.deselectSelection()
386                  self._controller.selectCell(realCoords[0], realCoords[1])
387               
388            elif event.getButton() == fife.MouseEvent.RIGHT:
389               self._controller.deselectSelection()
390               
391         elif self._mode == MapEditor.INSERTING:
392            if event.getButton() == fife.MouseEvent.LEFT:
393               self._controller.deselectSelection()
394               self._controller.selectCell(realCoords[0], realCoords[1])
395               self._controller.getUndoManager().startGroup("Inserted instances")
396               self._undogroup = True
397               
398               position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
399               position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
400               
401               self._controller.selectCell(realCoords[0], realCoords[1])
402               self._controller.placeInstance(position, self._object)
403           
404         elif self._mode == MapEditor.REMOVING:
405            if event.getButton() == fife.MouseEvent.LEFT:
406               self._controller.deselectSelection()
407               self._controller.selectCell(realCoords[0], realCoords[1])
408               self._controller.getUndoManager().startGroup("Removed instances")
409               self._undogroup = True
410               
411               self._controller.removeInstances(self._controller.getInstancesFromSelection())
412           
413         elif self._mode == MapEditor.MOVING:
414            if event.getButton() == fife.MouseEvent.LEFT:
415           
416               position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
417
418               self._last_drag_pos = self._controller._layer.getCellGrid().toLayerCoordinates(position)
419               self._last_drag_pos_exact = self._controller._layer.getCellGrid().toExactLayerCoordinates(position)
420   
421               for loc in self._controller._selection:
422                  if loc.getLayerCoordinates() == self._last_drag_pos:
423                     break
424               else:
425                  self._controller.deselectSelection()
426                  self._controller.selectCell(realCoords[0], realCoords[1])
427                 
428               self._selected_instances = self._controller.getInstancesFromSelection()
429               
430               self._controller.getUndoManager().startGroup("Moved instances")
431               self._undogroup = True
432               
433         elif self._mode == MapEditor.OBJECTPICKER:
434            position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
435            exact = self._controller._layer.getCellGrid().toExactLayerCoordinates(position)
436            instances = self._controller.getInstancesFromPosition(exact)
437            if len(instances) >= 1:
438               object = instances[0].getObject()
439               if object.getId() != self._object.getId() or object.getNamespace() != self._object.getNamespace():
440                  events.onObjectSelected.send(sender=self, object=object)
441
442   def mouseDragged(self, sender, event):
443      if event.isConsumedByWidgets():
444         return
445         
446      if not self._controller._layer:
447         if self._debug: print 'No layers active. Cancelling map action'
448         return
449         
450      realCoords = self._getRealCoords(sender, event)
451         
452      if event.getButton() == fife.MouseEvent.MIDDLE:
453         self._scrollX = (self._dragx-realCoords[0])/10.0
454         self._scrollY = (self._dragy-realCoords[1])/10.0
455         
456      else:
457         if self._mode != MapEditor.SELECTING:
458            self._controller.deselectSelection()
459           
460         if self._mode == MapEditor.SELECTING:
461            if event.getButton() == fife.MouseEvent.LEFT:
462               if self._eventlistener.shiftPressed:
463                  self._controller.deselectCell(realCoords[0], realCoords[1])
464               else:
465                  self._controller.selectCell(realCoords[0], realCoords[1])
466               
467         elif self._mode == MapEditor.INSERTING:
468            position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
469            position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
470           
471            self._controller.selectCell(realCoords[0], realCoords[1])
472            self._controller.placeInstance(position, self._object)
473           
474         elif self._mode == MapEditor.REMOVING:
475            self._controller.selectCell(realCoords[0], realCoords[1])
476            self._controller.removeInstances(self._controller.getInstancesFromSelection())
477           
478         elif self._mode == MapEditor.MOVING:
479            position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
480           
481            positionExact = self._controller._layer.getCellGrid().toExactLayerCoordinates(position)
482            position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
483           
484            if self._eventlistener.shiftPressed:
485               self._controller.moveInstances(self._selected_instances, positionExact-self._last_drag_pos_exact, True)
486            else:
487               self._controller.moveInstances(self._selected_instances, position-self._last_drag_pos, False)
488            self._last_drag_pos = position
489            self._last_drag_pos_exact = positionExact
490           
491            # Update selection
492            self._controller.deselectSelection()
493           
494            for i in self._selected_instances:
495               pos = i.getLocation().getMapCoordinates()
496               pos = self._controller._camera.toScreenCoordinates(pos)
497               self._controller.selectCell(pos.x, pos.y)
498               
499         elif self._mode == MapEditor.OBJECTPICKER:
500            pass
501
502   def mouseReleased(self, sender, event):
503      if event.isConsumedByWidgets():
504         return
505         
506      if not self._controller._layer:
507         if self._debug: print 'No layers active. Cancelling map action'
508         return
509         
510      if self._mode == MapEditor.SELECTING or self._mode == MapEditor.MOVING:
511         instances = self._controller.getInstancesFromSelection()
512         if len(instances) > 0:
513            events.onInstancesSelected.send(sender=self, instances=instances)
514         
515      if event.getButton() == fife.MouseEvent.MIDDLE:
516         self._scrollX = 0
517         self._scrollY = 0
518         
519      realCoords = self._getRealCoords(sender, event)
520
521      if self._undogroup:
522         self._controller.getUndoManager().endGroup()
523         self._undogroup = False
524
525   def mouseMoved(self, sender, event):
526      pass
527     
528   def mouseEntered(self, sender, event):
529      # Mouse has entered map area. Set cursor to reflect current mode
530      self._updateCursor()
531     
532   def mouseExited(self, sender, event):
533      # Mouse has exited the map area. Set the cursor to native arrow
534      self._resetCursor()
535           
536   def mouseWheelMovedUp(self, event):
537      # Zoom in
538      if self._eventlistener.controlPressed and self._controller._camera:
539         self._controller._camera.setZoom(self._controller._camera.getZoom() * 1.10)
540
541   def mouseWheelMovedDown(self, event):
542      # Zoom out
543      if self._eventlistener.controlPressed and self._controller._camera:
544         self._controller._camera.setZoom(self._controller._camera.getZoom() / 1.10)
545
546   def keyPressed(self, event):
547      keyval = event.getKey().getValue()
548      keystr = event.getKey().getAsString().lower()
549     
550      if keyval == fife.Key.LEFT:
551         self._controller.moveCamera(50, 0)
552      elif keyval == fife.Key.RIGHT:
553         self._controller.moveCamera(-50, 0)
554      elif keyval == fife.Key.UP:
555         self._controller.moveCamera(0, 50)
556      elif keyval == fife.Key.DOWN:
557         self._controller.moveCamera(0, -50)
558     
559      elif keyval == fife.Key.INSERT:
560         self._controller.fillSelection(self._object)
561
562      elif keyval == fife.Key.DELETE:
563         self._controller.clearSelection()
564         
565      elif keyval == fife.Key.F7:
566         self.captureScreen()
567         
568      elif keystr == "s":
569         self._setMode(MapEditor.SELECTING)
570         
571      elif keystr == "i":
572         if self._mode != MapEditor.INSERTING:
573            self._setMode(MapEditor.INSERTING)
574         else:
575            self._setMode(MapEditor.SELECTING)
576         
577      elif keystr == "r":
578         if self._mode != MapEditor.REMOVING:
579            self._setMode(MapEditor.REMOVING)
580         else:
581            self._setMode(MapEditor.SELECTING)
582
583      elif keystr == 'm':
584         if self._mode != MapEditor.MOVING:
585            self._setMode(MapEditor.MOVING)
586         else:
587            self._setMode(MapEditor.SELECTING)
588
589      elif keystr == 't':
590         gridrenderer = self._controller._camera.getRenderer('GridRenderer')
591         gridrenderer.setEnabled(not gridrenderer.isEnabled())
592
593      elif keystr == 'b':
594         blockrenderer = self._controller._camera.getRenderer('BlockingInfoRenderer')
595         blockrenderer.setEnabled(not blockrenderer.isEnabled())
596
597      elif keystr == 'c':
598         self._editor.toggleCoordinates("Toggle Coordinates")
599         
600      elif keystr == 'z':
601         if self._eventlistener.controlPressed:
602            if self._eventlistener.altPressed:
603               if self._eventlistener.shiftPressed:
604                  self._controller.getUndoManager().previousBranch()
605               else:
606                  self._controller.getUndoManager().nextBranch()
607            else:
608               if self._eventlistener.shiftPressed:
609                  self._controller.redo()
610               else:
611                  self._controller.undo()
612         
613
614   def keyReleased(self, event):   
615      pass
616     
617   def _getRealCoords(self, sender, event):
618      """ Converts relative widget coordinate to absolute coordinates """
619      cw = sender
620      offsetX = event.getX()
621      offsetY = event.getY()
622     
623      parent = cw
624      while parent is not None:
625         if isinstance(parent, widgets.Widget):
626            offsetX += parent.x
627            offsetY += parent.y
628            parent = parent.parent
629         else:
630            break
631         
632      return (offsetX, offsetY)
633     
634   def pump(self):
635      """ Called each frame """
636      # Scroll camera
637      self._controller.moveCamera(self._scrollX, self._scrollY)
Note: See TracBrowser for help on using the repository browser.