How to add a menu bar in the title bar 308-406

Custom Renderer lines 308-406 blue background of selected rows
mail@pastecode.io avatar
unknown
python
2 years ago
52 kB
12
Indexable
Never
# 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.lib.mixins.listctrl as listmix
import wx.dataview as dv
import rectshapedbitmapbuttonTwo as SBBTwo
import data

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

# musicdata = sorted(data.musicdata)

# def SwitchRGBtoBGR
# def CreateBackgroundBitmap
# class MyMenuRenderer
# class MyMenuBar
# 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("#fec54c"))
    mem_dc.DrawRectangle(0, 15, 122, 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 MyMenuBar(FM.FlatMenuBar):
    """
    A custom renderer class for FlatMenu.
    """

    def __init__(self, parent):
        FM.FlatMenuBar.__init__(
            self, parent, id=wx.ID_ANY, iconSize=32, spacer=3, options=FM.FM_OPT_IS_LCD
        )

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

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

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

        self.parent = parent

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

        # FM.StyleDefault or FM.Style2007
        # FM.StyleXP or FM.StyleVista
        self.newMyTheme = self.GetRendererManager().AddRenderer(MyMenuRenderer())
        self.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.SetBackgroundColour(wx.Colour(wx.WHITE))

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

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

        # Simplified init method.
        self.SetProperties()

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

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

        self.SetMaxSize((91, 20))


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


class MyCustomRenderer(dv.DataViewCustomRenderer):
    def __init__(self, log, *args, **kw):
        dv.DataViewCustomRenderer.__init__(self, *args, **kw)
        self.log = log
        self.value = None

    def SetValue(self, value):
        # self.log.write('MyCustomRenderer.SetValue: %s\n' % value)
        self.value = value
        return True

    def GetValue(self):
        # self.log.write('MyCustomRenderer.GetValue\n')
        return self.value

    def GetSize(self):
        # Return the size needed to display the value.  The renderer
        # has a helper function we can use for measuring text that is
        # aware of any custom attributes that may have been set for
        # this item.
        value = self.value if self.value else ""
        size = self.GetTextExtent(value)
        return size

    def Render(self, rect, dc, state):
        if state != 0:
            print("Render: %s, %d\n" % (rect, state))

        if state & dv.DATAVIEW_CELL_SELECTED:
            # we'll draw a shaded background to see if the rect correctly
            # fills the cell
            dc.SetBrush(wx.Brush("#0066ff"))
            dc.SetPen(wx.TRANSPARENT_PEN)
            rect.Deflate(1, 1)
            dc.DrawRoundedRectangle(rect, 2)

        # And then finish up with this helper function that draws the
        # text for us, dealing with alignment, font and color
        # attributes, etc
        value = self.value if self.value else ""
        self.RenderText(
            value,
            4,  # x-offset, to compensate for the rounded rectangles
            rect,
            dc,
            state,  # wxDataViewCellRenderState flags
        )
        return True


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


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_THEME
            # | dv.DV_ROW_LINES
            | dv.DV_HORIZ_RULES | dv.DV_VERT_RULES | dv.DV_MULTIPLE,
        )

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

        # Now we create some columns.
        c0 = self.dvlc.AppendTextColumn("Id", 0, width=40)
        c0.Alignment = wx.ALIGN_RIGHT
        c0.MinWidth = 100

        # Load the data. Each item (row) is added as a sequence
        # of values whose order matches the columns.
        for title, col, width in [
            ("Artist", 1, 170),
            ("Title", 2, 260),
            ("Genre", 3, 80),
        ]:
            renderer = MyCustomRenderer(self, mode=dv.DATAVIEW_CELL_EDITABLE)
            column = dv.DataViewColumn(title, renderer, col, width=width)
            column.Alignment = wx.ALIGN_LEFT
            self.dvlc.AppendColumn(column)

        for itemvalues in musicdata:
            self.dvlc.AppendItem(itemvalues)
            print(itemvalues)

        # Set the layout so the listctrl fills the panel.
        self.Sizer = wx.BoxSizer(wx.VERTICAL)
        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(wx.WHITE))
        dc.Clear()

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

        dc.SetTextForeground("gray")
        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 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.CreateMenu()
        self.CreateCtrls()
        self.BindEvents()
        self.DoLayout()

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

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

        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.SetBackgroundColour(wx.WHITE)

    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 CreateMenu(self):
        """
        ...
        """

        self.menuBar = MyMenuBar(self)

    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(wx.WHITE))
        # 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 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)

        self.Bind(wx.EVT_MENU, self.OnFullScreen, id=ID_FULLSCREEN)
        self.Bind(wx.EVT_MENU, self.OnBtnClose, id=wx.ID_EXIT)

    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)
        mainSizer.Add((10, 1), 0, wx.ALL, 0)
        mainSizer.Add(self.menuBar, 1)
        mainSizer.Add((20, 1), 0, wx.EXPAND, 0)

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

        self.SetSizer(mainSizer)
        self.Layout()

    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.
        brush = wx.WHITE
        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("white")
            gcdc.DrawText("", int(tposx), int(tposy + 1))

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

        else:
            gcdc.SetTextForeground("white")
            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.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="grey" 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

        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="gray" size="9" weight="normal">'
            "{}</font>"
        ).format(
            self.app_name
        )  # Custom Gui 4

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

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

        # Return image size.
        bw, bh = self.bmp.GetWidth(), self.bmp.GetHeight()

        # 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 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.")

    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=int(ID_MAIN_PNL), size=size, style=style
        )

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

        # Attributes.
        self.parent = parent

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

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

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

    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.line = wx.StaticLine(
            self, -1, pos=(0, 70), size=(-1, -1), style=wx.LI_HORIZONTAL
        )

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

        txtSizer = wx.BoxSizer(wx.VERTICAL)

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

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(txtSizer, 0, wx.BOTTOM, 15)
        sizer.Add(self.line, 0, wx.EXPAND | wx.ALL, 10)

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

        self.SetSizer(mainSizer)
        self.Layout()

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

        self.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_MAIN_PNL)

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

        event_id = event.GetId()

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

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

    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 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.AcceleratorTable()
        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(wx.WHITE))
        self.SetTitle(self.app_name)
        self.SetClientSize((600, 380))
        self.SetMinSize((128, 60))

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

        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 AcceleratorTable(self):
        """
        ...
        """

        table = wx.AcceleratorTable(
            [
                (wx.ACCEL_CTRL, ord("F"), ID_FULLSCREEN),
                (wx.ACCEL_CTRL, ord("Q"), wx.ID_EXIT),
                (wx.ACCEL_CTRL, ord("A"), wx.ID_ABOUT),
            ]
        )
        self.SetAcceleratorTable(table)

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

        self.sb = MyStatusBar(self, -1)
        self.sb.SetBackgroundColour(wx.Colour(wx.WHITE))
        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)

        mainSizer.Add(self.titleBarPnl, 1, wx.EXPAND, 0)
        # mainSizer.Add(self.line, 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 (25).
            self.SetClientSize((self.unrolledFrameClientSize_size[0], 25))
            # 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.mainPnl.SetSize((w, h - 25))  # 25

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

        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)
            sys.exit()
        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 main():
    app = MyApp(False)
    app.MainLoop()


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

if __name__ == "__main__":
    main()