def _initToolbarbuttons(self):
		""" Sets up and connects buttons related to the toolbar """
	
		rotateLeftAction = Action(text=u"Rotate counterclockwise", icon="gui/icons/rotate_countercw.png")
		rotateRightAction = Action(text=u"Rotate clockwise", icon="gui/icons/rotate_clockwise.png")
		zoomInAction = Action(text=u"Zoom in", icon="gui/icons/zoom_in.png")
		zoomOutAction = Action(text=u"Zoom out", icon="gui/icons/zoom_out.png")
		zoomResetAction = Action(text=u"Reset zoom", icon="gui/icons/zoom_default.png")
		screenshotAction = Action(text=u"Take screenshot", icon="gui/icons/take_screenshot.png")
		
		rotateLeftAction.helptext = u"Rotate counterclockwise by 90 degrees"
		rotateRightAction.helptext = u"Rotate clockwise by 90 degrees"
		zoomInAction.helptext = u"Zoom in   (CTRL + Mousewheel up)"
		zoomOutAction.helptext = u"Zoom out   (CTRL + Mousewheel down)"
		zoomResetAction.helptext = u"Reset zoom to default level"
		screenshotAction.helptext = u"Take screenshot   (F7)"
		
		action.activated.connect(self._rotateCounterClockwise, sender=rotateLeftAction)
		action.activated.connect(self._rotateClockwise, sender=rotateRightAction)
		action.activated.connect(self._zoomIn, sender=zoomInAction)
		action.activated.connect(self._zoomOut, sender=zoomOutAction)
		action.activated.connect(self._resetZoom, sender=zoomResetAction)
		action.activated.connect(self._captureScreen, sender=screenshotAction)
	
		self._viewGroup = ActionGroup(name=u"View group")
		self._viewGroup.addAction(rotateLeftAction)
		self._viewGroup.addAction(rotateRightAction)
		self._viewGroup.addAction(zoomInAction)
		self._viewGroup.addAction(zoomOutAction)
		self._viewGroup.addAction(zoomResetAction)
		self._viewGroup.addAction(screenshotAction)
		
		self._toolbar.addAction(self._viewGroup)
		self._toolbar.adaptLayout()
	def _initToolboxButtons(self):
		""" Sets up and connects buttons related to the toolbox """
		
		self._selectAction = Action(text=u"Select", icon="gui/icons/select_instance.png", checkable=True)
		self._drawAction = Action(text=u"Draw", icon="gui/icons/add_instance.png", checkable=True)
		self._removeAction = Action(text=u"Remove", icon="gui/icons/erase_instance.png", checkable=True)
		self._moveAction = Action(text=u"Move", icon="gui/icons/move_instance.png", checkable=True)
		self._objectpickerAction = Action(text=u"Pick object", icon="gui/icons/objectpicker.png", checkable=True)
		
		self._selectAction.helptext = u"Select cells on layer  (S)"
		self._moveAction.helptext = u"Moves instances   (M)"
		self._drawAction.helptext = u"Adds new instances based on currently selected object   (I)"
		self._removeAction.helptext = u"Deletes instances   (R)"
		self._objectpickerAction.helptext = u"Click an instance to set the current object to the one used by instance"
		
		action.toggled.connect(self._buttonToggled, sender=self._selectAction)
		action.toggled.connect(self._buttonToggled, sender=self._moveAction)
		action.toggled.connect(self._buttonToggled, sender=self._drawAction)
		action.toggled.connect(self._buttonToggled, sender=self._removeAction)
		action.toggled.connect(self._buttonToggled, sender=self._objectpickerAction)
		
		self._toolgroup = ActionGroup(exclusive=True, name=u"Tool group")
		self._toolgroup.addAction(self._selectAction)
		self._toolgroup.addAction(self._moveAction)
		self._toolgroup.addAction(self._drawAction)
		self._toolgroup.addAction(self._removeAction)
		self._toolgroup.addAction(self._objectpickerAction)
		
		self._toolbox.addAction(self._toolgroup)
		self._toolbox.adaptLayout()
		
		self._editor._edit_menu.addAction(self._toolgroup)
Beispiel #3
0
	def __init__(self):
		self.editor = scripts.editor.getEditor()
		self.engine = self.editor.getEngine()
		self._map = None
		self._layer = None
		self._mapdlg = None
		self._layerdlg = None
		self._cameradlg = None
		
		self._filebrowser = None
		self._importbrowser = None
		self._savebrowser = None

		newAction = Action(u"New map", "gui/icons/new_map.png")
		loadAction = Action(u"Open", "gui/icons/load_map.png")
		closeAction = Action(u"Close", "gui/icons/close_map.png")
		saveAction = Action(u"Save", "gui/icons/save_map.png")
		saveAsAction = Action(u"Save as", "gui/icons/save_mapas.png")
		saveAllAction = Action(u"Save all", "gui/icons/save_allmaps.png")
		importFileAction = Action(u"Import file", "gui/icons/import_file.png")
		importDirAction = Action(u"Import directory", "gui/icons/import_dir.png")
		
		newAction.helptext = u"Create new map"
		loadAction.helptext = u"Open existing map"
		closeAction.helptext = u"Close map"
		saveAction.helptext = u"Save map"
		saveAsAction.helptext = u"Save map as"
		saveAllAction.helptext = u"Save all opened maps"
		importFileAction.helptext = u"Imports an object file"
		importDirAction.helptext = u"Recursively imports all objects from a directory"
		
		action.activated.connect(self.showMapWizard, sender=newAction)
		action.activated.connect(self.showLoadDialog, sender=loadAction)
		action.activated.connect(self.closeCurrentMap, sender=closeAction)
		action.activated.connect(self.save, sender=saveAction)
		action.activated.connect(self.saveAs, sender=saveAsAction)
		action.activated.connect(self.editor.saveAll, sender=saveAllAction)
		
		self._importFileCallback = cbwa(self.showImportDialog, self.importFile, False)
		self._importDirCallback = cbwa(self.showImportDialog, self.importDir, True)
		action.activated.connect(self._importFileCallback, sender=importFileAction)
		action.activated.connect(self._importDirCallback, sender=importDirAction)
		
		eventlistener = self.editor.getEventListener()
		eventlistener.getKeySequenceSignal(fife.Key.N, ["ctrl"]).connect(self.showMapWizard)
		eventlistener.getKeySequenceSignal(fife.Key.O, ["ctrl"]).connect(self.showLoadDialog)
		eventlistener.getKeySequenceSignal(fife.Key.W, ["ctrl"]).connect(self.closeCurrentMap)
		eventlistener.getKeySequenceSignal(fife.Key.S, ["ctrl"]).connect(self.save)
		eventlistener.getKeySequenceSignal(fife.Key.S, ["ctrl", "shift"]).connect(self.editor.saveAll)
		
		fileGroup = ActionGroup()
		fileGroup.addAction(newAction)
		fileGroup.addAction(loadAction)
		fileGroup.addSeparator()
		fileGroup.addAction(closeAction)
		fileGroup.addSeparator()
		fileGroup.addAction(saveAction)
		fileGroup.addAction(saveAsAction)
		fileGroup.addAction(saveAllAction)
		fileGroup.addSeparator()
		fileGroup.addAction(importFileAction)
		fileGroup.addAction(importDirAction)
		
		self.editor.getToolBar().insertAction(fileGroup, 0)
		self.editor.getToolBar().insertSeparator(None, 1)
		self.editor._file_menu.insertAction(fileGroup, 0)
		self.editor._file_menu.insertSeparator(None, 1)
