#---------------------------------------------------------------------- # Name: wxPython.lib.sizers.box # Purpose: A sizer/layout managers for wxPython that places items in # a stretchable box # # Author: Robin Dunn and Dirk Holtwick # # Created: 17-May-1999 # RCS-ID: $Id$ # Copyright: (c) 1998 by Total Control Software # Licence: wxWindows license #---------------------------------------------------------------------- from sizer import wxSizer from wxPython.wx import wxVERTICAL, wxHORIZONTAL #---------------------------------------------------------------------- class wxBoxSizer(wxSizer): """ wxBoxSizer A Sizer that lays components out in a box, in the order they are added to the layout manager, with a given orientation. The orientation is specified in the constructor with either wxVERTICAL or wxHORIZONTAL. The optional parameter to the Add method (for this sizer it's called the stretch flag) can be used to flag one or more components as stretchable, meaning that they will expand to fill available space in the given orientation. The default is zero, or not stretchable. If the stretch flag is non-zero then the widget will stretch. If the sizer holds more than one item that is stretchable then they share the available space. If the strech flag is greater than 1 then it serves as a weighting factor. Widgets with a flag of 2 will get twice as much space as widgets with 1, etc. """ def __init__(self, orientation, size = None): wxSizer.__init__(self, size) self.orientation = orientation def CalcMin(self): self.stretchable = 0 # number of stretchable items self.minWidth = 0 # minimal size self.minHeight = 0 self.fixedWidth = 0 # size without stretched widgets self.fixedHeight = 0 # iterate through children for (isSizer, widget, width, height, stretch) in self.children: weight = 1 if stretch: weight = stretch if isSizer: # let sub-sizers recalc their required space width, height = widget.CalcMin() # minimal size if self.orientation == wxVERTICAL: self.minHeight = self.minHeight + (height * weight) self.minWidth = max(self.minWidth, width) else: self.minWidth = self.minWidth + (width * weight) self.minHeight = max(self.minHeight, height) # stretchable items if stretch: self.stretchable = self.stretchable + weight else: if self.orientation == wxVERTICAL: self.fixedHeight = self.fixedHeight + height self.fixedWidth = max(self.fixedWidth, width) else: self.fixedWidth = self.fixedWidth + width self.fixedHeight = max(self.fixedHeight, height) return self.minWidth, self.minHeight def RecalcSizes(self): # get current dimensions, save for performance myWidth = self.size.width myHeight = self.size.height # relative recent positions & sizes px = self.origin.x py = self.origin.y newWidth = 0 newHeight = 0 # calculate space for one stretched item if self.stretchable: if self.orientation == wxHORIZONTAL: delta = (myWidth - self.fixedWidth) / self.stretchable extra = (myWidth - self.fixedWidth) % self.stretchable else: delta = (myHeight - self.fixedHeight) / self.stretchable extra = (myHeight - self.fixedHeight) % self.stretchable # iterate children ... for (isSizer, widget, width, height, stretch) in self.children: weight = 1 if stretch: weight = stretch if isSizer: width, height = widget.CalcMin() # ... vertical if self.orientation == wxVERTICAL: newHeight = height if stretch: newHeight = (delta * weight) + extra # first stretchable gets extra pixels extra = 0 widget.SetDimensions(px, py, myWidth, newHeight) # ... horizontal elif self.orientation == wxHORIZONTAL: newWidth = width if stretch: newWidth = (delta * weight) + extra # first stretchable gets extra pixels extra = 0 widget.SetDimensions(px, py, newWidth, myHeight) px = px + newWidth py = py + newHeight #----------------------------------------------------------------------