= How to create a customized settings dialog (Phoenix) =
'''Keywords :''' Dialog, Setting, ListBox, FourWaySplitter, Scrolledpanel, StaticBoxSizer, StaticBox.

 . <<TableOfContents>>

--------
= Demonstrating : =
__'''''Tested''' py3.x, wx4.x and Win10. ''__

Are you ready to use some samples ? ;)

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

--------
== Settings dialog ==
{{attachment:img_sample_one.png}}

'''ICON''' file : [[attachment:icon_wxWidgets.ico]]

{{{#!python
# sample_one.py

import sys
import os
import wx
import wx.lib.agw.fourwaysplitter as FWS
import wx.lib.scrolledpanel as scrolled

# class MyGeneralPane
# class MyInterfacePane
# class MySourcePane
# class MyLanguagePane
# class MyControlPane
# class MySplitterPanel
# class MySettingDialog
# class MyFrame
# class MyApp

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

class MyGeneralPane(wx.Panel):
    """
    ...
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent,
                          style=wx.BORDER_THEME |
                                wx.TAB_TRAVERSAL)

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


        labels = 'One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Firteen'.split()

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

        # Font, size and style.
        font = self.GetFont().GetPointSize()
        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

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

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)

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

        sbox = wx.StaticBox(self, -1, " General : ")
        sbox.SetForegroundColour("#0068c6")
        sbox.SetFont(font)

        ssizer = wx.StaticBoxSizer(sbox, wx.VERTICAL)
        sizer.Add(ssizer, 1, wx.EXPAND | wx.ALL, 10)

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

        spanel = scrolled.ScrolledPanel(self, -1)
        ssizer.Add(spanel, 1, wx.EXPAND)

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

        spsizer = wx.BoxSizer(wx.VERTICAL)
        spanel.SetSizer(spsizer)
        for label in labels:
            self.chkbx = wx.CheckBox(spanel,
                                      label=label,
                                      size=(-1,-1))
            spsizer.Add(self.chkbx, flag=wx.ALL, border=10)

            self.Bind(wx.EVT_CHECKBOX, self.OnPass, self.chkbx)

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

        spanel.SetupScrolling(scroll_x=False,
                              scroll_y=True,
                              rate_y=10,
                              scrollToTop=True)

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

        sizer.Layout()

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

    def OnPass(self, event):
        """
        Just grouping the empty event handlers together.
        """

        print("Hello 1 !")

        pass

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

class MyInterfacePane(wx.Panel):
    """
    ...
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent,
                          style=wx.BORDER_THEME |
                                wx.TAB_TRAVERSAL)

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

        labels = 'One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Firteen'.split()

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

        # Font, size and style.
        font = self.GetFont().GetPointSize()
        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

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

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)

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

        sbox = wx.StaticBox(self, -1, " User interface : ")
        sbox.SetForegroundColour("#0068c6")
        sbox.SetFont(font)

        ssizer = wx.StaticBoxSizer(sbox, wx.VERTICAL)
        sizer.Add(ssizer, 1, wx.EXPAND | wx.ALL, 10)

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

        spanel = scrolled.ScrolledPanel(self, -1)
        ssizer.Add(spanel, 1, wx.EXPAND)

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

        spsizer = wx.BoxSizer(wx.VERTICAL)
        spanel.SetSizer(spsizer)
        for label in labels:
            self.btn = wx.Button(spanel,
                            label=label,
                            size=(-1,50))
            spsizer.Add(self.btn, flag=wx.ALL, border=2)

            self.Bind(wx.EVT_BUTTON, self.OnPass, self.btn)

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

        spanel.SetupScrolling(scroll_x=False,
                              scroll_y=True,
                              rate_y=10,
                              scrollToTop=False)

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

        sizer.Layout()

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

    def OnPass(self, event):
        """
        Just grouping the empty event handlers together.
        """

        print("Hello 2 !")

        pass

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

class MySourcePane(wx.Panel):
    """
    ...
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent,
                          style=wx.BORDER_THEME |
                                wx.TAB_TRAVERSAL)

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

        labels = 'One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Firteen'.split()

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

        # Font, size and style.
        font = self.GetFont().GetPointSize()
        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

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

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)

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

        sbox = wx.StaticBox(self, -1, " Path : ")
        sbox.SetForegroundColour("#0068c6")
        sbox.SetFont(font)

        ssizer = wx.StaticBoxSizer(sbox, wx.VERTICAL)
        sizer.Add(ssizer, 1, wx.EXPAND | wx.ALL, 10)

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

        spanel = scrolled.ScrolledPanel(self, -1)
        ssizer.Add(spanel, 1, wx.EXPAND)

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

        spsizer = wx.BoxSizer(wx.VERTICAL)
        spanel.SetSizer(spsizer)
        for label in labels:
            self.chkbx = wx.CheckBox(spanel,
                                      label=label,
                                      size=(-1,-1))
            spsizer.Add(self.chkbx, flag=wx.ALL, border=10)

            self.Bind(wx.EVT_CHECKBOX, self.OnPass, self.chkbx)

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

        spanel.SetupScrolling(scroll_x=False,
                              scroll_y=True,
                              rate_y=10,
                              scrollToTop=False)

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

        sizer.Layout()

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

    def OnPass(self, event):
        """
        Just grouping the empty event handlers together.
        """

        print("Hello 3 !")

        pass

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

class MyLanguagePane(wx.Panel):
    """
    ...
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent,
                          style=wx.BORDER_THEME |
                                wx.TAB_TRAVERSAL)

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

        labels = 'One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Firteen'.split()

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

        # Font, size and style.
        font = self.GetFont().GetPointSize()
        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

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

        sizer = wx.BoxSizer(orient=wx.VERTICAL)
        self.SetSizer(sizer)

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

        sbox = wx.StaticBox(self, -1, " Language : ")
        sbox.SetForegroundColour("#0068c6")
        sbox.SetFont(font)

        ssizer = wx.StaticBoxSizer(sbox, orient=wx.VERTICAL)
        sizer.Add(ssizer, 1, wx.EXPAND | wx.ALL, 10)

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

        spanel = scrolled.ScrolledPanel(self, -1)
        ssizer.Add(spanel, 1, wx.EXPAND)

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

        spsizer = wx.BoxSizer(wx.VERTICAL)
        spanel.SetSizer(spsizer)
        for label in labels:
            self.btn = wx.Button(spanel,
                            label=label,
                            size=(-1,50))
            spsizer.Add(self.btn, flag=wx.ALL, border=2)

            self.Bind(wx.EVT_BUTTON, self.OnPass, self.btn)

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

        spanel.SetupScrolling(scroll_x=False,
                              scroll_y=True,
                              rate_y=10,
                              scrollToTop=False)

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

        sizer.Layout()

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

    def OnPass(self, event):
        """
        Just grouping the empty event handlers together.
        """

        print("Hello 4 !")

        pass

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

