]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/rcsizer.py
Aquire the GIL before raising the NotImplementedError exception
[wxWidgets.git] / wxPython / wx / lib / rcsizer.py
1 #----------------------------------------------------------------------
2 # Name: wxPython.lib.rcsizer
3 # Purpose: RowColSizer:
4 #
5 # Author: Robin Dunn, adapted from code by Niki Spahiev
6 #
7 # Created: 26-Feb-2002
8 # RCS-ID: $Id$
9 # Copyright: (c) 2002 by Total Control Software
10 # Licence: wxWindows license
11 #----------------------------------------------------------------------
12 # 12/10/2003 - Jeff Grimmett (grimmtooth@softhome.net)
13 #
14 # o 2.5 compatability update.
15 # o There appears to be a prob with the wx.PySizer.GetSize() method.
16 #
17
18 """
19 A pure-Python wxSizer that lays out items in a grid similar to
20 wxFlexGridSizer but item position is not implicit but explicitly
21 specified by row and col, and row/col spanning is supported.
22
23 Adapted from code by Niki Spahiev.
24
25 NOTE: There is now a C++ version of this class that has been wrapped
26 as wx.GridBagSizer. It is quicker and more capable so you are
27 encouraged to switch.
28 """
29
30 import operator
31 import wx
32
33
34 # After the lib and demo no longer uses this sizer enable this warning...
35
36 ## import warnings
37 ## warningmsg = r"""\
38
39 ## #####################################################\
40 ## # THIS MODULE IS NOW DEPRECATED |
41 ## # |
42 ## # The core wx library now contains a similar class |
43 ## # wrapped as wx.GridBagSizer. |
44 ## #####################################################/
45
46 ## """
47
48 ## warnings.warn(warningmsg, DeprecationWarning, stacklevel=2)
49
50 #----------------------------------------------------------------------
51
52 class RowColSizer(wx.PySizer):
53
54 # default sizes for cells with no item
55 col_w = 10
56 row_h = 22
57
58 def __init__(self):
59 wx.PySizer.__init__(self)
60 self.growableRows = []
61 self.growableCols = []
62
63
64 def AddGrowableRow(self, idx):
65 self.growableRows.append(idx)
66
67 def AddGrowableCol(self, idx):
68 self.growableCols.append(idx)
69
70
71
72 #--------------------------------------------------
73 def Add(self, item, option=0, flag=0, border=0,
74 row=-1, col=-1, # row, col and spanning can be specified individually...
75 rowspan=1, colspan=1,
76 pos=None, size=None, # or as tuples (row,col) and (rowspan,colspan)
77 ):
78
79 if pos is not None:
80 row, col = pos
81 if size is not None:
82 rowspan, colspan = size
83
84 assert row != -1, "Row must be specified"
85 assert col != -1, "Column must be specified"
86
87 # Do I really want to do this? Probably not...
88 #if rowspan > 1 or colspan > 1:
89 # flag = flag | wx.EXPAND
90
91 wx.PySizer.Add(self, item, option, flag, border,
92 userData=(row, col, row+rowspan, col+colspan))
93
94 #AddWindow = Add
95 #AddSizer = Add
96
97 def AddSpacer(self, width, height, option=0, flag=0, border=0,
98 row=-1, col=-1,
99 rowspan=1, colspan=1,
100 pos=None, size=None,
101 ):
102 if pos is not None:
103 row, col = pos
104 if size is not None:
105 rowspan, colspan = size
106
107 assert row != -1, "Row must be specified"
108 assert col != -1, "Column must be specified"
109
110 wx.PySizer.AddSpacer(self, (width, height), option, flag, border,
111 userData=(row, col, row+rowspan, col+colspan))
112
113 #--------------------------------------------------
114 def _add( self, size, dim ):
115 r, c, r2, c2 = dim # unpack coords and spanning
116
117 # are the widths and heights lists long enough?
118 if r2 > len(self.rowHeights):
119 x = [self.row_h] * (r2-len(self.rowHeights))
120 self.rowHeights.extend( x )
121 if c2 > len(self.colWidths):
122 x = [self.col_w] * (c2-len(self.colWidths))
123 self.colWidths.extend( x )
124
125 # set the widths and heights lists for this item
126 scale = (r2 - r)
127 for i in range(r, r2):
128 self.rowHeights[i] = max( self.rowHeights[i], size.height / scale )
129 scale = (c2 - c)
130 for i in range(c, c2):
131 self.colWidths[i] = max( self.colWidths[i], size.width / scale )
132
133
134 #--------------------------------------------------
135 def CalcMin( self ):
136 self.rowHeights = []
137 self.colWidths = []
138
139 items = self.GetChildren()
140 if not items:
141 return wx.Size(10, 10)
142
143 for item in items:
144 self._add( item.CalcMin(), item.GetUserData() )
145
146 size = wx.Size( reduce( operator.add, self.colWidths),
147 reduce( operator.add, self.rowHeights) )
148 return size
149
150
151 #--------------------------------------------------
152 def RecalcSizes( self ):
153 # save current dimensions, etc.
154 curWidth, curHeight = self.GetSize()
155 px, py = self.GetPosition()
156 minWidth, minHeight = self.CalcMin()
157
158 # Check for growables
159 if self.growableRows and curHeight > minHeight:
160 delta = (curHeight - minHeight) / len(self.growableRows)
161 extra = (curHeight - minHeight) % len(self.growableRows)
162 for idx in self.growableRows:
163 self.rowHeights[idx] += delta
164 self.rowHeights[self.growableRows[0]] += extra
165
166 if self.growableCols and curWidth > minWidth:
167 delta = (curWidth - minWidth) / len(self.growableCols)
168 extra = (curWidth - minWidth) % len(self.growableCols)
169 for idx in self.growableCols:
170 self.colWidths[idx] += delta
171 self.colWidths[self.growableCols[0]] += extra
172
173 rpos = [0] * len(self.rowHeights)
174 cpos = [0] * len(self.colWidths)
175
176 for i in range(len(self.rowHeights)):
177 height = self.rowHeights[i]
178 rpos[i] = py
179 py += height
180
181 for i in range(len(self.colWidths)):
182 width = self.colWidths[i]
183 cpos[i] = px
184 px += width
185
186 # iterate children and set dimensions...
187 for item in self.GetChildren():
188 r, c, r2, c2 = item.GetUserData()
189 width = reduce( operator.add, self.colWidths[c:c2] )
190 height = reduce( operator.add, self.rowHeights[r:r2] )
191 self.SetItemBounds( item, cpos[c], rpos[r], width, height )
192
193
194 #--------------------------------------------------
195 def SetItemBounds(self, item, x, y, w, h):
196 # calculate the item's actual size and position within
197 # its grid cell
198 ipt = wx.Point(x, y)
199 isz = item.CalcMin()
200 flag = item.GetFlag()
201
202 if flag & wx.EXPAND or flag & wx.SHAPED:
203 isz = wx.Size(w, h)
204 else:
205 if flag & wx.ALIGN_CENTER_HORIZONTAL:
206 ipt.x = x + (w - isz.width) / 2
207 elif flag & wx.ALIGN_RIGHT:
208 ipt.x = x + (w - isz.width)
209
210 if flag & wx.ALIGN_CENTER_VERTICAL:
211 ipt.y = y + (h - isz.height) / 2
212 elif flag & wx.ALIGN_BOTTOM:
213 ipt.y = y + (h - isz.height)
214
215 item.SetDimension(ipt, isz)
216
217
218 #----------------------------------------------------------------------
219 #----------------------------------------------------------------------
220
221
222