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