]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/demo/Main.py
Always set background colour prior to any HTML rendering (this fixes assert in GTK2...
[wxWidgets.git] / wxPython / demo / Main.py
index b3ff2f716f255330df932c80baf375ea7a3d1480..e353972a2db9c4db04c5811eb2b6adb4cfb5d151 100644 (file)
 #----------------------------------------------------------------------------
 
 import sys, os, time
 #----------------------------------------------------------------------------
 
 import sys, os, time
-from   wxPython.wx import *
-from   wxPython.lib.splashscreen import SplashScreen
-from   wxPython.html import wxHtmlWindow
+
+import wx                  # This module uses the new wx namespace
+import wx.html
 
 import images
 
 
 import images
 
+##wx.Trap()
+##raw_input("Press a key...")
+
+
+# Use Python's bool constants if available, make aliases if not
+try:
+    True
+except NameError:
+    True = 1==1
+    False = 1==0
+
 #---------------------------------------------------------------------------
 
 
 _treeList = [
 #---------------------------------------------------------------------------
 
 
 _treeList = [
-    ('New since last release', ['ContextHelp',
-                                'PyCrust',
-                                'PyCrustWithFilling',
-                                'VirtualListCtrl',
-                                'wxListCtrl',
-                                'TablePrint',
-                                'OOR',
-                                'wxFindReplaceDialog',
-                                'DrawXXXList',
-                                'ErrorDialogs',
-                                'wxRightTextCtrl',
-                                'URLDragAndDrop',
-                                'wxMimeTypesManager',
-                                'wxPopupWindow',
-                                'wxDynamicSashWindow',
-                                'wxEditableListBox',
-                                'SplitTree',
-                                'wxLEDNumberCtrl',
-                                'wxEditor',
-                                ]),
-
-    ('Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame',
-                 'wxGrid', 'wxSashWindow',
-                 'wxScrolledWindow', 'wxSplitterWindow',
-                 'wxStatusBar', 'wxNotebook',
-                 'wxHtmlWindow',
-                 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2',
-                 'wxPopupWindow',
-                 'wxDynamicSashWindow',
-                 ]),
-
-    ('Common Dialogs', ['wxColourDialog', 'wxDirDialog', 'wxFileDialog',
-                        'wxSingleChoiceDialog', 'wxTextEntryDialog',
-                        'wxFontDialog', 'wxPageSetupDialog', 'wxPrintDialog',
-                        'wxMessageDialog', 'wxProgressDialog', 'wxFindReplaceDialog',
-                        ]),
-
-    ('Controls', ['wxButton', 'wxCheckBox', 'wxCheckListBox', 'wxChoice',
-                  'wxComboBox', 'wxGauge', 'wxListBox', 'wxListCtrl', 'wxTextCtrl',
-                  'wxTreeCtrl', 'wxSpinButton', 'wxSpinCtrl', 'wxStaticText',
-                  'wxStaticBitmap', 'wxRadioBox', 'wxSlider', 'wxToolBar',
-                  'wxCalendarCtrl', 'wxToggleButton',
-                  'wxEditableListBox', 'wxLEDNumberCtrl',
-                  ]),
-
-    ('Window Layout', ['wxLayoutConstraints', 'LayoutAnchors', 'Sizers', 'XML_Resource']),
-
-    ('Miscellaneous', [ 'DragAndDrop', 'CustomDragAndDrop', 'URLDragAndDrop',
-                        'FontEnumerator',
-                        'wxTimer', 'wxValidator', 'wxGLCanvas', 'DialogUnits',
-                        'wxImage', 'wxMask', 'PrintFramework', 'wxOGL',
-                        'PythonEvents', 'Threads',
-                        'ActiveXWrapper_Acrobat', 'ActiveXWrapper_IE',
-                        'wxDragImage', "wxProcess", "FancyText", "OOR", "wxWave",
-                        'wxJoystick', 'DrawXXXList', 'ErrorDialogs', 'wxMimeTypesManager',
-                        'SplitTree',
-                        ]),
-
-    ('wxPython Library', ['Layoutf', 'wxScrolledMessageDialog',
-                          'wxMultipleChoiceDialog', 'wxPlotCanvas', 'wxFloatBar',
-                          'wxCalendar', 'wxMVCTree', 'wxVTKRenderWindow',
-                          'FileBrowseButton', 'GenericButtons', 'wxEditor',
-                          'ColourSelect', 'ImageBrowser',
-                          'infoframe', 'ColourDB', 'PyCrust', 'TablePrint',
-                          'wxRightTextCtrl',
-                          ]),
-
-    ('Cool Contribs', ['pyTree', 'hangman',
-                       #'SlashDot',
-                       'XMLtreeview'
-                       ]),
-
-    ]
+    # new stuff
+    ('Recent Additions', [
+        'wxVListBox',
+        'wxListbook',
+        'wxMaskedNumCtrl',
+        'FloatCanvas',
+        'wxXmlResourceSubclass',
+        ]),
+
+    # managed windows == things with a (optional) caption you can close
+    ('Base Frames and Dialogs', [
+        'wxDialog',
+        'wxFrame',
+        'wxMDIWindows',
+        'wxMiniFrame',
+        'wxWizard',
+        ]),
+
+    # the common dialogs
+    ('Common Dialogs', [
+        'wxColourDialog',
+        'wxDirDialog',
+        'wxFileDialog',
+        'wxFileDialog_Save',
+        'wxFindReplaceDialog',
+        'wxFontDialog',
+        'wxMessageDialog',
+        'wxPageSetupDialog',
+        'wxPrintDialog',
+        'wxProgressDialog',
+        'wxSingleChoiceDialog',
+        'wxTextEntryDialog',
+        ]),
+
+    # dialogs from libraries
+    ('More Dialogs', [
+        'ErrorDialogs',
+        'ImageBrowser',
+        'wxMultipleChoiceDialog',
+        'wxScrolledMessageDialog',
+        ]),
+
+    # core controls
+    ('Core Windows/Controls', [
+        'PopupMenu',
+        'wxButton',
+        'wxCheckBox',
+        'wxCheckListBox',
+        'wxChoice',
+        'wxComboBox',
+        'wxGauge',
+        'wxGenericDirCtrl',
+        'wxGrid',
+        'wxGrid_MegaExample',
+        'wxListbook',
+        'wxListBox',
+        'wxListCtrl',
+        'wxListCtrl_virtual',
+        'wxMenu',
+        'wxNotebook',
+        'wxPopupWindow',
+        'wxRadioBox',
+        'wxRadioButton',
+        'wxSashWindow',
+        'wxScrolledWindow',
+        'wxSlider',
+        'wxSpinButton',
+        'wxSpinCtrl',
+        'wxSplitterWindow',
+        'wxStaticBitmap',
+        'wxStaticText',
+        'wxStatusBar',
+        'wxTextCtrl',
+        'wxToggleButton',
+        'wxToolBar',
+        'wxTreeCtrl',
+        'wxValidator',
+        ]),
+
+    # controls coming from other libraries
+    ('More Windows/Controls', [
+        #'wxFloatBar',          deprecated
+        #'wxMVCTree',           deprecated
+        #'wxRightTextCtrl',     deprecated as we have wxTE_RIGHT now.
+        'AnalogClockWindow',
+        'ColourSelect',
+        'ContextHelp',
+        'FancyText',
+        'FloatCanvas',
+        'FileBrowseButton',
+        'GenericButtons',
+        'MaskedEditControls',
+        'PyShell',
+        'PyCrust',
+        'SplitTree',
+        'TablePrint',
+        'Throbber',
+        'wxCalendar',
+        'wxCalendarCtrl',
+        'wxPyColourChooser',
+        'wxDynamicSashWindow',
+        'wxEditableListBox',
+        'wxEditor',
+        'wxHtmlWindow',
+        'wxIEHtmlWin',
+        'wxIntCtrl',
+        'wxLEDNumberCtrl',
+        'wxMimeTypesManager',
+        'wxMaskedNumCtrl',
+        'wxMultiSash',
+        'wxPopupControl',
+        'wxStyledTextCtrl_1',
+        'wxStyledTextCtrl_2',
+        'wxTimeCtrl',
+        'wxTreeListCtrl',
+        'wxVListBox',
+        ]),
+
+    # How to lay out the controls in a frame/dialog
+    ('Window Layout', [
+        'LayoutAnchors',
+        'Layoutf',
+        'RowColSizer',
+        'Sizers',
+        'wxLayoutConstraints',
+        'wxScrolledPanel',
+        'wxXmlResource',
+        'wxXmlResourceHandler',
+        'wxXmlResourceSubclass',
+        ]),
+
+    # ditto
+    ('Process and Events', [
+        'EventManager',
+        'infoframe',
+        'OOR',
+        'PythonEvents',
+        'Threads',
+        'wxKeyEvents',
+        'wxProcess',
+        'wxTimer',
+        ]),
+
+    # Clipboard and DnD
+    ('Clipboard and DnD', [
+        'CustomDragAndDrop',
+        'DragAndDrop',
+        'URLDragAndDrop',
+        ]),
+
+    # Images
+    ('Using Images', [
+        'Throbber',
+        'wxArtProvider',
+        'wxDragImage',
+        'wxImage',
+        'wxImageFromStream',
+        'wxMask',
+        ]),
+
+    # Other stuff
+    ('Miscellaneous', [
+        'ColourDB',
+        'DialogUnits',
+        'DrawXXXList',
+        'FontEnumerator',
+        'NewNamespace',
+        'PrintFramework',
+        'ShapedWindow',
+        'Throbber',
+        'Unicode',
+        'wxFileHistory',
+        'wxJoystick',
+        'wxOGL',
+        'wxWave',
+        ]),
+
+    # need libs not coming with the demo
+    ('Objects using an external library', [
+        'ActiveXWrapper_Acrobat',
+        'ActiveXWrapper_IE',
+        'wxGLCanvas',
+        'wxPlotCanvas',
+        ]),
+
+
+    ('Check out the samples dir too', [
+        ]),
+
+]
+
+
 
 #---------------------------------------------------------------------------
 
 #---------------------------------------------------------------------------
