X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/08ecc92023f15aaa5695a616f9712c980650c7c7..9d45af36fe32c2aba06e9692f7a133884ce75f53:/wxPython/demo/Main.py diff --git a/wxPython/demo/Main.py b/wxPython/demo/Main.py index 642d5427f1..fa46693622 100644 --- a/wxPython/demo/Main.py +++ b/wxPython/demo/Main.py @@ -36,8 +36,8 @@ import images # For debugging ##wx.Trap(); -##print "wx.VERSION_STRING = ", wx.VERSION_STRING -##print os.getpid(); +##print "wx.VERSION_STRING = %s (%s)" % (wx.VERSION_STRING, wx.USE_UNICODE and 'unicode' or 'ansi') +##print "pid:", os.getpid() ##raw_input("Press Enter...") @@ -47,12 +47,29 @@ import images _treeList = [ # new stuff ('Recent Additions/Updates', [ - 'OGL', - 'FloatCanvas', + 'AnalogClock', + 'AUI_DockingWindowMgr', + 'AUI_Notebook', + 'CheckListCtrlMixin', + 'ComboTreeBox', + 'Pickers', + 'PseudoDC', + 'RichTextCtrl', + 'Treebook', + 'Toolbook', + 'BitmapFromBuffer', + 'RawBitmapAccess', + 'DragScroller', +## 'AlphaDrawing', + 'DelayedResult', + 'ExpandoTextCtrl', + 'ButtonPanel', + 'FlatNotebook', ]), # managed windows == things with a (optional) caption you can close - ('Base Frames and Dialogs', [ + ('Frames and Dialogs', [ + 'AUI_DockingWindowMgr', 'Dialog', 'Frame', 'MDIWindows', @@ -65,10 +82,10 @@ _treeList = [ 'ColourDialog', 'DirDialog', 'FileDialog', - 'FileDialog_Save', 'FindReplaceDialog', 'FontDialog', 'MessageDialog', + 'MultiChoiceDialog', 'PageSetupDialog', 'PrintDialog', 'ProgressDialog', @@ -79,7 +96,6 @@ _treeList = [ # dialogs from libraries ('More Dialogs', [ 'ImageBrowser', - 'MultipleChoiceDialog', 'ScrolledMessageDialog', ]), @@ -97,9 +113,8 @@ _treeList = [ 'ListBox', 'ListCtrl', 'ListCtrl_virtual', - 'Listbook', + 'ListCtrl_edit', 'Menu', - 'Notebook', 'PopupMenu', 'PopupWindow', 'RadioBox', @@ -111,19 +126,33 @@ _treeList = [ 'SpinCtrl', 'SplitterWindow', 'StaticBitmap', + 'StaticBox', 'StaticText', 'StatusBar', + 'StockButtons', 'TextCtrl', 'ToggleButton', 'ToolBar', 'TreeCtrl', 'Validator', ]), + + ('"Book" Controls', [ + 'AUI_Notebook', + 'Choicebook', + 'Listbook', + 'Notebook', + 'Toolbook', + 'Treebook', + ]), ('Custom Controls', [ - 'AnalogClockWindow', + 'AnalogClock', + 'ButtonPanel', 'ColourSelect', + 'ComboTreeBox', 'Editor', + 'FlatNotebook', 'GenericButtons', 'GenericDirCtrl', 'LEDNumberCtrl', @@ -141,28 +170,38 @@ _treeList = [ #'RightTextCtrl', deprecated as we have wxTE_RIGHT now. 'Calendar', 'CalendarCtrl', + 'CheckListCtrlMixin', 'ContextHelp', + 'DatePickerCtrl', 'DynamicSashWindow', 'EditableListBox', + 'ExpandoTextCtrl', 'FancyText', 'FileBrowseButton', 'FloatBar', 'FloatCanvas', + 'FoldPanelBar', + 'GIFAnimationCtrl', 'HtmlWindow', + 'HyperLinkCtrl', 'IntCtrl', 'MVCTree', 'MaskedEditControls', 'MaskedNumCtrl', - 'MimeTypesManager', + 'MediaCtrl', + 'MultiSplitterWindow', + 'Pickers', 'PyCrust', 'PyPlot', 'PyShell', + 'RichTextCtrl', 'ScrolledPanel', 'SplitTree', 'StyledTextCtrl_1', 'StyledTextCtrl_2', 'TablePrint', 'Throbber', + 'Ticker', 'TimeCtrl', 'VListBox', ]), @@ -183,13 +222,14 @@ _treeList = [ # ditto ('Process and Events', [ + 'DelayedResult', 'EventManager', 'KeyEvents', 'Process', 'PythonEvents', 'Threads', 'Timer', - 'infoframe', + ##'infoframe', # needs better explanation and some fixing ]), # Clipboard and DnD @@ -201,36 +241,42 @@ _treeList = [ # Images ('Using Images', [ +## 'AlphaDrawing', 'ArtProvider', + 'BitmapFromBuffer', 'Cursor', 'DragImage', + 'GIFAnimationCtrl', 'Image', 'ImageAlpha', 'ImageFromStream', 'Mask', + 'RawBitmapAccess', 'Throbber', ]), # Other stuff ('Miscellaneous', [ +## 'AlphaDrawing', 'ColourDB', - 'DialogUnits', + ##'DialogUnits', # needs more explanations + 'DragScroller', 'DrawXXXList', 'FileHistory', 'FontEnumerator', + 'GLCanvas', 'Joystick', + 'MimeTypesManager', + 'MouseGestures', 'OGL', 'PrintFramework', + 'PseudoDC', 'ShapedWindow', 'Sound', + 'StandardPaths', 'Unicode', ]), - # need libs not coming with the demo - ('Samples using an external library', [ - 'GLCanvas', - ]), - ('Check out the samples dir too', [ ]), @@ -249,9 +295,10 @@ class MyLog(wx.PyLog): self.logTime = logTime def DoLogString(self, message, timeStamp): - if self.logTime: - message = time.strftime("%X", time.localtime(timeStamp)) + \ - ": " + message + #print message, timeStamp + #if self.logTime: + # message = time.strftime("%X", time.localtime(timeStamp)) + \ + # ": " + message if self.tc: self.tc.AppendText(message + '\n') @@ -260,6 +307,60 @@ class MyTP(wx.PyTipProvider): def GetTip(self): return "This is my tip" +#--------------------------------------------------------------------------- +# A class to be used to simply display a message in the demo pane +# rather than running the sample itself. + +class MessagePanel(wx.Panel): + def __init__(self, parent, message, caption='', flags=0): + wx.Panel.__init__(self, parent) + + # Make widgets + if flags: + artid = None + if flags & wx.ICON_EXCLAMATION: + artid = wx.ART_WARNING + elif flags & wx.ICON_ERROR: + artid = wx.ART_ERROR + elif flags & wx.ICON_QUESTION: + artid = wx.ART_QUESTION + elif flags & wx.ICON_INFORMATION: + artid = wx.ART_INFORMATION + + if artid is not None: + bmp = wx.ArtProvider.GetBitmap(artid, wx.ART_MESSAGE_BOX, (32,32)) + icon = wx.StaticBitmap(self, -1, bmp) + else: + icon = (32,32) # make a spacer instead + + if caption: + caption = wx.StaticText(self, -1, caption) + caption.SetFont(wx.Font(28, wx.SWISS, wx.NORMAL, wx.BOLD)) + + message = wx.StaticText(self, -1, message) + + # add to sizers for layout + tbox = wx.BoxSizer(wx.VERTICAL) + if caption: + tbox.Add(caption) + tbox.Add((10,10)) + tbox.Add(message) + + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add((10,10), 1) + hbox.Add(icon) + hbox.Add((10,10)) + hbox.Add(tbox) + hbox.Add((10,10), 1) + + box = wx.BoxSizer(wx.VERTICAL) + box.Add((10,10), 1) + box.Add(hbox, 0, wx.EXPAND) + box.Add((10,10), 2) + + self.SetSizer(box) + self.Fit() + #--------------------------------------------------------------------------- # A class to be used to display source code in the demo. Try using the @@ -274,7 +375,7 @@ try: class DemoCodeEditor(PythonSTC): def __init__(self, parent): - PythonSTC.__init__(self, parent, -1, wx.BORDER_NONE) + PythonSTC.__init__(self, parent, -1, style=wx.BORDER_NONE) self.SetUpEditor() # Some methods to make it compatible with how the wxTextCtrl is used @@ -297,7 +398,8 @@ try: def ShowPosition(self, pos): line = self.LineFromPosition(pos) - self.EnsureVisible(line) + #self.EnsureVisible(line) + self.GotoLine(line) def GetLastPosition(self): return self.GetLength() @@ -355,9 +457,12 @@ try: # 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) + # EOL: Since we are loading/saving ourselves, and the + # strings will always have \n's in them, set the STC to + # edit them that way. + self.SetEOLMode(wx.stc.STC_EOL_LF) + self.SetViewEOL(False) + # No right-edge mode indicator self.SetEdgeMode(stc.STC_EDGE_NONE) @@ -382,7 +487,7 @@ try: 'fore:#000000,back:#FFFFFF,face:Courier New,size:9') else: self.StyleSetSpec(stc.STC_STYLE_DEFAULT, - 'fore:#000000,back:#FFFFFF,face:Courier,size:12') + 'fore:#000000,back:#FFFFFF,face:Courier,size:9') # Clear styles and revert to default. self.StyleClearAll() @@ -391,8 +496,7 @@ try: # The rest remains unchanged. # Line numbers in margin - self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2') - + 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 @@ -440,8 +544,8 @@ try: except ImportError: class DemoCodeEditor(wx.TextCtrl): def __init__(self, parent): - wx.TextCtrl.__init__(self, parent, -1, style = wx.TE_MULTILINE | - wx.HSCROLL | wx.TE_RICH2 | wx.TE_NOHIDESEL) + wx.TextCtrl.__init__(self, parent, -1, style = + wx.TE_MULTILINE | wx.HSCROLL | wx.TE_RICH2 | wx.TE_NOHIDESEL) def RegisterModifiedEvent(self, eventHandler): self.Bind(wx.EVT_TEXT, eventHandler) @@ -453,13 +557,13 @@ except ImportError: def GetText(self): return self.GetValue() - def GetPositionFromLine(line): + def GetPositionFromLine(self, line): return self.XYToPosition(0,line) def GotoLine(self, line): - pos = self.editor.GetPositionFromLine(line) - self.editor.SetInsertionPoint(pos) - self.editor.ShowPosition(pos) + pos = self.GetPositionFromLine(line) + self.SetInsertionPoint(pos) + self.ShowPosition(pos) def SelectLine(self, line): start = self.GetPositionFromLine(line) @@ -479,7 +583,9 @@ modDefault = modOriginal class DemoCodePanel(wx.Panel): """Panel for the 'Demo Code' tab""" def __init__(self, parent, mainFrame): - wx.Panel.__init__(self, parent) + wx.Panel.__init__(self, parent, size=(1,1)) + if 'wxMSW' in wx.PlatformInfo: + self.Hide() self.mainFrame = mainFrame self.editor = DemoCodeEditor(self) self.editor.RegisterModifiedEvent(self.OnCodeModified) @@ -506,6 +612,7 @@ class DemoCodePanel(wx.Panel): self.box = wx.BoxSizer(wx.VERTICAL) self.box.Add(self.controlBox, 0, wx.EXPAND) + self.box.Add(wx.StaticLine(self), 0, wx.EXPAND) self.box.Add(self.editor, 1, wx.EXPAND) self.box.Fit(self) @@ -601,7 +708,7 @@ class DemoCodePanel(wx.Panel): try: os.makedirs(GetModifiedDirectory()) if not os.path.exists(GetModifiedDirectory()): - wx.LogMessage("BUG: Created demo directory but it still doesn't exit") + wx.LogMessage("BUG: Created demo directory but it still doesn't exist") raise AssetionError except: wx.LogMessage("Error creating demo directory: %s" % GetModifiedDirectory()) @@ -610,7 +717,7 @@ class DemoCodePanel(wx.Panel): wx.LogMessage("Created directory for modified demos: %s" % GetModifiedDirectory()) # Save - f = open(modifiedFilename, "w") + f = open(modifiedFilename, "wt") source = self.editor.GetText() try: f.write(source) @@ -704,6 +811,7 @@ class DemoModules: # load original module self.LoadFromFile(modOriginal, GetOriginalFilename(name)) + self.SetActive(modOriginal) # load modified module (if one exists) if DoesModifiedExist(name): @@ -712,7 +820,7 @@ class DemoModules: def LoadFromFile(self, modID, filename): self.modules[modID][2] = filename - file = open(filename, "r") + file = open(filename, "rt") self.LoadFromSource(modID, file.read()) file.close() @@ -725,7 +833,8 @@ class DemoModules: def LoadDict(self, modID): if self.name != __name__: source = self.modules[modID][1] - description = self.modules[modID][3] + #description = self.modules[modID][3] + description = self.modules[modID][2] try: self.modules[modID][0] = {} @@ -789,7 +898,7 @@ class DemoModules: filename = self.modules[modID][2] try: - file = open(filename, "w") + file = open(filename, "wt") file.write(source) finally: file.close() @@ -804,35 +913,6 @@ class DemoModules: self.modules[modID][2] = "" -#--------------------------------------------------------------------------- -class ReloadDemoPanel(wx.Panel): - """ - Panel put into the demo tab when the demo just shows some - top-level window. Enables the demo to be reloaded after being - closed. - """ - - infoText = "This demo runs outside the main window" - - def __init__(self, parent, codePanel, log): - wx.Panel.__init__(self, parent, -1) - self.codePanel = codePanel - self.log = log - - self.label = wx.StaticText(self, -1, self.infoText) - self.btnReload = wx.Button(self, -1, "Reload Demo") - self.btnReload.Bind(wx.EVT_BUTTON, self.OnReload) - - self.box = wx.BoxSizer(wx.VERTICAL) - self.box.Add(self.label, 0, wx.ALIGN_CENTER | wx.ALL, 10) - self.box.Add(self.btnReload, 0, wx.ALIGN_CENTER | wx.ALL, 10) - - self.box.Fit(self) - self.SetSizer(self.box) - - def OnReload(self, event): - self.codePanel.ReloadDemo() - #--------------------------------------------------------------------------- class DemoError: @@ -890,7 +970,7 @@ class DemoErrorPanel(wx.Panel): self.box = wx.BoxSizer(wx.VERTICAL) # Main Label - self.box.Add(wx.StaticText(self, -1, "An error has occured while trying to run the demo") + self.box.Add(wx.StaticText(self, -1, "An error has occurred while trying to run the demo") , 0, wx.ALIGN_CENTER | wx.TOP, 10) # Exception Information @@ -967,37 +1047,115 @@ class DemoErrorPanel(wx.Panel): #--------------------------------------------------------------------------- +class DemoTaskBarIcon(wx.TaskBarIcon): + TBMENU_RESTORE = wx.NewId() + TBMENU_CLOSE = wx.NewId() + TBMENU_CHANGE = wx.NewId() + TBMENU_REMOVE = wx.NewId() + + def __init__(self, frame): + wx.TaskBarIcon.__init__(self) + self.frame = frame + + # Set the image + icon = self.MakeIcon(images.getWXPdemoImage()) + self.SetIcon(icon, "wxPython Demo") + self.imgidx = 1 + + # bind some events + self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate) + self.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE) + self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE) + self.Bind(wx.EVT_MENU, self.OnTaskBarChange, id=self.TBMENU_CHANGE) + self.Bind(wx.EVT_MENU, self.OnTaskBarRemove, id=self.TBMENU_REMOVE) + + + def CreatePopupMenu(self): + """ + This method is called by the base class when it needs to popup + the menu for the default EVT_RIGHT_DOWN event. Just create + the menu how you want it and return it from this function, + the base class takes care of the rest. + """ + menu = wx.Menu() + menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo") + menu.Append(self.TBMENU_CLOSE, "Close wxPython Demo") + menu.AppendSeparator() + menu.Append(self.TBMENU_CHANGE, "Change the TB Icon") + menu.Append(self.TBMENU_REMOVE, "Remove the TB Icon") + return menu + + + def MakeIcon(self, img): + """ + The various platforms have different requirements for the + icon size... + """ + if "wxMSW" in wx.PlatformInfo: + img = img.Scale(16, 16) + elif "wxGTK" in wx.PlatformInfo: + img = img.Scale(22, 22) + # wxMac can be any size upto 128x128, so leave the source img alone.... + icon = wx.IconFromBitmap(img.ConvertToBitmap() ) + return icon + + + def OnTaskBarActivate(self, evt): + if self.frame.IsIconized(): + self.frame.Iconize(False) + if not self.frame.IsShown(): + self.frame.Show(True) + self.frame.Raise() + + + def OnTaskBarClose(self, evt): + self.frame.Close() + + + def OnTaskBarChange(self, evt): + names = [ "WXPdemo", "Mondrian", "Pencil", "Carrot" ] + name = names[self.imgidx] + + getFunc = getattr(images, "get%sImage" % name) + self.imgidx += 1 + if self.imgidx >= len(names): + self.imgidx = 0 + + icon = self.MakeIcon(getFunc()) + self.SetIcon(icon, "This is a new icon: " + name) + + + def OnTaskBarRemove(self, evt): + self.RemoveIcon() + + +#--------------------------------------------------------------------------- class wxPythonDemo(wx.Frame): overviewText = "wxPython Overview" def __init__(self, parent, title): - wx.Frame.__init__(self, parent, -1, title, size = (950, 750), + wx.Frame.__init__(self, parent, -1, title, size = (950, 720), style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE) + self.SetMinSize((640,480)) + self.loaded = False self.cwd = os.getcwd() self.curOverview = "" self.demoPage = None self.codePage = None - self.useModified = False + self.shell = None + self.firstTime = True + self.finddlg = None - icon = images.getMondrianIcon() + icon = images.getWXPdemoIcon() self.SetIcon(icon) - if wx.Platform != '__WXMAC__': - # setup a taskbar icon, and catch some events from it - dim = 16 # (may want to use 22 on wxGTK, but 16 looks okay too) - icon = wx.IconFromBitmap( - images.getMondrianImage().Scale(dim,dim).ConvertToBitmap() ) - #icon = wx.Icon('bmp_source/mondrian.ico', wx.BITMAP_TYPE_ICO) - #icon = images.getMondrianIcon() - self.tbicon = wx.TaskBarIcon() - self.tbicon.SetIcon(icon, "wxPython Demo") - 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) - + try: + self.tbicon = DemoTaskBarIcon(self) + except: + self.tbicon = None + wx.CallAfter(self.ShowTip) self.otherWin = None @@ -1032,7 +1190,7 @@ class wxPythonDemo(wx.Frame): 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()) + wx.App.SetMacExitMenuItemId(item.GetId()) self.mainmenu.Append(menu, '&File') # Make a Demo menu @@ -1045,43 +1203,33 @@ class wxPythonDemo(wx.Frame): menu.AppendMenu(wx.NewId(), item[0], submenu) self.mainmenu.Append(menu, '&Demo') - # Make a Demo Code menu - #TODO: Add new menu items - # Like the option-enabled entries to select the - # active module - #TODO: should we bother? - - #menu = wx.Menu() - #saveID = wx.NewId() - #restoreID = wx.NewId() - # - #menu.Append(saveID, '&Save\tCtrl-S', 'Save edited demo') - #menu.Append(restoreID, '&Delete Modified\tCtrl-R', 'Delete modified copy') - #self.Bind(wx.EVT_MENU, self.codePage.OnSave, id=saveID) - #self.Bind(wx.EVT_MENU, self.codePage.OnRestore, id=restoreID) - #self.mainmenu.Append(menu, 'Demo &Code') - # # Make a Help menu - 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()) + + shellItem = menu.Append(-1, 'Open Py&Shell Window\tF5', + 'An interactive interpreter window with the demo app and frame objects in the namesapce') + menu.AppendSeparator() + helpItem = menu.Append(-1, '&About wxPython Demo', 'wxPython RULES!!!') + wx.App.SetMacAboutMenuItemId(helpItem.GetId()) + + self.Bind(wx.EVT_MENU, self.OnOpenShellWindow, shellItem) 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.Bind(wx.EVT_FIND, self.OnFind) + self.Bind(wx.EVT_FIND_NEXT, self.OnFind) + self.Bind(wx.EVT_FIND_CLOSE, self.OnFindClose) + self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateFindItems, findItem) + self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateFindItems, findnextItem) self.mainmenu.Append(menu, '&Help') self.SetMenuBar(self.mainmenu) self.finddata = wx.FindReplaceData() + self.finddata.SetFlags(wx.FR_DOWN) if 0: # This is another way to set Accelerators, in addition to @@ -1136,7 +1284,7 @@ class wxPythonDemo(wx.Frame): panel.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler) if "gtk2" in wx.PlatformInfo: - self.ovr.NormalizeFontSizes() + self.ovr.SetStandardFonts() self.SetOverview(self.overviewText, mainOverview) @@ -1155,12 +1303,15 @@ class wxPythonDemo(wx.Frame): #wx.Log_SetTraceMask(wx.TraceMessages) + self.Bind(wx.EVT_ACTIVATE, self.OnActivate) + wx.GetApp().Bind(wx.EVT_ACTIVATE_APP, self.OnAppActivate) + # add the windows to the splitter and split it. splitter2.SplitHorizontally(self.nb, self.log, -160) splitter.SplitVertically(self.tree, splitter2, 200) - splitter.SetMinimumPaneSize(20) - splitter2.SetMinimumPaneSize(20) + splitter.SetMinimumPaneSize(120) + splitter2.SetMinimumPaneSize(60) # Make the splitter on the right expand the top window when resized def SplitterOnSize(evt): @@ -1272,30 +1423,37 @@ class wxPythonDemo(wx.Frame): self.ShutdownDemoModule() overviewText = "" - # o If the demo returns a window it is placed in a tab. - # o Otherwise, a placeholder tab is created, informing the user that the - # demo runs outside the main window, and allowing it to be reloaded. - # o If an error occurs (or has occured before) an error tab is created. + # o The RunTest() for all samples must now return a window that can + # be palced in a tab in the main notebook. + # o If an error occurs (or has occurred before) an error tab is created. if module is not None: wx.LogMessage("Running demo module...") if hasattr(module, "overview"): overviewText = module.overview - # in case runTest is modal, make sure things look right... - wx.YieldIfNeeded() - try: self.demoPage = module.runTest(self, self.nb, self) - if self.demoPage is None: - self.demoPage = ReloadDemoPanel(self.nb, self.codePage, self) except: - self.demoPage = DemoErrorPanel(self.nb, self.codePage, DemoError(sys.exc_info()), self) + self.demoPage = DemoErrorPanel(self.nb, self.codePage, + DemoError(sys.exc_info()), self) + + assert self.demoPage is not None, "runTest must return a window!" + else: # There was a previous error in compiling or exec-ing - self.demoPage = DemoErrorPanel(self.nb, self.codePage, self.demoModules.GetErrorInfo(), self) + self.demoPage = DemoErrorPanel(self.nb, self.codePage, + self.demoModules.GetErrorInfo(), self) + self.SetOverview(self.demoModules.name + " Overview", overviewText) - self.UpdateNotebook() + + if self.firstTime: + # cahnge to the demo page the first time a module is run + self.UpdateNotebook(2) + self.firstTime = False + else: + # otherwise just stay on the same tab in case the user has changed to another one + self.UpdateNotebook() #--------------------------------------------- def ShutdownDemoModule(self): @@ -1323,23 +1481,12 @@ class wxPythonDemo(wx.Frame): if page: if not pageExists: # Add a new page - - # panel = wx.Panel(nb, -1) - # page.Reparent(panel) - # panel.page = page - # nb.AddPage(panel, pageText) nb.AddPage(page, pageText) if debug: wx.LogMessage("DBG: ADDED %s" % pageText) else: - # if nb.GetPage(pagePos).page != page: if nb.GetPage(pagePos) != page: # Reload an existing page nb.Freeze() - - # panel = nb.GetPage(pagePos) - # panel.page = page - # page.Reparent(panel) - nb.DeletePage(pagePos) nb.InsertPage(pagePos, page, pageText) nb.Thaw() @@ -1360,7 +1507,7 @@ class wxPythonDemo(wx.Frame): UpdatePage(self.codePage, "Demo Code") UpdatePage(self.demoPage, "Demo") - if select >= 0: + if select >= 0 and select < nb.GetPageCount(): nb.SetSelection(select) #--------------------------------------------- @@ -1395,25 +1542,40 @@ class wxPythonDemo(wx.Frame): about.Destroy() def OnHelpFind(self, event): + if self.finddlg != None: + return + self.nb.SetSelection(1) self.finddlg = wx.FindReplaceDialog(self, self.finddata, "Find", - wx.FR_NOUPDOWN | - wx.FR_NOMATCHCASE | - wx.FR_NOWHOLEWORD) + wx.FR_NOMATCHCASE | wx.FR_NOWHOLEWORD) self.finddlg.Show(True) + + def OnUpdateFindItems(self, evt): + evt.Enable(self.finddlg == None) + + def OnFind(self, event): editor = self.codePage.editor self.nb.SetSelection(1) end = editor.GetLastPosition() textstring = editor.GetRange(0, end).lower() - start = editor.GetSelection()[1] findstring = self.finddata.GetFindString().lower() - loc = textstring.find(findstring, start) + backward = not (self.finddata.GetFlags() & wx.FR_DOWN) + if backward: + start = editor.GetSelection()[0] + loc = textstring.rfind(findstring, 0, start) + else: + start = editor.GetSelection()[1] + 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 backward: + start = end + loc = textstring.rfind(findstring, 0, start) + else: + 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', @@ -1426,6 +1588,7 @@ class wxPythonDemo(wx.Frame): return else: self.finddlg.Destroy() + self.finddlg = None editor.ShowPosition(loc) editor.SetSelection(loc, loc + len(findstring)) @@ -1439,14 +1602,44 @@ class wxPythonDemo(wx.Frame): def OnFindClose(self, event): event.GetDialog().Destroy() + self.finddlg = None + + def OnOpenShellWindow(self, evt): + if self.shell: + # if it already exists then just make sure it's visible + s = self.shell + if s.IsIconized(): + s.Iconize(False) + s.Raise() + else: + # Make a PyShell window + from wx import py + namespace = { 'wx' : wx, + 'app' : wx.GetApp(), + 'frame' : self, + } + self.shell = py.shell.ShellFrame(None, locals=namespace) + self.shell.SetSize((640,480)) + self.shell.Show() + + # Hook the close event of the main frame window so that we + # close the shell at the same time if it still exists + def CloseShell(evt): + if self.shell: + self.shell.Close() + evt.Skip() + self.Bind(wx.EVT_CLOSE, CloseShell) + #--------------------------------------------- def OnCloseWindow(self, event): self.dying = True self.demoPage = None self.codePage = None self.mainmenu = None + if self.tbicon is not None: + self.tbicon.Destroy() self.Destroy() @@ -1484,38 +1677,10 @@ class wxPythonDemo(wx.Frame): self.tree.EnsureVisible(selectedDemo) - #--------------------------------------------- - def OnTaskBarActivate(self, evt): - if self.IsIconized(): - self.Iconize(False) - if not self.IsShown(): - self.Show(True) - self.Raise() - - #--------------------------------------------- - - TBMENU_RESTORE = 1000 - TBMENU_CLOSE = 1001 - - def OnTaskBarMenu(self, evt): - menu = wx.Menu() - menu.Append(self.TBMENU_RESTORE, "Restore wxPython Demo") - menu.Append(self.TBMENU_CLOSE, "Close") - self.tbicon.PopupMenu(menu) - menu.Destroy() - - #--------------------------------------------- - def OnTaskBarClose(self, evt): - self.Close() - - # 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 - wx.GetApp().ProcessIdle() - #--------------------------------------------- def OnIconfiy(self, evt): - wx.LogMessage("OnIconfiy: %d" % evt.Iconized()) + wx.LogMessage("OnIconfiy: %s" % evt.Iconized()) evt.Skip() #--------------------------------------------- @@ -1523,26 +1688,48 @@ class wxPythonDemo(wx.Frame): wx.LogMessage("OnMaximize") evt.Skip() + #--------------------------------------------- + def OnActivate(self, evt): + wx.LogMessage("OnActivate: %s" % evt.GetActive()) + evt.Skip() - + #--------------------------------------------- + def OnAppActivate(self, evt): + wx.LogMessage("OnAppActivate: %s" % evt.GetActive()) + evt.Skip() #--------------------------------------------------------------------------- #--------------------------------------------------------------------------- class MySplashScreen(wx.SplashScreen): def __init__(self): - bmp = wx.Image(opj("bitmaps/splash.gif")).ConvertToBitmap() + bmp = wx.Image(opj("bitmaps/splash.png")).ConvertToBitmap() wx.SplashScreen.__init__(self, bmp, wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT, - 3000, None, -1) + 5000, None, -1) self.Bind(wx.EVT_CLOSE, self.OnClose) + self.fc = wx.FutureCall(2000, self.ShowMain) + def OnClose(self, evt): + # Make sure the default handler runs too so this window gets + # destroyed + evt.Skip() self.Hide() + + # if the timer is still running then go ahead and show the + # main frame now + if self.fc.IsRunning(): + self.fc.Stop() + self.ShowMain() + + + def ShowMain(self): frame = wxPythonDemo(None, "wxPython: (A Demonstration)") frame.Show() - evt.Skip() # Make sure the default handler runs too... - + if self.fc.IsRunning(): + self.Raise() + class MyApp(wx.App): def OnInit(self): @@ -1551,6 +1738,8 @@ class MyApp(wx.App): the main frame when it is time to do so. """ + wx.SystemOptions.SetOptionInt("mac.window-plain-transition", 1) + # For debugging #self.SetAssertMode(wx.PYAPP_ASSERT_DIALOG) @@ -1559,7 +1748,7 @@ class MyApp(wx.App): # 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 SplashScreen effect. + # ShowMain above) so the users can see the SplashScreen effect. splash = MySplashScreen() splash.Show() @@ -1575,7 +1764,7 @@ def main(): os.chdir(demoPath) except: pass - app = MyApp(0) ##wx.Platform == "__WXMAC__") + app = MyApp(False) app.MainLoop() #---------------------------------------------------------------------------