5 from wx
.lib 
import buttons
 
   7 from example1 
import SketchWindow
 
   9 class SketchFrame(wx
.Frame
): 
  10     def __init__(self
, parent
): 
  11         self
.title 
= "Sketch Frame" 
  12         wx
.Frame
.__init
__(self
, parent
, -1, self
.title
, 
  15         self
.sketch 
= SketchWindow(self
, -1) 
  16         wx
.EVT_MOTION(self
.sketch
, self
.OnSketchMotion
) 
  22     def createPanel(self
): 
  23         controlPanel 
= ControlPanel(self
, -1, self
.sketch
) 
  24         box 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
  25         box
.Add(controlPanel
, 0, wx
.EXPAND
) 
  26         box
.Add(self
.sketch
, 1, wx
.EXPAND
) 
  29     def initStatusBar(self
): 
  30         self
.statusbar 
= self
.CreateStatusBar() 
  31         self
.statusbar
.SetFieldsCount(3) 
  32         self
.statusbar
.SetStatusWidths([-1, -2, -3]) 
  34     def OnSketchMotion(self
, event
): 
  35         self
.statusbar
.SetStatusText("Pos: %s" % 
  36                 str(event
.GetPositionTuple()), 0) 
  37         self
.statusbar
.SetStatusText("Current Pts: %s" % 
  38                 len(self
.sketch
.curLine
), 1) 
  39         self
.statusbar
.SetStatusText("Line Count: %s" % 
  40                 len(self
.sketch
.lines
), 2) 
  45                     ("&New", "New Sketch file", self
.OnNew
), 
  46                     ("&Open", "Open sketch file", self
.OnOpen
), 
  47                     ("&Save", "Save sketch file", self
.OnSave
), 
  50                         ("&Black", "", self
.OnColor
, wx
.ITEM_RADIO
), 
  51                         ("&Red", "", self
.OnColor
, wx
.ITEM_RADIO
), 
  52                         ("&Green", "", self
.OnColor
, wx
.ITEM_RADIO
), 
  53                         ("&Blue", "", self
.OnColor
, wx
.ITEM_RADIO
), 
  54                         ("&Other...", "", self
.OnOtherColor
, wx
.ITEM_RADIO
))), 
  56                     ("About...", "Show about window", self
.OnAbout
), 
  57                     ("&Quit", "Quit", self
.OnCloseWindow
)))] 
  59     def createMenuBar(self
): 
  60         menuBar 
= wx
.MenuBar() 
  61         for eachMenuData 
in self
.menuData(): 
  62             menuLabel 
= eachMenuData
[0] 
  63             menuItems 
= eachMenuData
[1] 
  64             menuBar
.Append(self
.createMenu(menuItems
), menuLabel
) 
  65         self
.SetMenuBar(menuBar
) 
  67     def createMenu(self
, menuData
): 
  69         for eachItem 
in menuData
: 
  70             if len(eachItem
) == 2: 
  72                 subMenu 
= self
.createMenu(eachItem
[1]) 
  73                 menu
.AppendMenu(wx
.NewId(), label
, subMenu
) 
  75                 self
.createMenuItem(menu
, *eachItem
) 
  78     def createMenuItem(self
, menu
, label
, status
, handler
, kind
=wx
.ITEM_NORMAL
): 
  80             menu
.AppendSeparator() 
  82         menuItem 
= menu
.Append(-1, label
, status
, kind
) 
  83         self
.Bind(wx
.EVT_MENU
, handler
, menuItem
) 
  85     def createToolBar(self
): 
  86         toolbar 
= self
.CreateToolBar() 
  87         for each 
in self
.toolbarData(): 
  88             self
.createSimpleTool(toolbar
, *each
) 
  89         toolbar
.AddSeparator() 
  90         for each 
in self
.toolbarColorData(): 
  91             self
.createColorTool(toolbar
, each
) 
  94     def createSimpleTool(self
, toolbar
, label
, filename
, help, handler
): 
  96             toolbar
.AddSeparator() 
  98         bmp 
= wx
.Image(filename
, wx
.BITMAP_TYPE_BMP
).ConvertToBitmap() 
  99         tool 
= toolbar
.AddSimpleTool(-1, bmp
, label
, help) 
 100         self
.Bind(wx
.EVT_MENU
, handler
, tool
) 
 102     def toolbarData(self
): 
 103         return (("New", "new.bmp", "Create new sketch", self
.OnNew
), 
 105                 ("Open", "open.bmp", "Open existing sketch", self
.OnOpen
), 
 106                 ("Save", "save.bmp", "Save existing sketch", self
.OnSave
)) 
 108     def createColorTool(self
, toolbar
, color
): 
 109         bmp 