+# Show how to derive a custom wxLog class
 
 
-class MyLog(wxPyLog):
+class MyLog(wx.PyLog):
     def __init__(self, textCtrl, logTime=0):
     def __init__(self, textCtrl, logTime=0):
-        wxPyLog.__init__(self)
+        wx.PyLog.__init__(self)
         self.tc = textCtrl
         self.logTime = logTime
 
         self.tc = textCtrl
         self.logTime = logTime
 
@@ -108,103 +239,182 @@ class MyLog(wxPyLog):
         if self.logTime:
             message = time.strftime("%X", time.localtime(timeStamp)) + \
                       ": " + message
         if self.logTime:
             message = time.strftime("%X", time.localtime(timeStamp)) + \
                       ": " + message
-        self.tc.AppendText(message + '\n')
+        if self.tc:
+            self.tc.AppendText(message + '\n')
+
 
 
+class MyTP(wx.PyTipProvider):
+    def GetTip(self):
+        return "This is my tip"
 
 #---------------------------------------------------------------------------
 
 #---------------------------------------------------------------------------
+# A class to be used to display source code in the demo.  Try using the
+# wxSTC in the wxStyledTextCtrl_2 sample first, fall back to wxTextCtrl
+# if there is an error, such as the stc module not being present.
+#
+
+try:
+    ##raise ImportError
+    from wx import stc
+    from wxStyledTextCtrl_2 import PythonSTC
+    class DemoCodeViewer(PythonSTC):
+        def __init__(self, parent, ID):
+            PythonSTC.__init__(self, parent, ID)
+            self.SetEdgeMode(stc.STC_EDGE_NONE)
+            self.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
+            self.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
+
+        # Some methods to make it compatible with how the wxTextCtrl is used
+        def SetValue(self, value):
+            self.SetReadOnly(False)
+            self.SetText(value)
+            self.SetReadOnly(True)
+
+        def Clear(self):
+            self.ClearAll()
+
+        def SetInsertionPoint(self, pos):
+            self.SetCurrentPos(pos)
+
+        def ShowPosition(self, pos):
+            self.GotoPos(pos)
+
+        def GetLastPosition(self):
+            return self.GetLength()
+
+        def GetRange(self, start, end):
+            return self.GetTextRange(start, end)
+
+        def GetSelection(self):
+            return self.GetAnchor(), self.GetCurrentPos()
+
+        def SetSelection(self, start, end):
+            self.SetSelectionStart(start)
+            self.SetSelectionEnd(end)
 
 
-class wxPythonDemo(wxFrame):
+
+except ImportError:
+    class DemoCodeViewer(wx.TextCtrl):
+        def __init__(self, parent, ID):
+            wx.TextCtrl.__init__(self, parent, ID, style =
+                                 wx.TE_MULTILINE | wx.TE_READONLY |
+                                 wx.HSCROLL | wx.TE_RICH2 | wx.TE_NOHIDESEL)
+
+
+#---------------------------------------------------------------------------
+
+def opj(path):
+    """Convert paths to the platform-specific separator"""
+    return apply(os.path.join, tuple(path.split('/')))
+
+
+#---------------------------------------------------------------------------
+
+class wxPythonDemo(wx.Frame):
+    overviewText = "wxPython Overview"
 
     def __init__(self, parent, id, title):
 
     def __init__(self, parent, id, title):
