= How to create a customized frame - Part 2 (Phoenix) =
'''Keywords :''' Shaped frame, Customized frame, Customized button, Transparency, Roll, Unroll, Fade in, Fade out, Shape, Region, BufferedPaintDC, BufferedDC, ClientDC, GCDC, AutoBufferedPaintDCFactory, Config,  AcceleratorTable.

<<TableOfContents>>

--------
= Demonstrating (only Windows) : =
__'''''Tested''' py3.x, wx4.x and Win10. ''__

Are you ready to use some samples ? ;)

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

--------
== Frame with resize border and colored panel : ==
=== First example ===
{{attachment:img_sample_one.png}}

{{{#!python
# sample_one.py

import sys
import os
import platform
import wx
import wx.lib.fancytext as fancytext
import wx.lib.agw.flatmenu as FM
from   wx.lib.agw.artmanager import ArtManager, RendererBase, DCSaver
from   wx.lib.agw.fmresources import ControlFocus, ControlPressed
import wx.dataview as dv
import wx.lib.colourdb
import rectshapedbitmapbuttonOne as SBB
import data

musicdata = sorted(data.musicdata.items())
musicdata = [[str(k)] + list(v) for k,v in musicdata]

# def SwitchRGBtoBGR
# def CreateBackgroundBitmap
# class MyMenuRenderer
# class MyListCtrlPnl
# class MyStatusBar
# class MyTitleBar
# class MyAboutDlg
# class MyPopupMenu
# class MyWindow
# class MyButtonBox
# class MyTitleBarPnl
# class MyMainPnl
# class MyFrame
# class MyApp

ID_FULLSCREEN = wx.NewIdRef()
ID_MAIN_PNL = wx.NewIdRef()
ID_BTN_FULLSCREEN = wx.NewIdRef()
ID_BTN_ABOUT = wx.NewIdRef()
ID_BTN_QUIT = wx.NewIdRef()
ID_HELLO = wx.NewIdRef()

#---------------------------------------------------------------------------

def SwitchRGBtoBGR(colour):
    """
    ...
    """

    return wx.Colour(colour.Blue(), colour.Green(), colour.Red())

#---------------------------------------------------------------------------

def CreateBackgroundBitmap():
    """
    ...
    """

    mem_dc = wx.MemoryDC()
    bmp = wx.Bitmap(121, 300)
    mem_dc.SelectObject(bmp)

    mem_dc.Clear()

    # Colour the menu face with background colour.
    mem_dc.SetPen(wx.Pen("#a0a0a0", 0))
    mem_dc.SetBrush(wx.Brush("#fc8787"))
    mem_dc.DrawRectangle(0, 15, 121, 300)
    mem_dc.DrawLine(0, 0, 300, 0)

    mem_dc.SelectObject(wx.NullBitmap)
    return bmp

#---------------------------------------------------------------------------

class MyMenuRenderer(FM.FMRenderer):
    """
    Thanks to Andrea Gavana.
    A custom renderer class for FlatMenu.
    """
    def __init__(self):
        FM.FMRenderer.__init__(self)

    #-----------------------------------------------------------------------

    def DrawMenuButton(self, dc, rect, state):
        """
        Draws the highlight on a FlatMenu.
        """

        self.DrawButton(dc, rect, state)


    def DrawMenuBarButton(self, dc, rect, state):
        """
        Draws the highlight on a FlatMenuBar.
        """

        self.DrawButton(dc, rect, state)


    def DrawButton(self, dc, rect, state, colour=None):
        """
        ...
        """

        if state == ControlFocus:
            penColour = wx.Colour(wx.BLACK)
            brushColour = wx.Colour("yellow")
        elif state == ControlPressed:
            penColour = wx.Colour(wx.BLACK)
            brushColour = wx.Colour("yellow")
        else:   # ControlNormal, ControlDisabled, default.
            penColour = wx.Colour(wx.BLACK)
            brushColour = wx.Colour("yellow")

        # Draw the button borders.
        dc = wx.GCDC(dc)
        dc.SetPen(wx.Pen(penColour, 1))
        dc.SetBrush(wx.Brush(brushColour))
        dc.DrawRoundedRectangle(rect.x, rect.y, rect.width, rect.height-1, 3)


    def DrawMenuBarBackground(self, dc, rect):
        """
        ...
        """

        # For office style, we simple draw a rectangle
        # with a gradient colouring.
        vertical = ArtManager.Get().GetMBVerticalGradient()

        dcsaver = DCSaver(dc)

        # Fill with gradient.
        startColour = self.menuBarFaceColour
        endColour   = ArtManager.Get().LightColour(startColour, 0)

        dc.SetPen(wx.Pen(endColour))
        dc.SetBrush(wx.Brush(endColour))
        dc.DrawRectangle(rect)


    def DrawToolBarBg(self, dc, rect):
        """
        ...
        """

        if not ArtManager.Get().GetRaiseToolbar():
            return

        # Fill with gradient.
        startColour = self.menuBarFaceColour()
        dc.SetPen(wx.Pen(startColour))
        dc.SetBrush(wx.Brush(startColour))
        dc.DrawRectangle(0, 0, rect.GetWidth(), rect.GetHeight())

#---------------------------------------------------------------------------

class MyListCtrlPnl(wx.Panel):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        # Create the listctrl.
        self.dvlc = dv.DataViewListCtrl(self,
                                        style=wx.BORDER_SIMPLE|
                                              dv.DV_ROW_LINES|
                                              dv.DV_HORIZ_RULES|
                                              dv.DV_VERT_RULES)

        # Give it some columns.
        # The ID col we'll customize a bit :
        self.dvlc.AppendTextColumn("Id", width=40)
        self.dvlc.AppendTextColumn("Artist", width=170)
        self.dvlc.AppendTextColumn("Title", width=260)
        self.dvlc.AppendTextColumn("Genre", width=80)

        # Load the data. Each item (row) is added as a sequence
        # of values whose order matches the columns.
        for itemvalues in musicdata:
            self.dvlc.AppendItem(itemvalues)

        self.dvlc.SetBackgroundColour("gray30")
        self.dvlc.SetForegroundColour("gray99")

        # Set the layout so the listctrl fills the panel.
        self.Sizer = wx.BoxSizer()
        self.Sizer.Add(self.dvlc, 1, wx.EXPAND)

#---------------------------------------------------------------------------

class MyStatusBar(wx.StatusBar) :
    """
    Thanks to ???.
    Simple custom colorized StatusBar.
    """
    def __init__(self, parent, id) :
        wx.StatusBar.__init__(self, parent, id)

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        # Read config file.
        self.SetBackgroundColour(wx.Colour(self.config.Read("Color1")))


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_PAINT, self.OnPaint)


    def OnPaint(self, event) :
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        self.Draw(dc)


    def Draw(self, dc) :
        """
        ...
        """

        # Read config file.
        dc.SetBackground(wx.Brush(self.config.Read("Color1")))
        dc.Clear()

        textVertOffset = 3      # Perfect for MSW.
        textHorzOffset = 5      # Arbitrary - looks nicer.

        dc.SetTextForeground("white")
        dc.DrawText(self.GetStatusText(), textHorzOffset, textVertOffset)

#---------------------------------------------------------------------------

class MyTitleBar(wx.Control):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, label, size):
        style = (wx.BORDER_NONE)
        super(MyTitleBar, self).__init__(parent,
                                         style=style)

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()

        #------------

        # Attributes.
        self.parent = parent
        self.label = label
        self.size = size

        #------------

        # Simplified init method.
        self.SetBackground()
        self.SetProperties(label, size)
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetBackground(self):
        """
        ...
        """

        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)


    def SetProperties(self, label, size):
        """
        ...
        """

        self.label = label
        self.size = size

        self.label_font = self.GetFont()
        self.label_font.SetFamily(wx.SWISS)
        self.label_font.SetPointSize(size)
        self.label_font.SetWeight(wx.BOLD)
        self.SetFont(self.label_font)


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetSize()
        w1, h1 = self.GetClientSize()

        #------------

        # Load an icon bitmap for titlebar.
        # bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
        #                              "icon_app.png"),
        #                 type=wx.BITMAP_TYPE_PNG)

        # self.ico = wx.StaticBitmap(self, -1, bmp)
        # self.ico.SetBackgroundColour(wx.Colour(self.config.Read("Color1")))
        # self.ico.SetPosition((300, 1))
        # self.ico.SetToolTip("This is a customized icon.")
        # self.ico.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        # self.ico.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
        # self.ico.Bind(wx.EVT_LEFT_DOWN, self.OnRightDown)

        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)


    def OnRightDown(self, event):
        """
        ...
        """

        self.PopupMenu(MyPopupMenu(self), event.GetPosition())

        print("Right down.")


    def OnLeftDown(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnLeftDown(event)


    def OnLeftUp(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnLeftUp(event)


    def SetLabel(self, label):
        """
        ...
        """

        self.label = label
        self.Refresh()


    def DoGetBestSize(self):
        """
        ...
        """

        dc = wx.ClientDC(self)
        dc.SetFont(self.GetFont())

        textWidth, textHeight = dc.GetTextExtent(self.label)
        spacing = 10
        totalWidth = textWidth + (spacing)
        totalHeight = textHeight + (spacing)

        best = wx.Size(totalWidth, totalHeight)
        self.CacheBestSize(best)

        return best


    def GetLabel(self):
        """
        ...
        """

        return self.label


    def GetLabelColor(self):
        """
        ...
        """

        return self.foreground


    def GetLabelSize(self):
        """
        ...
        """

        return self.size


    def SetLabelColour(self, colour):
        """
        ...
        """

        self.labelColour = colour


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        gcdc = wx.GCDC(dc)

        gcdc.Clear()

        # Setup the GraphicsContext.
        gc = gcdc.GetGraphicsContext()

        # Get the working size we can draw in.
        width, height = self.GetSize()

        # Use the GCDC to draw the text.
        # Read config file.
        brush = self.config.Read("Color1")
        gcdc.SetPen(wx.Pen(brush, 1))
        gcdc.SetBrush(wx.Brush(brush))
        gcdc.DrawRectangle(0, 0, width, height)

        # Get the system font.
        gcdc.SetFont(self.GetFont())

        textWidth, textHeight = gcdc.GetTextExtent(self.label)
        tposx, tposy = ((width/2)-(textWidth/2), (height/3)-(textHeight/3))

        tposx += 0
        tposy += 0

        # Set position and text color.
        gcdc.SetTextForeground("black")
        gcdc.DrawText(self.label, int(tposx), int(tposy+1))

        gcdc.SetTextForeground(self.labelColour)
        gcdc.DrawText(self.label, int(tposx), int(tposy))

#---------------------------------------------------------------------------

class MyAboutDlg(wx.Frame):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        style = (wx.FRAME_SHAPED | wx.NO_BORDER |
                 wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
                 wx.SYSTEM_MENU | wx.CLOSE_BOX |
                 wx.NO_FULL_REPAINT_ON_RESIZE)
        wx.Frame.__init__(self,
                          parent,
                          id=-1,
                          title="About...",
                          style=style)

        #------------

        # Attributes.
        self.SetTransparent(0)
        self.opacity_in = 0
        self.opacity_out = 255
        self.deltaN = -70
        self.hasShape = False
        self.delta = wx.Point(0,0)

        #------------

        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
        # Return icons folder.
        self.icons_dir = wx.GetApp().GetIconsDir()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.OnTimerIn(self)
        self.CreateCtrls()
        self.BindEvents()

        #------------

        self.CenterOnParent(wx.BOTH)
        self.GetParent().Enable(False)

        #------------

        self.Show(True)

        #------------

        self.eventLoop = wx.GUIEventLoop()
        self.eventLoop.Run()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        Set the dialog properties (title, icon, transparency...).
        """

        frameIcon = wx.Icon(os.path.join(self.icons_dir,
                                         "icon_wxWidgets.ico"),
                            type=wx.BITMAP_TYPE_ICO)
        self.SetIcon(frameIcon)


    def OnTimerIn(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer1 = wx.Timer(self, -1)
        self.timer1.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)

        print("Fade-in was launched.")


    def OnTimerOut(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer2 = wx.Timer(self, -1)
        self.timer2.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)

        print("Fade-out was launched.")


    def AlphaCycle1(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_in += self.deltaN
        if self.opacity_in <= 0:
            self.deltaN = -self.deltaN
            self.opacity_in = 0

        if self.opacity_in >= 255:
            self.deltaN = -self.deltaN
            self.opacity_in = 255

            self.timer1.Stop()

        self.SetTransparent(self.opacity_in)

        print("Fade in = {}/255".format(self.opacity_in))


    def AlphaCycle2(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_out += self.deltaN
        if self.opacity_out >= 255:
            self.deltaN = -self.deltaN
            self.opacity_out = 255

        if self.opacity_out <= 0:
            self.deltaN = -self.deltaN
            self.opacity_out = 0

            self.timer2.Stop()

            wx.CallAfter(self.Destroy)

        self.SetTransparent(self.opacity_out)

        print("Fade out = {}/255".format(self.opacity_out))


    def CreateCtrls(self):
        """
        Make widgets for my dialog.
        """

        # Load a background bitmap.
        self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "skin_about_4.png"),
                             type=wx.BITMAP_TYPE_PNG)
        mask = wx.Mask(self.bmp, wx.RED)
        self.bmp.SetMask(mask)

        #------------

        self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))

        #------------

        if wx.Platform == "__WXGTK__":
            # wxGTK requires that the window be created before you can
            # set its shape, so delay the call to SetWindowShape until
            # this event.
            self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        else:
            # On wxMSW and wxMac the window has already
            # been created, so go for it.
            self.SetWindowShape()


    def BindEvents(self):
        """
        Bind all the events related to my dialog.
        """

        # Bind some events to an events handler.
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow)  # Panel right clic.
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)


    def SetWindowShape(self, event=None):
        """
        ...
        """

        # Use the bitmap's mask to determine the region.
        r = wx.Region(self.bmp)
        self.hasShape = self.SetShape(r)


    def OnEraseBackground(self, event):
        """
        ...
        """

        dc = event.GetDC()
        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)


    def OnLeftDown(self, event):
        """
        ...
        """

        self.CaptureMouse()
        x, y = self.ClientToScreen(event.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))


    def OnLeftUp(self, evt):
        """
        ...
        """

        if self.HasCapture():
            self.ReleaseMouse()


    def OnMouseMove(self, event):
        """
        ...
        """

        if event.Dragging() and event.LeftIsDown():
            x, y = self.ClientToScreen(event.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            self.Move(fp)


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.AutoBufferedPaintDCFactory(self)
        dc.DrawBitmap(self.bmp, 0, 0, True)

        #------------

        # These are strings.
        py_version = sys.version.split()[0]

        str1 = (('<font style="normal" family="default" color="orange" size="10" weight="bold">'
                 'Programming : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 'Python {}</font>').format(py_version))   # Python 3.7.2

        str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
                 'GUI toolkit : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 'wxPython {}</font>').format(wx.VERSION_STRING))  # wxPython 4.0.4  wx.VERSION_STRING

        str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
                 'Library : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 '{}</font>').format(wx.GetLibraryVersionInfo().VersionString))   # wxWidgets 3.0.5

        str4 = (('<font style="normal" family="default" color="blue" size="10" weight="bold">'
                 'Operating system : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 '{}</font>').format(platform.system()))   # Windows

        str5 = (('<font style="normal" family="default" color="darkgreen" size="9" weight="normal">'
                 '{}</font>').format(self.app_name))   # Custom Gui 3

        str6 = (('<font style="normal" family="default" color="Black" size="8" weight="normal">'
                 'Right clic or Esc for Exit</font>'))

        #------------

        # Get the working size we can draw in.
        bw, bh = self.GetSize()

        # Use the GCDC to draw the text.
        dc.GradientFillLinear((0, 0, bw, bh),
                               "gray",
                               wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENU),
                               wx.NORTH)

        # Draw the about borders.
        dc.SetPen(wx.Pen(wx.Colour(0, 0, 0), 5))
        # dc.SetBrush(wx.Brush(wx.Colour(150, 150, 150)))
        # or
        dc.SetBrush(wx.Brush(wx.TRANSPARENT_BRUSH))
        dc.DrawRectangle(0, 0, bw, bh)

        #------------
        # Draw text.
        # Need width to calculate x position of str1.
        tw, th = fancytext.GetExtent(str1, dc)
        # Centered text.
        fancytext.RenderToDC(str1, dc, (bw-tw)/2, 30)

        #------------

        # Need width to calculate x position of str2.
        tw, th = fancytext.GetExtent(str2, dc)
        # Centered text.
        fancytext.RenderToDC(str2, dc, (bw-tw)/2, 50)

        #------------

        # Need width to calculate x position of str3.
        tw, th = fancytext.GetExtent(str3, dc)
        # Centered text.
        fancytext.RenderToDC(str3, dc, (bw-tw)/2, 70)

        #------------

        # Need width to calculate x position of str4.
        tw, th = fancytext.GetExtent(str4, dc)
        # Centered text.
        fancytext.RenderToDC(str4, dc, (bw-tw)/2, 90)

        #------------

        # Need width to calculate x position of str5.
        tw, th = fancytext.GetExtent(str5, dc)
        # Centered text.
        fancytext.RenderToDC(str5, dc, (bw-tw)/2, 130)

        #------------

        # Need width to calculate x position of str6.
        tw, th = fancytext.GetExtent(str6, dc)
        # Centered text.
        fancytext.RenderToDC(str6, dc, (bw-tw)/2, 195)


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_ESCAPE:
            self.OnCloseWindow(event)

        event.Skip()


    def OnCloseWindow(self, event):
        """
        ...
        """

        self.GetParent().Enable(True)
        self.eventLoop.Exit()
        #self.Destroy()
        self.OnTimerOut(self)

#---------------------------------------------------------------------------

class MyPopupMenu(wx.Menu):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        wx.Menu.__init__(self)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Returns bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Simplified init method.
        self.CreatePopupMenu()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def CreatePopupMenu(self, event=None):
        """
        This method is called by the base class when it needs to popup
        the menu for the default EVT_RIGHT_DOWN event.  Just create
        the menu how you want it and return it from this function,
        the base class takes care of the rest.
        """

        bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                     "item_about.png"),
                        type=wx.BITMAP_TYPE_PNG)

        item = wx.MenuItem(self, id=wx.ID_ABOUT, text=" About")
        item.SetBitmap(bmp)
        self.Append(item)
        self.AppendSeparator()

        #------------

        bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                     "item_exit.png"),
                        type=wx.BITMAP_TYPE_PNG)

        if True or "__WXMSW__" in wx.PlatformInfo:
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            font.SetWeight(wx.BOLD)

        item = wx.MenuItem(self, id=wx.ID_EXIT, text=" Exit")
        item.SetBitmap(bmp)
        item.SetFont(font)
        self.Append(item)

        return self


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        # Bind the menu events to an events handler.
        self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT)


    def OnAbout(self, event):
        """
        ...
        """

        self.mainFrame = wx.GetApp().GetTopWindow()
        self.mainFrame.OnAbout(self)

        print("About icon was clicked.")


    def OnClose(self, event):
        """
        ...
        """

        self.mainFrame = wx.GetApp().GetTopWindow()
        self.mainFrame.OnCloseWindow(self)

        print("Close icon was clicked.")

#---------------------------------------------------------------------------

class MyWindow(wx.Control):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, label,
                 foreground, background,
                 normal, pressed=None):
        style = (wx.BORDER_NONE)
        super(MyWindow, self).__init__(parent,
                                       -1,
                                       style=style)

        #------------

        # Attributes.
        self.label = label
        self.foreground = foreground
        self.background = background

        if wx.Platform == "__WXGTK__":
            self.color = "#9e9d9d"

        else:
            self.color = "#b1b1b0"

        self.normal = normal
        self.pressed = pressed

        self._clicked = False

        #------------

        self.region = wx.Region(normal, wx.Colour(0, 0, 0, 0))

        #------------

        # Simplified init method.
        self.SetProperties(label, foreground, background)
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self, label, foreground, background):
        """
        ...
        """

        self.label = label
        self.foreground = foreground
        self.background = background
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
        self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDclick)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMotion)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)


    def SetLabel(self, label):
        """
        ...
        """

        self.label = label
        self.Refresh()


    def DoGetBestSize(self):
        """
        ...
        """

        return self.normal.GetSize()


    def GetLabel(self):
        """
        ...
        """

        return self.label


    def GetLabelColor(self):
        """
        ...
        """

        return self.foreground


    def Enable(self, *args, **kwargs):
        """
        ...
        """

        super(MyWindow, self).Enable(*args, **kwargs)
        self.Refresh()


    def Disable(self, *args, **kwargs):
        """
        ...
        """

        super(MyWindow, self).Disable(*args, **kwargs)
        self.Refresh()


    def PostEvent(self):
        """
        ...
        """

        event = wx.CommandEvent()
        event.SetEventObject(self)
        event.SetEventType(wx.EVT_BUTTON.typeId)
        wx.PostEvent(self, event)


    def OnSize(self, event):
        """
        ...
        """

        event.Skip()
        self.Refresh()


    def GetBackground(self):
        """
        ...
        """

        return self.background


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        dc.Clear()
        gcdc = wx.GCDC(dc)

        # Set the background color.
        if wx.Platform == "__WXGTK__":
            gcdc.SetBackground(wx.Brush("grey55"))
        else:
            gcdc.SetBackground(wx.Brush(self.background))

        gcdc.Clear()

        # Get the working rectangle we can draw in.
        rect = self.GetClientRect()

        # Font size and style.
        fontSize = self.GetFont().GetPointSize()

        if wx.Platform == "__WXGTK__":
            boldFont = wx.Font(fontSize-1, wx.DEFAULT,
                               wx.NORMAL, wx.NORMAL, False, "")
        else:
            boldFont = wx.Font(fontSize+2, wx.DEFAULT,
                               wx.NORMAL, wx.BOLD, False, "")

        if wx.Platform == "__WXMSW__":
            pen = wx.Pen(self.color, 1, wx.SOLID)

        else:
            pen = wx.Pen(self.color, 1, wx.SOLID)

        gcdc.SetPen(pen)

        x, y = self.GetSize()
        # x, y , width, height, radius
        gcdc.DrawRoundedRectangle (0, 0, 71, 25, 3)

        bitmap = self.normal

        w, h = bitmap.GetWidth(), bitmap.GetHeight()

        if self.clicked:
            bitmap = self.pressed or bitmap
        if not self.IsEnabled():
            bitmap = self.normal or bitmap

        # Draw a bitmap with an alpha channel.
        # image, x, y, transparency.
        dc.DrawBitmap(bitmap, 0, 0, True)

        if wx.Platform == "__WXGTK__":
            # Add the Caption.
            # White text - Shadow.
            rect = wx.Rect(rect.x, rect.y+3,
                           rect.width, 22)

        else:
            rect = wx.Rect(rect.x, rect.y+3,
                           rect.width, 20)

        dc.SetFont(boldFont)
        dc.SetTextForeground(wx.WHITE)
        dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)

        if wx.Platform == "__WXGTK__":
            # Add the Caption.
            # Black text.
            rect = wx.Rect(rect.x, rect.y,
                           rect.width, 21)

        else:
            rect = wx.Rect(rect.x, rect.y,
                           rect.width, 19)

        gcdc.SetFont(boldFont)
        # Get the text color.
        dc.SetTextForeground(self.foreground)
        dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)


    def SetClicked(self, clicked):
        """
        ...
        """

        if clicked != self._clicked:
            self._clicked = clicked
            self.Refresh()


    def GetClicked(self):
        """
        ...
        """

        return self._clicked


    clicked = property(GetClicked, SetClicked)
    def OnLeftDown(self, event):
        """
        ...
        """

        x, y = event.GetPosition()
        if self.region.Contains(x, y):
            self.clicked = True
            self.SetFocus()


    def OnLeftDclick(self, event):
        """
        ...
        """

        self.OnLeftDown(event)


    def OnLeftUp(self, event):
        """
        ...
        """

        if self.clicked:
            x, y = event.GetPosition()
            if self.region.Contains(x, y):
                self.PostEvent()
        self.clicked = False


    def OnMotion(self, event):
        """
        ...
        """

        if self.clicked:
            x, y = event.GetPosition()
            if not self.region.Contains(x, y):
                self.clicked = False


    def OnLeave(self, event):
        """
        ...
        """

        self.clicked = False


    def OnSetFocus(self, event):
        """
        ...
        """

        self.color = "white"
        self.Refresh()


    def OnKillFocus(self, event):
        """
        ...
        """

        if wx.Platform == "__WXGTK__":
            self.color = "#9e9d9d"

        else:
            self.color = "#b1b1b0"

        self.Refresh()


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_SPACE:
            self.PostEvent()
            return

        elif event.GetKeyCode() == wx.WXK_ESCAPE:
            self.GetTopLevelParent().OnCloseWindow(True)

        event.Skip()

#---------------------------------------------------------------------------

class MyButtonBox(wx.Panel):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, caption):
        style = (wx.NO_BORDER | wx.TAB_TRAVERSAL)
        super(MyButtonBox, self).__init__(parent,
                                          style=style)

        #------------

        # Attributes.
        self._caption = caption

        #------------

        # Simplified init method.
        self.DoLayout()

    #-----------------------------------------------------------------------

    def DoLayout(self):
        """
        ...
        """

        self._csizer = wx.BoxSizer(wx.VERTICAL)
        msizer = wx.BoxSizer(wx.HORIZONTAL)
        msizer.Add(self._csizer, 0 )
        self.SetSizer(msizer)


    def DoGetBestSize(self):
        """
        ...
        """

        size = super(MyButtonBox, self).DoGetBestSize()

        # Compensate for wide caption labels.
        tw = self.GetTextExtent(self._caption)[0]
        size.SetWidth(max(size.width, size.height))
        return size


    def AddItem(self, item):
        """
        Add a window or sizer item to the MyButtonBox.
        """

        self._csizer.Add(item, 0 )

#---------------------------------------------------------------------------

class MyTitleBarPnl(wx.Panel):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, id, size):
        style = (wx.NO_BORDER)
        super(MyTitleBarPnl, self).__init__(parent,
                                            id,
                                            size=size,
                                            style=style)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.CreateCtrls()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        # Read config file.
        self.SetBackgroundColour(wx.Colour(self.config.Read("Color1")))


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyTitleBarPnl :", self.GetClientSize())

        #------------
        #------------

        # Add titleBar.
        self.titleBar = MyTitleBar(self,
                                   label=self.app_name,
                                   size=10)
        self.titleBar.SetPosition((0, 0))
        self.titleBar.SetSize((w, 24))
        self.titleBar.SetLabelColour("white")
        self.titleBar.SetToolTip("This is a customized title bar.")

        #------------
        #------------

        # Gloss Buttons box (titleBar).
        self.box3 = MyButtonBox(self.titleBar, "")   # Button Exit.
        self.box4 = MyButtonBox(self.titleBar, "")   # Button Maximize.
        self.box5 = MyButtonBox(self.titleBar, "")   # Button Reduce.
        self.box6 = MyButtonBox(self.titleBar, "")   # Button Roll.

        # Gloss Buttons bitmap.
        bmpa = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_exit_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpb = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_exit_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpc = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_maximize_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpd = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_maximize_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpe = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_reduce_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpf = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_reduce_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_roll_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmph = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_roll_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        self.btn3 = MyWindow(self.box3, "", "black", "#9e9d9d", bmpa, bmpb)
        self.btn3.SetToolTip("This is a customized gloss button.")

        self.btn4 = MyWindow(self.box4, "", "black", "#9e9d9d", bmpc, bmpd)
        self.btn4.SetToolTip("This is a customized gloss button.")

        self.btn5 = MyWindow(self.box5, "", "black", "#9e9d9d", bmpe, bmpf)
        self.btn5.SetToolTip("This is a customized gloss button.")

        self.btn6 = MyWindow(self.box6, "", "black", "#9e9d9d", bmpg, bmph)
        self.btn6.SetToolTip("This is a customized gloss button.")

        self.box3.AddItem(self.btn3)
        self.box4.AddItem(self.btn4)
        self.box5.AddItem(self.btn5)
        self.box6.AddItem(self.btn6)

        #------------
        #------------

        w, h = self.GetSize()

        #------------

        self.box3.SetSize((25, 19))
        x1, y1 = self.box3.GetSize()
        self.box3.SetPosition((x1-18, h-6-y1))

        #------------

        self.box4.SetSize((25, 19))
        self.box4.SetPosition(((x1*2)-18, h-6-y1))

        #------------

        self.box5.SetSize((25, 19))
        self.box5.SetPosition(((x1*3)-18, h-6-y1))

        #------------

        self.box6.SetSize((25, 19))
        self.box6.SetPosition(((x1*4)-18, h-6-y1))


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)
        self.btn4.Bind(wx.EVT_BUTTON, self.OnFullScreen)
        self.btn5.Bind(wx.EVT_BUTTON, self.OnIconfiy)
        self.btn6.Bind(wx.EVT_BUTTON, self.OnRoll)

        self.Bind(wx.EVT_SIZE, self.OnResize)


    def OnResize(self, event):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyTitleBarPnl :", self.GetClientSize())

        #------------
        #------------

        self.titleBar.SetSize((w, 24))

        #------------

        x1, y1 = self.box3.GetSize()

        self.box3.SetPosition((x1-18, h-6-y1))
        self.box4.SetPosition(((x1*2)-18, h-6-y1))
        self.box5.SetPosition(((x1*3)-18, h-6-y1))
        self.box6.SetPosition(((x1*4)-18, h-6-y1))

        #------------

        self.Refresh()

        print("On resize was clicked.")


    def OnRoll(self, event):
        """
        ...
        """

        self.GetParent().OnRoll(True)

        print("Roll/unRoll button was clicked.")


    def OnIconfiy(self, event):
        """
        ...
        """

        self.GetParent().OnIconfiy(self)

        print("Iconfiy button was clicked.")


    def OnFullScreen(self, event):
        """
        ...
        """

        self.GetParent().OnFullScreen(self)

        print("FullScreen button was clicked.")


    def OnBtnClose(self, event):
        """
        ...
        """

        self.GetParent().OnCloseWindow(self)

        print("Close button was clicked.")

#---------------------------------------------------------------------------

class MyMainPnl(wx.Panel):
    """
    ...
    """
    def __init__(self, parent, id, size):
        style = (wx.NO_BORDER | wx.TAB_TRAVERSAL)
        super(MyMainPnl, self).__init__(parent,
                                        id=ID_MAIN_PNL,
                                        size=size,
                                        style=style)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Colourdb.
        wx.lib.colourdb.updateColourDB()

        # Create a colour list from the colourdb database.
        self.colour_list = wx.lib.colourdb.getColourList()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.CreateCtrls()
        self.DoLayout()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        if wx.Platform == "__WXMSW__":
            self.SetDoubleBuffered(True)

        # Read config file.
        self.SetBackgroundColour(self.config.Read("Color1"))


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyMainPnl :", self.GetClientSize())

        #------------
        #------------

        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

        #------------
        #------------

        # Create data view control.
        self.list = MyListCtrlPnl(self)

        #------------
        #------------

        self.txt = wx.StaticText(self,
                                 -1,
                                 label="Hello World !")
        self.txt.SetForegroundColour("BLACK")
        self.txt.SetFont(font)

        #------------
        #------------

        # Thanks to MCOW.
        # Button Fullscreen.
        self.btn1 = SBB.ShapedBitmapButton(self, ID_BTN_FULLSCREEN,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="Fullscreen",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        self.btn1.SetFocus() # Necessary for Linux.

        #------------

        # Button About.
        self.btn2 = SBB.ShapedBitmapButton(self, ID_BTN_ABOUT,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="About",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------

        # Button Quit.
        self.btn3 = SBB.ShapedBitmapButton(self, ID_BTN_QUIT,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="Quit",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------
        #------------

        self.line = wx.StaticLine(self, -1,
                                  pos=(0, 70),
                                  size=(-1, -1),
                                  style=wx.LI_HORIZONTAL)

        #------------
        #------------

        # Create a choice widget.
        self.choice = wx.Choice(self,
                                -1,
                                pos=(-1, -1),
                                size=(131, -1),
                                choices=self.colour_list,
                                style=wx.CB_SORT)

        # Select item 35 in choice list to show.
        # self.choice.SetSelection(35)  # BROWN1
        # Read config file.
        self.choice.SetSelection(self.config.ReadInt("Item1"))

        item = self.choice.GetCurrentSelection()
        bgcolour = self.choice.GetStringSelection()
        print("Item : %s , %s" % (item, bgcolour))


    def DoLayout(self):
        """
        ...
        """

        txtSizer = wx.BoxSizer(wx.VERTICAL)
        txtSizer.Add(self.txt, 0, wx.LEFT, 10)

        sizerList = wx.BoxSizer(wx.VERTICAL)
        sizerList.Add(self.list, 1,
                      wx.LEFT|wx.TOP|wx.BOTTOM|
                      wx.EXPAND|wx.ALIGN_TOP, 10)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(txtSizer, 0, wx.BOTTOM, 0)
        sizer.Add(self.btn1, 1, wx.ALL, 10)
        sizer.Add(self.btn2, 1, wx.ALL, 10)
        sizer.Add(self.line, 0, wx.EXPAND|wx.ALL, 10)
        sizer.Add(self.choice, 0, wx.ALL, 10)
        sizer.Add(self.btn3, 1, wx.ALL, 10)

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(sizerList, 1,
                      wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5)
        mainSizer.Add(sizer, 0, wx.ALIGN_BOTTOM|wx.ALL, 5)

        self.SetSizer(mainSizer)
        self.Layout()


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_CHOICE, self.OnChoice)

        self.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_MAIN_PNL)
        self.btn1.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_FULLSCREEN)
        self.btn2.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_ABOUT)
        self.btn3.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_QUIT)

        self.btn1.Bind(wx.EVT_BUTTON, self.OnFullScreen)
        self.btn2.Bind(wx.EVT_BUTTON, self.OnAbout)
        self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)


    def OnInfo(self, event):
        """
        ...
        """

        event_id = event.GetId()

        if event_id == ID_MAIN_PNL:
            self.GetParent().SetStatusText(text="Hello world !")

        elif event_id == ID_BTN_FULLSCREEN:
            self.GetParent().SetStatusText(text="Fullscreen")

        elif event_id == ID_BTN_ABOUT:
            self.GetParent().SetStatusText(text="About")

        elif event_id == ID_BTN_QUIT:
            self.GetParent().SetStatusText(text="Quit the program")

        else:
            # Tell the event system to continue
            # looking for an event handler, so the
            # default handler will get called.
            event.Skip()


    def OnChoice(self, event):
        """
        ...
        """

        item = event.GetSelection()
        bgcolour = self.choice.GetStringSelection()
        print("New item : %s , %s" % (item, bgcolour))

        # Change colour of the panel to the selected colour...
        self.SetBackgroundColour(bgcolour)

        frame = self.GetTopLevelParent()
        frame.SetBackgroundColour(bgcolour)

        # Write config file.
        self.config.WriteInt("Item1", self.choice.GetCurrentSelection())
        self.config.Write("Color1", self.choice.GetStringSelection())
        self.config.Flush()

        self.Refresh()

        print("OnChoice button was clicked.")


    def OnAbout(self, event):
        """
        ...
        """

        self.GetParent().OnAbout(self)

        print("FullScreen button was clicked.")


    def OnFullScreen(self, event):
        """
        ...
        """

        self.GetParent().OnFullScreen(self)

        print("FullScreen button was clicked.")


    def OnBtnClose(self, event):
        """
        ...
        """

        self.GetParent().OnCloseWindow(self)

        print("Close button was clicked.")

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self):
        style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
                 wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
                 wx.RESIZE_BORDER | wx.NO_FULL_REPAINT_ON_RESIZE)
        super(MyFrame, self).__init__(None,
                                      -1,
                                      title="",
                                      style=style)

        #------------

        wx.SystemOptions.SetOption("msw.remap", "0")

        #------------

        # Attributes.
        self.SetTransparent(0)
        self.opacity_in = 0
        self.opacity_out = 255
        self.deltaN = -70
        self.delta = wx.Point(0,0)

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
        # Return icons folder.
        self.icons_dir = wx.GetApp().GetIconsDir()

        #------------

        # Colourdb.
        wx.lib.colourdb.updateColourDB()

        # Create a colour list from the colourdb database.
        self.colour_list = wx.lib.colourdb.getColourList()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.OnTimerIn(self)
        self.CreateMenu()
        self.CreateStatusBar()
        self.CreateCtrls()
        self.BindEvents()
        self.DoLayout()

        #------------

        # Thanks to Ray Pasco.
        # Initialize to the current state.
        self.unrolledFrameClientSize_size = self.GetClientSize()
        self.isRolled = False

        #------------

        self.CenterOnScreen(wx.BOTH)

        #------------

        self.Show(True)

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        self.SetBackgroundColour(wx.Colour(self.config.Read("Color1")))
        self.SetTitle(self.app_name)
        self.SetClientSize((600, 380))
        self.SetMinSize((128, 82))

        #------------

        frameIcon = wx.Icon(os.path.join(self.icons_dir,
                                         "icon_wxWidgets.ico"),
                            type=wx.BITMAP_TYPE_ICO)
        self.SetIcon(frameIcon)


    def OnTimerIn(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer1 = wx.Timer(self, -1)
        self.timer1.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)

        print("Fade-in was launched.")


    def OnTimerOut(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer2 = wx.Timer(self, -1)
        self.timer2.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)

        print("Fade-out was launched.")


    def AlphaCycle1(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_in += self.deltaN
        if self.opacity_in <= 0:
            self.deltaN = -self.deltaN
            self.opacity_in = 0

        if self.opacity_in >= 255:
            self.deltaN = -self.deltaN
            self.opacity_in = 255

            self.timer1.Stop()

        self.SetTransparent(self.opacity_in)

        print("Fade in = {}/255".format(self.opacity_in))


    def AlphaCycle2(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_out += self.deltaN
        if self.opacity_out >= 255:
            self.deltaN = -self.deltaN
            self.opacity_out = 255

        if self.opacity_out <= 0:
            self.deltaN = -self.deltaN
            self.opacity_out = 0

            self.timer2.Stop()
            wx.CallAfter(self.Destroy)
            wx.Exit()

        self.SetTransparent(self.opacity_out)

        print("Fade out = {}/255".format(self.opacity_out))


    def CreateMenu(self):
        """
        ...
        """

        # FlatMenuBar.
        self.menuBar = FM.FlatMenuBar(self,
                                      wx.ID_ANY,
                                      32, 3,
                                      options=FM.FM_OPT_IS_LCD)

        # FM.StyleDefault or FM.Style2007
        # FM.StyleXP or FM.StyleVista
        self.newMyTheme = self.menuBar.GetRendererManager().AddRenderer(MyMenuRenderer())
        self.menuBar.GetRendererManager().SetTheme(self.newMyTheme)

        #------------

        # Set an icon to the exit/help menu item.
        exitImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                         "item_exit.png"),
                            type=wx.BITMAP_TYPE_PNG)

        helpImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                         "item_about.png"),
                            type=wx.BITMAP_TYPE_PNG)

        #------------
        #------------

        # File Menu.
        self.file_menu = FM.FlatMenu()

        # Create the menu items.
        item = FM.FlatMenuItem(self.file_menu,
                               ID_FULLSCREEN,
                               "&Fullscreen\tCtrl+F",
                               "Fullscreen",
                               wx.ITEM_NORMAL,
                               None)
        item.SetTextColour("black")
        self.file_menu.AppendItem(item)
        self.file_menu.AppendSeparator()


        item = FM.FlatMenuItem(self.file_menu,
                               wx.ID_EXIT,
                               "&Quit\tCtrl+Q",
                               "Quit the program",
                               wx.ITEM_NORMAL,
                               None,
                               exitImg)
        # Demonstrate how to set custom font
        # and text colour to a FlatMenuItem.
        item.SetFont(wx.Font(-1, wx.FONTFAMILY_DEFAULT,
                             wx.FONTSTYLE_NORMAL,
                             wx.FONTWEIGHT_BOLD,
                             False, ""))
        item.SetTextColour("#d34725")

        self.file_menu.AppendItem(item)

        #------------

        # Add Create background bitmap.
        self.file_menu.SetBackgroundBitmap(CreateBackgroundBitmap())

        #------------
        #------------

        # Help Menu.
        self.help_menu = FM.FlatMenu()

        # Create the menu items.
        item = FM.FlatMenuItem(self.help_menu,
                               wx.ID_ABOUT,
                               "&About\tCtrl+A",
                               "About",
                               wx.ITEM_NORMAL,
                               None,
                               helpImg)
        item.SetTextColour("black")
        self.help_menu.AppendItem(item)
        self.help_menu.AppendSeparator()

        item = FM.FlatMenuItem(self.help_menu,
                               ID_HELLO,
                               "Hello !",
                               "Hello !",
                               wx.ITEM_NORMAL,
                               None)
        item.SetTextColour("black")
        self.help_menu.AppendItem(item)

        #------------

        # Add Create background bitmap.
        self.help_menu.SetBackgroundBitmap(CreateBackgroundBitmap())

        #------------
        #------------

        # Menu background color.
        # Read config file.
        self.menuBar.SetBackgroundColour(wx.Colour(self.config.Read("Color1")))

        # Add menu to the menu bar.
        self.menuBar.Append(self.file_menu, "&File")
        self.menuBar.Append(self.help_menu, "&Help")


    def CreateStatusBar(self):
        """
        ...
        """

        self.sb = MyStatusBar(self, -1)
        self.sb.SetStatusText("Hello world !")

        self.SetStatusBar(self.sb)


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyFrame :", self.GetClientSize())

        #------------
        #------------

        self.titleBarPnl = MyTitleBarPnl(self, -1, (w, 24))
        self.titleBarPnl.SetPosition((0, 0))
        print("self.titleBarPnl :", self.titleBarPnl.GetSize())

        #------------

        # self.line = wx.StaticLine(self, -1,
        #                          pos=(0, 70),
        #                          size=(-1, -1),
        #                          style=wx.LI_HORIZONTAL)

        #------------

        self.mainPnl = MyMainPnl(self, -1, (w, h-25))
        self.mainPnl.SetPosition((0, 25))
        print("self.mainPnl :", self.mainPnl.GetSize())


    def BindEvents(self):
        """
        ...
        """

        self.titleBarPnl.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

        self.Bind(wx.EVT_SIZE, self.OnResize)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyUp)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        self.Bind(wx.EVT_MENU, self.OnFullScreen, id=ID_FULLSCREEN)
        self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT)


    def DoLayout(self):
        """
        ...
        """

        # MainSizer is the top-level one that manages everything.
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        mbSizer = wx.BoxSizer(wx.HORIZONTAL)
        mbSizer.Add(self.menuBar, 1, wx.ALL, 0)

        mainSizer.Add(self.titleBarPnl, 1, wx.EXPAND, 0)
        # mainSizer.Add(self.line, 0, wx.EXPAND, 0)
        mainSizer.Add(mbSizer, 0, wx.EXPAND, 0)
        mainSizer.Add(self.mainPnl, 1, wx.EXPAND, 0)

        # Finally, tell the panel to use the sizer for layout.
        self.SetSizer(mainSizer)
        self.Layout()


    def OnRoll(self, event) :
        """
        Thanks to Ray Pasco.
        """

        if not bool(self.isRolled) :
        # Set the flag to the state we want regardless of whether
        # or not it's in currently in the opposite state.
           self.RollUnRoll(wantToRoll=True)

        elif self.isRolled :   # UnRoll.
           # Set the flag to the state we want regardless of whether
           # or not it's in currently in the opposite state.
           self.RollUnRoll(wantToRoll=False)

        print("OnRoll :", self.GetClientSize())


    def RollUnRoll(self, wantToRoll) :
        """
        Thanks to Ray Pasco.
        """

        # Save the current size only if the Frame is not rolled up.
        if not bool(self.isRolled) :
            self.unrolledFrameClientSize_size = self.GetClientSize()

        if bool(wantToRoll) :   # UnRoll.
            # Set size (45).
            self.SetClientSize((self.unrolledFrameClientSize_size[0], 45))
            # Set to match this new state.
            self.isRolled = True

        else :   # Roll
            self.SetClientSize(self.unrolledFrameClientSize_size)
            # Set to match this new state.
            self.isRolled = False

        print("RollUnRoll :", self.GetClientSize())


    def OnAbout(self, event):
        """
        ...
        """

        self.dialog = MyAboutDlg(self)


    def OnLeftDown(self, event):
        """
        ...
        """

        self.CaptureMouse()
        x, y = self.ClientToScreen(event.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))


    def OnLeftUp(self, evt):
        """
        ...
        """

        if self.HasCapture():
            self.ReleaseMouse()


    def OnMouseMove(self, event):
        """
        ...
        """

        if event.Dragging() and event.LeftIsDown():
            x, y = self.ClientToScreen(event.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            self.Move(fp)


    def OnIconfiy(self, event):
        """
        ...
        """

        self.Iconize()


    def OnResize(self, event):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("self :", self.GetClientSize())

        #------------
        #------------

        self.titleBarPnl.SetSize((w, 24))
        # self.line.SetSize((w, -1))
        self.menuBar.SetSize((w, -1))
        self.mainPnl.SetSize((w, h-45))

        #------------

        self.Refresh()


    def OnFullScreen(self, event):
        """
        ...
        """

        self.ShowFullScreen(not self.IsFullScreen(),
                            wx.FULLSCREEN_NOCAPTION)


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_ESCAPE:
            # Close the frame, no action.
            self.OnCloseWindow(event)
        event.Skip()


    def OnBtnClose(self, event):
        """
        ...
        """

        self.Close()


    def OnCloseWindow(self, event):
        """
        Quit this application.
        """

        # self.Destroy()
        self.OnTimerOut(self)

        print("Exit application.")

#---------------------------------------------------------------------------

class MyApp(wx.App):
    """
    Thanks to Andrea Gavana.
    """
    def OnInit(self):

        #------------

        self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)

        #------------

        self.SetAppName("Custom Gui 1")

        #------------

        self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]

        #------------

        frame = MyFrame()
        self.SetTopWindow(frame)
        frame.Show(True)

        return True

    #-----------------------------------------------------------------------

    def GetInstallDir(self):
        """
        Returns the installation directory for my application.
        """

        return self.installDir


    def GetIconsDir(self):
        """
        Returns the icons directory for my application.
        """

        icons_dir = os.path.join(self.installDir, "icons")
        return icons_dir


    def GetBitmapsDir(self):
        """
        Returns the bitmaps directory for my application.
        """

        bitmaps_dir = os.path.join(self.installDir, "bitmaps")
        return bitmaps_dir


    def GetConfig(self):
        """
        Returns the config file for my application.
        """

        config = wx.FileConfig(appName="Custom Gui",
                               localFilename=os.path.join(self.installDir,
                                                          "options"))
        return config

#---------------------------------------------------------------------------

def main():
    app = MyApp(False)
    app.MainLoop()

#---------------------------------------------------------------------------

if __name__ == "__main__" :
    main()
}}}
--------
=== Second example ===
{{attachment:img_sample_two.png}}

{{{#!python
# sample_two.py

import sys
import os
import platform
import wx
from wx.adv import TaskBarIcon as TaskBarIcon
import wx.lib.fancytext as fancytext
import wx.lib.agw.flatmenu as FM
from   wx.lib.agw.artmanager import ArtManager, RendererBase, DCSaver
from   wx.lib.agw.fmresources import ControlFocus, ControlPressed
import wx.dataview as dv
import wx.lib.colourdb
import rectshapedbitmapbutton as SBB
import rectshapedbitmapbuttonTwo as SBBTwo
import data

musicdata = sorted(data.musicdata.items())
musicdata = [[str(k)] + list(v) for k,v in musicdata]

# def SwitchRGBtoBGR
# def CreateBackgroundBitmap
# class MyMenuRenderer
# class MyTaskBarIcon
# class MyListCtrlPnl
# class MyStatusBar
# class MyTitleBar
# class MyAboutDlg
# class MyPopupMenu
# class MyTitleBarPnl
# class MyMainPnl
# class MyFrame
# class MyApp

ID_FULLSCREEN = wx.NewIdRef()
ID_MAIN_PNL = wx.NewIdRef()
ID_BTN_FULLSCREEN = wx.NewIdRef()
ID_BTN_ABOUT = wx.NewIdRef()
ID_BTN_QUIT = wx.NewIdRef()
ID_HELLO = wx.NewIdRef()

#---------------------------------------------------------------------------

def SwitchRGBtoBGR(colour):
    """
    ...
    """

    return wx.Colour(colour.Blue(), colour.Green(), colour.Red())

#---------------------------------------------------------------------------

def CreateBackgroundBitmap():
    """
    ...
    """

    mem_dc = wx.MemoryDC()
    bmp = wx.Bitmap(121, 300)
    mem_dc.SelectObject(bmp)

    mem_dc.Clear()

    # Colour the menu face with background colour.
    mem_dc.SetPen(wx.Pen("#a0a0a0", 0))
    mem_dc.SetBrush(wx.Brush("#93c037"))
    mem_dc.DrawRectangle(0, 15, 121, 300)
    mem_dc.DrawLine(0, 0, 300, 0)

    mem_dc.SelectObject(wx.NullBitmap)
    return bmp

#---------------------------------------------------------------------------

class MyMenuRenderer(FM.FMRenderer):
    """
    Thanks to Andrea Gavana.
    A custom renderer class for FlatMenu.
    """
    def __init__(self):
        FM.FMRenderer.__init__(self)

    #-----------------------------------------------------------------------

    def DrawMenuButton(self, dc, rect, state):
        """
        Draws the highlight on a FlatMenu.
        """

        self.DrawButton(dc, rect, state)


    def DrawMenuBarButton(self, dc, rect, state):
        """
        Draws the highlight on a FlatMenuBar.
        """

        self.DrawButton(dc, rect, state)


    def DrawButton(self, dc, rect, state, colour=None):
        """
        ...
        """

        if state == ControlFocus:
            penColour = wx.Colour(wx.BLACK)
            brushColour = wx.Colour("yellow")
        elif state == ControlPressed:
            penColour = wx.Colour(wx.BLACK)
            brushColour = wx.Colour("yellow")
        else:   # ControlNormal, ControlDisabled, default.
            penColour = wx.Colour(wx.BLACK)
            brushColour = wx.Colour("yellow")

        # Draw the button borders.
        dc = wx.GCDC(dc)
        dc.SetPen(wx.Pen(penColour, 1))
        dc.SetBrush(wx.Brush(brushColour))
        dc.DrawRoundedRectangle(rect.x, rect.y, rect.width, rect.height-3, 4)


    def DrawMenuBarBackground(self, dc, rect):
        """
        ...
        """

        # For office style, we simple draw a rectangle
        # with a gradient colouring.
        vertical = ArtManager.Get().GetMBVerticalGradient()

        dcsaver = DCSaver(dc)

        # Fill with gradient.
        startColour = self.menuBarFaceColour
        endColour   = ArtManager.Get().LightColour(startColour, 0)

        dc.SetPen(wx.Pen(endColour))
        dc.SetBrush(wx.Brush(endColour))
        dc.DrawRectangle(rect)


    def DrawToolBarBg(self, dc, rect):
        """
        ...
        """

        if not ArtManager.Get().GetRaiseToolbar():
            return

        # Fill with gradient.
        startColour = self.menuBarFaceColour()
        dc.SetPen(wx.Pen(startColour))
        dc.SetBrush(wx.Brush(startColour))
        dc.DrawRectangle(0, 0, rect.GetWidth(), rect.GetHeight())

#---------------------------------------------------------------------------

class MyTaskBarIcon(TaskBarIcon):
    TBMENU_RESTORE = wx.NewIdRef()
    TBMENU_CLOSE   = wx.NewIdRef()
    TBMENU_REMOVE  = wx.NewIdRef()
    def __init__(self, frame):
        TaskBarIcon.__init__(self, wx.adv.TBI_DOCK)
        self.frame = frame

        #------------

        # Return icons folder.
        self.icons_dir = wx.GetApp().GetIconsDir()

        #------------

        frameIcon = wx.Icon(os.path.join(self.icons_dir,
                                         "icon_wxWidgets.ico"),
                            type=wx.BITMAP_TYPE_ICO)
        self.SetIcon(frameIcon)

        # Bind some events.
        self.Bind(wx.adv.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate)
        self.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE)
        self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE)
        self.Bind(wx.EVT_MENU, self.OnTaskBarRemove, id=self.TBMENU_REMOVE)


    def CreatePopupMenu(self):
        """
        This method is called by the base class when it needs to popup
        the menu for the default EVT_RIGHT_DOWN event.  Just create
        the menu how you want it and return it from this function,
        the base class takes care of the rest.
        """
        menu = wx.Menu()
        menu.Append(self.TBMENU_RESTORE, "Restore main frame")
        menu.Append(self.TBMENU_CLOSE,   "Close main frame")
        menu.AppendSeparator()
        menu.Append(self.TBMENU_REMOVE, "Remove the TB Icon")
        return menu


    def OnTaskBarActivate(self, evt):
        if self.frame.IsIconized():
            self.frame.Iconize(False)
        if not self.frame.IsShown():
            self.frame.Show(True)
        self.frame.Raise()


    def OnTaskBarClose(self, evt):
        wx.CallAfter(self.frame.Close)


    def OnTaskBarRemove(self, evt):
        self.RemoveIcon()

#---------------------------------------------------------------------------

class MyListCtrlPnl(wx.Panel):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        # Create the listctrl.
        self.dvlc = dv.DataViewListCtrl(self,
                                        style=wx.BORDER_SIMPLE|
                                              dv.DV_ROW_LINES|
                                              dv.DV_HORIZ_RULES|
                                              dv.DV_VERT_RULES)

        # Give it some columns.
        # The ID col we'll customize a bit :
        self.dvlc.AppendTextColumn("Id", width=40)
        self.dvlc.AppendTextColumn("Artist", width=170)
        self.dvlc.AppendTextColumn("Title", width=260)
        self.dvlc.AppendTextColumn("Genre", width=80)

        # Load the data. Each item (row) is added as a sequence
        # of values whose order matches the columns.
        for itemvalues in musicdata:
            self.dvlc.AppendItem(itemvalues)

        self.dvlc.SetBackgroundColour("#c9f72b")
        self.dvlc.SetForegroundColour("black")

        # Set the layout so the listctrl fills the panel.
        self.Sizer = wx.BoxSizer()
        self.Sizer.Add(self.dvlc, 1, wx.EXPAND)

#---------------------------------------------------------------------------

class MyStatusBar(wx.StatusBar) :
    """
    Thanks to ???.
    Simple custom colorized StatusBar.
    """
    def __init__(self, parent, id) :
        wx.StatusBar.__init__(self, parent, id)

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        # Read config file.
        self.SetBackgroundColour(wx.Colour(self.config.Read("Color2")))


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_PAINT, self.OnPaint)


    def OnPaint(self, event) :
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        self.Draw(dc)


    def Draw(self, dc) :
        """
        ...
        """

        # Read config file.
        dc.SetBackground(wx.Brush(self.config.Read("Color2")))
        dc.Clear()

        textVertOffset = 3      # Perfect for MSW.
        textHorzOffset = 5      # Arbitrary - looks nicer.

        dc.SetTextForeground("white")
        dc.DrawText(self.GetStatusText(), textHorzOffset, textVertOffset)

#---------------------------------------------------------------------------

class MyTitleBar(wx.Control):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, label, size):
        style = (wx.BORDER_NONE)
        super(MyTitleBar, self).__init__(parent,
                                         style=style)

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Attributes.
        self.parent = parent
        self.label = label
        self.size = size

        #------------

        # Simplified init method.
        self.SetBackground()
        self.SetProperties(label, size)
        self.CreateCtrls()
        self.DoLayout()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetBackground(self):
        """
        ...
        """

        self.SetBackgroundColour(wx.Colour(self.config.Read("Color2")))
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)


    def SetProperties(self, label, size):
        """
        ...
        """

        self.label = label
        self.size = size

        self.label_font = self.GetFont()
        self.label_font.SetFamily(wx.SWISS)
        self.label_font.SetPointSize(size)
        self.label_font.SetWeight(wx.BOLD)
        self.SetFont(self.label_font)


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetSize()
        w1, h1 = self.GetClientSize()

        #------------

        # Load an icon bitmap for titlebar.
        # bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
        #                              "icon_app.png"),
        #                 type=wx.BITMAP_TYPE_PNG)

        # self.ico = wx.StaticBitmap(self, -1, bmp)
        # self.ico.SetBackgroundColour(wx.Colour(self.config.Read("Color2")))
        # self.ico.SetPosition((300, 1))
        # self.ico.SetToolTip("This is a customized icon.")
        # self.ico.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)

        #------------

        # Button Exit.
        self.btn3 = SBBTwo.ShapedBitmapButton(self, -1,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "btn_gloss_exit_normal_1.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "btn_gloss_exit_selected_1.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "btn_gloss_exit_normal_1.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "btn_gloss_exit_normal_1.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------

        # Button Maximize.
        self.btn4 = SBBTwo.ShapedBitmapButton(self, -1,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "btn_gloss_maximize_normal_1.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "btn_gloss_maximize_selected_1.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "btn_gloss_maximize_normal_1.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "btn_gloss_maximize_normal_1.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------

        # Thanks to MCOW.
        # Button Reduce.
        self.btn5 = SBBTwo.ShapedBitmapButton(self, -1,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "btn_gloss_reduce_normal_1.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "btn_gloss_reduce_selected_1.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "btn_gloss_reduce_normal_1.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "btn_gloss_reduce_normal_1.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------

        # Button Roll.
        self.btn6 = SBBTwo.ShapedBitmapButton(self, -1,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "btn_gloss_roll_normal_1.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "btn_gloss_roll_selected_1.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "btn_gloss_roll_normal_1.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "btn_gloss_roll_normal_1.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)


    def DoLayout(self):
        """
        ...
        """

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)

        #------------

        mainSizer.Add(self.btn3, 0, wx.LEFT, 4)
        mainSizer.Add(self.btn4, 0, wx.LEFT, 4)
        mainSizer.Add(self.btn5, 0, wx.LEFT, 4)
        mainSizer.Add(self.btn6, 0, wx.LEFT, 4)

        #------------

        self.SetSizer(mainSizer)
        self.Layout()


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        # self.ico.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
        # self.ico.Bind(wx.EVT_LEFT_DOWN, self.OnRightDown)

        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)

        self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)
        self.btn4.Bind(wx.EVT_BUTTON, self.OnFullScreen)
        self.btn5.Bind(wx.EVT_BUTTON, self.OnIconfiy)
        self.btn6.Bind(wx.EVT_BUTTON, self.OnRoll)


    def OnRightDown(self, event):
        """
        ...
        """

        self.PopupMenu(MyPopupMenu(self), event.GetPosition())

        print("Right down.")


    def OnLeftDown(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnLeftDown(event)


    def OnLeftUp(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnLeftUp(event)


    def SetLabel(self, label):
        """
        ...
        """

        self.label = label
        self.Refresh()


    def DoGetBestSize(self):
        """
        ...
        """

        dc = wx.ClientDC(self)
        dc.SetFont(self.GetFont())

        textWidth, textHeight = dc.GetTextExtent(self.label)
        spacing = 10
        totalWidth = textWidth + (spacing)
        totalHeight = textHeight + (spacing)

        best = wx.Size(totalWidth, totalHeight)
        self.CacheBestSize(best)

        return best


    def GetLabel(self):
        """
        ...
        """

        return self.label


    def GetLabelColor(self):
        """
        ...
        """

        return self.foreground


    def GetLabelSize(self):
        """
        ...
        """

        return self.size


    def SetLabelColour(self, colour):
        """
        ...
        """

        self.labelColour = colour


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        gcdc = wx.GCDC(dc)

        gcdc.Clear()

        # Setup the GraphicsContext.
        gc = gcdc.GetGraphicsContext()

        # Get the working size we can draw in.
        width, height = self.GetSize()

        # Use the GCDC to draw the text.
        # Read config file.
        brush = self.config.Read("Color2")
        gcdc.SetPen(wx.Pen(brush, 1))
        gcdc.SetBrush(wx.Brush(brush))
        gcdc.DrawRectangle(0, 0, width, height)

        # Get the system font.
        gcdc.SetFont(self.GetFont())

        textWidth, textHeight = gcdc.GetTextExtent(self.label)
        tposx, tposy = ((width/2)-(textWidth/2), (height/3)-(textHeight/3))

        tposx += 0
        tposy += 0

        # Set position and text color.
        if tposx <= 100:
            gcdc.SetTextForeground("black")
            gcdc.DrawText("", int(tposx), int(tposy+1))

            gcdc.SetTextForeground(self.labelColour)
            gcdc.DrawText("", int(tposx), int(tposy))

        else:
            gcdc.SetTextForeground("black")
            gcdc.DrawText(self.label, int(tposx), int(tposy+1))

            gcdc.SetTextForeground(self.labelColour)
            gcdc.DrawText(self.label, int(tposx), int(tposy))


    def OnRoll(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnRoll(True)

        print("Roll/unRoll button was clicked.")


    def OnIconfiy(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnIconfiy(self)

        print("Iconfiy button was clicked.")


    def OnFullScreen(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnFullScreen(self)

        print("FullScreen button was clicked.")


    def OnBtnClose(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnCloseWindow(self)

        print("Close button was clicked.")

#---------------------------------------------------------------------------

class MyAboutDlg(wx.Frame):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        style = (wx.FRAME_SHAPED | wx.NO_BORDER |
                 wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
                 wx.SYSTEM_MENU | wx.CLOSE_BOX |
                 wx.NO_FULL_REPAINT_ON_RESIZE)
        wx.Frame.__init__(self,
                          parent,
                          id=-1,
                          title="About...",
                          style=style)

        #------------

        # Attributes.
        self.SetTransparent(0)
        self.opacity_in = 0
        self.opacity_out = 255
        self.deltaN = -70
        self.hasShape = False
        self.delta = wx.Point(0,0)

        #------------

        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
        # Return icons folder.
        self.icons_dir = wx.GetApp().GetIconsDir()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.OnTimerIn(self)
        self.CreateCtrls()
        self.BindEvents()

        #------------

        self.CenterOnParent(wx.BOTH)
        self.GetParent().Enable(False)

        #------------

        self.Show(True)

        #------------

        self.eventLoop = wx.GUIEventLoop()
        self.eventLoop.Run()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        Set the dialog properties (title, icon, transparency...).
        """

        frameIcon = wx.Icon(os.path.join(self.icons_dir,
                                         "icon_wxWidgets.ico"),
                            type=wx.BITMAP_TYPE_ICO)
        self.SetIcon(frameIcon)


    def OnTimerIn(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer1 = wx.Timer(self, -1)
        self.timer1.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)

        print("Fade-in was launched.")


    def OnTimerOut(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer2 = wx.Timer(self, -1)
        self.timer2.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)

        print("Fade-out was launched.")


    def AlphaCycle1(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_in += self.deltaN
        if self.opacity_in <= 0:
            self.deltaN = -self.deltaN
            self.opacity_in = 0

        if self.opacity_in >= 255:
            self.deltaN = -self.deltaN
            self.opacity_in = 255

            self.timer1.Stop()

        self.SetTransparent(self.opacity_in)

        print("Fade in = {}/255".format(self.opacity_in))


    def AlphaCycle2(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_out += self.deltaN
        if self.opacity_out >= 255:
            self.deltaN = -self.deltaN
            self.opacity_out = 255

        if self.opacity_out <= 0:
            self.deltaN = -self.deltaN
            self.opacity_out = 0

            self.timer2.Stop()

            wx.CallAfter(self.Destroy)

        self.SetTransparent(self.opacity_out)

        print("Fade out = {}/255".format(self.opacity_out))


    def CreateCtrls(self):
        """
        Make widgets for my dialog.
        """

        # Load a background bitmap.
        self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "skin_about_4.png"),
                             type=wx.BITMAP_TYPE_PNG)
        mask = wx.Mask(self.bmp, wx.RED)
        self.bmp.SetMask(mask)

        #------------

        self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))

        #------------

        if wx.Platform == "__WXGTK__":
            # wxGTK requires that the window be created before you can
            # set its shape, so delay the call to SetWindowShape until
            # this event.
            self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        else:
            # On wxMSW and wxMac the window has already
            # been created, so go for it.
            self.SetWindowShape()


    def BindEvents(self):
        """
        Bind all the events related to my dialog.
        """

        # Bind some events to an events handler.
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow)  # Panel right clic.
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)


    def SetWindowShape(self, event=None):
        """
        ...
        """

        # Use the bitmap's mask to determine the region.
        r = wx.Region(self.bmp)
        self.hasShape = self.SetShape(r)


    def OnEraseBackground(self, event):
        """
        ...
        """

        dc = event.GetDC()
        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)


    def OnLeftDown(self, event):
        """
        ...
        """

        self.CaptureMouse()
        x, y = self.ClientToScreen(event.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))


    def OnLeftUp(self, evt):
        """
        ...
        """

        if self.HasCapture():
            self.ReleaseMouse()


    def OnMouseMove(self, event):
        """
        ...
        """

        if event.Dragging() and event.LeftIsDown():
            x, y = self.ClientToScreen(event.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            self.Move(fp)


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.AutoBufferedPaintDCFactory(self)
        dc.DrawBitmap(self.bmp, 0, 0, True)

        #------------

        # These are strings.
        py_version = sys.version.split()[0]

        str1 = (('<font style="normal" family="default" color="orange" size="10" weight="bold">'
                 'Programming : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 'Python {}</font>').format(py_version))   # Python 3.7.2

        str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
                 'GUI toolkit : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 'wxPython {}</font>').format(wx.VERSION_STRING))  # wxPython 4.0.4  wx.VERSION_STRING

        str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
                 'Library : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 '{}</font>').format(wx.GetLibraryVersionInfo().VersionString))   # wxWidgets 3.0.5

        str4 = (('<font style="normal" family="default" color="blue" size="10" weight="bold">'
                 'Operating system : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 '{}</font>').format(platform.system()))   # Windows

        str5 = (('<font style="normal" family="default" color="darkgreen" size="9" weight="normal">'
                 '{}</font>').format(self.app_name))   # Custom Gui 3

        str6 = (('<font style="normal" family="default" color="Black" size="8" weight="normal">'
                 'Right clic or Esc for Exit</font>'))

        #------------

        # Get the working size we can draw in.
        bw, bh = self.GetSize()

        # Use the GCDC to draw the text.
        dc.GradientFillLinear((0, 0, bw, bh),
                               "gray",
                               wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENU),
                               wx.NORTH)

        # Draw the about borders.
        dc.SetPen(wx.Pen(wx.Colour(0, 0, 0), 5))
        # dc.SetBrush(wx.Brush(wx.Colour(150, 150, 150)))
        # or
        dc.SetBrush(wx.Brush(wx.TRANSPARENT_BRUSH))
        dc.DrawRectangle(0, 0, bw, bh)

        #------------
        # Draw text.
        # Need width to calculate x position of str1.
        tw, th = fancytext.GetExtent(str1, dc)
        # Centered text.
        fancytext.RenderToDC(str1, dc, (bw-tw)/2, 30)

        #------------

        # Need width to calculate x position of str2.
        tw, th = fancytext.GetExtent(str2, dc)
        # Centered text.
        fancytext.RenderToDC(str2, dc, (bw-tw)/2, 50)

        #------------

        # Need width to calculate x position of str3.
        tw, th = fancytext.GetExtent(str3, dc)
        # Centered text.
        fancytext.RenderToDC(str3, dc, (bw-tw)/2, 70)

        #------------

        # Need width to calculate x position of str4.
        tw, th = fancytext.GetExtent(str4, dc)
        # Centered text.
        fancytext.RenderToDC(str4, dc, (bw-tw)/2, 90)

        #------------

        # Need width to calculate x position of str5.
        tw, th = fancytext.GetExtent(str5, dc)
        # Centered text.
        fancytext.RenderToDC(str5, dc, (bw-tw)/2, 130)

        #------------

        # Need width to calculate x position of str6.
        tw, th = fancytext.GetExtent(str6, dc)
        # Centered text.
        fancytext.RenderToDC(str6, dc, (bw-tw)/2, 195)


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_ESCAPE:
            self.OnCloseWindow(event)

        event.Skip()


    def OnCloseWindow(self, event):
        """
        ...
        """

        self.GetParent().Enable(True)
        self.eventLoop.Exit()
        #self.Destroy()
        self.OnTimerOut(self)

#---------------------------------------------------------------------------

class MyPopupMenu(wx.Menu):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        wx.Menu.__init__(self)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Returns bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Simplified init method.
        self.CreatePopupMenu()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def CreatePopupMenu(self, event=None):
        """
        This method is called by the base class when it needs to popup
        the menu for the default EVT_RIGHT_DOWN event.  Just create
        the menu how you want it and return it from this function,
        the base class takes care of the rest.
        """

        bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                     "item_about.png"),
                        type=wx.BITMAP_TYPE_PNG)

        item = wx.MenuItem(self, id=wx.ID_ABOUT, text=" About")
        item.SetBitmap(bmp)
        self.Append(item)
        self.AppendSeparator()

        #------------

        bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                     "item_exit.png"),
                        type=wx.BITMAP_TYPE_PNG)

        if True or "__WXMSW__" in wx.PlatformInfo:
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            font.SetWeight(wx.BOLD)

        item = wx.MenuItem(self, id=wx.ID_EXIT, text=" Exit")
        item.SetBitmap(bmp)
        item.SetFont(font)
        self.Append(item)

        return self


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        # Bind the menu events to an events handler.
        self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT)


    def OnAbout(self, event):
        """
        ...
        """

        self.mainFrame = wx.GetApp().GetTopWindow()
        self.mainFrame.OnAbout(self)

        print("About icon was clicked.")


    def OnClose(self, event):
        """
        ...
        """

        self.mainFrame = wx.GetApp().GetTopWindow()
        self.mainFrame.OnCloseWindow(self)

        print("Close icon was clicked.")

