How to create a customized frame - Part 1 (Phoenix)

Keywords : Shaped frame, Customized frame, Customized button, Transparency, Roll, Unroll, Fade in, Fade out, Shape, Region, BufferedPaintDC, BufferedDC, ClientDC, GCDC, AutoBufferedPaintDCFactory, Config, AcceleratorTable.


Demonstrating :

Tested py3.x, wx4.x and Win10.

Are you ready to use some samples ? ;)

Test, modify, correct, complete, improve and share your discoveries ! (!)


Shaped frame with mask :

First example

img_sample_one.png

   1 # sample_one.py
   2 
   3 import sys
   4 import os
   5 import platform
   6 import time
   7 import wx
   8 import wx.adv
   9 import wx.lib.fancytext as fancytext
  10 
  11 # class MyAboutDlg
  12 # class MyWindow
  13 # class MyButtonBox
  14 # class MyPanel
  15 # class MyFrame
  16 # class MyApp
  17 
  18 #-------------------------------------------------------------------------------
  19 
  20 class MyAboutDlg(wx.Frame):
  21     """
  22     Thanks to Robin Dunn.
  23     """
  24     def __init__(self, parent):
  25         style = (wx.FRAME_SHAPED | wx.SIMPLE_BORDER |
  26                  wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
  27                  wx.SYSTEM_MENU | wx.CLOSE_BOX |
  28                  wx.NO_FULL_REPAINT_ON_RESIZE)
  29         wx.Frame.__init__(self,
  30                           parent,
  31                           id=-1,
  32                           title="About...",
  33                           style=style)
  34 
  35         #------------
  36 
  37         # Attributes.
  38         self.SetTransparent(0)
  39         self.opacity_in = 0
  40         self.opacity_out = 255
  41         self.deltaN = -70
  42         self.hasShape = False
  43         self.delta = wx.Point(0,0)
  44 
  45         #------------
  46 
  47         # Return application name.
  48         self.app_name = wx.GetApp().GetAppName()
  49         # Return bitmaps folder.
  50         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
  51         # Return icons folder.
  52         self.icons_dir = wx.GetApp().GetIconsDir()
  53 
  54         #------------
  55 
  56         # Simplified init method.
  57         self.SetProperties()
  58         self.OnTimerIn(self)
  59         self.CreateCtrls()
  60         self.BindEvents()
  61 
  62         #------------
  63 
  64         self.CenterOnParent(wx.BOTH)
  65         self.GetParent().Enable(False)
  66 
  67         #------------
  68 
  69         self.Show(True)
  70 
  71         #------------
  72 
  73         self.eventLoop = wx.GUIEventLoop()
  74         self.eventLoop.Run()
  75 
  76     #---------------------------------------------------------------------------
  77 
  78     def SetProperties(self):
  79         """
  80         Set the dialog properties (title, icon, transparency...).
  81         """
  82 
  83         frameIcon = wx.Icon(os.path.join(self.icons_dir,
  84                                          "icon_wxWidgets.ico"),
  85                             type=wx.BITMAP_TYPE_ICO)
  86         self.SetIcon(frameIcon)
  87 
  88 
  89     def OnTimerIn(self, evt):
  90         """
  91         Thanks to Pascal Faut.
  92         """
  93 
  94         self.timer1 = wx.Timer(self, -1)
  95         self.timer1.Start(1)
  96         self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
  97 
  98         print("Fade-in was launched.")
  99 
 100 
 101     def OnTimerOut(self, evt):
 102         """
 103         Thanks to Pascal Faut.
 104         """
 105 
 106         self.timer2 = wx.Timer(self, -1)
 107         self.timer2.Start(1)
 108         self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
 109 
 110         print("Fade-out was launched.")
 111 
 112 
 113     def AlphaCycle1(self, *args):
 114         """
 115         Thanks to Pascal Faut.
 116         """
 117 
 118         self.opacity_in += self.deltaN
 119         if self.opacity_in <= 0:
 120             self.deltaN = -self.deltaN
 121             self.opacity_in = 0
 122 
 123         if self.opacity_in >= 255:
 124             self.deltaN = -self.deltaN
 125             self.opacity_in = 255
 126 
 127             self.timer1.Stop()
 128 
 129         self.SetTransparent(self.opacity_in)
 130 
 131         print("Fade in = {}/255".format(self.opacity_in))
 132 
 133 
 134     def AlphaCycle2(self, *args):
 135         """
 136         Thanks to Pascal Faut.
 137         """
 138 
 139         self.opacity_out += self.deltaN
 140         if self.opacity_out >= 255:
 141             self.deltaN = -self.deltaN
 142             self.opacity_out = 255
 143 
 144         if self.opacity_out <= 0:
 145             self.deltaN = -self.deltaN
 146             self.opacity_out = 0
 147 
 148             self.timer2.Stop()
 149 
 150             wx.CallAfter(self.Destroy)
 151 
 152         self.SetTransparent(self.opacity_out)
 153 
 154         print("Fade out = {}/255".format(self.opacity_out))
 155 
 156 
 157     def CreateCtrls(self):
 158         """
 159         Make widgets for my dialog.
 160         """
 161 
 162         # Load a background bitmap.
 163         self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
 164                                           "skin_about_1.png"),
 165                              type=wx.BITMAP_TYPE_PNG)
 166         mask = wx.Mask(self.bmp, wx.RED)
 167         self.bmp.SetMask(mask)
 168 
 169         #------------
 170 
 171         self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
 172 
 173         #------------
 174 
 175         if wx.Platform == "__WXGTK__":
 176             # wxGTK requires that the window be created before you can
 177             # set its shape, so delay the call to SetWindowShape until
 178             # this event.
 179             self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
 180         else:
 181             # On wxMSW and wxMac the window has already
 182             # been created, so go for it.
 183             self.SetWindowShape()
 184 
 185 
 186     def BindEvents(self):
 187         """
 188         Bind all the events related to my dialog.
 189         """
 190 
 191         # Bind some events to an events handler.
 192         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
 193         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
 194         self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow)  # Panel right clic.
 195         self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)  # View mask.
 196         self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
 197         self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
 198         self.Bind(wx.EVT_MOTION, self.OnMouseMove)
 199         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
 200         self.Bind(wx.EVT_PAINT, self.OnPaint)
 201         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 202 
 203 
 204     def SetWindowShape(self, event=None):
 205         """
 206         ...
 207         """
 208 
 209         # Use the bitmap's mask to determine the region.
 210         r = wx.Region(self.bmp)
 211         self.hasShape = self.SetShape(r)
 212 
 213 
 214     def OnEraseBackground(self, event):
 215         """
 216         ...
 217         """
 218 
 219         dc = event.GetDC()
 220         if not dc:
 221             dc = wx.ClientDC(self)
 222             rect = self.GetUpdateRegion().GetBox()
 223             dc.SetClippingRect(rect)
 224 
 225 
 226     def OnDoubleClick(self, event):
 227         """
 228         ...
 229         """
 230 
 231         if self.hasShape:
 232             self.SetShape(wx.Region())
 233             self.hasShape = False
 234         else:
 235             self.SetWindowShape()
 236 
 237 
 238     def OnLeftDown(self, event):
 239         """
 240         ...
 241         """
 242 
 243         self.CaptureMouse()
 244         x, y = self.ClientToScreen(event.GetPosition())
 245         originx, originy = self.GetPosition()
 246         dx = x - originx
 247         dy = y - originy
 248         self.delta = ((dx, dy))
 249 
 250 
 251     def OnLeftUp(self, evt):
 252         """
 253         ...
 254         """
 255 
 256         if self.HasCapture():
 257             self.ReleaseMouse()
 258 
 259 
 260     def OnMouseMove(self, event):
 261         """
 262         ...
 263         """
 264 
 265         if event.Dragging() and event.LeftIsDown():
 266             x, y = self.ClientToScreen(event.GetPosition())
 267             fp = (x - self.delta[0], y - self.delta[1])
 268             self.Move(fp)
 269 
 270 
 271     def OnPaint(self, event):
 272         """
 273         ...
 274         """
 275 
 276         dc = wx.AutoBufferedPaintDCFactory(self)
 277         dc.DrawBitmap(self.bmp, -1, -1, True)
 278 
 279         #------------
 280 
 281         # These are strings.
 282         py_version = sys.version.split()[0]
 283 
 284         str1 = (('<font style="normal" family="default" color="yellow" size="10" weight="bold">'
 285                  'Programming : </font>'
 286                  '<font style="normal" family="default" color="white" size="10" weight="normal">'
 287                  'Python {}</font>').format(py_version))   # Python 3.6.5
 288 
 289         str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
 290                  'GUI toolkit : </font>'
 291                  '<font style="normal" family="default" color="white" size="10" weight="normal">'
 292                  'wxPython {}</font>').format(wx.VERSION_STRING))  # wxPython 4.0.2
 293 
 294         str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
 295                  'Library : </font>'
 296                  '<font style="normal" family="default" color="white" size="10" weight="normal">'
 297                  '{}</font>').format(wx.GetLibraryVersionInfo().VersionString))   # wxWidgets 3.0.5
 298 
 299         str4 = (('<font style="normal" family="default" color="cyan" size="10" weight="bold">'
 300                  'Operating system : </font>'
 301                  '<font style="normal" family="default" color="white" size="10" weight="normal">'
 302                  '{}</font>').format(platform.system()))   # Windows
 303 
 304         str5 = (('<font style="normal" family="default" color="gray" size="9" weight="normal">'
 305                  '{}</font>').format(self.app_name))   # Custom Gui 1
 306 
 307         str6 = (('<font style="normal" family="default" color="White" size="8" weight="normal">'
 308                  'Right clic or Esc for Exit</font>'))
 309 
 310         #------------
 311 
 312         # Return main image size.
 313         bw, bh = self.bmp.GetWidth(), self.bmp.GetHeight()
 314 
 315         # Draw text.
 316         # Need width to calculate x position of str1.
 317         tw, th = fancytext.GetExtent(str1, dc)
 318         # Centered text.
 319         fancytext.RenderToDC(str1, dc, (bw-tw)/2, 50)
 320 
 321         #------------
 322 
 323         # Need width to calculate x position of str2.
 324         tw, th = fancytext.GetExtent(str2, dc)
 325         # Centered text.
 326         fancytext.RenderToDC(str2, dc, (bw-tw)/2, 70)
 327 
 328         #------------
 329 
 330         # Need width to calculate x position of str3.
 331         tw, th = fancytext.GetExtent(str3, dc)
 332         # Centered text.
 333         fancytext.RenderToDC(str3, dc, (bw-tw)/2, 90)
 334 
 335         #------------
 336 
 337         # Need width to calculate x position of str4.
 338         tw, th = fancytext.GetExtent(str4, dc)
 339         # Centered text.
 340         fancytext.RenderToDC(str4, dc, (bw-tw)/2, 110)
 341 
 342         #------------
 343 
 344         # Need width to calculate x position of str5.
 345         tw, th = fancytext.GetExtent(str5, dc)
 346         # Centered text.
 347         fancytext.RenderToDC(str5, dc, (bw-tw)/2, 150)
 348 
 349         #------------
 350 
 351         # Need width to calculate x position of str6.
 352         tw, th = fancytext.GetExtent(str6, dc)
 353         # Centered text.
 354         fancytext.RenderToDC(str6, dc, (bw-tw)/2, 185)
 355 
 356 
 357     def OnKeyUp(self, event):
 358         """
 359         ...
 360         """
 361 
 362         if event.GetKeyCode() == wx.WXK_ESCAPE:
 363             self.OnCloseWindow(event)
 364 
 365         event.Skip()
 366 
 367 
 368     def OnCloseWindow(self, event):
 369         """
 370         ...
 371         """
 372 
 373         self.GetParent().Enable(True)
 374         self.eventLoop.Exit()
 375         #self.Destroy()
 376         self.OnTimerOut(self)
 377 
 378 #-------------------------------------------------------------------------------
 379 
 380 class MyWindow(wx.Control):
 381     """
 382     Thanks to Cody Precord.
 383     """
 384     def __init__(self, parent, label,
 385                  foreground, background,
 386                  normal, pressed=None, disabled=None):
 387         super(MyWindow, self).__init__(parent, -1,
 388                                        style=wx.BORDER_NONE)
 389 
 390         #------------
 391 
 392         # Attributes.
 393         self.label = label
 394         self.foreground = foreground
 395         self.background = background
 396 
 397         if wx.Platform == "__WXGTK__":
 398             self.color = "#9e9d9d"
 399 
 400         else:
 401             self.color = "#b1b1b0"
 402 
 403         self.normal = normal
 404         self.pressed = pressed
 405         self.disabled = disabled
 406 
 407         self._clicked = False
 408 
 409         #------------
 410 
 411         self.region = wx.Region(normal, wx.Colour(0, 0, 0, 0))
 412 
 413         #------------
 414 
 415         # Simplified init method.
 416         self.SetProperties(label, foreground, background)
 417         self.BindEvents()
 418 
 419     #---------------------------------------------------------------------------
 420 
 421     def SetProperties(self, label, foreground, background):
 422         """
 423         ...
 424         """
 425 
 426         self.label = label
 427         self.foreground = foreground
 428         self.background = background
 429         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
 430 
 431 
 432     def BindEvents(self):
 433         """
 434         Bind some events to an events handler.
 435         """
 436 
 437         self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
 438         self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
 439         self.Bind(wx.EVT_PAINT, self.OnPaint)
 440         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
 441         self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDclick)
 442         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
 443         self.Bind(wx.EVT_MOTION, self.OnMotion)
 444         self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
 445         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
 446 
 447 
 448     def SetLabel(self, label):
 449         """
 450         ...
 451         """
 452 
 453         self.label = label
 454         self.Refresh()
 455 
 456 
 457     def DoGetBestSize(self):
 458         """
 459         ...
 460         """
 461 
 462         return self.normal.GetSize()
 463 
 464 
 465     def GetLabel(self):
 466         """
 467         ...
 468         """
 469 
 470         return self.label
 471 
 472 
 473     def GetLabelColor(self):
 474         """
 475         ...
 476         """
 477 
 478         return self.foreground
 479 
 480 
 481     def Enable(self, *args, **kwargs):
 482         """
 483         ...
 484         """
 485 
 486         super(MyWindow, self).Enable(*args, **kwargs)
 487         self.Refresh()
 488 
 489 
 490     def Disable(self, *args, **kwargs):
 491         """
 492         ...
 493         """
 494 
 495         super(MyWindow, self).Disable(*args, **kwargs)
 496         self.Refresh()
 497 
 498 
 499     def PostEvent(self):
 500         """
 501         ...
 502         """
 503 
 504         event = wx.CommandEvent()
 505         event.SetEventObject(self)
 506         event.SetEventType(wx.EVT_BUTTON.typeId)
 507         wx.PostEvent(self, event)
 508 
 509 
 510     def OnSize(self, event):
 511         """
 512         ...
 513         """
 514 
 515         event.Skip()
 516         self.Refresh()
 517 
 518 
 519     def Getbackground(self):
 520         """
 521         ...
 522         """
 523 
 524         return self.background
 525 
 526 
 527     def OnPaint(self, event):
 528         """
 529         ...
 530         """
 531 
 532         dc = wx.BufferedPaintDC(self)
 533         dc.Clear()
 534         gcdc = wx.GCDC(dc)
 535 
 536         # Set the background color.
 537         if wx.Platform == "__WXGTK__":
 538             gcdc.SetBackground(wx.Brush("grey55"))
 539         else:
 540             gcdc.SetBackground(wx.Brush(self.background))
 541 
 542         gcdc.Clear()
 543 
 544         # Get the working rectangle we can draw in.
 545         rect = self.GetClientRect()
 546 
 547         # Font size and style.
 548         fontSize = self.GetFont().GetPointSize()
 549 
 550         if wx.Platform == "__WXGTK__":
 551             boldFont = wx.Font(fontSize-1, wx.DEFAULT,
 552                                wx.NORMAL, wx.NORMAL, False, "")
 553         else:
 554             boldFont = wx.Font(fontSize+2, wx.DEFAULT,
 555                                wx.NORMAL, wx.BOLD, False, "")
 556 
 557         if wx.Platform == "__WXMSW__":
 558             pen = wx.Pen(self.color, 1, wx.SOLID)
 559 
 560         else:
 561             pen = wx.Pen(self.color, 1, wx.SOLID)
 562 
 563         gcdc.SetPen(pen)
 564 
 565         x, y = self.GetSize()
 566         # x, y , width, height, radius
 567         gcdc.DrawRoundedRectangle (0, 0, 71, 25, 3)
 568 
 569         bitmap = self.normal
 570 
 571         w, h = bitmap.GetWidth(), bitmap.GetHeight()
 572 
 573         if self.clicked:
 574             bitmap = self.pressed or bitmap
 575         if not self.IsEnabled():
 576             bitmap = self.normal or bitmap
 577 
 578         # Draw a bitmap with an alpha channel.
 579         # image, x, y, transparency.
 580         dc.DrawBitmap(bitmap, 0, 0, True)
 581 
 582         if wx.Platform == "__WXGTK__":
 583             # Add the Caption.
 584             # White text - Shadow.
 585             rect = wx.Rect(rect.x, rect.y+3,
 586                            rect.width, 22)
 587 
 588         else:
 589             rect = wx.Rect(rect.x, rect.y+3,
 590                            rect.width, 20)
 591 
 592         dc.SetFont(boldFont)
 593         dc.SetTextForeground(wx.WHITE)
 594         dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
 595 
 596         if wx.Platform == "__WXGTK__":
 597             # Add the Caption.
 598             # Black text.
 599             rect = wx.Rect(rect.x, rect.y,
 600                            rect.width, 21)
 601 
 602         else:
 603             rect = wx.Rect(rect.x, rect.y,
 604                            rect.width, 19)
 605 
 606         gcdc.SetFont(boldFont)
 607         # Get the text color.
 608         dc.SetTextForeground(self.foreground)
 609         dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
 610 
 611 
 612     def SetClicked(self, clicked):
 613         """
 614         ...
 615         """
 616 
 617         if clicked != self._clicked:
 618             self._clicked = clicked
 619             self.Refresh()
 620 
 621 
 622     def GetClicked(self):
 623         """
 624         ...
 625         """
 626 
 627         return self._clicked
 628 
 629 
 630     clicked = property(GetClicked, SetClicked)
 631     def OnLeftDown(self, event):
 632         """
 633         ...
 634         """
 635 
 636         x, y = event.GetPosition()
 637         if self.region.Contains(x, y):
 638             self.clicked = True
 639             self.SetFocus()
 640 
 641 
 642     def OnLeftDclick(self, event):
 643         """
 644         ...
 645         """
 646 
 647         self.OnLeftDown(event)
 648 
 649 
 650     def OnLeftUp(self, event):
 651         """
 652         ...
 653         """
 654 
 655         if self.clicked:
 656             x, y = event.GetPosition()
 657             if self.region.Contains(x, y):
 658                 self.PostEvent()
 659         self.clicked = False
 660 
 661 
 662     def OnMotion(self, event):
 663         """
 664         ...
 665         """
 666 
 667         if self.clicked:
 668             x, y = event.GetPosition()
 669             if not self.region.Contains(x, y):
 670                 self.clicked = False
 671 
 672 
 673     def OnLeave(self, event):
 674         """
 675         ...
 676         """
 677 
 678         self.clicked = False
 679 
 680 
 681     def OnSetFocus(self, event):
 682         """
 683         ...
 684         """
 685 
 686         self.color = "white"
 687         self.Refresh()
 688 
 689 
 690     def OnKillFocus(self, event):
 691         """
 692         ...
 693         """
 694 
 695         if wx.Platform == "__WXGTK__":
 696             self.color = "#9e9d9d"
 697 
 698         else:
 699             self.color = "#b1b1b0"
 700 
 701         self.Refresh()
 702 
 703 
 704     def OnKeyUp(self, event):
 705         """
 706         ...
 707         """
 708 
 709         if event.GetKeyCode() == wx.WXK_SPACE:
 710             self.PostEvent()
 711             return
 712 
 713         elif event.GetKeyCode() == wx.WXK_ESCAPE:
 714             self.GetTopLevelParent().OnCloseWindow(True)
 715 
 716         event.Skip()
 717 
 718 #-------------------------------------------------------------------------------
 719 
 720 class MyButtonBox(wx.Panel):
 721     """
 722     Thanks to Cody Precord.
 723     """
 724     def __init__(self, parent, caption):
 725         super(MyButtonBox, self).__init__(parent,
 726                                            style=wx.NO_BORDER |
 727                                            wx.TAB_TRAVERSAL)
 728 
 729         #------------
 730 
 731         # Attributes.
 732         self._caption = caption
 733 
 734         #------------
 735 
 736         # Simplified init method.
 737         self.DoLayout()
 738 
 739     #---------------------------------------------------------------------------
 740 
 741     def DoLayout(self):
 742         """
 743         ...
 744         """
 745 
 746         self._csizer = wx.BoxSizer(wx.VERTICAL)
 747         msizer = wx.BoxSizer(wx.HORIZONTAL)
 748         msizer.Add(self._csizer, 0 )
 749         self.SetSizer(msizer)
 750 
 751 
 752     def DoGetBestSize(self):
 753         """
 754         ...
 755         """
 756 
 757         size = super(MyButtonBox, self).DoGetBestSize()
 758 
 759         # Compensate for wide caption labels.
 760         tw = self.GetTextExtent(self._caption)[0]
 761         size.SetWidth(max(size.width, size.height))
 762         return size
 763 
 764 
 765     def AddItem(self, item):
 766         """
 767         Add a window or sizer item to the MyButtonBox.
 768         """
 769 
 770         self._csizer.Add(item, 0 )
 771 
 772 #-------------------------------------------------------------------------------
 773 
 774 class MyPanel(wx.Panel):
 775     """
 776     Thanks to Cody Precord.
 777     """
 778     def __init__(self, parent):
 779         wx.Panel.__init__(self, parent)
 780 
 781         #------------
 782 
 783         # Return bitmaps folder.
 784         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
 785 
 786         #------------
 787 
 788         # Create a timer.
 789         self.timer = wx.Timer(self)
 790         self.timer.Start(1000)
 791         self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
 792 
 793         #------------
 794 
 795         # Simplified init method.
 796         self.SetProperties()
 797         self.CreateCtrls()
 798         self.BindEvents()
 799 
 800     #---------------------------------------------------------------------------
 801 
 802     def SetProperties(self):
 803         """
 804         ...
 805         """
 806 
 807         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
 808 
 809 
 810     def CreateCtrls(self):
 811         """
 812         ...
 813         """
 814 
 815         # Load an background bitmap.
 816         self.bitmap = wx.Bitmap(os.path.join(self.bitmaps_dir,
 817                                              "skin_main_1.png"),
 818                                 type=wx.BITMAP_TYPE_PNG)
 819 
 820         #------------
 821 
 822         # Buttons box.
 823         self.box1 = MyButtonBox(self, "")   # Button About.
 824         self.box2 = MyButtonBox(self, "")   # Button Quit.
 825 
 826         #------------
 827 
 828         # Buttons bitmap.
 829         bmp1 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 830                                       "btn_exit_normal.png"),
 831                          type=wx.BITMAP_TYPE_PNG)
 832 
 833         bmp2 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 834                                       "btn_exit_pressed.png"),
 835                          type=wx.BITMAP_TYPE_PNG)
 836 
 837         bmp3 = wx.Bitmap(os.path.join(self.bitmaps_dir,
 838                                       "btn_exit_disabled.png"),
 839                          type=wx.BITMAP_TYPE_PNG)
 840 
 841         bmpA = wx.Bitmap(os.path.join(self.bitmaps_dir,
 842                                       "btn_about_normal.png"),
 843                          type=wx.BITMAP_TYPE_PNG)
 844 
 845         bmpB = wx.Bitmap(os.path.join(self.bitmaps_dir,
 846                                       "btn_about_pressed.png"),
 847                          type=wx.BITMAP_TYPE_PNG)
 848 
 849         bmpC = wx.Bitmap(os.path.join(self.bitmaps_dir,
 850                                       "btn_about_disabled.png"),
 851                          type=wx.BITMAP_TYPE_PNG)
 852 
 853         # Buttons panel.
 854         self.btn1 = MyWindow(self.box1, "", "black", "#9e9d9d", bmpA, bmpB, bmpC)
 855         self.btn1.SetToolTip("This is a customized button.")
 856         self.btn1.Bind(wx.EVT_BUTTON, self.OnBtnAbout)
 857         self.btn1.SetFocus() # Necessary for Linux.
 858 
 859         self.btn2 = MyWindow(self.box2, "", "black", "#9e9d9d", bmp1, bmp2, bmp3)
 860         self.btn2.SetToolTip("This is a customized button.")
 861         self.btn2.Bind(wx.EVT_BUTTON, self.OnBtnClose)
 862         # self.btn2.Enable(False)
 863 
 864         # Return main image size.
 865         bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
 866 
 867         self.box1.AddItem(self.btn1)
 868         self.box2.AddItem(self.btn2)
 869 
 870         self.box1.SetPosition((int((bw-21+170)/2), int(50)))
 871         self.box1.SetSize((21, 21))
 872 
 873         self.box2.SetPosition((int((bw-50)/2), int(415)))
 874         self.box2.SetSize((50, 50))
 875 
 876 
 877     def BindEvents(self):
 878         """
 879         Bind some events to an events handler.
 880         """
 881 
 882         self.Bind(wx.EVT_PAINT, self.OnPaint)
 883         self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
 884 
 885 
 886     def OnEraseBackground(self, event):
 887         """
 888         ...
 889         """
 890 
 891         dc = event.GetDC()
 892         if not dc:
 893             dc = wx.ClientDC(self)
 894             rect = self.GetUpdateRegion().GetBox()
 895             dc.SetClippingRect(rect)
 896 
 897 
 898     def OnBtnAbout(self, event):
 899         """
 900         ...
 901         """
 902 
 903         self.GetParent().OnAbout(True)
 904 
 905         print("About button was clicked.")
 906 
 907 
 908     def OnBtnClose(self, event):
 909         """
 910         ...
 911         """
 912 
 913         self.GetParent().OnCloseWindow(self)
 914 
 915         print("Close button was clicked.")
 916 
 917 
 918     def Draw(self, dc):
 919         """
 920         ...
 921         """
 922 
 923         # Draw a bitmap with an alpha channel
 924         # on top of the last group.
 925         # image, x, y, transparence
 926         dc.DrawBitmap(self.bitmap, 0, 0, True)
 927 
 928         #------------
 929 
 930         fontSize = self.GetFont().GetPointSize()
 931 
 932         # wx.Font(pointSize, family, style, weight, underline, faceName)
 933         if wx.Platform == "__WXMAC__":
 934             self.normalBoldFont = wx.Font(fontSize-1,
 935                                           wx.DEFAULT, wx.NORMAL,
 936                                           wx.NORMAL, False, "")
 937             self.normalFont = wx.Font(fontSize-2,
 938                                           wx.DEFAULT, wx.NORMAL,
 939                                       wx.NORMAL, False, "")
 940 
 941         elif wx.Platform == "__WXGTK__":
 942             self.normalBoldFont = wx.Font(fontSize-1,
 943                                           wx.DEFAULT, wx.NORMAL,
 944                                           wx.NORMAL, False, "")
 945             self.normalFont = wx.Font(fontSize-2,
 946                                       wx.DEFAULT, wx.NORMAL,
 947                                       wx.NORMAL, False, "")
 948 
 949         else:
 950             self.normalBoldFont = wx.Font(fontSize+23,
 951                                           wx.DEFAULT, wx.NORMAL,
 952                                           wx.NORMAL, False, "")
 953             self.normalFont = wx.Font(fontSize+1,
 954                                       wx.DEFAULT, wx.NORMAL,
 955                                       wx.NORMAL, False, "")
 956 
 957         dc.SetFont(self.normalFont)
 958         dc.SetFont(self.normalBoldFont)
 959 
 960         #------------
 961 
 962         # Return main image size.
 963         bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
 964 
 965         # Draw text.
 966         dc.SetTextForeground("#8e8e8e")
 967         dc.SetFont(self.normalFont)
 968         date = time.strftime("%A %d %B %Y")
 969         tw, th = dc.GetTextExtent(date)
 970         dc.DrawText(date, (int((bw-tw)/2), int(143)))
 971 
 972         dc.SetTextForeground(wx.WHITE)
 973         dc.SetFont(self.normalBoldFont)
 974         hour = time.strftime("%H:%M:%S")  # "%I:%M:%S %p"
 975         tw, th = dc.GetTextExtent(hour)
 976         dc.DrawText(hour, (int((bw-tw)/2), int(100)))
 977 
 978 
 979     def OnTimer(self, event):
 980         """
 981         ...
 982         """
 983 
 984         dc = wx.BufferedDC(wx.ClientDC(self))
 985         self.Draw(dc)
 986         self.Refresh()   # Mac
 987 
 988 
 989     def OnPaint(self, event):
 990         """
 991         ...
 992         """
 993 
 994         dc = wx.BufferedPaintDC(self)
 995         dc.Clear()
 996 
 997         self.Draw(dc)
 998 
 999 #-------------------------------------------------------------------------------
