changeset 194:9631a2958851

* Object selector can now be toggled to use either the old list format or show preview images. * Fixed a small bug in ScrollArea.removeChild() fife.ScrollArea.setContent(None) does not work, so the client would crash on calling that function. I now set an empty pychan.Container. There might be a better way to do this.
author nihathrael@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 01 Mar 2009 10:59:17 +0000
parents 9661d611b346
children 13e5be34484e
files clients/editor/plugins/objectselector.py engine/extensions/pychan/widgets.py
diffstat 2 files changed, 99 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/clients/editor/plugins/objectselector.py	Sun Mar 01 00:04:58 2009 +0000
+++ b/clients/editor/plugins/objectselector.py	Sun Mar 01 10:59:17 2009 +0000
@@ -14,6 +14,7 @@
 		self.engine = engine
 		self.map = map
 		self.notify = selectNotify
+		self.mode = 'list' # Other mode is 'preview'
 
 		self.buildGui()
 
@@ -27,56 +28,80 @@
 		scrollArea = widgets.ScrollArea(size=(200,300))
 		hbox.addChild(scrollArea)
 		self.namespaces = widgets.ListBox()
-		self.namespaces.capture(self.fillList)
+		self.namespaces.capture(self.update)
 		self.namespaces.items = self.engine.getModel().getNamespaces()
 		self.namespaces.selected = 0
 		scrollArea.addChild(self.namespaces)
 
 		# This Vbox is used to display the preview images
+		self.mainScrollArea = widgets.ScrollArea(size=(200,300))
+		self.objects = None
+		if self.mode == 'list':
+			self.setTextList()
+		else: # Assuming self.mode is 'preview'
+			self.setImageList()
+		hbox.addChild(self.mainScrollArea)
+
+		# This is the preview area
 		scrollArea = widgets.ScrollArea(size=(200,300))
-		self.objects = widgets.VBox(size=(200,300))
-		scrollArea.addChild(self.objects)
 		hbox.addChild(scrollArea)
+		self.preview = widgets.Icon()
+		scrollArea.addChild(self.preview)
 
 		# Add another Hbox to hold the close button
 		hbox = widgets.HBox(parent=self.gui)
 		self.gui.addChild(hbox)
 		hbox.addSpacer(widgets.Spacer())
+		toggleButton = widgets.Button(text="Toggle Preview Mode")
+		toggleButton.capture(self.toggleMode)
+		hbox.addChild(toggleButton)
 		closeButton = widgets.Button(text="Close")
 		closeButton.capture(self.hide)
 		hbox.addChild(closeButton)
 
-
-	def update(self):
-		self.namespaces.items = self.engine.getModel().getNamespaces()
-		self.namespaces.selected = 0
-		self.fillList()
+	def toggleMode(self):
+		if self.mode == 'list':
+			self.setImageList()
+			self.mode = 'preview'
+		elif self.mode == 'preview':
+			self.setTextList()
+			self.mode = 'list'
+		self.update()
 
-	def fillList(self):
-		for obj in self.engine.getModel().getObjects(self.namespaces.selected_item):
-			# Find visual for the object
-			visual = None
-			try:
-				visual = obj.get2dGfxVisual()
-			except:
-				print 'Visual Selection created for type without a visual?'
-				raise
+
+	def setImageList(self):
+		"""Sets the mainScrollArea to contain a Vbox that can be used to fill in
+		preview Images"""
+		if self.objects is not None:
+			self.mainScrollArea.removeChild(self.objects)
+		self.objects = widgets.VBox(name='list', size=(200,300))
+		self.mainScrollArea.addChild(self.objects)
 
-			# Try to find a usable image
-			index = visual.getStaticImageIndexByAngle(0)
+	def setTextList(self):
+		"""Sets the mainScrollArea to contain a List that can be used to fill in
+		Object names/paths"""
+		if self.objects is not None:
+			self.mainScrollArea.removeChild(self.objects)
+		self.objects = widgets.ListBox(name='list')
+		self.objects.capture(self.listEntrySelected)
+		self.mainScrollArea.addChild(self.objects)
 
