Home | Trees | Indices | Help |
---|
|
1 # --------------------------------------------------------------------------------- # 2 # SUPERTOOLTIP wxPython IMPLEMENTATION 3 # 4 # Andrea Gavana, @ 07 October 2008 5 # Latest Revision: 07 October 2008, 22.00 GMT 6 # 7 # 8 # TODO List 9 # 10 # 1) Maybe add some more customization like multiline text 11 # in the header and footer; 12 # 2) Check whether it's possible to use rounded corners and 13 # shadows on the Mac 14 # 15 # 16 # For all kind of problems, requests of enhancements and bug reports, please 17 # write to me at: 18 # 19 # andrea.gavana@gmail.com 20 # gavana@kpo.kz 21 # 22 # Or, obviously, to the wxPython mailing list!!! 23 # 24 # 25 # End Of Comments 26 # --------------------------------------------------------------------------------- # 27 28 """ 29 Description 30 =========== 31 32 SuperToolTip is a class that mimics the behaviour of wx.TipWindow and generic tooltip 33 windows, although it is a custom-drawn widget. 34 This class supports: 35 36 * Blended triple-gradient for the tooltip background; 37 * Header text and header image, with possibility to set the header font indipendently; 38 * Footer text and footer image, with possibility to set the footer font indipendently; 39 * Multiline text message in the tooltip body, plus an optional image as "body image"; 40 * Bold lines and hyperlink lines in the tooltip body; 41 * A wide set of predefined drawing styles for the tooltip background; 42 * Drawing of separator lines after the header and/or before the footer; 43 * Rounded corners and shadows below the tooltip window (Windows XP only); 44 * Fade in/fade out effects (Windows XP only); 45 * User-settable delays for the delay after which the tooltip appears and the delay 46 after which the tooltip is destroyed. 47 48 And a lot more. Check the demo for an almost complete review of the functionalities. 49 50 51 Supported Platforms 52 =================== 53 54 SuperToolTip has been tested on the following platforms: 55 * Windows (Windows XP). 56 57 58 Latest Revision: Andrea Gavana @ 07 October 2008, 22.00 GMT 59 Version 0.1 60 61 """ 62 63 import wx 64 import webbrowser 65 66 # Let's see if we can add few nice shadows to our tooltips (Windows only) 67 _libimported = None 68 69 if wx.Platform == "__WXMSW__": 70 osVersion = wx.GetOsVersion() 71 # Shadows behind menus are supported only in XP 72 if osVersion[1] == 5 and osVersion[2] == 1: 73 try: 74 # Try Mark Hammond's win32all extensions 75 import win32api 76 import win32con 77 import win32gui 78 import winxpgui 79 _libimported = "MH" 80 except ImportError: 81 _libimported = None 82 else: 83 _libimported = None 84 85 86 # Define a bunch of predefined colour schemes... 87 88 _colorSchemes = {"Beige": (wx.Colour(255,255,255), wx.Colour(242,242,223), wx.Colour(198,195,160), wx.Colour(0,0,0)), 89 "Blue": (wx.Colour(255,255,255), wx.Colour(202,220,246), wx.Colour(150,180,222), wx.Colour(0,0,0)), 90 "Blue 2": (wx.Colour(255,255,255), wx.Colour(228,236,248), wx.Colour(198,214,235), wx.Colour(0,0,0)), 91 "Blue 3": (wx.Colour(255,255,255), wx.Colour(213,233,243), wx.Colour(151,195,216), wx.Colour(0,0,0)), 92 "Blue 4": (wx.Colour(255,255,255), wx.Colour(227,235,255), wx.Colour(102,153,255), wx.Colour(0,0,0)), 93 "Blue Glass": (wx.Colour(182,226,253), wx.Colour(137,185,232), wx.Colour(188,244,253), wx.Colour(0,0,0)), 94 "Blue Glass 2": (wx.Colour(192,236,255), wx.Colour(147,195,242), wx.Colour(198,254,255), wx.Colour(0,0,0)), 95 "Blue Glass 3": (wx.Colour(212,255,255), wx.Colour(167,215,255), wx.Colour(218,255,255), wx.Colour(0,0,0)), 96 "Blue Inverted": (wx.Colour(117,160,222), wx.Colour(167,210,240), wx.Colour(233,243,255), wx.Colour(0,0,0)), 97 "Blue Shift": (wx.Colour(124,178,190), wx.Colour(13,122,153), wx.Colour(0,89,116), wx.Colour(255,255,255)), 98 "CodeProject": (wx.Colour(255,250,172), wx.Colour(255,207,157), wx.Colour(255,153,0), wx.Colour(0,0,0)), 99 "Dark Gray": (wx.Colour(195,195,195), wx.Colour(168,168,168), wx.Colour(134,134,134), wx.Colour(255,255,255)), 100 "Deep Purple": (wx.Colour(131,128,164), wx.Colour(112,110,143), wx.Colour(90,88,117), wx.Colour(255,255,255)), 101 "Electric Blue": (wx.Colour(224,233,255), wx.Colour(135,146,251), wx.Colour(99,109,233), wx.Colour(0,0,0)), 102 "Firefox": (wx.Colour(255,254,207), wx.Colour(254,248,125), wx.Colour(225,119,24), wx.Colour(0,0,0)), 103 "Gold": (wx.Colour(255,202,0), wx.Colour(255,202,0), wx.Colour(255,202,0), wx.Colour(0,0,0)), 104 "Gold Shift": (wx.Colour(178,170,107), wx.Colour(202,180,32), wx.Colour(162,139,1), wx.Colour(255,255,255)), 105 "Gray": (wx.Colour(255,255,255), wx.Colour(228,228,228), wx.Colour(194,194,194), wx.Colour(0,0,0)), 106 "Green": (wx.Colour(234,241,223), wx.Colour(211,224,180), wx.Colour(182,200,150), wx.Colour(0,0,0)), 107 "Green Shift": (wx.Colour(129,184,129), wx.Colour(13,185,15), wx.Colour(1,125,1), wx.Colour(255,255,255)), 108 "Light Green": (wx.Colour(174,251,171), wx.Colour(145,221,146), wx.Colour(90,176,89), wx.Colour(0,0,0)), 109 "NASA Blue": (wx.Colour(0,91,134), wx.Colour(0,100,150), wx.Colour(0,105,160), wx.Colour(255,255,255)), 110 "Office 2007 Blue": (wx.Colour(255,255,255), wx.Colour(242,246,251), wx.Colour(202,218,239), wx.Colour(76,76,76)), 111 "Orange Shift": (wx.Colour(179,120,80), wx.Colour(183,92,19), wx.Colour(157,73,1), wx.Colour(255,255,255)), 112 "Outlook Green": (wx.Colour(236,242,208), wx.Colour(219,230,187), wx.Colour(195,210,155), wx.Colour(0,0,0)), 113 "Pale Green": (wx.Colour(249,255,248), wx.Colour(206,246,209), wx.Colour(148,225,155), wx.Colour(0,0,0)), 114 "Pink Blush": (wx.Colour(255,254,255), wx.Colour(255,231,242), wx.Colour(255,213,233), wx.Colour(0,0,0)), 115 "Pink Shift": (wx.Colour(202,135,188), wx.Colour(186,8,158), wx.Colour(146,2,116), wx.Colour(255,255,255)), 116 "Pretty Pink": (wx.Colour(255,240,249), wx.Colour(253,205,217), wx.Colour(255,150,177), wx.Colour(0,0,0)), 117 "Red": (wx.Colour(255,183,176), wx.Colour(253,157,143), wx.Colour(206,88,78), wx.Colour(0,0,0)), 118 "Red Shift": (wx.Colour(186,102,102), wx.Colour(229,23,9), wx.Colour(182,11,1), wx.Colour(255,255,255)), 119 "Silver": (wx.Colour(255,255,255), wx.Colour(242,242,246), wx.Colour(212,212,224), wx.Colour(0,0,0)), 120 "Silver 2": (wx.Colour(255,255,255), wx.Colour(242,242,248), wx.Colour(222,222,228), wx.Colour(0,0,0)), 121 "Silver Glass": (wx.Colour(158,158,158), wx.Colour(255,255,255), wx.Colour(105,105,105), wx.Colour(0,0,0)), 122 "Silver Inverted": (wx.Colour(161,160,186), wx.Colour(199,201,213), wx.Colour(255,255,255), wx.Colour(0,0,0)), 123 "Silver Inverted 2": (wx.Colour(181,180,206), wx.Colour(219,221,233), wx.Colour(255,255,255), wx.Colour(0,0,0)), 124 "Soylent Green": (wx.Colour(134,211,131), wx.Colour(105,181,106), wx.Colour(50,136,49), wx.Colour(255,255,255)), 125 "Spring Green": (wx.Colour(154,231,151), wx.Colour(125,201,126), wx.Colour(70,156,69), wx.Colour(255,255,255)), 126 "Too Blue": (wx.Colour(255,255,255), wx.Colour(225,235,244), wx.Colour(188,209,226), wx.Colour(0,0,0)), 127 "Totally Green": (wx.Colour(190,230,160), wx.Colour(190,230,160), wx.Colour(190,230,160), wx.Colour(0,0,0)), 128 "XP Blue": (wx.Colour(119,185,236), wx.Colour(81,144,223), wx.Colour(36,76,171), wx.Colour(255,255,255)), 129 "Yellow": (wx.Colour(255,255,220), wx.Colour(255,231,161), wx.Colour(254,218,108), wx.Colour(0,0,0))} 130 131 132134 """ Returns the predefined styles keywords. """ 135 136 schemes = _colorSchemes.keys() 137 schemes.sort() 138 return schemes139 140142 """ 143 Makes a font bold. Utility method. 144 145 @param font: the font to be made bold. 146 """ 147 148 newFont = wx.Font(font.GetPointSize(), font.GetFamily(), font.GetStyle(), 149 wx.BOLD, font.GetUnderlined(), font.GetFaceName()) 150 151 return newFont152 153155 """ 156 Extract the link from an hyperlink line. 157 158 @param line: the line of text to be processed. 159 """ 160 161 line = line[4:] 162 indxStart = line.find("{") 163 indxEnd = line.find("}") 164 hl = line[indxStart+1:indxEnd].strip() 165 line = line[0:indxStart].strip() 166 167 return line, hl168 169171 """ Base class for the different Windows and Mac implementation. """ 172643 644 645 # Handle Mac and Windows/GTK differences... 646 647 if wx.Platform == "__WXMAC__": 648174 """ 175 Default class constructor. 176 177 @param parent: the L{SuperToolTip} parent widget; 178 @param classParent: the L{SuperToolTip} class object. 179 """ 180 181 self._spacing = 6 182 self._wasOnLink = False 183 self._hyperlinkRect, self._hyperlinkWeb = [], [] 184 185 self._classParent = classParent 186 self._alphaTimer = wx.Timer(self, wx.ID_ANY) 187 188 # Initialize the fonts 189 self.InitFont() 190 191 # Bind the events 192 self.Bind(wx.EVT_PAINT, self.OnPaint) 193 self.Bind(wx.EVT_SIZE, self.OnSize) 194 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) 195 self.Bind(wx.EVT_MOTION, self.OnMouseMotion) 196 self.Bind(wx.EVT_TIMER, self.AlphaCycle) 197 self.Bind(wx.EVT_KILL_FOCUS, self.OnDestroy) 198 self.Bind(wx.EVT_LEFT_DOWN, self.OnDestroy) 199 self.Bind(wx.EVT_LEFT_DCLICK, self.OnDestroy)200 201203 """ Initalizes the fonts for L{SuperToolTip}. """ 204 205 self._messageFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) 206 self._headerFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) 207 self._headerFont.SetWeight(wx.BOLD) 208 self._footerFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) 209 self._footerFont.SetWeight(wx.BOLD) 210 self._hyperlinkFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT) 211 self._hyperlinkFont.SetWeight(wx.BOLD) 212 self._hyperlinkFont.SetUnderlined(True)213 214216 """ Handles the wx.EVT_PAINT event for L{SuperToolTip}. """ 217 218 # Go with double buffering... 219 dc = wx.BufferedPaintDC(self) 220 221 frameRect = self.GetClientRect() 222 x, y, width, height = frameRect 223 # Store the rects for the hyperlink lines 224 self._hyperlinkRect, self._hyperlinkWeb = [], [] 225 classParent = self._classParent 226 227 # Retrieve the colours for the blended triple-gradient background 228 topColour, middleColour, bottomColour = classParent.GetTopGradientColour(), \ 229 classParent.GetMiddleGradientColour(), \ 230 classParent.GetBottomGradientColour() 231 232 # Get the user options for header, bitmaps etc... 233 drawHeader, drawFooter = classParent.GetDrawHeaderLine(), classParent.GetDrawFooterLine() 234 topRect = wx.Rect(frameRect.x, frameRect.y, frameRect.width, frameRect.height/2) 235 bottomRect = wx.Rect(frameRect.x, frameRect.y+frameRect.height/2, frameRect.width, frameRect.height/2+1) 236 # Fill the triple-gradient 237 dc.GradientFillLinear(topRect, topColour, middleColour, wx.SOUTH) 238 dc.GradientFillLinear(bottomRect, middleColour, bottomColour, wx.SOUTH) 239 240 header, headerBmp = classParent.GetHeader(), classParent.GetHeaderBitmap() 241 xPos, yPos = self._spacing, 0 242 bmpXPos = bmpYPos = 0 243 bmpHeight = textHeight = bmpWidth = 0 244 245 if headerBmp and headerBmp.IsOk(): 246 # We got the header bitmap 247 bmpHeight, bmpWidth = headerBmp.GetHeight(), headerBmp.GetWidth() 248 bmpXPos = self._spacing 249 250 if header: 251 # We got the header text 252 dc.SetFont(self._headerFont) 253 textWidth, textHeight = dc.GetTextExtent(header) 254 255 # Calculate the header height 256 height = max(textHeight, bmpHeight) 257 if header: 258 dc.DrawText(header, bmpXPos+bmpWidth+self._spacing, (height-textHeight+self._spacing)/2) 259 if headerBmp and headerBmp.IsOk(): 260 dc.DrawBitmap(headerBmp, bmpXPos, (height-bmpHeight+self._spacing)/2) 261 262 if header or (headerBmp and headerBmp.IsOk()): 263 yPos += height 264 if drawHeader: 265 # Draw the separator line after the header 266 dc.SetPen(wx.GREY_PEN) 267 dc.DrawLine(self._spacing, yPos+self._spacing, width-self._spacing, yPos+self._spacing) 268 269 # Get the big body image (if any) 270 embeddedImage = classParent.GetBodyImage() 271 bmpWidth = bmpHeight = -1 272 if embeddedImage and embeddedImage.IsOk(): 273 bmpWidth, bmpHeight = embeddedImage.GetWidth(), embeddedImage.GetHeight() 274 275 # A bunch of calculations to draw the main body message 276 messageHeight = 0 277 textSpacing = (bmpWidth > 0 and [3*self._spacing] or [2*self._spacing])[0] 278 lines = classParent.GetMessage().split("\n") 279 yText = yPos 280 normalText = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUTEXT) 281 hyperLinkText = wx.BLUE 282 283 for indx, line in enumerate(lines): 284 # Loop over all the lines in the message 285 isLink = False 286 dc.SetTextForeground(normalText) 287 if line.startswith("</b>"): # is a bold line 288 line = line[4:] 289 font = MakeBold(self._messageFont) 290 dc.SetFont(font) 291 elif line.startswith("</l>"): # is a link 292 dc.SetFont(self._hyperlinkFont) 293 isLink = True 294 line, hl = ExtractLink(line) 295 dc.SetTextForeground(hyperLinkText) 296 else: 297 # Is a normal line 298 dc.SetFont(self._messageFont) 299 300 textWidth, textHeight = dc.GetTextExtent(line) 301 if textHeight == 0: 302 textWidth, textHeight = dc.GetTextExtent("a") 303 304 messageHeight += textHeight 305 306 xText = (bmpWidth > 0 and [bmpWidth+2*self._spacing] or [self._spacing])[0] 307 yText += textHeight/2+self._spacing 308 309 dc.DrawText(line, xText, yText) 310 if isLink: 311 # Store the hyperlink rectangle and link 312 self._hyperlinkRect.append(wx.Rect(xText, yText, textWidth, textHeight)) 313 self._hyperlinkWeb.append(hl) 314 315 if indx == 0: 316 messagePos = yText 317 318 toAdd = 0 319 if bmpHeight > textHeight: 320 yPos += 2*self._spacing + bmpHeight 321 toAdd = self._spacing 322 else: 323 yPos += messageHeight + 2*self._spacing 324 325 yText = max(messageHeight, bmpHeight+2*self._spacing) 326 if embeddedImage and embeddedImage.IsOk(): 327 # Draw the main body image 328 dc.DrawBitmap(embeddedImage, self._spacing, messagePos) 329 330 footer, footerBmp = classParent.GetFooter(), classParent.GetFooterBitmap() 331 bmpHeight = bmpWidth = textHeight = textWidth = 0 332 bmpXPos = bmpYPos = 0 333 334 if footerBmp and footerBmp.IsOk(): 335 # Got the footer bitmap 336 bmpHeight, bmpWidth = footerBmp.GetHeight(), footerBmp.GetWidth() 337 bmpXPos = self._spacing 338 339 if footer: 340 # Got the footer text 341 dc.SetFont(self._footerFont) 342 textWidth, textHeight = dc.GetTextExtent(footer) 343 344 if textHeight or bmpHeight: 345 if drawFooter: 346 # Draw the separator line before the footer 347 dc.SetPen(wx.GREY_PEN) 348 dc.DrawLine(self._spacing, yPos-self._spacing/2+toAdd, width-self._spacing, yPos-self._spacing/2+toAdd) 349 350 # Draw the footer and footer bitmap (if any) 351 dc.SetTextForeground(normalText) 352 height = max(textHeight, bmpHeight) 353 yPos += toAdd 354 if footer: 355 dc.DrawText(footer, bmpXPos+bmpWidth+self._spacing, yPos + (height-textHeight+self._spacing)/2) 356 if footerBmp and footerBmp.IsOk(): 357 dc.DrawBitmap(footerBmp, bmpXPos, yPos + (height-bmpHeight+self._spacing)/2)358 359361 """ Handles the wx.EVT_ERASE_BACKGROUND event for L{SuperToolTip}. """ 362 363 # This is intentionally empty to reduce flicker 364 pass365 366368 """ Handles the wx.EVT_SIZE event for L{SuperToolTip}. """ 369 370 self.Refresh() 371 event.Skip()372 373375 """ Handles the wx.EVT_MOTION event for L{SuperToolTip}. """ 376 377 x, y = event.GetPosition() 378 for rect in self._hyperlinkRect: 379 if rect.Contains((x, y)): 380 # We are over one hyperlink... 381 self.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) 382 self._wasOnLink = True 383 return 384 385 if self._wasOnLink: 386 # Restore the normal cursor 387 self._wasOnLink = False 388 self.SetCursor(wx.NullCursor)389 390392 """ 393 Handles the wx.EVT_LEFT_DOWN, wx.EVT_LEFT_DCLICK and wx.EVT_KILL_FOCUS 394 events for L{SuperToolTip}. All these events destroy the L{SuperToolTip}, 395 unless the user clicked on one hyperlink. 396 """ 397 398 if not isinstance(event, wx.MouseEvent): 399 # We haven't clicked a link 400 self.Destroy() 401 return 402 403 x, y = event.GetPosition() 404 for indx, rect in enumerate(self._hyperlinkRect): 405 if rect.Contains((x, y)): 406 # Run the webbrowser with the clicked link 407 webbrowser.open_new_tab(self._hyperlinkWeb[indx]) 408 return 409 410 if self._classParent.GetUseFade(): 411 # Fade out... 412 self.StartAlpha(False) 413 else: 414 self.Destroy()415 416418 """ 419 Start the timer which set the alpha channel for L{SuperToolTip}. 420 421 @param isShow: whether L{SuperToolTip} is being shown or deleted. 422 """ 423 424 if self._alphaTimer.IsRunning(): 425 return 426 427 # Calculate starting alpha value and its step 428 self.amount = (isShow and [0] or [255])[0] 429 self.delta = (isShow and [5] or [-5])[0] 430 # Start the timer 431 self._alphaTimer.Start(30)432 433435 """ 436 Sets the L{SuperToolTip} font globally. 437 438 @param font: the font to set. 439 """ 440 441 wx.PopupWindow.SetFont(self, font) 442 self.InitFont() 443 self.Invalidate()444 445447 """ Invalidate L{SuperToolTip} size and repaint it. """ 448 449 if not self._classParent.GetMessage(): 450 # No message yet... 451 return 452 453 self.CalculateBestSize() 454 self.Refresh()455 456458 """ 459 Adds a shadow under the window (Windows XP only). 460 461 @param drop: whether to drop a shadow or not. 462 """ 463 464 if not _libimported: 465 # No Mark Hammond's win32all extension 466 return 467 468 if wx.Platform != "__WXMSW__": 469 # This works only on Windows XP 470 return 471 472 hwnd = self.GetHandle() 473 474 # Create a rounded rectangle region 475 size = self.GetSize() 476 if drop: 477 rgn = win32gui.CreateRoundRectRgn(0, 0, size.x, size.y, 9, 9) 478 win32gui.SetWindowRgn(hwnd, rgn, True) 479 480 CS_DROPSHADOW = 0x00020000 481 # Load the user32 library 482 if not hasattr(self, "_winlib"): 483 self._winlib = win32api.LoadLibrary("user32") 484 485 csstyle = win32api.GetWindowLong(hwnd, win32con.GCL_STYLE) 486 if drop: 487 if csstyle & CS_DROPSHADOW: 488 return 489 else: 490 csstyle |= CS_DROPSHADOW #Nothing to be done 491 else: 492 csstyle &= ~CS_DROPSHADOW 493 494 # Drop the shadow underneath the window 495 GCL_STYLE= -26 496 cstyle= win32gui.GetClassLong(hwnd, GCL_STYLE) 497 if drop: 498 if cstyle & CS_DROPSHADOW == 0: 499 win32api.SetClassLong(hwnd, GCL_STYLE, cstyle | CS_DROPSHADOW) 500 else: 501 win32api.SetClassLong(hwnd, GCL_STYLE, cstyle &~ CS_DROPSHADOW)502 503505 """ Handles the wx.EVT_TIMER event for L{SuperToolTip}. """ 506 507 # Increase (or decrease) the alpha channel 508 self.amount += self.delta 509 510 if self.amount > 255 or self.amount < 0: 511 # We're done, stop the timer 512 self._alphaTimer.Stop() 513 if self.amount < 0: 514 # Destroy the SuperToolTip, we are fading out 515 self.Destroy() 516 return 517 518 # Make the SuperToolTip more or less transparent 519 self.MakeWindowTransparent(self.amount) 520 if not self.IsShown(): 521 self.Show()522 523525 """ 526 Makes the L{SuperToolTip} window transparent. 527 528 @param amount: the alpha channel value. 529 """ 530 531 if not _libimported: 532 # No way, only Windows XP with Mark Hammond's win32all 533 return 534 535 # this API call is not in all SDKs, only the newer ones, so 536 # we will runtime bind this 537 if wx.Platform != "__WXMSW__": 538 return 539 540 hwnd = self.GetHandle() 541 542 if not hasattr(self, "_winlib"): 543 self._winlib = win32api.LoadLibrary("user32") 544 545 pSetLayeredWindowAttributes = win32api.GetProcAddress(self._winlib, 546 "SetLayeredWindowAttributes") 547 548 if pSetLayeredWindowAttributes == None: 549 return 550 551 exstyle = win32api.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) 552 if 0 == (exstyle & 0x80000): 553 win32api.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, exstyle | 0x80000) 554 555 winxpgui.SetLayeredWindowAttributes(hwnd, 0, amount, 2)556 557559 """ Calculates the L{SuperToolTip} window best size. """ 560 561 # See the OnPaint method for explanations... 562 maxWidth = maxHeight = 0 563 dc = wx.ClientDC(self) 564 565 classParent = self._classParent 566 header, headerBmp = classParent.GetHeader(), classParent.GetHeaderBitmap() 567 568 textHeight, bmpHeight = 0, 0 569 if header: 570 dc.SetFont(self._headerFont) 571 textWidth, textHeight = dc.GetTextExtent(header) 572 maxWidth = max(maxWidth, textWidth + 2*self._spacing) 573 maxHeight += self._spacing/2 574 if headerBmp and headerBmp.IsOk(): 575 maxWidth += headerBmp.GetWidth() + 2*self._spacing 576 bmpHeight = headerBmp.GetHeight() 577 if not header: 578 maxHeight += self._spacing/2 579 580 maxHeight += max(textHeight, bmpHeight) 581 if textHeight or bmpHeight: 582 maxHeight += self._spacing/2 583 584 # See the OnPaint method for explanations... 585 bmpWidth = bmpHeight = -1 586 embeddedImage = classParent.GetBodyImage() 587 if embeddedImage and embeddedImage.IsOk(): 588 bmpWidth, bmpHeight = embeddedImage.GetWidth(), embeddedImage.GetHeight() 589 590 messageHeight = 0 591 textSpacing = (bmpWidth and [3*self._spacing] or [2*self._spacing])[0] 592 lines = classParent.GetMessage().split("\n") 593 594 for line in lines: 595 if line.startswith("</b>"): # is a bold line 596 font = MakeBold(self._messageFont) 597 dc.SetFont(font) 598 line = line[4:] 599 elif line.startswith("</l>"): # is a link 600 dc.SetFont(self._hyperlinkFont) 601 line, hl = ExtractLink(line) 602 else: 603 dc.SetFont(self._messageFont) 604 605 textWidth, textHeight = dc.GetTextExtent(line) 606 if textHeight == 0: 607 textWidth, textHeight = dc.GetTextExtent("a") 608 609 maxWidth = max(maxWidth, textWidth + textSpacing + bmpWidth) 610 messageHeight += textHeight 611 612 # See the OnPaint method for explanations... 613 messageHeight = max(messageHeight, bmpHeight) 614 maxHeight += messageHeight 615 toAdd = 0 616 if bmpHeight > textHeight: 617 maxHeight += 2*self._spacing 618 toAdd = self._spacing 619 else: 620 maxHeight += 2*self._spacing 621 622 footer, footerBmp = classParent.GetFooter(), classParent.GetFooterBitmap() 623 textHeight, bmpHeight = 0, 0 624 625 # See the OnPaint method for explanations... 626 if footer: 627 dc.SetFont(self._footerFont) 628 textWidth, textHeight = dc.GetTextExtent(footer) 629 maxWidth = max(maxWidth, textWidth + 2*self._spacing) 630 maxHeight += self._spacing/2 631 632 if footerBmp and footerBmp.IsOk(): 633 bmpWidth, bmpHeight = footerBmp.GetWidth(), footerBmp.GetHeight() 634 maxWidth = max(maxWidth, textWidth + 3*self._spacing + bmpWidth) 635 if not footer: 636 maxHeight += self._spacing/2 637 638 if textHeight or bmpHeight: 639 maxHeight += self._spacing/2 + max(textHeight, bmpHeight) 640 641 maxHeight += toAdd 642 self.SetSize((maxWidth, maxHeight))650 """ Popup window that works on wxMac. """ 651663 664 else: 665653 """ 654 Default class constructor. 655 656 @param parent: the L{SuperToolTip} widget parent; 657 @param classParent: the L{SuperToolTip} object parent. 658 """ 659 660 wx.Frame.__init__(self, parent, style=wx.NO_BORDER|wx.FRAME_FLOAT_ON_PARENT|wx.FRAME_NO_TASKBAR|wx.POPUP_WINDOW) 661 # Call the base class 662 ToolTipWindowBase.__init__(self, parent, classParent)667 """ 668 A simple wx.PopupWindow that holds fancy tooltips. 669 Not available on Mac as wx.PopupWindow is not implemented. 670 """ 671683 684673 """ 674 Default class constructor. 675 676 @param parent: the L{SuperToolTip} parent; 677 @param classParent: the L{SuperToolTip} object parent. 678 """ 679 680 wx.PopupWindow.__init__(self, parent) 681 # Call the base class 682 ToolTipWindowBase.__init__(self, parent, classParent)686 """ 687 The main class for L{SuperToolTip}, which holds all the methods 688 and setters/getters available to the user. 689 """ 6901231691 - def __init__(self, message, bodyImage=wx.NullBitmap, header="", headerBmp=wx.NullBitmap, 692 footer="", footerBmp=wx.NullBitmap):693 """ 694 Default class constructor. 695 696 @param message: the main message in L{SuperToolTip} body; 697 @param bodyImage: the image in the L{SuperToolTip} body; 698 @param header: the header text; 699 @param headerBmp: the header bitmap; 700 @param footer: the footer text; 701 @param footerBmp: the footer bitmap. 702 """ 703 704 self._superToolTip = None 705 706 # Set all the initial options 707 self.SetMessage(message) 708 self.SetBodyImage(bodyImage) 709 self.SetHeader(header) 710 self.SetHeaderBitmap(headerBmp) 711 self.SetFooter(footer) 712 self.SetFooterBitmap(footerBmp) 713 self._dropShadow = False 714 self._useFade = False 715 716 # Get the running applications 717 self._runningApp = wx.GetApp() 718 self._runningApp.__superToolTip = True 719 720 # Build a couple of timers... 721 self._startTimer = wx.PyTimer(self.OnStartTimer) 722 self._endTimer = wx.PyTimer(self.OnEndTimer) 723 724 self.SetStartDelay() 725 self.SetEndDelay()726 727729 """ 730 Sets the target window for L{SuperToolTip}. 731 732 @param widget: the widget to which L{SuperToolTip} is associated. 733 """ 734 735 self._widget = widget 736 737 self._widget.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter) 738 self._widget.Bind(wx.EVT_LEAVE_WINDOW, self.OnWidgetLeave)739 740742 """ Returns the target window for L{SuperToolTip}. """ 743 744 if not hasattr(self, "_widget"): 745 raise Exception("\nError: the widget target for L{SuperToolTip} has not been set.") 746 747 return self._widget748 749751 """ 752 Sets the time delay (in seconds) after which the L{SuperToolTip} is created. 753 754 @param delay: the delay in seconds. 755 """ 756 757 self._startDelayTime = float(delay)758 759761 """ Returns the tim delay (in seconds) after which the L{SuperToolTip} is created.""" 762 763 return self._startDelayTime764 765767 """ 768 Sets the delay time (in seconds) after which the L{SuperToolTip} is destroyed. 769 770 @param delay: the delay in seconds. 771 """ 772 773 self._endDelayTime = float(delay)774 775777 """ Returns the delay time (in seconds) after which the L{SuperToolTip} is destroyed.""" 778 779 return self._endDelayTime780 781783 """Starts the L{SuperToolTip} timer for creation, handles the wx.EVT_ENTER_WINDOW event.""" 784 785 if self._superToolTip: 786 # Not yet created 787 return 788 789 if not self._runningApp.__superToolTip: 790 # The running app doesn't want tooltips... 791 return 792 793 if self._startTimer.IsRunning(): 794 # We are already running 795 event.Skip() 796 return 797 798 self._startTimer.Start(self._startDelayTime*1000) 799 event.Skip()800 801803 """ Handles the wx.EVT_LEAVE_WINDOW for the target widgets. """ 804 805 pos = wx.GetMousePosition() 806 realPos = self._widget.ScreenToClient(pos) 807 rect = self._widget.GetClientRect() 808 809 if rect.Contains(realPos): 810 # We get fake leave events... 811 event.Skip() 812 return 813 814 if self._superToolTip: 815 if self.GetUseFade(): 816 # Fade out... 817 self._superToolTip.StartAlpha(False) 818 else: 819 self._superToolTip.Destroy() 820 821 self._startTimer.Stop() 822 self._endTimer.Stop() 823 824 event.Skip()825 826828 """ The creation time has expired, create the L{SuperToolTip}. """ 829 830 tip = ToolTipWindow(self._widget, self) 831 self._superToolTip = tip 832 self._superToolTip.CalculateBestSize() 833 self._superToolTip.SetPosition(wx.GetMousePosition()) 834 self._superToolTip.DropShadow(self.GetDropShadow()) 835 836 if self.GetUseFade(): 837 self._superToolTip.StartAlpha(True) 838 else: 839 self._superToolTip.Show() 840 841 self._startTimer.Stop() 842 self._endTimer.Start(self._endDelayTime*1000)843 844846 """ The show time for L{SuperToolTip} has expired, destroy the L{SuperToolTip}. """ 847 848 if self._superToolTip: 849 if self.GetUseFade(): 850 self._superToolTip.StartAlpha(False) 851 else: 852 self._superToolTip.Destroy() 853 854 self._endTimer.Stop()855 856858 """ Handles the L{SuperToolTip} target destruction. """ 859 860 if self._superToolTip: 861 # Unbind the events! 862 self._widget.Unbind(wx.EVT_LEAVE_WINDOW) 863 self._widget.Unbind(wx.EVT_ENTER_WINDOW) 864 865 self._superToolTip.Destroy() 866 del self._superToolTip 867 self._superToolTip = None868 869871 """ 872 Sets the header bitmap for L{SuperToolTip}. 873 874 @param bmp: the bitmap to use. 875 """ 876 877 self._headerBmp = bmp 878 if self._superToolTip: 879 self._superToolTip.Invalidate()880 881 886 887889 """ 890 Sets the header text. 891 892 @param header: the header text to display. 893 """ 894 895 self._header = header 896 if self._superToolTip: 897 self._superToolTip.Invalidate()898 899 904 905907 """ 908 Whether to draw a separator line after the header or not. 909 910 @param draw: bool value. 911 """ 912 913 self._topLine = draw 914 if self._superToolTip: 915 self._superToolTip.Refresh()916 917919 """ Returns whether the separator line after the header is drawn or not. """ 920 921 return self._topLine922 923925 """ 926 Sets the main body bitmap for L{SuperToolTip}. 927 928 @param bmp: the bitmap to use. 929 """ 930 931 self._embeddedImage = bmp 932 if self._superToolTip: 933 self._superToolTip.Invalidate()934 935937 """ Returns the main body bitmap used in L{SuperToolTip}. """ 938 939 return self._embeddedImage940 941 952 953 958 959 970 971 976 977 988 989 994 995997 """ 998 Sets the main body message for L{SuperToolTip}. 999 1000 @param message: the message to display in the body. 1001 """ 1002 1003 self._message = message 1004 if self._superToolTip: 1005 self._superToolTip.Invalidate()1006 1007 1012 10131015 """ 1016 Sets the top gradient colour for L{SuperToolTip}. 1017 1018 @param colour: the colour to use as top colour. 1019 """ 1020 1021 self._topColour = colour 1022 if self._superToolTip: 1023 self._superToolTip.Refresh()1024 10251027 """ 1028 Sets the middle gradient colour for L{SuperToolTip}. 1029 1030 @param colour: the colour to use as middle colour. 1031 """ 1032 1033 self._middleColour = colour 1034 if self._superToolTip: 1035 self._superToolTip.Refresh()1036 10371039 """ 1040 Sets the bottom gradient colour for L{SuperToolTip}. 1041 1042 @param colour: the colour to use as bottom colour. 1043 """ 1044 1045 self._bottomColour = colour 1046 if self._superToolTip: 1047 self._superToolTip.Refresh()1048 10491051 """ 1052 Sets the text colour for L{SuperToolTip}. 1053 1054 @param colour: the colour to use as text colour. 1055 """ 1056 1057 self._textColour = colour 1058 if self._superToolTip: 1059 self._superToolTip.Refresh()1060 1061 1066 1067 1072 1073 1078 1079 1084 1085 1086 SetTopGradientColor = SetTopGradientColour 1087 SetMiddleGradientColor = SetMiddleGradientColour 1088 SetBottomGradientColor = SetBottomGradientColour 1089 GetTopGradientColor = GetTopGradientColour 1090 GetMiddleGradientColor = GetMiddleGradientColour 1091 GetBottomGradientColor = GetBottomGradientColour 1092 SetTextColor = SetTextColour 1093 GetTextColor = GetTextColour 1094 10951097 """ 1098 Sets the font for the main body message. 1099 1100 @param font: the font to use for the main body message. 1101 """ 1102 1103 self._messageFont = font 1104 if self._superToolTip: 1105 self._superToolTip.Invalidate()1106 11071109 """ 1110 Sets the font for the header text. 1111 1112 @param font: the font to use for the header text. 1113 """ 1114 1115 self._headerFont = font 1116 if self._superToolTip: 1117 self._superToolTip.Invalidate()1118 1119 1130 1131 1136 1137 1142 1143 1148 11491151 """ 1152 Whether to draw a shadow below L{SuperToolTip} or not. 1153 1154 @param drop: boolean value. 1155 @note: this functionality is available only in Windows XP 1156 with Mark Hammond win32all extensions installed. 1157 """ 1158 1159 self._dropShadow = drop 1160 if self._superToolTip: 1161 self._superToolTip.Invalidate()1162 11631165 """ 1166 Returns whether a shadow below L{SuperToolTip} is drawn or not. 1167 1168 @note: this functionality is available only in Windows XP 1169 with Mark Hammond win32all extensions installed. 1170 """ 1171 1172 return self._dropShadow1173 11741176 """ 1177 Whether to use a fade in/fade out effect or not. 1178 1179 @param fade: boolean value. 1180 @note: this functionality is available only in Windows XP 1181 with Mark Hammond win32all extensions installed. 1182 """ 1183 1184 self._useFade = fade1185 11861188 """ 1189 Returns whether a fade in/fade out effect is used or not. 1190 1191 @note: this functionality is available only in Windows XP 1192 with Mark Hammond win32all extensions installed. 1193 """ 1194 1195 return self._useFade1196 11971199 """ 1200 Applies none of the predefined styles. 1201 1202 @param style: one of the predefined styles available at the 1203 beginning of the module. 1204 """ 1205 1206 if style not in _colorSchemes: 1207 raise Exception("Invalid style '%s' selected"%style) 1208 1209 top, middle, bottom, text = _colorSchemes[style] 1210 self._topColour = top 1211 self._middleColour = middle 1212 self._bottomColour = bottom 1213 self._textColour = text 1214 1215 if self._superToolTip: 1216 self._superToolTip.Refresh()1217 12181220 """ 1221 Globally (application-wide) enables/disables L{SuperToolTip}. 1222 1223 @param enable: whether to enable or disable L{SuperToolTip}. 1224 """ 1225 1226 wx.GetApp().__superToolTip = enable 1227 if not enable and self._superToolTip: 1228 self._superToolTip.Destroy() 1229 self._superToolTip = None 1230 del self._superToolTip
Home | Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Wed Oct 08 13:53:55 2008 | http://epydoc.sourceforge.net |