]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/multisash.py
Tweaked some sample code
[wxWidgets.git] / wxPython / wx / lib / multisash.py
1 #----------------------------------------------------------------------
2 # Name: multisash
3 # Purpose: Multi Sash control
4 #
5 # Author: Gerrit van Dyk
6 #
7 # Created: 2002/11/20
8 # Version: 0.1
9 # RCS-ID: $Id$
10 # License: wxWindows licensie
11 #----------------------------------------------------------------------
12 # 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
13 #
14 # o 2.5 compatability update.
15 #
16
17 import wx
18
19 MV_HOR = 0
20 MV_VER = not MV_HOR
21
22 SH_SIZE = 5
23 CR_SIZE = SH_SIZE * 3
24
25 #----------------------------------------------------------------------
26
27 class wxMultiSash(wx.Window):
28 def __init__(self, *_args,**_kwargs):
29 apply(wx.Window.__init__,(self,) + _args,_kwargs)
30 self._defChild = EmptyChild
31 self.child = wxMultiSplit(self,self,(0,0),self.GetSize())
32 self.Bind(wx.EVT_SIZE,self.OnMultiSize)
33
34 def SetDefaultChildClass(self,childCls):
35 self._defChild = childCls
36 self.child.DefaultChildChanged()
37
38 def OnMultiSize(self,evt):
39 self.child.SetSize(self.GetSize())
40
41 def UnSelect(self):
42 self.child.UnSelect()
43
44 def Clear(self):
45 old = self.child
46 self.child = wxMultiSplit(self,self,(0,0),self.GetSize())
47 old.Destroy()
48 self.child.OnSize(None)
49
50 def GetSaveData(self):
51 saveData = {}
52 saveData['_defChild'] = str(self._defChild)
53 saveData['child'] = self.child.GetSaveData()
54 return saveData
55
56 def SetSaveData(self,data):
57 dChild = data['_defChild']
58 mod = dChild.split('.')[0]
59 exec 'import %s' % mod
60 self._defChild = eval(dChild)
61 old = self.child
62 self.child = wxMultiSplit(self,self,wxPoint(0,0),self.GetSize())
63 self.child.SetSaveData(data['child'])
64 old.Destroy()
65 self.OnMultiSize(None)
66 self.child.OnSize(None)
67
68
69 #----------------------------------------------------------------------
70
71
72 class wxMultiSplit(wx.Window):
73 def __init__(self,multiView,parent,pos,size,view1 = None):
74 wx.Window.__init__(self,id = -1,parent = parent,pos = pos,size = size,
75 style = wx.CLIP_CHILDREN)
76 self.multiView = multiView
77 self.view2 = None
78 if view1:
79 self.view1 = view1
80 self.view1.Reparent(self)
81 self.view1.MoveXY(0,0)
82 else:
83 self.view1 = wxMultiViewLeaf(self.multiView,self,
84 (0,0),self.GetSize())
85 self.direction = None
86
87 self.Bind(wx.EVT_SIZE,self.OnSize)
88
89 def GetSaveData(self):
90 saveData = {}
91 if self.view1:
92 saveData['view1'] = self.view1.GetSaveData()
93 if isinstance(self.view1,wxMultiSplit):
94 saveData['view1IsSplit'] = 1
95 if self.view2:
96 saveData['view2'] = self.view2.GetSaveData()
97 if isinstance(self.view2,wxMultiSplit):
98 saveData['view2IsSplit'] = 1
99 saveData['direction'] = self.direction
100 v1,v2 = self.GetPosition()
101 saveData['x'] = v1
102 saveData['y'] = v2
103 v1,v2 = self.GetSize()
104 saveData['w'] = v1
105 saveData['h'] = v2
106 return saveData
107
108 def SetSaveData(self,data):
109 self.direction = data['direction']
110 self.SetDimensions(data['x'],data['y'],data['w'],data['h'])
111 v1Data = data.get('view1',None)
112 if v1Data:
113 isSplit = data.get('view1IsSplit',None)
114 old = self.view1
115 if isSplit:
116 self.view1 = wxMultiSplit(self.multiView,self,
117 (0,0),self.GetSize())
118 else:
119 self.view1 = wxMultiViewLeaf(self.multiView,self,
120 (0,0),self.GetSize())
121 self.view1.SetSaveData(v1Data)
122 if old:
123 old.Destroy()
124 v2Data = data.get('view2',None)
125 if v2Data:
126 isSplit = data.get('view2IsSplit',None)
127 old = self.view2
128 if isSplit:
129 self.view2 = wxMultiSplit(self.multiView,self,
130 (0,0),self.GetSize())
131 else:
132 self.view2 = wxMultiViewLeaf(self.multiView,self,
133 (0,0),self.GetSize())
134 self.view2.SetSaveData(v2Data)
135 if old:
136 old.Destroy()
137 if self.view1:
138 self.view1.OnSize(None)
139 if self.view2:
140 self.view2.OnSize(None)
141
142 def UnSelect(self):
143 if self.view1:
144 self.view1.UnSelect()
145 if self.view2:
146 self.view2.UnSelect()
147
148 def DefaultChildChanged(self):
149 if not self.view2:
150 self.view1.DefaultChildChanged()
151
152 def AddLeaf(self,direction,caller,pos):
153 if self.view2:
154 if caller == self.view1:
155 self.view1 = wxMultiSplit(self.multiView,self,
156 caller.GetPosition(),
157 caller.GetSize(),
158 caller)
159 self.view1.AddLeaf(direction,caller,pos)
160 else:
161 self.view2 = wxMultiSplit(self.multiView,self,
162 caller.GetPosition(),
163 caller.GetSize(),
164 caller)
165 self.view2.AddLeaf(direction,caller,pos)
166 else:
167 self.direction = direction
168 w,h = self.GetSize()
169 if direction == MV_HOR:
170 x,y = (pos,0)
171 w1,h1 = (w-pos,h)
172 w2,h2 = (pos,h)
173 else:
174 x,y = (0,pos)
175 w1,h1 = (w,h-pos)
176 w2,h2 = (w,pos)
177 self.view2 = wxMultiViewLeaf(self.multiView, self, (x,y), (w1,h1))
178 self.view1.SetSize((w2,h2))
179 self.view2.OnSize(None)
180
181 def DestroyLeaf(self,caller):
182 if not self.view2: # We will only have 2 windows if
183 return # we need to destroy any
184 parent = self.GetParent() # Another splitview
185 if parent == self.multiView: # We'r at the root
186 if caller == self.view1:
187 old = self.view1
188 self.view1 = self.view2
189 self.view2 = None
190 old.Destroy()
191 else:
192 self.view2.Destroy()
193 self.view2 = None
194 self.view1.SetSize(self.GetSize())
195 self.view1.Move(self.GetPosition())
196 else:
197 w,h = self.GetSize()
198 x,y = self.GetPosition()
199 if caller == self.view1:
200 if self == parent.view1:
201 parent.view1 = self.view2
202 else:
203 parent.view2 = self.view2
204 self.view2.Reparent(parent)
205 self.view2.SetDimensions(x,y,w,h)
206 else:
207 if self == parent.view1:
208 parent.view1 = self.view1
209 else:
210 parent.view2 = self.view1
211 self.view1.Reparent(parent)
212 self.view1.SetDimensions(x,y,w,h)
213 self.view1 = None
214 self.view2 = None
215 self.Destroy()
216
217 def CanSize(self,side,view):
218 if self.SizeTarget(side,view):
219 return True
220 return False
221
222 def SizeTarget(self,side,view):
223 if self.direction == side and self.view2 and view == self.view1:
224 return self
225 parent = self.GetParent()
226 if parent != self.multiView:
227 return parent.SizeTarget(side,self)
228 return None
229
230 def SizeLeaf(self,leaf,pos,side):
231 if self.direction != side:
232 return
233 if not (self.view1 and self.view2):
234 return
235 if pos < 10: return
236 w,h = self.GetSize()
237 if side == MV_HOR:
238 if pos > w - 10: return
239 else:
240 if pos > h - 10: return
241 if side == MV_HOR:
242 self.view1.SetDimensions(0,0,pos,h)
243 self.view2.SetDimensions(pos,0,w-pos,h)
244 else:
245 self.view1.SetDimensions(0,0,w,pos)
246 self.view2.SetDimensions(0,pos,w,h-pos)
247
248 def OnSize(self,evt):
249 if not self.view2:
250 self.view1.SetSize(self.GetSize())
251 self.view1.OnSize(None)
252 return
253 v1w,v1h = self.view1.GetSize()
254 v2w,v2h = self.view2.GetSize()
255 v1x,v1y = self.view1.GetPosition()
256 v2x,v2y = self.view2.GetPosition()
257 w,h = self.GetSize()
258
259 if v1x != v2x:
260 ratio = float(w) / float((v1w + v2w))
261 v1w *= ratio
262 v2w = w - v1w
263 v2x = v1w
264 else:
265 v1w = v2w = w
266
267 if v1y != v2y:
268 ratio = float(h) / float((v1h + v2h))
269 v1h *= ratio
270 v2h = h - v1h
271 v2y = v1h
272 else:
273 v1h = v2h = h
274
275 self.view1.SetDimensions(v1x,v1y,v1w,v1h)
276 self.view2.SetDimensions(v2x,v2y,v2w,v2h)
277 self.view1.OnSize(None)
278 self.view2.OnSize(None)
279
280
281 #----------------------------------------------------------------------
282
283
284 class wxMultiViewLeaf(wx.Window):
285 def __init__(self,multiView,parent,pos,size):
286 wx.Window.__init__(self,id = -1,parent = parent,pos = pos,size = size,
287 style = wx.CLIP_CHILDREN)
288 self.multiView = multiView
289
290 self.sizerHor = MultiSizer(self,MV_HOR)
291 self.sizerVer = MultiSizer(self,MV_VER)
292 self.creatorHor = MultiCreator(self,MV_HOR)
293 self.creatorVer = MultiCreator(self,MV_VER)
294 self.detail = MultiClient(self,multiView._defChild)
295 self.closer = MultiCloser(self)
296
297 self.Bind(wx.EVT_SIZE,self.OnSize)
298
299 def GetSaveData(self):
300 saveData = {}
301 saveData['detailClass'] = str(self.detail.child.__class__)
302 if hasattr(self.detail.child,'GetSaveData'):
303 attr = getattr(self.detail.child,'GetSaveData')
304 if callable(attr):
305 dData = attr()
306 if dData:
307 saveData['detail'] = dData
308 v1,v2 = self.GetPosition()
309 saveData['x'] = v1
310 saveData['y'] = v2
311 v1,v2 = self.GetSize()
312 saveData['w'] = v1
313 saveData['h'] = v2
314 return saveData
315
316 def SetSaveData(self,data):
317 dChild = data['detailClass']
318 mod = dChild.split('.')[0]
319 exec 'import %s' % mod
320 detClass = eval(dChild)
321 self.SetDimensions(data['x'],data['y'],data['w'],data['h'])
322 old = self.detail
323 self.detail = MultiClient(self,detClass)
324 dData = data.get('detail',None)
325 if dData:
326 if hasattr(self.detail.child,'SetSaveData'):
327 attr = getattr(self.detail.child,'SetSaveData')
328 if callable(attr):
329 attr(dData)
330 old.Destroy()
331 self.detail.OnSize(None)
332
333 def UnSelect(self):
334 self.detail.UnSelect()
335
336 def DefaultChildChanged(self):
337 self.detail.SetNewChildCls(self.multiView._defChild)
338
339 def AddLeaf(self,direction,pos):
340 if pos < 10: return
341 w,h = self.GetSize()
342 if direction == MV_VER:
343 if pos > h - 10: return
344 else:
345 if pos > w - 10: return
346 self.GetParent().AddLeaf(direction,self,pos)
347
348 def DestroyLeaf(self):
349 self.GetParent().DestroyLeaf(self)
350
351 def SizeTarget(self,side):
352 return self.GetParent().SizeTarget(side,self)
353
354 def CanSize(self,side):
355 return self.GetParent().CanSize(side,self)
356
357 def OnSize(self,evt):
358 self.sizerHor.OnSize(evt)
359 self.sizerVer.OnSize(evt)
360 self.creatorHor.OnSize(evt)
361 self.creatorVer.OnSize(evt)
362 self.detail.OnSize(evt)
363 self.closer.OnSize(evt)
364
365 #----------------------------------------------------------------------
366
367
368 class MultiClient(wx.Window):
369 def __init__(self,parent,childCls):
370 w,h = self.CalcSize(parent)
371 wx.Window.__init__(self,id = -1,parent = parent,
372 pos = (0,0),
373 size = (w,h),
374 style = wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)
375 self.child = childCls(self)
376 self.child.MoveXY(2,2)
377 self.normalColour = self.GetBackgroundColour()
378 self.selected = False
379
380 self.Bind(wx.EVT_SET_FOCUS,self.OnSetFocus)
381 self.Bind(wx.EVT_CHILD_FOCUS,self.OnChildFocus)
382
383 def UnSelect(self):
384 if self.selected:
385 self.selected = False
386 self.SetBackgroundColour(self.normalColour)
387 self.Refresh()
388
389 def Select(self):
390 self.GetParent().multiView.UnSelect()
391 self.selected = True
392 self.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow
393 self.Refresh()
394
395 def CalcSize(self,parent):
396 w,h = parent.GetSize()
397 w -= SH_SIZE
398 h -= SH_SIZE
399 return (w,h)
400
401 def OnSize(self,evt):
402 w,h = self.CalcSize(self.GetParent())
403 self.SetDimensions(0,0,w,h)
404 w,h = self.GetClientSize()
405 self.child.SetSize((w-4,h-4))
406
407 def SetNewChildCls(self,childCls):
408 if self.child:
409 self.child.Destroy()
410 self.child = None
411 self.child = childCls(self)
412 self.child.MoveXY(2,2)
413
414 def OnSetFocus(self,evt):
415 self.Select()
416
417 def OnChildFocus(self,evt):
418 self.OnSetFocus(evt)
419 ## from Funcs import FindFocusedChild
420 ## child = FindFocusedChild(self)
421 ## child.Bind(wx.EVT_KILL_FOCUS,self.OnChildKillFocus)
422
423
424 #----------------------------------------------------------------------
425
426
427 class MultiSizer(wx.Window):
428 def __init__(self,parent,side):
429 self.side = side
430 x,y,w,h = self.CalcSizePos(parent)
431 wx.Window.__init__(self,id = -1,parent = parent,
432 pos = (x,y),
433 size = (w,h),
434 style = wx.CLIP_CHILDREN)
435
436 self.px = None # Previous X
437 self.py = None # Previous Y
438 self.isDrag = False # In Dragging
439 self.dragTarget = None # View being sized
440
441 self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
442 self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
443 self.Bind(wx.EVT_MOTION,self.OnMouseMove)
444 self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
445 self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
446
447 def CalcSizePos(self,parent):
448 pw,ph = parent.GetSize()
449 if self.side == MV_HOR:
450 x = CR_SIZE + 2
451 y = ph - SH_SIZE
452 w = pw - CR_SIZE - SH_SIZE - 2
453 h = SH_SIZE
454 else:
455 x = pw - SH_SIZE
456 y = CR_SIZE + 2 + SH_SIZE
457 w = SH_SIZE
458 h = ph - CR_SIZE - SH_SIZE - 4 - SH_SIZE # For Closer
459 return (x,y,w,h)
460
461 def OnSize(self,evt):
462 x,y,w,h = self.CalcSizePos(self.GetParent())
463 self.SetDimensions(x,y,w,h)
464
465 def OnLeave(self,evt):
466 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
467
468 def OnEnter(self,evt):
469 if not self.GetParent().CanSize(not self.side):
470 return
471 if self.side == MV_HOR:
472 self.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS))
473 else:
474 self.SetCursor(wx.StockCursor(wx.CURSOR_SIZEWE))
475
476 def OnMouseMove(self,evt):
477 if self.isDrag:
478 DrawSash(self.dragTarget,self.px,self.py,self.side)
479 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
480 self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py)
481 DrawSash(self.dragTarget,self.px,self.py,self.side)
482 else:
483 evt.Skip()
484
485 def OnPress(self,evt):
486 self.dragTarget = self.GetParent().SizeTarget(not self.side)
487 if self.dragTarget:
488 self.isDrag = True
489 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
490 self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py)
491 DrawSash(self.dragTarget,self.px,self.py,self.side)
492 self.CaptureMouse()
493 else:
494 evt.Skip()
495
496 def OnRelease(self,evt):
497 if self.isDrag:
498 DrawSash(self.dragTarget,self.px,self.py,self.side)
499 self.ReleaseMouse()
500 self.isDrag = False
501 if self.side == MV_HOR:
502 self.dragTarget.SizeLeaf(self.GetParent(),
503 self.py,not self.side)
504 else:
505 self.dragTarget.SizeLeaf(self.GetParent(),
506 self.px,not self.side)
507 self.dragTarget = None
508 else:
509 evt.Skip()
510
511 #----------------------------------------------------------------------
512
513
514 class MultiCreator(wx.Window):
515 def __init__(self,parent,side):
516 self.side = side
517 x,y,w,h = self.CalcSizePos(parent)
518 wx.Window.__init__(self,id = -1,parent = parent,
519 pos = (x,y),
520 size = (w,h),
521 style = wx.CLIP_CHILDREN)
522
523 self.px = None # Previous X
524 self.py = None # Previous Y
525 self.isDrag = False # In Dragging
526
527 self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
528 self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
529 self.Bind(wx.EVT_MOTION,self.OnMouseMove)
530 self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
531 self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
532 self.Bind(wx.EVT_PAINT,self.OnPaint)
533
534 def CalcSizePos(self,parent):
535 pw,ph = parent.GetSize()
536 if self.side == MV_HOR:
537 x = 2
538 y = ph - SH_SIZE
539 w = CR_SIZE
540 h = SH_SIZE
541 else:
542 x = pw - SH_SIZE
543 y = 4 + SH_SIZE # Make provision for closer
544 w = SH_SIZE
545 h = CR_SIZE
546 return (x,y,w,h)
547
548 def OnSize(self,evt):
549 x,y,w,h = self.CalcSizePos(self.GetParent())
550 self.SetDimensions(x,y,w,h)
551
552 def OnLeave(self,evt):
553 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
554
555 def OnEnter(self,evt):
556 if self.side == MV_HOR:
557 self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
558 else:
559 self.SetCursor(wx.StockCursor(wx.CURSOR_POINT_LEFT))
560
561 def OnMouseMove(self,evt):
562 if self.isDrag:
563 parent = self.GetParent()
564 DrawSash(parent,self.px,self.py,self.side)
565 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
566 self.px,self.py = parent.ScreenToClientXY(self.px,self.py)
567 DrawSash(parent,self.px,self.py,self.side)
568 else:
569 evt.Skip()
570
571 def OnPress(self,evt):
572 self.isDrag = True
573 parent = self.GetParent()
574 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
575 self.px,self.py = parent.ScreenToClientXY(self.px,self.py)
576 DrawSash(parent,self.px,self.py,self.side)
577 self.CaptureMouse()
578
579 def OnRelease(self,evt):
580 if self.isDrag:
581 parent = self.GetParent()
582 DrawSash(parent,self.px,self.py,self.side)
583 self.ReleaseMouse()
584 self.isDrag = False
585
586 if self.side == MV_HOR:
587 parent.AddLeaf(MV_VER,self.py)
588 else:
589 parent.AddLeaf(MV_HOR,self.px)
590 else:
591 evt.Skip()
592
593 def OnPaint(self,evt):
594 dc = wx.PaintDC(self)
595 dc.SetBackground(wx.Brush(self.GetBackgroundColour(),wx.SOLID))
596 dc.Clear()
597
598 highlight = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT), 1, wx.SOLID)
599 shadow = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW), 1, wx.SOLID)
600 black = wx.Pen(wx.BLACK,1,wx.SOLID)
601 w,h = self.GetSize()
602 w -= 1
603 h -= 1
604
605 # Draw outline
606 dc.SetPen(highlight)
607 dc.DrawLine((0,0), (0,h))
608 dc.DrawLine((0,0), (w,0))
609 dc.SetPen(black)
610 dc.DrawLine((0,h), (w+1,h))
611 dc.DrawLine((w,0), (w,h))
612 dc.SetPen(shadow)
613 dc.DrawLine((w-1,2), (w-1,h))
614
615 #----------------------------------------------------------------------
616
617
618 class MultiCloser(wx.Window):
619 def __init__(self,parent):
620 x,y,w,h = self.CalcSizePos(parent)
621 wx.Window.__init__(self,id = -1,parent = parent,
622 pos = (x,y),
623 size = (w,h),
624 style = wx.CLIP_CHILDREN)
625
626 self.down = False
627 self.entered = False
628
629 self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
630 self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
631 self.Bind(wx.EVT_PAINT,self.OnPaint)
632 self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
633 self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
634
635 def OnLeave(self,evt):
636 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
637 self.entered = False
638
639 def OnEnter(self,evt):
640 self.SetCursor(wx.StockCursor(wx.CURSOR_BULLSEYE))
641 self.entered = True
642
643 def OnPress(self,evt):
644 self.down = True
645 evt.Skip()
646
647 def OnRelease(self,evt):
648 if self.down and self.entered:
649 self.GetParent().DestroyLeaf()
650 else:
651 evt.Skip()
652 self.down = False
653
654 def OnPaint(self,evt):
655 dc = wx.PaintDC(self)
656 dc.SetBackground(wx.Brush(wx.RED,wx.SOLID))
657 dc.Clear()
658
659 def CalcSizePos(self,parent):
660 pw,ph = parent.GetSize()
661 x = pw - SH_SIZE
662 w = SH_SIZE
663 h = SH_SIZE + 2
664 y = 1
665 return (x,y,w,h)
666
667 def OnSize(self,evt):
668 x,y,w,h = self.CalcSizePos(self.GetParent())
669 self.SetDimensions(x,y,w,h)
670
671
672 #----------------------------------------------------------------------
673
674
675 class EmptyChild(wx.Window):
676 def __init__(self,parent):
677 wx.Window.__init__(self,parent,-1, style = wx.CLIP_CHILDREN)
678
679
680 #----------------------------------------------------------------------
681
682
683 def DrawSash(win,x,y,direction):
684 dc = wx.ScreenDC()
685 dc.StartDrawingOnTopWin(win)
686 bmp = wx.EmptyBitmap(8,8)
687 bdc = wx.MemoryDC()
688 bdc.SelectObject(bmp)
689 bdc.DrawRectangle((-1,-1), (10,10))
690 for i in range(8):
691 for j in range(8):
692 if ((i + j) & 1):
693 bdc.DrawPoint((i,j))
694
695 brush = wx.Brush(wx.Colour(0,0,0))
696 brush.SetStipple(bmp)
697
698 dc.SetBrush(brush)
699 dc.SetLogicalFunction(wx.XOR)
700
701 body_w,body_h = win.GetClientSize()
702
703 if y < 0:
704 y = 0
705 if y > body_h:
706 y = body_h
707 if x < 0:
708 x = 0
709 if x > body_w:
710 x = body_w
711
712 if direction == MV_HOR:
713 x = 0
714 else:
715 y = 0
716
717 x,y = win.ClientToScreenXY(x,y)
718
719 w = body_w
720 h = body_h
721
722 if direction == MV_HOR:
723 dc.DrawRectangle((x,y-2), (w,4))
724 else:
725 dc.DrawRectangle((x-2,y), (4,h))
726
727 dc.EndDrawingOnTop()