= self
.MakeBitmap(color
) 
 110         tool 
= toolbar
.AddRadioTool(-1, bmp
, shortHelp
=color
) 
 111         self
.Bind(wx
.EVT_MENU
, self
.OnColor
, tool
) 
 113     def MakeBitmap(self
, color
): 
 114         bmp 
= wx
.EmptyBitmap(16, 15) 
 117         dc
.SetBackground(wx
.Brush(color
)) 
 119         dc
.SelectObject(wx
.NullBitmap
) 
 122     def toolbarColorData(self
): 
 123         return ("Black", "Red", "Green", "Blue") 
 125     def OnNew(self
, event
): pass 
 127     def OnColor(self
, event
): 
 128         menubar 
= self
.GetMenuBar() 
 129         itemId 
= event
.GetId() 
 130         item 
= menubar
.FindItemById(itemId
) 
 132             toolbar 
= self
.GetToolBar() 
 133             item 
= toolbar
.FindById(itemId
) 
 134             color 
= item
.GetShortHelp() 
 136             color 
= item
.GetLabel() 
 137         self
.sketch
.SetColor(color
) 
 139     def OnCloseWindow(self
, event
): 
 144             data 
= self
.sketch
.GetLinesData() 
 145             f 
= open(self
.filename
, 'w') 
 146             cPickle
.dump(data
, f
) 
 152                 f 
= open(self
.filename
, 'r') 
 153                 data 
= cPickle
.load(f
) 
 155                 self
.sketch
.SetLinesData(data
) 
 156             except cPickle
.UnpicklingError
: 
 157                 wx
.MessageBox("%s is not a sketch file." % self
.filename
, 
 158                              "oops!", style
=wx
.OK|wx
.ICON_EXCLAMATION
) 
 160     wildcard 
= "Sketch files (*.sketch)|*.sketch|All files (*.*)|*.*" 
 162     def OnOpen(self
, event
): 
 163         dlg 
= wx
.FileDialog(self
, "Open sketch file...", os
.getcwd(), 
 164                            style
=wx
.OPEN
, wildcard
=self
.wildcard
) 
 165         if dlg
.ShowModal() == wx
.ID_OK
: 
 166             self
.filename 
= dlg
.GetPath() 
 168             self
.SetTitle(self
.title 
+ ' -- ' + self
.filename
) 
 171     def OnSave(self
, event
): 
 172         if not self
.filename
: 
 177     def OnSaveAs(self
, event
): 
 178         dlg 
= wx
.FileDialog(self
, "Save sketch as...", os
.getcwd(), 
 179                            style
=wx
.SAVE | wx
.OVERWRITE_PROMPT
, 
 180                            wildcard 
= self
.wildcard
) 
 181         if dlg
.ShowModal() == wx
.ID_OK
: 
 182             filename 
= dlg
.GetPath() 
 183             if not os
.path
.splitext(filename
)[1]: 
 184                 filename 
= filename 
+ '.sketch' 
 185             self
.filename 
= filename
 
 187             self
.SetTitle(self
.title 
+ ' -- ' + self
.filename
) 
 190     def OnOtherColor(self
, event
): 
 191         dlg 
= wx
.ColourDialog(self
) 
 192         dlg
.GetColourData().SetChooseFull(True) 
 193         if dlg
.ShowModal() == wx
.ID_OK
: 
 194             self
.sketch
.SetColor(dlg
.GetColourData().GetColour()) 
 197     def OnAbout(self
, event
): 
 198         dlg 
= SketchAbout(self
) 
 203 class SketchAbout(wx
.Dialog
): 
 206 <body bgcolor="#ACAA60"> 
 207 <center><table bgcolor="#455481" width="100%" cellspacing="0" 
 208 cellpadding="0" border="1"> 
 210     <td align="center"><h1>Sketch!</h1></td> 
 214 <p><b>Sketch</b> is a demonstration program for <b>wxPython In Action</b> 
 215 Chapter 7.  It is based on the SuperDoodle demo included with wxPython, 
 216 available at http://www.wxpython.org/ 
 219 <p><b>SuperDoodle</b> and <b>wxPython</b> are brought to you by 
 220 <b>Robin Dunn</b> and <b>Total Control Software</b>, Copyright 
 221 © 1997-2006.</p> 
 226     def __init__(self
, parent
): 
 227         wx
