Added wxPython.lib.multisash by Gerrit van Dyk which is a nice
implementation of allowing the user to split a window any number of times either horizontally or vertically, and to close the split off windows when desired. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@18223 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -65,6 +65,11 @@ wxDialog because of some issues with wxPopupWindow...
|
||||
Added wxPython.lib.gridmovers by Gerrit van Dyk which facilitates the
|
||||
dragging of columns and/or rows in a wxGrid.
|
||||
|
||||
Added wxPython.lib.multisash by Gerrit van Dyk which is a nice
|
||||
implementation of allowing the user to split a window any number of
|
||||
times either horizontally or vertically, and to close the split off
|
||||
windows when desired.
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -28,6 +28,7 @@ _treeList = [
|
||||
'wxRadioButton',
|
||||
'Throbber',
|
||||
'wxPopupControl',
|
||||
'wxMultiSash',
|
||||
]),
|
||||
|
||||
# managed windows == things with a caption you can close
|
||||
@@ -119,6 +120,7 @@ _treeList = [
|
||||
'wxIEHtmlWin',
|
||||
'wxLEDNumberCtrl',
|
||||
'wxMimeTypesManager',
|
||||
'wxMultiSash',
|
||||
'wxPopupControl',
|
||||
'wxRightTextCtrl',
|
||||
'wxStyledTextCtrl_1',
|
||||
|
90
wxPython/demo/wxMultiSash.py
Normal file
90
wxPython/demo/wxMultiSash.py
Normal file
@@ -0,0 +1,90 @@
|
||||
from wxPython.wx import *
|
||||
from wxPython.lib.multisash import wxMultiSash
|
||||
from wxPython.stc import *
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
sampleText="""\
|
||||
You can drag the little tab on the vertical sash left to create another view,
|
||||
or you can drag the tab on the horizontal sash to the top to create another
|
||||
horizontal view.
|
||||
|
||||
The red blocks on the sashes will destroy the view (bottom,left) this block
|
||||
belongs to.
|
||||
|
||||
A yellow rectangle also highlights the current selected view.
|
||||
|
||||
By calling GetSaveData on the multiSash control the control will return its
|
||||
contents and the positions of each sash as a dictionary.
|
||||
Calling SetSaveData with such a dictionary will restore the control to the
|
||||
state it was in when it was saved.
|
||||
|
||||
If the class, that is used as a view, has GetSaveData/SetSaveData implemented,
|
||||
these will also be called to save/restore their state. Any object can be
|
||||
returned by GetSaveData, as it is just another object in the dictionary.
|
||||
"""
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class TestWindow(wxStyledTextCtrl):
|
||||
def __init__(self, parent):
|
||||
wxStyledTextCtrl.__init__(self, parent, -1, style=wxNO_BORDER)
|
||||
self.SetMarginWidth(1,0)
|
||||
if wxPlatform == '__WXMSW__':
|
||||
fSize = 10
|
||||
else:
|
||||
fSize = 12
|
||||
self.StyleSetFont(wxSTC_STYLE_DEFAULT,
|
||||
wxFont(fSize, wxMODERN, wxNORMAL, wxNORMAL))
|
||||
self.SetText(sampleText)
|
||||
|
||||
class TestFrame(wxFrame):
|
||||
def __init__(self, parent, log):
|
||||
wxFrame.__init__(self, parent, -1, "Multi Sash Demo",
|
||||
size=(640,480))
|
||||
self.multi = wxMultiSash(self,-1,pos = wxPoint(0,0),
|
||||
size = (640,480))
|
||||
|
||||
# Use this method to set the default class that will be created when
|
||||
# a new sash is created. The class's constructor needs 1 parameter
|
||||
# which is the parent of the window
|
||||
self.multi.SetDefaultChildClass(TestWindow)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def runTest(frame, nb, log):
|
||||
multi = wxMultiSash(nb, -1, pos = (0,0), size = (640,480))
|
||||
|
||||
# Use this method to set the default class that will be created when
|
||||
# a new sash is created. The class's constructor needs 1 parameter
|
||||
# which is the parent of the window
|
||||
multi.SetDefaultChildClass(TestWindow)
|
||||
|
||||
return multi
|
||||
|
||||
# win = TestPanel(nb, log)
|
||||
# return win
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
overview = """<html><body>
|
||||
<h2><center>wxMultiSash</center></h2>
|
||||
|
||||
wxMultiSash allows the user to split a window any number of times
|
||||
either horizontally or vertically, and to close the split off windows
|
||||
when desired.
|
||||
|
||||
</body></html>
|
||||
"""
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys,os
|
||||
import run
|
||||
run.main(['', os.path.basename(sys.argv[0])])
|
||||
|
726
wxPython/wxPython/lib/multisash.py
Normal file
726
wxPython/wxPython/lib/multisash.py
Normal file
@@ -0,0 +1,726 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Name: multisash
|
||||
# Purpose: Multi Sash control
|
||||
#
|
||||
# Author: Gerrit van Dyk
|
||||
#
|
||||
# Created: 2002/11/20
|
||||
# Version: 0.1
|
||||
# RCS-ID: $Id$
|
||||
# License: wxWindows licensie
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
from wxPython.wx import *
|
||||
|
||||
MV_HOR = 0
|
||||
MV_VER = not MV_HOR
|
||||
|
||||
SH_SIZE = 5
|
||||
CR_SIZE = SH_SIZE * 3
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class wxMultiSash(wxWindow):
|
||||
def __init__(self, *_args,**_kwargs):
|
||||
apply(wxWindow.__init__,(self,) + _args,_kwargs)
|
||||
self._defChild = EmptyChild
|
||||
self.child = wxMultiSplit(self,self,wxPoint(0,0),self.GetSize())
|
||||
EVT_SIZE(self,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 = wxMultiSplit(self,self,wxPoint(0,0),self.GetSize())
|
||||
old.Destroy()
|
||||
self.child.OnSize(None)
|
||||
|
||||
def GetSaveData(self):
|
||||
saveData = {}
|
||||
saveData['_defChild'] = str(self._defChild)
|
||||
saveData['child'] = self.child.GetSaveData()
|
||||
return saveData
|
||||
|
||||
def SetSaveData(self,data):
|
||||
dChild = data['_defChild']
|
||||
mod = dChild.split('.')[0]
|
||||
exec 'import %s' % mod
|
||||
self._defChild = eval(dChild)
|
||||
old = self.child
|
||||
self.child = wxMultiSplit(self,self,wxPoint(0,0),self.GetSize())
|
||||
self.child.SetSaveData(data['child'])
|
||||
old.Destroy()
|
||||
self.OnMultiSize(None)
|
||||
self.child.OnSize(None)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class wxMultiSplit(wxWindow):
|
||||
def __init__(self,multiView,parent,pos,size,view1 = None):
|
||||
wxWindow.__init__(self,id = -1,parent = parent,pos = pos,size = size,
|
||||
style = wxCLIP_CHILDREN)
|
||||
self.multiView = multiView
|
||||
self.view2 = None
|
||||
if view1:
|
||||
self.view1 = view1
|
||||
self.view1.Reparent(self)
|
||||
self.view1.MoveXY(0,0)
|
||||
else:
|
||||
self.view1 = wxMultiViewLeaf(self.multiView,self,
|
||||
wxPoint(0,0),self.GetSize())
|
||||
self.direction = None
|
||||
|
||||
EVT_SIZE(self,self.OnSize)
|
||||
|
||||
def GetSaveData(self):
|
||||
saveData = {}
|
||||
if self.view1:
|
||||
saveData['view1'] = self.view1.GetSaveData()
|
||||
if isinstance(self.view1,wxMultiSplit):
|
||||
saveData['view1IsSplit'] = 1
|
||||
if self.view2:
|
||||
saveData['view2'] = self.view2.GetSaveData()
|
||||
if isinstance(self.view2,wxMultiSplit):
|
||||
saveData['view2IsSplit'] = 1
|
||||
saveData['direction'] = self.direction
|
||||
v1,v2 = self.GetPositionTuple()
|
||||
saveData['x'] = v1
|
||||
saveData['y'] = v2
|
||||
v1,v2 = self.GetSizeTuple()
|
||||
saveData['w'] = v1
|
||||
saveData['h'] = v2
|
||||
return saveData
|
||||
|
||||
def SetSaveData(self,data):
|
||||
self.direction = data['direction']
|
||||
self.SetDimensions(data['x'],data['y'],data['w'],data['h'])
|
||||
v1Data = data.get('view1',None)
|
||||
if v1Data:
|
||||
isSplit = data.get('view1IsSplit',None)
|
||||
old = self.view1
|
||||
if isSplit:
|
||||
self.view1 = wxMultiSplit(self.multiView,self,
|
||||
wxPoint(0,0),self.GetSize())
|
||||
else:
|
||||
self.view1 = wxMultiViewLeaf(self.multiView,self,
|
||||
wxPoint(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 = wxMultiSplit(self.multiView,self,
|
||||
wxPoint(0,0),self.GetSize())
|
||||
else:
|
||||
self.view2 = wxMultiViewLeaf(self.multiView,self,
|
||||
wxPoint(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 = wxMultiSplit(self.multiView,self,
|
||||
caller.GetPosition(),
|
||||
caller.GetSize(),
|
||||
caller)
|
||||
self.view1.AddLeaf(direction,caller,pos)
|
||||
else:
|
||||
self.view2 = wxMultiSplit(self.multiView,self,
|
||||
caller.GetPosition(),
|
||||
caller.GetSize(),
|
||||
caller)
|
||||
self.view2.AddLeaf(direction,caller,pos)
|
||||
else:
|
||||
self.direction = direction
|
||||
w,h = self.GetSizeTuple()
|
||||
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 = wxMultiViewLeaf(self.multiView,self,
|
||||
wxPoint(x,y),wxSize(w1,h1))
|
||||
self.view1.SetSize(wxSize(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.GetSizeTuple()
|
||||
x,y = self.GetPositionTuple()
|
||||
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.GetSizeTuple()
|
||||
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.GetSizeTuple()
|
||||
v2w,v2h = self.view2.GetSizeTuple()
|
||||
v1x,v1y = self.view1.GetPositionTuple()
|
||||
v2x,v2y = self.view2.GetPositionTuple()
|
||||
w,h = self.GetSizeTuple()
|
||||
|
||||
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(v1x,v1y,v1w,v1h)
|
||||
self.view2.SetDimensions(v2x,v2y,v2w,v2h)
|
||||
self.view1.OnSize(None)
|
||||
self.view2.OnSize(None)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class wxMultiViewLeaf(wxWindow):
|
||||
def __init__(self,multiView,parent,pos,size):
|
||||
wxWindow.__init__(self,id = -1,parent = parent,pos = pos,size = size,
|
||||
style = wxCLIP_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)
|
||||
|
||||
EVT_SIZE(self,self.OnSize)
|
||||
|
||||
def GetSaveData(self):
|
||||
saveData = {}
|
||||
saveData['detailClass'] = str(self.detail.child.__class__)
|
||||
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.GetPositionTuple()
|
||||
saveData['x'] = v1
|
||||
saveData['y'] = v2
|
||||
v1,v2 = self.GetSizeTuple()
|
||||
saveData['w'] = v1
|
||||
saveData['h'] = v2
|
||||
return saveData
|
||||
|
||||
def SetSaveData(self,data):
|
||||
dChild = data['detailClass']
|
||||
mod = dChild.split('.')[0]
|
||||
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.GetSizeTuple()
|
||||
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):
|
||||
self.sizerHor.OnSize(evt)
|
||||
self.sizerVer.OnSize(evt)
|
||||
self.creatorHor.OnSize(evt)
|
||||
self.creatorVer.OnSize(evt)
|
||||
self.detail.OnSize(evt)
|
||||
self.closer.OnSize(evt)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class MultiClient(wxWindow):
|
||||
def __init__(self,parent,childCls):
|
||||
w,h = self.CalcSize(parent)
|
||||
wxWindow.__init__(self,id = -1,parent = parent,
|
||||
pos = wxPoint(0,0),
|
||||
size = wxSize(w,h),
|
||||
style = wxCLIP_CHILDREN | wxSUNKEN_BORDER)
|
||||
self.child = childCls(self)
|
||||
self.child.MoveXY(2,2)
|
||||
self.normalColour = self.GetBackgroundColour()
|
||||
self.selected = false
|
||||
|
||||
EVT_SET_FOCUS(self,self.OnSetFocus)
|
||||
EVT_CHILD_FOCUS(self,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(wxColour(255,255,0)) # Yellow
|
||||
self.Refresh()
|
||||
|
||||
def CalcSize(self,parent):
|
||||
w,h = parent.GetSizeTuple()
|
||||
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.GetClientSizeTuple()
|
||||
self.child.SetSize(wxSize(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)
|
||||
## EVT_KILL_FOCUS(child,self.OnChildKillFocus)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class MultiSizer(wxWindow):
|
||||
def __init__(self,parent,side):
|
||||
self.side = side
|
||||
x,y,w,h = self.CalcSizePos(parent)
|
||||
wxWindow.__init__(self,id = -1,parent = parent,
|
||||
pos = wxPoint(x,y),
|
||||
size = wxSize(w,h),
|
||||
style = wxCLIP_CHILDREN)
|
||||
|
||||
self.px = None # Previous X
|
||||
self.py = None # Previous Y
|
||||
self.isDrag = false # In Dragging
|
||||
self.dragTarget = None # View being sized
|
||||
|
||||
EVT_LEAVE_WINDOW(self,self.OnLeave)
|
||||
EVT_ENTER_WINDOW(self,self.OnEnter)
|
||||
EVT_MOTION(self,self.OnMouseMove)
|
||||
EVT_LEFT_DOWN(self,self.OnPress)
|
||||
EVT_LEFT_UP(self,self.OnRelease)
|
||||
|
||||
def CalcSizePos(self,parent):
|
||||
pw,ph = parent.GetSizeTuple()
|
||||
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(wxStockCursor(wxCURSOR_ARROW))
|
||||
|
||||
def OnEnter(self,evt):
|
||||
if not self.GetParent().CanSize(not self.side):
|
||||
return
|
||||
if self.side == MV_HOR:
|
||||
self.SetCursor(wxStockCursor(wxCURSOR_SIZENS))
|
||||
else:
|
||||
self.SetCursor(wxStockCursor(wxCURSOR_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(wxWindow):
|
||||
def __init__(self,parent,side):
|
||||
self.side = side
|
||||
x,y,w,h = self.CalcSizePos(parent)
|
||||
wxWindow.__init__(self,id = -1,parent = parent,
|
||||
pos = wxPoint(x,y),
|
||||
size = wxSize(w,h),
|
||||
style = wxCLIP_CHILDREN)
|
||||
|
||||
self.px = None # Previous X
|
||||
self.py = None # Previous Y
|
||||
self.isDrag = false # In Dragging
|
||||
|
||||
EVT_LEAVE_WINDOW(self,self.OnLeave)
|
||||
EVT_ENTER_WINDOW(self,self.OnEnter)
|
||||
EVT_MOTION(self,self.OnMouseMove)
|
||||
EVT_LEFT_DOWN(self,self.OnPress)
|
||||
EVT_LEFT_UP(self,self.OnRelease)
|
||||
EVT_PAINT(self,self.OnPaint)
|
||||
|
||||
def CalcSizePos(self,parent):
|
||||
pw,ph = parent.GetSizeTuple()
|
||||
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(wxStockCursor(wxCURSOR_ARROW))
|
||||
|
||||
def OnEnter(self,evt):
|
||||
if self.side == MV_HOR:
|
||||
self.SetCursor(wxStockCursor(wxCURSOR_HAND))
|
||||
else:
|
||||
self.SetCursor(wxStockCursor(wxCURSOR_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 = wxPaintDC(self)
|
||||
dc.SetBackground(wxBrush(self.GetBackgroundColour(),wxSOLID))
|
||||
dc.Clear()
|
||||
|
||||
highlight = wxPen(wxSystemSettings_GetSystemColour(
|
||||
wxSYS_COLOUR_BTNHIGHLIGHT),1,wxSOLID)
|
||||
shadow = wxPen(wxSystemSettings_GetSystemColour(
|
||||
wxSYS_COLOUR_BTNSHADOW),1,wxSOLID)
|
||||
black = wxPen(wxBLACK,1,wxSOLID)
|
||||
w,h = self.GetSizeTuple()
|
||||
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(wxWindow):
|
||||
def __init__(self,parent):
|
||||
x,y,w,h = self.CalcSizePos(parent)
|
||||
wxWindow.__init__(self,id = -1,parent = parent,
|
||||
pos = wxPoint(x,y),
|
||||
size = wxSize(w,h),
|
||||
style = wxCLIP_CHILDREN)
|
||||
|
||||
self.down = false
|
||||
self.entered = false
|
||||
|
||||
EVT_LEFT_DOWN(self,self.OnPress)
|
||||
EVT_LEFT_UP(self,self.OnRelease)
|
||||
EVT_PAINT(self,self.OnPaint)
|
||||
EVT_LEAVE_WINDOW(self,self.OnLeave)
|
||||
EVT_ENTER_WINDOW(self,self.OnEnter)
|
||||
|
||||
def OnLeave(self,evt):
|
||||
self.SetCursor(wxStockCursor(wxCURSOR_ARROW))
|
||||
self.entered = false
|
||||
|
||||
def OnEnter(self,evt):
|
||||
self.SetCursor(wxStockCursor(wxCURSOR_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 = wxPaintDC(self)
|
||||
dc.SetBackground(wxBrush(wxRED,wxSOLID))
|
||||
dc.Clear()
|
||||
|
||||
def CalcSizePos(self,parent):
|
||||
pw,ph = parent.GetSizeTuple()
|
||||
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(wxWindow):
|
||||
def __init__(self,parent):
|
||||
wxWindow.__init__(self,parent,-1, style = wxCLIP_CHILDREN)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
def DrawSash(win,x,y,direction):
|
||||
dc = wxScreenDC()
|
||||
dc.StartDrawingOnTopWin(win)
|
||||
bmp = wxEmptyBitmap(8,8)
|
||||
bdc = wxMemoryDC()
|
||||
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 = wxBrush(wxColour(0,0,0))
|
||||
brush.SetStipple(bmp)
|
||||
|
||||
dc.SetBrush(brush)
|
||||
dc.SetLogicalFunction(wxXOR)
|
||||
|
||||
body_w,body_h = win.GetClientSizeTuple()
|
||||
|
||||
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()
|
Reference in New Issue
Block a user