Updated SWIG patches for new CVS line numbers, also output "int" for
[wxWidgets.git] / wxPython / wx / lib / grids.py
CommitLineData
d14a1e28
RD
1#----------------------------------------------------------------------
2# Name: wxPython.lib.grids
3# Purpose: An example sizer derived from the C++ wxPySizer that
4# sizes items in a fixed or flexible grid.
5#
6# Author: Robin Dunn
7#
8# Created: 21-Sept-1999
9# RCS-ID: $Id$
10# Copyright: (c) 1999 by Total Control Software
11# Licence: wxWindows license
12#----------------------------------------------------------------------
b881fc78
RD
13# 12/07/2003 - Jeff Grimmett (grimmtooth@softhome.net)
14#
15# o 2.5 Compatability changes
16#
d14a1e28
RD
17
18"""
19In this module you will find wxGridSizer and wxFlexGridSizer. Please
20note that these sizers have since been ported to C++ and those
21versions are now exposed in the regular wxPython wrappers. However I
22am also leaving them here in the library so they can serve as an
23example of how to implement sizers in Python.
24
25wxGridSizer: Sizes and positions items such that all rows are the same
26height and all columns are the same width. You can specify a gap in
27pixels to be used between the rows and/or the columns. When you
28create the sizer you specify the number of rows or the number of
29columns and then as you add items it figures out the other dimension
30automatically. Like other sizers, items can be set to fill their
31available space, or to be aligned on a side, in a corner, or in the
32center of the space. When the sizer is resized, all the items are
33resized the same amount so all rows and all columns remain the same
34size.
35
36wxFlexGridSizer: Derives from wxGridSizer and adds the ability for
37particular rows and/or columns to be marked as growable. This means
38that when the sizer changes size, the growable rows and colums are the
39ones that stretch. The others remain at their initial size.
d14a1e28
RD
40"""
41
42
b881fc78
RD
43import operator
44import wx
d14a1e28
RD
45
46#----------------------------------------------------------------------
47
b881fc78 48class wxGridSizer(wx.PySizer):
d14a1e28 49 def __init__(self, rows=0, cols=0, hgap=0, vgap=0):
b881fc78 50 wx.PySizer.__init__(self)
d14a1e28
RD
51 if rows == 0 and cols == 0:
52 raise ValueError, "rows and cols cannot both be zero"
53
54 self.rows = rows
55 self.cols = cols
56 self.hgap = hgap
57 self.vgap = vgap
58
59
60 def SetRows(self, rows):
61 if rows == 0 and self.cols == 0:
62 raise ValueError, "rows and cols cannot both be zero"
63 self.rows = rows
64
65 def SetColumns(self, cols):
66 if self.rows == 0 and cols == 0:
67 raise ValueError, "rows and cols cannot both be zero"
68 self.cols = cols
69
70 def GetRows(self):
71 return self.rows
72
73 def GetColumns(self):
74 return self.cols
75
76 def SetHgap(self, hgap):
77 self.hgap = hgap
78
79 def SetVgap(self, vgap):
80 self.vgap = vgap
81
82 def GetHgap(self, hgap):
83 return self.hgap
84
85 def GetVgap(self, vgap):
86 return self.vgap
87
88 #--------------------------------------------------
89 def CalcMin(self):
90 items = self.GetChildren()
91 nitems = len(items)
92 nrows = self.rows
93 ncols = self.cols
94
95 if ncols > 0:
96 nrows = (nitems + ncols-1) / ncols
97 else:
98 ncols = (nitems + nrows-1) / nrows
99
100 # Find the max width and height for any component.
101 w = 0
102 h = 0
103 for item in items:
104 size = item.CalcMin()
105 w = max(w, size.width)
106 h = max(h, size.height)
107
b881fc78
RD
108 return wx.Size(ncols * w + (ncols-1) * self.hgap,
109 nrows * h + (nrows-1) * self.vgap)
d14a1e28
RD
110
111
112 #--------------------------------------------------
113 def RecalcSizes(self):
114 items = self.GetChildren()
115 if not items:
116 return
117
118 nitems = len(items)
119 nrows = self.rows
120 ncols = self.cols
121
122 if ncols > 0:
123 nrows = (nitems + ncols-1) / ncols
124 else:
125 ncols = (nitems + nrows-1) / nrows
126
127
128 sz = self.GetSize()
129 pt = self.GetPosition()
130 w = (sz.width - (ncols - 1) * self.hgap) / ncols;
131 h = (sz.height - (nrows - 1) * self.vgap) / nrows;
132
133 x = pt.x
134 for c in range(ncols):
135 y = pt.y
136 for r in range(nrows):
137 i = r * ncols + c
138 if i < nitems:
139 self.SetItemBounds(items[i], x, y, w, h)
b881fc78 140
d14a1e28 141 y = y + h + self.vgap
b881fc78 142
d14a1e28
RD
143 x = x + w + self.hgap
144
145
146 #--------------------------------------------------
147 def SetItemBounds(self, item, x, y, w, h):
148 # calculate the item's size and position within
149 # its grid cell
b881fc78 150 ipt = wx.Point(x, y)
d14a1e28
RD
151 isz = item.CalcMin()
152 flag = item.GetFlag()
153
b881fc78
RD
154 if flag & wx.EXPAND or flag & wx.SHAPED:
155 isz = (w, h)
d14a1e28 156 else:
b881fc78 157 if flag & wx.ALIGN_CENTER_HORIZONTAL:
d14a1e28 158 ipt.x = x + (w - isz.width) / 2
b881fc78 159 elif flag & wx.ALIGN_RIGHT:
d14a1e28
RD
160 ipt.x = x + (w - isz.width)
161
b881fc78 162 if flag & wx.ALIGN_CENTER_VERTICAL:
d14a1e28 163 ipt.y = y + (h - isz.height) / 2
b881fc78 164 elif flag & wx.ALIGN_BOTTOM:
d14a1e28
RD
165 ipt.y = y + (h - isz.height)
166
167 item.SetDimension(ipt, isz)
168
169
170#----------------------------------------------------------------------
171
172
173
174class wxFlexGridSizer(wxGridSizer):
175 def __init__(self, rows=0, cols=0, hgap=0, vgap=0):
176 wxGridSizer.__init__(self, rows, cols, hgap, vgap)
177 self.rowHeights = []
178 self.colWidths = []
179 self.growableRows = []
180 self.growableCols = []
181
182 def AddGrowableRow(self, idx):
183 self.growableRows.append(idx)
184
185 def AddGrowableCol(self, idx):
186 self.growableCols.append(idx)
187
188 #--------------------------------------------------
189 def CalcMin(self):
190 items = self.GetChildren()
191 nitems = len(items)
192 nrows = self.rows
193 ncols = self.cols
194
195 if ncols > 0:
196 nrows = (nitems + ncols-1) / ncols
197 else:
198 ncols = (nitems + nrows-1) / nrows
199
200 # Find the max width and height for any component.
201 self.rowHeights = [0] * nrows
202 self.colWidths = [0] * ncols
b881fc78 203
d14a1e28
RD
204 for i in range(len(items)):
205 size = items[i].CalcMin()
206 row = i / ncols
207 col = i % ncols
208 self.rowHeights[row] = max(size.height, self.rowHeights[row])
209 self.colWidths[col] = max(size.width, self.colWidths[col])
210
211 # Add up all the widths and heights
212 cellsWidth = reduce(operator.__add__, self.colWidths)
213 cellHeight = reduce(operator.__add__, self.rowHeights)
214
b881fc78
RD
215 return wx.Size(cellsWidth + (ncols-1) * self.hgap,
216 cellHeight + (nrows-1) * self.vgap)
d14a1e28
RD
217
218
219 #--------------------------------------------------
220 def RecalcSizes(self):
221 items = self.GetChildren()
222 if not items:
223 return
224
225 nitems = len(items)
226 nrows = self.rows
227 ncols = self.cols
228
229 if ncols > 0:
230 nrows = (nitems + ncols-1) / ncols
231 else:
232 ncols = (nitems + nrows-1) / nrows
233
234 minsz = self.CalcMin()
235 sz = self.GetSize()
236 pt = self.GetPosition()
237
238 # Check for growables
239 if self.growableRows and sz.height > minsz.height:
240 delta = (sz.height - minsz.height) / len(self.growableRows)
241 for idx in self.growableRows:
242 self.rowHeights[idx] = self.rowHeights[idx] + delta
243
244 if self.growableCols and sz.width > minsz.width:
245 delta = (sz.width - minsz.width) / len(self.growableCols)
246 for idx in self.growableCols:
247 self.colWidths[idx] = self.colWidths[idx] + delta
248
249 # bottom right corner
b881fc78 250 sz = wx.Size(pt.x + sz.width, pt.y + sz.height)
d14a1e28
RD
251
252 # Layout each cell
253 x = pt.x
254 for c in range(ncols):
255 y = pt.y
256 for r in range(nrows):
257 i = r * ncols + c
b881fc78 258
d14a1e28
RD
259 if i < nitems:
260 w = max(0, min(self.colWidths[c], sz.width - x))
261 h = max(0, min(self.rowHeights[r], sz.height - y))
262 self.SetItemBounds(items[i], x, y, w, h)
b881fc78 263
d14a1e28 264 y = y + self.rowHeights[r] + self.vgap
b881fc78 265
d14a1e28
RD
266 x = x + self.colWidths[c] + self.hgap
267
268#----------------------------------------------------------------------
269
270
271
272
1fded56b 273
1fded56b 274