--- /dev/null
+import wx
+import wx.html
+import cPickle
+import os
+from wx.lib import buttons
+
+from example1 import SketchWindow
+
+class SketchFrame(wx.Frame):
+ def __init__(self, parent):
+ self.title = "Sketch Frame"
+ wx.Frame.__init__(self, parent, -1, self.title,
+ size=(800,600))
+ self.filename = ""
+ self.sketch = SketchWindow(self, -1)
+ wx.EVT_MOTION(self.sketch, self.OnSketchMotion)
+ self.initStatusBar()
+ self.createMenuBar()
+ self.createToolBar()
+ self.createPanel()
+
+ def createPanel(self):
+ controlPanel = ControlPanel(self, -1, self.sketch)
+ box = wx.BoxSizer(wx.HORIZONTAL)
+ box.Add(controlPanel, 0, wx.EXPAND)
+ box.Add(self.sketch, 1, wx.EXPAND)
+ self.SetSizer(box)
+
+ def initStatusBar(self):
+ self.statusbar = self.CreateStatusBar()
+ self.statusbar.SetFieldsCount(3)
+ self.statusbar.SetStatusWidths([-1, -2, -3])
+
+ def OnSketchMotion(self, event):
+ self.statusbar.SetStatusText("Pos: %s" %
+ str(event.GetPositionTuple()), 0)
+ self.statusbar.SetStatusText("Current Pts: %s" %
+ len(self.sketch.curLine), 1)
+ self.statusbar.SetStatusText("Line Count: %s" %
+ len(self.sketch.lines), 2)
+ event.Skip()
+
+ def menuData(self):
+ return [("&File", (
+ ("&New", "New Sketch file", self.OnNew),
+ ("&Open", "Open sketch file", self.OnOpen),
+ ("&Save", "Save sketch file", self.OnSave),
+ ("", "", ""),
+ ("&Color", (
+ ("&Black", "", self.OnColor, wx.ITEM_RADIO),
+ ("&Red", "", self.OnColor, wx.ITEM_RADIO),
+ ("&Green", "", self.OnColor, wx.ITEM_RADIO),
+ ("&Blue", "", self.OnColor, wx.ITEM_RADIO),
+ ("&Other...", "", self.OnOtherColor, wx.ITEM_RADIO))),
+ ("", "", ""),
+ ("About...", "Show about window", self.OnAbout),
+ ("&Quit", "Quit", self.OnCloseWindow)))]
+
+ def createMenuBar(self):
+ menuBar = wx.MenuBar()
+ for eachMenuData in self.menuData():
+ menuLabel = eachMenuData[0]
+ menuItems = eachMenuData[1]
+ menuBar.Append(self.createMenu(menuItems), menuLabel)
+ self.SetMenuBar(menuBar)
+
+ def createMenu(self, menuData):
+ menu = wx.Menu()
+ for eachItem in menuData:
+ if len(eachItem) == 2:
+ label = eachItem[0]
+ subMenu = self.createMenu(eachItem[1])
+ menu.AppendMenu(wx.NewId(), label, subMenu)
+ else:
+ self.createMenuItem(menu, *eachItem)
+ return menu
+
+ def createMenuItem(self, menu, label, status, handler, kind=wx.ITEM_NORMAL):
+ if not label:
+ menu.AppendSeparator()
+ return
+ menuItem = menu.Append(-1, label, status, kind)
+ self.Bind(wx.EVT_MENU, handler, menuItem)
+
+ def createToolBar(self):
+ toolbar = self.CreateToolBar()
+ for each in self.toolbarData():
+ self.createSimpleTool(toolbar, *each)
+ toolbar.AddSeparator()
+ for each in self.toolbarColorData():
+ self.createColorTool(toolbar, each)
+ toolbar.Realize()
+
+ def createSimpleTool(self, toolbar, label, filename, help, handler):
+ if not label:
+ toolbar.AddSeparator()
+ return
+ bmp = wx.Image(filename, wx.BITMAP_TYPE_BMP).ConvertToBitmap()
+ tool = toolbar.AddSimpleTool(-1, bmp, label, help)
+ self.Bind(wx.EVT_MENU, handler, tool)
+
+ def toolbarData(self):
+ return (("New", "new.bmp", "Create new sketch", self.OnNew),
+ ("", "", "", ""),
+ ("Open", "open.bmp", "Open existing sketch", self.OnOpen),
+ ("Save", "save.bmp", "Save existing sketch", self.OnSave))
+
+ def createColorTool(self, toolbar, color):
+ bmp = self.MakeBitmap(color)
+ tool = toolbar.AddRadioTool(-1, bmp, shortHelp=color)
+ self.Bind(wx.EVT_MENU, self.OnColor, tool)
+
+ def MakeBitmap(self, color):
+ bmp = wx.EmptyBitmap(16, 15)
+ dc = wx.MemoryDC()
+ dc.SelectObject(bmp)
+ dc.SetBackground(wx.Brush(color))
+ dc.Clear()
+ dc.SelectObject(wx.NullBitmap)
+ return bmp
+
+ def toolbarColorData(self):
+ return ("Black", "Red", "Green", "Blue")
+
+ def OnNew(self, event): pass
+
+ def OnColor(self, event):
+ menubar = self.GetMenuBar()
+ itemId = event.GetId()
+ item = menubar.FindItemById(itemId)
+ if not item:
+ toolbar = self.GetToolBar()
+ item = toolbar.FindById(itemId)
+ color = item.GetShortHelp()
+ else:
+ color = item.GetLabel()
+ self.sketch.SetColor(color)
+
+ def OnCloseWindow(self, event):
+ self.Destroy()
+
+ def SaveFile(self):
+ if self.filename:
+ data = self.sketch.GetLinesData()
+ f = open(self.filename, 'w')
+ cPickle.dump(data, f)
+ f.close()
+
+ def ReadFile(self):
+ if self.filename:
+ try:
+ f = open(self.filename, 'r')
+ data = cPickle.load(f)
+ f.close()
+ self.sketch.SetLinesData(data)
+ except cPickle.UnpicklingError:
+ wx.MessageBox("%s is not a sketch file." % self.filename,
+ "oops!", style=wx.OK|wx.ICON_EXCLAMATION)
+
+ wildcard = "Sketch files (*.sketch)|*.sketch|All files (*.*)|*.*"
+
+ def OnOpen(self, event):
+ dlg = wx.FileDialog(self, "Open sketch file...", os.getcwd(),
+ style=wx.OPEN, wildcard=self.wildcard)
+ if dlg.ShowModal() == wx.ID_OK:
+ self.filename = dlg.GetPath()
+ self.ReadFile()
+ self.SetTitle(self.title + ' -- ' + self.filename)
+ dlg.Destroy()
+
+ def OnSave(self, event):
+ if not self.filename:
+ self.OnSaveAs(event)
+ else:
+ self.SaveFile()
+
+ def OnSaveAs(self, event):
+ dlg = wx.FileDialog(self, "Save sketch as...", os.getcwd(),
+ style=wx.SAVE | wx.OVERWRITE_PROMPT,
+ wildcard = self.wildcard)
+ if dlg.ShowModal() == wx.ID_OK:
+ filename = dlg.GetPath()
+ if not os.path.splitext(filename)[1]:
+ filename = filename + '.sketch'
+ self.filename = filename
+ self.SaveFile()
+ self.SetTitle(self.title + ' -- ' + self.filename)
+ dlg.Destroy()
+
+ def OnOtherColor(self, event):
+ dlg = wx.ColourDialog(frame)
+ dlg.GetColourData().SetChooseFull(True)
+ if dlg.ShowModal() == wx.ID_OK:
+ self.sketch.SetColor(dlg.GetColourData().GetColour())
+ dlg.Destroy()
+
+ def OnAbout(self, event):
+ dlg = SketchAbout(self)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+class SketchAbout(wx.Dialog):
+ text = '''
+<html>
+<body bgcolor="#ACAA60">
+<center><table bgcolor="#455481" width="100%" cellspacing="0"
+cellpadding="0" border="1">
+<tr>
+ <td align="center"><h1>Sketch!</h1></td>
+</tr>
+</table>
+</center>
+<p><b>Sketch</b> is a demonstration program for <b>wxPython In Action</b>
+Chapter 7. It is based on the SuperDoodle demo included with wxPython,
+available at http://www.wxpython.org/
+</p>
+
+<p><b>SuperDoodle</b> and <b>wxPython</b> are brought to you by
+<b>Robin Dunn</b> and <b>Total Control Software</b>, Copyright
+© 1997-2006.</p>
+</body>
+</html>
+'''
+
+ def __init__(self, parent):
+ wx.Dialog.__init__(self, parent, -1, 'About Sketch',
+ size=(440, 400) )
+
+ html = wx.html.HtmlWindow(self)
+ html.SetPage(self.text)
+ button = wx.Button(self, wx.ID_OK, "Okay")
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(html, 1, wx.EXPAND|wx.ALL, 5)
+ sizer.Add(button, 0, wx.ALIGN_CENTER|wx.ALL, 5)
+
+ self.SetSizer(sizer)
+ self.Layout()
+
+
+
+class ControlPanel(wx.Panel):
+
+ BMP_SIZE = 16
+ BMP_BORDER = 3
+ NUM_COLS = 4
+ SPACING = 4
+
+ colorList = ('Black', 'Yellow', 'Red', 'Green', 'Blue', 'Purple',
+ 'Brown', 'Aquamarine', 'Forest Green', 'Light Blue',
+ 'Goldenrod', 'Cyan', 'Orange', 'Navy', 'Dark Grey',
+ 'Light Grey')
+ maxThickness = 16
+
+ def __init__(self, parent, ID, sketch):
+ wx.Panel.__init__(self, parent, ID, style=wx.RAISED_BORDER)
+ self.sketch = sketch
+ buttonSize = (self.BMP_SIZE + 2 * self.BMP_BORDER,
+ self.BMP_SIZE + 2 * self.BMP_BORDER)
+ colorGrid = self.createColorGrid(parent, buttonSize)
+ thicknessGrid = self.createThicknessGrid(buttonSize)
+ self.layout(colorGrid, thicknessGrid)
+
+ def createColorGrid(self, parent, buttonSize):
+ self.colorMap = {}
+ self.colorButtons = {}
+ colorGrid = wx.GridSizer(cols=self.NUM_COLS, hgap=2, vgap=2)
+ for eachColor in self.colorList:
+ bmp = parent.MakeBitmap(eachColor)
+ b = buttons.GenBitmapToggleButton(self, -1, bmp, size=buttonSize)
+ b.SetBezelWidth(1)
+ b.SetUseFocusIndicator(False)
+ self.Bind(wx.EVT_BUTTON, self.OnSetColour, b)
+ colorGrid.Add(b, 0)
+ self.colorMap[b.GetId()] = eachColor
+ self.colorButtons[eachColor] = b
+ self.colorButtons[self.colorList[0]].SetToggle(True)
+ return colorGrid
+
+ def createThicknessGrid(self, buttonSize):
+ self.thicknessIdMap = {}
+ self.thicknessButtons = {}
+ thicknessGrid = wx.GridSizer(cols=self.NUM_COLS, hgap=2, vgap=2)
+ for x in range(1, self.maxThickness + 1):
+ b = buttons.GenToggleButton(self, -1, str(x), size=buttonSize)
+ b.SetBezelWidth(1)
+ b.SetUseFocusIndicator(False)
+ self.Bind(wx.EVT_BUTTON, self.OnSetThickness, b)
+ thicknessGrid.Add(b, 0)
+ self.thicknessIdMap[b.GetId()] = x
+ self.thicknessButtons[x] = b
+ self.thicknessButtons[1].SetToggle(True)
+ return thicknessGrid
+
+ def layout(self, colorGrid, thicknessGrid):
+ box = wx.BoxSizer(wx.VERTICAL)
+ box.Add(colorGrid, 0, wx.ALL, self.SPACING)
+ box.Add(thicknessGrid, 0, wx.ALL, self.SPACING)
+ self.SetSizer(box)
+ box.Fit(self)
+
+ def OnSetColour(self, event):
+ color = self.colorMap[event.GetId()]
+ if color != self.sketch.color:
+ self.colorButtons[self.sketch.color].SetToggle(False)
+ self.sketch.SetColor(color)
+
+ def OnSetThickness(self, event):
+ thickness = self.thicknessIdMap[event.GetId()]
+ if thickness != self.sketch.thickness:
+ self.thicknessButtons[self.sketch.thickness].SetToggle(False)
+ self.sketch.SetThickness(thickness)
+
+
+class SketchApp(wx.App):
+
+ def OnInit(self):
+ bmp = wx.Image("splash.png").ConvertToBitmap()
+ wx.SplashScreen(bmp, wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT,
+ 1000, None, -1)
+ wx.Yield()
+
+ frame = SketchFrame(None)
+ frame.Show(True)
+ self.SetTopWindow(frame)
+ return True
+
+if __name__ == '__main__':
+ app = SketchApp(False)
+ app.MainLoop()