class MyControlPane(wx.Panel):
    """
    ...
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

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

        # Font, size and style.
        font = self.GetFont().GetPointSize()
        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        font.SetWeight(wx.BOLD)

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

        statictxt = wx.StaticText(self, -1, "Category :")
        statictxt.SetForegroundColour("#be3a3a")
        statictxt.SetFont(font)

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

        sampleList = ["General",
                      "User interface",
                      "Path",
                      "Language"]

        combo = wx.ListBox(self,
                           -1,
                           (-1, -1),
                           (200, 1600),
                           sampleList,
                           style=wx.LB_ALWAYS_SB |
                                 wx.LB_SINGLE)
        combo.SetSelection(0)
        combo.SetForegroundColour("white")
        combo.SetBackgroundColour("gray")

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

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(statictxt, 0, wx.TOP, 7)
        sizer.Add(combo, 1, wx.EXPAND | wx.TOP, 2)

        border = wx.BoxSizer()
        border.Add(sizer, 1, wx.EXPAND | wx.ALL, 9)
        self.SetSizer(border)

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

        # Simplified init method.
        self.BindEvents()

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

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

        self.Bind(wx.EVT_LISTBOX, self.OnExpandWindow)


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

        self.GetParent().ExpandWindow(event.GetSelection())

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

class MySplitterPanel(wx.Panel):
    """
    ...
    """
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

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

        cp = MyControlPane(self)
        splitter = FWS.FourWaySplitter(self)
        self.splitter = splitter
        self.splitter.SetExpanded(0)

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

        sizer = wx.BoxSizer(wx.HORIZONTAL)

        sizer.Add(cp)
        sizer.Add(splitter, 1, wx.EXPAND | wx.ALL, 10)

        self.SetSizer(sizer)

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

        pane1 = MyGeneralPane(splitter)
        splitter.AppendWindow(pane1)

        pane2 = MyInterfacePane(splitter)
        splitter.AppendWindow(pane2)

        pane3 = MySourcePane(splitter)
        splitter.AppendWindow(pane3)

        pane4 = MyLanguagePane(splitter)
        splitter.AppendWindow(pane4)

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

    def ExpandWindow(self, selection):
        """
        ...
        """

        self.splitter.SetExpanded(selection)

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

class MySettingDialog(wx.Dialog):
    """
    ...
    """
    def __init__(self, parent, title,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize):
        wx.Dialog.__init__(self,
                           parent,
                           -1,
                           title,
                           pos=(-1, -1),
                           size=(640, 526),
                           style=wx.DEFAULT_FRAME_STYLE)

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

        # Attributes.
        self.parent = parent

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

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

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

        self.CenterOnScreen(wx.BOTH)
        print("\nDisplay the settings dialog")

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

        self.ShowModal()
        self.Destroy()

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

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

        frameicon = wx.Icon("icon_wxWidgets.ico")
        self.SetIcon(frameicon)

        self.SetMinSize((640, 526))


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

        self.panel = MySplitterPanel(self)

        self.btnSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL)


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

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        ctrlSizer = wx.BoxSizer(wx.VERTICAL)

        ctrlSizer.Add(self.panel, 1, wx.EXPAND)
        ctrlSizer.Add(self.btnSizer, 0, wx.EXPAND |
                      wx.RIGHT, 5)

        mainSizer.Add(ctrlSizer, 1, wx.EXPAND |
                      wx.BOTTOM, 10)

        self.SetSizer(mainSizer)
        mainSizer.Layout()

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

class MyFrame(wx.Frame):
    """
    ...
    """
    def __init__(self):
        super(MyFrame, self).__init__(None,
                                      -1,
                                      title="")

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

        # Return application name.
        self.app_name = wx.GetApp().GetAppName()

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

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

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

        self.CenterOnScreen()

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

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

        self.SetTitle(self.app_name)

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

        frameicon = wx.Icon("icon_wxWidgets.ico")
        self.SetIcon(frameicon)


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

        # Create a panel.
        self.panel = wx.Panel(self, -1)

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

        # Add some buttons.
        self.btnDlg = wx.Button(self.panel,
                                -1,
                                "&Show settings dialog")

        self.btnClose = wx.Button(self.panel,
                                  -1,
                                  "&Close")


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

        # Bind the close event to an event handler.
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        # Bind the buttons event to an event handler.
        self.Bind(wx.EVT_BUTTON, self.OnSetting, self.btnDlg)
        self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)


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

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

        # wx.BoxSizer(window, proportion, flag, border)
        # wx.BoxSizer(sizer, proportion, flag, border)
        mainSizer.Add(self.btnDlg, 1, wx.EXPAND | wx.ALL, 10)
        mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)

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

        mainSizer.Fit(self.panel)

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

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

        self.Close(True)


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

        settingDlg = MySettingDialog(self,
                                     title="Settings dialog")
                                     #pos=(-1, -1),
                                     #size=(500, 300))

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

        self.Destroy()

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

class MyApp(wx.App):
    """
    ...
    """
    def OnInit(self):

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

        self.SetAppName("Main frame")

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

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

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

if __name__ == "__main__" :
    main()
}}}
--------
= Download source =
[[attachment:source.zip]]

--------
= Additional Information =
'''Link :'''

- - - - -

https://wiki.wxpython.org/TitleIndex

https://docs.wxpython.org/

--------
= Thanks to =
Robin Dunn, Andrea Gavana, the wxPython community...

--------
= About this page =
Date (d/m/y)     Person (bot)    Comments :

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

--------
= Comments =
- blah, blah, blah....