changeset 332:457e626296ba

Working on the XXX_image attributes to force consistent behaviour - this needs a double check. Failed to reproduce #355.
author phoku@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 24 Aug 2009 13:23:03 +0000
parents 48c99636453e
children fee958103d58
files engine/extensions/pychan/properties.py engine/extensions/pychan/widgets/buttons.py
diffstat 2 files changed, 79 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/engine/extensions/pychan/properties.py	Mon Aug 24 12:01:34 2009 +0000
+++ b/engine/extensions/pychan/properties.py	Mon Aug 24 13:23:03 2009 +0000
@@ -23,6 +23,11 @@
 # ####################################################################
 
 import fife
+from exceptions import RuntimeError
+
+def get_manager():
+	import pychan
+	return pychan.manager
 
 """
 Property bindings
@@ -64,3 +69,40 @@
 		color = self._getGetter(obj)()
 		return fife.Color(color.r,color.g,color.b,color.a)
 
+class DummyImage(object):
+	def getWidth(self): return 0
+	def getHeight(self): return 0
+
+class ImageProperty(WrappedProperty):
+	def __init__(self, name):
+		super(ImageProperty, self).__init__(name)
+		self.prop_name = "_prop_" + self.name.lower()
+	def __set__(self, obj, image):
+		image_info = getattr(obj, self.prop_name, {})
+		if not image:
+			image_info["source"] = ""
+			image_info["image"] = DummyImage()
+			self._getSetter(obj)(None)
+
+		elif isinstance(image, str):
+			image_info["source"] = image
+			# to catch or not to catch ...
+			# we just let the NotFound exception trickle here.
+			# depedning on complains we can catch and print a warning.
+			image_info["image"] = get_manager().loadImage(image)
+			self._getSetter(obj)(image_info["image"])
+
+		elif isinstance(image,fife.GuiImage):
+			image_info["source"] = None
+			image_info["image"] = image
+			self._getSetter(obj)(image_info["image"])
+		else:
+			attribute_name = "%s.%s" % (obj.__class__.__name__,self.name)
+			error_message = "%s only accepts GuiImage and python strings, not '%s'"
+			raise RuntimeError(error_message % (attribute_name, repr(source)))
+		
+		setattr(obj, self.prop_name, image_info)
+
+	def __get__(self, obj, objtype = None):
+		return getattr(obj, self.prop_name, {}).get("image",None)
+
--- a/engine/extensions/pychan/widgets/buttons.py	Mon Aug 24 12:01:34 2009 +0000
+++ b/engine/extensions/pychan/widgets/buttons.py	Mon Aug 24 13:23:03 2009 +0000
@@ -24,6 +24,7 @@
 
 from common import *
 from basictextwidget import BasicTextWidget
+from pychan.properties import ImageProperty
 
 class Button(BasicTextWidget):
 	"""
@@ -50,7 +51,7 @@
 	ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [Attr('up_image'),Attr('down_image'),PointAttr('offset'),Attr('hover_image')]
 
 	def __init__(self,up_image="",down_image="",hover_image="",offset=(0,0),**kwargs):
-		self.real_widget = fife.TwoButton()
+		self.real_widget = kwargs.get("real_widget", fife.TwoButton())
 		super(ImageButton,self).__init__(**kwargs)
 
 		self.up_image = up_image
@@ -58,63 +59,9 @@
 		self.hover_image = hover_image
 		self.offset = offset
 
-	def _setUpImage(self, source):
-		if isinstance(source,str):
-			self._upimage_source = source
-			try:
-				self._upimage = get_manager().loadImage(source)
-				self.real_widget.setUpImage( self._upimage )
-			except:
-				self._upimage = DummyImage()
-		elif isinstance(source,fife.GuiImage):
-			self._upimage_source = None
-			self._upimage = source
-			self.real_widget.setUpImage( self._upimage )
-		else:
-			raise RuntimeError("Icon.image only accepts GuiImage and python strings, not '%s'" % repr(source))
-
-		# Set minimum size accoriding to image
-		self.min_size = self.real_widget.getWidth(),self.real_widget.getHeight()
-		self.size  = self.max_size = self.min_size
-
-	def _getUpImage(self): return self._upimage_source
-	up_image = property(_getUpImage,_setUpImage)
-
-	def _setDownImage(self, source):
-		if isinstance(source,str):
-			self._downimage_source = source
-			try:
-				self._downimage = get_manager().loadImage(source)
-				self.real_widget.setDownImage( self._downimage )
-			except:
-				self._downimage = DummyImage()
-		elif isinstance(source,fife.GuiImage):
-			self._downimage_source = None
-			self._downimage = source
-			self.real_widget.setDownImage( self._downimage )
-		else:
-			raise RuntimeError("Icon.image only accepts GuiImage and python strings, not '%s'" % repr(source))
-
-	def _getDownImage(self): return self._downimage_source
-	down_image = property(_getDownImage,_setDownImage)
-
-	def _setHoverImage(self, source):
-		if isinstance(source, str):
-			self._hoverimage_source = source
-			try:
-				self._hoverimage = get_manager().loadImage(source)
-				self.real_widget.setHoverImage( self._hoverimage )
-			except:
-				self._hoverimage = DummyImage()
-		elif isinstance(source,fife.GuiImage):
-			self._hoverimage_source = None
-			self._hoverimage = source
-			self.real_widget.setHoverImage( self._hoverimage )
-		else:
-			raise RuntimeError("Icon.image only accepts GuiImage and python strings, not '%s'" % repr(source))
-
-	def _getHoverImage(self): return self._hoverimage_source
-	hover_image = property(_getHoverImage,_setHoverImage)
+	up_image = ImageProperty("UpImage")
+	down_image = ImageProperty("DownImage")
+	hover_image = ImageProperty("HoverImage")
 
 	def _setOffset(self, offset):
 		self.real_widget.setDownOffset(offset[0], offset[1])
