resizes in wxMSW. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33037 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			747 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			747 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #----------------------------------------------------------------------
 | |
| # Name:         multisash
 | |
| # Purpose:      Multi Sash control
 | |
| #
 | |
| # Author:       Gerrit van Dyk
 | |
| #
 | |
| # Created:      2002/11/20
 | |
| # Version:      0.1
 | |
| # RCS-ID:       $Id$
 | |
| # License:      wxWindows license
 | |
| #----------------------------------------------------------------------
 | |
| # 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
 | |
| #
 | |
| # o 2.5 compatability update.
 | |
| #
 | |
| # 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
 | |
| #
 | |
| # o wxMultiSash -> MultiSash
 | |
| # o wxMultiSplit -> MultiSplit 
 | |
| # o wxMultiViewLeaf -> MultiViewLeaf
 | |
| #
 | |
| 
 | |
| import wx
 | |
| 
 | |
| MV_HOR = 0
 | |
| MV_VER = not MV_HOR
 | |
| 
 | |
| SH_SIZE = 5
 | |
| CR_SIZE = SH_SIZE * 3
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| class MultiSash(wx.Window):
 | |
|     def __init__(self, *_args,**_kwargs):
 | |
|         apply(wx.Window.__init__,(self,) + _args,_kwargs)
 | |
|         self._defChild = EmptyChild
 | |
|         self.child = MultiSplit(self,self,(0,0),self.GetSize())
 | |
|         self.Bind(wx.EVT_SIZE,self.OnMultiSize)
 | |
| 
 | |
|     def SetDefaultChildClass(self,childCls):
 | |
|         self._defChild = childCls
 | |
|         self.child.DefaultChildChanged()
 | |
| 
 | |
|     def OnMultiSize(self,evt):
 | |
|         self.child.SetSize(self.GetSize())
 | |
| 
 | |
|     def UnSelect(self):
 | |
|         self.child.UnSelect()
 | |
| 
 | |
|     def Clear(self):
 | |
|         old = self.child
 | |
|         self.child = MultiSplit(self,self,(0,0),self.GetSize())
 | |
|         old.Destroy()
 | |
|         self.child.OnSize(None)
 | |
| 
 | |
|     def GetSaveData(self):
 | |
|         saveData = {}
 | |
|         saveData['_defChild_class'] = self._defChild.__name__
 | |
|         saveData['_defChild_mod']   = self._defChild.__module__
 | |
|         saveData['child'] = self.child.GetSaveData()
 | |
|         return saveData
 | |
| 
 | |
|     def SetSaveData(self,data):
 | |
|         mod = data['_defChild_mod']
 | |
|         dChild = mod + '.' + data['_defChild_class']
 | |
|         exec 'import %s' % mod
 | |
|         self._defChild = eval(dChild)
 | |
|         old = self.child
 | |
|         self.child = MultiSplit(self,self,wx.Point(0,0),self.GetSize())
 | |
|         self.child.SetSaveData(data['child'])
 | |
|         old.Destroy()
 | |
|         self.OnMultiSize(None)
 | |
|         self.child.OnSize(None)
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| class MultiSplit(wx.Window):
 | |
|     def __init__(self,multiView,parent,pos,size,view1 = None):
 | |
|         wx.Window.__init__(self,id = -1,parent = parent,pos = pos,size = size,
 | |
|                           style = wx.CLIP_CHILDREN)
 | |
|         self.multiView = multiView
 | |
|         self.view2 = None
 | |
|         if view1:
 | |
|             self.view1 = view1
 | |
|             self.view1.Reparent(self)
 | |
|             self.view1.MoveXY(0,0)
 | |
|         else:
 | |
|             self.view1 = MultiViewLeaf(self.multiView,self,
 | |
|                                          (0,0),self.GetSize())
 | |
|         self.direction = None
 | |
| 
 | |
|         self.Bind(wx.EVT_SIZE,self.OnSize)
 | |
| 
 | |
|     def GetSaveData(self):
 | |
