]>
Commit | Line | Data |
---|---|---|
d14a1e28 RD |
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 | #---------------------------------------------------------------------- | |
b881fc78 RD |
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 | # | |
c3bc3b61 RD |
17 | # 12/23/2003 - Jeff Grimmett (grimmtooth@softhome.net) |
18 | # | |
19 | # o wx.PySizer.GetSize() method working right now. | |
20 | # | |
d14a1e28 RD |
21 | |
22 | """ | |
c3bc3b61 RD |
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 | |
d14a1e28 RD |
25 | specified by row and col, and row/col spanning is supported. |
26 | ||
27 | Adapted from code by Niki Spahiev. | |
28 | ||
b881fc78 RD |
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. | |
d14a1e28 RD |
32 | """ |
33 | ||
b881fc78 RD |
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 | ## #####################################################/ | |
d14a1e28 | 49 | |
b881fc78 | 50 | ## """ |
d14a1e28 | 51 | |
b881fc78 | 52 | ## warnings.warn(warningmsg, DeprecationWarning, stacklevel=2) |
d14a1e28 RD |
53 | |
54 | #---------------------------------------------------------------------- | |
55 | ||
b881fc78 | 56 | class RowColSizer(wx.PySizer): |
d14a1e28 RD |
57 | |
58 | # default sizes for cells with no item | |
59 | col_w = 10 | |
60 | row_h = 22 | |
61 | ||
62 | def __init__(self): | |
b881fc78 | 63 | wx.PySizer.__init__(self) |
d14a1e28 RD |
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, | |
c3bc3b61 RD |
78 | # row, col and spanning can be specified individually... |
79 | row=-1, col=-1, | |
d14a1e28 | 80 | rowspan=1, colspan=1, |
c3bc3b61 RD |
81 | # or as tuples (row,col) and (rowspan,colspan) |
82 | pos=None, size=None, | |
d14a1e28 RD |
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: | |
b881fc78 | 95 | # flag = flag | wx.EXPAND |
d14a1e28 | 96 | |
75748473 RD |
97 | return wx.PySizer.Add(self, item, option, flag, border, |
98 | userData=(row, col, row+rowspan, col+colspan)) | |
d14a1e28 RD |
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 | ||
75748473 RD |
116 | return wx.PySizer.Add(self, (width, height), option, flag, border, |
117 | userData=(row, col, row+rowspan, col+colspan)) | |
d14a1e28 RD |
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: | |
b881fc78 | 147 | return wx.Size(10, 10) |
d14a1e28 RD |
148 | |
149 | for item in items: | |
150 | self._add( item.CalcMin(), item.GetUserData() ) | |
151 | ||
b881fc78 RD |
152 | size = wx.Size( reduce( operator.add, self.colWidths), |
153 | reduce( operator.add, self.rowHeights) ) | |
d14a1e28 RD |
154 | return size |
155 | ||
156 | ||
157 | #-------------------------------------------------- | |
158 | def RecalcSizes( self ): | |
159 | # save current dimensions, etc. | |
b881fc78 RD |
160 | curWidth, curHeight = self.GetSize() |
161 | px, py = self.GetPosition() | |
162 | minWidth, minHeight = self.CalcMin() | |
d14a1e28 RD |
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 | |
b881fc78 | 204 | ipt = wx.Point(x, y) |
d14a1e28 RD |
205 | isz = item.CalcMin() |
206 | flag = item.GetFlag() | |
207 | ||
b881fc78 RD |
208 | if flag & wx.EXPAND or flag & wx.SHAPED: |
209 | isz = wx.Size(w, h) | |
d14a1e28 | 210 | else: |
b881fc78 | 211 | if flag & wx.ALIGN_CENTER_HORIZONTAL: |
d14a1e28 | 212 | ipt.x = x + (w - isz.width) / 2 |
b881fc78 | 213 | elif flag & wx.ALIGN_RIGHT: |
d14a1e28 RD |
214 | ipt.x = x + (w - isz.width) |
215 | ||
b881fc78 | 216 | if flag & wx.ALIGN_CENTER_VERTICAL: |
d14a1e28 | 217 | ipt.y = y + (h - isz.height) / 2 |
b881fc78 | 218 | elif flag & wx.ALIGN_BOTTOM: |
d14a1e28 RD |
219 | ipt.y = y + (h - isz.height) |
220 | ||
221 | item.SetDimension(ipt, isz) | |
222 | ||
223 | ||
224 | #---------------------------------------------------------------------- | |
225 | #---------------------------------------------------------------------- | |
226 | ||
1fded56b | 227 | |
1fded56b | 228 |