comparison engine/extensions/pychan/widgets.py @ 188:06dddc96ce54

* Fixed some space and tab mixing * Fixed a small bug in manager.py, thanks to phoku for the pointer.
author nihathrael@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 26 Feb 2009 11:26:01 +0000
parents 3fb17daa1b27
children bec4b69ad83a
comparison
equal deleted inserted replaced
187:644bf7ca1e0a 188:06dddc96ce54
12 import events 12 import events
13 from exceptions import * 13 from exceptions import *
14 from attrs import Attr,PointAttr,ColorAttr,BoolAttr,IntAttr,FloatAttr 14 from attrs import Attr,PointAttr,ColorAttr,BoolAttr,IntAttr,FloatAttr
15 15
16 def get_manager(): 16 def get_manager():
17 import pychan 17 import pychan
18 return pychan.manager 18 return pychan.manager
19 19
20 def _mungeText(text): 20 def _mungeText(text):
21 """ 21 """
22 This function is applied to all text set on widgets, currently only replacing tabs with four spaces. 22 This function is applied to all text set on widgets, currently only replacing tabs with four spaces.
23 """ 23 """
88 ] 88 ]
89 89
90 DEFAULT_NAME = '__unnamed__' 90 DEFAULT_NAME = '__unnamed__'
91 91
92 HIDE_SHOW_ERROR = """\ 92 HIDE_SHOW_ERROR = """\
93 You can only show/hide the top widget of a hierachy. 93 You can only show/hide the top widget of a hierachy.
94 Use 'addChild' or 'removeChild' to add/remove labels for example. 94 Use 'addChild' or 'removeChild' to add/remove labels for example.
95 """ 95 """
96 96
97 def __init__(self,parent = None, name = DEFAULT_NAME, 97 def __init__(self,parent = None, name = DEFAULT_NAME,
98 size = (-1,-1), min_size=(0,0), max_size=(5000,5000), 98 size = (-1,-1), min_size=(0,0), max_size=(5000,5000),
99 style = None, **kwargs): 99 style = None, **kwargs):
100 100
101 assert( hasattr(self,'real_widget') ) 101 assert( hasattr(self,'real_widget') )
102 self.event_mapper = events.EventMapper(self) 102 self.event_mapper = events.EventMapper(self)
103 self._visible = False 103 self._visible = False
104 104
105 # Data distribution & retrieval settings 105 # Data distribution & retrieval settings
167 return True 167 return True
168 168
169 def capture(self, callback, event_name="action", group_name="default"): 169 def capture(self, callback, event_name="action", group_name="default"):
170 """ 170 """
171 Add a callback to be executed when the widget event occurs on this widget. 171 Add a callback to be executed when the widget event occurs on this widget.
172 172
173 The callback must be either a callable or None. 173 The callback must be either a callable or None.
174 The old event handler (if any) will be overridden by the callback. 174 The old event handler (if any) will be overridden by the callback.
175 If None is given, the event will be disabled. You can query L{isCaptured} 175 If None is given, the event will be disabled. You can query L{isCaptured}
176 wether this widgets events are currently captured. 176 wether this widgets events are currently captured.
177 177
233 233
234 To make this clear consider this arrangement:: 234 To make this clear consider this arrangement::
235 VBox 1 235 VBox 1
236 - Container 236 - Container
237 - VBox 2 237 - VBox 2
238 - HBox 238 - HBox
239 - Label 239 - Label
240 240
241 If you call adaptLayout on the Label the layout from the VBox 2 241 If you call adaptLayout on the Label the layout from the VBox 2
242 will get recalculated, while the VBox 1 stays untouched. 242 will get recalculated, while the VBox 1 stays untouched.
243 243
244 @param recurse Pass False here to force the layout to start from 244 @param recurse Pass False here to force the layout to start from
245 this widget. 245 this widget.
321 321
322 Subsequent calls of mapEvents will merge events with different 322 Subsequent calls of mapEvents will merge events with different
323 widget names and override the previously set callback. 323 widget names and override the previously set callback.
324 You can also pass C{None} instead of a callback, which will 324 You can also pass C{None} instead of a callback, which will
325 disable the event completely. 325 disable the event completely.
326 326
327 @param eventMap: A dictionary with widget/event names as keys and callbacks as values. 327 @param eventMap: A dictionary with widget/event names as keys and callbacks as values.
328 @param ignoreMissing: Normally this method raises an RuntimeError, when a widget 328 @param ignoreMissing: Normally this method raises an RuntimeError, when a widget
329 can not be found - this behaviour can be overriden by passing True here. 329 can not be found - this behaviour can be overriden by passing True here.
330 330
331 The keys in the dictionary are parsed as "widgetName/eventName" with the slash 331 The keys in the dictionary are parsed as "widgetName/eventName" with the slash
399 def distributeData(self,dataMap): 399 def distributeData(self,dataMap):
400 """ 400 """
401 Distribute data from a dictionary over the widgets in the hierachy 401 Distribute data from a dictionary over the widgets in the hierachy
402 using the keys as names and the values as the data (which is set via L{setData}). 402 using the keys as names and the values as the data (which is set via L{setData}).
403 This will only accept unique matches. 403 This will only accept unique matches.
404 404
405 Use it like this:: 405 Use it like this::
406 guiElement.distributeData({ 406 guiElement.distributeData({
407 'myTextField' : 'Hello World!', 407 'myTextField' : 'Hello World!',
408 'myListBox' : ["1","2","3"] 408 'myListBox' : ["1","2","3"]
409 }) 409 })
410 410
411 """ 411 """
412 for name,data in dataMap.items(): 412 for name,data in dataMap.items():
413 widgetList = self.findChildren(name = name) 413 widgetList = self.findChildren(name = name)
414 if len(widgetList) != 1: 414 if len(widgetList) != 1:
415 raise RuntimeError("DistributeData can only handle widgets with unique names.") 415 raise RuntimeError("DistributeData can only handle widgets with unique names.")
963 class HBox(HBoxLayoutMixin,Container): 963 class HBox(HBoxLayoutMixin,Container):
964 """ 964 """
965 A horizontally aligned box - for containement of child widgets. 965 A horizontally aligned box - for containement of child widgets.
966 966
967 Please see L{VBox} for details - just change the directions :-). 967 Please see L{VBox} for details - just change the directions :-).
968 """ 968 """
969 def __init__(self,padding=5,**kwargs): 969 def __init__(self,padding=5,**kwargs):
970 super(HBox,self).__init__(**kwargs) 970 super(HBox,self).__init__(**kwargs)
971 self.padding = padding 971 self.padding = padding
972 972
973 class Window(VBoxLayoutMixin,Container): 973 class Window(VBoxLayoutMixin,Container):
1098 1098
1099 - wrap_text: Boolean: Enable/Disable automatic text wrapping. Disabled by default. 1099 - wrap_text: Boolean: Enable/Disable automatic text wrapping. Disabled by default.
1100 Currently to actually see text wrapping you have to explicitly set a max_size with 1100 Currently to actually see text wrapping you have to explicitly set a max_size with
1101 the desired width of the text, as the layout engine is not capable of deriving 1101 the desired width of the text, as the layout engine is not capable of deriving
1102 the maximum width from a parent container. 1102 the maximum width from a parent container.
1103 1103
1104 """ 1104 """
1105 1105
1106 ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [BoolAttr('wrap_text')] 1106 ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [BoolAttr('wrap_text')]
1107 1107
1108 def __init__(self,wrap_text=False,**kwargs): 1108 def __init__(self,wrap_text=False,**kwargs):
1109 self.real_widget = fife.Label("") 1109 self.real_widget = fife.Label("")
1110 self.wrap_text = wrap_text 1110 self.wrap_text = wrap_text
1111 super(Label,self).__init__(**kwargs) 1111 super(Label,self).__init__(**kwargs)
1112 1112
1113 def resizeToContent(self): 1113 def resizeToContent(self):
1114 self.real_widget.setWidth( self.max_size[0] ) 1114 self.real_widget.setWidth( self.max_size[0] )
1115 self.real_widget.adjustSize() 1115 self.real_widget.adjustSize()
1116 self.height = self.real_widget.getHeight() + self.margins[1]*2 1116 self.height = self.real_widget.getHeight() + self.margins[1]*2
1117 self.width = self.real_widget.getWidth() + self.margins[0]*2 1117 self.width = self.real_widget.getWidth() + self.margins[0]*2
1118 #print self.width,self.max_size[0] 1118 #print self.width,self.max_size[0]
1119 1119
1120 def _setTextWrapping(self,wrapping): self.real_widget.setTextWrapping(wrapping) 1120 def _setTextWrapping(self,wrapping): self.real_widget.setTextWrapping(wrapping)
1121 def _getTextWrapping(self): self.real_widget.isTextWrapping() 1121 def _getTextWrapping(self): self.real_widget.isTextWrapping()
1122 wrap_text = property(_getTextWrapping,_setTextWrapping) 1122 wrap_text = property(_getTextWrapping,_setTextWrapping)
1123 1123
1124 class ClickLabel(Label): 1124 class ClickLabel(Label):
1187 self._hoverimage = get_manager().loadImage(image) 1187 self._hoverimage = get_manager().loadImage(image)
1188 self.real_widget.setHoverImage( self._hoverimage ) 1188 self.real_widget.setHoverImage( self._hoverimage )
1189 except: 1189 except:
1190 self._hoverimage = _DummyImage() 1190 self._hoverimage = _DummyImage()
1191 def _getHoverImage(self): return self._hoverimage_source 1191 def _getHoverImage(self): return self._hoverimage_source
1192 hover_image = property(_getHoverImage,_setHoverImage) 1192 hover_image = property(_getHoverImage,_setHoverImage)
1193 1193
1194 def _setOffset(self, offset): 1194 def _setOffset(self, offset):
1195 self.real_widget.setDownOffset(offset[0], offset[1]) 1195 self.real_widget.setDownOffset(offset[0], offset[1])
1196 def _getOffset(self): 1196 def _getOffset(self):
1197 return (self.real_widget.getDownXOffset(), self.real_widget.getDownYOffset()) 1197 return (self.real_widget.getDownXOffset(), self.real_widget.getDownYOffset())
1209 1209
1210 class ToggleButton(BasicTextWidget): 1210 class ToggleButton(BasicTextWidget):
1211 """ 1211 """
1212 A basic push button that can be toggled. 1212 A basic push button that can be toggled.
1213 1213
1214 Unfortunately a bit of code duplication from ImageButton. 1214 Unfortunately a bit of code duplication from ImageButton.
1215 1215
1216 New Attributes 1216 New Attributes
1217 ============== 1217 ==============
1218 1218
1219 - group: String: The group the button belongs to. Only one button in each group will be toggled at one time. 1219 - group: String: The group the button belongs to. Only one button in each group will be toggled at one time.
1221 """ 1221 """
1222 1222
1223 ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [Attr('up_image'),Attr('down_image'),PointAttr('offset'),Attr('helptext'),Attr('hover_image'),Attr('group')] 1223 ATTRIBUTES = BasicTextWidget.ATTRIBUTES + [Attr('up_image'),Attr('down_image'),PointAttr('offset'),Attr('helptext'),Attr('hover_image'),Attr('group')]
1224 1224
1225 def __init__(self,up_image="",down_image="",hover_image="",offset=(0,0),group="",**kwargs): 1225 def __init__(self,up_image="",down_image="",hover_image="",offset=(0,0),group="",**kwargs):
1226 1226
1227 self.real_widget = fife.ToggleButton() 1227 self.real_widget = fife.ToggleButton()
1228 super(ToggleButton,self).__init__(**kwargs) 1228 super(ToggleButton,self).__init__(**kwargs)
1229 self.group = group 1229 self.group = group
1230 self.up_image = up_image 1230 self.up_image = up_image
1231 self.down_image = down_image 1231 self.down_image = down_image
1232 self.hover_image = hover_image 1232 self.hover_image = hover_image
1233 self.offset = offset 1233 self.offset = offset
1234 1234
1235 def _setGroup(self,group): 1235 def _setGroup(self,group):
1236 self.real_widget.setGroup( group ) 1236 self.real_widget.setGroup( group )
1237 1237
1238 def _getGroup(self): 1238 def _getGroup(self):
1239 return self.real_widget.getGroup() 1239 return self.real_widget.getGroup()
1240 group = property(_getGroup,_setGroup) 1240 group = property(_getGroup,_setGroup)
1241 1241
1242 def _setToggled(self, toggled): 1242 def _setToggled(self, toggled):
1243 self.real_widget.setToggled( toggled ) 1243 self.real_widget.setToggled( toggled )
1244 1244
1245 def _isToggled(self): 1245 def _isToggled(self):
1246 return self.real_widget.isToggled() 1246 return self.real_widget.isToggled()
1247 toggled = property(_isToggled, _setToggled) 1247 toggled = property(_isToggled, _setToggled)
1248 1248
1249 ### 1249 ###
1276 self._hoverimage = get_manager().loadImage(image) 1276 self._hoverimage = get_manager().loadImage(image)
1277 self.real_widget.setHoverImage( self._hoverimage ) 1277 self.real_widget.setHoverImage( self._hoverimage )
1278 except: 1278 except:
1279 self._hoverimage = _DummyImage() 1279 self._hoverimage = _DummyImage()
1280 def _getHoverImage(self): return self._hoverimage_source 1280 def _getHoverImage(self): return self._hoverimage_source
1281 hover_image = property(_getHoverImage,_setHoverImage) 1281 hover_image = property(_getHoverImage,_setHoverImage)
1282 1282
1283 def _setOffset(self, offset): 1283 def _setOffset(self, offset):
1284 self.real_widget.setDownOffset(offset[0], offset[1]) 1284 self.real_widget.setDownOffset(offset[0], offset[1])
1285 def _getOffset(self): 1285 def _getOffset(self):
1286 return (self.real_widget.getDownXOffset(), self.real_widget.getDownYOffset()) 1286 return (self.real_widget.getDownXOffset(), self.real_widget.getDownYOffset())
1651 self.content.resizeToContent(recurse=True) 1651 self.content.resizeToContent(recurse=True)
1652 self.content.width = max(self.content.width,self.width-5) 1652 self.content.width = max(self.content.width,self.width-5)
1653 self.content.height = max(self.content.height,self.height-5) 1653 self.content.height = max(self.content.height,self.height-5)
1654 1654
1655 def _visibilityToScrollPolicy(self,visibility): 1655 def _visibilityToScrollPolicy(self,visibility):
1656 if visibility: 1656 if visibility:
1657 return fife.ScrollArea.SHOW_AUTO 1657 return fife.ScrollArea.SHOW_AUTO
1658 return fife.ScrollArea.SHOW_NEVER 1658 return fife.ScrollArea.SHOW_NEVER
1659 1659
1660 def _scrollPolicyToVisibility(self,policy): 1660 def _scrollPolicyToVisibility(self,policy):
1661 if policy == fife.ScrollArea.SHOW_NEVER: 1661 if policy == fife.ScrollArea.SHOW_NEVER:
1699 def __repr__(self): 1699 def __repr__(self):
1700 return "<Spacer(parent.name='%s') at %x>" % (getattr(self._parent,'name','None'),id(self)) 1700 return "<Spacer(parent.name='%s') at %x>" % (getattr(self._parent,'name','None'),id(self))
1701 1701
1702 class Slider(Widget): 1702 class Slider(Widget):
1703 """ A slider widget 1703 """ A slider widget
1704 1704
1705 Use a callback to read out the slider value every time the marker 1705 Use a callback to read out the slider value every time the marker
1706 is moved. 1706 is moved.
1707 1707
1708 New Attributes 1708 New Attributes
1709 ============== 1709 ==============
1710 1710
1711 - orientation: 1 = horizontal, 0=vertical 1711 - orientation: 1 = horizontal, 0=vertical
1712 - scale_start: float: default 0.0 1712 - scale_start: float: default 0.0
1713 - scale_end: float: default 1.0 1713 - scale_end: float: default 1.0
1714 1714
1715 FIXME: 1715 FIXME:
1716 - set new attributes for marker & step length, value 1716 - set new attributes for marker & step length, value
1717 - update docstrings 1717 - update docstrings
1718 """ 1718 """
1719 1719
1720 HORIZONTAL = fife.Slider.HORIZONTAL 1720 HORIZONTAL = fife.Slider.HORIZONTAL
1721 VERTICAL = fife.Slider.VERTICAL 1721 VERTICAL = fife.Slider.VERTICAL
1722 1722
1723 ATTRIBUTES = Widget.ATTRIBUTES + [IntAttr('orientation'), FloatAttr('scale_start'), FloatAttr('scale_end')] 1723 ATTRIBUTES = Widget.ATTRIBUTES + [IntAttr('orientation'), FloatAttr('scale_start'), FloatAttr('scale_end')]
1724 1724
1725 def __init__(self, scaleStart=0.0, scaleEnd=1.0, orientation=HORIZONTAL, **kwargs): 1725 def __init__(self, scaleStart=0.0, scaleEnd=1.0, orientation=HORIZONTAL, **kwargs):
1726 self.real_widget = fife.Slider(scaleStart, scaleEnd) 1726 self.real_widget = fife.Slider(scaleStart, scaleEnd)
1727 self.orientation = orientation 1727 self.orientation = orientation
1728 self.setOrientation(self.orientation) 1728 self.setOrientation(self.orientation)
1729 super(Slider, self).__init__(**kwargs) 1729 super(Slider, self).__init__(**kwargs)
1730 1730
1731 def _setScale(self, start, end): 1731 def _setScale(self, start, end):
1732 """setScale(self, double scaleStart, double scaleEnd)""" 1732 """setScale(self, double scaleStart, double scaleEnd)"""
1733 if type(start) != float: 1733 if type(start) != float:
1734 raise RuntimeError("Slider expects float for start scale") 1734 raise RuntimeError("Slider expects float for start scale")
1735 if type(end) != float: 1735 if type(end) != float:
1736 raise RuntimeError("Slider expects float for end scale") 1736 raise RuntimeError("Slider expects float for end scale")
1737 self.real_widget.setScale(start, end) 1737 self.real_widget.setScale(start, end)
1738 1738
1739 def getScaleStart(self): 1739 def getScaleStart(self):
1740 """getScaleStart(self) -> double""" 1740 """getScaleStart(self) -> double"""
1741 return self.real_widget.getScaleStart() 1741 return self.real_widget.getScaleStart()
1742 1742
1743 def setScaleStart(self, start): 1743 def setScaleStart(self, start):
1744 """setScaleStart(self, double scaleStart)""" 1744 """setScaleStart(self, double scaleStart)"""
1745 if type(start) != float: 1745 if type(start) != float:
1746 raise RuntimeError("Slider expects float for start scale") 1746 raise RuntimeError("Slider expects float for start scale")
1747 self.real_widget.setScaleStart(start) 1747 self.real_widget.setScaleStart(start)
1748 scale_start = property(getScaleStart, setScaleStart) 1748 scale_start = property(getScaleStart, setScaleStart)
1749 1749
1750 def getScaleEnd(self): 1750 def getScaleEnd(self):
1751 """getScaleEnd(self) -> double""" 1751 """getScaleEnd(self) -> double"""
1752 return self.real_widget.getScaleEnd() 1752 return self.real_widget.getScaleEnd()
1779 return self.real_widget.getMarkerLength() 1779 return self.real_widget.getMarkerLength()
1780 1780
1781 def setOrientation(self, orientation): 1781 def setOrientation(self, orientation):
1782 """setOrientation(self, Orientation orientation)""" 1782 """setOrientation(self, Orientation orientation)"""
1783 self.real_widget.setOrientation(orientation) 1783 self.real_widget.setOrientation(orientation)
1784 1784
1785 def getOrientation(self): 1785 def getOrientation(self):
1786 """getOrientation(self) -> int""" 1786 """getOrientation(self) -> int"""
1787 return self.real_widget.getOrientation() 1787 return self.real_widget.getOrientation()
1788 orientation = property(getOrientation, setOrientation) 1788 orientation = property(getOrientation, setOrientation)
1789 1789