changeset 211:f10a2e78a0e1

- updated objectedit plugin, should work much better now - removed data records from objectedit plugin (way too buggy & ugly) - removed obsolete plugin data from settings.py NOTE: - the sliders for offset manipulation don't work ATM
author chewie@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 16 Mar 2009 14:40:36 +0000
parents be246fb3a0df
children bbf17f8c221f
files clients/editor/plugins/objectedit.py clients/editor/settings.py
diffstat 2 files changed, 168 insertions(+), 237 deletions(-) [+]
line wrap: on
line diff
--- a/clients/editor/plugins/objectedit.py	Mon Mar 16 01:23:03 2009 +0000
+++ b/clients/editor/plugins/objectedit.py	Mon Mar 16 14:40:36 2009 +0000
@@ -22,6 +22,8 @@
 # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ###################################################
 
+""" a tool for FIFEdit to edit object and instance attributes """
+
 import fife
 import plugin
 import pychan
@@ -29,50 +31,53 @@
 from pychan.tools import callbackWithArguments as cbwa
 
 import settings as Settings
+import math
 
 class ObjectEdit(plugin.Plugin):
-	def __init__(self, engine, mapedit):
-		"""
-			ObjectEdit plugin for FIFEdit
-			
-			Mission: provide a gui mask to edit all important object data within the editor
-			(id, offsets, rotation, blocking, static)
-			
-			namespaces and object ids are excluded
+	""" The B{ObjectEdit} module is a plugin for FIFedit and allows to edit
+	attributes of an selected instance - like offset, instance id or rotation
+	(namespaces and object id editing is excluded)
+	
+	current features:
+		- click instance and get all known data
+		- edit offsets, rotation, instance id
+		- outline highlighting of the selected object
 			
-			Current features:
-				- click instance and get all known data
-				- edit offsets, rotation, blocking, static
-				- outline highlighting of the selected object
-				- 3 data states: current, previous and default (so there is at least a one-step-undo)
-				
-			Missing features:
-				- object saving
-				- id saving (handled by Fifedit via save map, but we have to set the id from here)
-				- a lot of bug fixing concerning the rotation and the data records ^^
-				- cleanup
-		
-			NOTE:
-				- this tool isn't ready for a working enviroment (yet)
-		"""
+	missing features:
+		- blocking flag (flag doesn't work yet from FIFE side)
+		- static flag (flag doesn't work yet from FIFE side)		
+		- object saving
+		- a lot of bug fixing concerning the rotation
+		- use sliders to allow offset changes
+		- the module should be able to use the editors global undo history
+
+	FIXME:
+		- this module owns a pointer to the mapedit module - this shouldn't be
+		  necessary; a better plugin system of fifedit should only hand over the needed
+		  data (selected instance)
+		- we also need to edit run.py of the editor core to make this plugin work (shouldn't be necessary, too)
+	"""
+	def __init__(self, engine, mapedit):
 		# Fifedit plugin data
 		self.menu_items = { 'ObjectEdit' : self.toggle_offsetedit }
 		
 		self._mapedit = mapedit
 
-# FIXME		
 		# this is _very bad_ - but I need to change the current rotation code by providing
 		# project specific rotation angles. FIFE later should provide a list of the loaded
 		# object rotations (they are provided by the xml files, so we just need to use them...)
 		self._mapedit._objectedit_rotations = None
-# end FIXME		
+	
 		self.active = False
+		self._camera = None
+		self._layer = None
+		
+		self.offset_slider = {}
+		self.offset_slider['x'] = False
+		self.offset_slider['y'] = False
 		
 		self.imagepool = engine.getImagePool()
 		self.animationpool = engine.getAnimationPool()
-			
-		self._camera = None
-		self._layer = None
 		
 		self.guidata = {}
 		self.objectdata = {}
@@ -80,7 +85,6 @@
 		self._reset()		
 		self.create_gui()
 
-	
 	def _reset(self):
 		"""
 			resets all dynamic vars, but leaves out static ones (e.g. camera, layer)
@@ -88,6 +92,8 @@
 		"""
 		self._instances = None
 		self._image = None
+		self._image_default_x_offset = None
+		self._image_default_y_offset = None
 		self._animation = False
 		self._rotation = None
 		self._avail_rotations = []
@@ -98,15 +104,6 @@
 		self._instance_id = None
 		self._fixed_rotation = None
 		
