]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/multisash.py
don't force wxUSE_EXTENDED_RTTI to eb 1 for Borland compiler (why?)
[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):
369 self.sizerHor.OnSize(evt)
370 self.sizerVer.OnSize(evt)
371 self.creatorHor.OnSize(evt)
372 self.creatorVer.OnSize(evt)
373 self.detail.OnSize(evt)
374 self.closer.OnSize(evt)
375
376#----------------------------------------------------------------------
377
378
b881fc78 379class MultiClient(wx.Window):
d14a1e28
RD
380 def __init__(self,parent,childCls):
381 w,h = self.CalcSize(parent)
b881fc78
RD
382 wx.Window.__init__(self,id = -1,parent = parent,
383 pos = (0,0),
384 size = (w,h),
385 style = wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)
d14a1e28
RD
386 self.child = childCls(self)
387 self.child.MoveXY(2,2)
388 self.normalColour = self.GetBackgroundColour()
389 self.selected = False
390
b881fc78
RD
391 self.Bind(wx.EVT_SET_FOCUS,self.OnSetFocus)
392 self.Bind(wx.EVT_CHILD_FOCUS,self.OnChildFocus)
d14a1e28
RD
393
394 def UnSelect(self):
395 if self.selected:
396 self.selected = False
397 self.SetBackgroundColour(self.normalColour)
398 self.Refresh()
399
400 def Select(self):
401 self.GetParent().multiView.UnSelect()
402 self.selected = True
b881fc78 403 self.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow
d14a1e28
RD
404 self.Refresh()
405
406 def CalcSize(self,parent):
b881fc78 407 w,h = parent.GetSize()
d14a1e28
RD
408 w -= SH_SIZE
409 h -= SH_SIZE
410 return (w,h)
411
412 def OnSize(self,evt):
413 w,h = self.CalcSize(self.GetParent())
414 self.SetDimensions(0,0,w,h)
b881fc78
RD
415 w,h = self.GetClientSize()
416 self.child.SetSize((w-4,h-4))
d14a1e28
RD
417
418 def SetNewChildCls(self,childCls):
419 if self.child:
420 self.child.Destroy()
421 self.child = None
422 self.child = childCls(self)
423 self.child.MoveXY(2,2)
424
425 def OnSetFocus(self,evt):
426 self.Select()
427
428 def OnChildFocus(self,evt):
429 self.OnSetFocus(evt)
430## from Funcs import FindFocusedChild
431## child = FindFocusedChild(self)
b881fc78 432## child.Bind(wx.EVT_KILL_FOCUS,self.OnChildKillFocus)
d14a1e28
RD
433
434
435#----------------------------------------------------------------------
436
437
b881fc78 438class MultiSizer(wx.Window):
d14a1e28
RD
439 def __init__(self,parent,side):
440 self.side = side
441 x,y,w,h = self.CalcSizePos(parent)
b881fc78
RD
442 wx.Window.__init__(self,id = -1,parent = parent,
443 pos = (x,y),
444 size = (w,h),
445 style = wx.CLIP_CHILDREN)
d14a1e28
RD
446
447 self.px = None # Previous X
448 self.py = None # Previous Y
449 self.isDrag = False # In Dragging
450 self.dragTarget = None # View being sized
451
b881fc78
RD
452 self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
453 self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
454 self.Bind(wx.EVT_MOTION,self.OnMouseMove)
455 self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
456 self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
d14a1e28 457
9ef73d79
RD
458 self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE))
459
460
d14a1e28 461 def CalcSizePos(self,parent):
b881fc78 462 pw,ph = parent.GetSize()
d14a1e28
RD
463 if self.side == MV_HOR:
464 x = CR_SIZE + 2
465 y = ph - SH_SIZE
466 w = pw - CR_SIZE - SH_SIZE - 2
467 h = SH_SIZE
468 else:
469 x = pw - SH_SIZE
470 y = CR_SIZE + 2 + SH_SIZE
471 w = SH_SIZE
472 h = ph - CR_SIZE - SH_SIZE - 4 - SH_SIZE # For Closer
473 return (x,y,w,h)
474
475 def OnSize(self,evt):
476 x,y,w,h = self.CalcSizePos(self.GetParent())
477 self.SetDimensions(x,y,w,h)
478
479 def OnLeave(self,evt):
b881fc78 480 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
d14a1e28
RD
481
482 def OnEnter(self,evt):
483 if not self.GetParent().CanSize(not self.side):
484 return
485 if self.side == MV_HOR:
b881fc78 486 self.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS))
d14a1e28 487 else:
b881fc78 488 self.SetCursor(wx.StockCursor(wx.CURSOR_SIZEWE))
d14a1e28
RD
489
490 def OnMouseMove(self,evt):
491 if self.isDrag:
492 DrawSash(self.dragTarget,self.px,self.py,self.side)
493 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
494 self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py)
495 DrawSash(self.dragTarget,self.px,self.py,self.side)
496 else:
497 evt.Skip()
498
499 def OnPress(self,evt):
500 self.dragTarget = self.GetParent().SizeTarget(not self.side)
501 if self.dragTarget:
502 self.isDrag = True
503 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
504 self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py)
505 DrawSash(self.dragTarget,self.px,self.py,self.side)
506 self.CaptureMouse()
507 else:
508 evt.Skip()
509
510 def OnRelease(self,evt):
511 if self.isDrag:
512 DrawSash(self.dragTarget,self.px,self.py,self.side)
513 self.ReleaseMouse()
514 self.isDrag = False
515 if self.side == MV_HOR:
516 self.dragTarget.SizeLeaf(self.GetParent(),
517 self.py,not self.side)
518 else:
519 self.dragTarget.SizeLeaf(self.GetParent(),
520 self.px,not self.side)
521 self.dragTarget = None
522 else:
523 evt.Skip()
524
525#----------------------------------------------------------------------
526
527
b881fc78 528class MultiCreator(wx.Window):
d14a1e28
RD
529 def __init__(self,parent,side):
530 self.side = side
531 x,y,w,h = self.CalcSizePos(parent)
b881fc78
RD
532 wx.Window.__init__(self,id = -1,parent = parent,
533 pos = (x,y),
534 size = (w,h),
535 style = wx.CLIP_CHILDREN)
d14a1e28
RD
536
537 self.px = None # Previous X
538 self.py = None # Previous Y
539 self.isDrag = False # In Dragging
540
b881fc78
RD
541 self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
542 self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
543 self.Bind(wx.EVT_MOTION,self.OnMouseMove)
544 self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
545 self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
546 self.Bind(wx.EVT_PAINT,self.OnPaint)
d14a1e28
RD
547
548 def CalcSizePos(self,parent):
b881fc78 549 pw,ph = parent.GetSize()
d14a1e28
RD
550 if self.side == MV_HOR:
551 x = 2
552 y = ph - SH_SIZE
553 w = CR_SIZE
554 h = SH_SIZE
555 else:
556 x = pw - SH_SIZE
557 y = 4 + SH_SIZE # Make provision for closer
558 w = SH_SIZE
559 h = CR_SIZE
560 return (x,y,w,h)
561
562 def OnSize(self,evt):
563 x,y,w,h = self.CalcSizePos(self.GetParent())
564 self.SetDimensions(x,y,w,h)
565
566 def OnLeave(self,evt):
b881fc78 567 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
d14a1e28
RD
568
569 def OnEnter(self,evt):
570 if self.side == MV_HOR:
b881fc78 571 self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
d14a1e28 572 else:
b881fc78 573 self.SetCursor(wx.StockCursor(wx.CURSOR_POINT_LEFT))
d14a1e28
RD
574
575 def OnMouseMove(self,evt):
576 if self.isDrag:
577 parent = self.GetParent()
578 DrawSash(parent,self.px,self.py,self.side)
579 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
580 self.px,self.py = parent.ScreenToClientXY(self.px,self.py)
581 DrawSash(parent,self.px,self.py,self.side)
582 else:
583 evt.Skip()
584
585 def OnPress(self,evt):
586 self.isDrag = True
587 parent = self.GetParent()
588 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y)
589 self.px,self.py = parent.ScreenToClientXY(self.px,self.py)
590 DrawSash(parent,self.px,self.py,self.side)
591 self.CaptureMouse()
592
593 def OnRelease(self,evt):
594 if self.isDrag:
595 parent = self.GetParent()
596 DrawSash(parent,self.px,self.py,self.side)
597 self.ReleaseMouse()
598 self.isDrag = False
599
600 if self.side == MV_HOR:
601 parent.AddLeaf(MV_VER,self.py)
602 else:
603 parent.AddLeaf(MV_HOR,self.px)
604 else:
605 evt.Skip()
606
607 def OnPaint(self,evt):
b881fc78
RD
608 dc = wx.PaintDC(self)
609 dc.SetBackground(wx.Brush(self.GetBackgroundColour(),wx.SOLID))
d14a1e28
RD
610 dc.Clear()
611
b881fc78
RD
612 highlight = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNHIGHLIGHT), 1, wx.SOLID)
613 shadow = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW), 1, wx.SOLID)
614 black = wx.Pen(wx.BLACK,1,wx.SOLID)
615 w,h = self.GetSize()
d14a1e28
RD
616 w -= 1
617 h -= 1
618
619 # Draw outline
620 dc.SetPen(highlight)
d7403ad2
RD
621 dc.DrawLine(0,0, 0,h)
622 dc.DrawLine(0,0, w,0)
d14a1e28 623 dc.SetPen(black)
d7403ad2
RD
624 dc.DrawLine(0,h, w+1,h)
625 dc.DrawLine(w,0, w,h)
d14a1e28 626 dc.SetPen(shadow)
d7403ad2 627 dc.DrawLine(w-1,2, w-1,h)
d14a1e28
RD
628
629#----------------------------------------------------------------------
630
631
b881fc78 632class MultiCloser(wx.Window):
d14a1e28
RD
633 def __init__(self,parent):
634 x,y,w,h = self.CalcSizePos(parent)
b881fc78
RD
635 wx.Window.__init__(self,id = -1,parent = parent,
636 pos = (x,y),
637 size = (w,h),
638 style = wx.CLIP_CHILDREN)
d14a1e28
RD
639
640 self.down = False
641 self.entered = False
642
b881fc78
RD
643 self.Bind(wx.EVT_LEFT_DOWN,self.OnPress)
644 self.Bind(wx.EVT_LEFT_UP,self.OnRelease)
645 self.Bind(wx.EVT_PAINT,self.OnPaint)
646 self.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeave)
647 self.Bind(wx.EVT_ENTER_WINDOW,self.OnEnter)
d14a1e28
RD
648
649 def OnLeave(self,evt):
b881fc78 650 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
d14a1e28
RD
651 self.entered = False
652
653 def OnEnter(self,evt):
b881fc78 654 self.SetCursor(wx.StockCursor(wx.CURSOR_BULLSEYE))
d14a1e28
RD
655 self.entered = True
656
657 def OnPress(self,evt):
658 self.down = True
659 evt.Skip()
660
661 def OnRelease(self,evt):
662 if self.down and self.entered:
663 self.GetParent().DestroyLeaf()
664 else:
665 evt.Skip()
666 self.down = False
667
668 def OnPaint(self,evt):
b881fc78
RD
669 dc = wx.PaintDC(self)
670 dc.SetBackground(wx.Brush(wx.RED,wx.SOLID))
d14a1e28
RD
671 dc.Clear()
672
673 def CalcSizePos(self,parent):
b881fc78 674 pw,ph = parent.GetSize()
d14a1e28
RD
675 x = pw - SH_SIZE
676 w = SH_SIZE
677 h = SH_SIZE + 2
678 y = 1
679 return (x,y,w,h)
680
681 def OnSize(self,evt):
682 x,y,w,h = self.CalcSizePos(self.GetParent())
683 self.SetDimensions(x,y,w,h)
684
685
686#----------------------------------------------------------------------
687
688
b881fc78 689class EmptyChild(wx.Window):
d14a1e28 690 def __init__(self,parent):
b881fc78 691 wx.Window.__init__(self,parent,-1, style = wx.CLIP_CHILDREN)
d14a1e28
RD
692
693
694#----------------------------------------------------------------------
695
696
697def DrawSash(win,x,y,direction):
b881fc78 698 dc = wx.ScreenDC()
d14a1e28 699 dc.StartDrawingOnTopWin(win)
b881fc78
RD
700 bmp = wx.EmptyBitmap(8,8)
701 bdc = wx.MemoryDC()
d14a1e28 702 bdc.SelectObject(bmp)
d7403ad2 703 bdc.DrawRectangle(-1,-1, 10,10)
d14a1e28
RD
704 for i in range(8):
705 for j in range(8):
706 if ((i + j) & 1):
d7403ad2 707 bdc.DrawPoint(i,j)
d14a1e28 708
b881fc78 709 brush = wx.Brush(wx.Colour(0,0,0))
d14a1e28
RD
710 brush.SetStipple(bmp)
711
712 dc.SetBrush(brush)
b881fc78 713 dc.SetLogicalFunction(wx.XOR)
d14a1e28 714
b881fc78 715 body_w,body_h = win.GetClientSize()
d14a1e28
RD
716
717 if y < 0:
718 y = 0
719 if y > body_h:
720 y = body_h
721 if x < 0:
722 x = 0
723 if x > body_w:
724 x = body_w
725
726 if direction == MV_HOR:
727 x = 0
728 else:
729 y = 0
730
731 x,y = win.ClientToScreenXY(x,y)
732
733 w = body_w
734 h = body_h
735
736 if direction == MV_HOR:
d7403ad2 737 dc.DrawRectangle(x,y-2, w,4)
d14a1e28 738 else:
d7403ad2 739 dc.DrawRectangle(x-2,y, 4,h)
d14a1e28
RD
740
741 dc.EndDrawingOnTop()