-        wxFrame.__init__(self, parent, -1, title, size = (800, 600),
-                         style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
+        wx.Frame.__init__(self, parent, -1, title, size = (800, 600),
+                         style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
 
         self.cwd = os.getcwd()
         self.curOverview = ""
 
         self.cwd = os.getcwd()
         self.curOverview = ""
+        self.window = None
 
 
-        if 1:
-            icon = wxIconFromXPMData(images.getMondrianData())
-        else:
-            # another way to do it
-            bmp = images.getMondrianBitmap()
-            icon = wxEmptyIcon()
-            icon.CopyFromBitmap(bmp)
-
+        icon = images.getMondrianIcon()
         self.SetIcon(icon)
 
         self.SetIcon(icon)
 
-        if wxPlatform == '__WXMSW__':
+        if wx.Platform == '__WXMSW__':
             # setup a taskbar icon, and catch some events from it
             # setup a taskbar icon, and catch some events from it
-            self.tbicon = wxTaskBarIcon()
+            self.tbicon = wx.TaskBarIcon()
             self.tbicon.SetIcon(icon, "wxPython Demo")
             self.tbicon.SetIcon(icon, "wxPython Demo")
-            EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
-            EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
-            EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
-            EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)
+            wx.EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
+            wx.EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
+            wx.EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
+            wx.EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)
 
 
+        wx.CallAfter(self.ShowTip)
 
         self.otherWin = None
 
         self.otherWin = None
-        EVT_IDLE(self, self.OnIdle)
-        EVT_CLOSE(self, self.OnCloseWindow)
-        EVT_ICONIZE(self, self.OnIconfiy)
-        EVT_MAXIMIZE(self, self.OnMaximize)
+        wx.EVT_IDLE(self, self.OnIdle)
+        wx.EVT_CLOSE(self, self.OnCloseWindow)
+        wx.EVT_ICONIZE(self, self.OnIconfiy)
+        wx.EVT_MAXIMIZE(self, self.OnMaximize)
 
 
-        self.Centre(wxBOTH)
-        self.CreateStatusBar(1, wxST_SIZEGRIP)
+        self.Centre(wx.BOTH)
+        self.CreateStatusBar(1, wx.ST_SIZEGRIP)
 
 
-        splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
-        splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
+        splitter = wx.SplitterWindow(self, -1)
+        splitter2 = wx.SplitterWindow(splitter, -1)
 
         def EmptyHandler(evt): pass
 
         def EmptyHandler(evt): pass
-        EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
-        EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
+        #wx.EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
+        #wx.EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
 
 
-        # Prevent TreeCtrl from displaying all items after destruction when true
-        self.dying = false
+        # Prevent TreeCtrl from displaying all items after destruction when True
+        self.dying = False
 
         # Make a File menu
 
         # Make a File menu
-        self.mainmenu = wxMenuBar()
-        menu = wxMenu()
-        exitID = wxNewId()
+        self.mainmenu = wx.MenuBar()
+        menu = wx.Menu()
+        exitID = wx.NewId()
         menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
         menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
-        EVT_MENU(self, exitID, self.OnFileExit)
+        wx.EVT_MENU(self, exitID, self.OnFileExit)
+        wx.App_SetMacExitMenuItemId(exitID)
         self.mainmenu.Append(menu, '&File')
 
         # Make a Demo menu
         self.mainmenu.Append(menu, '&File')
 
         # Make a Demo menu
-        menu = wxMenu()
+        menu = wx.Menu()
         for item in _treeList:
         for item in _treeList:
