+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()