-		self.guidata['instance_id'] = 'None'
-		self.guidata['object_id'] = 'None'
-		self.guidata['x_offset'] = 0
-		self.guidata['y_offset'] = 0
-		self.guidata['instance_rotation'] = 0
-		self.guidata['namespace'] = 'None'
-		self.guidata['blocking'] = 0
-		self.guidata['static'] = 0
-		
 		if self._camera is not None:
 			self.renderer.removeAllOutlines()		
 		
@@ -115,7 +112,7 @@
 			- creates the gui skeleton by loading the xml file
 			- finds some important childs and saves their widget in the object
 		"""
-		self.container = pychan.loadXML('gui/offsetedit.xml')
+		self.container = pychan.loadXML('gui/objectedit.xml')
 		self.container.mapEvents({
 			'x_offset_up' 	: cbwa(self.change_offset_x, 1),
 			'x_offset_dn' 	: cbwa(self.change_offset_x, -1),
@@ -123,9 +120,11 @@
 			'y_offset_up' 	: cbwa(self.change_offset_y, 1),
 			'y_offset_dn' 	: cbwa(self.change_offset_y, -1),
 			
-			'use_data'		: cbwa(self.use_user_data),
-			'previous_data' : cbwa(self.load_previous_data),
-			'default_data'	: cbwa(self.load_default_data)
+			'x_offset_slider' : cbwa(self.get_slider_value, "x"),
+			'y_offset_slider' : cbwa(self.get_slider_value, "y"),
+			
+			'use_data'		: self.use_user_data,
+			
 		})
 
 		self._gui_anim_panel_wrapper = self.container.findChild(name="animation_panel_wrapper")
@@ -137,6 +136,50 @@
 		
 		self._gui_xoffset_textfield = self.container.findChild(name="x_offset")
 		self._gui_yoffset_textfield = self.container.findChild(name="y_offset")
+		
+		self._gui_instance_id_textfield = self.container.findChild(name="instance_id")
+		
+		print "Steplength x slider", self.container.findChild(name="x_offset_slider").getStepLength()
+		print "Steplength y slider", self.container.findChild(name="y_offset_slider").getStepLength()
+		self.container.findChild(name="x_offset_slider").setStepLength(0.01)
+		self.container.findChild(name="y_offset_slider").setStepLength(0.01)
+		print "New steplength x slider", self.container.findChild(name="x_offset_slider").getStepLength()
+		print "New steplength y slider", self.container.findChild(name="y_offset_slider").getStepLength()
+		
+	def get_slider_value(self, orientation):
+		""" get current slider value for offset manipulation """
+		
+		slider_name = orientation + "_offset_slider"
+		widget = self.container.findChild(name=slider_name)
+		value = widget.getValue()
+
+		print "%s slider value: %s" % (orientation, str(value))
+		
+		if value < 0: 
+			self.offset_slider[orientation] = False
+			return
+		
+		callback = getattr(self, "change_offset_" + orientation)
+
+		if self.offset_slider[orientation] == widget.getScaleStart():
+			self.set_default_offset(orientation)
+			self.offset_slider[orientation] = False
+			return	
+		elif self.offset_slider[orientation] >= widget.getScaleEnd():
+			pass
+		elif self.offset_slider[orientation] < value:
+			callback(1)
+		elif self.offset_slider[orientation] > value :
+			callback(-1)
+
+		self.offset_slider[orientation] = value
+
+	def set_default_offset(self, axis):
+		""" set default image offset for given axis """
+		if axis == 'x':
+			self._image.setXShift(self._image_default_x_offset)
+		elif axis == 'y':
+			self._image.setYShift(self._image_default_y_offset)
 
 	def _get_gui_size(self):
 		"""
@@ -165,17 +208,17 @@
 				#self._gui_anim_panel_wrapper.resizeToContent()
 			#except:
 				#pass
-		
+
 		self.container.distributeInitialData({
 			'select_rotations' 	: self._avail_rotations,
-			'instance_id'		: self.guidata['instance_id'],
-			'object_id'			: self.guidata['object_id'],
-			'x_offset'			: self.guidata['x_offset'],
-			'y_offset'			: self.guidata['y_offset'],
-			'instance_rotation' : self.guidata['instance_rotation'],
-			'object_namespace'	: self.guidata['namespace'],
-			'object_blocking'	: self.guidata['blocking'],
-			'object_static'		: self.guidata['static'],
+			'instance_id'		: str( self._instances[0].getId() ),
+			'object_id'			: str( self._object_id ),
+			'x_offset'			: str( self._image.getXShift() ),
+			'y_offset'			: str( self._image.getYShift() ),
+			'instance_rotation' : str( self._instances[0].getRotation() ),
+			'object_namespace'	: str( self._namespace ),
+			'object_blocking'	: str( self._blocking ),
+			'object_static'		: str( self._static ),
 		})
 		try:
 			print self._avail_rotations