@@ -123,10 +70,22 @@
 	offset = property(_getOffset,_setOffset)
 
 	def resizeToContent(self, recurse=True):
-		self.height = max(self._upimage.getHeight(),self._downimage.getHeight(),self._hoverimage.getHeight()) + self.margins[1]*2
-		self.width = max(self._upimage.getWidth(),self._downimage.getWidth(),self._hoverimage.getWidth()) + self.margins[0]*2
+		th, tw = 0, 0
+		if self.text:
+			th = self.real_font.getHeight()#+self.real_font.getSpacing()
+			tw = self.real_font.getWidth(text2gui(self.text))#+self.real_font.getSpacing()
+		self.height = max(
+			self._prop_upimage["image"].getHeight(),
+			self._prop_downimage["image"].getHeight(),
+			self._prop_hoverimage["image"].getHeight(),
+			th) + self.margins[1]*2
+		self.width = max(
+			self._prop_upimage["image"].getWidth(),
+			self._prop_downimage["image"].getWidth(),
+			self._prop_hoverimage["image"].getWidth(),
+			tw) + self.margins[0]*2
 
-class ToggleButton(BasicTextWidget):
+class ToggleButton(ImageButton):
 	"""
 	A basic push button that can be toggled.
 
@@ -144,15 +103,10 @@
 		PointAttr('offset'),Attr('group')
 	]
 
-	def __init__(self,up_image="",down_image="",hover_image="",offset=(0,0),group="",**kwargs):
+	def __init__(self,group="",**kwargs):
 
-		self.real_widget = fife.ToggleButton()
-		super(ToggleButton,self).__init__(**kwargs)
+		super(ToggleButton,self).__init__(real_widget = fife.ToggleButton(), **kwargs)
 		self.group = group
-		self.up_image = up_image
-		self.down_image = down_image
-		self.hover_image = hover_image
-		self.offset = offset
 
 	def _setGroup(self,group):
 		self.real_widget.setGroup( group )
@@ -168,48 +122,19 @@
 		return self.real_widget.isToggled()
 	toggled = property(_isToggled, _setToggled)
 
-	###
-	# I didn't want to do this, but this is just cut and paste from the ImageButton class:
-	###
-
-	def _setUpImage(self,image):
-		self._upimage_source = image
-		try:
-			self._upimage = get_manager().loadImage(image)
-			self.real_widget.setUpImage( self._upimage )
-		except:
-			self._upimage = DummyImage()
-	def _getUpImage(self): return self._upimage_source
-	up_image = property(_getUpImage,_setUpImage)
-
-	def _setDownImage(self,image):
-		self._downimage_source = image
-		try:
-			self._downimage = get_manager().loadImage(image)
-			self.real_widget.setDownImage( self._downimage )
-		except:
-			self._downimage = DummyImage()
-	def _getDownImage(self): return self._downimage_source
-	down_image = property(_getDownImage,_setDownImage)
-
-	def _setHoverImage(self,image):
-		self._hoverimage_source = image
-		try:
-			self._hoverimage = get_manager().loadImage(image)
-			self.real_widget.setHoverImage( self._hoverimage )
-		except:
-			self._hoverimage = DummyImage()
-	def _getHoverImage(self): return self._hoverimage_source
-	hover_image = property(_getHoverImage,_setHoverImage)
-
-	def _setOffset(self, offset):
-		self.real_widget.setDownOffset(offset[0], offset[1])
-	def _getOffset(self):
-		return (self.real_widget.getDownXOffset(), self.real_widget.getDownYOffset())
-	offset = property(_getOffset,_setOffset)
-
 	def resizeToContent(self, recurse=True):
-		th = self.real_font.getHeight()+self.real_widget.getSpacing()
-		tw = self.real_font.getWidth(text2gui(self.text))+self.real_widget.getSpacing()
-		self.height = max(self._upimage.getHeight(),self._downimage.getHeight(),self._hoverimage.getHeight(),th) + self.margins[1]*2
-		self.width = max(self._upimage.getWidth(),self._downimage.getWidth(),self._hoverimage.getWidth(),tw) + self.margins[0]*2
+		# NOTE: Figure out how the spacing comes into play
+		tw, th = 0, 0
+		if self.text:
+			th = self.real_font.getHeight() + self.real_widget.getSpacing()
+			tw = self.real_font.getWidth(text2gui(self.text)) + self.real_widget.getSpacing()
+		self.height = max(
+			self._prop_upimage["image"].getHeight(),
+			self._prop_downimage["image"].getHeight(),
+			self._prop_hoverimage["image"].getHeight(),
+			th) + self.margins[1]*2
+		self.width = max(
+			self._prop_upimage["image"].getWidth(),
+			self._prop_downimage["image"].getWidth(),
+			self._prop_hoverimage["image"].getWidth(),
+			tw) + self.margins[0]*2