.Dialog
.__init
__(self
, parent
, -1, 'About Sketch', 
 230         html 
= wx
.html
.HtmlWindow(self
) 
 231         html
.SetPage(self
.text
) 
 232         button 
= wx
.Button(self
, wx
.ID_OK
, "Okay") 
 234         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 235         sizer
.Add(html
, 1, wx
.EXPAND|wx
.ALL
, 5) 
 236         sizer
.Add(button
, 0, wx
.ALIGN_CENTER|wx
.ALL
, 5) 
 243 class ControlPanel(wx
.Panel
): 
 250     colorList 
= ('Black', 'Yellow', 'Red', 'Green', 'Blue', 'Purple', 
 251               'Brown', 'Aquamarine', 'Forest Green', 'Light Blue', 
 252               'Goldenrod', 'Cyan', 'Orange', 'Navy', 'Dark Grey', 
 256     def __init__(self
, parent
, ID
, sketch
): 
 257         wx
.Panel
.__init
__(self
, parent
, ID
, style
=wx
.RAISED_BORDER
) 
 259         buttonSize 
= (self
.BMP_SIZE 
+ 2 * self
.BMP_BORDER
, 
 260                       self
.BMP_SIZE 
+ 2 * self
.BMP_BORDER
) 
 261         colorGrid 
= self
.createColorGrid(parent
, buttonSize
) 
 262         thicknessGrid 
= self
.createThicknessGrid(buttonSize
) 
 263         self
.layout(colorGrid
, thicknessGrid
) 
 265     def createColorGrid(self
, parent
, buttonSize
): 
 267         self
.colorButtons 
= {} 
 268         colorGrid 
= wx
.GridSizer(cols
=self
.NUM_COLS
, hgap
=2, vgap
=2) 
 269         for eachColor 
in self
.colorList
: 
 270             bmp 
= parent
.MakeBitmap(eachColor
) 
 271             b 
= buttons
.GenBitmapToggleButton(self
, -1, bmp
, size
=buttonSize
) 
 273             b
.SetUseFocusIndicator(False) 
 274             self
.Bind(wx
.EVT_BUTTON
, self
.OnSetColour
, b
) 
 276             self
.colorMap
[b
.GetId()] = eachColor
 
 277             self
.colorButtons
[eachColor
] = b
 
 278         self
.colorButtons
[self
.colorList
[0]].SetToggle(True) 
 281     def createThicknessGrid(self
, buttonSize
): 
 282         self
.thicknessIdMap 
= {} 
 283         self
.thicknessButtons 
= {} 
 284         thicknessGrid 
= wx
.GridSizer(cols
=self
.NUM_COLS
, hgap
=2, vgap
=2) 
 285         for x 
in range(1, self
.maxThickness 
+ 1): 
 286             b 
= buttons
.GenToggleButton(self
, -1, str(x
), size
=buttonSize
) 
 288             b
.SetUseFocusIndicator(False) 
 289             self
.Bind(wx
.EVT_BUTTON
, self
.OnSetThickness
, b
) 
 290             thicknessGrid
.Add(b
, 0) 
 291             self
.thicknessIdMap
[b
.GetId()] = x
 
 292             self
.thicknessButtons
[x
] = b
 
 293         self
.thicknessButtons
[1].SetToggle(True) 
 296     def layout(self
, colorGrid
, thicknessGrid
): 
 297         box 
= wx
.BoxSizer(wx
.VERTICAL
) 
 298         box
.Add(colorGrid
, 0, wx
.ALL
, self
.SPACING
) 
 299         box
.Add(thicknessGrid
, 0, wx
.ALL
, self
.SPACING
) 
 303     def OnSetColour(self
, event
): 
 304         color 
= self
.colorMap
[event
.GetId()] 
 305         if color 
!= self
.sketch
.color 
and self
.sketch
.color 
in self
.colorButtons
: 
 306             self
.colorButtons
[self
.sketch
.color
].SetToggle(False) 
 307         self
.sketch
.SetColor(color
) 
 309     def OnSetThickness(self
, event
): 
 310         thickness 
= self
.thicknessIdMap
[event
.GetId()] 
 311         if thickness 
!= self
.sketch
.thickness
: 
 312             self
.thicknessButtons
[self
.sketch
.thickness
].SetToggle(False) 
 313         self
.sketch
.SetThickness(thickness
) 
 316 class SketchApp(wx
.App
): 
 319         bmp 
= wx
.Image("splash.png").ConvertToBitmap() 
 320         wx
.SplashScreen(bmp
, wx
.SPLASH_CENTRE_ON_SCREEN | wx
.SPLASH_TIMEOUT
, 
 324         frame 
= SketchFrame(None) 
 326         self
.SetTopWindow(frame
) 
 329 if __name__ 
== '__main__': 
 330     app 
= SketchApp(False)