@@ -224,12 +267,11 @@
 			- changes x offset of current instance (image)
 			- updates gui
 			
-			@param	int		value	the modifier for the x offset
+			@type	value:	int
+			@param	value:	the modifier for the x offset
 		"""		
 		if self._image is not None:
 			self._image.setXShift(self._image.getXShift() + value)
-			
-			self.guidata['x_offset'] = str( self._image.getXShift() )
 			self.update_gui()
 
 	def change_offset_y(self, value=1):
@@ -238,12 +280,11 @@
 			- changes y offset of current instance (image)
 			- updates gui
 			
-			@param	int		value	the modifier for the y offset
+			@type	value:	int
+			@param	value:	the modifier for the y offset
 		"""
 		if self._image is not None:
 			self._image.setYShift(self._image.getYShift() + value)
-			
-			self.guidata['y_offset'] = str( self._image.getYShift() )
 			self.update_gui()
 
 	def use_user_data(self):
@@ -259,6 +300,16 @@
 		xoffset = self._gui_xoffset_textfield._getText()
 		yoffset = self._gui_yoffset_textfield._getText()
 		
+		instance_id = self._gui_instance_id_textfield._getText()
+		if instance_id is not None and instance_id is not "None":
+			existing_instances = self._mapedit._layer.getInstances(instance_id)
+			if existing_instances == ():
+				self._instances[0].setId(instance_id)
+				print "Set new instance id: ", instance_id		
+			else:
+				for i in existing_instances:
+					print i
+		
 		# workaround - dropdown list only has 2 entries, but sends 3 -> pychan bug?
 		if len(self._avail_rotations) < self._gui_rotation_dropdown._getSelected():
 			index = len(self._avail_rotations)
@@ -284,79 +335,9 @@
 		except:
 			pass
 #		print "y offset must be of type int!"
-		
-		self.write_current_data()
-		self.objectdata[self._namespace][self._object_id]['previous'] = self.objectdata[self._namespace][self._object_id]['current'].copy()
-		self.update_gui()
-		
-	def load_previous_data(self):
-		"""
-			- writes a copy of the previous record back to the current record (aka one-step-undo)
-			- loads current data into class object
-			- updates gui
-		"""
-		self.objectdata[self._namespace][self._object_id]['current'] = self.objectdata[self._namespace][self._object_id]['previous'].copy()
-		self.load_current_data()
+
 		self.update_gui()
 		
