Mercurial > fife-parpg
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 |