#---------------------------------------------------------------------------

class MyTitleBarPnl(wx.Panel):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, id, size):
        style = (wx.NO_BORDER)
        super(MyTitleBarPnl, self).__init__(parent,
                                            id,
                                            size=size,
                                            style=style)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.CreateCtrls()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        # Read config file.
        self.SetBackgroundColour(wx.Colour(self.config.Read("Color2")))


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyTitleBarPnl :", self.GetClientSize())

        #------------
        #------------

        # Add titleBar.
        self.titleBar = MyTitleBar(self,
                                   label=self.app_name,
                                   size=10)
        self.titleBar.SetPosition((0, 0))
        self.titleBar.SetSize((w, 24))
        self.titleBar.SetLabelColour("white")
        self.titleBar.SetToolTip("This is a customized title bar.")


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_SIZE, self.OnResize)


    def OnResize(self, event):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyTitleBarPnl :", self.GetClientSize())

        #------------
        #------------

        self.titleBar.SetSize((w, 24))

        #------------

        self.Refresh()

        print("On resize was clicked.")

#---------------------------------------------------------------------------

class MyMainPnl(wx.Panel):
    """
    ...
    """
    def __init__(self, parent, id, size):
        style = (wx.NO_BORDER | wx.TAB_TRAVERSAL)
        super(MyMainPnl, self).__init__(parent,
                                        id=ID_MAIN_PNL,
                                        size=size,
                                        style=style)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Colourdb.
        wx.lib.colourdb.updateColourDB()

        # Create a colour list from the colourdb database.
        self.colour_list = wx.lib.colourdb.getColourList()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.CreateCtrls()
        self.DoLayout()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        if wx.Platform == "__WXMSW__":
            self.SetDoubleBuffered(True)

        # Read config file.
        self.SetBackgroundColour(self.config.Read("Color2"))


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyMainPnl :", self.GetClientSize())

        #------------
        #------------

        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

        #------------
        #------------

        # Create data view control.
        self.list = MyListCtrlPnl(self)

        #------------
        #------------

        self.txt = wx.StaticText(self,
                                 -1,
                                 label="Hello World !")
        self.txt.SetForegroundColour("BLACK")
        self.txt.SetFont(font)

        #------------
        #------------

        # Thanks to MCOW.
        # Button Fullscreen.
        self.btn1 = SBB.ShapedBitmapButton(self, ID_BTN_FULLSCREEN,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="Fullscreen",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        self.btn1.SetFocus() # Necessary for Linux.

        #------------

        # Button About.
        self.btn2 = SBB.ShapedBitmapButton(self, ID_BTN_ABOUT,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="About",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------

        # Button Quit.
        self.btn3 = SBB.ShapedBitmapButton(self, ID_BTN_QUIT,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="Quit",
            labelForeColour=wx.WHITE,
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------
        #------------

        self.line = wx.StaticLine(self, -1,
                                  pos=(0, 70),
                                  size=(-1, -1),
                                  style=wx.LI_HORIZONTAL)

        #------------
        #------------

        # Create a choice widget.
        self.choice = wx.Choice(self,
                                -1,
                                pos=(-1, -1),
                                size=(131, -1),
                                choices=self.colour_list,
                                style=wx.CB_SORT)

        # Select item 629 in choice list to show.
        # self.choice.SetSelection(626)  # YELLOWGREEN
        # Read config file.
        self.choice.SetSelection(self.config.ReadInt("Item2"))

        item = self.choice.GetCurrentSelection()
        bgcolour = self.choice.GetStringSelection()
        print("Item : %s , %s" % (item, bgcolour))


    def DoLayout(self):
        """
        ...
        """

        txtSizer = wx.BoxSizer(wx.VERTICAL)
        txtSizer.Add(self.txt, 0, wx.LEFT, 10)

        sizerList = wx.BoxSizer(wx.VERTICAL)
        sizerList.Add(self.list, 1,
                      wx.LEFT|wx.TOP|wx.BOTTOM|
                      wx.EXPAND|wx.ALIGN_TOP, 10)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(txtSizer, 0, wx.BOTTOM, 0)
        sizer.Add(self.btn1, 1, wx.ALL, 10)
        sizer.Add(self.btn2, 1, wx.ALL, 10)
        sizer.Add(self.line, 0, wx.EXPAND|wx.ALL, 10)
        sizer.Add(self.choice, 0, wx.ALL, 10)
        sizer.Add(self.btn3, 1, wx.ALL, 10)

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(sizerList, 1,
                      wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5)
        mainSizer.Add(sizer, 0, wx.ALIGN_BOTTOM|wx.ALL, 5)

        self.SetSizer(mainSizer)
        self.Layout()


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_CHOICE, self.OnChoice)

        self.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_MAIN_PNL)
        self.btn1.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_FULLSCREEN)
        self.btn2.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_ABOUT)
        self.btn3.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_QUIT)

        self.btn1.Bind(wx.EVT_BUTTON, self.OnFullScreen)
        self.btn2.Bind(wx.EVT_BUTTON, self.OnAbout)
        self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)


    def OnInfo(self, event):
        """
        ...
        """

        event_id = event.GetId()

        if event_id == ID_MAIN_PNL:
            self.GetParent().SetStatusText(text="Hello world !")

        elif event_id == ID_BTN_FULLSCREEN:
            self.GetParent().SetStatusText(text="Fullscreen")

        elif event_id == ID_BTN_ABOUT:
            self.GetParent().SetStatusText(text="About")

        elif event_id == ID_BTN_QUIT:
            self.GetParent().SetStatusText(text="Quit the program")

        else:
            # Tell the event system to continue
            # looking for an event handler, so the
            # default handler will get called.
            event.Skip()


    def OnChoice(self, event):
        """
        ...
        """

        item = event.GetSelection()
        bgcolour = self.choice.GetStringSelection()
        print("New item : %s , %s" % (item, bgcolour))

        # Change colour of the panel to the selected colour...
        self.SetBackgroundColour(bgcolour)

        frame = self.GetTopLevelParent()
        frame.SetBackgroundColour(bgcolour)

        # Write config file.
        self.config.WriteInt("Item2", self.choice.GetCurrentSelection())
        self.config.Write("Color2", self.choice.GetStringSelection())
        self.config.Flush()

        self.Refresh()

        print("OnChoice button was clicked.")


    def OnAbout(self, event):
        """
        ...
        """

        self.GetParent().OnAbout(self)

        print("FullScreen button was clicked.")


    def OnFullScreen(self, event):
        """
        ...
        """

        self.GetParent().OnFullScreen(self)

        print("FullScreen button was clicked.")


    def OnBtnClose(self, event):
        """
        ...
        """

        self.GetParent().OnCloseWindow(self)

        print("Close button was clicked.")

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self):
        style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
                 wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
                 wx.RESIZE_BORDER | wx.NO_FULL_REPAINT_ON_RESIZE)
        super(MyFrame, self).__init__(None,
                                      -1,
                                      title="",
                                      style=style)

        #------------

        wx.SystemOptions.SetOption("msw.remap", "0")

        #------------

        # Attributes.
        self.SetTransparent(0)
        self.opacity_in = 0
        self.opacity_out = 255
        self.deltaN = -70
        self.delta = wx.Point(0,0)

        #------------

        try:
            self.tbicon = MyTaskBarIcon(self)
        except:
            self.tbicon = None

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
        # Return icons folder.
        self.icons_dir = wx.GetApp().GetIconsDir()

        #------------

        # Colourdb.
        wx.lib.colourdb.updateColourDB()

        # Create a colour list from the colourdb database.
        self.colour_list = wx.lib.colourdb.getColourList()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.OnTimerIn(self)
        self.CreateMenu()
        self.CreateStatusBar()
        self.CreateCtrls()
        self.BindEvents()
        self.DoLayout()

        #------------

        # Thanks to Ray Pasco.
        # Initialize to the current state.
        self.unrolledFrameClientSize_size = self.GetClientSize()
        self.isRolled = False

        #------------

        self.CenterOnScreen(wx.BOTH)

        #------------

        self.Show(True)

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """
        self.SetBackgroundColour(wx.Colour(self.config.Read("Color2")))
        self.SetTitle(self.app_name)
        self.SetClientSize((600, 380))
        self.SetMinSize((128, 82))

        #------------

        frameIcon = wx.Icon(os.path.join(self.icons_dir,
                                         "icon_wxWidgets.ico"),
                            type=wx.BITMAP_TYPE_ICO)
        self.SetIcon(frameIcon)


    def OnTimerIn(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer1 = wx.Timer(self, -1)
        self.timer1.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)

        print("Fade-in was launched.")


    def OnTimerOut(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer2 = wx.Timer(self, -1)
        self.timer2.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)

        print("Fade-out was launched.")


    def AlphaCycle1(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_in += self.deltaN
        if self.opacity_in <= 0:
            self.deltaN = -self.deltaN
            self.opacity_in = 0

        if self.opacity_in >= 255:
            self.deltaN = -self.deltaN
            self.opacity_in = 255

            self.timer1.Stop()

        self.SetTransparent(self.opacity_in)

        print("Fade in = {}/255".format(self.opacity_in))


    def AlphaCycle2(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_out += self.deltaN
        if self.opacity_out >= 255:
            self.deltaN = -self.deltaN
            self.opacity_out = 255

        if self.opacity_out <= 0:
            self.deltaN = -self.deltaN
            self.opacity_out = 0

            self.timer2.Stop()
            wx.CallAfter(self.Destroy)
            wx.Exit()

        self.SetTransparent(self.opacity_out)

        print("Fade out = {}/255".format(self.opacity_out))


    def CreateMenu(self):
        """
        ...
        """

        # FlatMenuBar.
        self.menuBar = FM.FlatMenuBar(self,
                                      wx.ID_ANY,
                                      32, 4,
                                      options=FM.FM_OPT_IS_LCD)

        # FM.StyleDefault or FM.Style2007
        # FM.StyleXP or FM.StyleVista
        self.newMyTheme = self.menuBar.GetRendererManager().AddRenderer(MyMenuRenderer())
        self.menuBar.GetRendererManager().SetTheme(self.newMyTheme)

        #------------

        # Set an icon to the exit/help menu item.
        exitImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                         "item_exit.png"),
                            type=wx.BITMAP_TYPE_PNG)

        helpImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                         "item_about.png"),
                            type=wx.BITMAP_TYPE_PNG)

        #------------
        #------------

        # File Menu.
        self.file_menu = FM.FlatMenu()

        # Create the menu items.
        item = FM.FlatMenuItem(self.file_menu,
                               ID_FULLSCREEN,
                               "&Fullscreen\tCtrl+F",
                               "Fullscreen",
                               wx.ITEM_NORMAL,
                               None)
        item.SetTextColour("black")
        self.file_menu.AppendItem(item)
        self.file_menu.AppendSeparator()


        item = FM.FlatMenuItem(self.file_menu,
                               wx.ID_EXIT,
                               "&Quit\tCtrl+Q",
                               "Quit the program",
                               wx.ITEM_NORMAL,
                               None,
                               exitImg)
        # Demonstrate how to set custom font
        # and text colour to a FlatMenuItem.
        item.SetFont(wx.Font(-1, wx.FONTFAMILY_DEFAULT,
                             wx.FONTSTYLE_NORMAL,
                             wx.FONTWEIGHT_BOLD,
                             False, ""))
        item.SetTextColour("#d34725")

        self.file_menu.AppendItem(item)

        #------------

        # Add Create background bitmap.
        self.file_menu.SetBackgroundBitmap(CreateBackgroundBitmap())

        #------------
        #------------

        # Help Menu.
        self.help_menu = FM.FlatMenu()

        # Create the menu items.
        item = FM.FlatMenuItem(self.help_menu,
                               wx.ID_ABOUT,
                               "&About\tCtrl+A",
                               "About",
                               wx.ITEM_NORMAL,
                               None,
                               helpImg)
        item.SetTextColour("black")
        self.help_menu.AppendItem(item)
        self.help_menu.AppendSeparator()

        item = FM.FlatMenuItem(self.help_menu,
                               ID_HELLO,
                               "Hello !",
                               "Hello !",
                               wx.ITEM_NORMAL,
                               None)
        item.SetTextColour("black")
        self.help_menu.AppendItem(item)

        #------------

        # Add Create background bitmap.
        self.help_menu.SetBackgroundBitmap(CreateBackgroundBitmap())

        #------------
        #------------

        # Menu background color.
        # Read config file.
        self.menuBar.SetBackgroundColour(wx.Colour(self.config.Read("Color2")))

        # Add menu to the menu bar.
        self.menuBar.Append(self.file_menu, "&File")
        self.menuBar.Append(self.help_menu, "&Help")


    def CreateStatusBar(self):
        """
        ...
        """

        self.sb = MyStatusBar(self, -1)
        self.sb.SetStatusText("Hello world !")

        self.SetStatusBar(self.sb)


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyFrame :", self.GetClientSize())

        #------------
        #------------

        self.titleBarPnl = MyTitleBarPnl(self, -1, (w, 24))
        self.titleBarPnl.SetPosition((0, 0))
        print("self.titleBarPnl :", self.titleBarPnl.GetSize())

        #------------

        # self.line = wx.StaticLine(self, -1,
        #                          pos=(0, 70),
        #                          size=(-1, -1),
        #                          style=wx.LI_HORIZONTAL)

        #------------

        self.mainPnl = MyMainPnl(self, -1, (w, h-25))
        self.mainPnl.SetPosition((0, 25))
        print("self.mainPnl :", self.mainPnl.GetSize())


    def BindEvents(self):
        """
        ...
        """

        self.titleBarPnl.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

        self.Bind(wx.EVT_SIZE, self.OnResize)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyUp)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        self.Bind(wx.EVT_MENU, self.OnFullScreen, id=ID_FULLSCREEN)
        self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT)


    def DoLayout(self):
        """
        ...
        """

        # MainSizer is the top-level one that manages everything.
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        mbSizer = wx.BoxSizer(wx.HORIZONTAL)
        mbSizer.Add(self.menuBar, 1, wx.ALL, 0)

        mainSizer.Add(self.titleBarPnl, 1, wx.EXPAND, 0)
        # mainSizer.Add(self.line, 0, wx.EXPAND, 0)
        mainSizer.Add(mbSizer, 0, wx.EXPAND, 0)
        mainSizer.Add(self.mainPnl, 1, wx.EXPAND, 0)

        # Finally, tell the panel to use the sizer for layout.
        self.SetSizer(mainSizer)
        self.Layout()


    def OnRoll(self, event) :
        """
        Thanks to Ray Pasco.
        """

        if not bool(self.isRolled) :
        # Set the flag to the state we want regardless of whether
        # or not it's in currently in the opposite state.
           self.RollUnRoll(wantToRoll=True)

        elif self.isRolled :   # UnRoll.
           # Set the flag to the state we want regardless of whether
           # or not it's in currently in the opposite state.
           self.RollUnRoll(wantToRoll=False)

        print("OnRoll :", self.GetClientSize())


    def RollUnRoll(self, wantToRoll) :
        """
        Thanks to Ray Pasco.
        """

        # Save the current size only if the Frame is not rolled up.
        if not bool(self.isRolled) :
            self.unrolledFrameClientSize_size = self.GetClientSize()

        if bool(wantToRoll) :   # UnRoll.
            # Set size (45).
            self.SetClientSize((self.unrolledFrameClientSize_size[0], 45))
            # Set to match this new state.
            self.isRolled = True

        else :   # Roll
            self.SetClientSize(self.unrolledFrameClientSize_size)
            # Set to match this new state.
            self.isRolled = False

        print("RollUnRoll :", self.GetClientSize())


    def OnAbout(self, event):
        """
        ...
        """

        self.dialog = MyAboutDlg(self)


    def OnLeftDown(self, event):
        """
        ...
        """

        self.CaptureMouse()
        x, y = self.ClientToScreen(event.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))


    def OnLeftUp(self, evt):
        """
        ...
        """

        if self.HasCapture():
            self.ReleaseMouse()


    def OnMouseMove(self, event):
        """
        ...
        """

        if event.Dragging() and event.LeftIsDown():
            x, y = self.ClientToScreen(event.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            self.Move(fp)


    def OnIconfiy(self, event):
        """
        ...
        """

        self.Iconize()


    def OnResize(self, event):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("self :", self.GetClientSize())

        #------------
        #------------

        self.titleBarPnl.SetSize((w, 24))
        # self.line.SetSize((w, -1))
        self.menuBar.SetSize((w, -1))
        self.mainPnl.SetSize((w, h-47))

        #------------

        self.Refresh()


    def OnFullScreen(self, event):
        """
        ...
        """

        self.ShowFullScreen(not self.IsFullScreen(),
                            wx.FULLSCREEN_NOCAPTION)


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_ESCAPE:
            # Close the frame, no action.
            self.OnCloseWindow(event)
        event.Skip()


    def OnBtnClose(self, event):
        """
        ...
        """

        self.Close()


    def OnCloseWindow(self, event):
        """
        Quit this application.
        """

        if self.tbicon is not None:
            self.tbicon.Destroy()

        #------------

        # self.Destroy()
        self.OnTimerOut(self)

        print("Exit application.")

#---------------------------------------------------------------------------

class MyApp(wx.App):
    """
    Thanks to Andrea Gavana.
    """
    def OnInit(self):

        #------------

        self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)

        #------------

        self.SetAppName("Custom Gui 2")

        #------------

        self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]

        #------------

        frame = MyFrame()
        self.SetTopWindow(frame)
        frame.Show(True)

        return True

    #-----------------------------------------------------------------------

    def GetInstallDir(self):
        """
        Returns the installation directory for my application.
        """

        return self.installDir


    def GetIconsDir(self):
        """
        Returns the icons directory for my application.
        """

        icons_dir = os.path.join(self.installDir, "icons")
        return icons_dir


    def GetBitmapsDir(self):
        """
        Returns the bitmaps directory for my application.
        """

        bitmaps_dir = os.path.join(self.installDir, "bitmaps")
        return bitmaps_dir


    def GetConfig(self):
        """
        Returns the config file for my application.
        """

        config = wx.FileConfig(appName="Custom Gui",
                               localFilename=os.path.join(self.installDir,
                                                          "options"))
        return config

#---------------------------------------------------------------------------

def main():
    app = MyApp(False)
    app.MainLoop()

#---------------------------------------------------------------------------

if __name__ == "__main__" :
    main()
}}}
--------
=== Third example ===
{{attachment:img_sample_three.png}}

{{{#!python
# sample_three.py

import sys
import os
import platform
import wx
import wx.lib.fancytext as fancytext
import wx.lib.agw.flatmenu as FM
from   wx.lib.agw.artmanager import ArtManager, RendererBase, DCSaver
from   wx.lib.agw.fmresources import ControlFocus, ControlPressed
import wx.dataview as dv
import wx.lib.colourdb
import rectshapedbitmapbuttonOne as SBB
import data

musicdata = sorted(data.musicdata.items())
musicdata = [[str(k)] + list(v) for k,v in musicdata]

# def SwitchRGBtoBGR
# def CreateBackgroundBitmap
# class MyMenuRenderer
# class MyListCtrlPnl
# class MyStatusBar
# class MyTitleBar
# class MyAboutDlg
# class MyPopupMenu
# class MyWindow
# class MyButtonBox
# class MyTitleBarPnl
# class MyMainPnl
# class MyFrame
# class MyApp

ID_FULLSCREEN = wx.NewIdRef()
ID_MAIN_PNL = wx.NewIdRef()
ID_BTN_FULLSCREEN = wx.NewIdRef()
ID_BTN_ABOUT = wx.NewIdRef()
ID_BTN_QUIT = wx.NewIdRef()
ID_HELLO = wx.NewIdRef()

#---------------------------------------------------------------------------

def SwitchRGBtoBGR(colour):
    """
    ...
    """

    return wx.Colour(colour.Blue(), colour.Green(), colour.Red())

#---------------------------------------------------------------------------

def CreateBackgroundBitmap():
    """
    ...
    """

    mem_dc = wx.MemoryDC()
    bmp = wx.Bitmap(121, 300)
    mem_dc.SelectObject(bmp)

    mem_dc.Clear()

    # Colour the menu face with background colour.
    mem_dc.SetPen(wx.Pen("#a0a0a0", 0))
    mem_dc.SetBrush(wx.Brush("#c0dcf3"))
    mem_dc.DrawRectangle(0, 15, 121, 300)
    mem_dc.DrawLine(0, 0, 300, 0)

    mem_dc.SelectObject(wx.NullBitmap)
    return bmp

#---------------------------------------------------------------------------

class MyMenuRenderer(FM.FMRenderer):
    """
    Thanks to Andrea Gavana.
    A custom renderer class for FlatMenu.
    """
    def __init__(self):
        FM.FMRenderer.__init__(self)

    #-----------------------------------------------------------------------

    def DrawMenuButton(self, dc, rect, state):
        """
        Draws the highlight on a FlatMenu.
        """

        self.DrawButton(dc, rect, state)


    def DrawMenuBarButton(self, dc, rect, state):
        """
        Draws the highlight on a FlatMenuBar.
        """

        self.DrawButton(dc, rect, state)


    def DrawButton(self, dc, rect, state, colour=None):
        """
        ...
        """

        if state == ControlFocus:
            penColour = SwitchRGBtoBGR(ArtManager.Get().FrameColour())
            brushColour = SwitchRGBtoBGR(ArtManager.Get().BackgroundColour())
        elif state == ControlPressed:
            penColour = SwitchRGBtoBGR(ArtManager.Get().FrameColour())
            brushColour = SwitchRGBtoBGR(ArtManager.Get().HighlightBackgroundColour())
        else:   # ControlNormal, ControlDisabled, default.
            penColour = SwitchRGBtoBGR(ArtManager.Get().FrameColour())
            brushColour = SwitchRGBtoBGR(ArtManager.Get().BackgroundColour())

        # Draw the button borders.
        dc = wx.GCDC(dc)
        dc.SetPen(wx.Pen(penColour))
        dc.SetBrush(wx.Brush(brushColour))
        dc.DrawRoundedRectangle(rect.x, rect.y, rect.width, rect.height-3, 4)


    def DrawMenuBarBackground(self, dc, rect):
        """
        ...
        """

        # For office style, we simple draw a rectangle
        # with a gradient colouring.
        vertical = ArtManager.Get().GetMBVerticalGradient()

        dcsaver = DCSaver(dc)

        # Fill with gradient.
        startColour = self.menuBarFaceColour
        endColour   = ArtManager.Get().LightColour(startColour, 0)

        dc.SetPen(wx.Pen(endColour))
        dc.SetBrush(wx.Brush(endColour))
        dc.DrawRectangle(rect)


    def DrawToolBarBg(self, dc, rect):
        """
        ...
        """

        if not ArtManager.Get().GetRaiseToolbar():
            return

        # Fill with gradient.
        startColour = self.menuBarFaceColour()
        dc.SetPen(wx.Pen(startColour))
        dc.SetBrush(wx.Brush(startColour))
        dc.DrawRectangle(0, 0, rect.GetWidth(), rect.GetHeight())

#---------------------------------------------------------------------------

class MyListCtrlPnl(wx.Panel):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        # Create the listctrl.
        self.dvlc = dv.DataViewListCtrl(self,
                                        style=wx.BORDER_SIMPLE|
                                              dv.DV_ROW_LINES|
                                              dv.DV_HORIZ_RULES|
                                              dv.DV_VERT_RULES)

        # Give it some columns.
        # The ID col we'll customize a bit :
        self.dvlc.AppendTextColumn("Id", width=40)
        self.dvlc.AppendTextColumn("Artist", width=170)
        self.dvlc.AppendTextColumn("Title", width=260)
        self.dvlc.AppendTextColumn("Genre", width=80)

        # Load the data. Each item (row) is added as a sequence
        # of values whose order matches the columns.
        for itemvalues in musicdata:
            self.dvlc.AppendItem(itemvalues)

        # Set the layout so the listctrl fills the panel.
        self.Sizer = wx.BoxSizer()
        self.Sizer.Add(self.dvlc, 1, wx.EXPAND)

#---------------------------------------------------------------------------

class MyStatusBar(wx.StatusBar) :
    """
    Thanks to ???.
    Simple custom colorized StatusBar.
    """
    def __init__(self, parent, id) :
        wx.StatusBar.__init__(self, parent, id)

        #------------

        # Simplified init method.
        self.SetProperties()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        if wx.Platform == "__WXMSW__":
            self.SetDoubleBuffered(True)


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_PAINT, self.OnPaint)


    def OnPaint(self, event) :
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        self.Draw(dc)


    def Draw(self, dc) :
        """
        ...
        """

        dc.SetBackground(wx.Brush("GREY95"))
        dc.Clear()

        textVertOffset = 3      # Perfect for MSW.
        textHorzOffset = 5      # Arbitrary - looks nicer.

        dc.SetTextForeground("grey40")
        dc.DrawText(self.GetStatusText(), textHorzOffset, textVertOffset)

#---------------------------------------------------------------------------

class MyTitleBar(wx.Control):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, label, size):
        style = (wx.BORDER_NONE)
        super(MyTitleBar, self).__init__(parent,
                                         style=style)

        #------------

        # Attributes.
        self.parent = parent
        self.label = label
        self.size = size

        #------------

        # Simplified init method.
        self.SetBackground()
        self.SetProperties(label, size)
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetBackground(self):
        """
        ...
        """

        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)


    def SetProperties(self, label, size):
        """
        ...
        """

        self.label = label
        self.size = size

        self.label_font = self.GetFont()
        self.label_font.SetFamily(wx.SWISS)
        self.label_font.SetPointSize(size)
        self.label_font.SetWeight(wx.BOLD)
        self.SetFont(self.label_font)


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)


    def OnLeftDown(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnLeftDown(event)


    def OnLeftUp(self, event):
        """
        ...
        """

        self.GetTopLevelParent().OnLeftUp(event)


    def SetLabel(self, label):
        """
        ...
        """

        self.label = label
        self.Refresh()


    def DoGetBestSize(self):
        """
        ...
        """

        dc = wx.ClientDC(self)
        dc.SetFont(self.GetFont())

        textWidth, textHeight = dc.GetTextExtent(self.label)
        spacing = 10
        totalWidth = textWidth + (spacing)
        totalHeight = textHeight + (spacing)

        best = wx.Size(totalWidth, totalHeight)
        self.CacheBestSize(best)

        return best


    def GetLabel(self):
        """
        ...
        """

        return self.label


    def GetLabelColor(self):
        """
        ...
        """

        return self.foreground


    def GetLabelSize(self):
        """
        ...
        """

        return self.size


    def SetLabelColour(self, colour):
        """
        ...
        """

        self.labelColour = colour


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        gcdc = wx.GCDC(dc)

        gcdc.Clear()

        # Setup the GraphicsContext.
        gc = gcdc.GetGraphicsContext()

        # Get the working size we can draw in.
        width, height = self.GetSize()

        # Use the GCDC to draw the text.
        gcdc.GradientFillLinear((0, 0, width, height), "#ffffff",
                                wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENU),
                                wx.SOUTH)

        # Get the system font.
        gcdc.SetFont(self.GetFont())

        textWidth, textHeight = gcdc.GetTextExtent(self.label)
        tposx, tposy = ((width/2)-(textWidth/2), (height/3)-(textHeight/3))

        tposx += 0
        tposy += 0

        # Set position and text color.
        gcdc.SetTextForeground("white")
        gcdc.DrawText(self.label, int(tposx), int(tposy+1))

        gcdc.SetTextForeground(self.labelColour)
        gcdc.DrawText(self.label, int(tposx), int(tposy))

#---------------------------------------------------------------------------

class MyAboutDlg(wx.Frame):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        style = (wx.FRAME_SHAPED | wx.NO_BORDER |
                 wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
                 wx.SYSTEM_MENU | wx.CLOSE_BOX |
                 wx.NO_FULL_REPAINT_ON_RESIZE)
        wx.Frame.__init__(self,
                          parent,
                          id=-1,
                          title="About...",
                          style=style)

        #------------

        # Attributes.
        self.SetTransparent(0)
        self.opacity_in = 0
        self.opacity_out = 255
        self.deltaN = -70
        self.hasShape = False
        self.delta = wx.Point(0,0)

        #------------

        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
        # Return icons folder.
        self.icons_dir = wx.GetApp().GetIconsDir()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.OnTimerIn(self)
        self.CreateCtrls()
        self.BindEvents()

        #------------

        self.CenterOnParent(wx.BOTH)
        self.GetParent().Enable(False)

        #------------

        self.Show(True)

        #------------

        self.eventLoop = wx.GUIEventLoop()
        self.eventLoop.Run()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        Set the dialog properties (title, icon, transparency...).
        """

        frameIcon = wx.Icon(os.path.join(self.icons_dir,
                                         "icon_wxWidgets.ico"),
                            type=wx.BITMAP_TYPE_ICO)
        self.SetIcon(frameIcon)


    def OnTimerIn(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer1 = wx.Timer(self, -1)
        self.timer1.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)

        print("Fade-in was launched.")


    def OnTimerOut(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer2 = wx.Timer(self, -1)
        self.timer2.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)

        print("Fade-out was launched.")


    def AlphaCycle1(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_in += self.deltaN
        if self.opacity_in <= 0:
            self.deltaN = -self.deltaN
            self.opacity_in = 0

        if self.opacity_in >= 255:
            self.deltaN = -self.deltaN
            self.opacity_in = 255

            self.timer1.Stop()

        self.SetTransparent(self.opacity_in)

        print("Fade in = {}/255".format(self.opacity_in))


    def AlphaCycle2(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_out += self.deltaN
        if self.opacity_out >= 255:
            self.deltaN = -self.deltaN
            self.opacity_out = 255

        if self.opacity_out <= 0:
            self.deltaN = -self.deltaN
            self.opacity_out = 0

            self.timer2.Stop()

            wx.CallAfter(self.Destroy)

        self.SetTransparent(self.opacity_out)

        print("Fade out = {}/255".format(self.opacity_out))


    def CreateCtrls(self):
        """
        Make widgets for my dialog.
        """

        # Load a background bitmap.
        self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "skin_about_4.png"),
                             type=wx.BITMAP_TYPE_PNG)
        mask = wx.Mask(self.bmp, wx.RED)
        self.bmp.SetMask(mask)

        #------------

        self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))

        #------------

        if wx.Platform == "__WXGTK__":
            # wxGTK requires that the window be created before you can
            # set its shape, so delay the call to SetWindowShape until
            # this event.
            self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        else:
            # On wxMSW and wxMac the window has already
            # been created, so go for it.
            self.SetWindowShape()


    def BindEvents(self):
        """
        Bind all the events related to my dialog.
        """

        # Bind some events to an events handler.
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow)  # Panel right clic.
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)


    def SetWindowShape(self, event=None):
        """
        ...
        """

        # Use the bitmap's mask to determine the region.
        r = wx.Region(self.bmp)
        self.hasShape = self.SetShape(r)


    def OnEraseBackground(self, event):
        """
        ...
        """

        dc = event.GetDC()
        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)


    def OnLeftDown(self, event):
        """
        ...
        """

        self.CaptureMouse()
        x, y = self.ClientToScreen(event.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))


    def OnLeftUp(self, evt):
        """
        ...
        """

        if self.HasCapture():
            self.ReleaseMouse()


    def OnMouseMove(self, event):
        """
        ...
        """

        if event.Dragging() and event.LeftIsDown():
            x, y = self.ClientToScreen(event.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            self.Move(fp)


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.AutoBufferedPaintDCFactory(self)
        dc.DrawBitmap(self.bmp, 0, 0, True)

        #------------

        # These are strings.
        py_version = sys.version.split()[0]

        str1 = (('<font style="normal" family="default" color="orange" size="10" weight="bold">'
                 'Programming : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 'Python {}</font>').format(py_version))   # Python 3.7.2

        str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
                 'GUI toolkit : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 'wxPython {}</font>').format(wx.VERSION_STRING))  # wxPython 4.0.4  wx.VERSION_STRING

        str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
                 'Library : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 '{}</font>').format(wx.GetLibraryVersionInfo().VersionString))   # wxWidgets 3.0.5

        str4 = (('<font style="normal" family="default" color="blue" size="10" weight="bold">'
                 'Operating system : </font>'
                 '<font style="normal" family="default" color="black" size="10" weight="normal">'
                 '{}</font>').format(platform.system()))   # Windows

        str5 = (('<font style="normal" family="default" color="darkgreen" size="9" weight="normal">'
                 '{}</font>').format(self.app_name))   # Custom Gui 3

        str6 = (('<font style="normal" family="default" color="Black" size="8" weight="normal">'
                 'Right clic or Esc for Exit</font>'))

        #------------

        # Get the working size we can draw in.
        bw, bh = self.GetSize()

        # Use the GCDC to draw the text.
        dc.GradientFillLinear((0, 0, bw, bh),
                               "gray",
                               wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENU),
                               wx.NORTH)

        # Draw the about borders.
        dc.SetPen(wx.Pen(wx.Colour(0, 0, 0), 5))
        # dc.SetBrush(wx.Brush(wx.Colour(150, 150, 150)))
        # or
        dc.SetBrush(wx.Brush(wx.TRANSPARENT_BRUSH))
        dc.DrawRectangle(0, 0, bw, bh)

        #------------
        # Draw text.
        # Need width to calculate x position of str1.
        tw, th = fancytext.GetExtent(str1, dc)
        # Centered text.
        fancytext.RenderToDC(str1, dc, (bw-tw)/2, 30)

        #------------

        # Need width to calculate x position of str2.
        tw, th = fancytext.GetExtent(str2, dc)
        # Centered text.
        fancytext.RenderToDC(str2, dc, (bw-tw)/2, 50)

        #------------

        # Need width to calculate x position of str3.
        tw, th = fancytext.GetExtent(str3, dc)
        # Centered text.
        fancytext.RenderToDC(str3, dc, (bw-tw)/2, 70)

        #------------

        # Need width to calculate x position of str4.
        tw, th = fancytext.GetExtent(str4, dc)
        # Centered text.
        fancytext.RenderToDC(str4, dc, (bw-tw)/2, 90)

        #------------

        # Need width to calculate x position of str5.
        tw, th = fancytext.GetExtent(str5, dc)
        # Centered text.
        fancytext.RenderToDC(str5, dc, (bw-tw)/2, 130)

        #------------

        # Need width to calculate x position of str6.
        tw, th = fancytext.GetExtent(str6, dc)
        # Centered text.
        fancytext.RenderToDC(str6, dc, (bw-tw)/2, 195)


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_ESCAPE:
            self.OnCloseWindow(event)

        event.Skip()


    def OnCloseWindow(self, event):
        """
        ...
        """

        self.GetParent().Enable(True)
        self.eventLoop.Exit()
        self.Destroy()

#---------------------------------------------------------------------------

class MyPopupMenu(wx.Menu):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self, parent):
        wx.Menu.__init__(self)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Returns bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Simplified init method.
        self.CreatePopupMenu()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def CreatePopupMenu(self, event=None):
        """
        This method is called by the base class when it needs to popup
        the menu for the default EVT_RIGHT_DOWN event.  Just create
        the menu how you want it and return it from this function,
        the base class takes care of the rest.
        """

        bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                     "item_about.png"),
                        type=wx.BITMAP_TYPE_PNG)

        item = wx.MenuItem(self, id=wx.ID_ABOUT, text=" About")
        item.SetBitmap(bmp)
        self.Append(item)
        self.AppendSeparator()

        #------------

        bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                     "item_exit.png"),
                        type=wx.BITMAP_TYPE_PNG)

        if True or "__WXMSW__" in wx.PlatformInfo:
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            font.SetWeight(wx.BOLD)

        item = wx.MenuItem(self, id=wx.ID_EXIT, text=" Exit")
        item.SetBitmap(bmp)
        item.SetFont(font)
        self.Append(item)

        return self


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        # Bind the menu events to an events handler.
        self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT)


    def OnAbout(self, event):
        """
        ...
        """

        self.mainFrame = wx.GetApp().GetTopWindow()
        self.mainFrame.OnAbout(self)

        print("About icon was clicked.")


    def OnClose(self, event):
        """
        ...
        """

        self.mainFrame = wx.GetApp().GetTopWindow()
        self.mainFrame.OnCloseWindow(self)

        print("Close icon was clicked.")

