wxWidgets/utils/wxPython/lib/grids.py
Robin Dunn 2f90df854e 1. wxHtmlHelpController and related classes
2. the C++ versions of wxSizer and firends, Python versions are
   'depreciated'
3. wxPyEvent and wxPyCommandEvent, event classes that can carry some
   python objects through the event system and safely come back out
   again.
4. wxGridSizer and wxFlexGridSizer
5. wxValidator
6. wxPyOnDemandOutputWindow
7. several tweaks, fixes and additions of missing methods, etc.
8. and probably several other things I am forgetting since CVS was
   down so long...


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3758 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1999-09-30 07:11:20 +00:00

253 lines
7.1 KiB
Python

#----------------------------------------------------------------------
# Name: wxPython.lib.GridSizer
# Purpose: An example sizer derived from the C++ wxPySizer that
# sizes items in a fixed or flexible grid.
#
# Author: Robin Dunn
#
# Created: 21-Sept-1999
# RCS-ID: $Id$
# Copyright: (c) 1999 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
"""
In this module you will find wxGridSizer and wxFlexgridSizer.
wxGridSizer arrainges its items in a grid in which all the widths and
heights are the same. wxFlexgridSizer allows different widths and
heights, and you can also specify rows and/or columns that are
growable. See the demo for a couple examples for how to use them.
"""
from wxPython.wx import *
import operator
#----------------------------------------------------------------------
class wxGridSizer(wxPySizer):
def __init__(self, rows=0, cols=0, hgap=0, vgap=0):
wxPySizer.__init__(self)
if rows == 0 and cols == 0:
raise ValueError, "rows and cols cannot both be zero"
self.rows = rows
self.cols = cols
self.hgap = hgap
self.vgap = vgap
def SetRows(self, rows):
if rows == 0 and self.cols == 0:
raise ValueError, "rows and cols cannot both be zero"
self.rows = rows
def SetColumns(self, cols):
if self.rows == 0 and cols == 0:
raise ValueError, "rows and cols cannot both be zero"
self.cols = cols
def GetRows(self):
return self.rows
def GetColumns(self):
return self.cols
def SetHgap(self, hgap):
self.hgap = hgap
def SetVgap(self, vgap):
self.vgap = vgap
def GetHgap(self, hgap):
return self.hgap
def GetVgap(self, vgap):
return self.vgap
#--------------------------------------------------
def CalcMin(self):
items = self.GetChildren()
nitems = len(items)
nrows = self.rows
ncols = self.cols
if ncols > 0:
nrows = (nitems + ncols-1) / ncols
else:
ncols = (nitems + nrows-1) / nrows
# Find the max width and height for any component.
w = 0
h = 0
for item in items:
size = item.CalcMin()
w = max(w, size.width)
h = max(h, size.height)
return wxSize(ncols * w + (ncols-1) * self.hgap,
nrows * h + (nrows-1) * self.vgap)
#--------------------------------------------------
def RecalcSizes(self):
items = self.GetChildren()
if not items:
return
nitems = len(items)
nrows = self.rows
ncols = self.cols
if ncols > 0:
nrows = (nitems + ncols-1) / ncols
else:
ncols = (nitems + nrows-1) / nrows
sz = self.GetSize()
pt = self.GetPosition()
w = (sz.width - (ncols - 1) * self.hgap) / ncols;
h = (sz.height - (nrows - 1) * self.vgap) / nrows;
x = pt.x
for c in range(ncols):
y = pt.y
for r in range(nrows):
i = r * ncols + c
if i < nitems:
self.SetItemBounds(items[i], x, y, w, h)
y = y + h + self.vgap
x = x + w + self.hgap
#--------------------------------------------------
def SetItemBounds(self, item, x, y, w, h):
# calculate the item's size and position within
# its grid cell
ipt = wxPoint(x, y)
isz = item.CalcMin()
flag = item.GetFlag()
if flag & wxEXPAND:
isz = wxSize(w, h)
elif flag & wxCENTER:
ipt.x = x + (w - isz.width) / 2
ipt.y = y + (h - isz.height) / 2
if flag & wxALIGN_LEFT:
ipt.x = x
elif flag & wxALIGN_RIGHT:
ipt.x = x + (w - isz.width)
if flag & wxALIGN_TOP:
ipt.y = y
elif flag & wxALIGN_BOTTOM:
ipt.y = y + (h - isz.height)
item.SetDimension(ipt, isz)
#----------------------------------------------------------------------
class wxFlexGridSizer(wxGridSizer):
def __init__(self, rows=0, cols=0, hgap=0, vgap=0):
wxGridSizer.__init__(self, rows, cols, hgap, vgap)
self.rowHeights = []
self.colWidths = []
self.growableRows = []
self.growableCols = []
def AddGrowableRow(self, idx):
self.growableRows.append(idx)
def AddGrowableCol(self, idx):
self.growableCols.append(idx)
#--------------------------------------------------
def CalcMin(self):
items = self.GetChildren()
nitems = len(items)
nrows = self.rows
ncols = self.cols
if ncols > 0:
nrows = (nitems + ncols-1) / ncols
else:
ncols = (nitems + nrows-1) / nrows
# Find the max width and height for any component.
self.rowHeights = [0] * nrows
self.colWidths = [0] * ncols
for i in range(len(items)):
size = items[i].CalcMin()
row = i / ncols
col = i % ncols
self.rowHeights[row] = max(size.height, self.rowHeights[row])
self.colWidths[col] = max(size.width, self.colWidths[col])
# Add up all the widths and heights
cellsWidth = reduce(operator.__add__, self.colWidths)
cellHeight = reduce(operator.__add__, self.rowHeights)
return wxSize(cellsWidth + (ncols-1) * self.hgap,
cellHeight + (nrows-1) * self.vgap)
#--------------------------------------------------
def RecalcSizes(self):
items = self.GetChildren()
if not items:
return
nitems = len(items)
nrows = self.rows
ncols = self.cols
if ncols > 0:
nrows = (nitems + ncols-1) / ncols
else:
ncols = (nitems + nrows-1) / nrows
minsz = self.CalcMin()
sz = self.GetSize()
pt = self.GetPosition()
# Check for growables
if self.growableRows and sz.height > minsz.height:
delta = (sz.height - minsz.height) / len(self.growableRows)
for idx in self.growableRows:
self.rowHeights[idx] = self.rowHeights[idx] + delta
if self.growableCols and sz.width > minsz.width:
delta = (sz.width - minsz.width) / len(self.growableCols)
for idx in self.growableCols:
self.colWidths[idx] = self.colWidths[idx] + delta
# Layout each cell
x = pt.x
for c in range(ncols):
y = pt.y
for r in range(nrows):
i = r * ncols + c
if i < nitems:
w = max(0, min(self.colWidths[c], sz.width - x))
h = max(0, min(self.rowHeights[r], sz.height - y))
self.SetItemBounds(items[i], x, y, w, h)
y = y + self.rowHeights[r] + self.vgap
x = x + self.colWidths[c] + self.hgap
#----------------------------------------------------------------------