Package mathbench :: Package ext :: Module columnsizer
[hide private]

Source Code for Module mathbench.ext.columnsizer

  1  #----------------------------------------------------------------------------- 
  2  # Name:        columnsizer.py 
  3  # Purpose:     mixin for list controls to resize columns 
  4  # 
  5  # Author:      Rob McMullen  
  6  # Comment:         Modified for mathbench by Thibauld Nion 
  7  # 
  8  # Created:     2007 
  9  # RCS-ID:      $Id: $ 
 10  # Copyright:   (c) 2007 Rob McMullen 
 11  # License:     wxWidgets 
 12  #----------------------------------------------------------------------------- 
 13  """columnsizer -- a mixin to handle column resizing for list controls 
 14   
 15  This mixin provides the capabibility to resize columns in a 
 16  report-mode list control.  Integer flags are used for each column to 
 17  indicate whether the column should be a fixed size or a width 
 18  proportional to te length of the largest item in the column.  It also 
 19  tries (with only some success) to avoid using a horizontal scrollbar 
 20  if at all possible. 
 21  """ 
 22  import wx 
 23  import logging 
 24   
 25   
26 -class ColumnSizerMixin(object):
27 """Enhancement to ListCtrl to handle column resizing. 28 29 Resizes columns to a fixed size or based on the size of the 30 contents, but constrains the whole width to the visible area of 31 the list. Theoretically there won't be any horizontal scrollbars, 32 but this doesnt' yet work on GTK, at least. 33 """
34 - def __init__(self, *args, **kw):
35 self._resize_flags = None 36 self._resize_dirty = True 37 self._last_size = None 38 self.Bind(wx.EVT_SIZE, self.OnSize)
39
40 - def OnSize(self, evt):
41 logging.debug("OnSize recieved event: %s" % evt.GetSize()) 42 if self._last_size is None or self._last_size != evt.GetSize(): 43 self._resize_dirty = True 44 self._last_size = evt.GetSize() 45 wx.CallAfter(self.resizeColumnsIfDirty) 46 evt.Skip()
47
48 - def resizeColumnsIfDirty(self):
49 # OnSize gets called a lot, so only do the column resize one 50 # time unless the data has changed 51 if self._resize_dirty: 52 self._resizeColumns()
53
54 - def resizeColumns(self, flags=[]):
55 try: 56 self._resize_dirty = True 57 self._resizeColumns(flags) 58 except wx._core.PyDeadObjectError: 59 # This happens because an event might be scheduled between 60 # the time the OnSize event is called and the CallAfter 61 # gets around to executing the resizeColumns 62 logging.debug("Caught dead object error for %s" % self) 63 pass
64
65 - def _resizeColumns(self, flags=[]):
66 """Resize each column according to the flag. 67 68 For each column, the respective flag indicates the following: 69 70 0: smallest width that fits the entire string 71 1: smallest width, and keep this column fixed width if possible 72 >1: maximum size 73 <0: absolute value is the minimum size 74 """ 75 if not self._resize_dirty: 76 return 77 self.Freeze() 78 if self._resize_flags is None or len(flags) > 0: 79 # have to make copy of list, otherwise are operating on 80 # the list that's passed in 81 copy = list(flags) 82 if len(copy) < self.GetColumnCount(): 83 copy.extend([0] * (self.GetColumnCount() - len(copy))) 84 self._resize_flags = tuple(copy) 85 logging.debug("Resetting flags to %s" % str(self._resize_flags)) 86 87 flags = self._resize_flags 88 fixed_width = 0 89 total_width = 0 90 num_fixed = 0 91 for col in range(self.GetColumnCount()): 92 self.SetColumnWidth(col, wx.LIST_AUTOSIZE) 93 flag = flags[col] 94 if flag > 1: 95 after = self.GetColumnWidth(col) 96 if after > flag: 97 self.SetColumnWidth(col, flag) 98 elif flag < 0: 99 after = self.GetColumnWidth(col) 100 if after < -flag: 101 self.SetColumnWidth(col, -flag) 102 103 after = self.GetColumnWidth(col) 104 total_width += after 105 if flag == 1: 106 num_fixed += 1 107 fixed_width += after 108 109 # FIXME: column 3 seems to get cut off by a few pixels when 110 # using a bold font. It seems like the SetColumnWidth 111 # algorithm doesn't see the difference in the bold font. 112 w, h = self.GetClientSizeTuple() 113 logging.debug("Client width = %d, fixed_width = %d" % (w, fixed_width)) 114 w -= fixed_width 115 for col in range(self.GetColumnCount()): 116 before = self.GetColumnWidth(col) 117 logging.debug("Col %d: flag=%d before=%d" % (col, flags[col], before)) 118 if flags[col] != 1: 119 self.SetColumnWidth(col, before*w/total_width) 120 self.Thaw() 121 self._resize_dirty = False
122