#---------------------------------------------------------------------------

class MyWindow(wx.Control):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, label,
                 foreground, background,
                 normal, pressed=None):
        style = (wx.BORDER_NONE)
        super(MyWindow, self).__init__(parent,
                                       -1,
                                       style=style)

        #------------

        # Attributes.
        self.label = label
        self.foreground = foreground
        self.background = background

        if wx.Platform == "__WXGTK__":
            self.color = "#9e9d9d"

        else:
            self.color = "#b1b1b0"

        self.normal = normal
        self.pressed = pressed

        self._clicked = False

        #------------

        self.region = wx.Region(normal, wx.Colour(0, 0, 0, 0))

        #------------

        # Simplified init method.
        self.SetProperties(label, foreground, background)
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self, label, foreground, background):
        """
        ...
        """

        self.label = label
        self.foreground = foreground
        self.background = background
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
        self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDclick)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMotion)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)


    def SetLabel(self, label):
        """
        ...
        """

        self.label = label
        self.Refresh()


    def DoGetBestSize(self):
        """
        ...
        """

        return self.normal.GetSize()


    def GetLabel(self):
        """
        ...
        """

        return self.label


    def GetLabelColor(self):
        """
        ...
        """

        return self.foreground


    def Enable(self, *args, **kwargs):
        """
        ...
        """

        super(MyWindow, self).Enable(*args, **kwargs)
        self.Refresh()


    def Disable(self, *args, **kwargs):
        """
        ...
        """

        super(MyWindow, self).Disable(*args, **kwargs)
        self.Refresh()


    def PostEvent(self):
        """
        ...
        """

        event = wx.CommandEvent()
        event.SetEventObject(self)
        event.SetEventType(wx.EVT_BUTTON.typeId)
        wx.PostEvent(self, event)


    def OnSize(self, event):
        """
        ...
        """

        event.Skip()
        self.Refresh()


    def GetBackground(self):
        """
        ...
        """

        return self.background


    def OnPaint(self, event):
        """
        ...
        """

        dc = wx.BufferedPaintDC(self)
        dc.Clear()
        gcdc = wx.GCDC(dc)

        # Set the background color.
        if wx.Platform == "__WXGTK__":
            gcdc.SetBackground(wx.Brush("grey55"))
        else:
            gcdc.SetBackground(wx.Brush(self.background))

        gcdc.Clear()

        # Get the working rectangle we can draw in.
        rect = self.GetClientRect()

        # Font size and style.
        fontSize = self.GetFont().GetPointSize()

        if wx.Platform == "__WXGTK__":
            boldFont = wx.Font(fontSize-1, wx.DEFAULT,
                               wx.NORMAL, wx.NORMAL, False, "")
        else:
            boldFont = wx.Font(fontSize+2, wx.DEFAULT,
                               wx.NORMAL, wx.BOLD, False, "")

        if wx.Platform == "__WXMSW__":
            pen = wx.Pen(self.color, 1, wx.SOLID)

        else:
            pen = wx.Pen(self.color, 1, wx.SOLID)

        gcdc.SetPen(pen)

        x, y = self.GetSize()
        # x, y , width, height, radius
        gcdc.DrawRoundedRectangle (0, 0, 71, 25, 3)

        bitmap = self.normal

        w, h = bitmap.GetWidth(), bitmap.GetHeight()

        if self.clicked:
            bitmap = self.pressed or bitmap
        if not self.IsEnabled():
            bitmap = self.normal or bitmap

        # Draw a bitmap with an alpha channel.
        # image, x, y, transparency.
        dc.DrawBitmap(bitmap, 0, 0, True)

        if wx.Platform == "__WXGTK__":
            # Add the Caption.
            # White text - Shadow.
            rect = wx.Rect(rect.x, rect.y+3,
                           rect.width, 22)

        else:
            rect = wx.Rect(rect.x, rect.y+3,
                           rect.width, 20)

        dc.SetFont(boldFont)
        dc.SetTextForeground(wx.WHITE)
        dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)

        if wx.Platform == "__WXGTK__":
            # Add the Caption.
            # Black text.
            rect = wx.Rect(rect.x, rect.y,
                           rect.width, 21)

        else:
            rect = wx.Rect(rect.x, rect.y,
                           rect.width, 19)

        gcdc.SetFont(boldFont)
        # Get the text color.
        dc.SetTextForeground(self.foreground)
        dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)


    def SetClicked(self, clicked):
        """
        ...
        """

        if clicked != self._clicked:
            self._clicked = clicked
            self.Refresh()


    def GetClicked(self):
        """
        ...
        """

        return self._clicked


    clicked = property(GetClicked, SetClicked)
    def OnLeftDown(self, event):
        """
        ...
        """

        x, y = event.GetPosition()
        if self.region.Contains(x, y):
            self.clicked = True
            self.SetFocus()


    def OnLeftDclick(self, event):
        """
        ...
        """

        self.OnLeftDown(event)


    def OnLeftUp(self, event):
        """
        ...
        """

        if self.clicked:
            x, y = event.GetPosition()
            if self.region.Contains(x, y):
                self.PostEvent()
        self.clicked = False


    def OnMotion(self, event):
        """
        ...
        """

        if self.clicked:
            x, y = event.GetPosition()
            if not self.region.Contains(x, y):
                self.clicked = False


    def OnLeave(self, event):
        """
        ...
        """

        self.clicked = False


    def OnSetFocus(self, event):
        """
        ...
        """

        self.color = "white"
        self.Refresh()


    def OnKillFocus(self, event):
        """
        ...
        """

        if wx.Platform == "__WXGTK__":
            self.color = "#9e9d9d"

        else:
            self.color = "#b1b1b0"

        self.Refresh()


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_SPACE:
            self.PostEvent()
            return

        elif event.GetKeyCode() == wx.WXK_ESCAPE:
            self.GetTopLevelParent().OnCloseWindow(True)

        event.Skip()