-            submenu = wxMenu()
+            submenu = wx.Menu()
             for childItem in item[1]:
             for childItem in item[1]:
-                mID = wxNewId()
+                mID = wx.NewId()
                 submenu.Append(mID, childItem)
                 submenu.Append(mID, childItem)
-                EVT_MENU(self, mID, self.OnDemoMenu)
-            menu.AppendMenu(wxNewId(), item[0], submenu)
+                wx.EVT_MENU(self, mID, self.OnDemoMenu)
+            menu.AppendMenu(wx.NewId(), item[0], submenu)
         self.mainmenu.Append(menu, '&Demo')
 
 
         # Make a Help menu
         self.mainmenu.Append(menu, '&Demo')
 
 
         # Make a Help menu
-        helpID = wxNewId()
-        menu = wxMenu()
+        helpID = wx.NewId()
+        findID = wx.NewId()
+        findnextID = wx.NewId()
+        menu = wx.Menu()
+        menu.Append(findID, '&Find\tCtrl-F', 'Find in the Demo Code')
+        menu.Append(findnextID, 'Find &Next\tF3', 'Find Next')
+        menu.AppendSeparator()
         menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
         menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
-        EVT_MENU(self, helpID, self.OnHelpAbout)
+        wx.App_SetMacAboutMenuItemId(helpID)
+        wx.EVT_MENU(self, helpID, self.OnHelpAbout)
+        wx.EVT_MENU(self, findID, self.OnHelpFind)
+        wx.EVT_MENU(self, findnextID, self.OnFindNext)
+        wx.EVT_COMMAND_FIND(self, -1, self.OnFind)
+        wx.EVT_COMMAND_FIND_NEXT(self, -1, self.OnFind)
+        wx.EVT_COMMAND_FIND_CLOSE(self, -1 , self.OnFindClose)
         self.mainmenu.Append(menu, '&Help')
         self.SetMenuBar(self.mainmenu)
 
         self.mainmenu.Append(menu, '&Help')
         self.SetMenuBar(self.mainmenu)
 
-        # set the menu accellerator table...
-        aTable = wxAcceleratorTable([(wxACCEL_ALT,  ord('X'), exitID),
-                                     (wxACCEL_CTRL, ord('H'), helpID)])
-        self.SetAcceleratorTable(aTable)
+        self.finddata = wx.FindReplaceData()
+
+        if 0:
+            # This is another way to set Accelerators, in addition to
+            # using the '\t<key>' syntax in the menu items.
+            aTable = wx.AcceleratorTable([(wx.ACCEL_ALT,  ord('X'), exitID),
+                                          (wx.ACCEL_CTRL, ord('H'), helpID),
+                                          (wx.ACCEL_CTRL, ord('F'), findID),
+                                          (wx.ACCEL_NORMAL, WXK_F3, findnextID)
+                                          ])
+            self.SetAcceleratorTable(aTable)
 
 
         # Create a TreeCtrl
 
 
         # Create a TreeCtrl
-        tID = wxNewId()
+        tID = wx.NewId()
         self.treeMap = {}
         self.treeMap = {}
-        self.tree = wxTreeCtrl(splitter, tID,
-                               style=wxTR_HAS_BUTTONS |
-                               wxTR_EDIT_LABELS |
-                               wxTR_HAS_VARIABLE_ROW_HEIGHT |
-                               wxSUNKEN_BORDER)
-        #self.tree.SetBackgroundColour(wxNamedColour("Pink"))
-        root = self.tree.AddRoot("Overview")
+        self.tree = wx.TreeCtrl(splitter, tID, style =
+                                wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
+                               )
+
+        root = self.tree.AddRoot("wxPython Overview")
         firstChild = None
         for item in _treeList:
             child = self.tree.AppendItem(root, item[0])
         firstChild = None
         for item in _treeList:
             child = self.tree.AppendItem(root, item[0])
@@ -215,62 +425,75 @@ class wxPythonDemo(wxFrame):
 
         self.tree.Expand(root)
         self.tree.Expand(firstChild)
 
         self.tree.Expand(root)
         self.tree.Expand(firstChild)
-        EVT_TREE_ITEM_EXPANDED   (self.tree, tID, self.OnItemExpanded)
-        EVT_TREE_ITEM_COLLAPSED  (self.tree, tID, self.OnItemCollapsed)
-        EVT_TREE_SEL_CHANGED     (self.tree, tID, self.OnSelChanged)
-        EVT_LEFT_DOWN            (self.tree,      self.OnTreeLeftDown)
+        wx.EVT_TREE_ITEM_EXPANDED   (self.tree, tID, self.OnItemExpanded)
+        wx.EVT_TREE_ITEM_COLLAPSED  (self.tree, tID, self.OnItemCollapsed)
+        wx.EVT_TREE_SEL_CHANGED     (self.tree, tID, self.OnSelChanged)
+        wx.EVT_LEFT_DOWN            (self.tree,      self.OnTreeLeftDown)
 
         # Create a Notebook
 
         # Create a Notebook
-        self.nb = wxNotebook(splitter2, -1, style=wxCLIP_CHILDREN)
+        self.nb = wx.Notebook(splitter2, -1, style=wx.CLIP_CHILDREN)
 
 
-        # Set up a wxHtmlWindow on the Overview Notebook page
+        # Set up a wx.html.HtmlWindow on the Overview Notebook page
         # we put it in a panel first because there seems to be a
         # refresh bug of some sort (wxGTK) when it is directly in
         # the notebook...
         if 0:  # the old way
         # we put it in a panel first because there seems to be a
         # refresh bug of some sort (wxGTK) when it is directly in
         # the notebook...
         if 0:  # the old way