1000 
1001 class MyFrame(wx.Frame):
1002     """
1003     Thanks to Robin Dunn.
1004     """
1005     def __init__(self):
1006         style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
1007                  wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
1008                  wx.NO_BORDER | wx.FRAME_SHAPED |
1009                  wx.NO_FULL_REPAINT_ON_RESIZE)
1010         wx.Frame.__init__(self, None, -1, title="", style=style)
1011 
1012         #------------
1013 
1014         # Attributes.
1015         self.SetTransparent(0)
1016         self.opacity_in = 0
1017         self.opacity_out = 250
1018         self.deltaN = -5
1019         self.hasShape = False
1020         self.delta = wx.Point(0,0)
1021 
1022         #------------
1023 
1024         # Return application name.
1025         self.app_name = wx.GetApp().GetAppName()
1026         # Return bitmaps folder.
1027         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1028         # Return icons folder.
1029         self.icons_dir = wx.GetApp().GetIconsDir()
1030 
1031         #------------
1032 
1033         # Simplified init method.
1034         self.SetProperties()
1035         self.OnTimerIn(self)
1036         self.CreateCtrls()
1037         self.BindEvents()
1038         self.DoLayout()
1039 
1040         #------------
1041 
1042         self.CenterOnScreen(wx.BOTH)
1043 
1044         #------------
1045 
1046         self.Show(True)
1047 
1048     #---------------------------------------------------------------------------
1049 
1050     def OnTimerIn(self, evt):
1051         """
1052         Thanks to Pascal Faut.
1053         """
1054 
1055         self.timer1 = wx.Timer(self, -1)
1056         self.timer1.Start(1)
1057         self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
1058 
1059         print("Fade-in was launched.")
1060 
1061 
1062     def OnTimerOut(self, evt):
1063         """
1064         Thanks to Pascal Faut.
1065         """
1066 
1067         self.timer2 = wx.Timer(self, -1)
1068         self.timer2.Start(1)
1069         self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
1070 
1071         print("Fade-out was launched.")
1072 
1073 
1074     def AlphaCycle1(self, *args):
1075         """
1076         Thanks to Pascal Faut.
1077         """
1078 
1079         self.opacity_in += self.deltaN
1080         if self.opacity_in <= 0:
1081             self.deltaN = -self.deltaN
1082             self.opacity_in = 0
1083 
1084         if self.opacity_in >= 250:
1085             self.deltaN = -self.deltaN
1086             self.opacity_in = 250
1087 
1088             self.timer1.Stop()
1089 
1090         self.SetTransparent(self.opacity_in)
1091 
1092         print("Fade in = {}/255".format(self.opacity_in))
1093 
1094 
1095     def AlphaCycle2(self, *args):
1096         """
1097         Thanks to Pascal Faut.
1098         """
1099 
1100         self.opacity_out += self.deltaN
1101         if self.opacity_out >= 250:
1102             self.deltaN = -self.deltaN
1103             self.opacity_out = 250
1104 
1105         if self.opacity_out <= 0:
1106             self.deltaN = -self.deltaN
1107             self.opacity_out = 0
1108 
1109             self.timer2.Stop()
1110             wx.CallAfter(self.Destroy)
1111             wx.Exit()
1112 
1113         self.SetTransparent(self.opacity_out)
1114 
1115         print("Fade out = {}/255".format(self.opacity_out))
1116 
1117 
1118     def SetProperties(self):
1119         """
1120         ...
1121         """
1122 
1123         self.SetTitle(self.app_name)
1124         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
1125 
1126         frameIcon = wx.Icon(os.path.join(self.icons_dir,
1127                                          "icon_wxWidgets.ico"),
1128                             type=wx.BITMAP_TYPE_ICO)
1129         self.SetIcon(frameIcon)
1130 
1131 
1132     def CreateCtrls(self):
1133         """
1134         ...
1135         """
1136 
1137         self.panel = MyPanel(self)
1138 
1139         #------------
1140 
1141         # Load a background bitmap.
1142         self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
1143                                           "skin_main_1.png"),
1144                              type=wx.BITMAP_TYPE_PNG)
1145         mask = wx.Mask(self.bmp, wx.RED)
1146         self.bmp.SetMask(mask)
1147 
1148         self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
1149 
1150         #------------
1151 
1152         if wx.Platform == "__WXGTK__":
1153             # wxGTK requires that the window be created before you can
1154             # set its shape, so delay the call to SetWindowShape until
1155             # this event.
1156             self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
1157         else:
1158             # On wxMSW and wxMac the window has
1159             # already been created, so go for it.
1160             self.SetWindowShape()
1161 
1162         # Create an accelerator table.
1163         self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('X'), wx.ID_EXIT),
1164                                               (wx.ACCEL_CTRL, ord('A'), wx.ID_ABOUT)
1165                                              ])
1166         self.SetAcceleratorTable(self.accel_tbl)
1167 
1168 
1169     def BindEvents(self):
1170         """
1171         Bind some events to an events handle.
1172         """
1173 
1174         self.panel.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)  # View mask.
1175         self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
1176         self.panel.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow)  # Panel right clic.
1177 
1178         self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
1179         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
1180         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
1181         self.Bind(wx.EVT_MOTION, self.OnMouseMove)
1182 
1183         self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT)  # Ctrl+X.
1184         self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
1185 
1186 
1187     def DoLayout(self):
1188         """
1189         ...
1190         """
1191 
1192         sizer = wx.BoxSizer(wx.VERTICAL)
1193         sizer.Add(self.panel, 1, wx.EXPAND)
1194         self.SetSizer(sizer)
1195 
1196 
1197     def OnAbout(self, event):
1198         """
1199         ...
1200         """
1201 
1202         self.dialog = MyAboutDlg(self)
1203 
1204 
1205     def SetWindowShape(self, *evt):
1206         """
1207         ...
1208         """
1209 
1210         # Use the bitmap's mask to determine the region.
1211         r = wx.Region(self.bmp)
1212         self.hasShape = self.SetShape(r)
1213 
1214 
1215     def OnEraseBackground(self, event):
1216         """
1217         ...
1218         """
1219 
1220         dc = event.GetDC()
1221         if not dc:
1222             dc = wx.ClientDC(self)
1223             rect = self.GetUpdateRegion().GetBox()
1224             dc.SetClippingRect(rect)
1225 
1226 
1227     def OnDoubleClick(self, event):
1228         """
1229         ...
1230         """
1231 
1232         if self.hasShape:
1233             self.SetShape(wx.Region())
1234             self.hasShape = False
1235         else:
1236             self.SetWindowShape()
1237 
1238 
1239     def OnLeftDown(self, event):
1240         """
1241         ...
1242         """
1243 
1244         self.CaptureMouse()
1245         x, y = self.ClientToScreen(event.GetPosition())
1246         originx, originy = self.GetPosition()
1247         dx = x - originx
1248         dy = y - originy
1249         self.delta = ((dx, dy))
1250 
1251 
1252     def OnLeftUp(self, evt):
1253         """
1254         ...
1255         """
1256 
1257         if self.HasCapture():
1258             self.ReleaseMouse()
1259 
1260 
1261     def OnMouseMove(self, event):
1262         """
1263         ...
1264         """
1265 
1266         if event.Dragging() and event.LeftIsDown():
1267             x, y = self.ClientToScreen(event.GetPosition())
1268             fp = (x - self.delta[0], y - self.delta[1])
1269             self.Move(fp)
1270 
1271 
1272     def OnIconize(self, event):
1273         """
1274         ...
1275         """
1276 
1277         self.Iconize()
1278 
1279 
1280     def OnCloseWindow(self, event):
1281         """
1282         Quit this application.
1283         """
1284 
1285         # self.Destroy()
1286         self.OnTimerOut(self)
1287 
1288         print("Exit application.")
1289 
1290 #-------------------------------------------------------------------------------
1291 
1292 class MyApp(wx.App):
1293     """
1294     Thanks to Andrea Gavana.
1295     """
1296     def OnInit(self):
1297 
1298         #------------
1299 
1300         self.locale = wx.Locale(wx.LANGUAGE_FRENCH)
1301 
1302         #------------
1303 
1304         self.SetAppName("Custom Gui 1")
1305 
1306         #------------
1307 
1308         self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
1309 
1310         #------------
1311 
1312         frame = MyFrame()
1313         self.SetTopWindow(frame)
1314         frame.Show(True)
1315 
1316         return True
1317 
1318     #---------------------------------------------------------------------------
1319 
1320     def GetInstallDir(self):
1321         """
1322         Returns the installation directory for my application.
1323         """
1324 
1325         return self.installDir
1326 
1327 
1328     def GetIconsDir(self):
1329         """
1330         Returns the icons directory for my application.
1331         """
1332 
1333         icons_dir = os.path.join(self.installDir, "icons")
1334         return icons_dir
1335 
1336 
1337     def GetBitmapsDir(self):
1338         """
1339         Returns the bitmaps directory for my application.
1340         """
1341 
1342         bitmaps_dir = os.path.join(self.installDir, "bitmaps")
1343         return bitmaps_dir
1344 
1345 #-------------------------------------------------------------------------------
1346 
1347 def main():
1348     app = MyApp(False)
1349     app.MainLoop()
1350 
1351 #-------------------------------------------------------------------------------
1352 
1353 if __name__ == "__main__" :
1354     main()