-	def load_default_data(self):
-		"""
-			- writes a copy of the default record back to the current record
-			- loads current data into class object
-			- updates gui			
-		"""
-		self.objectdata[self._namespace][self._object_id]['current'] = self.objectdata[self._namespace][self._object_id]['default'].copy()
-		self.load_current_data()
-		self.update_gui()
-
-	def load_current_data(self):
-		"""
-			loads the current record into class object
-		"""
-		self._image = self.objectdata[self._namespace][self._object_id]['current']['image']
-		self._animation = self.objectdata[self._namespace][self._object_id]['current']['animation']
-		self._rotation = self.objectdata[self._namespace][self._object_id]['current']['rotation']
-		self._fixed_rotation = self.objectdata[self._namespace][self._object_id]['current']['fixed_rotation']
-		self._avail_rotations = self.objectdata[self._namespace][self._object_id]['current']['avail_rotations']
-		self._blocking = self.objectdata[self._namespace][self._object_id]['current']['blocking']
-		self._static = self.objectdata[self._namespace][self._object_id]['current']['static']
-		self._instance_id = self.objectdata[self._namespace][self._object_id]['current']['instance_id']
-		self._image.setXShift( self.objectdata[self._namespace][self._object_id]['current']['xoffset'] )
-		self._image.setYShift( self.objectdata[self._namespace][self._object_id]['current']['yoffset'] )
-		
-		self.write_current_guidata()
-		
-	def write_current_data(self):
-		"""
-			updates the current record
-		"""
-		self.objectdata[self._namespace][self._object_id]['current']['instance'] = self._instances[0]
-		self.objectdata[self._namespace][self._object_id]['current']['image'] = self._image
-		self.objectdata[self._namespace][self._object_id]['current']['animation'] = self._animation
-		self.objectdata[self._namespace][self._object_id]['current']['rotation'] = self._rotation
-		self.objectdata[self._namespace][self._object_id]['current']['fixed_rotation'] = self._fixed_rotation
-		self.objectdata[self._namespace][self._object_id]['current']['avail_rotations'] = self._avail_rotations
-		self.objectdata[self._namespace][self._object_id]['current']['blocking'] = self._blocking
-		self.objectdata[self._namespace][self._object_id]['current']['static'] = self._static
-		self.objectdata[self._namespace][self._object_id]['current']['instance_id'] = self._instance_id
-		self.objectdata[self._namespace][self._object_id]['current']['xoffset'] = self._image.getXShift()
-		self.objectdata[self._namespace][self._object_id]['current']['yoffset'] = self._image.getYShift()
-		
-		self.write_current_guidata()
-		
-	def write_current_guidata(self):
-		"""
-			updates the gui data with
-		"""		
-		self.guidata['instance_rotation'] = str( self._instances[0].getRotation() )		
-		self.guidata['object_id'] = str( self._object_id )
-		self.guidata['instance_id'] = str( self._instance_id )
-		self.guidata['x_offset'] = str( self._image.getXShift() )
-		self.guidata['y_offset'] = str( self._image.getYShift() )
-		self.guidata['namespace'] = self._namespace	
-		self.guidata['blocking'] = str( self._blocking )
-		self.guidata['static'] = str( self._static )		
-			
 	def get_instance_data(self, timestamp=None, frame=None, angle=-1, instance=None):
 		"""
 			- grabs all available data from both object and instance
@@ -377,105 +358,69 @@
 		self._namespace = object.getNamespace()
 		self._object_id = object.getId()
 
-		if angle != -1:
-			del self.objectdata[self._namespace][self._object_id]
-		
-		if not self.objectdata.has_key(self._namespace):
-			self.objectdata[self._namespace] = {}
-		
-		if not self.objectdata[self._namespace].has_key(self._object_id):
-			self.objectdata[self._namespace][self._object_id] = {}
-			
-			# we hold 3 versions of the data: current, previous, default
-			# default is only set one time, current and previous are changing data
-			# due to the users actions
-			self.objectdata[self._namespace][self._object_id]['current'] = {}
-			self.objectdata[self._namespace][self._object_id]['previous'] = {}
+		self._instance_id = instance.getId()
+	
+		if self._instance_id == '':
+			self._instance_id = 'None'
+
+		if angle == -1:
+			angle = int(instance.getRotation())
+		else:
+			angle = int(angle)	
 			
-			self._instance_id = instance.getId()
+		self._rotation = angle
 		
-			if self._instance_id == '':
-				self._instance_id = 'None'
-
-			if angle == -1:
-				angle = int(instance.getRotation())
-			else:
-				angle = int(angle)	
-				
-			self._rotation = angle
-			
-			if object.isBlocking():
-				self._blocking = 1
-				
-			if object.isStatic():
-				self._static = 1
+		if object.isBlocking():
+			self._blocking = 1
 			
-			try:
-				visual = object.get2dGfxVisual()
-			except:
-				print 'Fetching visual of object - failed. :/'
-				raise			
+		if object.isStatic():
+			self._static = 1
+		
+		try:
+			visual = object.get2dGfxVisual()
+		except:
+			print 'Fetching visual of object - failed. :/'
+			raise			
 
-			self._fixed_rotation = int(instance.getRotation() + abs( self._camera.getTilt() ) )		
-			self._fixed_rotation = visual.getClosestMatchingAngle(self._fixed_rotation)	
+#		print "Camera Tilt: ", self._camera.getTilt()
+#		print "Camera Rotation: ", self._camera.getRotation()
 
-			index = visual.getStaticImageIndexByAngle(self._fixed_rotation)
+		self._fixed_rotation = int(instance.getRotation() + abs( self._camera.getTilt() ) )		
+		self._fixed_rotation = visual.getClosestMatchingAngle(self._fixed_rotation)	
+
+		index = visual.getStaticImageIndexByAngle(self._fixed_rotation)
 
-			if index == -1:
-				# object is an animation
-				self._animation = True
-				# no static image available, try default action
-				action = object.getDefaultAction()
-				if action:
-					animation_id = action.get2dGfxVisual().getAnimationIndexByAngle(self._fixed_rotation)
-					animation = self.animationpool.getAnimation(animation_id)
-					if timestamp is None and frame is not None:
-						self._image = animation.getFrame(frame)	
-					elif timestamp is not None and frame is None:
-						self._image = animation.getFrameByTimestamp(timestamp)
-					else:
-						self._image = animation.getFrameByTimestamp(0)
-					index = self._image.getPoolId()
-			elif index != -1:
-				# object is a static image
-				self._animation = False
-				self._image = self.imagepool.getImage(index)
+		if index == -1:
+			# object is an animation
+			self._animation = True
+			# no static image available, try default action
+			action = object.getDefaultAction()
+			if action:
+				animation_id = action.get2dGfxVisual().getAnimationIndexByAngle(self._fixed_rotation)
+				animation = self.animationpool.getAnimation(animation_id)
+#				if timestamp is None and frame is not None:
+#					self._image = animation.getFrame(frame)	
+#				elif timestamp is not None and frame is None:
+#					self._image = animation.getFrameByTimestamp(timestamp)
+#				else:
+				self._image = animation.getFrameByTimestamp(0)
+				index = self._image.getPoolId()
+		elif index != -1:
+			# object is a static image
+			self._animation = False
+			self._image = self.imagepool.getImage(index)
 
-			if self._animation:
-				self._avail_rotations = Settings.RotAngles['animations']
-			else:
-				rotation_tuple = visual.getStaticImageAngles()
-				for angle in rotation_tuple:
-					self._avail_rotations.append( str(angle) )
+		if not self._animation:
+			rotation_tuple = visual.getStaticImageAngles()
+			for angle in rotation_tuple:
+				self._avail_rotations.append( str(angle) )
+				
+		self._image_default_x_offset = self._image.getXShift()
+		self._image_default_y_offset = self._image.getYShift()
 
 # FIXME: see l. 40
-			self._mapedit._objectedit_rotations = self._avail_rotations
+		self._mapedit._objectedit_rotations = self._avail_rotations
 # end FIXME
-			self.write_current_data()
-			
-			self.objectdata[self._namespace][self._object_id]['default'] = {}
-			self.objectdata[self._namespace][self._object_id]['default'] = self.objectdata[self._namespace][self._object_id]['current'].copy()
-			self.objectdata[self._namespace][self._object_id]['previous'] = self.objectdata[self._namespace][self._object_id]['current'].copy()
-			
-			self.write_current_guidata()
-		else:
-			self.load_current_data()
-
-	def dump_objectdata(self):
-		"""
-			just a useful dumper ^^
-		"""
-		print "#"*4, "Dump of objectdata", "#"*4, "\n" 
-		for namespace in self.objectdata:
-			print "namespace: ", namespace
-			for key in self.objectdata[namespace]:
-				print "\tkey: ", key
-				for item in self.objectdata[namespace][key]:
-					if len(item) >= 9:
-						tab = "\t"*1
-					else:
-						tab = "\t"*2
-					print "\t\t", item, " : ", tab, self.objectdata[namespace][key][item]
 		
 	def input(self):
 		"""
