#----------------------------------------------------------------------------
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
+# For debugging
+##wx.Trap();
+##print os.getpid(); raw_input("Press a key...")
+
+
#---------------------------------------------------------------------------
_treeList = [
- ('New since last release', ['ContextHelp',
- 'PyCrust',
- 'PyCrustWithFilling',
- 'VirtualListCtrl',
- 'wxListCtrl',
- 'TablePrint',
- 'OOR',
- 'wxFindReplaceDialog',
- 'DrawXXXList',
- 'ErrorDialogs',
- 'wxRightTextCtrl',
- 'URLDragAndDrop',
- 'wxMimeTypesManager',
- 'wxPopupWindow',
- 'wxDynamicSashWindow',
- 'wxEditableListBox',
- ]),
-
- ('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',
- ]),
-
- ('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',
- ]),
-
- ('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', [
+ 'VListBox',
+ 'Listbook',
+ 'MaskedNumCtrl',
+ 'FloatCanvas',
+ 'XmlResourceSubclass',
+ 'GridBagSizer',
+ 'Cursor',
+ 'PyPlot',
+ ]),
+
+ # managed windows == things with a (optional) caption you can close
+ ('Base Frames and Dialogs', [
+ 'Dialog',
+ 'Frame',
+ 'MDIWindows',
+ 'MiniFrame',
+ 'Wizard',
+ ]),
+
+ # the common dialogs
+ ('Common Dialogs', [
+ 'ColourDialog',
+ 'DirDialog',
+ 'FileDialog',
+ 'FileDialog_Save',
+ 'FindReplaceDialog',
+ 'FontDialog',
+ 'MessageDialog',
+ 'PageSetupDialog',
+ 'PrintDialog',
+ 'ProgressDialog',
+ 'SingleChoiceDialog',
+ 'TextEntryDialog',
+ ]),
+
+ # dialogs from libraries
+ ('More Dialogs', [
+ 'ErrorDialogs',
+ 'ImageBrowser',
+ 'MultipleChoiceDialog',
+ 'ScrolledMessageDialog',
+ ]),
+
+ # core controls
+ ('Core Windows/Controls', [
+ 'Button',
+ 'CheckBox',
+ 'CheckListBox',
+ 'Choice',
+ 'ComboBox',
+ 'Gauge',
+ 'Grid',
+ 'Grid_MegaExample',
+ 'ListBox',
+ 'ListCtrl',
+ 'ListCtrl_virtual',
+ 'Listbook',
+ 'Menu',
+ 'Notebook',
+ 'PopupMenu',
+ 'PopupWindow',
+ 'RadioBox',
+ 'RadioButton',
+ 'SashWindow',
+ 'ScrolledWindow',
+ 'Slider',
+ 'SpinButton',
+ 'SpinCtrl',
+ 'SplitterWindow',
+ 'StaticBitmap',
+ 'StaticText',
+ 'StatusBar',
+ 'TextCtrl',
+ 'ToggleButton',
+ 'ToolBar',
+ 'TreeCtrl',
+ 'Validator',
+ ]),
+
+ ('Custom Controls', [
+ 'AnalogClockWindow',
+ 'ColourSelect',
+ 'Editor',
+ 'GenericButtons',
+ 'GenericDirCtrl',
+ 'LEDNumberCtrl',
+ 'MultiSash',
+ 'PopupControl',
+ 'PyColourChooser',
+ 'TreeListCtrl',
+ ]),
+
+ # controls coming from other libraries
+ ('More Windows/Controls', [
+ #'RightTextCtrl', deprecated as we have wxTE_RIGHT now.
+ 'Calendar',
+ 'CalendarCtrl',
+ 'ContextHelp',
+ 'DynamicSashWindow',
+ 'EditableListBox',
+ 'FancyText',
+ 'FileBrowseButton',
+ 'FloatBar',
+ 'FloatCanvas',
+ 'HtmlWindow',
+ 'IEHtmlWin',
+ 'IntCtrl',
+ 'MVCTree',
+ 'MaskedEditControls',
+ 'MaskedNumCtrl',
+ 'MimeTypesManager',
+ 'PyCrust',
+ 'PyPlot',
+ 'PyShell',
+ 'ScrolledPanel',
+ 'SplitTree',
+ 'StyledTextCtrl_1',
+ 'StyledTextCtrl_2',
+ 'TablePrint',
+ 'Throbber',
+ 'TimeCtrl',
+ 'VListBox',
+ ]),
+
+ # How to lay out the controls in a frame/dialog
+ ('Window Layout', [
+ 'GridBagSizer',
+ 'LayoutAnchors',
+ 'LayoutConstraints',
+ 'Layoutf',
+ 'RowColSizer',
+ 'ScrolledPanel',
+ 'Sizers',
+ 'XmlResource',
+ 'XmlResourceHandler',
+ 'XmlResourceSubclass',
+ ]),
+
+ # ditto
+ ('Process and Events', [
+ 'EventManager',
+ 'KeyEvents',
+ 'OOR',
+ 'Process',
+ 'PythonEvents',
+ 'Threads',
+ 'Timer',
+ 'infoframe',
+ ]),
+
+ # Clipboard and DnD
+ ('Clipboard and DnD', [
+ 'CustomDragAndDrop',
+ 'DragAndDrop',
+ 'URLDragAndDrop',
+ ]),
+
+ # Images
+ ('Using Images', [
+ 'ArtProvider',
+ 'Cursor',
+ 'DragImage',
+ 'Image',
+ 'ImageFromStream',
+ 'Mask',
+ 'Throbber',
+ ]),
+
+ # Other stuff
+ ('Miscellaneous', [
+ 'ColourDB',
+ 'DialogUnits',
+ 'DrawXXXList',
+ 'FileHistory',
+ 'FontEnumerator',
+ 'Joystick',
+ 'NewNamespace',
+ 'OGL',
+ 'PrintFramework',
+ 'ShapedWindow',
+ 'Sound',
+ 'Unicode',
+ ]),
+
+ # need libs not coming with the demo
+ ('Objects using an external library', [
+ 'ActiveXWrapper_Acrobat',
+ 'ActiveXWrapper_IE',
+ 'GLCanvas',
+ #'PlotCanvas', # deprecated, use PyPlot
+ ]),
+
+
+ ('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):
- wxPyLog.__init__(self)
+ wx.PyLog.__init__(self)
self.tc = textCtrl
self.logTime = logTime
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 StyledTextCtrl_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 StyledTextCtrl_2 import PythonSTC
+ class DemoCodeViewer(PythonSTC):
+ def __init__(self, parent, ID):
+ PythonSTC.__init__(self, parent, ID)
+ self.SetUpEditor()
+
+ # 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)
+
+ def SetUpEditor(self):
+ """
+ This method carries out the work of setting up the demo editor.
+ It's seperate so as not to clutter up the init code.
+ """
+ import keyword
+
+ self.SetLexer(stc.STC_LEX_PYTHON)
+ self.SetKeyWords(0, " ".join(keyword.kwlist))
+
+ # Enable folding
+ self.SetProperty("fold", "1" )
+
+ # Highlight tab/space mixing (shouldn't be any)
+ self.SetProperty("tab.timmy.whinge.level", "1")
+
+ # Set left and right margins
+ self.SetMargins(2,2)
+
+ # Set up the numbers in the margin for margin #1
+ self.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
+ # Reasonable value for, say, 4-5 digits using a mono font (40 pix)
+ self.SetMarginWidth(1, 40)
+
+ # Indentation and tab stuff
+ self.SetIndent(4) # Proscribed indent size for wx
+ self.SetIndentationGuides(True) # Show indent guides
+ self.SetBackSpaceUnIndents(True)# Backspace unindents rather than delete 1 space
+ self.SetTabIndents(True) # Tab key indents
+ self.SetTabWidth(4) # Proscribed tab size for wx
+ self.SetUseTabs(False) # Use spaces rather than tabs, or
+ # TabTimmy will complain!
+ # White space
+ self.SetViewWhiteSpace(False) # Don't view white space
+
+ # EOL
+ #self.SetEOLMode(wx.stc.STC_EOL_CRLF) # Just leave it at the default (autosense)
+ self.SetViewEOL(False)
+ # No right-edge mode indicator
+ self.SetEdgeMode(stc.STC_EDGE_NONE)
+
+ # Setup a margin to hold fold markers
+ self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
+ self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
+ self.SetMarginSensitive(2, True)
+ self.SetMarginWidth(2, 12)
+
+ # and now set up the fold markers
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "black")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "black")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "black")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "black")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "black")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "black")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "black")
+
+ # Global default style
+ if wx.Platform == '__WXMSW__':
+ self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
+ 'fore:#000000,back:#FFFFFF,face:Courier New,size:9')
+ else:
+ self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
+ 'fore:#000000,back:#FFFFFF,face:Courier,size:12')
+
+ # Clear styles and revert to default.
+ self.StyleClearAll()
+
+ # Following style specs only indicate differences from default.
+ # The rest remains unchanged.
+
+ # Line numbers in margin
+ self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2')
+
+ # Highlighted brace
+ self.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00')
+ # Unmatched brace
+ self.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,'fore:#00009D,back:#FF0000')
+ # Indentation guide
+ self.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD")
+
+ # Python styles
+ self.StyleSetSpec(wx.stc.STC_P_DEFAULT, 'fore:#000000')
+ # Comments
+ self.StyleSetSpec(wx.stc.STC_P_COMMENTLINE, 'fore:#008000,back:#F0FFF0')
+ self.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, 'fore:#008000,back:#F0FFF0')
+ # Numbers
+ self.StyleSetSpec(wx.stc.STC_P_NUMBER, 'fore:#008080')
+ # Strings and characters
+ self.StyleSetSpec(wx.stc.STC_P_STRING, 'fore:#800080')
+ self.StyleSetSpec(wx.stc.STC_P_CHARACTER, 'fore:#800080')
+ # Keywords
+ self.StyleSetSpec(wx.stc.STC_P_WORD, 'fore:#000080,bold')
+ # Triple quotes
+ self.StyleSetSpec(wx.stc.STC_P_TRIPLE, 'fore:#800080,back:#FFFFEA')
+ self.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, 'fore:#800080,back:#FFFFEA')
+ # Class names
+ self.StyleSetSpec(wx.stc.STC_P_CLASSNAME, 'fore:#0000FF,bold')
+ # Function names
+ self.StyleSetSpec(wx.stc.STC_P_DEFNAME, 'fore:#008080,bold')
+ # Operators
+ self.StyleSetSpec(wx.stc.STC_P_OPERATOR, 'fore:#800000,bold')
+ # Identifiers. I leave this as not bold because everything seems
+ # to be an identifier if it doesn't match the above criterae
+ self.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, 'fore:#000000')
+
+ # Caret color
+ self.SetCaretForeground("BLUE")
+ # Selection background
+ self.SetSelBackground(1, '#66CCFF')
+
+ self.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
+ self.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
+
+
+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)
#---------------------------------------------------------------------------
-class wxPythonDemo(wxFrame):
+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):
- 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.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)
- if wxPlatform == '__WXMSW__':
+ if wx.Platform != '__WXMAC__':
# setup a taskbar icon, and catch some events from it
- self.tbicon = wxTaskBarIcon()
+ icon = wx.IconFromBitmap(
+ images.getMondrianImage().Scale(16,16).ConvertToBitmap() )
+ self.tbicon = wx.TaskBarIcon()
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)
+ self.tbicon.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate)
+ self.tbicon.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.OnTaskBarMenu)
+ self.tbicon.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE)
+ self.tbicon.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE)
+ wx.CallAfter(self.ShowTip)
self.otherWin = None
- EVT_IDLE(self, self.OnIdle)
- EVT_CLOSE(self, self.OnCloseWindow)
- EVT_ICONIZE(self, self.OnIconfiy)
- EVT_MAXIMIZE(self, self.OnMaximize)
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+ self.Bind(wx.EVT_ICONIZE, self.OnIconfiy)
+ self.Bind(wx.EVT_MAXIMIZE, self.OnMaximize)
+
+ self.Centre(wx.BOTH)
+ self.CreateStatusBar(1, wx.ST_SIZEGRIP)
+
+ splitter = wx.SplitterWindow(self, -1)
+ splitter2 = wx.SplitterWindow(splitter, -1)
+
+ # Set up a log on the View Log Notebook page
+ self.log = wx.TextCtrl(splitter2, -1,
+ style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
+
+ # Set the wxWindows log target to be this textctrl
+ #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.Centre(wxBOTH)
- self.CreateStatusBar(1, wxST_SIZEGRIP)
- splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
- splitter2 = wxSplitterWindow(splitter, -1, style=wxNO_3D|wxSP_3D)
def EmptyHandler(evt): pass
- EVT_ERASE_BACKGROUND(splitter, EmptyHandler)
- EVT_ERASE_BACKGROUND(splitter2, EmptyHandler)
+ #splitter.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
+ #splitter2.Bind(wx.EVT_ERASE_BACKGROUND, 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
- self.mainmenu = wxMenuBar()
- menu = wxMenu()
- exitID = wxNewId()
- menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!')
- EVT_MENU(self, exitID, self.OnFileExit)
+ self.mainmenu = wx.MenuBar()
+ menu = wx.Menu()
+ item = menu.Append(-1, 'E&xit\tAlt-X', 'Get the heck outta here!')
+ self.Bind(wx.EVT_MENU, self.OnFileExit, item)
+ wx.App_SetMacExitMenuItemId(item.GetId())
self.mainmenu.Append(menu, '&File')
# Make a Demo menu
- menu = wxMenu()
+ menu = wx.Menu()
for item in _treeList:
- submenu = wxMenu()
+ submenu = wx.Menu()
for childItem in item[1]:
- mID = wxNewId()
- submenu.Append(mID, childItem)
- EVT_MENU(self, mID, self.OnDemoMenu)
- menu.AppendMenu(wxNewId(), item[0], submenu)
+ mi = submenu.Append(-1, childItem)
+ self.Bind(wx.EVT_MENU, self.OnDemoMenu, mi)
+ menu.AppendMenu(wx.NewId(), item[0], submenu)
self.mainmenu.Append(menu, '&Demo')
# Make a Help menu
- helpID = wxNewId()
- menu = wxMenu()
- menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!')
- EVT_MENU(self, helpID, self.OnHelpAbout)
+ helpID = wx.NewId()
+ findID = wx.NewId()
+ findnextID = wx.NewId()
+ menu = wx.Menu()
+ findItem = menu.Append(-1, '&Find\tCtrl-F', 'Find in the Demo Code')
+ findnextItem = menu.Append(-1, 'Find &Next\tF3', 'Find Next')
+ menu.AppendSeparator()
+ helpItem = menu.Append(-1, '&About\tCtrl-H', 'wxPython RULES!!!')
+ wx.App_SetMacAboutMenuItemId(helpItem.GetId())
+ self.Bind(wx.EVT_MENU, self.OnHelpAbout, helpItem)
+ self.Bind(wx.EVT_MENU, self.OnHelpFind, findItem)
+ self.Bind(wx.EVT_MENU, self.OnFindNext, findnextItem)
+ self.Bind(wx.EVT_COMMAND_FIND, self.OnFind)
+ self.Bind(wx.EVT_COMMAND_FIND_NEXT, self.OnFind)
+ self.Bind(wx.EVT_COMMAND_FIND_CLOSE, self.OnFindClose)
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
- tID = wxNewId()
+ tID = wx.NewId()
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])
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)
+ self.tree.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, id=tID)
+ self.tree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, id=tID)
+ self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=tID)
+ self.tree.Bind(wx.EVT_LEFT_DOWN, self.OnTreeLeftDown)
# 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
- 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())
- EVT_SIZE(panel, OnOvrSize)
- EVT_ERASE_BACKGROUND(panel, EmptyHandler)
+ panel.Bind(wx.EVT_SIZE, OnOvrSize)
+ panel.Bind(wx.EVT_ERASE_BACKGROUND, 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.LoadDemoSource('Main.py')
- # Set up a log on the View Log Notebook page
- self.log = wxTextCtrl(splitter2, -1,
- style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
- # Set the wxWindows log target to be this textctrl
- #wxLog_SetActiveTarget(wxLogTextCtrl(self.log))
- wxLog_SetActiveTarget(MyLog(self.log))
+ # add the windows to the splitter and split it.
+ splitter2.SplitHorizontally(self.nb, self.log, -120)
+ splitter.SplitVertically(self.tree, splitter2, 180)
+ splitter.SetMinimumPaneSize(20)
+ splitter2.SetMinimumPaneSize(20)
- self.Show(true)
+ # Make the splitter on the right expand the top window when resized
+ def SplitterOnSize(evt):
+ splitter = evt.GetEventObject()
+ sz = splitter.GetSize()
+ splitter.SetSashPosition(sz.height - 120, False)
+ evt.Skip()
- # add the windows to the splitter and split it.
- splitter2.SplitHorizontally(self.nb, self.log)
- splitter2.SetSashPosition(450, true)
- splitter2.SetMinimumPaneSize(20)
-
- splitter.SplitVertically(self.tree, splitter2)
- splitter.SetSashPosition(180, true)
- splitter.SetMinimumPaneSize(20)
+ splitter2.Bind(wx.EVT_SIZE, SplitterOnSize)
# select initial items
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]
- wxLogMessage(text)
+ wx.LogMessage(text)
def write(self, txt):
#---------------------------------------------
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()
- wxLogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
+ wx.LogMessage("OnItemCollapsed: %s" % self.tree.GetItemText(item))
event.Skip()
#---------------------------------------------
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()
#---------------------------------------------
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)
- if itemText == 'Overview':
- self.GetDemoFile('Main.py')
- self.SetOverview('Overview', overview)
+ if itemText == self.overviewText:
+ self.LoadDemoSource('Main.py')
+ self.SetOverview(self.overviewText, overview)
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')
+ self.LoadDemoSource(itemText + '.py')
+
+ if (sys.modules.has_key(itemText)):
+ reload(sys.modules[itemText])
+
module = __import__(itemText, globals())
- self.SetOverview(itemText, module.overview)
+ self.SetOverview(itemText + " Overview", module.overview)
finally:
- wxEndBusyCursor()
+ wx.EndBusyCursor()
+ self.tree.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) ###
- if self.window:
+ if self.window is not None:
self.nb.AddPage(self.window, 'Demo')
- wxYield()
self.nb.SetSelection(2)
+ self.nb.Refresh() # without this wxMac has troubles showing the just added page
else:
self.ovr.SetPage("")
#---------------------------------------------
# Get the Demo files
- def GetDemoFile(self, filename):
+ def LoadDemoSource(self, filename):
self.txt.Clear()
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.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)
def OnFileExit(self, *event):
self.Close()
-
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):
- self.dying = true
+ self.dying = True
self.window = None
self.mainmenu = None
if hasattr(self, "tbicon"):
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 OnTaskBarActivate(self, evt):
if self.IsIconized():
- self.Iconize(false)
+ self.Iconize(False)
if not self.IsShown():
- self.Show(true)
+ self.Show(True)
self.Raise()
#---------------------------------------------
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)
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
- wxGetApp().ProcessIdle()
+ wx.GetApp().ProcessIdle()
#---------------------------------------------
def OnIconfiy(self, evt):
- wxLogMessage("OnIconfiy")
+ wx.LogMessage("OnIconfiy")
evt.Skip()
#---------------------------------------------
def OnMaximize(self, evt):
- wxLogMessage("OnMaximize")
+ wx.LogMessage("OnMaximize")
evt.Skip()
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
-class MyApp(wxApp):
- def OnInit(self):
- wxInitAllImageHandlers()
+class MySplashScreen(wx.SplashScreen):
+ def __init__(self):
+ bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap()
+ wx.SplashScreen.__init__(self, bmp,
+ wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT,
+ 3000, None, -1)
+ self.Bind(wx.EVT_CLOSE, self.OnClose)
- self.splash = SplashScreen(None, bitmapfile='bitmaps/splash.gif',
- duration=4000, callback=self.AfterSplash)
- self.splash.Show(true)
- wxYield()
- return true
+ def OnClose(self, evt):
+ frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
+ frame.Show()
+ evt.Skip() # Make sure the default handler runs too...
- def AfterSplash(self):
- self.splash.Close(true)
- frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)")
- frame.Show(true)
- self.SetTopWindow(frame)
- self.ShowTip(frame)
+class MyApp(wx.App):
+ def OnInit(self):
+ """
+ Create and show the splash screen. It will then create and show
+ the main frame when it is time to do so.
+ """
+ wx.InitAllImageHandlers()
+
+ # Normally when using a SplashScreen you would create it, show
+ # it and then continue on with the applicaiton's
+ # initialization, finally creating and showing the main
+ # application window(s). In this case we have nothing else to
+ # do so we'll delay showing the main frame until later (see
+ # OnClose above) so the users can see the SplashScrren effect.
+ splash = MySplashScreen()
+ splash.Show()
+
+ return True
- def ShowTip(self, frame):
- try:
- showTipText = open("data/showTips").read()
- showTip, index = eval(showTipText)
- except IOError:
- showTip, index = (1, 0)
- #print showTip, index
- if showTip:
- tp = wxCreateFileTipProvider("data/tips.txt", index)
- showTip = wxShowTip(frame, tp)
- index = tp.GetCurrentTip()
- open("data/showTips", "w").write(str( (showTip, index) ))
#---------------------------------------------------------------------------
os.chdir(demoPath)
except:
pass
- app = MyApp(0)
+ app = MyApp(0) #wx.Platform == "__WXMAC__")
app.MainLoop()
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.
+
+"""
#----------------------------------------------------------------------------