From: Alex T. <al...@tw...> - 2004-09-16 01:20:13
Attachments:
autosize_pyrcsizer.py
|
#---------------------------------------------------------------------- # Name: wxPython.lib.rcsizer # Purpose: RowColSizer: # # Author: Robin Dunn, adapted from code by Niki Spahiev # # further adapted by Alex Tweedly # uses different scheme for allocating space to col(row) from a # component that spans multiple cols(rows). Process all single col items # first, then for spanning items, allocate only additional as needed. # # Also, added the concept of component being able to grow in one dimension only # to better handle things like text fields which shouldn't grow in size in height # even if the row grows for other reasons. !? """ A pure-Python Sizer that lays out items in a grid similar to wx.FlexGridSizer but item position is not implicit but explicitly specified by row and col, and row/col spanning is supported. Adapted from code by Niki Spahiev. """ import operator import wx DEBUG = False #---------------------------------------------------------------------- class RowColSizer(wx.PySizer): # default sizes for cells with no item col_w = 10 row_h = 22 def __init__(self, min_w=10, min_h=22, border=0): wx.PySizer.__init__(self) self.col_w = min_w self.row_h = min_h self.border = border self.growableRows = [] self.growableCols = [] def AddGrowableRow(self, idx): self.growableRows.append(idx) def AddGrowableCol(self, idx): self.growableCols.append(idx) #-------------------------------------------------- def Add(self, item, option=0, flag=0, border=0, # row, col and spanning can be specified individually... row=-1, col=-1, rowspan=1, colspan=1, # or as tuples (row,col) and (rowspan,colspan) pos=None, size=None, growXonly = False ): if pos is not None: row, col = pos if size is not None: rowspan, colspan = size if rowspan == 0: rowspan = 1 if colspan == 0: rowspan = 1 assert row != -1, "Row must be specified" assert col != -1, "Column must be specified" # Do I really want to do this? Probably not... #if rowspan > 1 or colspan > 1: # flag = flag | wx.EXPAND #rint "----", rowspan, colspan, row, col wx.PySizer.Add(self, item, option, flag, border, userData=(row, col, row+rowspan, col+colspan, growXonly)) #AddWindow = Add #AddSizer = Add def AddSpacer(self, width, height, option=0, flag=0, border=0, row=-1, col=-1, rowspan=1, colspan=1, pos=None, size=None, ): if pos is not None: row, col = pos if size is not None: rowspan, colspan = size assert row != -1, "Row must be specified" assert col != -1, "Column must be specified" wx.PySizer.Add(self, (width, height), option, flag, border, userData=(row, col, row+rowspan, col+colspan, False)) #-------------------------------------------------- def _addRow( self, size, r, r2 ): # are the widths and heights lists long enough? if r2 > len(self.rowHeights): x = [self.row_h] * (r2-len(self.rowHeights)) self.rowHeights.extend( x ) # set the widths and heights lists for this item ## if DEBUG: print "rows", r, r2 if r == r2-1: already = self.rowHeights[r] else: already = reduce( operator.add, self.rowHeights[r:r2] ) if DEBUG and False: print "already have", already if already < size.height+2*self.border: scale = (r2 - r) delta = (size.height+2*self.border-already) / scale extra = (size.height+2*self.border-already) % scale for i in range(r, r2): self.rowHeights[i] += delta self.rowHeights[r] += extra if DEBUG and False: print "just added (row) ", size, "at", r,r2, self.rowHeights #-------------------------------------------------- def _addCol( self, size, c, c2 ): # are the widths and heights lists long enough? if c2 > len(self.colWidths): x = [self.col_w] * (c2-len(self.colWidths)) self.colWidths.extend( x ) # set the widths and heights lists for this item ## if DEBUG: print "cols", c, c2 if c == c2-1: already = self.colWidths[c] else: already = reduce( operator.add, self.colWidths[c:c2]) if already < size.width+2*self.border: scale = (c2 - c) delta = (size.width+2*self.border-already) / scale extra = (size.width+2*self.border-already) % scale for i in range(c, c2): self.colWidths[i] += delta self.colWidths[c] += extra if DEBUG: print "just added", size, "at", c, c2, self.colWidths #-------------------------------------------------- def CalcMin( self ): global DEBUG self.rowHeights = [] self.colWidths = [] items = self.GetChildren() if not items: return wx.Size(10, 10) for item in items: r, c, r2, c2, growXonly = item.GetUserData() # unpack coords and spanning if r2 == r+1: if DEBUG: print "do single row", r,r2 self._addRow( item.CalcMin(), r, r2 ) if c2 == c+1: if DEBUG: print "do single col", r,r2 self._addCol( item.CalcMin(), c, c2 ) for item in items: r, c, r2, c2, growXonly = item.GetUserData() # unpack coords and spanning if r2 > r+1: if DEBUG: print "do multi row", r,r2 self._addRow( item.CalcMin(), r, r2 ) if c2 > c+1: if DEBUG: print "do multi col", r,r2 self._addCol( item.CalcMin(), c, c2 ) size = wx.Size( reduce( operator.add, self.colWidths), reduce( operator.add, self.rowHeights) ) if DEBUG: print "Calc min", self.rowHeights, self.colWidths DEBUG=False return size #-------------------------------------------------- def RecalcSizes( self ): # save current dimensions, etc. curWidth, curHeight = self.GetSize() px, py = self.GetPosition() minWidth, minHeight = self.CalcMin() # Check for growables if self.growableRows and curHeight > minHeight: delta = (curHeight - minHeight) / len(self.growableRows) extra = (curHeight - minHeight) % len(self.growableRows) for idx in self.growableRows: self.rowHeights[idx] += delta self.rowHeights[self.growableRows[0]] += extra if self.growableCols and curWidth > minWidth: delta = (curWidth - minWidth) / len(self.growableCols) extra = (curWidth - minWidth) % len(self.growableCols) for idx in self.growableCols: self.colWidths[idx] += delta self.colWidths[self.growableCols[0]] += extra rpos = [0] * len(self.rowHeights) cpos = [0] * len(self.colWidths) for i in range(len(self.rowHeights)): height = self.rowHeights[i] rpos[i] = py py += height for i in range(len(self.colWidths)): width = self.colWidths[i] cpos[i] = px px += width # iterate children and set dimensions... for item in self.GetChildren(): r, c, r2, c2, growXonly = item.GetUserData() if DEBUG: print "reduce in recalc", r, r2, "and cols", c, c2, item width = reduce( operator.add, self.colWidths[c:c2] ) height = reduce( operator.add, self.rowHeights[r:r2] ) starty = rpos[r] if growXonly: ix, newHeight = item.CalcMin() if DEBUG: print "replacing ", height, " by ", newHeight starty = starty + (height-newHeight)/2 height = newHeight self.SetItemBounds( item, cpos[c], starty, width, height ) #-------------------------------------------------- def SetItemBounds(self, item, x, y, w, h): # calculate the item's actual size and position within # its grid cell ipt = wx.Point(x, y) isz = item.CalcMin() flag = item.GetFlag() if flag & wx.EXPAND or flag & wx.SHAPED: isz = wx.Size(w, h) else: if flag & wx.ALIGN_CENTER_HORIZONTAL: ipt.x = x + (w - isz.width) / 2 elif flag & wx.ALIGN_RIGHT: ipt.x = x + (w - isz.width) if flag & wx.ALIGN_CENTER_VERTICAL: ipt.y = y + (h - isz.height) / 2 elif flag & wx.ALIGN_BOTTOM: ipt.y = y + (h - isz.height) item.SetDimension(ipt, isz) #---------------------------------------------------------------------- #---------------------------------------------------------------------- |
From: Alex T. <al...@tw...> - 2004-09-16 01:48:27
|
At 02:30 16/09/2004 +0100, Alex Tweedly wrote: >WARNING: The remainder of this message has not been transferred. >The estimated size of this message is 41479 bytes. Oops - sorry, didn't realize that was so big, or I'd have ZIPped it. Here's my first example using the notebook component - lets you view multiple csv files, one per tab of the notebook. You can only open and close them for now, but it does show setting status bar, title, opening and closing pages, etc. And, of course, it resizes them - using the autosizer (also included in the zip file). The resizing is imperfect - sometimes the initial open of a csv file doesn't fill the page - but as soon as you resize it, that comes right. NOTE - this uses an up-to-date from CVS version of Pythoncard - it depends on at least one of the changes made since the very first appearance of notebook. -- Alex. |