|         saveData = {}
 | |
|         if self.view1:
 | |
|             saveData['view1'] = self.view1.GetSaveData()
 | |
|             if isinstance(self.view1,MultiSplit):
 | |
|                 saveData['view1IsSplit'] = 1
 | |
|         if self.view2:
 | |
|             saveData['view2'] = self.view2.GetSaveData()
 | |
|             if isinstance(self.view2,MultiSplit):
 | |
|                 saveData['view2IsSplit'] = 1
 | |
|         saveData['direction'] = self.direction
 | |
|         v1,v2 = self.GetPosition()
 | |
|         saveData['x'] = v1
 | |
|         saveData['y'] = v2
 | |
|         v1,v2 = self.GetSize()
 | |
|         saveData['w'] = v1
 | |
|         saveData['h'] = v2
 | |
|         return saveData
 | |
| 
 | |
|     def SetSaveData(self,data):
 | |
|         self.direction = data['direction']
 | |
|         self.SetDimensions(int(data['x']), int(data['y']), int(data['w']), int(data['h']))
 | |
|         v1Data = data.get('view1',None)
 | |
|         if v1Data:
 | |
|             isSplit = data.get('view1IsSplit',None)
 | |
|             old = self.view1
 | |
|             if isSplit:
 | |
|                 self.view1 = MultiSplit(self.multiView,self,
 | |
|                                           (0,0),self.GetSize())
 | |
|             else:
 | |
|                 self.view1 = MultiViewLeaf(self.multiView,self,
 | |
|                                              (0,0),self.GetSize())
 | |
|             self.view1.SetSaveData(v1Data)
 | |
|             if old:
 | |
|                 old.Destroy()
 | |
|         v2Data = data.get('view2',None)
 | |
|         if v2Data:
 | |
|             isSplit = data.get('view2IsSplit',None)
 | |
|             old = self.view2
 | |
|             if isSplit:
 | |
|                 self.view2 = MultiSplit(self.multiView,self,
 | |
|                                           (0,0),self.GetSize())
 | |
|             else:
 | |
|                 self.view2 = MultiViewLeaf(self.multiView,self,
 | |
|                                              (0,0),self.GetSize())
 | |
|             self.view2.SetSaveData(v2Data)
 | |
|             if old:
 | |
|                 old.Destroy()
 | |
|         if self.view1:
 | |
|             self.view1.OnSize(None)
 | |
|         if self.view2:
 | |
|             self.view2.OnSize(None)
 | |
| 
 | |
|     def UnSelect(self):
 | |
|         if self.view1:
 | |
|             self.view1.UnSelect()
 | |
|         if self.view2:
 | |
|             self.view2.UnSelect()
 | |
| 
 | |
|     def DefaultChildChanged(self):
 | |
|         if not self.view2:
 | |
|             self.view1.DefaultChildChanged()
 | |
| 
 | |
|     def AddLeaf(self,direction,caller,pos):
 | |
|         if self.view2:
 | |
|             if caller == self.view1:
 | |
|                 self.view1 = MultiSplit(self.multiView,self,
 | |
|                                           caller.GetPosition(),
 | |
|                                           caller.GetSize(),
 | |
|                                           caller)
 | |
|                 self.view1.AddLeaf(direction,caller,pos)
 | |
|             else:
 | |
|                 self.view2 = MultiSplit(self.multiView,self,
 | |
|                                           caller.GetPosition(),
 | |
|                                           caller.GetSize(),
 | |
|                                           caller)
 | |
|                 self.view2.AddLeaf(direction,caller,pos)
 | |
|         else:
 | |
|             self.direction = direction
 | |
|             w,h = self.GetSize()
 | |
|             if direction == MV_HOR:
 | |
|                 x,y = (pos,0)
 | |
|                 w1,h1 = (w-pos,h)
 | |
|                 w2,h2 = (pos,h)
 | |
|             else:
 | |
|                 x,y = (0,pos)
 | |