#---------------------------------------------------------------------------

class MyButtonBox(wx.Panel):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, caption):
        style = (wx.NO_BORDER | wx.TAB_TRAVERSAL)
        super(MyButtonBox, self).__init__(parent,
                                          style=style)

        #------------

        # Attributes.
        self._caption = caption

        #------------

        # Simplified init method.
        self.DoLayout()

    #-----------------------------------------------------------------------

    def DoLayout(self):
        """
        ...
        """

        self._csizer = wx.BoxSizer(wx.VERTICAL)
        msizer = wx.BoxSizer(wx.HORIZONTAL)
        msizer.Add(self._csizer, 0 )
        self.SetSizer(msizer)


    def DoGetBestSize(self):
        """
        ...
        """

        size = super(MyButtonBox, self).DoGetBestSize()

        # Compensate for wide caption labels.
        tw = self.GetTextExtent(self._caption)[0]
        size.SetWidth(max(size.width, size.height))
        return size


    def AddItem(self, item):
        """
        Add a window or sizer item to the MyButtonBox.
        """

        self._csizer.Add(item, 0 )

#---------------------------------------------------------------------------

class MyTitleBarPnl(wx.Panel):
    """
    Thanks to Cody Precord.
    """
    def __init__(self, parent, id, size):
        style = (wx.NO_BORDER)
        super(MyTitleBarPnl, self).__init__(parent,
                                            id,
                                            size=size,
                                            style=style)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.CreateCtrls()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        self.SetBackgroundColour(wx.WHITE)


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyTitleBarPnl :", self.GetClientSize())

        #------------
        #------------

        # Add titleBar.
        self.titleBar = MyTitleBar(self,
                                   label=self.app_name,
                                   size=10)
        self.titleBar.SetPosition((0, 0))
        self.titleBar.SetSize((w, 24))
        self.titleBar.SetLabelColour("black")
        self.titleBar.SetToolTip("This is a customized title bar.")

        # Load an icon bitmap for titlebar.
        self.icon = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                           "icon_app_1.png"),
                              type=wx.BITMAP_TYPE_PNG)

        self.ico = wx.StaticBitmap(self.titleBar, -1, self.icon)
        self.ico.SetPosition((8, 1))
        self.ico.SetToolTip("This is a customized icon.")

        #------------
        #------------

        # Gloss Buttons box (titleBar).
        self.box3 = MyButtonBox(self.titleBar, "")   # Button Exit.
        self.box4 = MyButtonBox(self.titleBar, "")   # Button Maximize.
        self.box5 = MyButtonBox(self.titleBar, "")   # Button Reduce.
        self.box6 = MyButtonBox(self.titleBar, "")   # Button Roll.

        # Gloss Buttons bitmap.
        bmpa = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_exit_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpb = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_exit_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpc = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_maximize_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpd = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_maximize_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpe = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_reduce_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpf = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_reduce_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmpg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_roll_normal_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        bmph = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                      "btn_gloss_roll_selected_5.png"),
                         type=wx.BITMAP_TYPE_PNG)

        self.btn3 = MyWindow(self.box3, "", "black", "#9e9d9d", bmpa, bmpb)
        self.btn3.SetToolTip("This is a customized gloss button.")

        self.btn4 = MyWindow(self.box4, "", "black", "#9e9d9d", bmpc, bmpd)
        self.btn4.SetToolTip("This is a customized gloss button.")

        self.btn5 = MyWindow(self.box5, "", "black", "#9e9d9d", bmpe, bmpf)
        self.btn5.SetToolTip("This is a customized gloss button.")

        self.btn6 = MyWindow(self.box6, "", "black", "#9e9d9d", bmpg, bmph)
        self.btn6.SetToolTip("This is a customized gloss button.")

        self.box3.AddItem(self.btn3)
        self.box4.AddItem(self.btn4)
        self.box5.AddItem(self.btn5)
        self.box6.AddItem(self.btn6)

        #------------
        #------------

        w, h = self.GetSize()

        #------------

        self.box3.SetSize((25, 19))
        x1, y1 = self.box3.GetSize()
        self.box3.SetPosition((w-7-x1, h-6-y1))

        #------------

        self.box4.SetSize((25, 19))
        self.box4.SetPosition((w-7-(x1*2), h-6-y1))

        #------------

        self.box5.SetSize((25, 19))
        self.box5.SetPosition((w-7-(x1*3), h-6-y1))

        #------------

        self.box6.SetSize((25, 19))
        self.box6.SetPosition((w-7-(x1*4), h-6-y1))


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.ico.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
        self.ico.Bind(wx.EVT_LEFT_DOWN, self.OnRightDown)

        self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)
        self.btn4.Bind(wx.EVT_BUTTON, self.OnFullScreen)
        self.btn5.Bind(wx.EVT_BUTTON, self.OnIconfiy)
        self.btn6.Bind(wx.EVT_BUTTON, self.OnRoll)

        self.Bind(wx.EVT_SIZE, self.OnResize)


    def OnRightDown(self, event):
        """
        ...
        """

        self.PopupMenu(MyPopupMenu(self), event.GetPosition())

        print("Right down.")


    def OnResize(self, event):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyTitleBarPnl :", self.GetClientSize())

        #------------
        #------------

        self.titleBar.SetSize((w, 24))

        #------------

        x1, y1 = self.box3.GetSize()

        self.box3.SetPosition((w-7-x1, h-6-y1))
        self.box4.SetPosition((w-7-(x1*2), h-6-y1))
        self.box5.SetPosition((w-7-(x1*3), h-6-y1))
        self.box6.SetPosition((w-7-(x1*4), h-6-y1))

        #------------

        self.Refresh()

        print("On resize was clicked.")


    def OnRoll(self, event):
        """
        ...
        """

        self.GetParent().OnRoll(True)

        print("Roll/unRoll button was clicked.")


    def OnIconfiy(self, event):
        """
        ...
        """

        self.GetParent().OnIconfiy(self)

        print("Iconfiy button was clicked.")


    def OnFullScreen(self, event):
        """
        ...
        """

        self.GetParent().OnFullScreen(self)

        print("FullScreen button was clicked.")


    def OnBtnClose(self, event):
        """
        ...
        """

        self.GetParent().OnCloseWindow(self)

        print("Close button was clicked.")

