]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/rcsizer.py
Changes to how overridable C++ methods are virtualized for Python.
[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#
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
23A pure-Python Sizer that lays out items in a grid similar to
24wx.FlexGridSizer but item position is not implicit but explicitly
d14a1e28
RD
25specified by row and col, and row/col spanning is supported.
26
27Adapted from code by Niki Spahiev.
28
b881fc78
RD
29NOTE: There is now a C++ version of this class that has been wrapped
30as wx.GridBagSizer. It is quicker and more capable so you are
31encouraged to switch.
d14a1e28
RD
32"""
33
b881fc78
RD
34import operator
35import 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 56class 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