-			# if no static image available, try default action
-			if index == -1:
-				action = obj.getDefaultAction()
-				if action:
-					animation_id = action.get2dGfxVisual().getAnimationIndexByAngle(0)
-					animation = self.engine.getAnimationPool().getAnimation(animation_id)
-					image = animation.getFrameByTimestamp(0)
-					index = image.getPoolId()
+	def fillTextList(self):
+		if self.namespaces.selected_item:
+			self.objects.items = [obj.getId() for obj in self.engine.getModel().getObjects(self.namespaces.selected_item)]
+			if not self.objects.selected_item:
+				self.objects.selected = 0
 
-			# Use the hopefully found image to set up the imagebutton
-			if index != -1:
-				image = fife.GuiImage(index, self.engine.getImagePool())
+	def listEntrySelected(self):
+		"""This function is used as callback for the TextList."""
+		if self.objects.selected_item:
+			obj = self.engine.getModel().getObject(self.objects.selected_item, self.namespaces.selected_item)
+			self.objectSelected(obj)
+
+	def fillPreviewList(self):
+		for obj in self.engine.getModel().getObjects(self.namespaces.selected_item):
+			image = self._getImage(obj)
+			if image is not None:
 				imagebutton = widgets.ImageButton(up_image=image, down_image=image, hover_image=image)
 				imagebutton.capture(tools.callbackWithArguments(self.objectSelected, obj))
 				self.objects.addChild(imagebutton)
@@ -89,8 +114,49 @@
 		"""This is used as callback function to notify the editor that a new object has
 		been selected.
 		@param obj: fife.Object instance"""
+		self.preview.image = self._getImage(obj)
 		self.notify(obj)
 
+	def update(self):
+		self.namespaces.items = self.engine.getModel().getNamespaces()
+		self.namespaces.selected = 0
+		if self.mode == 'list':
+			self.fillTextList()
+		elif self.mode == 'preview':
+			self.fillPreviewList()
+
+		self.mainScrollArea.resizeToContent()
+
+	def _getImage(self, obj):
+		""" Returs an image for the given object.
+		@param: fife.Object for which an image is to be returned
+		@return: fife.GuiImage"""
+		visual = None
+		try:
+			visual = obj.get2dGfxVisual()
+		except:
+			print 'Visual Selection created for type without a visual?'
+			raise
+
+		# Try to find a usable image
+		index = visual.getStaticImageIndexByAngle(0)
+		image = None
+		# if no static image available, try default action
+		if index == -1:
+			action = obj.getDefaultAction()
+			if action:
+				animation_id = action.get2dGfxVisual().getAnimationIndexByAngle(0)
+				animation = self.engine.getAnimationPool().getAnimation(animation_id)
+				image = animation.getFrameByTimestamp(0)
+				index = image.getPoolId()
+
+		# Construct the new GuiImage that is to be returned
+		if index != -1:
+			image = fife.GuiImage(index, self.engine.getImagePool())
+
+		return image
+
+
 	def show(self):
 		self.update()
 		self.gui.show()
--- a/engine/extensions/pychan/widgets.py	Sun Mar 01 00:04:58 2009 +0000
+++ b/engine/extensions/pychan/widgets.py	Sun Mar 01 10:59:17 2009 +0000
@@ -1660,7 +1660,9 @@
 	def removeChild(self,widget):
 		if self._content != widget:
 			raise RuntimeError("%s does not have %s as direct child widget." % (str(self),str(widget)))
-		self.content = None
+		# Set a Container here, as this can not be set to None
+		# Might be possible to find a better solution, needs peer review
+		self.content = Container()
 		widget.parent = None
 
 	def _setContent(self,content):