Second example

img_sample_two.png

   1 # sample_two.py
   2 
   3 import sys
   4 import os
   5 import platform
   6 import time
   7 import wx
   8 import wx.adv
   9 import wx.lib.fancytext as fancytext
  10 
  11 # class MyTitleBar
  12 # class MyAboutDlg
  13 # class MyPopupMenu
  14 # class MyWindow
  15 # class MyButtonBox
  16 # class MyPanel
  17 # class MyFrame
  18 # class MyApp
  19 
  20 #-------------------------------------------------------------------------------
  21 
  22 class MyTitleBar(wx.Control):
  23     """
  24     Thanks to Cody Precord.
  25     """
  26     def __init__(self, parent, label, size):
  27         super(MyTitleBar, self).__init__(parent, style=wx.BORDER_SIMPLE)
  28 
  29         #------------
  30 
  31         # Attributes.
  32         self.parent = parent
  33         self.label = label
  34         self.size = size
  35 
  36         #------------
  37 
  38         # Simplified init method.
  39         self.SetBackground()
  40         self.SetProperties(label, size)
  41         self.BindEvents()
  42 
  43     #-----------------------------------------------------------------------
  44 
  45     def SetBackground(self):
  46         """
  47         ...
  48         """
  49 
  50         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  51 
  52 
  53     def SetProperties(self, label, size):
  54         """
  55         ...
  56         """
  57 
  58         self.label = label
  59         self.size = size
  60 
  61         self.label_font = self.GetFont()
  62         self.label_font.SetFamily(wx.SWISS)
  63         self.label_font.SetPointSize(size)
  64         self.label_font.SetWeight(wx.BOLD)
  65         self.SetFont(self.label_font)
  66 
  67 
  68     def BindEvents(self):
  69         """
  70         Bind some events to an events handler.
  71         """
  72 
  73         self.Bind(wx.EVT_PAINT, self.OnPaint)
  74         self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)  # View mask.
  75         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
  76         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
  77 
  78 
  79     def OnLeftDown(self, event):
  80         """
  81         ...
  82         """
  83 
  84         self.GetTopLevelParent().OnLeftDown(event)
  85 
  86 
  87     def OnLeftUp(self, event):
  88         """
  89         ...
  90         """
  91 
  92         self.GetTopLevelParent().OnLeftUp(event)
  93 
  94 
  95     def OnDoubleClick(self, event):
  96         """
  97         ...
  98         """
  99 
 100         self.GetTopLevelParent().OnDoubleClick(event)
 101 
 102 
 103     def SetLabel(self, label):
 104         """
 105         ...
 106         """
 107 
 108         self.label = label
 109         self.Refresh()
 110 
 111 
 112     def DoGetBestSize(self):
 113         """
 114         ...
 115         """
 116 
 117         dc = wx.ClientDC(self)
 118         dc.SetFont(self.GetFont())
 119 
 120         textWidth, textHeight = dc.GetTextExtent(self.label)
 121         spacing = 10
 122         totalWidth = textWidth + (spacing)
 123         totalHeight = textHeight + (spacing)
 124 
 125         best = wx.Size(totalWidth, totalHeight)
 126         self.CacheBestSize(best)
 127 
 128         return best
 129 
 130 
 131     def GetLabel(self):
 132         """
 133         ...
 134         """
 135 
 136         return self.label
 137 
 138 
 139     def GetLabelColor(self):
 140         """
 141         ...
 142         """
 143 
 144         return self.foreground
 145 
 146 
 147     def GetLabelSize(self):
 148         """
 149         ...
 150         """
 151 
 152         return self.size
 153 
 154 
 155     def SetLabelColour(self, colour):
 156         """
 157         ...
 158         """
 159 
 160         self.labelColour = colour
 161 
 162 
 163     def OnPaint(self, event):
 164         """
 165         ...
 166         """
 167 
 168         dc = wx.BufferedPaintDC(self)
 169         gcdc = wx.GCDC(dc)
 170 
 171         gcdc.Clear()
 172 
 173         # Setup the GraphicsContext.
 174         gc = gcdc.GetGraphicsContext()
 175 
 176         # Get the working size we can draw in.
 177         width, height = self.GetSize()
 178 
 179         # Use the GCDC to draw the text.
 180         gcdc.GradientFillLinear((0, 0, width, height+70), "#3D3D3D",
 181                                 wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENU),
 182                                 wx.NORTH)
 183 
 184         # Get the system font.
 185         gcdc.SetFont(self.GetFont())
 186 
 187         textWidth, textHeight = gcdc.GetTextExtent(self.label)
 188         tposx, tposy = ((width/2)-(textWidth/2), (height/3)-(textHeight/3))
 189 
 190         tposx += 0
 191         tposy += 0
 192 
 193         # Set position and text color.
 194         gcdc.SetTextForeground("white")
 195         gcdc.DrawText(self.label, int(tposx-25), int(tposy+1))
 196 
 197         gcdc.SetTextForeground(self.labelColour)
 198         gcdc.DrawText(self.label, int(tposx-25), int(tposy))
 199 
 200 #-------------------------------------------------------------------------------
 201 
 202 class MyAboutDlg(wx.Frame):
 203     """
 204     Thanks to Robin Dunn.
 205     """
 206     def __init__(self, parent):
 207         style = (wx.FRAME_SHAPED | wx.NO_BORDER |
 208                  wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
 209                  wx.SYSTEM_MENU | wx.CLOSE_BOX |
 210                  wx.NO_FULL_REPAINT_ON_RESIZE)
 211         wx.Frame.__init__(self,
 212                           parent,
 213                           id=-1,
 214                           title="About...",
 215                           style=style)
 216 
 217         #------------
 218 
 219         # Attributes.
 220         self.SetTransparent(0)
 221         self.opacity_in = 0
 222         self.opacity_out = 255
 223         self.deltaN = -70
 224         self.hasShape = False
 225         self.delta = wx.Point(0,0)
 226 
 227         #------------
 228 
 229         # Return application name.
 230         self.app_name = wx.GetApp().GetAppName()
 231         # Return bitmaps folder.
 232         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
 233         # Return icons folder.
 234         self.icons_dir = wx.GetApp().GetIconsDir()
 235 
 236         #------------
 237 
 238         # Simplified init method.
 239         self.SetProperties()
 240         self.OnTimerIn(self)
 241         self.CreateCtrls()
 242         self.BindEvents()
 243 
 244         #------------
 245 
 246         self.CenterOnParent(wx.BOTH)
 247         self.GetParent().Enable(False)
 248 
 249         #------------
 250 
 251         self.Show(True)
 252 
 253         #------------
 254 
 255         self.eventLoop = wx.GUIEventLoop()
 256         self.eventLoop.Run()
 257 
 258     #---------------------------------------------------------------------------
 259 
 260     def SetProperties(self):
 261         """
 262         Set the dialog properties (title, icon, transparency...).
 263         """
 264 
 265         frameIcon = wx.Icon(os.path.join(self.icons_dir,
 266                                          "icon_wxWidgets.ico"),
 267                             type=wx.BITMAP_TYPE_ICO)
 268         self.SetIcon(frameIcon)
 269 
 270 
 271     def OnTimerIn(self, evt):
 272         """
 273         Thanks to Pascal Faut.
 274         """
 275 
 276         self.timer1 = wx.Timer(self, -1)
 277         self.timer1.Start(1)
 278         self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
 279 
 280         print("Fade-in was launched.")
 281 
 282 
 283     def OnTimerOut(self, evt):
 284         """
 285         Thanks to Pascal Faut.
 286         """
 287 
 288         self.timer2 = wx.Timer(self, -1)
 289         self.timer2.Start(1)
 290         self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
 291 
 292         print("Fade-out was launched.")
 293 
 294 
 295     def AlphaCycle1(self, *args):
 296         """
 297         Thanks to Pascal Faut.
 298         """
 299 
 300         self.opacity_in += self.deltaN
 301         if self.opacity_in <= 0:
 302             self.deltaN = -self.deltaN
 303             self.opacity_in = 0
 304 
 305         if self.opacity_in >= 255:
 306             self.deltaN = -self.deltaN
 307             self.opacity_in = 255
 308 
 309             self.timer1.Stop()
 310 
 311         self.SetTransparent(self.opacity_in)
 312 
 313         print("Fade in = {}/255".format(self.opacity_in))
 314 
 315 
 316     def AlphaCycle2(self, *args):
 317         """
 318         Thanks to Pascal Faut.
 319         """
 320 
 321         self.opacity_out += self.deltaN
 322         if self.opacity_out >= 255:
 323             self.deltaN = -self.deltaN
 324             self.opacity_out = 255
 325 
 326         if self.opacity_out <= 0:
 327             self.deltaN = -self.deltaN
 328             self.opacity_out = 0
 329 
 330             self.timer2.Stop()
 331 
 332             wx.CallAfter(self.Destroy)
 333 
 334         self.SetTransparent(self.opacity_out)
 335 
 336         print("Fade out = {}/255".format(self.opacity_out))
 337 
 338 
 339     def CreateCtrls(self):
 340         """
 341         Make widgets for my dialog.
 342         """
 343 
 344         # Load a background bitmap.
 345         self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
 346                                           "skin_about.png"),
 347                              type=wx.BITMAP_TYPE_PNG)
 348         mask = wx.Mask(self.bmp, wx.RED)
 349         self.bmp.SetMask(mask)
 350 
 351         #------------
 352 
 353         self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
 354 
 355         #------------
 356 
 357         if wx.Platform == "__WXGTK__":
 358             # wxGTK requires that the window be created before you can
 359             # set its shape, so delay the call to SetWindowShape until
 360             # this event.
 361             self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
 362         else:
 363             # On wxMSW and wxMac the window has already
 364             # been created, so go for it.
 365             self.SetWindowShape()
 366 
 367 
 368     def BindEvents(self):
 369         """
 370         Bind all the events related to my dialog.
 371         """
 372 
 373         # Bind some events to an events handler.
 374         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
 375         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
 376         self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow)  # Panel right clic.
 377         self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)  # View mask.
 378         self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
 379         self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
 380         self.Bind(wx.EVT_MOTION, self.OnMouseMove)
 381         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
 382         self.Bind(wx.EVT_PAINT, self.OnPaint)
 383         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 384 
 385 
 386     def SetWindowShape(self, event=None):
 387         """
 388         ...
 389         """
 390 
 391         # Use the bitmap's mask to determine the region.
 392         r = wx.Region(self.bmp)
 393         self.hasShape = self.SetShape(r)
 394 
 395 
 396     def OnEraseBackground(self, event):
 397         """
 398         ...
 399         """
 400 
 401         dc = event.GetDC()
 402         if not dc:
 403             dc = wx.ClientDC(self)
 404             rect = self.GetUpdateRegion().GetBox()
 405             dc.SetClippingRect(rect)
 406 
 407 
 408     def OnDoubleClick(self, event):
 409         """
 410         ...
 411         """
 412 
 413         if self.hasShape:
 414             self.SetShape(wx.Region())
 415             self.hasShape = False
 416         else:
 417             self.SetWindowShape()
 418 
 419 
 420     def OnLeftDown(self, event):
 421         """
 422         ...
 423         """
 424 
 425         self.CaptureMouse()
 426         x, y = self.ClientToScreen(event.GetPosition())
 427         originx, originy = self.GetPosition()
 428         dx = x - originx
 429         dy = y - originy
 430         self.delta = ((dx, dy))
 431 
 432 
 433     def OnLeftUp(self, evt):
 434         """
 435         ...
 436         """
 437 
 438         if self.HasCapture():
 439             self.ReleaseMouse()
 440 
 441 
 442     def OnMouseMove(self, event):
 443         """
 444         ...
 445         """
 446 
 447         if event.Dragging() and event.LeftIsDown():
 448             x, y = self.ClientToScreen(event.GetPosition())
 449             fp = (x - self.delta[0], y - self.delta[1])
 450             self.Move(fp)
 451 
 452 
 453     def OnPaint(self, event):
 454         """
 455         ...
 456         """
 457 
 458         dc = wx.AutoBufferedPaintDCFactory(self)
 459         dc.DrawBitmap(self.bmp, 0, 0, True)
 460 
 461         #------------
 462 
 463         # These are strings.
 464         py_version = sys.version.split()[0]
 465 
 466         str1 = (('<font style="normal" family="default" color="yellow" size="10" weight="bold">'
 467                  'Programming : </font>'
 468                  '<font style="normal" family="default" color="black" size="10" weight="normal">'
 469                  'Python {}</font>').format(py_version))   # Python 3.6.5
 470 
 471         str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
 472                  'GUI toolkit : </font>'
 473                  '<font style="normal" family="default" color="black" size="10" weight="normal">'
 474                  'wxPython {}</font>').format(wx.VERSION_STRING))  # wxPython 4.0.2
 475 
 476         str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
 477                  'Library : </font>'
 478                  '<font style="normal" family="default" color="black" size="10" weight="normal">'
 479                  '{}</font>').format(wx.GetLibraryVersionInfo().VersionString))   # wxWidgets 3.0.5
 480 
 481         str4 = (('<font style="normal" family="default" color="blue" size="10" weight="bold">'
 482                  'Operating system : </font>'
 483                  '<font style="normal" family="default" color="black" size="10" weight="normal">'
 484                  '{}</font>').format(platform.system()))   # Windows
 485 
 486         str5 = (('<font style="normal" family="default" color="white" size="9" weight="normal">'
 487                  '{}</font>').format(self.app_name))   # Custom Gui 2
 488 
 489         str6 = (('<font style="normal" family="default" color="dark blue" size="8" weight="normal">'
 490                  'Right clic or Esc for Exit</font>'))
 491 
 492         #------------
 493 
 494         # Return image size.
 495         bw, bh = self.bmp.GetWidth(), self.bmp.GetHeight()
 496 
 497         # Draw text.
 498         # Need width to calculate x position of str1.
 499         tw, th = fancytext.GetExtent(str1, dc)
 500         # Centered text.
 501         fancytext.RenderToDC(str1, dc, (bw-tw)/2, 30)
 502 
 503         #------------
 504 
 505         # Need width to calculate x position of str2.
 506         tw, th = fancytext.GetExtent(str2, dc)
 507         # Centered text.
 508         fancytext.RenderToDC(str2, dc, (bw-tw)/2, 50)
 509 
 510         #------------
 511 
 512         # Need width to calculate x position of str3.
 513         tw, th = fancytext.GetExtent(str3, dc)
 514         # Centered text.
 515         fancytext.RenderToDC(str3, dc, (bw-tw)/2, 70)
 516 
 517         #------------
 518 
 519         # Need width to calculate x position of str4.
 520         tw, th = fancytext.GetExtent(str4, dc)
 521         # Centered text.
 522         fancytext.RenderToDC(str4, dc, (bw-tw)/2, 90)
 523 
 524         #------------
 525 
 526         # Need width to calculate x position of str5.
 527         tw, th = fancytext.GetExtent(str5, dc)
 528         # Centered text.
 529         fancytext.RenderToDC(str5, dc, (bw-tw)/2, 130)
 530 
 531         #------------
 532 
 533         # Need width to calculate x position of str6.
 534         tw, th = fancytext.GetExtent(str6, dc)
 535         # Centered text.
 536         fancytext.RenderToDC(str6, dc, (bw-tw)/2, 195)
 537 
 538 
 539     def OnKeyUp(self, event):
 540         """
 541         ...
 542         """
 543 
 544         if event.GetKeyCode() == wx.WXK_ESCAPE:
 545             self.OnCloseWindow(event)
 546 
 547         event.Skip()
 548 
 549 
 550     def OnCloseWindow(self, event):
 551         """
 552         ...
 553         """
 554 
 555         self.GetParent().Enable(True)
 556         self.eventLoop.Exit()
 557         #self.Destroy()
 558         self.OnTimerOut(self)
 559 
 560 #-------------------------------------------------------------------------------
 561 
 562 class MyPopupMenu(wx.Menu):
 563     """
 564     Thanks to Robin Dunn.
 565     """
 566     def __init__(self, parent):
 567         wx.Menu.__init__(self)
 568 
 569         #------------
 570 
 571         # Attributes.
 572         self.parent = parent
 573 
 574         #------------
 575 
 576         # Simplified init method.
 577         self.CreatePopupMenu()
 578         self.BindEvents()
 579 
 580     #---------------------------------------------------------------------------
 581 
 582     def CreatePopupMenu(self, event=None):
 583         """
 584         This method is called by the base class when it needs to popup
 585         the menu for the default EVT_RIGHT_DOWN event.  Just create
 586         the menu how you want it and return it from this function,
 587         the base class takes care of the rest.
 588         """
 589 
 590         # Returns bitmaps folder.
 591         bitmaps_dir = wx.GetApp().GetBitmapsDir()
 592 
 593         #------------
 594 
 595         bmp = wx.Bitmap(os.path.join(bitmaps_dir,
 596                                      "item_about.png"),
 597                         type=wx.BITMAP_TYPE_PNG)
 598 
 599         item = wx.MenuItem(self, id=wx.ID_ABOUT, text=" About")
 600         item.SetBitmap(bmp)
 601         self.Append(item)
 602         self.AppendSeparator()
 603 
 604         #------------
 605 
 606         bmp = wx.Bitmap(os.path.join(bitmaps_dir,
 607                                      "item_exit.png"),
 608                         type=wx.BITMAP_TYPE_PNG)
 609 
 610         if True or "__WXMSW__" in wx.PlatformInfo:
 611             font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
 612             font.SetWeight(wx.BOLD)
 613 
 614         item = wx.MenuItem(self, id=wx.ID_EXIT, text=" Exit")
 615         item.SetBitmap(bmp)
 616         item.SetFont(font)
 617         self.Append(item)
 618 
 619         return self
 620 
 621 
 622     def BindEvents(self):
 623         """
 624         Bind some events to an events handler.
 625         """
 626 
 627         # Bind the menu events to an events handler.
 628         self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
 629         self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT)
 630 
 631 
 632     def OnAbout(self, event):
 633         """
 634         ...
 635         """
 636 
 637         self.mainFrame = wx.GetApp().GetTopWindow()
 638         self.mainFrame.OnAbout(self)
 639 
 640         print("About icon was clicked.")
 641 
 642 
 643     def OnClose(self, event):
 644         """
 645         ...
 646         """
 647 
 648         self.mainFrame = wx.GetApp().GetTopWindow()
 649         self.mainFrame.OnTimerOut(self)
 650 
 651         print("Close icon was clicked.")
 652 
 653 #-------------------------------------------------------------------------------
 654 
 655 class MyWindow(wx.Control):
 656     """
 657     Thanks to Cody Precord.
 658     """
 659     def __init__(self, parent, label,
 660                  foreground, background,
 661                  normal, pressed=None):
 662         super(MyWindow, self).__init__(parent, -1,
 663                                        style=wx.BORDER_NONE)
 664 
 665         #------------
 666 
 667         # Attributes.
 668         self.label = label
 669         self.foreground = foreground
 670         self.background = background
 671 
 672         if wx.Platform == "__WXGTK__":
 673             self.color = "#9e9d9d"
 674 
 675         else:
 676             self.color = "#b1b1b0"
 677 
 678         self.normal = normal
 679         self.pressed = pressed
 680 
 681         self._clicked = False
 682 
 683         #------------
 684 
 685         self.region = wx.Region(normal, wx.Colour(0, 0, 0, 0))
 686 
 687         #------------
 688 
 689         # Simplified init method.
 690         self.SetProperties(label, foreground, background)
 691         self.BindEvents()
 692 
 693     #---------------------------------------------------------------------------
 694 
 695     def SetProperties(self, label, foreground, background):
 696         """
 697         ...
 698         """
 699 
 700         self.label = label
 701         self.foreground = foreground
 702         self.background = background
 703         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
 704 
 705 
 706     def BindEvents(self):
 707         """
 708         Bind some events to an events handler.
 709         """
 710 
 711         self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
 712         self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
 713         self.Bind(wx.EVT_PAINT, self.OnPaint)
 714         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
 715         self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDclick)
 716         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
 717         self.Bind(wx.EVT_MOTION, self.OnMotion)
 718         self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
 719         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
 720 
 721 
 722     def SetLabel(self, label):
 723         """
 724         ...
 725         """
 726 
 727         self.label = label
 728         self.Refresh()
 729 
 730 
 731     def DoGetBestSize(self):
 732         """
 733         ...
 734         """
 735 
 736         return self.normal.GetSize()
 737 
 738 
 739     def GetLabel(self):
 740         """
 741         ...
 742         """
 743 
 744         return self.label
 745 
 746 
 747     def GetLabelColor(self):
 748         """
 749         ...
 750         """
 751 
 752         return self.foreground
 753 
 754 
 755     def Enable(self, *args, **kwargs):
 756         """
 757         ...
 758         """
 759 
 760         super(MyWindow, self).Enable(*args, **kwargs)
 761         self.Refresh()
 762 
 763 
 764     def Disable(self, *args, **kwargs):
 765         """
 766         ...
 767         """
 768 
 769         super(MyWindow, self).Disable(*args, **kwargs)
 770         self.Refresh()
 771 
 772 
 773     def PostEvent(self):
 774         """
 775         ...
 776         """
 777 
 778         event = wx.CommandEvent()
 779         event.SetEventObject(self)
 780         event.SetEventType(wx.EVT_BUTTON.typeId)
 781         wx.PostEvent(self, event)
 782 
 783 
 784     def OnSize(self, event):
 785         """
 786         ...
 787         """
 788 
 789         event.Skip()
 790         self.Refresh()
 791 
 792 
 793     def Getbackground(self):
 794         """
 795         ...
 796         """
 797 
 798         return self.background
 799 
 800 
 801     def OnPaint(self, event):
 802         """
 803         ...
 804         """
 805 
 806         dc = wx.BufferedPaintDC(self)
 807         dc.Clear()
 808         gcdc = wx.GCDC(dc)
 809 
 810         # Set the background color.
 811         if wx.Platform == "__WXGTK__":
 812             gcdc.SetBackground(wx.Brush("grey55"))
 813         else:
 814             gcdc.SetBackground(wx.Brush(self.background))
 815 
 816         gcdc.Clear()
 817 
 818         # Get the working rectangle we can draw in.
 819         rect = self.GetClientRect()
 820 
 821         # Font size and style.
 822         fontSize = self.GetFont().GetPointSize()
 823 
 824         if wx.Platform == "__WXGTK__":
 825             boldFont = wx.Font(fontSize-1, wx.DEFAULT,
 826                                wx.NORMAL, wx.NORMAL, False, "")
 827         else:
 828             boldFont = wx.Font(fontSize+2, wx.DEFAULT,
 829                                wx.NORMAL, wx.BOLD, False, "")
 830 
 831         if wx.Platform == "__WXMSW__":
 832             pen = wx.Pen(self.color, 1, wx.SOLID)
 833 
 834         else:
 835             pen = wx.Pen(self.color, 1, wx.SOLID)
 836 
 837         gcdc.SetPen(pen)
 838 
 839         x, y = self.GetSize()
 840         # x, y , width, height, radius
 841         gcdc.DrawRoundedRectangle (0, 0, 71, 25, 3)
 842 
 843         bitmap = self.normal
 844 
 845         w, h = bitmap.GetWidth(), bitmap.GetHeight()
 846 
 847         if self.clicked:
 848             bitmap = self.pressed or bitmap
 849         if not self.IsEnabled():
 850             bitmap = self.normal or bitmap
 851 
 852         # Draw a bitmap with an alpha channel.
 853         # image, x, y, transparency.
 854         dc.DrawBitmap(bitmap, 0, 0, True)
 855 
 856         if wx.Platform == "__WXGTK__":
 857             # Add the Caption.
 858             # White text - Shadow.
 859             rect = wx.Rect(rect.x, rect.y+3,
 860                            rect.width, 22)
 861 
 862         else:
 863             rect = wx.Rect(rect.x, rect.y+3,
 864                            rect.width, 20)
 865 
 866         dc.SetFont(boldFont)
 867         dc.SetTextForeground(wx.WHITE)
 868         dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
 869 
 870         if wx.Platform == "__WXGTK__":
 871             # Add the Caption.
 872             # Black text.
 873             rect = wx.Rect(rect.x, rect.y,
 874                            rect.width, 21)
 875 
 876         else:
 877             rect = wx.Rect(rect.x, rect.y,
 878                            rect.width, 19)
 879 
 880         gcdc.SetFont(boldFont)
 881         # Get the text color.
 882         dc.SetTextForeground(self.foreground)
 883         dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
 884 
 885 
 886     def SetClicked(self, clicked):
 887         """
 888         ...
 889         """
 890 
 891         if clicked != self._clicked:
 892             self._clicked = clicked
 893             self.Refresh()
 894 
 895 
 896     def GetClicked(self):
 897         """
 898         ...
 899         """
 900 
 901         return self._clicked
 902 
 903 
 904     clicked = property(GetClicked, SetClicked)
 905     def OnLeftDown(self, event):
 906         """
 907         ...
 908         """
 909 
 910         x, y = event.GetPosition()
 911         if self.region.Contains(x, y):
 912             self.clicked = True
 913             self.SetFocus()
 914 
 915 
 916     def OnLeftDclick(self, event):
 917         """
 918         ...
 919         """
 920 
 921         self.OnLeftDown(event)
 922 
 923 
 924     def OnLeftUp(self, event):
 925         """
 926         ...
 927         """
 928 
 929         if self.clicked:
 930             x, y = event.GetPosition()
 931             if self.region.Contains(x, y):
 932                 self.PostEvent()
 933         self.clicked = False
 934 
 935 
 936     def OnMotion(self, event):
 937         """
 938         ...
 939         """
 940 
 941         if self.clicked:
 942             x, y = event.GetPosition()
 943             if not self.region.Contains(x, y):
 944                 self.clicked = False
 945 
 946 
 947     def OnLeave(self, event):
 948         """
 949         ...
 950         """
 951 
 952         self.clicked = False
 953 
 954 
 955     def OnSetFocus(self, event):
 956         """
 957         ...
 958         """
 959 
 960         self.color = "white"
 961         self.Refresh()
 962 
 963 
 964     def OnKillFocus(self, event):
 965         """
 966         ...
 967         """
 968 
 969         if wx.Platform == "__WXGTK__":
 970             self.color = "#9e9d9d"
 971 
 972         else:
 973             self.color = "#b1b1b0"
 974 
 975         self.Refresh()
 976 
 977 
 978     def OnKeyUp(self, event):
 979         """
 980         ...
 981         """
 982 
 983         if event.GetKeyCode() == wx.WXK_SPACE:
 984             self.PostEvent()
 985             return
 986 
 987         elif event.GetKeyCode() == wx.WXK_ESCAPE:
 988             self.GetTopLevelParent().OnCloseWindow(True)
 989 
 990         event.Skip()
 991 
 992 #-------------------------------------------------------------------------------
 993 
 994 class MyButtonBox(wx.Panel):
 995     """
 996     Thanks to Cody Precord.
 997     """
 998     def __init__(self, parent, caption):
 999         super(MyButtonBox, self).__init__(parent,
1000                                            style=wx.NO_BORDER |
1001                                            wx.TAB_TRAVERSAL)
1002 
1003         #------------
1004 
1005         # Attributes.
1006         self._caption = caption
1007 
1008         #------------
1009 
1010         # Simplified init method.
1011         self.DoLayout()
1012 
1013     #---------------------------------------------------------------------------
1014 
1015     def DoLayout(self):
1016         """
1017         ...
1018         """
1019 
1020         self._csizer = wx.BoxSizer(wx.VERTICAL)
1021         msizer = wx.BoxSizer(wx.HORIZONTAL)
1022         msizer.Add(self._csizer, 0 )
1023         self.SetSizer(msizer)
1024 
1025 
1026     def DoGetBestSize(self):
1027         """
1028         ...
1029         """
1030 
1031         size = super(MyButtonBox, self).DoGetBestSize()
1032 
1033         # Compensate for wide caption labels.
1034         tw = self.GetTextExtent(self._caption)[0]
1035         size.SetWidth(max(size.width, size.height))
1036         return size
1037 
1038 
1039     def AddItem(self, item):
1040         """
1041         Add a window or sizer item to the MyButtonBox.
1042         """
1043 
1044         self._csizer.Add(item, 0 )
1045 
1046 #-------------------------------------------------------------------------------
1047 
1048 class MyPanel(wx.Panel):
1049     """
1050     Thanks to Cody Precord.
1051     """
1052     def __init__(self, parent):
1053         wx.Panel.__init__(self, parent)
1054 
1055         #------------
1056 
1057         # Return application name.
1058         self.app_name = wx.GetApp().GetAppName()
1059         # Return bitmaps folder.
1060         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1061 
1062         #------------
1063 
1064         # Create a timer.
1065         self.timer = wx.Timer(self)
1066         self.timer.Start(1000)
1067         self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
1068 
1069         #------------
1070 
1071         # Simplified init method.
1072         self.SetProperties()
1073         self.CreateCtrls()
1074         self.BindEvents()
1075 
1076     #---------------------------------------------------------------------------
1077 
1078     def SetProperties(self):
1079         """
1080         ...
1081         """
1082 
1083         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
1084 
1085 
1086     def CreateCtrls(self):
1087         """
1088         ...
1089         """
1090 
1091         # Load a background bitmap.
1092         self.bitmap = wx.Bitmap(os.path.join(self.bitmaps_dir,
1093                                              "skin_main.png"),
1094                                 type=wx.BITMAP_TYPE_PNG)
1095 
1096         #------------
1097 
1098         # Add titleBar.
1099         self.titleBar = MyTitleBar(self,
1100                                    label=self.app_name,
1101                                    size=10)
1102         self.titleBar.SetPosition((1, 1))
1103         self.titleBar.SetSize((258, 24))
1104         self.titleBar.SetLabelColour(wx.BLACK)
1105         self.titleBar.SetToolTip("This is a customized title bar.")
1106 
1107         #------------
1108 
1109         # Load an icon bitmap for titlebar.
1110         self.icon = wx.Bitmap(os.path.join(self.bitmaps_dir,
1111                                            "icon_app_2.png"),
1112                               type=wx.BITMAP_TYPE_PNG)
1113 
1114         self.ico = wx.StaticBitmap(self.titleBar, -1, self.icon)
1115         self.ico.SetPosition((5, 2))
1116         self.ico.SetToolTip("This is a customized icon.")
1117 
1118         self.ico.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
1119         self.ico.Bind(wx.EVT_LEFT_DOWN, self.OnRightDown)
1120 
1121         #------------
1122         #------------
1123 
1124         # Load a bitmap.
1125         self.logo  = wx.Bitmap(os.path.join(self.bitmaps_dir,
1126                                             "logo.png"),
1127                                type=wx.BITMAP_TYPE_PNG)
1128 
1129         #------------
1130 
1131         # Aluminium Buttons box (main).
1132         self.box1 = MyButtonBox(self, "")   # Button About.
1133         self.box2 = MyButtonBox(self, "")   # Button Quit.
1134 
1135         # Gloss Buttons box (titleBar).
1136         self.box3 = MyButtonBox(self.titleBar, "")   # Button Exit.
1137         self.box4 = MyButtonBox(self.titleBar, "")   # Button Reduce.
1138 
1139         #------------
1140 
1141         # Aluminium Buttons bitmap.
1142         bmp1 = wx.Bitmap(os.path.join(self.bitmaps_dir,
1143                                       "btn_alu_normal.png"),
1144                          type=wx.BITMAP_TYPE_PNG)
1145 
1146         bmp2 = wx.Bitmap(os.path.join(self.bitmaps_dir,
1147                                       "btn_alu_pressed.png"),
1148                          type=wx.BITMAP_TYPE_PNG)
1149 
1150         bmpa = wx.Bitmap(os.path.join(self.bitmaps_dir,
1151                                       "btn_alu_exit_normal.png"),
1152                          type=wx.BITMAP_TYPE_PNG)
1153 
1154         bmpb = wx.Bitmap(os.path.join(self.bitmaps_dir,
1155                                       "btn_alu_exit_selected.png"),
1156                          type=wx.BITMAP_TYPE_PNG)
1157 
1158 
1159         bmpc = wx.Bitmap(os.path.join(self.bitmaps_dir,
1160                                       "btn_alu_roll_normal.png"),
1161                          type=wx.BITMAP_TYPE_PNG)
1162 
1163         bmpd = wx.Bitmap(os.path.join(self.bitmaps_dir,
1164                                       "btn_alu_roll_selected.png"),
1165                          type=wx.BITMAP_TYPE_PNG)
1166 
1167         # Buttons panel.
1168         self.btn1 = MyWindow(self.box1, "About", "black", "#9e9d9d", bmp1, bmp2)
1169         self.btn1.SetToolTip("This is a customized aluminium button.")
1170         self.btn1.Bind(wx.EVT_BUTTON, self.OnBtnAbout)
1171         self.btn1.SetFocus() # Necessary for Linux.
1172 
1173         self.btn2 = MyWindow(self.box2, "Exit", "black", "#9e9d9d", bmp1, bmp2)
1174         self.btn2.SetToolTip("This is a customized aluminium button.")
1175         self.btn2.Bind(wx.EVT_BUTTON, self.OnBtnClose)
1176 
1177         self.btn3 = MyWindow(self.box3, "", "black", "#9e9d9d", bmpa, bmpb)
1178         self.btn3.SetToolTip("This is a customized gloss button.")
1179         self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)
1180 
1181         self.btn4 = MyWindow(self.box4, "", "black", "#9e9d9d", bmpc, bmpd)
1182         self.btn4.SetToolTip("This is a customized gloss button.")
1183         self.btn4.Bind(wx.EVT_BUTTON, self.OnBtnRoll)
1184 
1185         self.box1.AddItem(self.btn1)
1186         self.box2.AddItem(self.btn2)
1187         self.box3.AddItem(self.btn3)
1188         self.box4.AddItem(self.btn4)
1189 
1190         self.box1.SetPosition((20, 138))
1191         self.box1.SetSize((71, 25))
1192 
1193         self.box2.SetPosition((20, 173))
1194         self.box2.SetSize((71, 25))
1195 
1196         self.box3.SetPosition((214, 2))
1197         self.box3.SetSize((40, 19))
1198 
1199         self.box4.SetPosition((189, 2))
1200         self.box4.SetSize((25, 19))
1201 
1202 
1203     def BindEvents(self):
1204         """
1205         Bind some events to an events handler.
1206         """
1207 
1208         self.Bind(wx.EVT_PAINT, self.OnPaint)
1209         self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
1210 
1211 
1212     def OnLeftDown(self, evt):
1213         """
1214         ...
1215         """
1216 
1217         print("Left down.")
1218 
1219 
1220     def OnRightDown(self, event):
1221         """
1222         ...
1223         """
1224 
1225         self.PopupMenu(MyPopupMenu(self), event.GetPosition())
1226 
1227         print("Right down.")
1228 
1229 
1230     def OnEraseBackground(self, event):
1231         """
1232         ...
1233         """
1234 
1235         dc = event.GetDC()
1236         if not dc:
1237             dc = wx.ClientDC(self)
1238             rect = self.GetUpdateRegion().GetBox()
1239             dc.SetClippingRect(rect)
1240 
1241 
1242     def OnBtnRoll(self, event):
1243         """
1244         ...
1245         """
1246 
1247         self.GetParent().OnRoll(True)
1248 
1249         print("Roll/unRoll button was clicked.")
1250 
1251 
1252     def OnBtnAbout(self, event):
1253         """
1254         ...
1255         """
1256 
1257         self.GetParent().OnAbout(True)
1258 
1259         print("About button was clicked.")
1260 
1261 
1262     def OnBtnClose(self, event):
1263         """
1264         ...
1265         """
1266 
1267         self.GetParent().OnCloseWindow(self)
1268 
1269         print("Close button was clicked.")
1270 
1271 
1272     def Draw(self, dc):
1273         """
1274         ...
1275         """
1276 
1277         # Draw a bitmap with an alpha channel
1278         # on top of the last group.
1279         # image, x, y, transparence
1280         dc.DrawBitmap(self.bitmap, 0, 0, True)
1281 
1282         #------------
1283 
1284         fontSize = self.GetFont().GetPointSize()
1285 
1286         # wx.Font(pointSize, family, style, weight, underline, faceName)
1287         if wx.Platform == "__WXGTK__":
1288             self.titleBoldFont = wx.Font(fontSize-2,
1289                                          wx.DEFAULT, wx.NORMAL,
1290                                          wx.BOLD, False, "")
1291             self.normalBoldFont = wx.Font(fontSize+18,
1292                                           wx.DEFAULT, wx.NORMAL,
1293                                           wx.NORMAL, False, "")
1294             self.normalFont = wx.Font(fontSize-2,
1295                                       wx.DEFAULT, wx.NORMAL,
1296                                       wx.NORMAL, False, "")
1297 
1298         else:
1299             self.titleBoldFont = wx.Font(fontSize+1,
1300                                          wx.DEFAULT, wx.NORMAL,
1301                                          wx.BOLD, False, "")
1302             self.normalBoldFont = wx.Font(fontSize+23,
1303                                           wx.DEFAULT, wx.NORMAL,
1304                                           wx.NORMAL, False, "")
1305             self.normalFont = wx.Font(fontSize+1,
1306                                       wx.DEFAULT, wx.NORMAL,
1307                                       wx.NORMAL, False, "")
1308 
1309         dc.SetFont(self.normalFont)
1310         dc.SetFont(self.normalBoldFont)
1311 
1312         #------------
1313 
1314         # Draw a bitmap with an alpha channel.
1315         # image, x, y, transparence
1316         dc.DrawBitmap(self.logo, 150, 165, True)
1317 
1318         #------------
1319 
1320         # Return image size.
1321         bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
1322 
1323         # Draw line.
1324         dc.SetPen(wx.Pen("#c5c4c4"))
1325         # x, y, x, y
1326         dc.DrawLine(2, 25, 258, 25)
1327 
1328         # Draw text.
1329         dc.SetTextForeground("#494848")
1330         dc.SetFont(self.normalFont)
1331         date = time.strftime("%A %d %B %Y")
1332         tw, th = dc.GetTextExtent(date)
1333         dc.DrawText(date, int((bw-tw)/2), int(100))
1334 
1335         dc.SetTextForeground("#e3dbdb")
1336         dc.SetFont(self.normalBoldFont)
1337         hour = time.strftime("%H:%M:%S")   # "%I:%M:%S %p"
1338         tw, th = dc.GetTextExtent(hour)
1339         dc.DrawText(hour, int((bw-tw)/2), int(40))
1340 
1341 
1342     def OnTimer(self, event):
1343         """
1344         ...
1345         """
1346 
1347         dc = wx.BufferedDC(wx.ClientDC(self))
1348         self.Draw(dc)
1349         self.Refresh()   # Mac
1350 
1351 
1352     def OnPaint(self, event):
1353         """
1354         ...
1355         """
1356 
1357         dc = wx.BufferedPaintDC(self)
1358         dc.Clear()
1359 
1360         self.Draw(dc)
1361 
1362 #-------------------------------------------------------------------------------
1363 
1364 class MyFrame(wx.Frame):
1365     """
1366     Thanks to Robin Dunn.
1367     """
1368     def __init__(self):
1369         style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
1370                  wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
1371                  wx.NO_BORDER | wx.FRAME_SHAPED |
1372                  wx.NO_FULL_REPAINT_ON_RESIZE)
1373         wx.Frame.__init__(self, None, -1, title="", style=style)
1374 
1375         #------------
1376 
1377         # Attributes.
1378         self.SetTransparent(0)
1379         self.opacity_in = 0
1380         self.opacity_out = 250
1381         self.deltaN = -3
1382         self.hasShape = False
1383         self.delta = wx.Point(0,0)
1384 
1385         #------------
1386 
1387         # Return application name.
1388         self.app_name = wx.GetApp().GetAppName()
1389         # Return bitmaps folder.
1390         self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1391         # Return icons folder.
1392         self.icons_dir = wx.GetApp().GetIconsDir()
1393 
1394         #------------
1395 
1396         # Simplified init method.
1397         self.SetProperties()
1398         self.OnTimerIn(self)
1399         self.CreateCtrls()
1400         self.BindEvents()
1401         self.DoLayout()
1402 
1403         #------------
1404 
1405         # Thanks to Ray Pasco.
1406         # Initialize to the current state.
1407         self.unrolledFrameClientSize_size = self.GetClientSize()
1408         self.isRolled = False
1409 
1410         #------------
1411 
1412         self.CenterOnScreen(wx.BOTH)
1413 
1414         #------------
1415 
1416         self.Show(True)
1417 
1418     #---------------------------------------------------------------------------
1419 
1420     def OnTimerIn(self, evt):
1421         """
1422         Thanks to Pascal Faut.
1423         """
1424 
1425         self.timer1 = wx.Timer(self, -1)
1426         self.timer1.Start(1)
1427         self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
1428 
1429         print("Fade-in was launched.")
1430 
1431 
1432     def OnTimerOut(self, evt):
1433         """
1434         Thanks to Pascal Faut.
1435         """
1436 
1437         self.timer2 = wx.Timer(self, -1)
1438         self.timer2.Start(1)
1439         self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
1440 
1441         print("Fade-out was launched.")
1442 
1443 
1444     def AlphaCycle1(self, *args):
1445         """
1446         Thanks to Pascal Faut.
1447         """
1448 
1449         self.opacity_in += self.deltaN
1450         if self.opacity_in <= 0:
1451             self.deltaN = -self.deltaN
1452             self.opacity_in = 0
1453 
1454         if self.opacity_in >= 250:
1455             self.deltaN = -self.deltaN
1456             self.opacity_in = 250
1457 
1458             self.timer1.Stop()
1459 
1460         self.SetTransparent(self.opacity_in)
1461 
1462         print("Fade in = {}/255".format(self.opacity_in))
1463 
1464 
1465     def AlphaCycle2(self, *args):
1466         """
1467         Thanks to Pascal Faut.
1468         """
1469 
1470         self.opacity_out += self.deltaN
1471         if self.opacity_out >= 250:
1472             self.deltaN = -self.deltaN
1473             self.opacity_out = 250
1474 
1475         if self.opacity_out <= 0:
1476             self.deltaN = -self.deltaN
1477             self.opacity_out = 0
1478 
1479             self.timer2.Stop()
1480             wx.CallAfter(self.Destroy)
1481             wx.Exit()
1482 
1483         self.SetTransparent(self.opacity_out)
1484 
1485         print("Fade out = {}/255".format(self.opacity_out))
1486 
1487 
1488     def SetProperties(self):
1489         """
1490         ...
1491         """
1492 
1493         self.SetTitle(self.app_name)
1494         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
1495 
1496         frameIcon = wx.Icon(os.path.join(self.icons_dir,
1497                                          "icon_wxWidgets.ico"),
1498                             type=wx.BITMAP_TYPE_ICO)
1499         self.SetIcon(frameIcon)
1500 
1501 
1502     def CreateCtrls(self):
1503         """
1504         ...
1505         """
1506 
1507         self.panel = MyPanel(self)
1508 
1509         #------------
1510 
1511         # Load a background bitmap.
1512         self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
1513                                           "skin_main.png"),
1514                              type=wx.BITMAP_TYPE_PNG)
1515         mask = wx.Mask(self.bmp, wx.RED)
1516         self.bmp.SetMask(mask)
1517 
1518         self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
1519 
1520         #------------
1521 
1522         if wx.Platform == "__WXGTK__":
1523             # wxGTK requires that the window be created before you can
1524             # set its shape, so delay the call to SetWindowShape until
1525             # this event.
1526             self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
1527         else:
1528             # On wxMSW and wxMac the window has
1529             # already been created, so go for it.
1530             self.SetWindowShape()
1531 
1532         # Create an accelerator table.
1533         self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('X'), wx.ID_EXIT),
1534                                               (wx.ACCEL_CTRL, ord('A'), wx.ID_ABOUT)
1535                                              ])
1536         self.SetAcceleratorTable(self.accel_tbl)
1537 
1538 
1539     def BindEvents(self):
1540         """
1541         Bind some events to an events handler.
1542         """
1543 
1544         self.panel.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)  # View mask.
1545         self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
1546         self.panel.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow)  # Panel right clic.
1547 
1548         self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
1549         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
1550         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
1551         self.Bind(wx.EVT_MOTION, self.OnMouseMove)
1552 
1553         self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT)  # Ctrl+X.
1554         self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
1555 
1556 
1557     def DoLayout(self):
1558         """
1559         ...
1560         """
1561 
1562         sizer = wx.BoxSizer(wx.VERTICAL)
1563         sizer.Add(self.panel, 1, wx.EXPAND)
1564         self.SetSizer(sizer)
1565 
1566 
1567     def OnRoll(self, event) :
1568         """
1569         Thanks to Ray Pasco.
1570         """
1571 
1572         if not bool(self.isRolled) :
1573         # Set the flag to the state we want regardless of whether
1574         # or not it's in currently in the opposite state.
1575            self.RollUnRoll(wantToRoll=True)
1576 
1577         elif self.isRolled :   # UnRoll.
1578            # Set the flag to the state we want regardless of whether
1579            # or not it's in currently in the opposite state.
1580            self.RollUnRoll(wantToRoll=False)
1581 
1582 
1583     def RollUnRoll(self, wantToRoll) :
1584         """
1585         Thanks to Ray Pasco.
1586         """
1587 
1588         # Thanks to Ray Pasco.
1589         # Save the current size only if the Frame is not rolled up.
1590         if not bool(self.isRolled) :
1591             self.unrolledFrameClientSize_size = self.GetClientSize()
1592 
1593         if bool(wantToRoll) :   # UnRoll.
1594             # Set size (25)
1595             self.SetClientSize((self.unrolledFrameClientSize_size[0], 25))
1596             # Set to match this new state.
1597             self.isRolled = True
1598 
1599         else :   # Roll
1600             self.SetClientSize(self.unrolledFrameClientSize_size)
1601             # Set to match this new state.
1602             self.isRolled = False
1603 
1604 
1605     def OnAbout(self, event):
1606         """
1607         ...
1608         """
1609 
1610         self.dialog = MyAboutDlg(self)
1611 
1612 
1613     def SetWindowShape(self, *evt):
1614         """
1615         ...
1616         """
1617 
1618         # Use the bitmap's mask to determine the region.
1619         r = wx.Region(self.bmp)
1620         self.hasShape = self.SetShape(r)
1621 
1622 
1623     def OnEraseBackground(self, event):
1624         """
1625         ...
1626         """
1627 
1628         dc = event.GetDC()
1629         if not dc:
1630             dc = wx.ClientDC(self)
1631             rect = self.GetUpdateRegion().GetBox()
1632             dc.SetClippingRect(rect)
1633 
1634 
1635     def OnDoubleClick(self, event):
1636         """
1637         ...
1638         """
1639 
1640         if self.hasShape:
1641             self.SetShape(wx.Region())
1642             self.hasShape = False
1643         else:
1644             self.SetWindowShape()
1645 
1646 
1647     def OnLeftDown(self, event):
1648         """
1649         ...
1650         """
1651 
1652         self.CaptureMouse()
1653         x, y = self.ClientToScreen(event.GetPosition())
1654         originx, originy = self.GetPosition()
1655         dx = x - originx
1656         dy = y - originy
1657         self.delta = ((dx, dy))
1658 
1659 
1660     def OnLeftUp(self, evt):
1661         """
1662         ...
1663         """
1664 
1665         if self.HasCapture():
1666             self.ReleaseMouse()
1667 
1668 
1669     def OnMouseMove(self, event):
1670         """
1671         ...
1672         """
1673 
1674         if event.Dragging() and event.LeftIsDown():
1675             x, y = self.ClientToScreen(event.GetPosition())
1676             fp = (x - self.delta[0], y - self.delta[1])
1677             self.Move(fp)
1678 
1679 
1680     def OnIconize(self, event):
1681         """
1682         ...
1683         """
1684 
1685         self.Iconize()
1686 
1687 
1688     def OnCloseWindow(self, event):
1689         """
1690         Quit this application.
1691         """
1692 
1693         # self.Destroy()
1694         self.OnTimerOut(self)
1695 
1696         print("Exit application.")
1697 
1698 #-------------------------------------------------------------------------------
1699 
1700 class MyApp(wx.App):
1701     """
1702     Thanks to Andrea Gavana.
1703     """
1704     def OnInit(self):
1705 
1706         #------------
1707 
1708         self.locale = wx.Locale(wx.LANGUAGE_FRENCH)
1709 
1710         #------------
1711 
1712         self.SetAppName("Custom Gui 2")
1713 
1714         #------------
1715 
1716         self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
1717 
1718         #------------
1719 
1720         frame = MyFrame()
1721         self.SetTopWindow(frame)
1722         frame.Show(True)
1723 
1724         return True
1725 
1726     #---------------------------------------------------------------------------
1727 
1728     def GetInstallDir(self):
1729         """
1730         Returns the installation directory for my application.
1731         """
1732 
1733         return self.installDir
1734 
1735 
1736     def GetIconsDir(self):
1737         """
1738         Returns the icons directory for my application.
1739         """
1740 
1741         icons_dir = os.path.join(self.installDir, "icons")
1742         return icons_dir
1743 
1744 
1745     def GetBitmapsDir(self):
1746         """
1747         Returns the bitmaps directory for my application.
1748         """
1749 
1750         bitmaps_dir = os.path.join(self.installDir, "bitmaps")
1751         return bitmaps_dir
1752 
1753 #-------------------------------------------------------------------------------
1754 
1755 def main():
1756     app = MyApp(False)
1757     app.MainLoop()
1758 
1759 #-------------------------------------------------------------------------------
1760 
1761 if __name__ == "__main__" :
1762     main()


