Wax demo: A simple file explorer

...in under 100 lines...

Here's a simple file explorer, with a treeview on the left to navigate directories, and a file display on the right. It's just a little demo; as such, it's far from complete: you cannot do anything with the files or directories in the listview, the only file information shown is the name, files are not reloaded, etc.

First, the code. This should work with all relatively modern versions of Wax.

from wax import *
import wx

class MainFrame(Frame):
    
    def Body(self):
        self.notebook = NoteBook(self) # [1]
        self.AddComponent(self.notebook, expand='both')
        
        self.statusbar = StatusBar(self, numpanels=3)
        self.AddComponent(self.statusbar)
        
        self.Pack()
        
        self.OpenFirstPage()
        
    def OpenFirstPage(self):
        win = self.MakeTreeWindow()
        self.notebook.AddPage(win, ":: root ::")
        
    def MakeTreeWindow(self):
        splitter = Splitter(self.notebook)
        treeview = FileTreeView(splitter) # [2]
        filewindow = self.MakeFileWindow(splitter)
        splitter.Split(treeview, filewindow, direction='v', sashposition=150, 
         minsize=100)
        
        # keep references around for later use
        splitter.treeview = treeview
        splitter.filewindow = filewindow
        
        treeview.ProcessFiles = self.ProcessFiles
        
        return splitter
        
    def ProcessFiles(self, dirs, files):
        page = self.notebook.GetCurrentPage() # [3]
        listview = page.filewindow.listview
        listview.DeleteAllItems()
        for short, long in dirs:
            listview.AppendRow(short + "/")
        for short, long in files:
            index = listview.AppendRow(short)
            image_index = listview._imagelist['file'] # [4]
            listview.SetItemImage(index, image_index, image_index)
        
    def MakeFileWindow(self, parent):
        p = Panel(parent, direction='v')
        listview = ListView(p, columns=['Filename', 'foo', 'bar', 'baz'])
        p.AddComponent(listview, expand='both')
        infopanel = Panel(p, direction='v')
        infopanel.SetSize((-1, 100))
        p.AddComponent(infopanel, expand='h')
        p.Pack()
        
        imagelist = ImageList(16, 16) # [4]
        imagelist.Add( # [5]
         wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)), 
         'folder')
        imagelist.Add(
         wx.ArtProvider_GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16,16)), 
         'file')
        listview.SetImageList(imagelist)
        listview.SetColumnWidth(0, 300)

        # keep references around for later use
        p.listview = listview
        p.infopanel = infopanel
        
        return p
    
    
if __name__ == "__main__":

    app = Application(MainFrame, title='simple file explorer', direction='v')
    app.Run()
    

[1] This is actually the first draft for an application I'm writing on, hence the use of the NoteBook, which could have been omitted otherwise. Ditto for the panel under the listview, which is currently unused.

[2] The new FileTreeView control derives from TreeView, and displays directories in a tree. On Windows, it looks up the available drive letters, and sticks those under the root item. (It helps if you have win32all installed, but it isn't strictly necessary.) On other systems, it simply attempts to get all files/directories from the root (/).

[3] This is a new method of NoteBook. It returns the current page (obviously), and raises an error if there are no pages.

[4] The Wax ImageList allows you to store names for images, then look up their indexes like it was a dictionary:

imagelist.Add(bitmap, 'folder')
imagelist.Add(bitmap, 'file')
# etc...
somecontrol.SetItemImage(item, imagelist['folder'])

[5] Once Wax supports the ArtProvider, this code can be rewritten as well, so we don't need to directly import the wx module anymore.
[2005.02.24] Wax supports it now, but I have yet to update this code.


Updates:
[2005-04-09] Bug with Splitter parent found by Ivo van der Wijk.