|                 w1,h1 = (w,h-pos)
 | |
|                 w2,h2 = (w,pos)
 | |
|             self.view2 = MultiViewLeaf(self.multiView, self, (x,y), (w1,h1))
 | |
|             self.view1.SetSize((w2,h2))
 | |
|             self.view2.OnSize(None)
 | |
| 
 | |
|     def DestroyLeaf(self,caller):
 | |
|         if not self.view2:              # We will only have 2 windows if
 | |
|             return                      # we need to destroy any
 | |
|         parent = self.GetParent()       # Another splitview
 | |
|         if parent == self.multiView:    # We'r at the root
 | |
|             if caller == self.view1:
 | |
|                 old = self.view1
 | |
|                 self.view1 = self.view2
 | |
|                 self.view2 = None
 | |
|                 old.Destroy()
 | |
|             else:
 | |
|                 self.view2.Destroy()
 | |
|                 self.view2 = None
 | |
|             self.view1.SetSize(self.GetSize())
 | |
|             self.view1.Move(self.GetPosition())
 | |
|         else:
 | |
|             w,h = self.GetSize()
 | |
|             x,y = self.GetPosition()
 | |
|             if caller == self.view1:
 | |
|                 if self == parent.view1:
 | |
|                     parent.view1 = self.view2
 | |
|                 else:
 | |
|                     parent.view2 = self.view2
 | |
|                 self.view2.Reparent(parent)
 | |
|                 self.view2.SetDimensions(x,y,w,h)
 | |
|             else:
 | |
|                 if self == parent.view1:
 | |
|                     parent.view1 = self.view1
 | |
|                 else:
 | |
|                     parent.view2 = self.view1
 | |
|                 self.view1.Reparent(parent)
 | |
|                 self.view1.SetDimensions(x,y,w,h)
 | |
|             self.view1 = None
 | |
|             self.view2 = None
 | |
|             self.Destroy()
 | |
| 
 | |
|     def CanSize(self,side,view):
 | |
|         if self.SizeTarget(side,view):
 | |
|             return True
 | |
|         return False
 | |
| 
 | |
|     def SizeTarget(self,side,view):
 | |
|         if self.direction == side and self.view2 and view == self.view1:
 | |
|             return self
 | |
|         parent = self.GetParent()
 | |
|         if parent != self.multiView:
 | |
|             return parent.SizeTarget(side,self)
 | |
|         return None
 | |
| 
 | |
|     def SizeLeaf(self,leaf,pos,side):
 | |
|         if self.direction != side:
 | |
|             return
 | |
|         if not (self.view1 and self.view2):
 | |
|             return
 | |
|         if pos < 10: return
 | |
|         w,h = self.GetSize()
 | |
|         if side == MV_HOR:
 | |
|             if pos > w - 10: return
 | |
|         else:
 | |
|             if pos > h - 10: return
 | |
|         if side == MV_HOR:
 | |
|             self.view1.SetDimensions(0,0,pos,h)
 | |
|             self.view2.SetDimensions(pos,0,w-pos,h)
 | |
|         else:
 | |
|             self.view1.SetDimensions(0,0,w,pos)
 | |
|             self.view2.SetDimensions(0,pos,w,h-pos)
 | |
| 
 | |
|     def OnSize(self,evt):
 | |
|         if not self.view2:
 | |
|             self.view1.SetSize(self.GetSize())
 | |
|             self.view1.OnSize(None)
 | |
|             return
 | |
|         v1w,v1h = self.view1.GetSize()
 | |
|         v2w,v2h = self.view2.GetSize()
 | |
|         v1x,v1y = self.view1.GetPosition()
 | |
|         v2x,v2y = self.view2.GetPosition()
 | |
|         w,h = self.GetSize()
 | |
| 
 | |
|         if v1x != v2x:
 | |
|             ratio = float(w) / float((v1w + v2w))
 | |
|             v1w *= ratio
 | |
|             v2w = w - v1w
 | |
|             v2x = v1w
 | |