#---------------------------------------------------------------------------

class MyMainPnl(wx.Panel):
    """
    ...
    """
    def __init__(self, parent, id, size):
        style = (wx.NO_BORDER | wx.TAB_TRAVERSAL)
        super(MyMainPnl, self).__init__(parent,
                                        id=int(ID_MAIN_PNL),
                                        size=size,
                                        style=style)

        #------------

        # Attributes.
        self.parent = parent

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()

        #------------

        # Colourdb.
        wx.lib.colourdb.updateColourDB()

        # Create a colour list from the colourdb database.
        self.colour_list = wx.lib.colourdb.getColourList()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.CreateCtrls()
        self.DoLayout()
        self.BindEvents()

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        if wx.Platform == "__WXMSW__":
            self.SetDoubleBuffered(True)

        # Read config file.
        self.SetBackgroundColour(self.config.Read("Color3"))


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyMainPnl :", self.GetClientSize())

        #------------
        #------------

        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

        #------------
        #------------

        # Create data view control.
        self.list = MyListCtrlPnl(self)

        #------------
        #------------

        self.txt = wx.StaticText(self,
                                 -1,
                                 label="Hello World !")
        self.txt.SetForegroundColour("black")
        self.txt.SetFont(font)

        #------------
        #------------

        # Thanks to MCOW.
        # Buttons.
        self.btn1 = SBB.ShapedBitmapButton(self, ID_BTN_FULLSCREEN,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="Fullscreen",
            labelForeColour=wx.WHITE,
            labelPosition=(35, 8),
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        self.btn1.SetFocus() # Necessary for Linux.

        #------------

        self.btn2 = SBB.ShapedBitmapButton(self, ID_BTN_ABOUT,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="About",
            labelForeColour=wx.WHITE,
            labelPosition=(50, 8),
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------

        self.btn3 = SBB.ShapedBitmapButton(self, ID_BTN_QUIT,
            bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                          "adbRect.png"),
                             type=wx.BITMAP_TYPE_PNG),

            pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                              "adbRect-pressed.png"),
                                 type=wx.BITMAP_TYPE_PNG),

            hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                            "adbRect-hover.png"),
                               type=wx.BITMAP_TYPE_PNG),

            disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
                                               "adbRect-disabled.png"),
                                  type=wx.BITMAP_TYPE_PNG),

            label="Quit",
            labelForeColour=wx.WHITE,
            labelPosition=(50, 8),
            labelFont=wx.Font(9,
                              wx.FONTFAMILY_DEFAULT,
                              wx.FONTSTYLE_NORMAL,
                              wx.FONTWEIGHT_BOLD),
            style=wx.BORDER_NONE)

        #------------
        #------------

        self.line = wx.StaticLine(self, -1,
                                  pos=(0, 70),
                                  size=(-1, -1),
                                  style=wx.LI_HORIZONTAL)

        #------------
        #------------

        # Create a choice widget.
        self.choice = wx.Choice(self,
                                -1,
                                pos=(-1, -1),
                                size=(131, -1),
                                choices=self.colour_list,
                                style=wx.CB_SORT)

        # Select item 277 in choice list to show.
        # self.choice.SetSelection(277)  # GREY95
        # Read config file.
        self.choice.SetSelection(self.config.ReadInt("Item3"))

        item = self.choice.GetCurrentSelection()
        bgcolour = self.choice.GetStringSelection()
        print("Item : %s , %s" % (item, bgcolour))


    def DoLayout(self):
        """
        ...
        """

        txtSizer = wx.BoxSizer(wx.VERTICAL)
        txtSizer.Add(self.txt, 0, wx.LEFT, 10)

        sizerList = wx.BoxSizer(wx.VERTICAL)
        sizerList.Add(self.list, 1,
                      wx.LEFT|wx.TOP|wx.BOTTOM|
                      wx.EXPAND|wx.ALIGN_TOP, 10)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(txtSizer, 0, wx.BOTTOM, 0)
        sizer.Add(self.btn1, 1, wx.ALL, 10)
        sizer.Add(self.btn2, 1, wx.ALL, 10)
        sizer.Add(self.line, 0, wx.EXPAND|wx.ALL, 10)
        sizer.Add(self.choice, 0, wx.ALL, 10)
        sizer.Add(self.btn3, 1, wx.ALL, 10)

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(sizerList, 1,
                      wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5)
        mainSizer.Add(sizer, 0, wx.ALIGN_BOTTOM|wx.ALL, 5)

        self.SetSizer(mainSizer)
        self.Layout()


    def BindEvents(self):
        """
        Bind some events to an events handler.
        """

        self.Bind(wx.EVT_CHOICE, self.OnChoice)

        self.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_MAIN_PNL)
        self.btn1.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_FULLSCREEN)
        self.btn2.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_ABOUT)
        self.btn3.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_BTN_QUIT)

        self.btn1.Bind(wx.EVT_BUTTON, self.OnFullScreen)
        self.btn2.Bind(wx.EVT_BUTTON, self.OnAbout)
        self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)


    def OnInfo(self, event):
        """
        ...
        """

        event_id = event.GetId()

        if event_id == ID_MAIN_PNL:
            self.GetParent().SetStatusText(text="Hello world !")

        elif event_id == ID_BTN_FULLSCREEN:
            self.GetParent().SetStatusText(text="Fullscreen")

        elif event_id == ID_BTN_ABOUT:
            self.GetParent().SetStatusText(text="About")

        elif event_id == ID_BTN_QUIT:
            self.GetParent().SetStatusText(text="Quit the program")

        else:
            # Tell the event system to continue
            # looking for an event handler, so the
            # default handler will get called.
            event.Skip()


    def OnChoice(self, event):
        """
        ...
        """

        item = event.GetSelection()
        bgcolour = self.choice.GetStringSelection()
        print("New item : %s , %s" % (item, bgcolour))

        # Change colour of the panel to the selected colour...
        self.SetBackgroundColour(bgcolour)

        frame = self.GetTopLevelParent()
        frame.SetBackgroundColour(bgcolour)

        # Write config file.
        self.config.WriteInt("Item3", self.choice.GetCurrentSelection())
        self.config.Write("Color3", self.choice.GetStringSelection())
        self.config.Flush()

        self.Refresh()

        print("OnChoice button was clicked.")


    def OnAbout(self, event):
        """
        ...
        """

        self.GetParent().OnAbout(self)

        print("FullScreen button was clicked.")


    def OnFullScreen(self, event):
        """
        ...
        """

        self.GetParent().OnFullScreen(self)

        print("FullScreen button was clicked.")


    def OnBtnClose(self, event):
        """
        ...
        """

        self.GetParent().OnCloseWindow(self)

        print("Close button was clicked.")

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    """
    Thanks to Robin Dunn.
    """
    def __init__(self):
        style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
                 wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
                 wx.RESIZE_BORDER | wx.NO_FULL_REPAINT_ON_RESIZE|
                 wx.STAY_ON_TOP)
        super(MyFrame, self).__init__(None,
                                      -1,
                                      title="",
                                      style=style)

        #------------

        wx.SystemOptions.SetOption("msw.remap", "0")

        #------------

        # Attributes.
        self.SetTransparent(0)
        self.opacity_in = 0
        self.opacity_out = 255
        self.deltaN = -70
        self.delta = wx.Point(0,0)

        #------------

        # Return config file.
        self.config = wx.GetApp().GetConfig()
        # Return application name.
        self.app_name = wx.GetApp().GetAppName()
        # Return bitmaps folder.
        self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
        # Return icons folder.
        self.icons_dir = wx.GetApp().GetIconsDir()

        #------------

        # Colourdb.
        wx.lib.colourdb.updateColourDB()

        # Create a colour list from the colourdb database.
        self.colour_list = wx.lib.colourdb.getColourList()

        #------------

        # Simplified init method.
        self.SetProperties()
        self.OnTimerIn(self)
        self.CreateMenu()
        self.CreateStatusBar()
        self.CreateCtrls()
        self.BindEvents()
        self.DoLayout()

        #------------

        # Thanks to Ray Pasco.
        # Initialize to the current state.
        self.unrolledFrameClientSize_size = self.GetClientSize()
        self.isRolled = False

        #------------

        self.CenterOnScreen(wx.BOTH)

        #------------

        self.Show(True)

    #-----------------------------------------------------------------------

    def SetProperties(self):
        """
        ...
        """

        self.SetTitle(self.app_name)
        self.SetClientSize((600, 380))
        self.SetMinSize((128, 82))

        # Read config file.
        self.SetBackgroundColour(self.config.Read("Color3"))

        #------------

        frameIcon = wx.Icon(os.path.join(self.icons_dir,
                                         "icon_wxWidgets.ico"),
                            type=wx.BITMAP_TYPE_ICO)
        self.SetIcon(frameIcon)


    def OnTimerIn(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer1 = wx.Timer(self, -1)
        self.timer1.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)

        print("Fade-in was launched.")


    def OnTimerOut(self, evt):
        """
        Thanks to Pascal Faut.
        """

        self.timer2 = wx.Timer(self, -1)
        self.timer2.Start(1)
        self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)

        print("Fade-out was launched.")


    def AlphaCycle1(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_in += self.deltaN
        if self.opacity_in <= 0:
            self.deltaN = -self.deltaN
            self.opacity_in = 0

        if self.opacity_in >= 255:
            self.deltaN = -self.deltaN
            self.opacity_in = 255

            self.timer1.Stop()

        self.SetTransparent(self.opacity_in)

        print("Fade in = {}/255".format(self.opacity_in))


    def AlphaCycle2(self, *args):
        """
        Thanks to Pascal Faut.
        """

        self.opacity_out += self.deltaN
        if self.opacity_out >= 255:
            self.deltaN = -self.deltaN
            self.opacity_out = 255

        if self.opacity_out <= 0:
            self.deltaN = -self.deltaN
            self.opacity_out = 0

            self.timer2.Stop()
            wx.CallAfter(self.Destroy)
            wx.Exit()

        self.SetTransparent(self.opacity_out)

        print("Fade out = {}/255".format(self.opacity_out))


    def CreateMenu(self):
        """
        ...
        """

        # FlatMenuBar.
        self.menuBar = FM.FlatMenuBar(self,
                                      wx.ID_ANY,
                                      32, 4,
                                      options=FM.FM_OPT_IS_LCD)

        # FM.StyleDefault or FM.Style2007
        # FM.StyleXP or FM.StyleVista
        self.newMyTheme = self.menuBar.GetRendererManager().AddRenderer(MyMenuRenderer())
        self.menuBar.GetRendererManager().SetTheme(self.newMyTheme)

        #------------

        # Set an icon to the exit/help menu item.
        exitImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                         "item_exit.png"),
                            type=wx.BITMAP_TYPE_PNG)

        helpImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
                                         "item_about.png"),
                            type=wx.BITMAP_TYPE_PNG)

        #------------
        #------------

        # File Menu.
        self.file_menu = FM.FlatMenu()

        # Create the menu items.
        item = FM.FlatMenuItem(self.file_menu,
                               ID_FULLSCREEN,
                               "&Fullscreen\tCtrl+F",
                               "Fullscreen",
                               wx.ITEM_NORMAL,
                               None)
        item.SetTextColour("black")
        self.file_menu.AppendItem(item)
        self.file_menu.AppendSeparator()


        item = FM.FlatMenuItem(self.file_menu,
                               wx.ID_EXIT,
                               "&Quit\tCtrl+Q",
                               "Quit the program",
                               wx.ITEM_NORMAL,
                               None,
                               exitImg)
        # Demonstrate how to set custom font
        # and text colour to a FlatMenuItem.
        item.SetFont(wx.Font(-1, wx.FONTFAMILY_DEFAULT,
                             wx.FONTSTYLE_NORMAL,
                             wx.FONTWEIGHT_BOLD,
                             False, ""))
        item.SetTextColour("#d34725")

        self.file_menu.AppendItem(item)

        #------------

        # Add Create background bitmap.
        self.file_menu.SetBackgroundBitmap(CreateBackgroundBitmap())

        #------------
        #------------

        # Help Menu.
        self.help_menu = FM.FlatMenu()

        # Create the menu items.
        item = FM.FlatMenuItem(self.help_menu,
                               wx.ID_ABOUT,
                               "&About\tCtrl+A",
                               "About",
                               wx.ITEM_NORMAL,
                               None,
                               helpImg)
        item.SetTextColour("black")
        self.help_menu.AppendItem(item)
        self.help_menu.AppendSeparator()

        item = FM.FlatMenuItem(self.help_menu,
                               ID_HELLO,
                               "Hello !",
                               "Hello !",
                               wx.ITEM_NORMAL,
                               None)
        item.SetTextColour("black")
        self.help_menu.AppendItem(item)

        #------------

        # Add Create background bitmap.
        self.help_menu.SetBackgroundBitmap(CreateBackgroundBitmap())

        #------------
        #------------

        # Menu background color.
        self.menuBar.SetBackgroundColour(wx.Colour("GREY95"))

        # Add menu to the menu bar.
        self.menuBar.Append(self.file_menu, "&File")
        self.menuBar.Append(self.help_menu, "&Help")


    def CreateStatusBar(self):
        """
        ...
        """

        self.sb = MyStatusBar(self, -1)
        self.sb.SetBackgroundColour(wx.Colour("GREY95"))
        self.sb.SetStatusText("Hello world !")

        self.SetStatusBar(self.sb)


    def CreateCtrls(self):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("MyFrame :", self.GetClientSize())

        #------------
        #------------

        self.titleBarPnl = MyTitleBarPnl(self, -1, (w, 24))
        self.titleBarPnl.SetPosition((0, 0))
        print("self.titleBarPnl :", self.titleBarPnl.GetSize())

        #------------

        # self.line = wx.StaticLine(self, -1,
        #                          pos=(0, 70),
        #                          size=(-1, -1),
        #                          style=wx.LI_HORIZONTAL)

        #------------

        self.mainPnl = MyMainPnl(self, -1, (w, h-25))
        self.mainPnl.SetPosition((0, 25))
        print("self.mainPnl :", self.mainPnl.GetSize())


    def BindEvents(self):
        """
        ...
        """

        self.titleBarPnl.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

        self.Bind(wx.EVT_SIZE, self.OnResize)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyUp)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        self.Bind(wx.EVT_MENU, self.OnFullScreen, id=ID_FULLSCREEN)
        self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT)


    def DoLayout(self):
        """
        ...
        """

        # MainSizer is the top-level one that manages everything.
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        mbSizer = wx.BoxSizer(wx.HORIZONTAL)
        mbSizer.Add(self.menuBar, 1, wx.ALL, 0)

        mainSizer.Add(self.titleBarPnl, 1, wx.EXPAND, 0)
        # mainSizer.Add(self.line, 0, wx.EXPAND, 0)
        mainSizer.Add(mbSizer, 0, wx.EXPAND, 0)
        mainSizer.Add(self.mainPnl, 1, wx.EXPAND, 0)

        # Finally, tell the panel to use the sizer for layout.
        self.SetSizer(mainSizer)
        self.Layout()


    def OnRoll(self, event) :
        """
        Thanks to Ray Pasco.
        """

        if not bool(self.isRolled) :
        # Set the flag to the state we want regardless of whether
        # or not it's in currently in the opposite state.
           self.RollUnRoll(wantToRoll=True)

        elif self.isRolled :   # UnRoll.
           # Set the flag to the state we want regardless of whether
           # or not it's in currently in the opposite state.
           self.RollUnRoll(wantToRoll=False)

        print("OnRoll :", self.GetClientSize())


    def RollUnRoll(self, wantToRoll) :
        """
        Thanks to Ray Pasco.
        """

        # Save the current size only if the Frame is not rolled up.
        if not bool(self.isRolled) :
            self.unrolledFrameClientSize_size = self.GetClientSize()

        if bool(wantToRoll) :   # UnRoll.
            # Set size (45).
            self.SetClientSize((self.unrolledFrameClientSize_size[0], 45))
            # Set to match this new state.
            self.isRolled = True

        else :   # Roll
            self.SetClientSize(self.unrolledFrameClientSize_size)
            # Set to match this new state.
            self.isRolled = False

        print("RollUnRoll :", self.GetClientSize())


    def OnAbout(self, event):
        """
        ...
        """

        self.dialog = MyAboutDlg(self)


    def OnLeftDown(self, event):
        """
        ...
        """

        self.CaptureMouse()
        x, y = self.ClientToScreen(event.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))


    def OnLeftUp(self, evt):
        """
        ...
        """

        if self.HasCapture():
            self.ReleaseMouse()


    def OnMouseMove(self, event):
        """
        ...
        """

        if event.Dragging() and event.LeftIsDown():
            x, y = self.ClientToScreen(event.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            self.Move(fp)


    def OnIconfiy(self, event):
        """
        ...
        """

        self.Iconize()


    def OnResize(self, event):
        """
        ...
        """

        w, h = self.GetClientSize()
        print("self :", self.GetClientSize())

        #------------
        #------------

        self.titleBarPnl.SetSize((w, 24))
        # self.line.SetSize((w, -1))
        self.menuBar.SetSize((w, -1))
        self.mainPnl.SetSize((w, h-47))

        #------------

        self.Refresh()


    def OnFullScreen(self, event):
        """
        ...
        """

        self.ShowFullScreen(not self.IsFullScreen(),
                            wx.FULLSCREEN_NOCAPTION)


    def OnKeyUp(self, event):
        """
        ...
        """

        if event.GetKeyCode() == wx.WXK_ESCAPE:
            # Close the frame, no action.
            self.OnCloseWindow(event)
        event.Skip()


    def OnBtnClose(self, event):
        """
        ...
        """

        self.Close()


    def OnCloseWindow(self, event):
        """
        Quit this application.
        """

        # self.Destroy()
        self.OnTimerOut(self)

        print("Exit application.")

#---------------------------------------------------------------------------

class MyApp(wx.App):
    """
    Thanks to Andrea Gavana.
    """
    def OnInit(self):

        #------------

        self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)

        #------------

        self.SetAppName("Custom Gui 3")

        #------------

        self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]

        #------------

        frame = MyFrame()
        self.SetTopWindow(frame)
        frame.Show(True)

        return True

    #-----------------------------------------------------------------------

    def GetInstallDir(self):
        """
        Returns the installation directory for my application.
        """

        return self.installDir


    def GetIconsDir(self):
        """
        Returns the icons directory for my application.
        """

        icons_dir = os.path.join(self.installDir, "icons")
        return icons_dir


    def GetBitmapsDir(self):
        """
        Returns the bitmaps directory for my application.
        """

        bitmaps_dir = os.path.join(self.installDir, "bitmaps")
        return bitmaps_dir


    def GetConfig(self):
        """
        Returns the config file for my application.
        """

        config = wx.FileConfig(appName="Custom Gui",
                               localFilename=os.path.join(self.installDir,
                                                          "options"))
        return config

#---------------------------------------------------------------------------

def main():
    app = MyApp(False)
    app.MainLoop()

#---------------------------------------------------------------------------

if __name__ == "__main__" :
    main()
}}}
--------
= Download source =
[[attachment:source.zip]]

--------
= Additional Information =
'''Link :'''

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

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....