Mercurial > fife-parpg
comparison engine/python/fife/extensions/pychan/widgets/containers.py @ 378:64738befdf3b
bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author | vtchill@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Mon, 11 Jan 2010 23:34:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
377:fe6fb0e0ed23 | 378:64738befdf3b |
---|---|
1 # -*- coding: utf-8 -*- | |
2 | |
3 # #################################################################### | |
4 # Copyright (C) 2005-2009 by the FIFE team | |
5 # http://www.fifengine.de | |
6 # This file is part of FIFE. | |
7 # | |
8 # FIFE is free software; you can redistribute it and/or | |
9 # modify it under the terms of the GNU Lesser General Public | |
10 # License as published by the Free Software Foundation; either | |
11 # version 2.1 of the License, or (at your option) any later version. | |
12 # | |
13 # This library is distributed in the hope that it will be useful, | |
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 # Lesser General Public License for more details. | |
17 # | |
18 # You should have received a copy of the GNU Lesser General Public | |
19 # License along with this library; if not, write to the | |
20 # Free Software Foundation, Inc., | |
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 # #################################################################### | |
23 | |
24 from common import * | |
25 from widget import Widget | |
26 from layout import VBoxLayoutMixin, HBoxLayoutMixin | |
27 | |
28 class Container(Widget): | |
29 """ | |
30 This is the basic container class. It provides space in which child widgets can | |
31 be position via the position attribute. If you want to use the layout engine, | |
32 you have to use derived containers with vertical or horizontal orientation | |
33 (L{VBox} or L{HBox}) | |
34 | |
35 New Attributes | |
36 ============== | |
37 | |
38 - padding - Integer: Not used in the Container class istelf, distance between child widgets. | |
39 - background_image - Set this to a GuiImage or a resource location (simply a filename). | |
40 The image will be tiled over the background area. | |
41 - opaque - Boolean: Whether the background should be drawn at all. Set this to False | |
42 to make the widget transparent. | |
43 - children - Just contains the list of contained child widgets. Do NOT modify. | |
44 """ | |
45 | |
46 ATTRIBUTES = Widget.ATTRIBUTES + [ IntAttr('padding'), Attr('background_image'), BoolAttr('opaque'),PointAttr('margins') ] | |
47 | |
48 def __init__(self,padding=5,margins=(5,5),_real_widget=None, **kwargs): | |
49 self.real_widget = _real_widget or fife.Container() | |
50 self.children = [] | |
51 self.margins = margins | |
52 self.padding = padding | |
53 self._background = [] | |
54 self._background_image = None | |
55 super(Container,self).__init__(**kwargs) | |
56 | |
57 def addChild(self, widget): | |
58 widget.parent = self | |
59 self.children.append(widget) | |
60 self.real_widget.add(widget.real_widget) | |
61 | |
62 def insertChild(self, widget, position): | |
63 if position > len(self.children) or 0-position > len(self.children): | |
64 print "insertChild: Warning: Index overflow.", | |
65 if position >= 0: | |
66 self.addChild(widget) | |
67 else: | |
68 self.insertChild(widget, 0) | |
69 return | |
70 | |
71 children = self.children[0:position]+[widget]+self.children[position:] | |
72 #assert len(children) == len(self.children) + 1 | |
73 self.removeAllChildren() | |
74 for child in children: | |
75 self.addChild(child) | |
76 | |
77 def insertChildBefore(self, widget, before): | |
78 if before not in self.children: | |
79 raise RuntimeError("Couldn't find widget %s as child of %s - in insertChildBefore" % (str(widget),str(before))) | |
80 self.insertChild(widget, self.children.index(before)) | |
81 | |
82 def removeChild(self,widget): | |
83 if not widget in self.children: | |
84 raise RuntimeError("%s does not have %s as direct child widget." % (str(self),str(widget))) | |
85 self.children.remove(widget) | |
86 self.real_widget.remove(widget.real_widget) | |
87 widget.parent = None | |
88 | |
89 def add(self,*widgets): | |
90 print "PyChan: Deprecation warning: Please use 'addChild' or 'addChildren' instead." | |
91 self.addChildren(*widgets) | |
92 | |
93 def getMaxChildrenWidth(self): | |
94 if not self.children: return 0 | |
95 return max(widget.width for widget in self.children) | |
96 | |
97 def getMaxChildrenHeight(self): | |
98 if not self.children: return 0 | |
99 return max(widget.height for widget in self.children) | |
100 | |
101 def deepApply(self,visitorFunc, leaves_first = True): | |
102 if leaves_first: | |
103 for child in self.children: | |
104 child.deepApply(visitorFunc, leaves_first = leaves_first) | |
105 visitorFunc(self) | |
106 if not leaves_first: | |
107 for child in self.children: | |
108 child.deepApply(visitorFunc, leaves_first = leaves_first) | |
109 | |
110 def beforeShow(self): | |
111 self._resetTiling() | |
112 | |
113 def _resetTiling(self): | |
114 image = self._background_image | |
115 if image is None: | |
116 return | |
117 | |
118 back_w,back_h = self.width, self.height | |
119 image_w, image_h = image.getWidth(), image.getHeight() | |
120 | |
121 map(self.real_widget.remove,self._background) | |
122 | |
123 # Now tile the background over the widget | |
124 self._background = [] | |
125 icon = fife.Icon(image) | |
126 x, w = 0, image_w | |
127 while x < back_w: | |
128 y, h = 0, image_h | |
129 while y < self.height: | |
130 icon = fife.Icon(image) | |
131 icon.setPosition(x,y) | |
132 self._background.append(icon) | |
133 y += h | |
134 x += w | |
135 map(self.real_widget.add,self._background) | |
136 for tile in self._background: | |
137 tile.requestMoveToBottom() | |
138 | |
139 def setBackgroundImage(self,image): | |
140 self._background = getattr(self,'_background',None) | |
141 if image is None: | |
142 self._background_image = image | |
143 map(self.real_widget.remove,self._background) | |
144 self._background = [] | |
145 return | |
146 # Background generation is done in _resetTiling | |
147 | |
148 if not isinstance(image, fife.GuiImage): | |
149 image = get_manager().loadImage(image) | |
150 self._background_image = image | |
151 | |
152 def getBackgroundImage(self): return self._background_image | |
153 background_image = property(getBackgroundImage,setBackgroundImage) | |
154 | |
155 def _setOpaque(self,opaque): self.real_widget.setOpaque(opaque) | |
156 def _getOpaque(self): return self.real_widget.isOpaque() | |
157 opaque = property(_getOpaque,_setOpaque) | |
158 | |
159 class VBox(VBoxLayoutMixin,Container): | |
160 """ | |
161 A vertically aligned box - for containement of child widgets. | |
162 | |
163 Widgets added to this container widget, will layout on top of each other. | |
164 Also the minimal width of the container will be the maximum of the minimal | |
165 widths of the contained widgets. | |
166 | |
167 The default alignment is to the top. This can be changed by adding a Spacer | |
168 to the widget at any point (but only one!). The spacer will expand, so that | |
169 widgets above the spacer are aligned to the top, while widgets below the spacer | |
170 are aligned to the bottom. | |
171 """ | |
172 DEFAULT_HEXPAND = 0 | |
173 DEFAULT_VEXPAND = 1 | |
174 | |
175 def __init__(self,padding=5,**kwargs): | |
176 super(VBox,self).__init__(**kwargs) | |
177 self.padding = padding | |
178 | |
179 | |
180 class HBox(HBoxLayoutMixin,Container): | |
181 """ | |
182 A horizontally aligned box - for containement of child widgets. | |
183 | |
184 Please see L{VBox} for details - just change the directions :-). | |
185 """ | |
186 DEFAULT_HEXPAND = 1 | |
187 DEFAULT_VEXPAND = 0 | |
188 | |
189 def __init__(self,padding=5,**kwargs): | |
190 super(HBox,self).__init__(**kwargs) | |
191 self.padding = padding | |
192 | |
193 class Window(VBoxLayoutMixin,Container): | |
194 """ | |
195 A L{VBox} with a draggable title bar aka a window | |
196 | |
197 New Attributes | |
198 ============== | |
199 | |
200 - title: The Caption of the window | |
201 - titlebar_height: The height of the window title bar | |
202 """ | |
203 | |
204 ATTRIBUTES = Container.ATTRIBUTES + [ UnicodeAttr('title'), IntAttr('titlebar_height') ] | |
205 | |
206 def __init__(self,title=u"title",titlebar_height=0,**kwargs): | |
207 super(Window,self).__init__(_real_widget = fife.Window(), **kwargs) | |
208 if titlebar_height == 0: | |
209 titlebar_height = self.real_font.getHeight() + 4 | |
210 self.titlebar_height = titlebar_height | |
211 self.title = title | |
212 | |
213 # Override explicit positioning | |
214 self.position_technique = "automatic" | |
215 | |
216 | |
217 def _getTitle(self): return gui2text(self.real_widget.getCaption()) | |
218 def _setTitle(self,text): self.real_widget.setCaption(text2gui(text)) | |
219 title = property(_getTitle,_setTitle) | |
220 | |
221 def _getTitleBarHeight(self): return self.real_widget.getTitleBarHeight() | |
222 def _setTitleBarHeight(self,h): self.real_widget.setTitleBarHeight(h) | |
223 titlebar_height = property(_getTitleBarHeight,_setTitleBarHeight) | |
224 | |
225 # Hackish way of hiding that title bar height in the perceived height. | |
226 # Fixes VBox calculation | |
227 def _setHeight(self,h): | |
228 h = max(self.min_size[1],h) | |
229 h = min(self.max_size[1],h) | |
230 self.real_widget.setHeight(h + self.titlebar_height) | |
231 def _getHeight(self): return self.real_widget.getHeight() - self.titlebar_height | |
232 height = property(_getHeight,_setHeight) | |
233 |