|         else:
 | |
|             v1w = v2w = w
 | |
| 
 | |
|         if v1y != v2y:
 | |
|             ratio = float(h) / float((v1h + v2h))
 | |
|             v1h *= ratio
 | |
|             v2h = h - v1h
 | |
|             v2y = v1h
 | |
|         else:
 | |
|             v1h = v2h = h
 | |
| 
 | |
|         self.view1.SetDimensions(int(v1x), int(v1y), int(v1w), int(v1h))
 | |
|         self.view2.SetDimensions(int(v2x), int(v2y), int(v2w), int(v2h))
 | |
|         self.view1.OnSize(None)
 | |
|         self.view2.OnSize(None)
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| class MultiViewLeaf(wx.Window):
 | |
|     def __init__(self,multiView,parent,pos,size):
 | |
|         wx.Window.__init__(self,id = -1,parent = parent,pos = pos,size = size,
 | |
|                           style = wx.CLIP_CHILDREN)
 | |
|         self.multiView = multiView
 | |
| 
 | |
|         self.sizerHor = MultiSizer(self,MV_HOR)
 | |
|         self.sizerVer = MultiSizer(self,MV_VER)
 | |
|         self.creatorHor = MultiCreator(self,MV_HOR)
 | |
|         self.creatorVer = MultiCreator(self,MV_VER)
 | |
|         self.detail = MultiClient(self,multiView._defChild)
 | |
|         self.closer = MultiCloser(self)
 | |
| 
 | |
|         self.Bind(wx.EVT_SIZE,self.OnSize)
 | |
| 
 | |
|         self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE))
 | |
| 
 | |
| 
 | |
|     def GetSaveData(self):
 | |
|         saveData = {}
 | |
|         saveData['detailClass_class'] = self.detail.child.__class__.__name__
 | |
|         saveData['detailClass_mod'] = self.detail.child.__module__
 | |
|         if hasattr(self.detail.child,'GetSaveData'):
 | |
|             attr = getattr(self.detail.child,'GetSaveData')
 | |
|             if callable(attr):
 | |
|                 dData = attr()
 | |
|                 if dData:
 | |
|                     saveData['detail'] = dData
 | |
|         v1,v2 = self.GetPosition()
 | |
|         saveData['x'] = v1
 | |
|         saveData['y'] = v2
 | |
|         v1,v2 = self.GetSize()
 | |
|         saveData['w'] = v1
 | |
|         saveData['h'] = v2
 | |
|         return saveData
 | |
| 
 | |
|     def SetSaveData(self,data):
 | |
|         mod = data['detailClass_mod']
 | |
|         dChild = mod + '.' + data['detailClass_class']
 | |
|         exec 'import %s' % mod
 | |
|         detClass = eval(dChild)
 | |
|         self.SetDimensions(data['x'],data['y'],data['w'],data['h'])
 | |
|         old = self.detail
 | |
|         self.detail = MultiClient(self,detClass)
 | |
|         dData = data.get('detail',None)
 | |
|         if dData:
 | |
|             if hasattr(self.detail.child,'SetSaveData'):
 | |
|                 attr = getattr(self.detail.child,'SetSaveData')
 | |
|                 if callable(attr):
 | |
|                     attr(dData)
 | |
|         old.Destroy()
 | |
|         self.detail.OnSize(None)
 | |
| 
 | |
|     def UnSelect(self):
 | |
|         self.detail.UnSelect()
 | |
| 
 | |
|     def DefaultChildChanged(self):
 | |
|         self.detail.SetNewChildCls(self.multiView._defChild)
 | |
| 
 | |
|     def AddLeaf(self,direction,pos):
 | |
|         if pos < 10: return
 | |
|         w,h = self.GetSize()
 | |
|         if direction == MV_VER:
 | |
|             if pos > h - 10: return
 | |
|         else:
 | |
|             if pos > w - 10: return
 | |
|         self.GetParent().AddLeaf(direction,self,pos)
 | |
