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