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