| 
 | |
|     def DestroyLeaf(self):
 | |
|         self.GetParent().DestroyLeaf(self)
 | |
| 
 | |
|     def SizeTarget(self,side):
 | |
|         return self.GetParent().SizeTarget(side,self)
 | |
| 
 | |
|     def CanSize(self,side):
 | |
|         return self.GetParent().CanSize(side,self)
 | |
| 
 | |
|     def OnSize(self,evt):
 | |
|         def doresize():
 | |
|             try:
 | |
|                 self.sizerHor.OnSize(evt)
 | |
|                 self.sizerVer.OnSize(evt)
 | |
|                 self.creatorHor.OnSize(evt)
 | |
|                 self.creatorVer.OnSize(evt)
 | |
|                 self.detail.OnSize(evt)
 | |
|                 self.closer.OnSize(evt)
 | |
|             except:
 | |
|                 pass
 | |
|         wx.CallAfter(doresize)
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| class MultiClient(wx.Window):
 | |
|     def __init__(self,parent,childCls):
 | |
|         w,h = self.CalcSize(parent)
 | |
|         wx.Window.__init__(self,id = -1,parent = parent,
 | |
|                           pos = (0,0),
 | |
|                           size = (w,h),
 | |
|                           style = wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)
 | |
|         self.child = childCls(self)
 | |
|         self.child.MoveXY(2,2)
 | |
|         self.normalColour = self.GetBackgroundColour()
 | |
|         self.selected = False
 | |
| 
 | |
|         self.Bind(wx.EVT_SET_FOCUS,self.OnSetFocus)
 | |
|         self.Bind(wx.EVT_CHILD_FOCUS,self.OnChildFocus)
 | |
| 
 | |
|     def UnSelect(self):
 | |
|         if self.selected:
 | |
|             self.selected = False
 | |
|             self.SetBackgroundColour(self.normalColour)
 | |
|             self.Refresh()
 | |
| 
 | |
|     def Select(self):
 | |
|         self.GetParent().multiView.UnSelect()
 | |
|         self.selected = True
 | |
|         self.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow
 | |
|         self.Refresh()
 | |
| 
 | |
|     def CalcSize(self,parent):
 | |
|         w,h = parent.GetSize()
 | |
|         w -= SH_SIZE
 | |
|         h -= SH_SIZE
 | |
|         return (w,h)
 | |
| 
 | |
|     def OnSize(self,evt):
 | |
|         w,h = self.CalcSize(self.GetParent())
 | |
|         self.SetDimensions(0,0,w,h)
 | |
|         w,h = self.GetClientSize()
 | |
|         self.child.SetSize((w-4,h-4))
 | |
| 
 | |
|     def SetNewChildCls(self,childCls):
 | |
|         if self.child:
 | |
|             self.child.Destroy()
 | |
|             self.child = None
 | |
|         self.child = childCls(self)
 | |
|         self.child.MoveXY(2,2)
 | |
| 
 | |
|     def OnSetFocus(self,evt):
 | |
|         self.Select()
 | |
| 
 | |
|     def OnChildFocus(self,evt):
 | |
|         self.OnSetFocus(evt)
 | |
| ##        from Funcs import FindFocusedChild
 | |
| ##        child = FindFocusedChild(self)
 | |
| ##        child.Bind(wx.EVT_KILL_FOCUS,self.OnChildKillFocus)
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| class MultiSizer(wx.Window):
 | |
|     def __init__(self,parent,side):
 | |
|         self.side = side
 | |
|         x,y,w,h = self.CalcSizePos(parent)
 | |
|         wx.Window.__init__(self,id = -1,parent = parent,
 | |
|                           pos = (x,y),
 | |
|                           size = (w,h),
 | |
|                           style = wx.CLIP_CHILDREN)
 | |
| 
 | |
|         self.px = None                  # Previous X
 | |
|         self.py = None                  # Previous Y
 | |
|         self.isDrag = False             # In Dragging
 | |