@@ -486,6 +431,7 @@
 		"""
 		if self._mapedit._instances != self._instances:
 			if self.active is True:
+				self._reset()
 				self._instances = self._mapedit._instances
 				
 				if self._camera is None:
@@ -497,17 +443,11 @@
 				if self._instances != ():
 					self.highlight_selected_instance()
 					self.get_instance_data()
-					
-					if self._animation is False:
-						self.update_gui()
-						self.container.adaptLayout()
-						self.container.show()
-						self._get_gui_size()
-						self.container._setPosition(self.position)
-					else:
-						self.container.hide()
-						print "Animation objects are not yet editable"
-#					self.dump_objectdata()
+					self.update_gui()
+					self.container.adaptLayout()
+					self.container.show()
+					self._get_gui_size()
+					self.container._setPosition(self.position)
 				else:
 					self._reset()
 					self.container.hide()
--- a/clients/editor/settings.py	Mon Mar 16 01:23:03 2009 +0000
+++ b/clients/editor/settings.py	Mon Mar 16 14:40:36 2009 +0000
@@ -16,12 +16,3 @@
 
 WindowTitle			= 'FIFE - Editor client'
 WindowIcon			= ''
-
-#offset editor:
-RotAngles = {}
-# zero-projekt angles
-#RotAngles['animations'] = ["0", "60", "120", "180", "240", "300"]
-# rio de hola angles
-RotAngles['animations'] = ["0", "45", "90", "135", "180", "225", "270", "315"]
-
-