Package Gnumed :: Package wxpython :: Module gmMultiSash
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmMultiSash

  1  #---------------------------------------------------------------------- 
  2  # ORIGINAL HEADER: 
  3  # 
  4  # Name:                 multisash 
  5  # Purpose:              Multi Sash control 
  6  # 
  7  # Author:               Gerrit van Dyk 
  8  # 
  9  # Created:              2002/11/20 
 10  # Version:              0.1 
 11  # RCS-ID:               $Id: gmMultiSash.py,v 1.7 2005-09-28 21:27:30 ncq Exp $ 
 12  # License:              wxWindows licensie 
 13  #---------------------------------------------------------------------- 
 14  # $Source: /home/ncq/Projekte/cvs2git/vcs-mirror/gnumed/gnumed/client/wxpython/gmMultiSash.py,v $ 
 15  # $Id: gmMultiSash.py,v 1.7 2005-09-28 21:27:30 ncq Exp $ 
 16  __version__ = "$Revision: 1.7 $" 
 17  __author__ = "Gerrit van Dyk, Carlos, Karsten" 
 18  #__license__ = "GPL" 
 19   
 20  try: 
 21          import wxversion 
 22          import wx 
 23  except ImportError: 
 24          from wxPython import wx 
 25              
 26  MV_HOR = 0 
 27  MV_VER = not MV_HOR 
 28   
 29  SH_SIZE = 5 
 30  CR_SIZE = SH_SIZE * 3 
 31   
 32  #---------------------------------------------------------------------- 