|         self.dragTarget = None          # View being sized
 | |
| 
 | |
|         self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
 | |
|         self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
 | |
|         self.Bind(wx.EVT_MOTION,self.OnMouseMove)
 | |
|         self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
 | |
|         self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
 | |
| 
 | |
|         self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE))
 | |
| 
 | |
| 
 | |
|     def CalcSizePos(self,parent):
 | |
|         pw,ph = parent.GetSize()
 | |
|         if self.side == MV_HOR:
 | |
|             x = CR_SIZE + 2
 | |
|             y = ph - SH_SIZE
 | |
|             w = pw - CR_SIZE - SH_SIZE - 2
 | |
|             h = SH_SIZE
 | |
|         else:
 | |
|             x = pw - SH_SIZE
 | |
|             y = CR_SIZE + 2 + SH_SIZE
 | |
|             w = SH_SIZE
 | |
|             h = ph - CR_SIZE - SH_SIZE - 4 - SH_SIZE # For Closer
 | |
|         return (x,y,w,h)
 | |
| 
 | |
|     def OnSize(self,evt):
 | |
|         x,y,w,h = self.CalcSizePos(self.GetParent())
 | |
|         self.SetDimensions(x,y,w,h)
 | |
| 
 | |
|     def OnLeave(self,evt):
 | |
|         self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
 | |
| 
 | |
|     def OnEnter(self,evt):
 | |
|         if not self.GetParent().CanSize(not self.side):
 | |
|             return
 | |
|         if self.side == MV_HOR:
 | |
|             self.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS))
 | |
|         else:
 | |
|             self.SetCursor(wx.StockCursor(wx.CURSOR_SIZEWE))
 | |
| 
 | |
|     def OnMouseMove(self,evt):
 | |
|         if self.isDrag:
 | |
|             DrawSash(self.dragTarget,self.px,self.py,self.side)
 | |
|             self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
 | |
|             self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py)
 | |
|             DrawSash(self.dragTarget,self.px,self.py,self.side)
 | |
|         else:
 | |
|             evt.Skip()
 | |
| 
 | |
|     def OnPress(self,evt):
 | |
|         self.dragTarget = self.GetParent().SizeTarget(not self.side)
 | |
|         if self.dragTarget:
 | |
|             self.isDrag = True
 | |
|             self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
 | |
|             self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py)
 | |
|             DrawSash(self.dragTarget,self.px,self.py,self.side)
 | |
|             self.CaptureMouse()
 | |
|         else:
 | |
|             evt.Skip()
 | |
| 
 | |
|     def OnRelease(self,evt):
 | |
|         if self.isDrag:
 | |
|             DrawSash(self.dragTarget,self.px,self.py,self.side)
 | |
|             self.ReleaseMouse()
 | |
|             self.isDrag = False
 | |
|             if self.side == MV_HOR:
 | |
|                 self.dragTarget.SizeLeaf(self.GetParent(),
 | |
|                                          self.py,not self.side)
 | |
|             else:
 | |
|                 self.dragTarget.SizeLeaf(self.GetParent(),
 | |
|                                          self.px,not self.side)
 | |
|             self.dragTarget = None
 | |
|         else:
 | |
|             evt.Skip()
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| class MultiCreator(wx.Window):
 | |
|     def __init__(self,parent,side):
 | |
|         self.side = side
 | |
|         x,y,w,h = self.CalcSizePos(parent)
 | |
|         wx.Window.__init__(self,id = -1,parent = parent,
 | |
|                           pos = (x,y),
 | |
|                           size = (w,h),
 | |
|                           style = wx.CLIP_CHILDREN)
 | |
| 
 | |
|         self.px = None                  # Previous X
 | |
|         self.py = None                  # Previous Y
 | |
|         self.isDrag = False           # In Dragging
 | |
| 
 | |
|         self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
 | |
|         self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
 | |
|         self.Bind(wx.EVT_MOTION,self.OnMouseMove)
 | |
|         self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
 | |
