git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5768 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			250 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#----------------------------------------------------------------------
 | 
						|
# Name:        wxPython.lib.grids
 | 
						|
# 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 or flag & wxSHAPED:
 | 
						|
            isz = wxSize(w, h)
 | 
						|
        else:
 | 
						|
            if flag & wxALIGN_CENTER_HORIZONTAL:
 | 
						|
                ipt.x = x + (w - isz.width) / 2
 | 
						|
            elif flag & wxALIGN_RIGHT:
 | 
						|
                ipt.x = x + (w - isz.width)
 | 
						|
 | 
						|
            if flag & wxALIGN_CENTER_VERTICAL:
 | 
						|
                ipt.y = y + (h - isz.height) / 2
 | 
						|
            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
 | 
						|
 | 
						|
        # bottom right corner
 | 
						|
        sz = wxSize(pt.x + sz.width, pt.y + sz.height)
 | 
						|
 | 
						|
        # 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
 | 
						|
 | 
						|
#----------------------------------------------------------------------
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 |