]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/rcsizer.py
Oops
[wxWidgets.git] / wxPython / wx / lib / rcsizer.py
CommitLineData
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#
d14a1e28
RD
17
18"""
19A pure-Python wxSizer that lays out items in a grid similar to
20wxFlexGridSizer but item position is not implicit but explicitly
21specified by row and col, and row/col spanning is supported.
22
23Adapted from code by Niki Spahiev.
24
b881fc78
RD
25NOTE: There is now a C++ version of this class that has been wrapped
26as wx.GridBagSizer. It is quicker and more capable so you are
27encouraged to switch.
d14a1e28
RD
28"""
29
b881fc78
RD
30import operator
31import 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## #####################################################/
d14a1e28 45
b881fc78 46## """
d14a1e28 47
b881fc78 48## warnings.warn(warningmsg, DeprecationWarning, stacklevel=2)
d14a1e28
RD
49
50#----------------------------------------------------------------------
51
b881fc78 52class RowColSizer(wx.PySizer):
d14a1e28
RD
53
54 # default sizes for cells with no item
55 col_w = 10
56 row_h = 22
57
58 def __init__(self):
b881fc78 59 wx.PySizer.__init__(self)
d14a1e28
RD
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:
b881fc78 89 # flag = flag | wx.EXPAND
d14a1e28 90
b881fc78 91 wx.PySizer.Add(self, item, option, flag, border,
d14a1e28
RD
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
b881fc78 110 wx.PySizer.AddSpacer(self, (width, height), option, flag, border,
d14a1e28
RD
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:
b881fc78 141 return wx.Size(10, 10)
d14a1e28
RD
142
143 for item in items:
144 self._add( item.CalcMin(), item.GetUserData() )
145
b881fc78
RD
146 size = wx.Size( reduce( operator.add, self.colWidths),
147 reduce( operator.add, self.rowHeights) )
d14a1e28
RD
148 return size
149
150
151 #--------------------------------------------------
152 def RecalcSizes( self ):
153 # save current dimensions, etc.
b881fc78
RD
154 curWidth, curHeight = self.GetSize()
155 px, py = self.GetPosition()
156 minWidth, minHeight = self.CalcMin()
d14a1e28
RD
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
b881fc78 198 ipt = wx.Point(x, y)
d14a1e28
RD
199 isz = item.CalcMin()
200 flag = item.GetFlag()
201
b881fc78
RD
202 if flag & wx.EXPAND or flag & wx.SHAPED:
203 isz = wx.Size(w, h)
d14a1e28 204 else:
b881fc78 205 if flag & wx.ALIGN_CENTER_HORIZONTAL:
d14a1e28 206 ipt.x = x + (w - isz.width) / 2
b881fc78 207 elif flag & wx.ALIGN_RIGHT:
d14a1e28
RD
208 ipt.x = x + (w - isz.width)
209
b881fc78 210 if flag & wx.ALIGN_CENTER_VERTICAL:
d14a1e28 211 ipt.y = y + (h - isz.height) / 2
b881fc78 212 elif flag & wx.ALIGN_BOTTOM:
d14a1e28
RD
213 ipt.y = y + (h - isz.height)
214
215 item.SetDimension(ipt, isz)
216
217
218#----------------------------------------------------------------------
219#----------------------------------------------------------------------
220
1fded56b 221
1fded56b 222