SetBestFittingSize --> SetInitialSize SetBestSize --> SetInitialSize SetInitialBestSize --> SetInitialSize git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42816 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			121 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #----------------------------------------------------------------------------
 | |
| # Name:         scrolledpanel.py
 | |
| # Author:       Will Sadkin
 | |
| # Created:      03/21/2003
 | |
| # Copyright:    (c) 2003 by Will Sadkin
 | |
| # RCS-ID:       $Id$
 | |
| # License:      wxWindows license
 | |
| #----------------------------------------------------------------------------
 | |
| # 12/11/2003 - Jeff Grimmett (grimmtooth@softhome.net)
 | |
| #
 | |
| # o 2.5 compatability update.
 | |
| #
 | |
| # 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
 | |
| #
 | |
| # o wxScrolledPanel -> ScrolledPanel
 | |
| #
 | |
| 
 | |
| import  wx
 | |
| 
 | |
| 
 | |
| class ScrolledPanel( wx.PyScrolledWindow ):
 | |
| 
 | |
|     """ ScrolledPanel fills a "hole" in the implementation of
 | |
|     wx.ScrolledWindow, providing automatic scrollbar and scrolling
 | |
|     behavior and the tab traversal management that wxScrolledWindow
 | |
|     lacks.  This code was based on the original demo code showing how
 | |
|     to do this, but is now available for general use as a proper class
 | |
|     (and the demo is now converted to just use it.)
 | |
| 
 | |
|     It is assumed that the ScrolledPanel will have a sizer, as it is
 | |
|     used to calculate the minimal virtual size of the panel and etc.
 | |
|     """
 | |
|     
 | |
|     def __init__(self, parent, id=-1, pos = wx.DefaultPosition,
 | |
|                  size = wx.DefaultSize, style = wx.TAB_TRAVERSAL,
 | |
|                  name = "scrolledpanel"):
 | |
| 
 | |
|         wx.PyScrolledWindow.__init__(self, parent, id,
 | |
|                                      pos=pos, size=size,
 | |
|                                      style=style, name=name)
 | |
|         self.SetInitialSize(size)
 | |
|         self.Bind(wx.EVT_CHILD_FOCUS, self.OnChildFocus)
 | |
| 
 | |
| 
 | |
|     def SetupScrolling(self, scroll_x=True, scroll_y=True, rate_x=20, rate_y=20):
 | |
|         """
 | |
|         This function sets up the event handling necessary to handle
 | |
|         scrolling properly. It should be called within the __init__
 | |
|         function of any class that is derived from ScrolledPanel,
 | |
|         once the controls on the panel have been constructed and
 | |
|         thus the size of the scrolling area can be determined.
 | |
| 
 | |
|         """
 | |
|         # The following is all that is needed to integrate the sizer and the
 | |
|         # scrolled window.
 | |
|         if not scroll_x: rate_x = 0
 | |
|         if not scroll_y: rate_y = 0
 | |
| 
 | |
|         # Round up the virtual size to be a multiple of the scroll rate
 | |
|         sizer = self.GetSizer()
 | |
|         if sizer:
 | |
|             w, h = sizer.GetMinSize()
 | |
|             if rate_x:
 | |
|                 w += rate_x - (w % rate_x)
 | |
|             if rate_y:
 | |
|                 h += rate_y - (h % rate_y)
 | |
|             self.SetVirtualSize( (w, h) )
 | |
|         self.SetScrollRate(rate_x, rate_y)        
 | |
|         wx.CallAfter(self._SetupAfter) # scroll back to top after initial events
 | |
| 
 | |
| 
 | |
|     def _SetupAfter(self):
 | |
|         self.SetVirtualSize(self.GetBestVirtualSize())
 | |
|         self.Scroll(0,0)
 | |
| 
 | |
| 
 | |
|     def OnChildFocus(self, evt):
 | |
|         # If the child window that gets the focus is not visible,
 | |
|         # this handler will try to scroll enough to see it.
 | |
|         evt.Skip()
 | |
|         child = evt.GetWindow()
 | |
| 
 | |
|         sppu_x, sppu_y = self.GetScrollPixelsPerUnit()
 | |
|         vs_x, vs_y   = self.GetViewStart()
 | |
|         cr = child.GetRect()
 | |
|         clntsz = self.GetClientSize()
 | |
|         new_vs_x, new_vs_y = -1, -1
 | |
| 
 | |
|         # is it before the left edge?
 | |
|         if cr.x < 0 and sppu_x > 0:
 | |
|             new_vs_x = vs_x + (cr.x / sppu_x)
 | |
| 
 | |
|         # is it above the top?
 | |
|         if cr.y < 0 and sppu_y > 0:
 | |
|             new_vs_y = vs_y + (cr.y / sppu_y)
 | |
| 
 | |
|         # For the right and bottom edges, scroll enough to show the
 | |
|         # whole control if possible, but if not just scroll such that
 | |
|         # the top/left edges are still visible
 | |
| 
 | |
|         # is it past the right edge ?
 | |
|         if cr.right > clntsz.width and sppu_x > 0:
 | |
|             diff = (cr.right - clntsz.width) / sppu_x
 | |
|             if cr.x - diff * sppu_x > 0:
 | |
|                 new_vs_x = vs_x + diff + 1
 | |
|             else:
 | |
|                 new_vs_x = vs_x + (cr.x / sppu_x)
 | |
|                 
 | |
|         # is it below the bottom ?
 | |
|         if cr.bottom > clntsz.height and sppu_y > 0:
 | |
|             diff = (cr.bottom - clntsz.height) / sppu_y
 | |
|             if cr.y - diff * sppu_y > 0:
 | |
|                 new_vs_y = vs_y + diff + 1
 | |
|             else:
 | |
|                 new_vs_y = vs_y + (cr.y / sppu_y)
 | |
| 
 | |
|         # if we need to adjust
 | |
|         if new_vs_x != -1 or new_vs_y != -1:
 | |
|             #print "%s: (%s, %s)" % (self.GetName(), new_vs_x, new_vs_y)
 | |
|             self.Scroll(new_vs_x, new_vs_y)
 |