-            self.ovr = wxHtmlWindow(self.nb, -1, size=(400, 400))
-            self.nb.AddPage(self.ovr, "Overview")
+            self.ovr = wx.html.HtmlWindow(self.nb, -1, size=(400, 400))
+            self.nb.AddPage(self.ovr, self.overviewText)
 
 
-        else:  # hopefully I can remove this hacky code soon, see bug #216861
-            panel = wxPanel(self.nb, -1, style=wxCLIP_CHILDREN)
-            self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
-            self.nb.AddPage(panel, "Overview")
+        else:  # hopefully I can remove this hacky code soon, see SF bug #216861
+            panel = wx.Panel(self.nb, -1, style=wx.CLIP_CHILDREN)
+            self.ovr = wx.html.HtmlWindow(panel, -1, size=(400, 400))
+            self.nb.AddPage(panel, self.overviewText)
 
             def OnOvrSize(evt, ovr=self.ovr):
                 ovr.SetSize(evt.GetSize())
 
 
             def OnOvrSize(evt, ovr=self.ovr):
                 ovr.SetSize(evt.GetSize())
 
-            EVT_SIZE(panel, OnOvrSize)
-            EVT_ERASE_BACKGROUND(panel, EmptyHandler)
+            wx.EVT_SIZE(panel, OnOvrSize)
+            wx.EVT_ERASE_BACKGROUND(panel, EmptyHandler)
 
 
 
 
-        self.SetOverview("Overview", overview)
+        self.SetOverview(self.overviewText, overview)
 
 
 
 
-        # Set up a TextCtrl on the Demo Code Notebook page
-        self.txt = wxTextCtrl(self.nb, -1,
-                              style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
+        # Set up a notebook page for viewing the source code of each sample
+        self.txt = DemoCodeViewer(self.nb, -1)
         self.nb.AddPage(self.txt, "Demo Code")
         self.nb.AddPage(self.txt, "Demo Code")
+        self.GetDemoFile('Main.py')
 
 
         # Set up a log on the View Log Notebook page
 
 
         # Set up a log on the View Log Notebook page
-        self.log = wxTextCtrl(splitter2, -1,
-                              style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
+        self.log = wx.TextCtrl(splitter2, -1,
+                              style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
+
         # Set the wxWindows log target to be this textctrl
         # Set the wxWindows log target to be this textctrl
-        #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
-        wxLog_SetActiveTarget(MyLog(self.log))
+        #wx.Log_SetActiveTarget(wx.LogTextCtrl(self.log))
+
+        # But instead of the above we want to show how to use our own wx.Log class
+        wx.Log_SetActiveTarget(MyLog(self.log))
 
 
+        # for serious debugging
+        #wx.Log_SetActiveTarget(wx.LogStderr())
+        #wx.Log_SetTraceMask(wx.TraceMessages)
 
 
+        self.Show(True)
 
 
-        self.Show(true)
 
         # add the windows to the splitter and split it.
 
         # add the windows to the splitter and split it.
-        splitter2.SplitHorizontally(self.nb, self.log)
-        splitter2.SetSashPosition(450, true)
-        splitter2.SetMinimumPaneSize(20)
+        splitter2.SplitHorizontally(self.nb, self.log, -120)
+        splitter.SplitVertically(self.tree, splitter2, 180)
 
 
-        splitter.SplitVertically(self.tree, splitter2)
-        splitter.SetSashPosition(180, true)
         splitter.SetMinimumPaneSize(20)
         splitter.SetMinimumPaneSize(20)
+        splitter2.SetMinimumPaneSize(20)
+
+
+        # Make the splitter on the right expand the top wind when resized
+        def SplitterOnSize(evt):
+            splitter = evt.GetEventObject()
+            sz = splitter.GetSize()
+            splitter.SetSashPosition(sz.height - 120, False)
+            evt.Skip()
+        wx.EVT_SIZE(splitter2, SplitterOnSize)
 
 
         # select initial items
 
 
         # select initial items
@@ -287,14 +510,14 @@ class wxPythonDemo(wxFrame):
                 self.tree.EnsureVisible(selectedDemo)
 
 
                 self.tree.EnsureVisible(selectedDemo)
 
 
-        wxLogMessage('window handle: %s' % self.GetHandle())
+        wx.LogMessage('window handle: %s' % self.GetHandle())
 
 
     #---------------------------------------------
     def WriteText(self, text):
         if text[-1:] == '\n':
             text = text[:-1]
 
 
     #---------------------------------------------
     def WriteText(self, text):
         if text[-1:] == '\n':
             text = text[:-1]
-        wxLogMessage(text)
+        wx.LogMessage(text)
 
 
     def write(self, txt):
 
 
     def write(self, txt):
@@ -303,13 +526,13 @@ class wxPythonDemo(wxFrame):
     #---------------------------------------------
     def OnItemExpanded(self, event):
         item = event.GetItem()
     #---------------------------------------------
     def OnItemExpanded(self, event):
         item = event.GetItem()
-        wxLogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
+        wx.LogMessage("OnItemExpanded: %s" % self.tree.GetItemText(item))
         event.Skip()
 
     #---------------------------------------------
     def OnItemCollapsed(self, event):
         item = event.GetItem()
         event.Skip()
 
     #---------------------------------------------
     def OnItemCollapsed(self, event):
         item = event.GetItem()
-        wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
+        wx.LogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
         event.Skip()
 
     #---------------------------------------------
         event.Skip()
 
     #---------------------------------------------
@@ -317,7 +540,7 @@ class wxPythonDemo(wxFrame):
         pt = event.GetPosition();
         item, flags = self.tree.HitTest(pt)
         if item == self.tree.GetSelection():
         pt = event.GetPosition();
         item, flags = self.tree.HitTest(pt)
         if item == self.tree.GetSelection():
-            self.SetOverview(self.tree.GetItemText(item), self.curOverview)
+            self.SetOverview(self.tree.GetItemText(item)+" Overview", self.curOverview)
         event.Skip()
 
     #---------------------------------------------
         event.Skip()
 
     #---------------------------------------------
@@ -336,34 +559,40 @@ class wxPythonDemo(wxFrame):
         if self.nb.GetPageCount() == 3:
             if self.nb.GetSelection() == 2:
                 self.nb.SetSelection(0)
         if self.nb.GetPageCount() == 3:
             if self.nb.GetSelection() == 2:
                 self.nb.SetSelection(0)
+            # inform the window that it's time to quit if it cares
+            if self.window is not None:
+                if hasattr(self.window, "ShutdownDemo"):
+                    self.window.ShutdownDemo()
+            wx.SafeYield() # in case the page has pending events
             self.nb.DeletePage(2)
 
             self.nb.DeletePage(2)
 
-        if itemText == 'Overview':
+        if itemText == self.overviewText:
             self.GetDemoFile('Main.py')
             self.GetDemoFile('Main.py')
-            self.SetOverview('Overview', overview)
+            self.SetOverview(self.overviewText, overview)
             self.nb.Refresh();
             self.window = None
 
         else:
             if os.path.exists(itemText + '.py'):
             self.nb.Refresh();
             self.window = None
 
         else:
             if os.path.exists(itemText + '.py'):
-                wxBeginBusyCursor()
-                wxLogMessage("Running demo %s.py..." % itemText)
+                wx.BeginBusyCursor()
+                wx.LogMessage("Running demo %s.py..." % itemText)
                 try:
                     self.GetDemoFile(itemText + '.py')
                     module = __import__(itemText, globals())
                 try:
                     self.GetDemoFile(itemText + '.py')
                     module = __import__(itemText, globals())
-                    self.SetOverview(itemText, module.overview)
+                    self.SetOverview(itemText + " Overview", module.overview)
                 finally:
                 finally:
-                    wxEndBusyCursor()
+                    wx.EndBusyCursor()
+                self.tree.Refresh()
 
                 # in case runTest is modal, make sure things look right...
                 self.nb.Refresh();
 
                 # in case runTest is modal, make sure things look right...
                 self.nb.Refresh();
-                wxYield()
+                wx.SafeYield()
 
                 self.window = module.runTest(self, self.nb, self) ###
 
                 self.window = module.runTest(self, self.nb, self) ###
-                if self.window:
+                if self.window is not None:
                     self.nb.AddPage(self.window, 'Demo')
                     self.nb.AddPage(self.window, 'Demo')
-                    wxYield()
                     self.nb.SetSelection(2)
                     self.nb.SetSelection(2)
+                    self.nb.Refresh()  # without this wxMac has troubles showing the just added page
 
             else:
                 self.ovr.SetPage("")
 
             else:
                 self.ovr.SetPage("")
@@ -379,7 +608,7 @@ class wxPythonDemo(wxFrame):
         try:
             self.txt.SetValue(open(filename).read())
         except IOError:
         try:
             self.txt.SetValue(open(filename).read())
         except IOError:
-            self.txt.WriteText("Cannot open %s file." % filename)
+            self.txt.SetValue("Cannot open %s file." % filename)
 
         self.txt.SetInsertionPoint(0)
         self.txt.ShowPosition(0)
 
         self.txt.SetInsertionPoint(0)
         self.txt.ShowPosition(0)
@@ -389,8 +618,7 @@ class wxPythonDemo(wxFrame):
         self.curOverview = text
         lead = text[:6]
         if lead != '<html>' and lead != '<HTML>':
         self.curOverview = text
         lead = text[:6]
         if lead != '<html>' and lead != '<HTML>':
-            text = string.join(string.split(text, '\n'), '<br>')
-            #text = '<font size="-1"><pre>' + text + '</pre></font>'
+            text = '<br>'.join(text.split('\n'))
         self.ovr.SetPage(text)
         self.nb.SetPageText(0, name)
 
         self.ovr.SetPage(text)
         self.nb.SetPageText(0, name)
 
@@ -399,17 +627,61 @@ class wxPythonDemo(wxFrame):
     def OnFileExit(self, *event):
         self.Close()
 
     def OnFileExit(self, *event):
         self.Close()
 
-
     def OnHelpAbout(self, event):
         from About import MyAboutBox
         about = MyAboutBox(self)
         about.ShowModal()
         about.Destroy()
 
     def OnHelpAbout(self, event):
         from About import MyAboutBox
         about = MyAboutBox(self)
         about.ShowModal()
         about.Destroy()
 
+    def OnHelpFind(self, event):
+        self.nb.SetSelection(1)
+        self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find",
+                        wx.FR_NOUPDOWN |
+                        wx.FR_NOMATCHCASE |
+                        wx.FR_NOWHOLEWORD)
+        self.finddlg.Show(True)
+
+    def OnFind(self, event):
+        self.nb.SetSelection(1)
+        end = self.txt.GetLastPosition()
+        textstring = self.txt.GetRange(0, end).lower()
+        start = self.txt.GetSelection()[1]
+        findstring = self.finddata.GetFindString().lower()
+        loc = textstring.find(findstring, start)
+        if loc == -1 and start != 0:
+            # string not found, start at beginning
+            start = 0
+            loc = textstring.find(findstring, start)
+        if loc == -1:
+            dlg = wx.MessageDialog(self, 'Find String Not Found',
+                          'Find String Not Found in Demo File',
+                          wx.OK | wx.ICON_INFORMATION)
+            dlg.ShowModal()
+            dlg.Destroy()
+        if self.finddlg:
+            if loc == -1:
+                self.finddlg.SetFocus()
+                return
+            else:
+                self.finddlg.Destroy()
+        self.txt.ShowPosition(loc)
+        self.txt.SetSelection(loc, loc + len(findstring))
+
+
+
+    def OnFindNext(self, event):
+        if self.finddata.GetFindString():
+            self.OnFind(event)
+        else:
+            self.OnHelpFind(event)
+
+    def OnFindClose(self, event):
+        event.GetDialog().Destroy()
+
 
     #---------------------------------------------
     def OnCloseWindow(self, event):
 
     #---------------------------------------------
     def OnCloseWindow(self, event):
-        self.dying = true
+        self.dying = True
         self.window = None
         self.mainmenu = None
         if hasattr(self, "tbicon"):
         self.window = None
         self.mainmenu = None
         if hasattr(self, "tbicon"):
@@ -424,6 +696,22 @@ class wxPythonDemo(wxFrame):
             self.window = self.otherWin
             self.otherWin = None
 
             self.window = self.otherWin
             self.otherWin = None
 
+
+    #---------------------------------------------
+    def ShowTip(self):
+        try:
+            showTipText = open(opj("data/showTips")).read()
+            showTip, index = eval(showTipText)
+        except IOError:
+            showTip, index = (1, 0)
+        if showTip:
+            tp = wx.CreateFileTipProvider(opj("data/tips.txt"), index)
+            ##tp = MyTP(0)
+            showTip = wx.ShowTip(self, tp)
+            index = tp.GetCurrentTip()
+            open(opj("data/showTips"), "w").write(str( (showTip, index) ))
+
+
     #---------------------------------------------
     def OnDemoMenu(self, event):
         try:
     #---------------------------------------------
     def OnDemoMenu(self, event):
         try:
@@ -438,9 +726,9 @@ class wxPythonDemo(wxFrame):
     #---------------------------------------------
     def OnTaskBarActivate(self, evt):
         if self.IsIconized():
     #---------------------------------------------
     def OnTaskBarActivate(self, evt):
         if self.IsIconized():
-            self.Iconize(false)
+            self.Iconize(False)
         if not self.IsShown():
         if not self.IsShown():
-            self.Show(true)
+            self.Show(True)
         self.Raise()
 
     #---------------------------------------------
         self.Raise()
 
     #---------------------------------------------
@@ -449,7 +737,7 @@ class wxPythonDemo(wxFrame):
     TBMENU_CLOSE   = 1001
 
     def OnTaskBarMenu(self, evt):
     TBMENU_CLOSE   = 1001
 
     def OnTaskBarMenu(self, evt):
-        menu = wxMenu()
+        menu = wx.Menu()
         menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
         menu.Append(self.TBMENU_CLOSE,   "Close")
         self.tbicon.PopupMenu(menu)
         menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo")
         menu.Append(self.TBMENU_CLOSE,   "Close")
         self.tbicon.PopupMenu(menu)
@@ -459,19 +747,19 @@ class wxPythonDemo(wxFrame):
     def OnTaskBarClose(self, evt):
         self.Close()
 
     def OnTaskBarClose(self, evt):
         self.Close()
 
-        # because of the way wxTaskBarIcon.PopupMenu is implemented we have to
+        # because of the way wx.TaskBarIcon.PopupMenu is implemented we have to
         # prod the main idle handler a bit to get the window to actually close
         # prod the main idle handler a bit to get the window to actually close
-        wxGetApp().ProcessIdle()
+        wx.GetApp().ProcessIdle()
 
 
     #---------------------------------------------
     def OnIconfiy(self, evt):
 
 
     #---------------------------------------------
     def OnIconfiy(self, evt):
-        wxLogMessage("OnIconfiy")
+        wx.LogMessage("OnIconfiy")
         evt.Skip()
 
     #---------------------------------------------
     def OnMaximize(self, evt):
         evt.Skip()
 
     #---------------------------------------------
     def OnMaximize(self, evt):
-        wxLogMessage("OnMaximize")
+        wx.LogMessage("OnMaximize")
         evt.Skip()
 
 
         evt.Skip()
 
 
@@ -480,45 +768,36 @@ class wxPythonDemo(wxFrame):
 #---------------------------------------------------------------------------
 #---------------------------------------------------------------------------
 
 #---------------------------------------------------------------------------
 #---------------------------------------------------------------------------
 
-class MySplashScreen(wxSplashScreen):
+class MySplashScreen(wx.SplashScreen):
     def __init__(self):
     def __init__(self):
-        bmp = wxImage('bitmaps/splash.gif').ConvertToBitmap()
-        wxSplashScreen.__init__(self, bmp,
-                                wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT,
-                                4000, None, -1)
-        EVT_CLOSE(self, self.OnClose)
+        bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()
+        wx.SplashScreen.__init__(self, bmp,
+                                wx.SPLASH_CENTRE_ON_SCREEN|wx.SPLASH_TIMEOUT,
+                                4000, None, -1,
+                                style = wx.SIMPLE_BORDER|wx.FRAME_NO_TASKBAR|wx.STAY_ON_TOP)
+        wx.EVT_CLOSE(self, self.OnClose)
 
     def OnClose(self, evt):
         frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
 
     def OnClose(self, evt):
         frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
-        frame.Show(true)
-        self.ShowTip(frame)
-        evt.Skip()
-
-    def ShowTip(self, frame):
-        try:
-            showTipText = open("data/showTips").read()
-            showTip, index = eval(showTipText)
-        except IOError:
-            showTip, index = (1, 0)
-        if showTip:
-            tp = wxCreateFileTipProvider("data/tips.txt", index)
-            showTip = wxShowTip(frame, tp)
-            index = tp.GetCurrentTip()
-            open("data/showTips", "w").write(str( (showTip, index) ))
-
+        frame.Show()
+        evt.Skip()  # Make sure the default handler runs too...
 
 
 
 
-class MyApp(wxApp):
+class MyApp(wx.App):
     def OnInit(self):
         """
     def OnInit(self):
         """
-        Create and show the splash screen.  It will then create and show 
+        Create and show the splash screen.  It will then create and show
         the main frame when it is time to do so.
         """
         the main frame when it is time to do so.
         """
-        wxInitAllImageHandlers()
+
+        #import locale
+        #self.locale = wx.Locale(wx.LANGUAGE_FRENCH)
+        #locale.setlocale(locale.LC_ALL, 'fr')
+
+        wx.InitAllImageHandlers()
         splash = MySplashScreen()
         splash.Show()
         splash = MySplashScreen()
         splash.Show()
-        wxYield()
-        return true
+        return True
 
 
 
 
 
 
@@ -530,7 +809,7 @@ def main():
         os.chdir(demoPath)
     except:
         pass
         os.chdir(demoPath)
     except:
         pass
-    app = MyApp(0)
+    app = MyApp(wx.Platform == "__WXMAC__")
     app.MainLoop()
 
 
     app.MainLoop()
 
 
@@ -539,76 +818,36 @@ def main():
 
 
 overview = """<html><body>
 
 
 overview = """<html><body>
- <h2>Python</h2>
-
- Python is an interpreted, interactive, object-oriented programming
- language often compared to Tcl, Perl, Scheme, or Java.
-
- <p> Python combines remarkable power with very clear syntax. It has
- modules, classes, exceptions, very high level dynamic data types, and
- dynamic typing.  There are interfaces to many system calls and
- libraries, and new built-in modules are easily written in C or
- C++. Python is also usable as an extension language for applications
- that need a programmable interface.  <p>
-
- <h2>wxWindows</h2>
-
- wxWindows is a free C++ framework designed to make cross-platform
- programming child's play. Well, almost. wxWindows 2 supports Windows
- 3.1/95/98/NT, Unix with GTK/Motif/Lesstif, with a Mac version
- underway. Other ports are under consideration.  <p>
-
- wxWindows is a set of libraries that allows C++ applications to
- compile and run on several different types of computers, with minimal
- source code changes.  There is one library per supported GUI (such as
- Motif, or Windows). As well as providing a common API (Application
- Programming Interface) for GUI functionality, it provides
- functionality for accessing some commonly-used operating system
- facilities, such as copying or deleting files. wxWindows is a
- 'framework' in the sense that it provides a lot of built-in
- functionality, which the application can use or replace as required,
- thus saving a great deal of coding effort. Basic data structures such
- as strings, linked lists and hash tables are also supported.
-
- <p>
- <h2>wxPython</h2>
-
- wxPython is a Python extension module that encapsulates the wxWindows
- GUI classes. Currently it is only available for the Win32 and GTK
- ports of wxWindows, but as soon as the other ports are brought up to
- the same level as Win32 and GTK, it should be fairly trivial to
- enable wxPython to be used with the new GUI.
-
- <p>
-
- The wxPython extension module attempts to mirror the class heiarchy
- of wxWindows as closely as possible. This means that there is a
- wxFrame class in wxPython that looks, smells, tastes and acts almost
- the same as the wxFrame class in the C++ version. Unfortunately,
- because of differences in the languages, wxPython doesn't match
- wxWindows exactly, but the differences should be easy to absorb
- because they are natural to Python. For example, some methods that
- return multiple values via argument pointers in C++ will return a
- tuple of values in Python.
-
- <p>
-
- There is still much to be done for wxPython, many classes still need
- to be mirrored. Also, wxWindows is still somewhat of a moving target
- so it is a bit of an effort just keeping wxPython up to date. On the
- other hand, there are enough of the core classes completed that
- useful applications can be written.
-
- <p>
-
- wxPython is close enough to the C++ version that the majority of
- the wxPython documentation is actually just notes attached to the C++
- documents that describe the places where wxPython is different. There
- is also a series of sample programs included, and a series of
- documentation pages that assist the programmer in getting started
- with wxPython.
-
- """
+<h2>wxPython</h2>
+
+<p> wxPython is a <b>GUI toolkit</b> for the <a
+href="http://www.python.org/">Python</a> programming language.  It
+allows Python programmers to create programs with a robust, highly
+functional graphical user interface, simply and easily.  It is
+implemented as a Python extension module (native code) that wraps the
+popular <a href="http://wxwindows.org/front.htm">wxWindows</a> cross
+platform GUI library, which is written in C++.
+
+<p> Like Python and wxWindows, wxPython is <b>Open Source</b> which
+means that it is free for anyone to use and the source code is
+available for anyone to look at and modify.  Or anyone can contribute
+fixes or enhancements to the project.
+
+<p> wxPython is a <b>cross-platform</b> toolkit.  This means that the
+same program will run on multiple platforms without modification.
+Currently supported platforms are 32-bit Microsoft Windows, most Unix
+or unix-like systems, and Macintosh OS X. Since the language is
+Python, wxPython programs are <b>simple, easy</b> to write and easy to
+understand.
+
+<p> <b>This demo</b> is not only a collection of test cases for
+wxPython, but is also designed to help you learn about and how to use
+wxPython.  Each sample is listed in the tree control on the left.
+When a sample is selected in the tree then a module is loaded and run
+(usually in a tab of this notebook,) and the source code of the module
+is loaded in another tab for you to browse and learn from.
+
+"""
 
 
 #----------------------------------------------------------------------------
 
 
 #----------------------------------------------------------------------------