33 -class cMultiSash(wx.Window):
34 """ 35 Main multisash widget. Dynamically displays a stack of child widgets. 36 """
37 - def __init__(self, *_args,**_kwargs):
38 apply(wx.Window.__init__,(self,) + _args,_kwargs) 39 #self._defChild = cEmptyChild 40 self.child = cMultiSashSplitter(self,self,wxPoint(0,0),self.GetSize()) 41 42 # Gnumed: focused and bottom leaf 43 self.focussed_leaf = self.child.leaf1 44 self.bottom_leaf = self.child.leaf1 45 self.displayed_leafs = [] 46 47 wx.EVT_SIZE(self,self._on_size)
48 #--------------------------------------------- 49 # public API 50 #--------------------------------------------- 51 # Gnumed:
52 - def get_focussed_leaf(self):
53 """ 54 Retrieves the currently focused leaf. Typically, used to 55 process some action over the focused widget. 56 """ 57 return self.focussed_leaf
58 #---------------------------------------------
59 - def get_displayed_leafs(self):
60 """ 61 Retrieves the currently displayed leafs. 62 """ 63 return self.displayed_leafs
64 #---------------------------------------------
65 - def add_content(self, content):
66 """ 67 Adds he supplied content widget to the multisash, setting it as 68 child of the bottom leaf. 69 70 @param content The new content widget to add. 71 @type content Any wx.Window derived object. 72 """ 73 successful, errno = self.bottom_leaf.AddLeaf(direction = MV_VER, pos = 100) 74 if successful: 75 self.bottom_leaf.set_content(content) 76 return successful, errno
77 #---------------------------------------------
78 - def Clear(self):
79 """ 80 Clear all mulsisash leafs and restores initial values 81 """ 82 # FIXME: keep an eye if strange behaviour 83 old = self.child 84 self.child = cMultiSashSplitter(self,self,wxPoint(0,0),self.GetSize()) 85 old.Destroy() 86 self.child.OnSize(None) 87 88 # Gnumed: focused and bottom leaf 89 self.focussed_leaf = self.child.leaf1 90 self.bottom_leaf = self.child.leaf1 91 self.bottom_leaf.Select() 92 self.displayed_leafs = []
93 #---------------------------------------------
94 - def refresh_bottom_leaf(self, bottom_leaf = None):
95 """ 96 Updates the field that keeps track of the bottom leaf. It is required 97 to ensure new leafs are created under the bottom one. 98 If the bottom leaf is supplied as parameter, it is set. Typically, 99 after a new leaf has been added/created. 100 If the bottom leaf ins not supplied ad parameter, it will be dinamically 101 obtained. Typically, after leaf destruction. 102 103 @param bottom_leaf The leaf to be set as bottom one 104 @type bottom_leaf wx.MultiViewLeaf 105 """ 106 if bottom_leaf is None: 107 self.bottom_leaf = self.__find_bottom_leaf(self.child) 108 else: 109 self.bottom_leaf = bottom_leaf 110 self.bottom_leaf.Select()
111 112 #---------------------------------------------
113 - def refresh_displayed_leafs(self, splitter):
114 """ 115 Recursively find all displayed leafs. 116 @param splitter The multisash splitter to traverse its leafs for. 117 @type splitter cMultiSashSplitter 118 """ 119 if id(splitter) == id(self.child): 120 self.displayed_leafs = [] 121 # print "__refresh_displayed_leafs()" 122 # print "splitter: %s [%s]" % (splitter.__class__.__name__, id(splitter)) 123 # print "- leaf 1: %s [%s]" % (splitter.leaf1.__class__.__name__, id(splitter.leaf1)) 124 # print "- leaf 2: %s [%s]" % (splitter.leaf2.__class__.__name__, id(splitter.leaf2)) 125 if isinstance(splitter.leaf1, cMultiSashSplitter): 126 # print "leaf 1 is splitter, recurse down" 127 self.refresh_displayed_leafs(splitter.leaf1) 128 if isinstance(splitter.leaf2, cMultiSashSplitter): 129 # print "leaf 2 is splitter, recurse down" 130 self.refresh_displayed_leafs(splitter.leaf2) 131 # print "found bottom split: %s [%s]" % (splitter.__class__.__name__, id(splitter)) 132 if not splitter.leaf2 is None and not isinstance(splitter.leaf2, cMultiSashSplitter): 133 # print "found leaf (leaf2): %s [%s]" % (splitter.leaf2.__class__.__name__, id(splitter.leaf2)) 134 self.displayed_leafs.append(splitter.leaf2) 135 if not splitter.leaf1 is None and not isinstance(splitter.leaf1, cMultiSashSplitter): 136 # print "found leaf (leaf1): %s [%s]" % (splitter.leaf1.__class__.__name__, id(splitter.leaf1)) 137 self.displayed_leafs.append(splitter.leaf1)
138 #--------------------------------------------- 139 # event handlers 140 #---------------------------------------------
141 - def _on_size(self, evt):
142 self.child.SetSize(self.GetSize())
143 #--------------------------------------------- 144 # internal API 145 #---------------------------------------------
146 - def __find_bottom_leaf(self, splitter):
147 """ 148 Recursively find and return the bottom leaf. 149 """ 150 # print "__find_bottom_leaf()" 151 # print "splitter: %s [%s]" % (splitter.__class__.__name__, id(splitter)) 152 # print "- leaf 1: %s [%s]" % (splitter.leaf1.__class__.__name__, id(splitter.leaf1)) 153 # print "- leaf 2: %s [%s]" % (splitter.leaf2.__class__.__name__, id(splitter.leaf2)) 154 if isinstance(splitter.leaf1, cMultiSashSplitter): 155 # print "leaf 1 is splitter, recurse down" 156 return self.__find_bottom_leaf(splitter.leaf1) 157 if isinstance(splitter.leaf2, cMultiSashSplitter): 158 # print "leaf 2 is splitter, recurse down" 159 return self.__find_bottom_leaf(splitter.leaf2) 160 # print "found bottom split: %s [%s]" % (splitter.__class__.__name__, id(splitter)) 161 if not splitter.leaf2 is None: 162 # print "bottom leaf (leaf2): %s [%s]" % (splitter.leaf2.__class__.__name__, id(splitter.leaf2)) 163 return splitter.leaf2 164 else: 165 # print "bottom leaf (leaf1): %s [%s]" % (splitter.leaf1.__class__.__name__, id(splitter.leaf1)) 166 return splitter.leaf1
167 #---------------------------------------------
168 - def _unselect(self):
169 self.child._unselect()
170 #----------------------------------------------------------------------
171 -class cMultiSashSplitter(wx.Window):
172 """ 173 Basic split windows container of the multisash widget. 174 Has references to two leafs or splitted windows (typically, first leaf 175 is another cMultiSashSplitter and the second leaf is the displayed content 176 widget). 177 """
178 - def __init__(self, top_parent, parent, pos, size, leaf1 = None):
179 wx.Window.__init__ ( 180 self, 181 id = -1, 182 parent = parent, 183 pos = pos, 184 size = size, 185 style = wx.CLIP_CHILDREN 186 ) 187 self.top_parent = top_parent 188 self.leaf2 = None 189 if leaf1: 190 self.leaf1 = leaf1 191 self.leaf1.Reparent(self) 192 self.leaf1.MoveXY(0,0) 193 else: 194 self.leaf1 = cMultiSashLeaf ( 195 self.top_parent, 196 self, 197 wxPoint(0,0), 198 self.GetSize() 199 ) 200 self.direction = None 201 202 wx.EVT_SIZE(self,self.OnSize)
203 #---------------------------------------------
204 - def _unselect(self):
205 if self.leaf1: 206 self.leaf1._unselect() 207 if self.leaf2: 208 self.leaf2._unselect()
209 210 #---------------------------------------------
211 - def AddLeaf(self,direction,caller,pos):
212 # print '%s[%s].AddLeaf()' % (self.__class__.__name__, id(self)) 213 # print "leaf 1: %s [%s]" % (self.leaf1.__class__.__name__, id(self.leaf1)) 214 # print "leaf 2: %s [%s]" % (self.leaf2.__class__.__name__, id(self.leaf2)) 215 if self.leaf2: 216 # print "we have two leafs" 217 # print "caller: %s [%s]" % (caller.__class__.__name__, id(caller)) 218 if caller == self.leaf1: 219 # print "caller was leaf 1, hence splitting leaf 1" 220 self.leaf1 = cMultiSashSplitter(self.top_parent,self, 221 caller.GetPosition(), 222 caller.GetSize(), 223 caller) 224 self.leaf1.AddLeaf(direction,caller,pos) 225 else: 226 # print "caller was leaf 2, hence splitting leaf 2" 227 self.leaf2 = cMultiSashSplitter(self.top_parent,self, 228 caller.GetPosition(), 229 caller.GetSize(), 230 caller) 231 self.leaf2.AddLeaf(direction,caller,pos) 232 else: 233 # print "we have only one leaf" 234 # print "caller: %s [%s]" % (caller.__class__.__name__, id(caller)) 235 # print "hence caller must have been leaf 1 hence adding leaf 2 ..." 236 self.direction = direction 237 w,h = self.GetSizeTuple() 238 if direction == MV_HOR: 239 # print "... next to leaf 1" 240 x,y = (pos,0) 241 w1,h1 = (w-pos,h) 242 w2,h2 = (pos,h) 243 else: 244 # print "... below leaf 1" 245 x,y = (0,pos) 246 w1,h1 = (w,h-pos) 247 w2,h2 = (w,pos) 248 self.leaf2 = cMultiSashLeaf(self.top_parent,self, 249 wxPoint(x,y),wx.Size(w1,h1)) 250 self.leaf1.SetSize(wx.Size(w2,h2)) 251 self.leaf2.OnSize(None) 252 # Gnumed: register added leaf content 253 self.top_parent.displayed_leafs.append(self.leaf2) 254 # Gnumed: sets the newly created leaf as the bottom and focus it 255 self.top_parent.refresh_bottom_leaf(self.leaf2) 256 self.leaf2.set_focus()
257
258 - def DestroyLeaf(self,caller):
259 # print '%s[%s].DestroyLeaf()' % (self.__class__.__name__, id(self)) 260 top_parent = self.top_parent 261 if not self.leaf2: 262 self.leaf1.set_content(cEmptyChild(self)) # We will only have 2 windows if 263 return # we need to destroy any 264 parent = self.GetParent() # Another splitview 265 if parent == self.top_parent: # We'r at the root 266 # print "parent is root view" 267 # print "caller: %s [%s]" % (caller.__class__.__name__, id(caller)) 268 if caller == self.leaf1: 269 # print "caller is leaf 1, hence destroying leaf 1 and copying leaf 2 to leaf 1" 270 old = self.leaf1 271 self.leaf1 = self.leaf2 272 self.leaf2 = None 273 # Gnumed: remove content from displayed leafs 274 #print "Removing old: %s [%s]" % (old.__class__.__name__, id(old)) 275 #self.top_parent.displayed_leafs.remove(old) 276 old.Destroy() 277 else: 278 # print "caller is leaf 2, hence destroying leaf 2" 279 # Gnumed: remove content from displayed leafs 280 #print "Removing leaf2: %s [%s]" % (self.leaf2.__class__.__name__, id(self.leaf2)) 281 #self.top_parent.displayed_leafs.remove(self.leaf2) 282 self.leaf2.Destroy() 283 self.leaf2 = None 284 self.leaf1.SetSize(self.GetSize()) 285 self.leaf1.Move(self.GetPosition()) 286 else: 287 # print "parent is NOT root view" 288 # print "caller: %s [%s]" % (caller.__class__.__name__, id(caller)) 289 # print "Removing caller" 290 # Gnumed: remove content from displayed leafs 291 self.top_parent.displayed_leafs.remove(caller) 292 w,h = self.GetSizeTuple() 293 x,y = self.GetPositionTuple() 294 if caller == self.leaf1: 295 if self == parent.leaf1: 296 # print "... leaf 1 ..." 297 parent.leaf1 = self.leaf2 298 else: 299 # print "... leaf 2 ..." 300 parent.leaf2 = self.leaf2 301 # print "... so replacing ourselves in the parent with our leaf 2" 302 self.leaf2.Reparent(parent) 303 self.leaf2.SetDimensions(x,y,w,h) 304 # print "caller is leaf 2" 305 # print "in the parent we are ..." 306 else: 307 if self == parent.leaf1: 308 # print "... leaf 1 ..." 309 parent.leaf1 = self.leaf1 310 else: 311 # print "... leaf 2 ..." 312 parent.leaf2 = self.leaf1 313 # print "... so replacing ourselves in the parent with our leaf 1" 314 self.leaf1.Reparent(parent) 315 self.leaf1.SetDimensions(x,y,w,h) 316 317 self.leaf1 = None 318 self.leaf2 = None 319 top_parent = self.top_parent 320 self.Destroy() 321 # try: 322 # print "leaf 1: %s [%s]" % (self.leaf1.__class__.__name__, id(self.leaf1)) 323 # except: 324 # pass 325 # try: 326 # print "leaf 2: %s [%s]" % (self.leaf2.__class__.__name__, id(self.leaf2)) 327 # except: 328 # pass 329 # Gnumed: find and update the bottom leaf 330 top_parent.refresh_bottom_leaf() 331 top_parent.refresh_displayed_leafs(top_parent.child)
332 # print "\nGuessed leafs:" 333 # cont = 0 334 # for a_leaf in top_parent.displayed_leafs: 335 # cont +=1 336 # print "leaf %d: %s [%s]" % (cont, a_leaf.__class__.__name__, id(a_leaf)) 337 #---------------------------------------------
338 - def CanSize(self,side,view):
339 if self.SizeTarget(side,view): 340 return True 341 return False
342
343 - def SizeTarget(self,side,view):
344 if self.direction == side and self.leaf2 and view == self.leaf1: 345 return self 346 parent = self.GetParent() 347 if parent != self.top_parent: 348 return parent.SizeTarget(side,self) 349 return None
350
351 - def SizeLeaf(self,leaf,pos,side):
352 if self.direction != side: 353 return 354 if not (self.leaf1 and self.leaf2): 355 return 356 if pos < 10: return 357 w,h = self.GetSizeTuple() 358 if side == MV_HOR: 359 if pos > w - 10: return 360 else: 361 if pos > h - 10: return 362 if side == MV_HOR: 363 self.leaf1.SetDimensions(0,0,pos,h) 364 self.leaf2.SetDimensions(pos,0,w-pos,h) 365 else: 366 self.leaf1.SetDimensions(0,0,w,pos) 367 self.leaf2.SetDimensions(0,pos,w,h-pos)
368
369 - def OnSize(self,evt):
370 if not self.leaf2: 371 self.leaf1.SetSize(self.GetSize()) 372 self.leaf1.OnSize(None) 373 return 374 v1w,v1h = self.leaf1.GetSizeTuple() 375 v2w,v2h = self.leaf2.GetSizeTuple() 376 v1x,v1y = self.leaf1.GetPositionTuple() 377 v2x,v2y = self.leaf2.GetPositionTuple() 378 w,h = self.GetSizeTuple() 379 380 if v1x != v2x: 381 ratio = float(w) / float((v1w + v2w)) 382 v1w *= ratio 383 v2w = w - v1w 384 v2x = v1w 385 else: 386 v1w = v2w = w 387 388 if v1y != v2y: 389 ratio = float(h) / float((v1h + v2h)) 390 v1h *= ratio 391 v2h = h - v1h 392 v2y = v1h 393 else: 394 v1h = v2h = h 395 396 self.leaf1.SetDimensions(v1x,v1y,v1w,v1h) 397 self.leaf2.SetDimensions(v2x,v2y,v2w,v2h) 398 self.leaf1.OnSize(None) 399 self.leaf2.OnSize(None)
400 401 #----------------------------------------------------------------------
402 -class cMultiSashLeaf(wx.Window):
403 """ 404 A leaf represent a split window, one instance of the displayed content 405 widget. 406 """
407 - def __init__(self,top_parent,parent,pos,size):
408 wx.Window.__init__(self,id = -1,parent = parent,pos = pos,size = size, 409 style = wx.CLIP_CHILDREN) 410 self.top_parent = top_parent 411 412 self.sizerHor = cMultiSizer(self,MV_HOR) 413 self.sizerVer = cMultiSizer(self,MV_VER) 414 # Gnumed: Disable creators until obvious solution 415 #self.creatorHor = cMultiCreator(self,MV_HOR) 416 #self.creatorVer = cMultiCreator(self,MV_VER) 417 self.content = cMultiSashLeafContent(self) 418 self.closer = cMultiCloser(self) 419 420 wx.EVT_SIZE(self,self.OnSize)
421 #-----------------------------------------------------
422 - def set_focus(self):
423 """ 424 Set current leaf as focused leaf. Typically, the focused widget 425 will be required to further actions and processing. 426 """ 427 self.top_parent.focussed_leaf = self
428 # print "focussed soap editor leaf:", self.__class__.__name__, id(self) 429
430 - def _unselect(self):
431 self.content._unselect()
432 433 #-----------------------------------------------------
434 - def set_content(self, content):
435 """ 436 Sets the as content child of this leaf. 437 438 @param content The new content widget to set.. 439 @type content Any wx.Window derived object. 440 """ 441 self.content.set_new_content(content)
442 443 #-----------------------------------------------------
444 - def get_content(self):
445 """ 446 Retrieves the content child of this leaf. 447 """ 448 return self.content.child
449 450 #-----------------------------------------------------
451 - def Select(self):
452 """ 453 Select the leaf 454 """ 455 self.content.Select()
456 #-----------------------------------------------------
457 - def AddLeaf(self,direction,pos):
458 """Add a leaf. 459 460 returns (Status, error) 461 errors: 462 1: lacking space to add leaf 463 """ 464 # print '%s[%s].AddLeaf()' % (self.__class__.__name__, id(self)) 465 if pos < 10: 466 pos = 10 467 w,h = self.GetSizeTuple() 468 if direction == MV_VER: 469 if pos > h - 10: 470 # print "pos", pos 471 # print "w,h", w, h 472 return (False, 1) 473 else: 474 if pos > w - 10: return (False, 1) 475 # Gnumed: when initial leaf, replace its content widget and focus it 476 # else, add a new leaf 477 if not isinstance(self.content.child, cEmptyChild): 478 self.GetParent().AddLeaf(direction,self,pos) 479 else: 480 self.set_focus() 481 # Gnumed: register added leaf content 482 self.GetParent().top_parent.displayed_leafs.append(self) 483 return (True, None)
484 485 #---------------------------------------------
486 - def DestroyLeaf(self):
487 # print '%s[%s].DestroyLeaf()' % (self.__class__.__name__, id(self)) 488 self.GetParent().DestroyLeaf(self)
489 490 #-----------------------------------------------------
491 - def SizeTarget(self,side):
492 return self.GetParent().SizeTarget(side,self)
493
494 - def CanSize(self,side):
495 return self.GetParent().CanSize(side,self)
496
497 - def OnSize(self,evt):
498 self.sizerHor.OnSize(evt) 499 self.sizerVer.OnSize(evt) 500 # Gnumed: creators disables until obvious solution 501 #self.creatorHor.OnSize(evt) 502 #self.creatorVer.OnSize(evt) 503 self.content.OnSize(evt) 504 self.closer.OnSize(evt)
505 506 #----------------------------------------------------------------------
507 -class cMultiSashLeafContent(wx.Window):
508 """ 509 Widget that encapsulate contents of a leaf or split window. 510 """
511 - def __init__(self,parent):
512 w,h = self.CalcSize(parent) 513 wx.Window.__init__ ( 514 self, 515 id = -1, 516 parent = parent, 517 pos = wxPoint(0,0), 518 size = wx.Size(w,h), 519 style = wx.CLIP_CHILDREN | wx.SUNKEN_BORDER 520 ) 521 self.child = cEmptyChild(self) 522 self.child.MoveXY(2,2) 523 self.__normal_colour = self.GetBackgroundColour() 524 self.selected = False 525 526 wx.EVT_SET_FOCUS(self, self._on_set_focus) 527 wx.EVT_CHILD_FOCUS(self, self._on_child_focus)
528 #---------------------------------------------
529 - def set_new_content(self,content):
530 """ 531 Sets the as content child of this widget. 532 533 @param content The new content widget to set.. 534 @type content Any wx.Window derived object. 535 """ 536 # Gnumed: avoid yellow blinking during widget replacement 537 self.SetBackgroundColour(self.__normal_colour) 538 if self.child: 539 self.child.Destroy() 540 content.Reparent(self) 541 self.child = content 542 self.child.MoveXY(2,2) 543 # Gnumed: required to a proper layout of the child and parent widgets 544 self.Select() 545 self.OnSize(None)
546 #--------------------------------------------- 547 # internal API 548 #---------------------------------------------
549 - def _unselect(self):
550 if self.selected: 551 self.selected = False 552 self.SetBackgroundColour(self.__normal_colour) 553 self.Refresh()
554 #---------------------------------------------
555 - def _on_set_focus(self,evt):
556 self.Select()
557 #---------------------------------------------
558 - def _on_child_focus(self,evt):
559 self._on_set_focus(evt)
560 ## from Funcs import FindFocusedChild 561 ## child = FindFocusedChild(self) 562 ## wx.EVT_KILL_FOCUS(child,self.OnChildKillFocus) 563 564 #---------------------------------------------
565 - def Select(self):
566 """ 567 May be invoked by user clicking on the leaf, or programmatically after 568 leaf creation. Highlight it and update focused leaf. 569 """ 570 # Gnumed: when the leaf is selected, highlight and update selected focus 571 parent = self.GetParent() 572 parent.top_parent._unselect() 573 self.selected = True 574 if parent.top_parent.focussed_leaf != parent: 575 parent.set_focus() 576 self.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow 577 self.Refresh()
578
579 - def CalcSize(self,parent):
580 w,h = parent.GetSizeTuple() 581 w -= SH_SIZE 582 h -= SH_SIZE 583 return (w,h)
584
585 - def OnSize(self,evt):
586 w,h = self.CalcSize(self.GetParent()) 587 self.SetDimensions(0,0,w,h) 588 w,h = self.GetClientSizeTuple() 589 self.child.SetSize(wx.Size(w-4,h-4))
590 #----------------------------------------------------------------------
591 -class cMultiSizer(wx.Window):
592 """ 593 Leaf's sash bar 594 """
595 - def __init__(self,parent,side):
596 self.side = side 597 x,y,w,h = self.CalcSizePos(parent) 598 wx.Window.__init__(self,id = -1,parent = parent, 599 pos = wxPoint(x,y), 600 size = wx.Size(w,h), 601 style = wx.CLIP_CHILDREN) 602 603 self.px = None # Previous X 604 self.py = None # Previous Y 605 self.isDrag = False # In Dragging 606 self.dragTarget = None # View being sized 607 608 wx.EVT_LEAVE_WINDOW(self,self.OnLeave) 609 wx.EVT_ENTER_WINDOW(self,self.OnEnter) 610 wx.EVT_MOTION(self,self.OnMouseMove) 611 wx.EVT_LEFT_DOWN(self,self.OnPress) 612 wx.EVT_LEFT_UP(self,self.OnRelease)
613
614 - def CalcSizePos(self,parent):
615 pw,ph = parent.GetSizeTuple() 616 if self.side == MV_HOR: 617 x = CR_SIZE + 2 618 y = ph - SH_SIZE 619 w = pw - CR_SIZE - SH_SIZE - 2 620 h = SH_SIZE 621 else: 622 x = pw - SH_SIZE 623 y = CR_SIZE + 2 + SH_SIZE 624 w = SH_SIZE 625 h = ph - CR_SIZE - SH_SIZE - 4 - SH_SIZE # For Closer 626 return (x,y,w,h)
627
628 - def OnSize(self,evt):
629 x,y,w,h = self.CalcSizePos(self.GetParent()) 630 self.SetDimensions(x,y,w,h)
631
632 - def OnLeave(self,evt):
633 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
634
635 - def OnEnter(self,evt):
636 if not self.GetParent().CanSize(not self.side): 637 return 638 if self.side == MV_HOR: 639 self.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS)) 640 else: 641 self.SetCursor(wx.StockCursor(wx.CURSOR_SIZEWE))
642
643 - def OnMouseMove(self,evt):
644 if self.isDrag: 645 DrawSash(self.dragTarget,self.px,self.py,self.side) 646 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) 647 self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py) 648 DrawSash(self.dragTarget,self.px,self.py,self.side) 649 else: 650 evt.Skip()
651
652 - def OnPress(self,evt):
653 self.dragTarget = self.GetParent().SizeTarget(not self.side) 654 if self.dragTarget: 655 self.isDrag = True 656 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) 657 self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py) 658 DrawSash(self.dragTarget,self.px,self.py,self.side) 659 self.CaptureMouse() 660 else: 661 evt.Skip()
662
663 - def OnRelease(self,evt):
664 if self.isDrag: 665 DrawSash(self.dragTarget,self.px,self.py,self.side) 666 self.ReleaseMouse() 667 self.isDrag = False 668 if self.side == MV_HOR: 669 self.dragTarget.SizeLeaf(self.GetParent(), 670 self.py,not self.side) 671 else: 672 self.dragTarget.SizeLeaf(self.GetParent(), 673 self.px,not self.side) 674 self.dragTarget = None 675 else: 676 evt.Skip()
677 678 #----------------------------------------------------------------------
679 -class cMultiCreator(wx.Window):
680 """ 681 Sash bar's creator element 682 """
683 - def __init__(self,parent,side):
684 self.side = side 685 x,y,w,h = self.CalcSizePos(parent) 686 wx.Window.__init__(self,id = -1,parent = parent, 687 pos = wxPoint(x,y), 688 size = wx.Size(w,h), 689 style = wx.CLIP_CHILDREN) 690 691 self.px = None # Previous X 692 self.py = None # Previous Y 693 self.isDrag = False # In Dragging 694 695 wx.EVT_LEAVE_WINDOW(self,self.OnLeave) 696 wx.EVT_ENTER_WINDOW(self,self.OnEnter) 697 wx.EVT_MOTION(self,self.OnMouseMove) 698 wx.EVT_LEFT_DOWN(self,self.OnPress) 699 wx.EVT_LEFT_UP(self,self.OnRelease) 700 wx.EVT_PAINT(self,self.OnPaint)
701
702 - def CalcSizePos(self,parent):
703 pw,ph = parent.GetSizeTuple() 704 if self.side == MV_HOR: 705 x = 2 706 y = ph - SH_SIZE 707 w = CR_SIZE 708 h = SH_SIZE 709 else: 710 x = pw - SH_SIZE 711 y = 4 + SH_SIZE # Make provision for closer 712 w = SH_SIZE 713 h = CR_SIZE 714 return (x,y,w,h)
715
716 - def OnSize(self,evt):
717 x,y,w,h = self.CalcSizePos(self.GetParent()) 718 self.SetDimensions(x,y,w,h)
719
720 - def OnLeave(self,evt):
721 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
722
723 - def OnEnter(self,evt):
724 if self.side == MV_HOR: 725 self.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) 726 else: 727 self.SetCursor(wx.StockCursor(wx.CURSOR_POINT_LEFT))
728
729 - def OnMouseMove(self,evt):
730 if self.isDrag: 731 parent = self.GetParent() 732 DrawSash(parent,self.px,self.py,self.side) 733 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) 734 self.px,self.py = parent.ScreenToClientXY(self.px,self.py) 735 DrawSash(parent,self.px,self.py,self.side) 736 else: 737 evt.Skip()
738
739 - def OnPress(self,evt):
740 self.isDrag = True 741 parent = self.GetParent() 742 self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) 743 self.px,self.py = parent.ScreenToClientXY(self.px,self.py) 744 DrawSash(parent,self.px,self.py,self.side) 745 self.CaptureMouse()
746
747 - def OnRelease(self,evt):
748 if self.isDrag: 749 parent = self.GetParent() 750 DrawSash(parent,self.px,self.py,self.side) 751 self.ReleaseMouse() 752 self.isDrag = False 753 754 if self.side == MV_HOR: 755 parent.AddLeaf(MV_VER,self.py) 756 else: 757 parent.AddLeaf(MV_HOR,self.px) 758 else: 759 evt.Skip()
760
761 - def OnPaint(self,evt):
762 dc = wxPaintDC(self) 763 dc.SetBackground(wx.Brush(self.GetBackgroundColour(),wx.SOLID)) 764 dc.Clear() 765 766 highlight = wxPen(wx.SystemSettings_GetSystemColour( 767 wx.SYS_COLOUR_BTNHIGHLIGHT),1,wx.SOLID) 768 shadow = wxPen(wx.SystemSettings_GetSystemColour( 769 wx.SYS_COLOUR_BTNSHADOW),1,wx.SOLID) 770 black = wxPen(wx.BLACK,1,wx.SOLID) 771 w,h = self.GetSizeTuple() 772 w -= 1 773 h -= 1 774 775 # Draw outline 776 dc.SetPen(highlight) 777 dc.DrawLine(0,0,0,h) 778 dc.DrawLine(0,0,w,0) 779 dc.SetPen(black) 780 dc.DrawLine(0,h,w+1,h) 781 dc.DrawLine(w,0,w,h) 782 dc.SetPen(shadow) 783 dc.DrawLine(w-1,2,w-1,h)
784 785 #----------------------------------------------------------------------
786 -class cMultiCloser(wx.Window):
787 """ 788 Sash bar's destroyer element 789 """
790 - def __init__(self,parent):
791 x,y,w,h = self.CalcSizePos(parent) 792 wx.Window.__init__(self,id = -1,parent = parent, 793 pos = wxPoint(x,y), 794 size = wx.Size(w,h), 795 style = wx.CLIP_CHILDREN) 796 797 self.down = False 798 self.entered = False 799 800 wx.EVT_LEFT_DOWN(self,self.OnPress) 801 wx.EVT_LEFT_UP(self,self.OnRelease) 802 wx.EVT_PAINT(self,self.OnPaint) 803 wx.EVT_LEAVE_WINDOW(self,self.OnLeave) 804 wx.EVT_ENTER_WINDOW(self,self.OnEnter)
805
806 - def OnLeave(self,evt):
807 self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) 808 self.entered = False
809
810 - def OnEnter(self,evt):
811 self.SetCursor(wx.StockCursor(wx.CURSOR_BULLSEYE)) 812 self.entered = True
813
814 - def OnPress(self,evt):
815 self.down = True 816 evt.Skip()
817
818 - def OnRelease(self,evt):
819 if self.down and self.entered: 820 self.GetParent().DestroyLeaf() 821 else: 822 evt.Skip() 823 self.down = False
824
825 - def OnPaint(self,evt):
826 dc = wxPaintDC(self) 827 dc.SetBackground(wx.Brush(wx.RED,wx.SOLID)) 828 dc.Clear()
829
830 - def CalcSizePos(self,parent):
831 pw,ph = parent.GetSizeTuple() 832 x = pw - SH_SIZE 833 w = SH_SIZE 834 h = SH_SIZE + 2 835 y = 1 836 return (x,y,w,h)
837
838 - def OnSize(self,evt):
839 x,y,w,h = self.CalcSizePos(self.GetParent()) 840 self.SetDimensions(x,y,w,h)
841 842 843 #---------------------------------------------------------------------- 844 845
846 -class cEmptyChild(wx.Window):
847 - def __init__(self,parent):
848 wx.Window.__init__(self,parent,-1, style = wx.CLIP_CHILDREN)
849 850 851 #---------------------------------------------------------------------- 852 853
854 -def DrawSash(win,x,y,direction):
855 dc = wx.ScreenDC() 856 dc.StartDrawingOnTopWin(win) 857 bmp = wx.EmptyBitmap(8,8) 858 bdc = wx.MemoryDC() 859 bdc.SelectObject(bmp) 860 bdc.DrawRectangle(-1,-1,10,10) 861 for i in range(8): 862 for j in range(8): 863 if ((i + j) & 1): 864 bdc.DrawPoint(i,j) 865 866 brush = wx.Brush(wx.Colour(0,0,0)) 867 brush.SetStipple(bmp) 868 869 dc.SetBrush(brush) 870 dc.SetLogicalFunction(wx.XOR) 871 872 body_w,body_h = win.GetClientSizeTuple() 873 874 if y < 0: 875 y = 0 876 if y > body_h: 877 y = body_h 878 if x < 0: 879 x = 0 880 if x > body_w: 881 x = body_w 882 883 if direction == MV_HOR: 884 x = 0 885 else: 886 y = 0 887 888 x,y = win.ClientToScreenXY(x,y) 889 890 w = body_w 891 h = body_h 892 893 if direction == MV_HOR: 894 dc.DrawRectangle(x,y-2,w,4) 895 else: 896 dc.DrawRectangle(x-2,y,4,h) 897 898 dc.EndDrawingOnTop()
899 #---------------------------------------------------------------------- 900