diff --git a/wxPython/demo/Main.py b/wxPython/demo/Main.py index 30c8bbd2c8..023e62d5e9 100644 --- a/wxPython/demo/Main.py +++ b/wxPython/demo/Main.py @@ -37,8 +37,6 @@ import wx.html import images -USE_CUSTOMTREECTRL = False - # For debugging ##wx.Trap(); ##print "wx.VERSION_STRING = %s (%s)" % (wx.VERSION_STRING, wx.USE_UNICODE and 'unicode' or 'ansi') @@ -46,10 +44,16 @@ USE_CUSTOMTREECTRL = False ##raw_input("Press Enter...") +#--------------------------------------------------------------------------- + +USE_CUSTOMTREECTRL = False +ALLOW_AUI_FLOATING = False +DEFAULT_PERSPECTIVE = "Default Perspective" + #--------------------------------------------------------------------------- _demoPngs = ["overview", "recent", "frame", "dialog", "moredialog", "core", - "book", "custom", "morecontrols", "layout", "process", "clipboard", + "book", "customcontrol", "morecontrols", "layout", "process", "clipboard", "images", "miscellaneous"] _treeList = [ @@ -663,7 +667,9 @@ class DemoCodePanel(wx.Panel): def ActiveModuleChanged(self): self.LoadDemoSource(self.demoModules.GetSource()) self.UpdateControlState() + self.mainFrame.Freeze() self.ReloadDemo() + self.mainFrame.Thaw() def LoadDemoSource(self, source): @@ -758,7 +764,7 @@ class DemoCodePanel(wx.Panel): self.demoModules.LoadFromFile(modModified, modifiedFilename) self.ActiveModuleChanged() - self.mainFrame.SetTreeModified(modifiedFilename, setIcon=True) + self.mainFrame.SetTreeModified(True) def OnRestore(self, event): # Handles the "Delete Modified" button @@ -766,9 +772,10 @@ class DemoCodePanel(wx.Panel): self.demoModules.Delete(modModified) os.unlink(modifiedFilename) # Delete the modified copy busy = wx.BusyInfo("Reloading demo module...") + self.ActiveModuleChanged() - self.mainFrame.SetTreeModified(modifiedFilename, setIcon=False) + self.mainFrame.SetTreeModified(False) #--------------------------------------------------------------------------- @@ -1230,7 +1237,8 @@ class wxPythonDemo(wx.Frame): self.CreateStatusBar(1, wx.ST_SIZEGRIP) self.dying = False - + self.skipLoad = False + def EmptyHandler(evt): pass self.ReadConfigurationFile() @@ -1249,11 +1257,11 @@ class wxPythonDemo(wx.Frame): self.finddata.SetFlags(wx.FR_DOWN) # Create a TreeCtrl - leftPanel = wx.Panel(self) + leftPanel = wx.Panel(self, style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN) self.treeMap = {} self.searchItems = {} - self.tree = wxPythonTreeCtrl(leftPanel) + self.tree = wxPythonDemoTree(leftPanel) self.filter = wx.SearchCtrl(leftPanel, style=wx.TE_PROCESS_ENTER) self.filter.ShowCancelButton(True) @@ -1346,14 +1354,24 @@ class wxPythonDemo(wx.Frame): # Use the aui manager to set up everything self.mgr.AddPane(self.nb, wx.aui.AuiPaneInfo().CenterPane().Name("Notebook")) - self.mgr.AddPane(leftPanel, wx.aui.AuiPaneInfo().Left().Layer(2).BestSize((240, -1)). - MinSize((160, -1)).FloatingSize((240, 700)).Caption("wxPython Demos"). - MaximizeButton().Name("TreeDemo")) - self.mgr.AddPane(self.log, wx.aui.AuiPaneInfo().Bottom().BestSize((-1, 150)). - MinSize((-1, 60)).FloatingSize((500, 160)).Caption("Event Handlers Messages"). - MaximizeButton().Name("LogWindow")) + self.mgr.AddPane(leftPanel, + wx.aui.AuiPaneInfo(). + Left().Layer(2).BestSize((240, -1)). + MinSize((160, -1)). + Floatable(ALLOW_AUI_FLOATING).FloatingSize((240, 700)). + Caption("wxPython Demos"). + CloseButton(False). + Name("DemoTree")) + self.mgr.AddPane(self.log, + wx.aui.AuiPaneInfo(). + Bottom().BestSize((-1, 150)). + MinSize((-1, 60)). + Floatable(ALLOW_AUI_FLOATING).FloatingSize((500, 160)). + Caption("Demo Log Messages"). + CloseButton(False). + Name("LogWindow")) - self.auiConfigurations["Default Perspective"] = self.mgr.SavePerspective() + self.auiConfigurations[DEFAULT_PERSPECTIVE] = self.mgr.SavePerspective() self.mgr.Update() self.mgr.SetFlags(self.mgr.GetFlags() ^ wx.aui.AUI_MGR_ALLOW_ACTIVE_PANE) @@ -1407,41 +1425,43 @@ class wxPythonDemo(wx.Frame): self.mainmenu.Append(menu, '&Demo') # Make an Option menu - menu = wx.Menu() - auiPerspectives = self.auiConfigurations.keys() - auiPerspectives.sort() - perspectivesMenu = wx.Menu() - item = wx.MenuItem(perspectivesMenu, -1, "Default Perspective", "Load startup default perspective", wx.ITEM_RADIO) - self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item) - perspectivesMenu.AppendItem(item) - for indx, key in enumerate(auiPerspectives): - if key == "Default Perspective": - continue - item = wx.MenuItem(perspectivesMenu, -1, key, "Load user perspective %d"%indx, wx.ITEM_RADIO) - perspectivesMenu.AppendItem(item) + # If we've turned off floatable panels then this menu is not needed + if ALLOW_AUI_FLOATING: + menu = wx.Menu() + auiPerspectives = self.auiConfigurations.keys() + auiPerspectives.sort() + perspectivesMenu = wx.Menu() + item = wx.MenuItem(perspectivesMenu, -1, DEFAULT_PERSPECTIVE, "Load startup default perspective", wx.ITEM_RADIO) self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item) + perspectivesMenu.AppendItem(item) + for indx, key in enumerate(auiPerspectives): + if key == DEFAULT_PERSPECTIVE: + continue + item = wx.MenuItem(perspectivesMenu, -1, key, "Load user perspective %d"%indx, wx.ITEM_RADIO) + perspectivesMenu.AppendItem(item) + self.Bind(wx.EVT_MENU, self.OnAUIPerspectives, item) - menu.AppendMenu(wx.ID_ANY, "&AUI Perspectives", perspectivesMenu) - self.perspectives_menu = perspectivesMenu - - item = wx.MenuItem(menu, -1, 'Save Perspective', 'Save AUI perspective') - item.SetBitmap(images.catalog['saveperspective'].getBitmap()) - menu.AppendItem(item) - self.Bind(wx.EVT_MENU, self.OnSavePerspective, item) + menu.AppendMenu(wx.ID_ANY, "&AUI Perspectives", perspectivesMenu) + self.perspectives_menu = perspectivesMenu - item = wx.MenuItem(menu, -1, 'Delete Perspective', 'Delete AUI perspective') - item.SetBitmap(images.catalog['deleteperspective'].getBitmap()) - menu.AppendItem(item) - self.Bind(wx.EVT_MENU, self.OnDeletePerspective, item) + item = wx.MenuItem(menu, -1, 'Save Perspective', 'Save AUI perspective') + item.SetBitmap(images.catalog['saveperspective'].getBitmap()) + menu.AppendItem(item) + self.Bind(wx.EVT_MENU, self.OnSavePerspective, item) - menu.AppendSeparator() - - item = wx.MenuItem(menu, -1, 'Restore Tree Expansion', 'Restore the initial tree expansion state') - item.SetBitmap(images.catalog['expansion'].getBitmap()) - menu.AppendItem(item) - self.Bind(wx.EVT_MENU, self.OnTreeExpansion, item) + item = wx.MenuItem(menu, -1, 'Delete Perspective', 'Delete AUI perspective') + item.SetBitmap(images.catalog['deleteperspective'].getBitmap()) + menu.AppendItem(item) + self.Bind(wx.EVT_MENU, self.OnDeletePerspective, item) - self.mainmenu.Append(menu, '&Options') + menu.AppendSeparator() + + item = wx.MenuItem(menu, -1, 'Restore Tree Expansion', 'Restore the initial tree expansion state') + item.SetBitmap(images.catalog['expansion'].getBitmap()) + menu.AppendItem(item) + self.Bind(wx.EVT_MENU, self.OnTreeExpansion, item) + + self.mainmenu.Append(menu, '&Options') # Make a Help menu menu = wx.Menu() @@ -1492,7 +1512,6 @@ class wxPythonDemo(wx.Frame): #--------------------------------------------- def RecreateTree(self, evt=None): - # Catch the search type (name or content) searchMenu = self.filter.GetMenu().GetMenuItems() fullSearch = searchMenu[1].IsChecked() @@ -1502,12 +1521,22 @@ class wxPythonDemo(wx.Frame): # Do not`scan all the demo files for every char # the user input, use wx.EVT_TEXT_ENTER instead return - + + expansionState = self.tree.GetExpansionState() + + current = None + item = self.tree.GetSelection() + if item: + prnt = self.tree.GetItemParent(item) + if prnt: + current = (self.tree.GetItemText(item), + self.tree.GetItemText(prnt)) + self.tree.Freeze() self.tree.DeleteAllItems() self.root = self.tree.AddRoot("wxPython Overview") self.tree.SetItemImage(self.root, 0) - self.tree.SetPyData(self.root, 0) + self.tree.SetItemPyData(self.root, 0) treeFont = self.tree.GetFont() catFont = self.tree.GetFont() @@ -1517,10 +1546,10 @@ class wxPythonDemo(wx.Frame): catFont.SetWeight(wx.BOLD) firstChild = None + selectItem = None filter = self.filter.GetValue() count = 0 - if USE_CUSTOMTREECTRL: - bmp = images.catalog['modifiedexists'].getBitmap() + for category, items in _treeList: count += 1 if filter: @@ -1531,21 +1560,31 @@ class wxPythonDemo(wx.Frame): if items: child = self.tree.AppendItem(self.root, category, image=count) self.tree.SetItemFont(child, catFont) - self.tree.SetPyData(child, count) + self.tree.SetItemPyData(child, count) if not firstChild: firstChild = child for childItem in items: - wnd = None - if USE_CUSTOMTREECTRL and DoesModifiedExist(childItem): - wnd = wx.StaticBitmap(self.tree, -1, bmp) - theDemo = self.tree.AppendItem(child, childItem, image=count, wnd=wnd) - self.tree.SetPyData(theDemo, count) + image = count + if DoesModifiedExist(childItem): + image = len(_demoPngs) + theDemo = self.tree.AppendItem(child, childItem, image=image) + self.tree.SetItemPyData(theDemo, count) self.treeMap[childItem] = theDemo + if current and (childItem, category) == current: + selectItem = theDemo + self.tree.Expand(self.root) if firstChild: self.tree.Expand(firstChild) if filter: self.tree.ExpandAll() + elif expansionState: + self.tree.SetExpansionState(expansionState) + if selectItem: + self.skipLoad = True + self.tree.SelectItem(selectItem) + self.skipLoad = False + self.tree.Thaw() self.searchItems = {} @@ -1581,30 +1620,14 @@ class wxPythonDemo(wx.Frame): self.RecreateTree() - def SetTreeModified(self, modifiedFilename, setIcon): - if not USE_CUSTOMTREECTRL: - return - self.tree.Freeze() - treeItemText = os.path.split(os.path.splitext(modifiedFilename)[0])[1] - self.LoopTreeCtrl(self.root, treeItemText, setIcon) - self.tree.CalculatePositions() - self.tree.Thaw() - - - def LoopTreeCtrl(self, parentItem, itemText, setIcon): - - child, cookie = self.tree.GetFirstChild(parentItem) - while child: - text = self.tree.GetItemText(child) - if text == itemText: - child.DeleteWindow() - if setIcon: - bmp = images.catalog['modifiedexists'].getBitmap() - child.SetWindow(wx.StaticBitmap(self.tree, -1, bmp)) - - self.LoopTreeCtrl(child, itemText, setIcon) - child, cookie = self.tree.GetNextChild(parentItem, cookie) - + def SetTreeModified(self, modified): + item = self.tree.GetSelection() + if modified: + image = len(_demoPngs) + else: + image = self.tree.GetItemPyData(item) + self.tree.SetItemImage(item, image) + def WriteText(self, text): if text[-1:] == '\n': @@ -1637,7 +1660,7 @@ class wxPythonDemo(wx.Frame): #--------------------------------------------- def OnSelChanged(self, event): - if self.dying or not self.loaded: + if self.dying or not self.loaded or self.skipLoad: return item = event.GetItem() @@ -1666,7 +1689,6 @@ class wxPythonDemo(wx.Frame): wx.LogMessage("Loading demo %s.py..." % demoName) self.demoModules = DemoModules(demoName) self.LoadDemoSource() - self.tree.Refresh() else: self.SetOverview("wxPython", mainOverview) self.codePage = None @@ -1718,7 +1740,7 @@ class wxPythonDemo(wx.Frame): self.SetOverview(self.demoModules.name + " Overview", overviewText) if self.firstTime: - # cahnge to the demo page the first time a module is run + # change to the demo page the first time a module is run self.UpdateNotebook(2) self.firstTime = False else: @@ -1862,7 +1884,7 @@ class wxPythonDemo(wx.Frame): lst.remove(sel) if loadDefault: - self.mgr.LoadPerspective(self.auiConfigurations["Default Perspective"]) + self.mgr.LoadPerspective(self.auiConfigurations[DEFAULT_PERSPECTIVE]) self.mgr.Update() @@ -1991,12 +2013,10 @@ class wxPythonDemo(wx.Frame): self.tbicon.Destroy() config = GetConfig() - config.Write('ExpansionState', str(self.expansionState)) + config.Write('ExpansionState', str(self.tree.GetExpansionState())) config.Write('AUIPerspectives', str(self.auiConfigurations)) config.Flush() - self.mgr.UnInit() - del self.mgr self.Destroy() @@ -2103,7 +2123,7 @@ else: TreeBaseClass = wx.TreeCtrl -class wxPythonTreeCtrl(ExpansionState, TreeBaseClass): +class wxPythonDemoTree(ExpansionState, TreeBaseClass): def __init__(self, parent): TreeBaseClass.__init__(self, parent, style=wx.TR_DEFAULT_STYLE| wx.TR_HAS_VARIABLE_ROW_HEIGHT) @@ -2123,6 +2143,9 @@ class wxPythonTreeCtrl(ExpansionState, TreeBaseClass): imgList = wx.ImageList(16, 16) for png in _demoPngs: imgList.Add(images.catalog[png].getBitmap()) + + # add the image for modified demos. + imgList.Add(images.catalog["custom"].getBitmap()) self.AssignImageList(imgList) diff --git a/wxPython/demo/images.py b/wxPython/demo/images.py index 7c7827f6ff..29f5061e29 100644 --- a/wxPython/demo/images.py +++ b/wxPython/demo/images.py @@ -14408,4 +14408,47 @@ catalog['saveperspective'].getData = getsaveperspectiveData catalog['saveperspective'].getImage = getsaveperspectiveImage catalog['saveperspective'].getBitmap = getsaveperspectiveBitmap +def getCustomControlData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x02tIDAT8\x8d\xa5\x93OoTe\x14\xc6\x7f\xe7}\xef\xcc\xb4\xd3\x99\xb6\x8c\ +\xb4\xa6-\xd04\x91\xc0BL\nD\xd0\x8d\xb8"nH`c\xdc\xb90!a\xc3\'0\xee\xdc`\xa2\ +\x89\x9f\xc0\x95n\xfc\x00\x86\xc0\nea4F\x8db\x90\x90\x0c0@\x85\xc20\x93\xb9s\ +\xef}\xcf9.n\xf9\x13\xe3\xc6\xf8lNr\x92\xf3\xe4\xfcN\x9e\x03\xffS\xb2\xb6y\ +\xe1\xc2\xf1c\xaf\x7f\xe0\x96$)$\x15TA\x15\x92\xed\xd4\x04j\xcf{\xa6\x81\xbc\ +4\xef\xff\xfa\xd9\xc7\xd9\xc1\x8d]\xef\x9c{wcq<)\xc9\x0b\x98\x16\xb2S\xa1\ +\xa8`:\x85\xbc\x80\xa2\x84|*\xe4\x15TU`{d\xdc\xbb\xb9\xfaV\xd6]h\x16k+-\xd4\ +\x9a\x98\x81\x19 B\x04\xca\xe4\xb8\t\xd3\xe4\xa8\x05\xcc\x1c5\xc1=Pj\xc6\xad\ +\xdfc\xca\x1a\x8d\xc0\xeaJ\x87\xee|\xfb\x19\xd7\xfd\xc7\x15\xdf\xf6+\x8e\xae\ +\xb7\x98T\xce\xe1\xe5\x0cpp\xc3\xdd\x01(\xab\xc8\xc2\x9c\x90\x01\xec\xf4\x00\ +\xb8rc\xca\x0f\x03\xe5\xa1\n\x97\xaem\xd1\x9c\x99\xe1\x8d\xf56\xaf-\t\xfb\ +\x97\x03ee\xb8\xd7xI\xb56xQ\x97\x7f\x1b\xb2\xd5\xea\xd0\xdc~\xc8\x83?\xfa\ +\xdc\x1a&\xae\xae\xed\xe3\xc8\x81\x97\xf9\xf4D\xc4\x05\xd4\xbcFu%\xbc8\xbc=V\ +\xfaE\x8b=/\xcdr\xe6\xd82_~\xf8&\x9f\x9f;\xccj\xcb\xb92P>\xf9>\xa1I\xc1\x1dS\ +\xc3\xed\x1f\x06A\xe0\xf2\xcf\x03\xae^\x7fD\xdeh\x11\xc49\xf2J\x9b\xf3\'\xf7\ +\xb2{W\x87\x9bCC\x93aV\x1b\x98[m "\x00,\xb4#_\xbc\xb7\x87^#\xf0\xe7\x18.\xde\ +\x0e\xf4\x1f9ss\x81\x03K\x8252\xb6\xc6^o\xe0\x0e\xa6d\x01!\xc6X\xa7J\xa07\ +\xdf\xe0\xda`\xc8\x8d\x07\x13\x8enty\xb2\x7f\x9eQ\xe1\xcc\x87\x82\xef\xae\ +\xdf%\x1e\xda\x8d\xaa\xed\x1c\xde\xea#\x86X\x93\xb8;\xeb\xbd&\xef\x1f\x9a\ +\x01U\xee\x149m\x9b\xe1\x9b\x9f\xb6X\\\xec\xf2\xd1\xdb=zm\x98V\x86\x99\x00J\ +\x16\xb3(\xad\xe6\xd3\r\x84\xcel\xe0\xec\x89%0\xe5\xab\x1f\xc7\x84i\xc9\xa9\ +\x83]\x86ybs\xef,fF\x16\x9d\x10\x02\x12D\xb2\xe1\xa8\x92\xed\x91\x10#h\xaa\ +\x93h\xaa\x98;\xc7W\xda5\xa7\x04\xdc#\xc3Q\xc2\xcc\x10\x81I^0\x1eM\xa2\xc4\ +\xce\xab\xa7W\xf7m\x9e\tbb\xf64Q\x86\x01\x010\xad\xc0\x15Lq\x12xBP\xca\xaa\ +\xe4\xaf\xc1/_\xff\xb7\xdf\xfd\x17\xfd\r*\xb1L*W\n\xe5H\x00\x00\x00\x00IEND\ +\xaeB`\x82' + +def getCustomControlBitmap(): + return BitmapFromImage(getCustomControlImage()) + +def getCustomControlImage(): + stream = cStringIO.StringIO(getCustomControlData()) + return ImageFromStream(stream) + +index.append('customcontrol') +catalog['customcontrol'] = ImageClass() +catalog['customcontrol'].getData = getCustomControlData +catalog['customcontrol'].getImage = getCustomControlImage +catalog['customcontrol'].getBitmap = getCustomControlBitmap