1 #----------------------------------------------------------------------
2 # Name: wxPython.lib.rcsizer
3 # Purpose: RowColSizer:
5 # Author: Robin Dunn, adapted from code by Niki Spahiev
9 # Copyright: (c) 2002 by Total Control Software
10 # Licence: wxWindows license
11 #----------------------------------------------------------------------
14 A pure-Python wxSizer that lays out items in a grid similar to
15 wxFlexGridSizer but item position is not implicit but explicitly
16 specified by row and col, and row/col spanning is supported.
18 Adapted from code by Niki Spahiev.
20 If anyone is interested, it would be nice to have this ported to C++.
25 from wxPython
.wx
import *
28 #----------------------------------------------------------------------
30 class RowColSizer(wxPySizer
):
32 # default sizes for cells with no item
37 wxPySizer
.__init
__(self
)
38 self
.growableRows
= []
39 self
.growableCols
= []
42 def AddGrowableRow(self
, idx
):
43 self
.growableRows
.append(idx
)
45 def AddGrowableCol(self
, idx
):
46 self
.growableCols
.append(idx
)
50 #--------------------------------------------------
51 def Add(self
, item
, option
=0, flag
=0, border
=0,
52 row
=-1, col
=-1, # row, col and spanning can be specified individually...
54 pos
=None, size
=None, # or as tuples (row,col) and (rowspan,colspan)
60 rowspan
, colspan
= size
62 assert row
!= -1, "Row must be specified"
63 assert col
!= -1, "Column must be specified"
65 # Do I really want to do this? Probably not...
66 #if rowspan > 1 or colspan > 1:
67 # flag = flag | wxEXPAND
69 wxPySizer
.Add(self
, item
, option
, flag
, border
,
70 userData
=(row
, col
, row
+rowspan
, col
+colspan
))
75 def AddSpacer(self
, width
, height
, option
=0, flag
=0, border
=0,
83 rowspan
, colspan
= size
85 assert row
!= -1, "Row must be specified"
86 assert col
!= -1, "Column must be specified"
88 wxPySizer
.AddSpacer(self
, width
, height
, option
, flag
, border
,
89 userData
=(row
, col
, row
+rowspan
, col
+colspan
))
91 #--------------------------------------------------
92 def _add( self
, size
, dim
):
93 r
, c
, r2
, c2
= dim
# unpack coords and spanning
95 # are the widths and heights lists long enough?
96 if r2
> len(self
.rowHeights
):
97 x
= [self
.row_h
] * (r2
-len(self
.rowHeights
))
98 self
.rowHeights
.extend( x
)
99 if c2
> len(self
.colWidths
):
100 x
= [self
.col_w
] * (c2
-len(self
.colWidths
))
101 self
.colWidths
.extend( x
)
103 # set the widths and heights lists for this item
105 for i
in range(r
, r2
):
106 self
.rowHeights
[i
] = max( self
.rowHeights
[i
], size
.height
/ scale
)
108 for i
in range(c
, c2
):
109 self
.colWidths
[i
] = max( self
.colWidths
[i
], size
.width
/ scale
)
112 #--------------------------------------------------
117 items
= self
.GetChildren()
119 return wxSize(10, 10)
122 self
._add
( item
.CalcMin(), item
.GetUserData() )
124 size
= wxSize( reduce( operator
.add
, self
.colWidths
),
125 reduce( operator
.add
, self
.rowHeights
) )
129 #--------------------------------------------------
130 def RecalcSizes( self
):
131 # save current dimensions, etc.
132 curWidth
= self
.GetSize().width
133 curHeight
= self
.GetSize().height
134 px
= self
.GetPosition().x
135 py
= self
.GetPosition().y
136 minWidth
= self
.CalcMin().width
137 minHeight
= self
.CalcMin().height
139 # Check for growables
140 if self
.growableRows
and curHeight
> minHeight
:
141 delta
= (curHeight
- minHeight
) / len(self
.growableRows
)
142 extra
= (curHeight
- minHeight
) % len(self
.growableRows
)
143 for idx
in self
.growableRows
:
144 self
.rowHeights
[idx
] += delta
145 self
.rowHeights
[self
.growableRows
[0]] += extra
147 if self
.growableCols
and curWidth
> minWidth
:
148 delta
= (curWidth
- minWidth
) / len(self
.growableCols
)
149 extra
= (curWidth
- minWidth
) % len(self
.growableCols
)
150 for idx
in self
.growableCols
:
151 self
.colWidths
[idx
] += delta
152 self
.colWidths
[self
.growableCols
[0]] += extra
154 rpos
= [0] * len(self
.rowHeights
)
155 cpos
= [0] * len(self
.colWidths
)
157 for i
in range(len(self
.rowHeights
)):
158 height
= self
.rowHeights
[i
]
162 for i
in range(len(self
.colWidths
)):
163 width
= self
.colWidths
[i
]
167 # iterate children and set dimensions...
168 for item
in self
.GetChildren():
169 r
, c
, r2
, c2
= item
.GetUserData()
170 width
= reduce( operator
.add
, self
.colWidths
[c
:c2
] )
171 height
= reduce( operator
.add
, self
.rowHeights
[r
:r2
] )
172 self
.SetItemBounds( item
, cpos
[c
], rpos
[r
], width
, height
)
175 #--------------------------------------------------
176 def SetItemBounds(self
, item
, x
, y
, w
, h
):
177 # calculate the item's actual size and position within
181 flag
= item
.GetFlag()
183 if flag
& wxEXPAND
or flag
& wxSHAPED
:
186 if flag
& wxALIGN_CENTER_HORIZONTAL
:
187 ipt
.x
= x
+ (w
- isz
.width
) / 2
188 elif flag
& wxALIGN_RIGHT
:
189 ipt
.x
= x
+ (w
- isz
.width
)
191 if flag
& wxALIGN_CENTER_VERTICAL
:
192 ipt
.y
= y
+ (h
- isz
.height
) / 2
193 elif flag
& wxALIGN_BOTTOM
:
194 ipt
.y
= y
+ (h
- isz
.height
)
196 item
.SetDimension(ipt
, isz
)
199 #----------------------------------------------------------------------
200 #----------------------------------------------------------------------