|         self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
 | |
|         self.Bind(wx.EVT_PAINT,self.OnPaint)
 | |
| 
 | |
|     def CalcSizePos(self,parent):
 | |
|         pw,ph = parent.GetSize()
 | |
|         if self.side == MV_HOR:
 | |
|             x = 2
 | |
|             y = ph - SH_SIZE
 | |
|             w = CR_SIZE
 | |
|             h = SH_SIZE
 | |
|         else:
 | |
|             x = pw - SH_SIZE
 | |
|             y = 4 + SH_SIZE             # Make provision for closer
 | |
|             w = SH_SIZE
 | |
|             h = CR_SIZE
 | |
|         return (x,y,w,h)
 | |
| 
 | |
|     def OnSize(self,evt):
 | |
|         x,y,w,h = self.CalcSizePos(self.GetParent())
 | |
|         self.SetDimensions(x,y,w,h)
 | |
| 
 | |
|     def OnLeave(self,evt):
 | |
|         self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
 | |
| 
 | |
|     def OnEnter(self,evt):
 | |
|         if self.side == MV_HOR:
 | |
|             self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
 | |
|         else:
 | |
|             self.SetCursor(wx.StockCursor(wx.CURSOR_POINT_LEFT))
 | |
| 
 | |
|     def OnMouseMove(self,evt):
 | |
|         if self.isDrag:
 | |
|             parent = self.GetParent()
 | |
|             DrawSash(parent,self.px,self.py,self.side)
 | |
|             self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
 | |
|             self.px,self.py = parent.ScreenToClientXY(self.px,self.py)
 | |
|             DrawSash(parent,self.px,self.py,self.side)
 | |
|         else:
 | |
|             evt.Skip()
 | |
| 
 | |
|     def OnPress(self,evt):
 | |
|         self.isDrag = True
 | |
|         parent = self.GetParent()
 | |
|         self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
 | |
|         self.px,self.py = parent.ScreenToClientXY(self.px,self.py)
 | |
|         DrawSash(parent,self.px,self.py,self.side)
 | |
|         self.CaptureMouse()
 | |
| 
 | |
|     def OnRelease(self,evt):
 | |
|         if self.isDrag:
 | |
|             parent = self.GetParent()
 | |
|             DrawSash(parent,self.px,self.py,self.side)
 | |
|             self.ReleaseMouse()
 | |
|             self.isDrag = False
 | |
| 
 | |
|             if self.side == MV_HOR:
 | |
|                 parent.AddLeaf(MV_VER,self.py)
 | |
|             else:
 | |
|                 parent.AddLeaf(MV_HOR,self.px)
 | |
|         else:
 | |
|             evt.Skip()
 | |
| 
 | |
|     def OnPaint(self,evt):
 | |
|         dc = wx.PaintDC(self)
 | |
|         dc.SetBackground(wx.Brush(self.GetBackgroundColour(),wx.SOLID))
 | |
|         dc.Clear()
 | |
| 
 | |
|         highlight = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT), 1, wx.SOLID)
 | |
|         shadow = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW), 1, wx.SOLID)
 | |
|         black = wx.Pen(wx.BLACK,1,wx.SOLID)
 | |
|         w,h = self.GetSize()
 | |
|         w -= 1
 | |
|         h -= 1
 | |
| 
 | |
|         # Draw outline
 | |
|         dc.SetPen(highlight)
 | |
|         dc.DrawLine(0,0, 0,h)
 | |
|         dc.DrawLine(0,0, w,0)
 | |
|         dc.SetPen(black)
 | |
|         dc.DrawLine(0,h, w+1,h)
 | |
|         dc.DrawLine(w,0, w,h)
 | |
|         dc.SetPen(shadow)
 | |
|         dc.DrawLine(w-1,2, w-1,h)
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| class MultiCloser(wx.Window):
 | |
|     def __init__(self,parent):
 | |
|         x,y,w,h = self.CalcSizePos(parent)
 | |