class MapEditor:
	""" This class provides a basic user interface for map editing. It allows the user
		to visually edit a map.
	"""
	
	# Editor states
	SELECTING		= u"Selecting"
	INSERTING		= u"Inserting"
	REMOVING		= u"Removing"
	MOVING			= u"Moving"
	OBJECTPICKER	= u"Objectpicking"
	
	def __init__(self):
		""" Set up all variables and call some initial functions """
		self._ignoreToggles = False # A hack to avoid infinite recursion when toggling a button
		self._controller = None
		self._mode = MapEditor.SELECTING
		self._debug = False # TODO: We should have a central system for activating debug messages
		
		# GUI
		self._editor = scripts.editor.getEditor()
		self._eventlistener = self._editor.getEventListener()
		self._statusbar = self._editor.getStatusBar()
		self._toolbar = self._editor.getToolBar()
		self._toolbox = self._editor.getToolbox()
		
		# Currently selected object type
		self._object = None
		
		# Variables used for moving instances
		self._last_drag_pos_exact = fife.ExactModelCoordinate(0,0,0)
		
		self._selected_instances = []
		
		self._undogroup = False
		
		# Variables for scrolling the map
		self._dragx = 0
		self._dragy = 0
		self._scrollX = 0
		self._scrollY = 0
		
		self._initToolboxButtons()
		self._toolbox.show()
		
		events.postMapShown.connect(self._mapChanged)
		events.preMapClosed.connect(self._mapClosed)
		events.onObjectSelected.connect(self.setObject)
		
	def setObject(self, object):
		""" Set the object type to be paint onto map """
		self._object = object

	def getObject(self):
		""" Return the current object """
		return self._object

	def setController(self, controller):
		""" Set the controller to use. """
		if self._controller is not None:
			self._clear()
			
		self._controller = controller

		if self._controller is not None:
			self._init()
		
	def _init(self):
		""" Sets up the mapeditor to work with the selected controller """
		self._debug = self._controller.debug
		self._setMode(MapEditor.SELECTING)
		
		self._initToolbarbuttons()
		
		events.keyPressed.connect(self.keyPressed)
		events.keyReleased.connect(self.keyReleased)
		
		events.mousePressed.connect(self.mousePressed)
		events.mouseDragged.connect(self.mouseDragged)
		events.mouseReleased.connect(self.mouseReleased)
		events.mouseMoved.connect(self.mouseMoved)
		events.mouseEntered.connect(self.mouseEntered)
		events.mouseExited.connect(self.mouseExited)
		events.mouseWheelMovedUp.connect(self.mouseWheelMovedUp)
		events.mouseWheelMovedDown.connect(self.mouseWheelMovedDown)
		events.onPump.connect(self.pump)
		
	def _clear(self):
		""" Remove any functionality set up by _init """
		self._clearToolbarButtons()
		
		events.keyPressed.disconnect(self.keyPressed)
		events.keyReleased.disconnect(self.keyReleased)
		
		events.mousePressed.disconnect(self.mousePressed)
		events.mouseDragged.disconnect(self.mouseDragged)
		events.mouseReleased.disconnect(self.mouseReleased)
		events.mouseMoved.disconnect(self.mouseMoved)
		events.mouseExited.disconnect(self.mouseExited)
		events.mouseEntered.disconnect(self.mouseEntered)
		events.mouseWheelMovedUp.disconnect(self.mouseWheelMovedUp)
		events.mouseWheelMovedDown.disconnect(self.mouseWheelMovedDown)
		events.onPump.disconnect(self.pump)
		
	def _mapChanged(self, sender, mapview):
		""" Called when a new map is selected. 
			Sets the mapeditor to control the mapcontroller in the new map 
		"""
		self.setController(mapview.getController())
		
	def _mapClosed(self, sender, mapview):
		""" Called when a map is closed. """
		if mapview.getMap().getId() == self._controller.getMap().getId():
			self.setController(None)
		
	def _updateCursor(self):
		""" Updates the cursor to reflect the mode of the editor """
		engine = self._editor.getEngine()
		cursor = engine.getCursor()
		
		id = -1
		if self._mode == MapEditor.SELECTING:
			image = engine.getImageManager().get("gui/icons/select_instance.png")
			id = image.getHandle()
			image.setXShift(-7)
			image.setYShift(-7)
			
		elif self._mode == MapEditor.INSERTING:
			image = engine.getImageManager().get("gui/icons/add_instance.png")
			id = image.getHandle()
			image.setXShift(-2)
			image.setYShift(-20)
			
		elif self._mode == MapEditor.REMOVING:
			image = engine.getImageManager().get("gui/icons/erase_instance.png")
			id = image.getHandle()
			image.setXShift(-2)
			image.setYShift(-19)
			
		elif self._mode == MapEditor.MOVING:
			image = engine.getImageManager().get("gui/icons/move_instance.png")
			id = image.getHandle()
			image.setXShift(-11)
			image.setYShift(-11)
			
		elif self._mode == MapEditor.OBJECTPICKER:
			image = engine.getImageManager().get("gui/icons/objectpicker.png")
			id = image.getHandle()
			image.setXShift(-0)
			image.setYShift(-22)
			
		if id < 0:
			self._resetCursor()
		else:
			cursor.set(image)
			
	def _resetCursor(self):
		""" Reset the cursor to the standard native one """
		cursor = self._editor.getEngine().getCursor()
		cursor.set(fife.NC_ARROW)
		
	def _initToolboxButtons(self):
		""" Sets up and connects buttons related to the toolbox """
		
		self._selectAction = Action(text=u"Select", icon="gui/icons/select_instance.png", checkable=True)
		self._drawAction = Action(text=u"Draw", icon="gui/icons/add_instance.png", checkable=True)
		self._removeAction = Action(text=u"Remove", icon="gui/icons/erase_instance.png", checkable=True)
		self._moveAction = Action(text=u"Move", icon="gui/icons/move_instance.png", checkable=True)
		self._objectpickerAction = Action(text=u"Pick object", icon="gui/icons/objectpicker.png", checkable=True)
		
		self._selectAction.helptext = u"Select cells on layer  (S)"
		self._moveAction.helptext = u"Moves instances   (M)"
		self._drawAction.helptext = u"Adds new instances based on currently selected object   (I)"
		self._removeAction.helptext = u"Deletes instances   (R)"
		self._objectpickerAction.helptext = u"Click an instance to set the current object to the one used by instance"
		
		action.toggled.connect(self._buttonToggled, sender=self._selectAction)
		action.toggled.connect(self._buttonToggled, sender=self._moveAction)
		action.toggled.connect(self._buttonToggled, sender=self._drawAction)
		action.toggled.connect(self._buttonToggled, sender=self._removeAction)
		action.toggled.connect(self._buttonToggled, sender=self._objectpickerAction)
		
		self._toolgroup = ActionGroup(exclusive=True, name=u"Tool group")
		self._toolgroup.addAction(self._selectAction)
		self._toolgroup.addAction(self._moveAction)
		self._toolgroup.addAction(self._drawAction)
		self._toolgroup.addAction(self._removeAction)
		self._toolgroup.addAction(self._objectpickerAction)
		
		self._toolbox.addAction(self._toolgroup)
		self._toolbox.adaptLayout()
		
		self._editor._edit_menu.addAction(self._toolgroup)
		
	def _initToolbarbuttons(self):
		""" Sets up and connects buttons related to the toolbar """
	
		rotateLeftAction = Action(text=u"Rotate counterclockwise", icon="gui/icons/rotate_countercw.png")
		rotateRightAction = Action(text=u"Rotate clockwise", icon="gui/icons/rotate_clockwise.png")
		zoomInAction = Action(text=u"Zoom in", icon="gui/icons/zoom_in.png")
		zoomOutAction = Action(text=u"Zoom out", icon="gui/icons/zoom_out.png")
		zoomResetAction = Action(text=u"Reset zoom", icon="gui/icons/zoom_default.png")
		screenshotAction = Action(text=u"Take screenshot", icon="gui/icons/take_screenshot.png")
		
		rotateLeftAction.helptext = u"Rotate counterclockwise by 90 degrees"
		rotateRightAction.helptext = u"Rotate clockwise by 90 degrees"
		zoomInAction.helptext = u"Zoom in   (CTRL + Mousewheel up)"
		zoomOutAction.helptext = u"Zoom out   (CTRL + Mousewheel down)"
		zoomResetAction.helptext = u"Reset zoom to default level"
		screenshotAction.helptext = u"Take screenshot   (F7)"
		
		action.activated.connect(self._rotateCounterClockwise, sender=rotateLeftAction)
		action.activated.connect(self._rotateClockwise, sender=rotateRightAction)
		action.activated.connect(self._zoomIn, sender=zoomInAction)
		action.activated.connect(self._zoomOut, sender=zoomOutAction)
		action.activated.connect(self._resetZoom, sender=zoomResetAction)
		action.activated.connect(self._captureScreen, sender=screenshotAction)
	
		self._viewGroup = ActionGroup(name=u"View group")
		self._viewGroup.addAction(rotateLeftAction)
		self._viewGroup.addAction(rotateRightAction)
		self._viewGroup.addAction(zoomInAction)
		self._viewGroup.addAction(zoomOutAction)
		self._viewGroup.addAction(zoomResetAction)
		self._viewGroup.addAction(screenshotAction)
		
		self._toolbar.addAction(self._viewGroup)
		self._toolbar.adaptLayout()
		
	def _clearToolbarButtons(self):
		""" Remove toolbar buttons """
		self._toolbar.removeAction(self._viewGroup)
		self._toolbar.adaptLayout()
		self._viewGroup = None
		
	def _setMode(self, mode):
		""" Set the editor mode """
		if (mode == MapEditor.INSERTING) and (not self._object):
			self._statusbar.setText(u'Please select object first')
			mode = self._mode

		self._ignoreToggles = True
		# Update toolbox buttons
		if (mode == MapEditor.INSERTING):
			self._drawAction.setChecked(True)
		elif mode == MapEditor.REMOVING:
			self._removeAction.setChecked(True)
		elif mode == MapEditor.MOVING:
			self._moveAction.setChecked(True)
		elif mode == MapEditor.OBJECTPICKER:
			self._objectpickerAction.setChecked(True)
		else:
			self._selectAction.setChecked(True)
		self._ignoreToggles = False

		self._mode = mode
		if self._debug: print "Entered mode " + mode
		self._statusbar.setText(mode)
		self._updateCursor()
		
	def _zoomIn(self, zoom=1.10):
		self._controller.setZoom(self._controller.getZoom()*zoom)
		
	def _zoomOut(self, zoom=1.10):
		self._controller.setZoom(self._controller.getZoom()/zoom)
		
	def _resetZoom(self):
		""" Resets zoom level to 1:1 """
		self._controller.setZoom(1)
		
	def _rotateCounterClockwise(self):
		""" Rotates map counterclockwise """
		self._controller.rotateCounterClockwise()
		
	def _rotateClockwise(self):
		""" Rotates map clockwise """
		self._controller.rotateClockwise()
		
	def _captureScreen(self):
		""" Saves a screenshot to the users data directory """
		userDir = fife_utils.getUserDataDirectory("fife", "editor")
		t = userDir+"/screenshots"
		if not os.path.isdir(t):
			os.makedirs(t)
		t += "/screen-%s-%s.png" % (date.today().strftime('%Y-%m-%d'),
									time.strftime('%H-%M-%S'))
		
		self._editor.getEngine().getRenderBackend().captureScreen(t)
		print "Saved screenshot to:", t		
		
	def _buttonToggled(self, sender, toggled):
		""" Called when a button controlling the editor mode was activated """
		if self._controller is None: return
		if self._ignoreToggles is True: return
	
		mode = MapEditor.SELECTING
		
		if toggled:
			if sender == self._selectAction:
				mode = MapEditor.SELECTING
			elif sender == self._moveAction:
				mode = MapEditor.MOVING
			elif sender == self._drawAction:
				mode = MapEditor.INSERTING
			elif sender == self._removeAction:
				mode = MapEditor.REMOVING
			elif sender == self._objectpickerAction:
				mode = MapEditor.OBJECTPICKER

		self._setMode(mode)
		
	def mousePressed(self, sender, event):
		if event.isConsumedByWidgets():
			return
			
		if not self._controller._layer:
			if self._debug: print 'No layers active. Cancelling map action'
			return

		realCoords = self._getRealCoords(sender, event)

		if event.getButton() == fife.MouseEvent.MIDDLE:
			self._dragx = realCoords[0]
			self._dragy = realCoords[1]
			
		else:
			if event.getButton() == fife.MouseEvent.RIGHT:
				self._controller.deselectSelection()
				
			if self._mode == MapEditor.SELECTING:
				if event.getButton() == fife.MouseEvent.LEFT:
					if self._eventlistener.shiftPressed:
						self._controller.deselectCell(realCoords[0], realCoords[1])
					else:
						if self._eventlistener.controlPressed is False:
							self._controller.deselectSelection()
						self._controller.selectCell(realCoords[0], realCoords[1])
					
				elif event.getButton() == fife.MouseEvent.RIGHT:
					self._controller.deselectSelection()
					
			elif self._mode == MapEditor.INSERTING:
				if event.getButton() == fife.MouseEvent.LEFT:
					self._controller.deselectSelection()
					self._controller.selectCell(realCoords[0], realCoords[1])
					self._controller.getUndoManager().startGroup("Inserted instances")
					self._undogroup = True

					position = self._controller.screenToMapCoordinates(realCoords[0], realCoords[1])
					position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
					
					self._controller.selectCell(realCoords[0], realCoords[1])
					self._controller.placeInstance(position, self._object)
				
			elif self._mode == MapEditor.REMOVING:
				if event.getButton() == fife.MouseEvent.LEFT:
					self._controller.deselectSelection()
					self._controller.selectCell(realCoords[0], realCoords[1])
					self._controller.getUndoManager().startGroup("Removed instances")
					self._undogroup = True
					
					self._controller.removeInstances(self._controller.getInstancesFromSelection())
				
			elif self._mode == MapEditor.MOVING:
				if event.getButton() == fife.MouseEvent.LEFT:
					self._last_drag_pos = self._controller.screenToMapCoordinates(realCoords[0], realCoords[1])
					self._last_drag_cell = self._controller._layer.getCellGrid().toLayerCoordinates(self._last_drag_pos)
					
					if self._controller._single_instance:
						self._selected_instances = self._controller.getInstance()
					else:
						self._selected_instances = self._controller.getInstancesFromSelection()
					
					self._controller.getUndoManager().startGroup("Moved instances")
					self._undogroup = True
					
			elif self._mode == MapEditor.OBJECTPICKER:
				position = self._controller.screenToMapCoordinates(realCoords[0], realCoords[1])
				exact = self._controller._layer.getCellGrid().toExactLayerCoordinates(position)
				instances = self._controller.getInstancesFromPosition(exact)
				if len(instances) >= 1:
					object = instances[0].getObject()
					if object.getId() != self._object.getId() or object.getNamespace() != self._object.getNamespace():
						events.onObjectSelected.send(sender=self, object=object)

	def mouseDragged(self, sender, event):
		if event.isConsumedByWidgets():
			return
			
		if not self._controller._layer:
			if self._debug: print 'No layers active. Cancelling map action'
			return
			
		realCoords = self._getRealCoords(sender, event)
			
		if event.getButton() == fife.MouseEvent.MIDDLE:
			self._scrollX = (self._dragx-realCoords[0])/10.0
			self._scrollY = (self._dragy-realCoords[1])/10.0
			
		else:
			if self._mode != MapEditor.SELECTING:
				self._controller.deselectSelection()
				
			if self._mode == MapEditor.SELECTING:
				if event.getButton() == fife.MouseEvent.LEFT:
					if self._eventlistener.shiftPressed:
						self._controller.deselectCell(realCoords[0], realCoords[1])
					else:
						self._controller.selectCell(realCoords[0], realCoords[1])
					
			elif self._mode == MapEditor.INSERTING:
				position = self._controller.screenToMapCoordinates(realCoords[0], realCoords[1])
				position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
				
				self._controller.selectCell(realCoords[0], realCoords[1])
				self._controller.placeInstance(position, self._object)
				
			elif self._mode == MapEditor.REMOVING:
				self._controller.selectCell(realCoords[0], realCoords[1])
				self._controller.removeInstances(self._controller.getInstancesFromSelection())
				
			elif self._mode == MapEditor.MOVING:
				position = self._controller.screenToMapCoordinates(realCoords[0], realCoords[1])				
				cell = self._controller._layer.getCellGrid().toLayerCoordinates(position)

				if self._eventlistener.shiftPressed:
					res = self._controller.moveInstances(
						self._selected_instances,
						position - self._last_drag_pos,
						exact = True)
				else:
					res = self._controller.moveInstances(
						self._selected_instances,
						self._controller._layer.getCellGrid().toMapCoordinates(cell) - self._controller._layer.getCellGrid().toMapCoordinates(self._last_drag_cell),
						exact = False)

				# update only if the instances moved
				if res:
					self._last_drag_pos = position
					self._last_drag_cell = cell
				
				# Update selection
				self._controller.deselectSelection()
				
				for i in self._selected_instances:
					pos = i.getLocation().getMapCoordinates()
					pos = self._controller._camera.toScreenCoordinates(pos)
					self._controller.selectCell(pos.x, pos.y)
					
			elif self._mode == MapEditor.OBJECTPICKER:
				pass

	def mouseReleased(self, sender, event):
		if event.isConsumedByWidgets():
			return
			
		if not self._controller._layer:
			if self._debug: print 'No layers active. Cancelling map action'
			return
			
		if self._mode == MapEditor.SELECTING or self._mode == MapEditor.MOVING:
			instances = self._controller.getInstancesFromSelection()
			if len(instances) > 0:
				events.onInstancesSelected.send(sender=self, instances=instances)

		if self._mode == MapEditor.SELECTING:
			locations = self._controller.getLocationsFromSelection()
			if len(locations) > 0:
				events.onCellSelected.send(sender=self, locations=locations)
			
		if event.getButton() == fife.MouseEvent.MIDDLE:
			self._scrollX = 0
			self._scrollY = 0
			
		realCoords = self._getRealCoords(sender, event)

		if self._undogroup:
			self._controller.getUndoManager().endGroup()
			self._undogroup = False

	def mouseMoved(self, sender, event):
		pass
		
	def mouseEntered(self, sender, event):
		# Mouse has entered map area. Set cursor to reflect current mode
		self._updateCursor()
		
	def mouseExited(self, sender, event):
		# Mouse has exited the map area. Set the cursor to native arrow
		self._resetCursor()
				
	def mouseWheelMovedUp(self, event):
		# Zoom in
		if self._eventlistener.controlPressed and self._controller._camera:
			self._controller._camera.setZoom(self._controller._camera.getZoom() * 1.10)

	def mouseWheelMovedDown(self, event):
		# Zoom out
		if self._eventlistener.controlPressed and self._controller._camera:
			self._controller._camera.setZoom(self._controller._camera.getZoom() / 1.10)

	def keyPressed(self, event):
		keyval = event.getKey().getValue()
		keystr = event.getKey().getAsString().lower()
		
		if keyval == fife.Key.LEFT:
			self._controller.moveCamera(50, 0)
		elif keyval == fife.Key.RIGHT:
			self._controller.moveCamera(-50, 0)
		elif keyval == fife.Key.UP:
			self._controller.moveCamera(0, 50)
		elif keyval == fife.Key.DOWN:
			self._controller.moveCamera(0, -50)
		
		elif keyval == fife.Key.INSERT:
			self._controller.fillSelection(self._object)

		elif keyval == fife.Key.DELETE:
			self._controller.clearSelection()

		elif keyval == fife.Key.PAGE_UP:
			if self._eventlistener.controlPressed:
				if self._controller._single_instance:
					self._selected_instances = self._controller.getInstance()
				elif self._controller.getInstancesFromSelection():
					self._selected_instances = self._controller.getInstancesFromSelection()
				elif self._controller.getAllInstances():
					self._selected_instances = self._controller.getAllInstances()

				if self._selected_instances:
					self._controller.moveInstances(self._selected_instances, fife.ExactModelCoordinate(0, 0, 1), exact=False)

		elif keyval == fife.Key.PAGE_DOWN:
			if self._eventlistener.controlPressed:
				if self._controller._single_instance:
					self._selected_instances = self._controller.getInstance()
				elif self._controller.getInstancesFromSelection():
					self._selected_instances = self._controller.getInstancesFromSelection()
				elif self._controller.getAllInstances():
					self._selected_instances = self._controller.getAllInstances()

				if self._selected_instances:
					self._controller.moveInstances(self._selected_instances, fife.ExactModelCoordinate(0, 0, -1), exact=False)

		elif keyval == fife.Key.F7:
			self.captureScreen()
			
		elif keystr == "s":
			self._setMode(MapEditor.SELECTING)
			
		elif keystr == "i":
			if self._mode != MapEditor.INSERTING:
				self._setMode(MapEditor.INSERTING)
			else:
				self._setMode(MapEditor.SELECTING)
			
		elif keystr == "r":
			if self._mode != MapEditor.REMOVING:
				self._setMode(MapEditor.REMOVING)
			else:
				self._setMode(MapEditor.SELECTING)

		elif keystr == 'm':
			if self._mode != MapEditor.MOVING:
				self._setMode(MapEditor.MOVING)
			else:
				self._setMode(MapEditor.SELECTING)

		elif keystr == 't':
			gridrenderer = self._controller._camera.getRenderer('GridRenderer')
			gridrenderer.setEnabled(not gridrenderer.isEnabled())

		elif keystr == 'b':
			blockrenderer = self._controller._camera.getRenderer('BlockingInfoRenderer')
			blockrenderer.setEnabled(not blockrenderer.isEnabled())

		elif keystr == 'c':
			self._editor.toggleCoordinates("Toggle Coordinates")
			
		elif keystr == 'z':
			if self._eventlistener.controlPressed:
				if self._eventlistener.altPressed:
					if self._eventlistener.shiftPressed:
						self._controller.getUndoManager().previousBranch()
					else:
						self._controller.getUndoManager().nextBranch()
				else:
					if self._eventlistener.shiftPressed:
						self._controller.redo()
					else:
						self._controller.undo()
			

	def keyReleased(self, event):		
		pass
		
	def _getRealCoords(self, sender, event):
		""" Converts relative widget coordinate to absolute coordinates """
		cw = sender
		offsetX = event.getX()
		offsetY = event.getY()
		
		parent = cw
		while parent is not None:
			if isinstance(parent, widgets.Widget):
				offsetX += parent.x
				offsetY += parent.y
				parent = parent.parent
			else:
				break
			
		return (offsetX, offsetY)
		
	def pump(self):
		""" Called each frame """
		# Scroll camera
		self._controller.moveCamera(self._scrollX, self._scrollY)
    def __init__(self):
        from fife import fife
        self.editor = scripts.editor.getEditor()
        self.engine = self.editor.getEngine()
        self._map = None
        self._layer = None
        self._mapdlg = None
        self._layerdlg = None
        self._cameradlg = None

        self._filebrowser = None
        self._importbrowser = None
        self._savebrowser = None

        newAction = Action(u"New map", "gui/icons/new_map.png")
        loadAction = Action(u"Open", "gui/icons/load_map.png")
        closeAction = Action(u"Close", "gui/icons/close_map.png")
        saveAction = Action(u"Save", "gui/icons/save_map.png")
        saveAsAction = Action(u"Save as", "gui/icons/save_mapas.png")
        saveAllAction = Action(u"Save all", "gui/icons/save_allmaps.png")
        importFileAction = Action(u"Import file", "gui/icons/import_file.png")
        importDirAction = Action(u"Import directory",
                                 "gui/icons/import_dir.png")

        newAction.helptext = u"Create new map"
        loadAction.helptext = u"Open existing map"
        closeAction.helptext = u"Close map"
        saveAction.helptext = u"Save map"
        saveAsAction.helptext = u"Save map as"
        saveAllAction.helptext = u"Save all opened maps"
        importFileAction.helptext = u"Imports an object file"
        importDirAction.helptext = u"Recursively imports all objects from a directory"

        action.activated.connect(self.showMapWizard, sender=newAction)
        action.activated.connect(self.showLoadDialog, sender=loadAction)
        action.activated.connect(self.closeCurrentMap, sender=closeAction)
        action.activated.connect(self.save, sender=saveAction)
        action.activated.connect(self.saveAs, sender=saveAsAction)
        action.activated.connect(self.editor.saveAll, sender=saveAllAction)

        self._importFileCallback = cbwa(self.showImportDialog, self.importFile,
                                        False)
        self._importDirCallback = cbwa(self.showImportDialog, self.importDir,
                                       True)
        action.activated.connect(self._importFileCallback,
                                 sender=importFileAction)
        action.activated.connect(self._importDirCallback,
                                 sender=importDirAction)

        eventlistener = self.editor.getEventListener()

        eventlistener.getKeySequenceSignal(fife.Key.N, ["ctrl"]).connect(
            self.showMapWizard)
        eventlistener.getKeySequenceSignal(fife.Key.O, ["ctrl"]).connect(
            self.showLoadDialog)
        eventlistener.getKeySequenceSignal(fife.Key.W, ["ctrl"]).connect(
            self.closeCurrentMap)
        eventlistener.getKeySequenceSignal(fife.Key.S,
                                           ["ctrl"]).connect(self.save)
        eventlistener.getKeySequenceSignal(
            fife.Key.S, ["ctrl", "shift"]).connect(self.editor.saveAll)

        fileGroup = ActionGroup()
        fileGroup.addAction(newAction)
        fileGroup.addAction(loadAction)
        fileGroup.addSeparator()
        fileGroup.addAction(closeAction)
        fileGroup.addSeparator()
        fileGroup.addAction(saveAction)
        fileGroup.addAction(saveAsAction)
        fileGroup.addAction(saveAllAction)
        fileGroup.addSeparator()
        fileGroup.addAction(importFileAction)
        fileGroup.addAction(importDirAction)

        self.editor.getToolBar().insertAction(fileGroup, 0)
        self.editor.getToolBar().insertSeparator(None, 1)
        self.editor._file_menu.insertAction(fileGroup, 0)
        self.editor._file_menu.insertSeparator(None, 1)