Download source

source.zip


Additional Information

Link :

https://hasenj.wordpress.com/2009/04/14/making-a-fancy-window-in-wxpython/

https://fooobar.com/questions/15910813/wxpython-change-the-headers-color

https://stackoverflow.com/questions/17479254/panel-doesnt-fully-refresh-when-using-a-custom-background-in-wxpython

https://stackoverflow.com/questions/12087140/custom-window-frame-and-window-appearance-with-wxpython

https://github.com/Metallicow/MCOW

https://github.com/Eseeme/wxpython-custom-button

- - - - -

https://wiki.wxpython.org/TitleIndex

https://docs.wxpython.org/


Thanks to

Robin Dunn, Cody Precord, Andrea Gavana, Metallicow, Mike Driscoll, Ray Pasco, Pascal Faut., Vegaseat (DaniWeb), Jan Bodnar (ZetCode), Alain Delgrange, Daniel Ramos, ActiveState, the wxPython community...

Thanks also to all known contributors or anonymous that I forgot.

And finally, congratulations to the many forums and blogs for all the available examples and the help which is the strength of wxPython. ;)


About this page

Date (d/m/y) Person (bot) Comments :

10/10/18 - Ecco (Created page for wxPython Phoenix).


Comments

- blah, blah, blah....

How to create a customized frame - Part 1 (Phoenix) (last edited 2021-05-08 12:49:56 by Ecco)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.