|         wx.Window.__init__(self,id = -1,parent = parent,
 | |
|                           pos = (x,y),
 | |
|                           size = (w,h),
 | |
|                           style = wx.CLIP_CHILDREN)
 | |
| 
 | |
|         self.down = False
 | |
|         self.entered = False
 | |
| 
 | |
|         self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
 | |
|         self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
 | |
|         self.Bind(wx.EVT_PAINT,self.OnPaint)
 | |
|         self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
 | |
|         self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
 | |
| 
 | |
|     def OnLeave(self,evt):
 | |
|         self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
 | |
|         self.entered = False
 | |
| 
 | |
|     def OnEnter(self,evt):
 | |
|         self.SetCursor(wx.StockCursor(wx.CURSOR_BULLSEYE))
 | |
|         self.entered = True
 | |
| 
 | |
|     def OnPress(self,evt):
 | |
|         self.down = True
 | |
|         evt.Skip()
 | |
| 
 | |
|     def OnRelease(self,evt):
 | |
|         if self.down and self.entered:
 | |
|             self.GetParent().DestroyLeaf()
 | |
|         else:
 | |
|             evt.Skip()
 | |
|         self.down = False
 | |
| 
 | |
|     def OnPaint(self,evt):
 | |
|         dc = wx.PaintDC(self)
 | |
|         dc.SetBackground(wx.Brush(wx.RED,wx.SOLID))
 | |
|         dc.Clear()
 | |
| 
 | |
|     def CalcSizePos(self,parent):
 | |
|         pw,ph = parent.GetSize()
 | |
|         x = pw - SH_SIZE
 | |
|         w = SH_SIZE
 | |
|         h = SH_SIZE + 2
 | |
|         y = 1
 | |
|         return (x,y,w,h)
 | |
| 
 | |
|     def OnSize(self,evt):
 | |
|         x,y,w,h = self.CalcSizePos(self.GetParent())
 | |
|         self.SetDimensions(x,y,w,h)
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| class EmptyChild(wx.Window):
 | |
|     def __init__(self,parent):
 | |
|         wx.Window.__init__(self,parent,-1, style = wx.CLIP_CHILDREN)
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| def DrawSash(win,x,y,direction):
 | |
|     dc = wx.ScreenDC()
 | |
|     dc.StartDrawingOnTopWin(win)
 | |
|     bmp = wx.EmptyBitmap(8,8)
 | |
|     bdc = wx.MemoryDC()
 | |
|     bdc.SelectObject(bmp)
 | |
|     bdc.DrawRectangle(-1,-1, 10,10)
 | |
|     for i in range(8):
 | |
|         for j in range(8):
 | |
|             if ((i + j) & 1):
 | |
|                 bdc.DrawPoint(i,j)
 | |
| 
 | |
|     brush = wx.Brush(wx.Colour(0,0,0))
 | |
|     brush.SetStipple(bmp)
 | |
| 
 | |
|     dc.SetBrush(brush)
 | |
|     dc.SetLogicalFunction(wx.XOR)
 | |
| 
 | |
|     body_w,body_h = win.GetClientSize()
 | |
| 
 | |
|     if y < 0:
 | |
|         y = 0
 | |
|     if y > body_h:
 | |
|         y = body_h
 | |
|     if x < 0:
 | |
|         x = 0
 | |
|     if x > body_w:
 | |
|         x = body_w
 | |
| 
 | |
|     if direction == MV_HOR:
 | |
|         x = 0
 | |
|     else:
 | |
|         y = 0
 | |
| 
 | |
|     x,y = win.ClientToScreenXY(x,y)
 | |
| 
 | |
|     w = body_w
 | |
|     h = body_h
 | |
| 
 | |
|     if direction == MV_HOR:
 | |
|         dc.DrawRectangle(x,y-2, w,4)
 | |
|     else:
 | |
|         dc.DrawRectangle(x-2,y, 4,h)
 | |
| 
 | |
|     dc.EndDrawingOnTop()
 |