Beispiel #6
0
class MapEditor:
	def __init__(self):	
		self._ignoreToggles = False # A hack to avoid infinite recursion when toggling a button
		self._controller = None
		self._mode = SELECTING
		
		self._editor = scripts.editor.getEditor()
		self._eventlistener = self._editor.getEventListener()
		self._statusbar = self._editor.getStatusBar()
		self._toolbar = self._editor.getToolBar()
		self._object = None
		self._startDragPos = None
		self._lastDragPos = None
		self._lastDragPosExact = None
		
		self._toolbox = self._editor.getToolbox()
		
		self._initToolbuttons()
		
		self._toolbox.show()
		self._instances = []
		
		events.postMapShown.connect(self._mapChanged)
		events.preMapClosed.connect(self._mapClosed)
		events.onObjectSelected.connect(self.setObject)
		self._undogroup = False
		
		self._scrollX = 0
		self._scrollY = 0
		
	def _init(self):
		self._dragx = NOT_INITIALIZED
		self._dragy = NOT_INITIALIZED
		
		self._setMode(SELECTING)
		
		self._initToolbarbuttons()
		
		events.keyPressed.connect(self.keyPressed)
		events.keyReleased.connect(self.keyReleased)
		
		events.mousePressed.connect(self.mousePressed)
		events.mouseDragged.connect(self.mouseDragged)
		events.mouseReleased.connect(self.mouseReleased)
		events.mouseMoved.connect(self.mouseMoved)
		events.mouseEntered.connect(self.mouseEntered)
		events.mouseExited.connect(self.mouseExited)
		events.mouseWheelMovedUp.connect(self.mouseWheelMovedUp)
		events.mouseWheelMovedDown.connect(self.mouseWheelMovedDown)
		events.onPump.connect(self.pump)
		events.layerSelected.connect(self._layerSelected)
		
	def _clear(self):
		self._clearToolbarButtons()
		
		events.keyPressed.disconnect(self.keyPressed)
		events.keyReleased.disconnect(self.keyReleased)
		
		events.mousePressed.disconnect(self.mousePressed)
		events.mouseDragged.disconnect(self.mouseDragged)
		events.mouseReleased.disconnect(self.mouseReleased)
		events.mouseMoved.disconnect(self.mouseMoved)
		events.mouseExited.disconnect(self.mouseExited)
		events.mouseEntered.disconnect(self.mouseEntered)
		events.mouseWheelMovedUp.disconnect(self.mouseWheelMovedUp)
		events.mouseWheelMovedDown.disconnect(self.mouseWheelMovedDown)
		events.onPump.disconnect(self.pump)
		events.layerSelected.disconnect(self._layerSelected)
		
	def _mapChanged(self, sender, mapview):
		self.setController(mapview.getController())
		
	def _mapClosed(self, sender, mapview):
		self.setController(None)
		
	def _setCursor(self):
		engine = self._editor.getEngine()
		cursor = engine.getCursor()
		
		id = -1
		if self._mode == SELECTING:
			id = engine.getImagePool().addResourceFromFile("gui/icons/select_instance.png")
			image = engine.getImagePool().getImage(id)
			image.setXShift(-7)
			image.setYShift(-7)
		elif self._mode == INSERTING:
			id = engine.getImagePool().addResourceFromFile("gui/icons/add_instance.png")
			image = engine.getImagePool().getImage(id)
			image.setXShift(-2)
			image.setYShift(-20)
		elif self._mode == REMOVING:
			id = engine.getImagePool().addResourceFromFile("gui/icons/erase_instance.png")
			image = engine.getImagePool().getImage(id)
			image.setXShift(-2)
			image.setYShift(-19)
		elif self._mode == MOVING:
			id = engine.getImagePool().addResourceFromFile("gui/icons/move_instance.png")
			image = engine.getImagePool().getImage(id)
			image.setXShift(-11)
			image.setYShift(-11)
		elif self._mode == OBJECTPICKER:
			id = engine.getImagePool().addResourceFromFile("gui/icons/objectpicker.png")
			image = engine.getImagePool().getImage(id)
			image.setXShift(-0)
			image.setYShift(-22)
			
		if id < 0:
			self._resetCursor()
		else:
			cursor.set(fife.CURSOR_IMAGE, id)
			
	def _resetCursor(self):
		cursor = self._editor.getEngine().getCursor()
		cursor.set(fife.CURSOR_NATIVE, fife.NC_ARROW)
		
	def _layerSelected(self, sender, mapcontroller, layer):
		gridrenderer = self._controller._camera.getRenderer('GridRenderer')
		gridrenderer.clearActiveLayers()
		if layer is not None:
			gridrenderer.addActiveLayer(self._controller.getLayer())

		blockrenderer = self._controller._camera.getRenderer('BlockingInfoRenderer')
		blockrenderer.clearActiveLayers()
		if layer is not None:
			blockrenderer.addActiveLayer(self._controller.getLayer())
		
		
	def setObject(self, object):
		self._object = object
		
	def setController(self, controller):
		if self._controller is not None:
			self._clear()

		if controller is not None:
			self._init()
			
		self._controller = controller
		
	def _initToolbuttons(self):
		self._selectAction = Action(text=u"Select", icon="gui/icons/select_instance.png", checkable=True)
		self._drawAction = Action(text=u"Draw", icon="gui/icons/add_instance.png", checkable=True)
		self._removeAction = Action(text=u"Remove", icon="gui/icons/erase_instance.png", checkable=True)
		self._moveAction = Action(text=u"Move", icon="gui/icons/move_instance.png", checkable=True)
		self._objectpickerAction = Action(text=u"Pick object", icon="gui/icons/objectpicker.png", checkable=True)
		
		self._selectAction.helptext = u"Select cells on layer  (S)"
		self._moveAction.helptext = u"Moves instances   (M)"
		self._drawAction.helptext = u"Adds new instances based on currently selected object   (I)"
		self._removeAction.helptext = u"Deletes instances   (R)"
		self._objectpickerAction.helptext = u"Click an instance to set the current object to the one used by instance"
		
		action.toggled.connect(self._buttonToggled, sender=self._selectAction)
		action.toggled.connect(self._buttonToggled, sender=self._moveAction)
		action.toggled.connect(self._buttonToggled, sender=self._drawAction)
		action.toggled.connect(self._buttonToggled, sender=self._removeAction)
		action.toggled.connect(self._buttonToggled, sender=self._objectpickerAction)
		
		self._toolgroup = ActionGroup(exclusive=True, name=u"Tool group")
		self._toolgroup.addAction(self._selectAction)
		self._toolgroup.addAction(self._moveAction)
		self._toolgroup.addAction(self._drawAction)
		self._toolgroup.addAction(self._removeAction)
		self._toolgroup.addAction(self._objectpickerAction)
		
		
		self._toolbox.addAction(self._toolgroup)
		self._toolbox.adaptLayout()
		
		self._editor._edit_menu.addAction(self._toolgroup)
		
	def _initToolbarbuttons(self):
		rotateLeftAction = Action(text=u"Rotate counterclockwise", icon="gui/icons/rotate_countercw.png")
		rotateRightAction = Action(text=u"Rotate clockwise", icon="gui/icons/rotate_clockwise.png")
		zoomInAction = Action(text=u"Zoom in", icon="gui/icons/zoom_in.png")
		zoomOutAction = Action(text=u"Zoom out", icon="gui/icons/zoom_out.png")
		zoomResetAction = Action(text=u"Reset zoom", icon="gui/icons/zoom_default.png")
		screenshotAction = Action(text=u"Take screenshot", icon="gui/icons/take_screenshot.png")
		
		rotateLeftAction.helptext = u"Rotate counterclockwise by 90 degrees"
		rotateRightAction.helptext = u"Rotate clockwise by 90 degrees"
		zoomInAction.helptext = u"Zoom in   (CTRL + Mousewheel up)"
		zoomOutAction.helptext = u"Zoom out   (CTRL + Mousewheel down)"
		zoomResetAction.helptext = u"Reset zoom to default level"
		screenshotAction.helptext = u"Take screenshot   (F7)"
		
		action.activated.connect(self.rotateCounterClockwise, sender=rotateLeftAction)
		action.activated.connect(self.rotateClockwise, sender=rotateRightAction)
		action.activated.connect(self.zoomIn, sender=zoomInAction)
		action.activated.connect(self.zoomOut, sender=zoomOutAction)
		action.activated.connect(self.resetZoom, sender=zoomResetAction)
		action.activated.connect(self.captureScreen, sender=screenshotAction)
	
		self._viewGroup = ActionGroup(name=u"View group")
		self._viewGroup.addAction(rotateLeftAction)
		self._viewGroup.addAction(rotateRightAction)
		self._viewGroup.addAction(zoomInAction)
		self._viewGroup.addAction(zoomOutAction)
		self._viewGroup.addAction(zoomResetAction)
		self._viewGroup.addAction(screenshotAction)
		
		self._toolbar.addAction(self._viewGroup)
		self._toolbar.adaptLayout()
		
	def _clearToolbarButtons(self):
		self._toolbar.removeAction(self._viewGroup)
		self._toolbar.adaptLayout()
		self._viewGroup = None
		
		
	def _setMode(self, mode):
		if (mode == INSERTING) and (not self._object):
			self._statusbar.setText(u'Please select object first')
			mode = self._mode

		self._ignoreToggles = True
		# Update toolbox buttons
		if (mode == INSERTING):
			self._drawAction.setChecked(True)
		elif mode == REMOVING:
			self._removeAction.setChecked(True)
		elif mode == MOVING:
			self._moveAction.setChecked(True)
		elif mode == OBJECTPICKER:
			self._objectpickerAction.setChecked(True)
		else:
			self._selectAction.setChecked(True)
		self._ignoreToggles = False

		self._mode = mode
		print "Entered mode " + mode
		self._statusbar.setText(mode.replace('_', ' ').capitalize())
		self._setCursor()
		
	def _buttonToggled(self, sender, toggled):
		if self._controller is None: return
		if self._ignoreToggles is True: return
	
		mode = SELECTING
		
		if toggled:
			if sender == self._selectAction:
				mode = SELECTING
			elif sender == self._moveAction:
				mode = MOVING
			elif sender == self._drawAction:
				mode = INSERTING
			elif sender == self._removeAction:
				mode = REMOVING
			elif sender == self._objectpickerAction:
				mode = OBJECTPICKER

		self._setMode(mode)
		
	def mousePressed(self, sender, event):
		if event.isConsumedByWidgets():
			return
			
		if not self._controller._layer:
			if self._controller.debug: print 'No layers active. Cancelling map action'
			return

		realCoords = self._getRealCoords(sender, event)

		if event.getButton() == fife.MouseEvent.MIDDLE:
			self._dragx = realCoords[0]
			self._dragy = realCoords[1]
			
		else:
			if event.getButton() == fife.MouseEvent.RIGHT:
				self._controller.deselectSelection()
				
			if self._mode == SELECTING:
				if event.getButton() == fife.MouseEvent.LEFT:
					if self._eventlistener.shiftPressed:
						self._controller.deselectCell(realCoords[0], realCoords[1])
					else:
						if self._eventlistener.controlPressed is False:
							self._controller.deselectSelection()
						self._controller.selectCell(realCoords[0], realCoords[1])
					
				elif event.getButton() == fife.MouseEvent.RIGHT:
					self._controller.deselectSelection()
					
			elif self._mode == INSERTING:
				if event.getButton() == fife.MouseEvent.LEFT:
					self._controller.deselectSelection()
					self._controller.selectCell(realCoords[0], realCoords[1])
					self._controller.getUndoManager().startGroup("Inserted instances")
					self._undogroup = True
					
					position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
					position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
					
					self._controller.selectCell(realCoords[0], realCoords[1])
					self._controller.placeInstance(position, self._object)
				
			elif self._mode == REMOVING:
				if event.getButton() == fife.MouseEvent.LEFT:
					self._controller.deselectSelection()
					self._controller.selectCell(realCoords[0], realCoords[1])
					self._controller.getUndoManager().startGroup("Removed instances")
					self._undogroup = True
					
					self._controller.removeInstances(self._controller.getInstancesFromSelection())
				
			elif self._mode == MOVING:
				if event.getButton() == fife.MouseEvent.LEFT:
				
					position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)

					self._lastDragPos = self._controller._layer.getCellGrid().toLayerCoordinates(position)
					self._lastDragPosExact = self._controller._layer.getCellGrid().toExactLayerCoordinates(position)
	
					for loc in self._controller._selection:
						if loc.getLayerCoordinates() == self._lastDragPos:
							break
					else:
						self._controller.deselectSelection()
						self._controller.selectCell(realCoords[0], realCoords[1])
						
					self._instances = self._controller.getInstancesFromSelection()
					
					self._controller.getUndoManager().startGroup("Moved instances")
					self._undogroup = True
					
			elif self._mode == OBJECTPICKER:
				position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
				exact = self._controller._layer.getCellGrid().toExactLayerCoordinates(position)
				instances = self._controller.getInstancesFromPosition(exact)
				if len(instances) >= 1:
					object = instances[0].getObject()
					if object.getId() != self._object.getId() or object.getNamespace() != self._object.getNamespace():
						events.onObjectSelected.send(sender=self, object=object)

	def mouseDragged(self, sender, event):
		if event.isConsumedByWidgets():
			return
			
		if not self._controller._layer:
			if self._controller.debug: print 'No layers active. Cancelling map action'
			return
			
		realCoords = self._getRealCoords(sender, event)
			
		if event.getButton() == fife.MouseEvent.MIDDLE:
			self._scrollX = (self._dragx-realCoords[0])/10.0
			self._scrollY = (self._dragy-realCoords[1])/10.0
		else:
			if self._mode != SELECTING:
				self._controller.deselectSelection()
				
			if self._mode == SELECTING:
				if event.getButton() == fife.MouseEvent.LEFT:
					if self._eventlistener.shiftPressed:
						self._controller.deselectCell(realCoords[0], realCoords[1])
					else:
						self._controller.selectCell(realCoords[0], realCoords[1])
					
			elif self._mode == INSERTING:
				position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
				position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
				
				self._controller.selectCell(realCoords[0], realCoords[1])
				self._controller.placeInstance(position, self._object)
				
			elif self._mode == REMOVING:
				self._controller.selectCell(realCoords[0], realCoords[1])
				self._controller.removeInstances(self._controller.getInstancesFromSelection())
				
			elif self._mode == MOVING:
				position = self._controller._camera.toMapCoordinates(fife.ScreenPoint(realCoords[0], realCoords[1]), False)
				
				positionExact = self._controller._layer.getCellGrid().toExactLayerCoordinates(position)
				position = self._controller._layer.getCellGrid().toLayerCoordinates(position)
				
				if self._eventlistener.shiftPressed:
					self._controller.moveInstances(self._instances, positionExact-self._lastDragPosExact, True)
				else:
					self._controller.moveInstances(self._instances, position-self._lastDragPos, False)
				self._lastDragPos = position
				self._lastDragPosExact = positionExact
				
				# Update selection
				self._controller.deselectSelection()
				
				for i in self._instances:
					pos = i.getLocation().getMapCoordinates()
					pos = self._controller._camera.toScreenCoordinates(pos)
					self._controller.selectCell(pos.x, pos.y)
			elif self._mode == OBJECTPICKER:
				pass

	def mouseReleased(self, sender, event):
		if event.isConsumedByWidgets():
			return
			
		if not self._controller._layer:
			if self._controller.debug: print 'No layers active. Cancelling map action'
			return
			
		if self._mode == SELECTING or self._mode == MOVING:
			instances = self._controller.getInstancesFromSelection()
			if len(instances) > 0:
				events.onInstancesSelected.send(sender=self, instances=instances)
			
		if event.getButton() == fife.MouseEvent.MIDDLE:
			self._scrollX = 0
			self._scrollY = 0
			
		realCoords = self._getRealCoords(sender, event)

		if self._undogroup:
			self._controller.getUndoManager().endGroup()
			self._undogroup = False

		self._dragx = NOT_INITIALIZED
		self._dragy = NOT_INITIALIZED

	def mouseMoved(self, sender, event):
		pass
		
	def mouseEntered(self, sender, event):
		self._setCursor()
		
	def mouseExited(self, sender, event):
		self._resetCursor()
				
	def mouseWheelMovedUp(self, event):
		if self._eventlistener.controlPressed and self._controller._camera:
			self._controller._camera.setZoom(self._controller._camera.getZoom() * 1.10)

	def mouseWheelMovedDown(self, event):
		if self._eventlistener.controlPressed and self._controller._camera:
			self._controller._camera.setZoom(self._controller._camera.getZoom() / 1.10)


	def keyPressed(self, event):
		keyval = event.getKey().getValue()
		keystr = event.getKey().getAsString().lower()
		
		if keyval == fife.Key.LEFT:
			self._controller.moveCamera(50, 0)
		elif keyval == fife.Key.RIGHT:
			self._controller.moveCamera(-50, 0)
		elif keyval == fife.Key.UP:
			self._controller.moveCamera(0, 50)
		elif keyval == fife.Key.DOWN:
			self._controller.moveCamera(0, -50)
		
		elif keyval == fife.Key.INSERT:
			self._controller.fillSelection(self._object)

		elif keyval == fife.Key.DELETE:
			self._controller.clearSelection()
			
		elif keyval == fife.Key.F7:
			self.captureScreen()
			
		elif keystr == "s":
			self._setMode(SELECTING)
			
		elif keystr == "i":
			if self._mode != INSERTING:
				self._setMode(INSERTING)
			else:
				self._setMode(SELECTING)
			
		elif keystr == "r":
			if self._mode != REMOVING:
				self._setMode(REMOVING)
			else:
				self._setMode(SELECTING)

		elif keystr == 'm':
			if self._mode != MOVING:
				self._setMode(MOVING)
			else:
				self._setMode(SELECTING)

		elif keystr == 't':
			gridrenderer = self._controller._camera.getRenderer('GridRenderer')
			gridrenderer.setEnabled(not gridrenderer.isEnabled())
			gridrenderer.clearActiveLayers()
			if self._controller.getLayer() is not None:
				gridrenderer.addActiveLayer(self._controller.getLayer())

		elif keystr == 'b':
			blockrenderer = self._controller._camera.getRenderer('BlockingInfoRenderer')
			blockrenderer.setEnabled(not blockrenderer.isEnabled())

		elif keystr == 'z':
			if self._eventlistener.controlPressed:
				if self._eventlistener.altPressed:
					if self._eventlistener.shiftPressed:
						self._controller.getUndoManager().previousBranch()
					else:
						self._controller.getUndoManager().nextBranch()
				else:
					if self._eventlistener.shiftPressed:
						self._controller.redo()
					else:
						self._controller.undo()
			

	def keyReleased(self, event):		
		pass
		
	def zoomIn(self, zoom=1.10):
		self._controller.setZoom(self._controller.getZoom()*zoom)
		
	def zoomOut(self, zoom=1.10):
		self._controller.setZoom(self._controller.getZoom()/zoom)
		
	def resetZoom(self):
		self._controller.setZoom(1)
		
	def rotateCounterClockwise(self):
		self._controller.rotateCounterClockwise()
		
	def rotateClockwise(self):
		self._controller.rotateClockwise()
			
	def _getRealCoords(self, sender, event):
		cw = sender
		offsetX = event.getX()
		offsetY = event.getY()
		
		parent = cw
		while parent is not None:
			if isinstance(parent, widgets.Widget):
				offsetX += parent.x
				offsetY += parent.y
				parent = parent.parent
			else:
				break
			
		return (offsetX, offsetY)
		
	def captureScreen(self):
		userDir = fife_utils.getUserDataDirectory("fife", "editor")
		t = userDir+"/screenshots"
		if not os.path.isdir(t):
			os.makedirs(t)
		t += "/screen-%s-%s.png" % (date.today().strftime('%Y-%m-%d'),
									time.strftime('%H-%M-%S'))
		
		self._editor.getEngine().getRenderBackend().captureScreen(t)
		print "Saved screenshot to:", t
		
	def pump(self):
		self._controller.moveCamera(self._scrollX, self._scrollY)