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