--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import cStringIO
+import wx
+
+#----------------------------------------------------------------------
+
+ArtClients = [ "wx.ART_TOOLBAR",
+ "wx.ART_MENU",
+ "wx.ART_FRAME_ICON",
+ "wx.ART_CMN_DIALOG",
+ "wx.ART_HELP_BROWSER",
+ "wx.ART_MESSAGE_BOX",
+ "wx.ART_OTHER",
+ ]
+
+ArtIDs = [ "wx.ART_ADD_BOOKMARK",
+ "wx.ART_DEL_BOOKMARK",
+ "wx.ART_HELP_SIDE_PANEL",
+ "wx.ART_HELP_SETTINGS",
+ "wx.ART_HELP_BOOK",
+ "wx.ART_HELP_FOLDER",
+ "wx.ART_HELP_PAGE",
+ "wx.ART_GO_BACK",
+ "wx.ART_GO_FORWARD",
+ "wx.ART_GO_UP",
+ "wx.ART_GO_DOWN",
+ "wx.ART_GO_TO_PARENT",
+ "wx.ART_GO_HOME",
+ "wx.ART_FILE_OPEN",
+ "wx.ART_PRINT",
+ "wx.ART_HELP",
+ "wx.ART_TIP",
+ "wx.ART_REPORT_VIEW",
+ "wx.ART_LIST_VIEW",
+ "wx.ART_NEW_DIR",
+ "wx.ART_FOLDER",
+ "wx.ART_GO_DIR_UP",
+ "wx.ART_EXECUTABLE_FILE",
+ "wx.ART_NORMAL_FILE",
+ "wx.ART_TICK_MARK",
+ "wx.ART_CROSS_MARK",
+ "wx.ART_ERROR",
+ "wx.ART_QUESTION",
+ "wx.ART_WARNING",
+ "wx.ART_INFORMATION",
+ ]
+
+
+#----------------------------------------------------------------------
+
+class MyArtProvider(wx.ArtProvider):
+ def __init__(self, log):
+ wx.ArtProvider.__init__(self)
+ self.log = log
+
+ def CreateBitmap(self, artid, client, size):
+ # You can do anything here you want, such as using the same
+ # image for any size, any client, etc., or using specific
+ # images for specific sizes, whatever...
+
+ # See end of file for the image data
+
+ bmp = wx.NullBitmap
+ # use this one for all 48x48 images
+ if size.width == 48:
+ bmp = makeBitmap(smile48_png)
+
+ # but be more specific for these
+ elif size.width == 16 and artid == wx.ART_ADD_BOOKMARK:
+ bmp = makeBitmap(smile16_png)
+ elif size.width == 32 and artid == wx.ART_ADD_BOOKMARK:
+ bmp = makeBitmap(smile32_png)
+
+ # and just ignore the size for these
+ elif artid == wx.ART_GO_BACK:
+ bmp = makeBitmap(left_png)
+ elif artid == wx.ART_GO_FORWARD:
+ bmp = makeBitmap(right_png)
+ elif artid == wx.ART_GO_UP:
+ bmp = makeBitmap(up_png)
+ elif artid == wx.ART_GO_DOWN:
+ bmp = makeBitmap(down_png)
+ elif artid == wx.ART_GO_TO_PARENT:
+ bmp = makeBitmap(back_png)
+
+ elif artid == wx.ART_CROSS_MARK:
+ bmp = makeBitmap(cross_png)
+ elif artid == wx.ART_TICK_MARK:
+ bmp = makeBitmap(tick_png)
+
+ if bmp.Ok():
+ self.log.write("MyArtProvider: providing %s:%s at %s\n" %(artid, client, size))
+ return bmp
+
+
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ title = wx.StaticText(self, -1, "ArtProvider")
+ title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
+ sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
+ sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+
+ fgs = wx.FlexGridSizer(0, 3, 10, 10)
+
+ combo = wx.ComboBox(self, -1, "", choices = ArtClients,
+ style = wx.CB_DROPDOWN|wx.CB_READONLY)
+ fgs.Add(combo, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ self.Bind(wx.EVT_COMBOBOX, self.OnSelectClient, combo)
+ combo.Select(0)
+
+ combo = wx.ComboBox(self, -1, "", choices = ArtIDs,
+ style = wx.CB_DROPDOWN|wx.CB_READONLY)
+ fgs.Add(combo, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ self.Bind(wx.EVT_COMBOBOX, self.OnSelectID, combo)
+ combo.Select(0)
+
+ cb = wx.CheckBox(self, -1, "Use custom provider")
+ fgs.Add(cb, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ self.Bind(wx.EVT_CHECKBOX, self.OnUseCustom, cb)
+
+ fgs.Add((10, 10), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ fgs.Add((10, 10), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ fgs.Add((10, 10), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ box = wx.BoxSizer(wx.VERTICAL)
+ bmp = wx.EmptyBitmap(16,16)
+ self.bmp16 = wx.StaticBitmap(self, -1, bmp)
+ box.Add(self.bmp16, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ text = wx.StaticText(self, -1, "16x16")
+ box.Add(text, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ fgs.Add(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ box = wx.BoxSizer(wx.VERTICAL)
+ bmp = wx.EmptyBitmap(32,32)
+ self.bmp32 = wx.StaticBitmap(self, -1, bmp)
+ box.Add(self.bmp32, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ text = wx.StaticText(self, -1, "32x32")
+ box.Add(text, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ fgs.Add(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ box = wx.BoxSizer(wx.VERTICAL)
+ bmp = wx.EmptyBitmap(48,48)
+ self.bmp48 = wx.StaticBitmap(self, -1, bmp)
+ box.Add(self.bmp48, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ text = wx.StaticText(self, -1, "48x48")
+ box.Add(text, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ fgs.AddSizer(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ sizer.Add(fgs, 0, wx.ALL, 5)
+ self.SetSizer(sizer)
+
+ self.client = eval(ArtClients[0])
+ self.artid = eval(ArtIDs[0])
+ self.getArt()
+
+
+ def OnSelectClient(self, evt):
+ self.log.write("OnSelectClient\n")
+ self.client = eval(evt.GetString())
+ self.getArt()
+
+
+ def OnSelectID(self, evt):
+ self.log.write("OnSelectID\n")
+ self.artid = eval(evt.GetString())
+ self.getArt()
+
+
+ def OnUseCustom(self, evt):
+ if evt.IsChecked():
+ self.log.write("Images will now be provided by MyArtProvider\n")
+ wx.ArtProvider_PushProvider( MyArtProvider(self.log) )
+ else:
+ self.log.write("MyArtProvider deactivated\n")
+ wx.ArtProvider_PopProvider()
+ self.getArt()
+
+
+ def getArt(self):
+ self.log.write("Getting art for %s:%s\n" % (self.client, self.artid))
+
+ bmp = wx.ArtProvider_GetBitmap(self.artid, self.client, (16,16))
+
+ if not bmp.Ok():
+ bmp = wxEmptyBitmap(16,16)
+
+ self.bmp16.SetBitmap(bmp)
+
+ bmp = wx.ArtProvider_GetBitmap(self.artid, self.client, (32,32))
+
+ if not bmp.Ok():
+ bmp = wxEmptyBitmap(32,32)
+
+ self.bmp32.SetBitmap(bmp)
+
+ bmp = wx.ArtProvider_GetBitmap(self.artid, self.client, (48,48))
+
+ if not bmp.Ok():
+ bmp = wxEmptyBitmap(48,48)
+
+ self.bmp48.SetBitmap(bmp)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """<html><body>
+<h2><center>wxArtProvider</center></h2>
+
+wxArtProvider class can be used to customize the look of wxWindows
+applications. When wxWindows internal classes need to display an icon
+or a bitmap (e.g. in the standard file dialog), it does not use a
+hard-coded resource but asks wxArtProvider for it instead. This way
+the users can plug in their own wxArtProvider class and easily replace
+standard art with his/her own version. It is easy thing to do: all
+that is needed is to derive a class from wxArtProvider, override it's
+CreateBitmap method and register the provider with
+wxArtProvider_PushProvider.
+<p>
+
+This class can also be used to get the platform native icons as
+provided by wxArtProvider_GetBitmap or wxArtProvider_GetIcon methods.
+
+</body></html>
+"""
+
+
+#----------------------------------------------------------------------
+# Image data
+
+
+def makeBitmap(data):
+ stream = cStringIO.StringIO(data)
+ return wx.BitmapFromImage(wx.ImageFromStream(stream))
+
+
+back_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07YID\
+ATx\x9c\xa5\x97Ml\x9dG\x15\x86\x9fsf\xbe\xef^\xfb:\xaeS\xd7\xa9\x1d;!IK)\xfd\
+A\x05\x95BQ\xc5\xdf\x02\xb1(\x12\x0b\x10\x8b\x8a\x05]Vl\xd8\xb2`\xcb\x92\xee\
+Q\x85\xd8U\xaa\xba\x03\tD+@j\x91J\x11\x8aT\xd14\xfd\xa7\xf9q\x9a\xc6\x8e\xe3\
+\xd8\xb1\xefwg\xcea1s\xaf\x13;\xaa*1\xd2h4su\xe7=\xe7\xcc{\xdes>\x99\x9b\x9b\
+\x03\xe0\xf9\x17\xff\xe2[\xb6B;u\'\x86`\x19\x9299Ar\xc8\x19\xb29\xd9 \xe5\
+\xb2O\x069\x97\xb3\x03{\x1b\xff\xa7\x9c\xa5zf\xe6,\x1e\xda\xe0\xe1\xe5U\xe6g\
+\xb6\x91\xb9\xb99~\xf7\xc2i\x1f\xcc-3\xdd\x8f\xe5r\x83Q\x86\x94\xa0K\x05p\
+\xbc\x1f\xe5\xba\xff?\xcf{\xb1\xe3;_x\x17\xf9\xd3\xcb\xaf\xbb\xce>\xc2\xcctd\
+\x94*x\xca\\\xdb\xd8\xe2Fg\x98\x0b\x96\x95l\xc2\xc8 \xbb\xe0Y\xc8&\xd5+!eadB\
+JBv\xa9`R\xef\x12FYH\x19\xcc\x84.\xcb\xc4\xb0\xa5\xd9k\xc4-[f\xb1_\xc0\xdda\
+\xed\xca*k\xabg\xd9\xda\xfc\x84\xeb;\x01\x97\x1eh\x03\x12A"N\x03D\\"\xe6\x81\
+LK\xf6H\xb6H\xf6@\xb6@\xf2H\xb2\xc0(+\xd9#\xbb]$y\x00\x14\xd5\x00\x08\x00\
+\x17\xaf\xcd\x12\t\x83b\x9d\xc3\xd6\xf5\xab|\xf4\xf6+|ti\xc8\xb9+\rW\xae\xb7\
+\x88*\x1a\x14\x15E\x82"Z\xa7(\xaa\rh\x00\tH]\x11\x05Q\\\x14<\xe0\x12HV"\xe8\
+\x08\xfd6\xd3k\x03\xee\xc2(\t\xd1\xc6\x841\xf8\xf8\xc2;\\^\x1f\xf2\xda\xd9\
+\x86\xc1\xf4!V\x16gh{-\xe6J\x08\x11\t\rA\x03\x1a"\xaa\r\x12\x02\xaa\x81 \x11\
+\x82\xa2\xd5\x10\x11-\x06\x11\xe8\xb7\xca(\x0b\xef\xad\n\xeb\x9b\x86Y\xa6UgD\
+\x03@4wF\x19,\x8f\xb8\xb1u\x85w/6\xf4z\x03N\x1e\x9bc\xa7\x13.\xad\x8d\xd8\
+\xed\x04QG\xd5\x11\x8d\x88\n\xa8 \x02\xaa\x02\x9a\x01\x07\x11\x10\xc1\xa5\
+\x84\xd8\x81\xa9>\x9cZR\xbev\xbf\xf3\xea\x1b\xc6ng\xb4\xd1\xd8\xee"\xee\x82\
+\x9a\x15V\xa6,\x98\x05\xae\xef\xf69<7 [\xe0\xfc\xe5!\xdb\xbb`D\x9c\x80\x110\
+\x1a2\x01\xf32\x93+)+\xc9\xea\xbb[ \xe5\xc8(\x17\x0e\\\xdbV\xfe\xf3a\xa6\x1b\
+\x19\xcb\x0bNTc\xaa5\xc6#\x9a\x97Ts\x03B\x8b\xc6\xcc\xf4T\x8f\xcd\x1b\x86y@\
+\xb4A5V\xcf[\xd0\x88H\x99\xd40#\x91\xe1\xf6\xc7|\xf0\xfa\xb3\xe44\xac$\x13\
+\x16\x1f|\x9a\xc3+\x8fc9s\xe1\n\xdc5\x0b\x17.\x1bM(\x112\x87\x98\xcdk\x8a\
+\x00\x94\xb7\r!\xe2#\x10\x95\xcf\x04\x8e\x04\xba\xe1&\xabg\x9e\'w[\x13\xef\
+\xe6V\x9e@W\x1eC\xc4p\x87\x18 \x06\xa3\x89\x8a{\xc9\xbahUt0\n\x80\xc6B\xb2\
+\x00\xaa\xf6\x99\xc0]\xea\xbe\xa6\xd7x\x08\x86\x88\xa1bD\x15\x82B\x10\xa7\t\
+\x19K\x1d9Iy\x82\x94\xc0\x11\xa0\xe4\xbajD\x15D\xed3\x82G\x1ce\xff\x10\xbc\
+\x82\x1bA\xa5\xcc`4\x01R\xee0\x13\xa2Y\xc9\x02\x1c\x8c0y\x82\x9a\xce\x07\xc0\
+\xddAt?x\xb8\xbd\x01\xe2\x15\xdcPQT\xa0Q\xa7\t`y\x88\xe5q\x16T\xfd\xf7q\x04B\
+ \x84\xe6\x00x\xeevx\xff\xb5\xdf\xb0~\xfe\xd5\x03\xe0\xb73@e\x0c\xee\x04\xf5\
+\xca\x01\xa7\t\x86\xa5\x0e\xcf\x1dj\xe6E\xbbS5@cU\xb8\x83\xe0\xef\xfc\xe3\
+\xd7|\xf8\xfa\xb3\x9cy\xf9\x17\\=\xf7\xea-\xe0\x8a\xdd\xc6\x00\xaf\xe0F\x08N\
+T\'(\xc4h\xb8\x8d\xb0\xdc\xa1\xe6%\x02E\x8e\x03\xa2-\x12""\xe1\x00\xf8\x857~\
+\x8f{fg\xe3\x03\xce\xbc\xf4s\xd6\xcf\xfd\xbd\x80\x8b\xa1d\x04?`@P+\xde\xab\
+\x13\x024\xc1\xe97\x8e\xe7\x0e\xcfCt\\zG&\xe4ZdT\x02\xaa\xb7\x07\x1f\x8f\x9d\
+\x8d\xf79\xfb\xd23\\;\xf7r\x01\x17\xdf\x1f\x00d\x1c\xfa\xeayPh\x1b\xa7\x89\
+\x0e\xdea\xd6\xa1\xee^\x940A\xf6H\x13c\xcd\xfd\xc2\xf6\x94\x86\xdc\xb1\xf4(s\
+\xcb\x8f\xdfry;}\x84\x95G\x9eA0`\x84\xe5m\xdco}\x86\x10t\xe2y\xac\xde7\x01z\
+\x11\xdc\n\x07&: \x02x\xa0m\xa4V;@\x84\xde\xccQ\x16\x1fx\x8a\xd4\xedp\xf5\
+\xfc+\x93\xcb\xd3p\x83\xde\xf4<\xf3\x9f\xfb&*\xc6\xf6\xe5\xd3\xe4\xd1\x8d\
+\xc9\xef\xb1\x99f\xee\xae{\n\xb8:M\xa8\x86D\xa1\x89`\xb9\xc3\xb2U\x1d\xc8\
+\xa0\x02f\x01Cji\x15\x10&l\xef\xcd\x9e@4\xe2\x96\x80r\xc1\xbb\xaf\xfc\x8a\
+\xb4\xb3J\x7fz\x9e\xff\x9e\xfe\xed-\xde7\xfdY\x06\xb3\x0b\x05<\x8e\xa3P\xc0\
+\xdb\x08X5 \xd7,P\x11\xdcJ\x9dV\t\x88\x08.LR\xed\xd0\xdd_e\xfa\xf0}l\xaf\xbd\
+9\x01\xd9\xdd\xfc\x88\xb7\xfe\xfaKD\xc3\xc4\xb0\xf1\xb8\xfb\xc47\x98=\xbcD\
+\x13\xbd\x86_*\t\xa1\x89\xe0\x96\xf0\x9c\xf6t\xa04\x94\x01#\x82j\x997\xe5y38\
+\xca\xd1\x87~\xc6~\xb9\x05?\x00\xde\xf4\x0e\xf1\xc5\xc7~J\xaf\r\x05<\xde\x04\
+\xde\x08m\x03\xee\t\xcb\xc3\x92\x86\xa3\xda4\x8er S\xbb\x9b}"\xa3b,\xdd\xffc\
+\x16N}\x1f\r\xed\x01\xc6\xef\xbd\xfd\x14\xf7=\xfa\x14\xcb\xa7\x1e\x9d\x80\
+\xc7\xeau\x08B\x1b\xa1\x8d\x8a\xdb\x10\xb7\xaeHqJ\x85\x03\x9e\x15s\x10\n\x07\
+\xbc\xa8\xf9$\xcf{3\x0b|\xe9\xc9\xe7X\xff\xf0\xcf\x9c;\xfd\x1c\x1b\x97N\x93j\
+\xf5\x8b\xcd\x14\xf3+_\xe1\x81\xaf?\xcd=\x0f}\x8f\xb6mn\x01\x8f*5\xfcJ\xbf\
+\xe7\x95\x037e\x81\nXR\x92\x95~\xaf\xdf+\x06LD\xa6V\xb5\xb6?\xe0\xd8\x03?d\
+\xf9\xde\xef\xb2}\xf5,\xdb\xebo\xa3df\xef<\xce\x91\x95\x87\x99\x1e\xcc\x1c\
+\xf0\xbc\t\xc2\xa1\x81\x12\x832\xd5S\xdahX\x1e\xe1y\xb8\x97\x05"\xd0\x8d"\
+\xd9\x84\x8dm\xe1\xd4Q\xe5\xd2zfk;\xdfTR\xf7\xb4\xbd\x99\x1a0=\xf82K\xc7\x1f\
+\xd9K\xb51\xe1\xf6\x81\xdfqH9\xbe\xd8pi-\xd36B\xd3\x08\xe27G \x15ju)\x90\x0c\
+.\xac\t\'\x16\x9d\'\x1e\x84s\x9f@7\xa2\xd6sAE\t\xea\x84 {\xda^E&\xdc\xcc\xf6\
+\x1a\xf6~O8~w\x83 \xacof\x8e-\x08MTR\xea\xb0<\xac\x1c\xc8P\xaaw\xc0\xdd\x19v\
+\xc6kof\x8e\x1c\x866Z\x05\xda\xabj\xb7\x14\x96O\x01\x8f\r\x88\x08\xabW2[\xbb\
+#\xa6{pbQ\xf9\xdb?/\xb2\xb9\xb9\x8d[":\xb5\x1f\x00\xdc\x85A\xdf\x18\xa5\x8c\
+\xbb\xb1\xb6Q:\xd8\x18\xac\x94Q-k[C\x1d\xa3\xd3\x8b\x8eEh\xa3 ^"iU\xc4\xd4\
+\x95&8m\x14\x16\xef\x14\x96\xe6\x95l\xc6\x0b\x7f\xf8\x17f\x1d\xb8\x11\x8f\
+\xcd]\xe5\xcc\xea\x11\xccJ#\xa9!0\x88\xd0\x84L\x1b\x85\x18tR\xc3\x83\x16\x1e\
+\xc4\x89!U\xdf\xe3\xb8\xd7s\x9a e\x8dB\xaf1\x1a\x15\xa2\n\xbbC\xe1\xf4[[\xbc\
+\xf8\xc7\x7f\xf3\xde\x07\xab\xb8\x97\xce(\x9e\xbck\x8d\x85\x99M\xce_\xbdc\
+\x12\x85\x11\xb1\xf6\xed%2f`\xa9#\xe5\x8e\x9c\x129\x15\x02y\x1eb\xb5\xa8\x94\
+\x0e\xa7+\nge?>/kWz\x00\xebp7<\x0f9yr\x19\xfd\xc9\x8f\x9e\x94o}\xfe=\xee]\
+\xf8\x04%\x17A\x1aW\xc7}_\xb5\xd9J+\xfd\xa9\xc3\r\xb7\\V\xb7\xc9\xea\x9e\x8b\
+b\xba!\x18G\x97\xe6\xf9\xc1\xb7\x97\xf9\x1f\x92tznH\x8fy\x14\x00\x00\x00\x00\
+IEND\xaeB`\x82'
+
+down_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x042ID\
+ATx\x9c\xa5\xd5Ko\x1bU\x14\xc0\xf1\xff\x8c\xe7\xe1g\xe2\xa6\x84\xa8\xa8\x82\
+\xd0\x88E\xabJ\x08\t\x8a*\xb1@\x02v\xec@l`\x87\xf8\x1e\x91\xf8\x06 \x90\xd8\
+\xb3\xe2S\xb0aS\x1ej\x8bhIe\xd2\xa8i\xa8\x13\xc7\x8f\xda\xe3\x99\xb93\xf7\
+\xcee1\x1e\xc7\xae\xed\xc4c\x16Wc\xddk\xfbw\xce\xf1\xf1\xb9\xc6\x0fw\xb5\xfe\
+h\x1b\x02\t\x91\x02\xa1 N&^+\x88\x12\x08%\x08\x99\xeeE\xa3\xf3l\t\x05~\x9c>\
+\xc3\xd1^(\'>7:\x7fqOH0\x13\r\x00\xa6\x91\xae\x82\x01F\xba5~\xca\x04\x94\x86\
+db\xa9\xd1\x92I\x1a|\x16t<\x91\x84\x18%\x15\xc4g\x81\x87Y\xa2\x12\x94R\x98J\
+\x8f\x0e\'\xb2\x11\nNzC\xfex\xb0\x8f\x17\xeb\xf4|"\xfb\xec\xfdB\x82\x17\x9fe\
+\xfcb\x05\xc6\x99gU\x12\n!\x13\xc2\x11\x8e\x14X*\x99\xc5#\x05a\x9c\xf0\xfdw\
+\xdf\xb0qe\x9bO>\xfb\x9c\xcb\x9b\x9b+\xe3\xa1L\xe8{\x01a\xa40\xdc**Iq\xad",\
+\xa5g\xf1HA\xb1R\xe3\xda\xcdw\xf8\xe5\xa7o9\xd8\xfb\x93\xdb\x1f\x7f\xc1\xdb\
+\xb7\xde\xc5)\x96s\xe1\xfda\xc0\xc0\x1b\x12)0\xdd\x1aI\xa2\xc78\xb1O\xe1\xc3\
+\xafvw\xafT\xa7q\x7f\xf4%\xf5\x8d-\xee\xfcz\x87\xb0w\xc2\xc1\xdf\xf7y\xf8\
+\xcf!Vu\x13wm\x8381\xce\xc5\xbd0\xe6\xb4\xd3a0\xf0\x90X\x18v\x19,w\nG\n\n\
+\x1f|\xb9\xbb\xbbU\x99\xc5#\tv\xa9\xc2\xa3\xc3\x16\x9d\xe6\x13\xb0\\\x82a\
+\x9f\xc7\xfb\rN\xfa!v\xf5\x12\x96[\x99\xc1\x07\xa1\xa4\xd5\xeepzz\x8a\x88\
+\x15\xda.\xa5\xb8S\xc2\x88\xa7\xf1\xb4\x07\xf4|\\(\x90\xda\xe0\xad\xdb\xef\
+\xf3\xf8\xaf\xdfP\x1a\x0c\xb7\x86L4O\x1e\xfc\xceq\xf3\x19Wo\xdc\xe2\xea\xceu\
+\x12\xd3!\x94\x9aV\xe79\'\xad\x14\xc6.\x81S\x1e\xe1e\x1cb\x84\x12S\xb8\x96\
+\x11\x96L\xe6\xe3Y\xc3m_\xbb\xc6\xfa\xab7\xe86\x0f\xc1.aXEp\xca\x88(f\xff\
+\xc1]\x8e\xdb]6^\xd9\xc1\xf3C\xfaC\x1f]pa\x84fx\xc5\xd2\x84A8\x83#E:\x07\x16\
+\xe1\x91\x02\xa3\xe0\xb2\xf3\xe6{`\x97\xc78N\x05\xc3)\x83]b\xe8y<=h\xd0\xeb\
+\x0f\xe6\xe2U\x1b,bT0\x98\xc1Q\x023N\x16\xe3Y\xb7o\xbfq\x9d\xf2KW_\xc0\'\xa0\
+\xe2\xfa\xec\xde\x08\xaf8\x90\x88!z\x0e\x8e\x8c\xd2At\xd1\x90q+kl\xbe~s>^\
+\xaa/\xc4\xab\x0eTL\x89\xef\xf5\xe7\xe2Z\nL\x99\x9c\x8fg\xdd\xfd\xca\xceu\n\
+\xe5z.|\xa3\x08\x81?D\x8a`.N\xec\xa7\x01,3\xe1\xca\xeb\x97\xa9\xbd\xfcZ.\xbc\
+h&\xf4\x9f\xf7\x16\xe2H1}\x17\x9c7\xe1\xe2\xc4\xe4\xd2\x95m\x0c\xa7\xb2\x14^\
+s@\x84>\xde\xa0\xbf\x10GE\x98?~z\xc9Xv\xb6;k\x9b\xd8\xeb[K\xe1eKs\xda\xe9\
+\xa2\xe3p!\xae\xa5\xc0\x84\xe5/\x16Up(\xd6\xb7.\xc4\xab\x0eh\x15\xd1>m\x9f\
+\x8b\x93\x05\x90\xe7J-\x94\xd60\xdc\xea\xb9x\xd5\x86V\xbbG\x14z\xe7\xe2\xc8\
+\x08\x0b\x96\xc7C\t\xca\xb01\x9c\n\xdar\x17\xe2\x16\x8a\xa3\xe6\xf1\x858jT\
+\x81e\xf1\xecL\x17\xec\x85x\xcd\x81^\xdf\xa3\xd7\xe9\\\x88\x9f\xf5@\x0e\\)\
+\x85\x11\x0b\\S\xcd\xc5\x8b\x05\xcd\xc1\xd3&*\n.\xc4\x89\xfcQ\x05r\xe0HA\xa2\
+\x04:\xf2g\xf0\x8a\rB\x08\x0e\x8f\x8e\x96\xc2\xc7M\x98\x07\xcf\xee\xf3\xa1\
+\xd7\xc7BN\xe15\x07\xf6\x8fZ\x04\x83\xeeR\xf88\x80\xbc8R\x10\x0e\x07xC\x7f\n\
+\'\x914\xf6\x1f/\x8dO\xf5@\x1e<\xbbX\x9a\xc7-\xdc\x82\x1e\xff\x14\xadn\x9f\
+\xe3\xe6\xbfK\xe3\xe3\n\xac\x82#\x05\xedv\x0b\xdf\x0f\xa8:\xb0\xeeh\xee\xed\
+\x1d\xa0\xa2pi\xfc\xeco\xb8\x02\x8e\x12D\x81O\xe3\xe91\x1bEx>\x0c\xd9k4r\xe1\
+\xe3\n\xac\x82gCf\xefQ\x83@D\xdcm<c\xd0\xeb\xe6\xc2\xb5\x14\xe9$\\\x15\'\xf6\
+\xe9u\x04?\xdf;\xe0\xfe\xc3G\xb9q"\x1f\xa3^\xafc}\xdd\xd5\xab\xe0Y\xb7\x1bIL\
+\x12\x05\xb9q&+\xb0*\xae\xc7@~|\xfc7\xfc?\xf8*e\x9f<\xfb\x0fT{\xea\xc3\x87j\
+\xf9\x90\x00\x00\x00\x00IEND\xaeB`\x82'
+
+left_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\
+\x03IDATx\x9c\xc5\xd7Mo\x1bE\x18\xc0\xf1\xff\xbe\xc4^\x9b\x86V\x81\x86\xf2\
+\x8e\x8aJ+\x90(jE\x85\x84\xd4\x03\x12G$\xee\\\xb8\xf2-\xfa9\x10_\x82\x0b\x07\
+N\xbd \xd4"\xd1&MQ\xd44iZ7N\xea$vl\xafwwv\x9e\x99\xe1\xe0\xf7\xc4i\xeb\xf4%\
+\x07k\xf6\x19\xef\xccoV\xf3\xb2\xcfz\xbf.8w\xba\x04\xb9\x05cA[0\x0e\xc4\x808\
+\x90^\xbd\xb2\xa0\xcd\xf0\x1eq\xddX\xdb\xee=\xa9t\xe3\xbc\xf7\xbf2\xbd\xd8t\
+\xafS\xe9\x96\xfd87\x90\t\x84\xa7Kpq~X\xd9\xbfa4N\xfa\x8d\xfb\xa5\x1d\xe9L \
+\xd6P\x0c\xc0\xb9\xee\xe05\xe0\x01\xb6\x17\xe7\xbd\x81j;\x8e\x1bc\xf0G;;*\
+\xde\xefP\x19\xc8\xccx\x9c\xe8n\x9d\xea\xd5\x8d\xe2\x88\xc27\xf6\xf8pgr|m\
+\x8f\x0fG\'\xf8\xc6\xbd>\x1ck\x08l>\xc0\x11\x85/\xaf\x18\xef?\\\x148\xe6J\
+\x80\xd5\x03\x1cQ\x84\xe2^\r\xde\xc9-\x99\xf1\xf1\x80\x13\x0581\xe3\xd1\x8cs\
+$\x8b\x07\xb8\x93\x9cP\xec\xcb\xc3\x13mi\xa5B\xa2\x1d\xda+R\x0c!\nav\x06D\
+\x84\xb8\xbd7\x86#\x8a\xd0\xd8\x17\xc33q4:9{\x1dE\xac,\xe2\x15\xa0P&\x1a\xc1\
+g|\xcbn\xb3\x89\xcd\xb31\x1c\xa3\x08\x95=\x1a\xdeN\x85\x9dV\x87\x9d\xbd\x0e\
+\x89v\x98\xa0\x887S>\x80\x97Bh\xc5)\x9d\xb8u\x00GrB=\x05\x9ej\xc7n3\xa6\xba]\
+\xa7\xdeN\xc9\xc4\x83\x99\x12\x14\xca\x87\xe2\x9e3\xec\xd6\xeb\x13q\xd7\x9f\
+\x82g\xe1\xad4\xa7\xb2\xb5Mu\xb3F\xb3\xddA\xc22^\xa1\xfcL\xbc\x18:6\xb7\x9b\
+\xe4ig"\x8eN\x08\xb5\x9d\x8cg\xda\xb2\xb1\xbd\xc7ze\x83\xcd\xcd-\xd2\\\xe3\
+\x82\x08J\xa7zx\xf9\xa9x\x14\x82R\x8a\xc6\xee\xee\xa1\xf8`\x1b\x8e\xe2\xb5V\
+\xc6\xea\xc3\xc7\xdc_{@\xa3^G[o\x08M\x81\x87\x9ee\xfd\xc9\x0eZ\xa5\x87\xe2\
+\x98\xde\x1aP\xe2X\xab\xd4X\\^\xe1\xd1\xfa\x1aI\x92\xe0\xc2h\x1c\x9a\x02\x8f\
+B\xd8\xad\xb7i\xee5\x9e\x8a;Q\xdd)\x88Sa\xe9\xde*k+\xcbd*?\x08M\x89G\x01\xa4\
+i\x82\xd3\xd9SqD\xe1\xfd\xf2\xa7s\xa1\xdf\x9d\x82\xda^\xcc\xfd\x07\x15\xaa\
+\x9b\x9b$\xa9\xc2\x06\xc5\xa9\xf1\xfeu\x1c\'\xdc\xb8u\xa7\xb7\x00\'\xe3H\x8e\
+\xf7\xf3\x1f\xce\x15\x83\xf1}\xde\xc9\x84Z\xa3E\xad\xd1\xa6\x9d\n\xe2\xcdL\
+\x85\x97B(\x06\x8e\xbb+\x15\x16\x96\xee\x1e\x8acTw\r87~\xc8\x18/\xe4\xc4\xc9\
+9\xfc\xf2\x1ce%\xb4SM\xa2=L\x10=\x17\x1e\x050[\xf4\xb8|\xee\x0c\x1b\x955v\
+\xb6\x1a\x13q\'j\x98\x11\x1d\xf6bq^HX(Q\x8c"B\x1f\x02\x1c\xe5\xc0=\x03\xef\
+\x96\xef\xbcY\xe0\xeb/>\xc5w2\x11\'O\xba\t\xc9\xf3\xbc\xcf\x95\x80\x88\xa1\
+\x93\xa4\xec4c\x1a\xed6\xceh\xa2\xc0M\xc4\xfb\x83\xfa\xe6\xfc{\x9c\xfd\xf8\
+\xfd\x898\xa2\xf0\xd5s\xe0\xfb3\x19\x95\xb4\xa9\xd5vX^}\xc4\xbd\xf5*\x8df\
+\x8c\xef\xcc\x01\xbc\x14\xc2\\9\xe0\x87\xab\x97(\x15\xc2\x038\xa2\xf0\xf5\
+\x11\xd2\xa8~c\x95v\xa8V\xab\xdc\xbc\xb5\xc0\xf5\x9b\x8b,\xadV\x89\x93\x8cb\
+\x0f\xef\xff\xbe\xfa\xe8\x14W.}y\x00w\xa2\x08s\xd3M\x9d\xa7\xc5G\x8fW+9\xdbO\
+Zl?^c\xb1\\\xe4\xc2\xd9\x0f\xb9\xf2\xf9\'\\xw\x96R\xe83[\xf0\xf8\xe9\xfb\xcb\
+\xfc\xf7\xef\rj\x1b\x8d\x01\x8e(\x823?^\xbb\x96\xc9\xd1\xf1\xfd\x87\x8cJ\xda\
+<\xae<\xe4\xf6\xe2\x1dV*5\\P`\xfed\x99s\xf3\x11\xfe\x1boq\xf3\xef\xbfp\x92\r\
+\xf3\x81T\x86\x1f\x0c/\x8a\x8fn\xb5\\r\x96\x97n\xb3\xbc\xf0\x0f\xbf\xcf\x9d\
+\xe4\xbb\xab\xdfr\xf1\xb3\x0f\x98?\xfd6[\x8f\xee\xf7\xda+\xbc\xf3\xbf9\xa7\
+\xed\xcb\xc5\'\xadvDQ\x08}\xf2N\x0b\'\xe9\xf8\x1a\xd8\xff\xb9\xf4*p\'\n\x95\
+\xa9\xc1\x93\x0f\xce\x81\xd7\x85\x0f\xdb\xef;\x07\x8e\x13w\xa2\xf0\x8f\x13G\
+\x14\xff\x03\xe8\x84\x1b+\xdf\xf26\x9e\x00\x00\x00\x00IEND\xaeB`\x82'
+
+right_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\nI\
+DATx\x9c\xc5\x96Ko\x1bU\x14\xc7\x7f\xf3\xb4=&\xd4mQ_H\xd0"\xdaD,\xda\x8aR\nB\
+\xa8\xb0a\x83\xc4\x82\r{>\x01_\x00\xa9;>\x04\x0b\xb6,\xd9\xb0fQ@\x08\x81BU\
+\x92\xaa\xa1\xa5\x0f\xbbQ\x12\'c{\xecy\xdf\x07\x8b\xf1\xb86u\x9c\xa4I\x95\
+\xd5\x9ds\xe6\xce\xfd\x9d9\xf7\x9c\xff\xbdF\xa3\xd1\xe0\xbb\xdf;:S \x15\xe4\
+\n\xa4\x06!Ah\x10C\x7f\xaa \x97O\xe7\x08]\xd8\xb9*\xe6\xc4\xa2\xb0\xb3\xe1\
+\xfbT\x0emY<\xc7\xa2\x18K;\x93\x90\x08\xb0\xbf\xf9\xa9\xa3/\x9dx\xea,\'\x8c\
+\xdbQ\xf9q9\xaa\xb1\xc5\x04\x0cr\xa8X\xa0u\x11|\x0e\x18\x80\x1a\xda\xd90\xd0\
+\\M\xc2\xa5\x94\x98R\xef\x1f^.\x98JH\xe4\xa4\x1d\xe5\x85/\x1d\xfa\xc6\xe1\
+\x88\x14S\xaa\xc3\x83k\x99\x15\x198,8y\x84]nA\xb9\xf8\x1fK\xf7\xb1\xaa\x1e\
+\xa7N\x9dBH\xe3\x85\xc2\x11)\xb6T\x93\x7f\xde\\\xf7\xf9\xfe\xdb\xaf9s\xe1\n\
+\xd7\xae\x7f\xc2\xf9\xf9\x0b\x98N\xe5\x85\xc0\x8b\x00\xf4d\xda\xaf]\xbd\xc2\
+\xcd\x9bW\xb9\xfb\xf3\x0f\xdc\xbf\xf5\x0b\x8d\xb3\x17Yx\xf7#\xe6\xdf\xbaHm\
+\xee(\x992\x0e\x0c\xaeE\x86-\xd4\xe4\x9eKm\xf2\xe9\xe7_\xd0\xbc\x7f\x87\xb8\
+\xd7\xc6o\xad\xf0\xebz\x8b\xc5\xdf\xcer\xf2\xcdK\xbc\xbep\x89\xa3\'N#\rg\xdf\
+pD\x8au\xfd\xcb\x1b7\x8eT\'\x0b\xce{i\x8e\x9e\xac\xd0\xfa\xf7.\xd8\x15\x8c\
+\xca\x1cBi\x02\xbfM\xeb\xf1CV76I\xa5\tN\ri:\xcf\rG\xa6\xd8#q\xf8_\xb5\xbf\
+\xf7\xc1\x87\xdc\xb9\xfd\x17\xdd\xf6*85\x0c\xbb\n\xae\x872\x1d\xfa]\x9f\xfe\
+\xd2"n\xb3\x85\xf7\xca\xab\xd4\x8e\x9d\xc1\xacx\xa4\xd2\xdc\x13\x1cQ\xb6\xe1\
+\x94V\xb3\xdd\x1a\x97?\xfe\x0c\xcbk\x8c\xe0\xb8u\x0c\xd7\x03\xc7\x03\xd7#\
+\x97\x9a^0`cm\x95\xcd\xf6&a\x94\x90\xe4z\xd7p-RL\xa1\xb6\xef\xf3\xb3o\x9c\
+\xe7\xe4\xfc;S\xe1\x86\xe3A\xad\x81\xe1zh\xabJ\xaeM2\xa1\x90\x18\xb8\xa6\xc6\
+6\x14\x86\x88g\xc2\xc9\xa3a\x11n\xd3\xe7\xb9\xb6\x98\xbf\xfc>\xbe\xdf%\x13b*\
+|\xc2\xe7z\xd4\x1d\xf0\x1c\x9b\x97\x9d:H\x9b\xa0\xd7\xa3\xd7MI\x92g\xe1\xa36\
+\x9c%2\xf5\xc6q\xce,\xbc\xcd\xa3\x95%\xb4S\xdb\x05\x1c\x1a\x15\xf0\x1c\x83\
+\xbaS\xe5\xdc\xf1*\xc8c\xf8\xdd.\xcd\'kl\xb5\xd7\xc8\xcbm\x91\x19F\xa3\xd1\
+\xe0\xab\x1f;z\x96\xc8\xf4\xa3\x8c\xbfo\xfdI\x14\xc5\xbb\x84S\xd8v1\x96\xef\
+\x1cC1\x08\x07,\xdfk\xb2\xf2\xcf\n\x9d\xcd\rl\xd8Y\xe1\x94\xe5b\xd7\x8f\x82\
+\xae<7\xbc\xee@\xa3b\xf2\xda\x919N\xcf\x9dC\xc4\x01\x8b\x1bO\x8a\x00v\x92\
+\xd7\xad\xde\x800\xcd\xf7\x05\xaf\x9a\x92\x87\xeb\x01\xb7\xef>`iy\x99\xb0\
+\xe7\x83\xc8\x8a\x00f\xc1\xc3L\xb1\xde\xdeD\x19\xce\x9e\xe1U[\x93$\x19\x0f\
+\x1e\xb5Y^\xb9\xc7\xdaj\x93<)\xdb2+\x84\x08f\x1f,[\x9d\x80$\xc9\xf6\x04wME\'\
+\x08\xb9\xf7\xf0\t\xad\xc7\x8f\x18\xf4\xb6@\x0e\xab\x7f\x0c\xae\xc50\x80\xed\
+\xe0Q&\xe9\x06\x01z(D;\xc1\x919\xcd\xad\xb1j\x8f\x82Q\xb5O\x83\x93E\xc3\x0cl\
+s\xaa\xf9\xdd\x1e\xb9d&\xbcf)\x928\xa1\xb5\xb9E\xbb\xbdA\x18\xf4&\xfa|\x16\
+\x9c2\x03\xd3\xe0\x838%\x8c\x92m\xe16\x92\xb0\x1f\xf2\xd8\xef\x10t}\xf2$|Fdv\
+\x82\x8f\x02\x98v\xa4\x06\x83\x08e\xb9\x13\xf0\x9a\r\x15r\xfc\xce\x80A\xafK\
+\x1c\xf6\xa7\xca\xebn\xe1\x1350\x0e\xefG)Y\xaeFp\xcf\xd2X*\'\xee\x87\xf8a\
+\x80L\xe3m\xb5}/\xf0Q\x06\xc6\xe1q\xae\x88\xe2\x14\x9c\x1a\xb85\x1c\x9d\x93&\
+\tQ\xdc\x1f}tP\xf0\xa7m8v\x99H2\x89\xb6*`9\x18YB&\xd3\x1d\x8f\xd4\xe7\x85\
+\x8f20~\x93\xc9q\xd0\xa6\x84<A\xed\xe2<\xdf\x0f\\\x8b\x14\xb3,\xc2\xbd\xded\
+\x0e\x02N\x16\x15\x01\x1c\x16\x9c\xf1\x0c\x1c\x06|\xb4\x05\x87\x05G\xa4\xfc\
+\x07\x8a\xed\x03}\xa8\xdcA9\x00\x00\x00\x00IEND\xaeB`\x82'
+
+smile16_png = \
+'\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\x02\xa3IDATx\x9ce\x93\xdfkSg\x18\xc7?\xe7WL\x1b\xa2\x07!U\xa9\x89\xe9j\
+\x90H\x87\x0cA\x86"\xb2\xf6B\xa1\xe0\x8d\xca\x19.\x88XJ\xa0\xb7R\xbc\x14\xbc\
+\xb2\xfb\x03z\x93u\x17\xbb\xdb\x8dcHA\x85\xe4\xa6\xec\x80\x11d\xa3\x9548WMW\
+\x10\xd9\xc4\xa2\x89\xc99=\xfdz\xd1D\x83\xbe\xf0\xde\xbc\xcf\xfb\xe1\xf9\xf2\
+\xfd>\x0f\xae\xeb\xd2\x7f\xcb\xe5\xb2\n\x85\xcb\xcaf\x0f\xc8\xb6\r9\x8e\xa9\
+\\.\xadbqZ\xbe\xef\xeb\xf3\xff&}\xc7\xf3.\xe9\xea\xd5\xf3\x8c\x8d\xfd\xc3\
+\xdd\xbb\'i\xb5~\xa0\xd9\xfc\x9e;w\x8e12r\x1f\xcf;\x85\xe7]T?c\xb8\xae\x0b\
+\xc0\x89\x13\xdf(\x93\xf9\x9f\xf9\xf9\xf38N\x004\x81w@\x04t\x80g\x84a\x8d\
+\x99\x99\x80F\xe3$\xd5\xea\xb2\x01\xec(\xf0\xbcK\xcad\xa0T\xba\x8d\xe3\xe4\
+\x81D\x17\xec5k\x03-\x1c\xc7\xa0T\xdaE&\xb3\x84\xe7]\xd8)\xfa\xbe\xaftz\xaf\
+\x82\xa0&\xe9\xb9\xa4\x07\x9a\x9d\x9d\x15 \xa9 \xa9 @\xa9TJ\xd2\xa0\xa4\x01\
+\x05\x01J\x1fD\xbe\xef\xcb(\x16\xa752\xb2\xc5\x8d\x1b7\x01\x0bx\x82a\x9c\x03\
+@*\x00\x9b\xe4\xf3OY]]E\x1a\x04E\xb0e0\xf7c\xc4Z\xa3\x80Y\xa9\xdccrr\x18\xd8\
+\x00\x9e\x01\x7f\xf6Y\xd4\x016X__\xef{\xdb\x86\xce \x93\x13I*\x95E\x0c\xc71\
+\xd5l^\xc7q\x92@\x9b\xa9\xa9\x97,,\x04\x1f\x8d\x83\xf5\xae\xa1]8\x8a`s\x88\
+\xb0m\x918\xd4\xe8\xc5\x18t\x1d\x7f\xcb\xc2B\x08l\x02\xcb@\xbd\x0f\x16h\x8b\
+\xaf\x0e\xc6!\x1c\x800\x0e\x80\x99\xcd\x0eS\xaf\xff\x0b\xbc\x02\xea\xe4\xf3\
+\x8f\x80\x87\xdd\xce\xfa\x04\x13Bd\xb2\xf6\xf2-\xb4\x92\xd4W\r\xb2\x87R\xd8\
+\xe3\xe3gY\\\xfc\x85\xb1\xb1\x18 j5H$D\xb3\xd7\x98m`\x0b"\x83\xe3G\x93\xe8\
+\xf90\xb4v\xb3\xf8\xe05\xe3g&z1\x1a\n\x82\x81nL;Q)\x1eW,\x16\x93m[J\xc4m\x1d\
+\x1b\xdd+m\x1c\x91j\xa7\x15<\xfeN\xe9\xfd1\xf9Ke\x19\xae\xeb\xe2y\x17\x14E?S\
+*\xd9}\x92\x05\xe66\xc4,&\x8e\x0eQ\xfe-\x05\xed$\x84\xbb\x98\xbeY\xc3J~\xcb\
+\xaf\xbfW\x8c\xbeQ\xfeZ\x99\xcc\x12\xf3\xf3\xe08=\xf5&\xbc\xdf\x03o\xf6C;I\
+\xd8\x8c1s\xebo\x1a\xff\x1d\xa0\xfa\xd7\xda\xa7Q\x06\xa8V\x97\r\xcb\x9abt\
+\x14\xe6\xe6`e\x05\xc2\x8eE\xd81Yy\xfa\x8e\xb9\x9f^0z\xee!\xd6\xee\xd3\x1fa\
+\x00>_O\xdf\xf7U,^S.\xb7O\x8e\x8d\x1c\x1b\xe5\x0e\x0f\xa98}E\xfe\x1fK_\xac\
+\xf3\x07\xc0b=\xfa\xc1x\xb5\x84\x00\x00\x00\x00IEND\xaeB`\x82'
+
+smile32_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\t\xc0I\
+DATx\x9c\xc5\x97il\\\xd5\x15\xc7\x7fo\xde\xbc7\xfbx6\xdb\x93L\xe2\x988\x9b\
+\x81\x10H\xd8\n\xa8-\x90PJ\xcb\xee\x90\xb0\x94B(\x08\xa9\xad\xa0\x85\x82J\
+\xa5\xaa\x1f\xa0\xa2\xa8,\x95\xba( \x81\x08!\x0b!\x86\x8a\xadI\x03\x05Z\xc2\
+\x1ah\x16\x12c\xc7`;\x1e\xc7\x9e}<3\xef\xbd\x99\xb7\xdc~\xb0\xb3\xe1\x80\xaa\
+~\xe9\x95\xae\xf4\xf4t\xef\xfd\xff\xee\xb9\xe7\x9c{\x8f\x14\x89D\xf8\x7f6\
+\xf7\x7f3h\xcd3\xcf\x8at:\x8d\xaeiH\x92D\xa1P\xa4\xd1h\xa0\xe9\x1a\xd9l\x16\
+\xaf\xd7\xcb\t\xed\xed\xa8\xaa\x8am\xdb\x04C!R\xa9\x14\x91H\x84\xe5]WI_\xb7\
+\xb6\xf4U\x16X\xfb\xecz\xd1\xdf\xdf\x8fe\x9aD\xa2Q\x12\x89\x04\xa6i\xd2\xbf\
+\x7f?\xbb\xf7\xec\xc1\xeb\xf5\x92lM\xb2{\xcfn>\xf9\xf8\x13\x96]\xb4\x8c\x13;\
+;\t75!\xcb2\xd9L\x86\\.\x8f\xdb\xedf\xee\xbc\xb9\xfc\xfcgw\x1c\x17\xe4\xb8\
+\x16x\xe4\xd1?\x88\xbe\xbe>\x96,^B"\x11G\xd3t,\xcb\xc2\xa8\x1b\xf8|>T\x8f\
+\x87P(Dkk+\xc1`\x00\x80\x83\x07\x0f2o\xee\\|>\x1f#\xe94\xd3S)\xe6\xcd\x9fO\
+\xb5Z\xe5\xa3\x0f?\xe2\xea\xaek\xc4\xb9\xe7\x9e;\x05\xe4\x18\x80u\xeb7\x8a\
+\xdd\xbbv\x91\xcdd\x08\x04\x83\x94\xc7\xcb(\x8aB\xbe\x90\'\x16\x8d100@*\x95\
+\xe2\x9co\x9c\x83n\xe8\x94\xcbe>\xeb\xed\xc50\x0c\x06\x07\x06Yz\xe1\x85L\x9b\
+6\r\xdb\xb6\xd9\xdf\xd7G\xad\xa6\xe18\x0e\xc5R\x91\xe1\xe1a\x06\x07\x07\xb9\
+\xf2\xaa.\xb1r\xe5JV\\\xd3%M\x01x\xe5\x95W\xe8\xee\xeef\xe1\xc2\x85\x94\x8aE\
+\xa2\xb1\x18~\xbf\x9f\xcf\xfb\xfbY\xb6\xec"\x92\xc9V*\x95\n\xd1h\x94x<\xcec\
+\x8f=FOO\x0f\x99L\x06\xaf\xd7\xcb\xce]\xbb\xb0,\x8bH4J\xa5R\xa5\xbb\xbb\x9bb\
+\xa9\xc8\x9c\x8e\x0e2\x99,\x8a\xa2\xa0\xeb:{\xf7\xee="\x1a\x89D\x88D"<\xb7i\
+\xb3ho\xef\x10\x1e\xaf_\xdcu\xd7="\xdc\x14\x15\xe7_\xb0T\x84\x9b\xa2Br\xb9\
+\xc5\x82\x05\'\x89\xef_z\xb9\x98={\xae\x981c\x96\xb8\xeb\xae{\x84?\x10\x12H\
+\xb2@\x92\x85\xe4r\x8b\xef\\|\x89X\xb8p\x91hk;A\x9cz\xeab\x91hn\x15H\xb2\xf0\
+\x07B\xe2\xf4\xd3\xcf\x14\x92\xcb-\xce8\xe3,\xd1\xb5|\x85\xd8\xb2u\x9b\x88D"\
+G,\xd0\xb3o\x1f\x8dF\x03\xbf\xd7\xcb\xa7\xef\xbeC\x9bdS\xfdl\x1fm\x8a\x0b\
+\x11\x8f\xe2\xd3*\x94v\xef\xc4_\xab\xe1\xb7\x1d\xde{\xa1\x9b\xd9.\x17x}\xe4M\
+\x93\x8am3\xf0\xe9^\x86GF0\x1c\x1b\xa1\xebx\x05\xc4\x90@\xd3\xe9\xed\xed\xc5\
++\xcb\xe4\xb29Z\x93I\xca\xe5\xf2\xb1Q\xb0a\xe3&\xa1e\xb2\x046>\xcdl*\x04B!\
+\xacX+\xdbX\xcc\xe6\xfa)\xb42\xca\xaa\xe6/\x98\xa3\xd4\x10\xba\x81(\x14A\xd3\
+\x11\xe9\x0c\xf9L\x8e\xf2h\x81}\xca,^\x9b~6\xfd\xb2\x97\xcer?g\xa5\xdf!\\/\
+\x93G\xd0\x87M\xc4\xad0\xe7\xd2K\x98y\xf3\r\\\xff\x83\xeb\x8f\xf5\x81\x95+\
+\x96K\xef\xdd\xb4JL\xa3\x8a\x14\x0c E\xa3lu/&y\xe3O\xd9\xf9\x84\x865>H\xcf\
+\x80\xc2\xf3\xe7\x17\x898uDS\x18gx\x04a\xda\x04\x1a&=\xbe\x0e\x12\x8f\xaea\
+\xc7F0k\xa3\x8cU\x0e0\x16Hr\xe7\xee\xa7\t\xe3\x90@\xa2b9\x94_\xfb;\xd3N>\xe9\
+\xb0\x0b\xb8\x0e}ly\xe0A\x91\xd8\xb9\x1d\xc9\xed\xc6\x15\x0c!\xb9=\xbc\xeb\
+\xcc\xe2\xb6\'4\x1cK\x03 m\xa8\xechx\x91\x12\t\xa4D\x1c)\x1eC\xf2{q\xc5#t\'\
+\xcf\xe7\xce\x8d`\x9b\x06\x00\x02\x89\xde\xd0tz\x02\xcd\xc7\x84\xb8i\x18\x1c\
+\xe8\xfe+\x9b7l\x12\x87\x01^x\xbe[$\xb6nAih`9\x08K\x80\xc7K\x8b\xab\x80=>\
+\x88\xa3eq\xf4,\xaa\x18\'\x10\x0bL\x00\xf8\xfdH>/\xf8}\x00\xa4j\x038\x954N\
+\xa3\x84c\x14q\xac\x1a\xe1\xea\x18Q\xbd0%\xcf\x8c\xf5\xeeg\xfc\xdd\x0f\x8e\
+\xe4\x01W\xb1D =\x88p\t$\x1b\xb0\x04X\x82\xe5\x89Q\xfeU\xf8\x80>#\x82\xaah\\\
+\xb8\xc8\xcbi\x0b\xe7A~t\xca\xa2]\xe3\x1f\xb0o\x8f\xc5\xfb\xb1ET]n|\xc5^\xbe\
+}\xe0\rf:\x16\xd5/\x8dm8.\xd2\xdb\xdef\xf3\xe6\x17\x85\x1b@\x1d\x1cB\xaeV\
+\xc0\xe7A\x98\x0e\x92)\x106\xb4\xc8&\xeb\x97\n\x86|\x02Ob&\xb1\x96\x18~\xe1\
+\xe0L\x91\x87\x80S\xe7\xb7\xe9\x978\xb0\xe7y\n.\x19\xc7\xd6\xf186\xe3\xc7\
+\x19\x8b\xec\xe1`\xdf\x10\x1d\xe9\xf4\x84\x05\x94\\\x0e\xc9\xb4@U\xc0\x14\
+\xe0\x00\x15\x1d\x112p\xe9\x1a\xed\x01?\x92\xab\x01\xb9Q\x1c@\xe4r\x08MC\xe8\
+\x06h\xfa1k\'\xed\x06A[PEP9\x9e\xf8$\x80a\xb9idr\x93\x00c#XB \x8f\x1b\xa0\
+\xd6\xb1\xc7J\xb8$\x15\xf2\x05\x84\xcf;1I\xd3\x0e\xcf\x17\x9a\x86\xc8\xe5\
+\x11\xf9\x02B3p\xf2%\x84^\x07\xbd\x8e\x85\xc0\x02\xcc\xc9n\x1fG\x1c\xd9\x83-\
+\xfb1\xb2\xa5\xc90\xac\x94\xb1\xea6\xaai\xc1\xd88R\x8bLv\xd8M\x8bW\xc7\x19\
+\x1eA\xd2\x8d\t\x87;\x04\xa0\x1b\x88|a"\x0f\xe4K\xa0\x19\x88B\x05\xa17\xb0\
+\x01\x0b\x81\x89\x00\xc0\xc1M\x81\x16`\x18\x1b0\xd50\xb6\xac`\xca^*\xe9\xe2\
+\x04\x80\xddp\xb0\x1c\x81\xd1\xb0\xf1Z\x06\xaf\x0e\\\xc0j\xee\xe4\xba\xec\
+\x0b\\\xb7\xe8\x8d\t\xa1Io\x9f\xb0\x86\x8e\xd0\x0cD\xbe4\xd1\x0b\x15\xd0\xeb\
+\x18\x08L\xc0\x9a\xdc\xb9\x8e`\xb5\xfbe\xf4x\x8a\xc5c\xf7\x92P\xdf\xc4\x94=\
+\xd8j\x18I\xf6#$e\x02\xa0\xde\x9c\xc4\xb0l\x84-\x90\xab\x06#R3\x9a\x12d}\xe1\
+\n\x96|\xf6!\xf3\xdb\xb2\x90/\x1dcI\xe7\xe8\x9d\x17\xc61\xf5\x06\x06\x1c\x86\
+0\x81\xb7\xb8\x9d\x9c\xa7\x13\xbf\xa8RqM\'"{\xb0\xd5\xd0\xc41\xa8\x01\x02\
+\xd3&\xef\x02+\x1cA\xb7\x04.\xcb\xa1n;\x84\x19\xc3\xed3\xc9\x97\x9a\xb9\xd3z\
+\x88K3/qk\xcbjd\xe9\xc8\x89\n\xbd~x\xe7\xa6\xde\xa0>y\xf6:0F\x0bkx\x88\x81\
+\xe07\xa9\xd5\x82$[FH\x16\xdf\xc5RC\xd8\xb2\x8a\xa34!\x84\x89\xaf9<\t0k\x06\
+\x86\xac ;:\x02X\xc0[\xb8\x95\xbb\xf1x\x0cf\xcd\xfa\x82\x97\xd3\x97\xb0\xe5\
+\xe02f\xd4\x078\xd1\xda\xc5\x12e;\x91\xc6(\xed\xf5\x0cu\x04=\x9c\xc4\x10\x1d\
+\xec\xe1lz\xbdgR\xf2\xa4@\x92\x08\xfbJ4\x85\x8b\xa8\x8a\x8e\xdb\x93\xc7\x90C\
+8J\x13\xa6\xec!\xe0\xb1\xf1\xb7\xa7&\x00\xc4\xcc\x14F \x84S\xaa\xd1\x00b|N\
+\xdc\x9f\xa5\xaa\x86\x98?g\x1fw\xff\xf8\x01^\xddv9;\xfe}&\xaf\x16\xaf\xe2U\
+\xae\xc6\x96\xdc\xb8\x03\r\x00l[\xc1%\xdbH.\x87d\xf3(\xdf=g\r\x0b;w\xf2\xc4\
+\x9a\x9f`\xd4\xbd\xa4\xa4\xedXj\x88\x86\x1a\xc2V\xc3\x085\xc4\xf4y\x01V\xdc\
+\xbaJr\x03\\u\xcbM\xd2\xa6s\x96\nkh\x04\x81\x04\xd8,\x93\x9ed\x9dq\x1f\xdb\
+\xdf?\x0f\x10\xdc\xf6\xc3?r\xfb\xcd\x8fQ,\xc6)\x14\x13\x0c\x0e\xb7c\x9a\n\
+\x00\x01\x7f\x8d\xb6\x19\x03\x84\x82\xe3$\xe2YF3\xd3x\xf8O\xf71^\t\xa2*\x16\
+\xb1\xe2\x0645\x8c\xa3\x84\xb1d\x0f\x8a\xc7\xcf\x8c\xf3N\x86\xb7\x8f\xba\r]\
+\x97]\x8c\xf1\xe1\'\x98\xb9<&p\xca\x81\xa7\xd9\x92\\\x05\xaa\xcc\xaeOO\xe3W\
+\xf7?\xcc\xcd\xd7=\xce\x89\x0bv3}Z\x9a\x93O\xdc9%\xbf\xd4\xb4\x00o\xfc\xf3"\
+\x9e\xd9\xb8\x8aHS\x89\xf1j\x84\x94\xb4\x85\xba\x00\xc7\xe5\xc1T\xc38j\x88T\
+\xab\x9b\xd8\xe29\xc0\x97^\xc5\xeb/\xbdF\xe8\xeb\x9eCq@\x06*t\xf0Lj-\x86\xe3\
+\'\x16)ppl:\x1d\xed\xfb\xb9\xec\xe2\xcd\xcc\x99\xddK"\x9e\x01 \x93M\xb2c\xd7\
+\x19\xbc\xfe\xe6\xc5\x0c\xa5\xdb\xe9h\xefc\xff\xc0\\Z\x03\xbd\xcc5~\x8d\xa3z\
+h\xa8a\x1a\xbe\x042\x06\xe7\xafZ\xc2-\xf7\xffr\xea\x9bP]~9\xc6\xde\x1e\xf4\
+\x8fw\xe2\x06\xfc\xf4\xb3"\xdd\xc5\xdf\xda\xffL\xdf\xd0\xa9\x9c\xbap\x07~\
+\x9f\xc6\xd3\x1b~D\xb9\xdaD"\x9a\x03\xa0<\x1e\xa1)\\\xa2m\xc6\x00\xa6\xa5\
+\xb0\xff\x8by\xcc\x0e\xbd\xcet\xfd\xf1\xc3\xe2\x96\x1aB\x92\x15\xe6w*DN\xeb<\
+\xac9\xa5.x\xeew\x8f\x88\xdco\x1e\xc4\x1c\x1dC\x99$4\xf1\xf1R`5\xe3\xb1N*\
+\xb5&Z\x9b\xc7hI\x1c\xa4m\xe6 \x00C\x07N\xe0\xf3\xc1\xd9\xd4\xf4 !_\x89P\xf1\
+\x1ft\xf8\xd7b*\xe1\xc3\xe2\x96\x1a\xa0-^\xe7\xac{\xaf\xa4\xeb\xdak\xa4\xaf\
+\x04\x00Xw\xc7/\xc4\xe8\xea\xa7h\x8ceP\x8e\xfa\xdf \xc0`\xe2Z\x06\x03\xdfc\
+\xac:\x1b\x07\x19\x00\xb7\xabA\xab\xaf\x87&\xed-\xe2\xce\xdb4\xd4 \x8e\xeb\
+\xc8\xce-\x97\xcc\xccf\x87\xd3\xef\xb8\x8c\x95\xb7\xdcpL]\xf0\x95\x95\xd1\
+\xc6\x07\x7f/F\xff\xf2$\xa5O\xf7"\xec)W\n0\x91n\x1bj\x08K\xf6`\xa9!L\xd9CC\
+\x9d\x8cu5\x8c\xa5\x06q\x99e\xe6\xceS\xe9\xbc\xe5\nV\xac\xbaqJu\xf4\x95\x00\
+\x00\xcf\xaf]\'\xc6_\xdb\xc6\xe8+[)\x1d8\x80\xe3\x1c\x05"Ox\xb59\x99^\x0fe8[\
+\x9d\x085YQ\x88\x055\xe6_0\x9f\x96\xa5\xe7q\xf5\xf2\xab\x8f[\x9a}-\xc0\xa1\
+\xb6\xe9\xa95\xa2\xb4\xf5\r2\xdb\xdf\xa7:\x96\xa3VkP\xb7\x04\xb6\xdb\x87\xad\
+\x04AV\x10J\x08\xb7\xea\xc2\xe7s\x13\x9b\x91$\xf5\xadE\xc4\x96,8\xe6\xbc\xff\
+g\x80Cm\xf3\xe6\x17\x85S.S\x1f\x1a\xa6\xba\xef3L}"\x13:\xc2A\x89F\x89\x9e~\n\
+J<N\xd7\xf5+\xbfV\xf4\xe8\xf6\x1f\xef}\x9b\xb7\xd0cu}\x00\x00\x00\x00IEND\
+\xaeB`\x82'
+
+smile48_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\x08\x06\x00\
+\x00\x00W\x02\xf9\x87\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\
+\x0c4IDATx\x9c\xed\x99{\x8c]\xc5}\xc7?3\xe7}\xef=\xf7\xe1\xbb\xde\x97\xd7\
+\xbb`{\xc1\x0b\xb10\xc6(\x01\xb2n\xa9 Ai"\x82[\x05E$\xfc\x83\x10Hi\xa5(j\xd4\
+H\x95\x9a\xaa\xad\x10i\xffI\x9b\xaaJj(\x15(~cC\xc2#H\x01c\x8ay8\xc5\xbb\xe0\
+\xf7zm\xaf\xd7\xbb\xeb}\xde\xdd\xfb\xbe\xf7\xbc\xa6\x7f\xec\x82\x85H\xbb\xbb\
+\xbe+\xa1J\x1di\xa4\xa393\xe7\xf7\xfd\x9e\xdfc~3?\x91N\xa7\xf9\xbf\xdc\xe4\
+\xe7\r\xa0\xd1\xf6\xff\x04>\xef\xa6\xaf\xf4\x07\xf7\xefyF\xd5\xf2g\xa9\x15\
+\x06\x11\xc1,Am\x14+\xd1\x81\xe1\xac\xc1L\xde\x88\x11\xdf\xc07\xb7\x7fK\xac\
+\x94<\xb1RN|\xe0\xf9\xdd*w\xf9u.\x9d\xd8CX\x1b\'a{\xd8\x16d\xdc\x85\tJ \x8d\
+\x18V\xeafd\xf6~\xcc\xf4\xed+BdE\x08\x1cx~\xb7:q\xf8o\x99\xbc\xfc;\x1c\xd3\'\
+\xe3\xce\x03O\xbb\xe0X`\x9bW\xe7\xd6<\xa8\xf96\xa1\xfb\x87\xc4\xaf\xffA\xc3$\
+V\xc4\x84.\x1d\x7f\x8eK\x83G\x89Y\xc1\'\xe0\xdb\x9a\xe6\x81g\xdc\xcf\x12\x98\
+-\xd6\xa8\xd5\xdf\xc0\x9f\xd9\xd4\xb0\xec\x86\x9dx\xc7?\x7f_\xf5\xbd\xf7\x02\
+\x9a\x9c\x07o[\xf3\x7f\xde6\xa1-\x0b\xd9\x14\xc4\x9d\xab=\x9b\x9a\x1f\xb7\r\
+\x0fr\x078\xb0\xe7\x17\xeas%p\xee\xc3\x17\xf1je,\xe3\xea\x1fw\x16l?\xee\xfc\
+\xfe5qg\xfe\xbd\xee_ *\x1emH~C\x04\xf6\xef}VM\x8c_\xfe\xcc\xb8m~\xdal~_\xb3M\
+p,EX9\xd7\x08\x84\xc6\x08\xa8(\xc4\xf3\xfc\x86\x00(\x7f\xb6\xa1\xf5\r\x11\
+\x98\x9d:G>_n\x08@!7\xc4\xf3\xfb~y\xcd~\xd0P\x14:=0N\xad\x1ea\xe8P\xaeA\xbe\
+\x0cRB\xa9\n\xd3ypcW\xe7\xda\xb6\x8dm\xdb\xe8\x9aF\x10\x86\x9c\x1f\xf18>Pa\
+\xf0\xca4_i\x99\xbcf\x0c\xd7L\xe0\xc5\xfd\xff\xa1\x9e\xfe\xc5\xbfp\xe0p\x04\
+\x80e\x82\xa1\xfd\xcf\xf3{z\xae\xa7\xb7\xb7\x97m\x7f\xb0\x8d\xb7\xdey\x8bCo\
+\xbeM\xdf\x87\xa7\xd0\xb4:\xb7\xf6\x9e\xe4\xd7/\xeeR\xdf\xb8\xff\xdb\xcb\xde\
+\x13\xae\xc9\x84\x9e\xfd\xa7\xef\xaa\x96\xdaO\xd9\xbc\xee\x12=\xeb\xe2$b:\
+\x86\xa1\x834P\x18\x94\xaa|\xa6W\xea\x92\xd1\xf1<o\x1cz\x97\x89\xa9<\x9af\
+\x90LX|q\xf3\x1a6\xb6\x0e\xb3V\x7f\x81}O\xff\xd9\xb2Mi\xd9\x1ax\xf6\xa9\x7fW\
+\xa3\xa7\xf7\xf0\x9fo\x0c\xd2\xda$x\xf8\x8f\x93\x94k\x82\xe6&\x87d\xc2! \xc6\
+\xe8T\x80mY\x98\x96\x85\x94&R\xea(i\x92J%X\xdf\xa1\x90!\xe4\xf3-\xcc\xe4\x12\
+\xe8\x94\x19\x1e\xec\xe7\xc3~\x8d\xd6u\xbd\xcb\x85\xb3<\x02;\x9f{Ni~\xc8\x8d\
+\x9b\xbfKP\xedd\xf0\xa3~\x08s\xe8\xa2\xce\xc8\xa8B7\x02\x1cw\x06KJt\xbd\x82\
+\xd0\x04RJ4MC\x97\x82`f\x88\x81s\x1a\xb99\x9b \x84z\x18Q*8\xf85\x87P\x18l\
+\xb8\xe5\x0e`\xef\xb2\x08,9\x17\xda\xb7w\xaf\xcaOL\xb2*\xbd\x8a\xd3\xc7\x8eq\
+\xea\xdd\xf7@\x85\x84\xf5*A\xad\x8a\n|\xd2\xe9$J)\x04\x1aa\xf4\xf1J\tRC\n\
+\x81\xd4@\x13\x12t\x89\x10\x82H\x80PP+\x97)\xe5\x8b(\xdbf\xfb\x0f\xbe\xcfw\
+\x1eyd\xc9\xbe\xb0d\x1f\x98\x19\x1f\'\x1eO0|\xfe"}\xef\xbcK\x14}\x82\x10!%\
+\xba\xae\xa3\xe9:\x86i"u\x1d\xa9ih\x0bc\x9a\xbe\xf0\xaci\xc8\x85\xae-\xbc\
+\x97\x9aF\xdcu1-\x93\xcaL\x8eC{\xf7\xf1\xc2\xc1\x83K\xf6\x85%\x99\xd0\xb3\
+\xcf<\xa3T\xbdN\xa5T\xe2\x9d\xd7\x0fQ\xcc\x17\x88[&R(\xa4RX\x96\x85!%BjD(4MC\
+H1\xaf\r\xa1\x81\x94H!\xf1B\x0fG\xd7@\x93H!@\n\x84\x04\xa1\x14\xa9t\x860TL\
+\x9f\xbf\xc8\xc0\xf1\xe3K\xc5\xbf4\r\x94f\xa6\x11\x08~\xfb\xf2\xcb\\\x1c8\
+\x87R\n?\x0c\x18\x99\x9be \x97\xe3\\\xbe@\xce0xu`\x90\xdf\x9c9G$%\x8e\xe3\
+\x10O$\xb0c\x0e\x96ms\xa5T\xe0W\'\x8eslr\x82\t\xcf\xa3\x7ft\x94\xf7/\\`\xa2P\
+\x00)\x89\xbb\t\xda\xdbZ\x11Jq\xe4W\xbf^\xb2\x16\x16\xd5\xc0\xfe={Tqr\x82\
+\xc2\xec\x0cC\xa7\xcf"\x80\x9a\xefs|r\x8c\xf3\xa3#x\x9e\x07\x80a\x18\xf8\xbe\
+\xcf\x9d\xb7\xdf\x8eeZ\x08)A\xcc;q\xa4 \xb5*\xcb\xf8\x7f\x1d\xe5\xfc\xc8\x08\
+\xba\xae\xe3\xfb>B\x08R\xae\xcb\xd6\xeen\xfeh\xe3M\x18\x9a\x8ea\x1a\xe4\xa6\
+\xa68\xf2\xe6\x9bK\xc1\xbf\xb8\x06\xfcj\x05\x15\xf8L\x8e]\x01\xa50M\x93+\x95\
+"g\x86.\x12\x04\x01\xb1X\x82\xf6\xf6N\x92\xc9\x0cn\xc2\xa5;\xe5\x12\x85\xc1<\
+\xf8\x05[\x97R\x92\xd2u\xba;:\xb0m\x87\xa6l\x0bm\xad\x1d\x98\xa6\xc5\\\xa1\
+\xc0\x91\x93\'\x99\xacV\x90RbY\x16A\xdd\xe7\xec\xb1\xbe%\x11XT\x03~\xa5\x8c\
+\nCf\'\'H\xc4\xe3\x08\xa5\xd1\x1c\xe9\xdc\xb5\xf5\x0e\xe2\xc9\x0c1\xc3\xc4\
+\xb4l\x94\n)\xcd\xcd\xe2\x196\xc5P\x91\xf9\xf8\x03B\x12\x112^\xf1\xf8\xd2\
+\xedw\xd3{\xa7A(utM\x92\x9b\x9dfrf\n+\xac\xd1\x92J#\x95"\x16\x8b\xa3P\xcc\
+\x8e\x8f\xb3c\xc7\x0e\xf5\xe8\xa3\x8f\xfe\xaf\x11iQ\x02\x91\xef\xa3K\x81\xa5\
+i\xb8\x89\x04U?\xc2p\xb2\xac5tz\xd6v\xa1\x87ut)\x90*\xc2\xbc\xa1\x9b\x81\x91\
+\x11N\x8f\\fu\xa9\xc2\xe0\xe8%R\xf1\x04\xa9\xd5\x1d\xac\xbd~#=\x9d\x9d8""\
+\xf0\xabH)\t\xda\xb3\xcc\xd5\xd630:\xc6D\xbdF\x97\xa3\x93t\x13h\xa6I\x04\x0c\
+\r\r-\xaa\x81\xc5\x9d8\x08\x88\x82\x00\xbfRf$_`Z\t\x0c)\xd9\xb4~#\xa1W\xa5^)\
+P\xc9O\x13\xd6\xab\xe0\xd7\xd9r\xd3\x17\xb8\xed\xe6[\x98\xae\xd7\x19\x99\x99\
+f\xacP\xa0s\xfdM\xdcy\xcbVb\xa6N\xe8W\x89\xc2:^%O\xe0UH\xdb\x06[\xbao`\xba\
+\x1epdd\x9c\xa9j\x15\xcb4\x91J\xe1\xd5j\x8d\x13\x88\xc2\x90Z\xb5\xc2\xdc\\\
+\x8e\xa0^\xe5\xe2\xa5A6\xae\xef\x99\x0f\x83JQ\xafU\xf1}\x8fz\xbdB\x18\x05DQ\
+\x84\x1bO20t\x91G\xbe\xfe\x15\xdc\x98\xc5\xf1\x93\x1f0W\xcc\xcf\xef\x13\x86\
+\x85&@j\x12\x15\x85h\x9a$\x93L\xd2\xde\xdcFan\x1a\xd7q\xf0\xc3\x10/\x08>\xb5\
+\xd7\\3\x01?\x8c\xa8\xd7j8v\x8c\x94&\x88\xbc:\x02\x85\x14\xf3\xf1[\xd7-\x14\
+\x02\xa5\xe9\xd4\xbd\x80\xc1\x8b\x83\xec\xd8\xf5o\xacJX|\xe7\xeb\xf7\xf2\xbd\
+\x07\xefg\xf8\xf2\x00O\xef\xfcW\xaa\xb5\n\x9a\xa1a;1\x0c\xcb\xc4t\x1c\x84\
+\x9cwt\x85\xa2\xbb\xbd\x8d\x98m3[.\x11\x08\xd0\xf4\xc5\xb7\xa9E\th\x96E\xe0\
+\x05\xd8\x8eC\xd6qp\r\x8d\xbe\x8f\x8eb[6\xae\x9b\xc6\x89\'HfZ\x88\xb9\xab\
+\x98\xadz\xec\xf9\xcd\x8b\xdc\xb7\xf9F^z\xf2\xafX\xd7\xd5\xc9\xb7\xff\xf4\
+\x9b\x1c\xfc\xc7\xbf!\xa6G\xbcz\xe8%\x94n\x10\xe9\x06\xba\xe3b\xdb\t\x9c\xb8\
+K\xc9\xf3\xe8;\xfe\x01m-\xcdxB\xa1t\r\xa5\xeb\xf3\xa1\xb8Q\x02F,\x06J\xcd\
+\xc7v"\xbe\xd0\xd2\xcc\x85\x0b\x03|p\xb2\x0faX\xa4\xb2m\xb8\xd9V\x8cx\x86\
+\xd7\xdf=DO{\x13\x7f\xff\xf0\x9f\xd0\x94r!\xf0Q\x85<\xdd\xed-\xfc\xc3c\x0fs\
+\xf4\xc3~^{\xfb0N2K<\xb5\x9ax\xa6\x99\xc8\xb0x\xff\xa3>\xdaR\x0em-\xcd\xcc\
+\x14\x0bxa\x880\x8cE\xc1\xc3\x12\xa2\x90\x93L\xe2y>RH\x0c\xc3 )%[\xdb[8}\xf2\
+\x18\xfd\'\xfbi\xce\xaefMK\x1b\xa3\x93cL\xccL\xd2\xeev\xa0+\x05\xb5\n\x9f\
+\xdaJ\xbd\x1aQ\x14\xf1\xde\x07\xefs\xfdu\x1b0\x0c\x83\xf1\x99\x19fg\'ivmn\
+\xdd\xba\x05\x84`fnv>\x1d\x89\xc7\xd0\x97`B\x8b\xce0l\x07a\x9aD*$\x1eOP*\x14\
+I\xd86w\\\xd7E\xd1\xf7\x89\x00Y\xce\xb1&n3\x9eH\xf0\xf6\xd9\x0b\xfc\xc5S\xbb\
+\xf8\xde7\xeee\xdd\x9aV\xaa\x9eO\xdf\xf9K\xfc\xdd\xae\x17\x11(\xb6\xf6t#j\
+\xd3\x10\xeat\xad\xb2\xb9\xa3g\x0b\x9a\xd4(\x97\xcb\xcc\xe4r\x8cNN\xa2[6\xd2\
+\xb2\xe9\xec\xecl\x9c\xc0\x03\xdb\xb7\x8b\xa7~\xf635~\xfe<\x86\x13C+/\x1c\
+\xe2\x85 \x1d\x8b\xa1\x1b\x06\xbaa\xa0\xe9:\xa5 `*_\xe0\x95c\'x\xa5\xef\x14m\
+\x99$\xd5\xba\xc7\x95\xb9"\xa6\xaeQ\x0b\x15]\x9d\x9dt\xb4\xb6b\xda\x16\xb6ec\
+\xd9\x16\xbe\x1f\xe0\xf9>G\xfb\xfa(U\xabd\xd7\xac\xa5\xb3\xb3\x93\xc7\x1e{l\
+\xd1\xb4zI\xd9hv\xcd\x1a\xccl\x96\xd9\xa9I\x84n@\x14"\xa4\xbc\xda\x17r\x9e\
+\xee\xd6V&K\xdd\xbc\x7f\xe2\x04\xba\x80\\\xa9\x8c@\xa0P(-\xc6\x83\xf7\xdd\
+\xcb\xf5m\xad(\x14\x9eWG\xd3t,a#\xa4\xe0\xf4\xc0Y\x06\x87/\xe3\xc4\xe3\x98n\
+\x82\xeb\xae\xbbn)\xd0\x96~\xa0yf\xc7\x0eux\xdf^\xaaS\xd3\x18BbY\xe6\xfcIkA\
+\x03\x1fk\xc1\x0fC\x86\xa6\xa6\x98,\x95\x98+\x97I\xc4b\xb465\xd1\xd5\xdcD{\
+\xf3jL\xd3@\x01a\x14\xe28q\xdc\x94\xcb\xc8\xe5\xcb\xec\x7f\xe9U\xca\xf5:M\
+\x1dkY\xb7\xb1\x87\x9d;w.\xe9P\xb3\xac\xdb\xe9\x9f\xfe\xe4\'\xea\xd0\x9e\xdd\
+\xa8r\x95t2\x89m\x99\xf3\xe0u\x1d\xdd41\x0c\x830\x8a\x08\x95B\xd3u,\xcb\xc24\
+M\x0c\xcbBHP(L\xcb$\x8a"\xbc\xc0\xc7\xb2\x1dj\xb5*\x87\xdf?\xca\xe5+\xe3\xa4\
+V\xb7`\xa53<\xf4\xd0C<\xfe\xf8\xe3K"\xb0\xac3q\xd7\r7p\xeb=\xf7p\xec\xb7\xaf\
+3\x91\x9b!f\x98\xb8\xaeK<\x11Gj\x1a\xb50D3\x0c\xcc\x05\x8d\x08!\x88\x94\xc2\
+\xab\xd7\x91\xba$\x0c|\x84\x8a0-\x13\x82\x90\xbe\xbe~>\x1c8\x8b\x1fF\xacji\
+\xc5H\xa7\xe9\xed\xed]2x\xb8\x86\xfa\xc0\xc1\x03\x07\xd4\xe0\xa9S\xbc\xf9\
+\xc2\x0b\x14FGqL\x93\xe6\xa6&\xd2\xe9\x0cB\x93W\xcdI\xd3\xd0\x16HH)\x91R\x00\
+\x11(\xc5L.G\xff\x993\x8c\xcf\xcd\xa1\x9b&\xa9\xd66\x0c7\xc9]w}\x99\'\x9f|rY\
+wC\xd7\\\xe0\xd8\xf1\xf3\x9f\xab\xc3\x07\x0f2|\xea\x14\xa6\xd4\x16\xec? \x99\
+L\x92M\xa7q\x1c\x07\xc30PBP\xad\xd5\xa8T\xca\xe4\xf3s\\\xc9\xcdP*\x14\t4\r7\
+\x9d\xc6iiEZ6\xbd\xbd\xbd<\xf1\xc4\x13\xcb\xbe\xd8j\xa8B\xf3\xfc\xfe\xfdjx\
+\xe0\x1c\xaf\xec\xdc\x89\x0c|.\x0c\x0e2\xedy\xb4$\x93$]\x17MJ\xbc \xa0\xe6yx\
+\xbe\x87\xeb8\x9c\x19\x1d\xe3\xb6u\xeb\x18\x1e\x1e&\xb3i\x137\xddr\x0b\xdb\
+\xb6m[\x96\xd9\xac\x18\x81\x8f\xdb=\xb7\xdd\xa6:\xae\\\xe1G\x99\x0c\x87-\x8b\
+]\xc5"\xd3\xc3\xc3T,\x8b \x08\xd04\x8dD\xb9\xcc\xb6\xaf}\x8d\xf5o\xbd\xc5\
+\xed\xad\xad<44\xc4\xcdw\xdd\xc5\xab\x87\x0e5TbZ\x912\xab\x93JQT\x8a\xec\xd0\
+\x10\xdf\x12\x82\xbfv]\xc6\xcbe\xb4L\x06\'\x95\xc27M\x92\x1b6\xf0h\xb1\xc8\
+\xc3--\xac\x8a\xc7\t\x95b\xd3\x96-\r\xcb^\x91\x1a\xd9\x8d\x9b61\xecy\xd4\x86\
+\x86\x90A@\xe2\xd2%\xc2Z\r16\xc6\xadMM\xbc^(\x90\xae\xd7\xf1\x84\xa0R.3U\xab\
+\x91jo\xa7\xad\xa3\xa3a\xd9+\xa2\x81\xb6\xceN\xc6fg\x99\xeb\xea"\xd6\xd6F{S\
+\x13\xc9\xd5\xab\x19*\x958\x92\xcb\xa1\x0c\x83T"\xc1\x86X\x8cX{;\x17\x85\xa0\
+\\,\x92\xcdf\x1b\x96\xbdb\x85\xee\xcbccT\xebu\x82J\x85\x1f\x9d?\xcfd\x18\xf2\
+\xe7?\xfc!\xed]]\xfc\xee\x8d78\xd6\xd7\xc7\x91\xe1a\xbe\xb4y3^\xb1H87\xb7\
+\xa4ls\xb1\xb6"\x04b\xb1\x181\xc7\xe1e\xc3`(\x97\xe3\xadL\x86\x07\xbf\xfaU\
+\xbe|\xf7\xdd<\xf0\xc0\x03b\xf7\xee\xdd\xaaX(\xf0\xf0\xe1\xc3<25\xc5P\x14\
+\xd1\x12\x8baYV\xc3\xb2W$\n\x1d<xP\xbd\xf7\xdak\x9c9s\x06]\x08\xbex\xcf=l\
+\xe8\xe9a\xfb\xf6\xed\x9fD\x98}\xfb\xf6\xa9\x93\xfd\xfd\xbc\xf9\xca+\xd8\xb6\
+\xcd\xdd\xf7\xdd\xc7_\xfe\xf8\xc7\rW\xea\xff\x1b\xd5\xe8\x0b\x01\xe7z\x82m\
+\x00\x00\x00\x00IEND\xaeB`\x82'
+
+up_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\
+\x03IDATx\x9c\xc5\xd7\xcdo\xdbd\x1c\xc0\xf1\xaf\x1d\xbb1v\xd2\xae\xac\x1b\
+\xd36\x10\x1b &!\x90V4\x06H\x1c&n\x08\xf1\x0f \xe0\xca\x15\x0e\xfb/8#.\x88\
+\x0bB\\&M\x88\x0b\x87ich\x0c!\x0e\x83\xb2\xc2\xd6\xb1\xf5}I\xd3.m\x12\xe7\
+\xf1\xe3\xe7\x85\x83\x9b\xbe\x904q\xb2\x03\xa7\xc4y\xfc\xf8c\xe7y~/v\xbe\x9b\
+m\xd9WO\x86$\x1a\xda\n\xa4\x86D\x834\x90l\x1fK\x93\xfd\x16\xa7\x90n\x8fw\xce\
+\xe9\x1c\x0b\x95\x8dw\xc6\x84\xde\xbe\x96\xca\xbew\xe6w\xce\xed8\xae\xb1\xf6\
+\x7f\xc3\xb3\x1b0\x8f\x87ol\xc5\xfc}\xef\xc1H8Z\xe2Jm\x1f\xeb\xc9\xff\x98\
+\xf9\x93\x9b?\\\xa2)\xe4\xd08*\xc15vt\xbc)4\xf7f~\xa3\xb1\xb6\xcc\xd2\xf2\
+\xca\xd0\xb8U\t\xae6\xa3\xaf\xf9j\xb5F\xbd\xb2\x80q\n,\xcc\xfd54\x8e\x8c\xb7\
+7\xe1\x88\x1bn\xee\xce,Jk\x9c\xb1\x88\xfa\xda*\xf5Fk(\x1c-q\x95\x19\r\xdfj\t\
+V\xfe\xb9\x8d\xe3\x87\x10\x8c#\x95fm\xad:\x14n\xb3=`G\n\xb5\xc5\xa5E\xda\x8d\
+:\x04\xe3P,\xe3\x04\xe3<\xaao"R\x93\x1bG%\xb8\xca\x8e\x10\xe7\xca\xb207\x8b\
+\xf5\x9e\xd8\xc1\x9dh\n\xa9\x0c\x8dv\x92\x1bG\xcb,\x0f\x0c\x9bd66\x1b4\x1e\
+\xad\xef\xc3)\x96\xb1~H[\xc8\xdc8*\xc1K\x8d\xc5\x1b\x02\x97\x1aV\x96\x16\x91\
+J\xef\xc3\x9d\xa0\x0c\xc18\n\x0f\x9b\x13G%\xb8\xd6\x0c\x87\xc7BQ]Y\xe8\x89;\
+\xc52v,\xc2C\xe5\xc2\xad\x96\xb8j\xbb\x16\xe4\xcd\xed\xd5Z\r!DO\x9cb\x99\xc8\
+\x87\xc8w@\xc9\x8182\xdeMDy\x0bKm\xad\x82-N\x1c\x88\x87>L\x85.\x91\xa7\x07\
+\xe2\xa8\x04W\xdb\xfcx#\x164c\xd1\x17?T\x84R\xd1a\xaa\\\x1c\x88\xef\xe4\x81\
+\xbc%u}c\x93\xd4\x16\xfa\xe2\xa1\x0f\x91\x0f\xc7\'C\x82\x82\xed\x8b\xa3e\xb6\
+\x04y\xf0\x964l5\xb6p\x8a\xa5\x81x\xe8\xc1\x91\xb2\xc7\xb1\'\xcb}\xf1l\t\x8c\
+\xcd\xd5L4[\x02\xa9\xc9\x85G>\x94|\x87\x17OLR\xb0\xea@\x1c\x95\xe0\xeeM@\xfd\
+\xeay3nc\xc7\xa2\\xg\xec\xf4\xd1\x88\xa3\x93\xa5\x03\xf1\x9d\x7f`\x10\xdeN4"\
+5C\xe1\x91\x0f\xc7J\x05\xa6_8q n\xb5\xcc\xa2`P\'\x13\')\xc6\x0b\x86\xc2\x0f\
+\x15\xb3\xcf\xe9\xd3SLDAO\x1c\x19\xe3*c\x07w2\x86\xbex\xe8\xdb\x9ex\xe4\xc3\
+\xa9\xc3E^9s\xaa\'\xbe\xdb\x92\xf5\xc1\x852\x98B\xd0\x13\x1fs\x0c\x0fk\x1b\
+\xcc\xcc-\xd1l\xc5]x\xe8\xc3D\xd1\xe1\xed\xb3\xcf\xe1;\xa6;\x1at\x82\xa7\x8c\
+\xed\xdbFI\xe3v\xe1\xa1\x07B\xb4\xb9\xbb\xfc\x90j\xb5\x8aM\x05\xab\x8b\xf3\
+\x9c=\xf3\x0c\x17^:N\x14z\x84>\x94\xb6\xe7\xbdvj\x82\xe7\x9f}\x9a\xdb3\xb7\
+\xf6\xe1Y?`\x0e\xc6\x13\rA\xc1\xee\xc3}4+\x95\x1a\xb7n\xdf\xa5R\xa9`S\x01*\
+\xa1\xd9\xa8\xf3\xd3\x8d\x9b|y\xf9*\xbf?\xa8\xe1\xbbv\xcffty\xef\xc2\xb9.\
+\x1c\xb5\xa7\x1f\xe8\x85\x17\xac\xa24\x96\xe1A\xc1\xd2n\xb5\x98\xbd\xb7\xc0\
+\xfd\xf9\x05R\x11w\xad\xa9M\x13\x16\xe7\x1f\xf0\xc5\xd7\x97\xf8\xfc\xf2/\xac\
+\xd6Ev\xf3\x01\xbc;}\x92\xa7\x8e\x1c\xde\x87gy\xc0\xd8\x9e8Z\x12z\x96\xc9\
+\xc0\xc15)\xcb\x955\xee\xdc\x9f\xa7\xb1\xf9h`zU\xa2\xc5\xb5kW\xb9\xf8\xd9W|{\
+\xe3>\xad\xc4\xf0\xf21\x9f\x0bo\xbd\xb9\x0fG\'8\xef\x7fS\xb1?\xd6\x8fv\xe1\
+\x05#9>\x19\xa0D\x9b\xda\xfa\x06I\xbb9\xb0\xb0\xf4\n5\'\x15\x9c?7\xcd\xa7\
+\x1f\xbc\x83\xd6\x86\x0f?\xfe\x04\xd9\xda\x04\x9d\xcd\xf1\xb4\xb5={8l\xcaz-&\
+nma\xd2\xc1U\xed\xa08\xb7*\xe1\xe7\xebW\xf8\xe8\xd7\xeb\xbc~\xfe\r|\x17\xa4\
+\xdemV<m\xbaq\xab\x12\x94\x8cQ9\xeay?|\xef\x86\x8b\xeb\r\xae|\x7fi\xe7\xc9w\
+\xdf\x0bl\xfe\x06rT|\xef\x9a\xff\xf7\xfa\xff\x02\x1b\x95\x05yYu\xd8\x0c\x00\
+\x00\x00\x00IEND\xaeB`\x82'
+
+
+tick_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x03\
+\x02IDATx\x9c\xe5\x97?HzQ\x14\xc7\xbf\xf7\xf6\x93\x1e\x0f\xc4G\x7f\x96\x86\
+\x04\xdb\x0b\x1c\x9a\xda\x83\x94H\xa1(!\x90\x8c\x0c\x87 r\x89p\n\xc1\xc9%\
+\x08\x8apI4\xa8\x1e\x91$\xe5\xd0\xd4\x14\x15A A\x04\r.\x12TC\x96\x10t~\x93\
+\xef\xa7\xe9\xf5O\xbfg\x0e\x1d\xb8\xf0x\xf7\x9c\xf3\xf9r\xee\xb9\xf7\xdd\xc7\
+\x14EA+\x8d\xb7\x94\xde\n\x01\xc1`\x90\x86\x87\x87imm\x8d\x00\xe0\xcfO\x81#\
+\x91\x08\xed\xed\xed!\x10\x08\xe0\xe9\xe9\t\x16\x8b\x05?"@UU:;;C \x10@:\x9d\
+\x06\x11\x01\x00\xde\xde\xde\x9a/@UUJ$\x12\xd8\xd8\xd8\xd0\x80\x05\xbb\xbf\
+\xbf\x07\xd0\xc4\x1e\xa8\x06\x07\x00I\x92\x9a\' \x16\x8b\xd1\xce\xce\x8e\x10\
+>00\x00\xa7\xd3\t\xa0\tK\x10\x8b\xc5hss\x13\x87\x87\x87\xf8\xfc\xfc,\x9b\xef\
+\xe9\xe9\xc1\xfc\xfc<|>\x1f\x03jT`\x7f\x7f\x9f\xf4\x86\xfb\xfd~,//\xb3\xc2;\
+\xf6\xf5$TU\x95nnn\x90J\xa5`0\x18055\x05\xaf\xd7\xcb\xca\xb25\x087\x1a\x8dXY\
+YA(\x14*\xcd\xa5(\x8a6\x92\xc9$\xb9\\.2\x1a\x8d\x04\x80\x00\xd0\xd0\xd0\x10\
+\xa5R)*\xf6\xfb:\x92\xc9$\x8d\x8d\x8d\x11\xe7\\\x8b+\x1e\xb2,\xd3\xe2\xe2"\
+\x9d\x9e\x9e\x96\xe5\xd1\x1e\x8e\x8f\x8f+&\xe9\xea\xea\xa2x<.\x14P\x0b.I\x92\
+\x10\xae(\xca\xbf\x1e\xb8\xbc\xbc\xc4\xd1\xd1QY\xf9^__\xf1\xfc\xfc\\\xb1\xec\
+\xaa\xaa\xd2\xc1\xc1\x81\xb0\xec\x9cs\xd8l6\x8c\x8c\x8c\xc0\xe9tV\\FM\xc0\
+\xc5\xc5\x05>>>\xca\x1c\xf2\xf9<\x1e\x1e\x1e*\xc2\x13\x89\x04\xa2\xd1\xa8\
+\x10>::\n\x8f\xc7\x83\xf1\xf1qa\x0fi\x02\xf2\xf9\xbc\xc8\x07www\x15\xe1\xa2}\
+\xce\x18\x83\xddn\xc7\xdc\xdc\x1c\\.W\xd5\x06\xae\xeb \xcaf\xb3\xda\x96\xdc\
+\xde\xde\xa6\xad\xad-!\x1c\x00\xacV+\xdcnwM8P\xe7A\x94N\xa7\xd9\xf5\xf55\x85\
+\xc3a\n\x06\x838??\xafX\xf6\x02|ii\t3335\xe1u\x0bxyy\xa1P(\x04\xce9\xb2\xd9\
+\xac\xd0\xcfj\xb5\xc2\xef\xf7k\xa7\x9cn\x02\x00\xe0\xf1\xf1Q8\xc79\xc7\xe0\
+\xe0 \x16\x16\x16\x1a\x82\x97\x08hkkk$\xae\x04^\xe8\xf6\xe9\xe9\xe9\x86\xe0%\
+\x02\xfa\xfa\xfa\xbe\r\xaf\xa7\xdb\x859\n\x0f&\x93\t\x8c\xd5\x9fC\x0fx\x89\
+\x00\xb3\xd9\x0cY\x96\xeb\n2\x18\x0c\xba\xc0\x81\xa2%\xe8\xee\xeeFgg\'r\xb9\
+\\\xd5\x00Y\x96\xe1\xf1x`\xb3\xd9099\xf9_p\xa0\xa8\x02\x92$\xa1\xb7\xb7\xb7&\
+\xdc\xeb\xf5\xc2\xe1p\xe8\x02\x07\x8a*011\xc1\xd6\xd7\xd7\xe9\xfd\xfd\x1dWWW\
+\xda\xed\xb5`\x1d\x1d\x1dp\xbb\xdd\xb0\xdb\xed\xc2\x0f\xcbw\xac\xecB\x12\x89\
+D(\x1a\x8d\xe2\xe4\xe4\x04\xb9\\\x0e\x8c1X,\x16\xf8|>\xac\xae\xae\xea\x06\
+\x16\n\x00\x80\xdd\xdd]\xba\xbd\xbdE&\x93A{{;\xfa\xfb\xfb1;;\xab;\\(\xe0\'\
+\xed\xf7\xfd\x9c~\xb5\xbf\x8a\xf3q\xb2q\x86\xa0|\x00\x00\x00\x00IEND\xaeB`\
+\x82'
+
+
+cross_png = \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
+\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x03\
+\x9fIDATx\x9c\xc5\x97OH*_\x14\xc7\xbfW~\x82\x8c\x19Sh\xc2\x80\x8b\xfe\x10\
+\x04A\x90P.\x84(r\x13ER\x14\x11\x18A\x11\x14\xba0\n\x83B\xa1\x90\\\x88\xa5\
+\x05\xe5B\x11%7\x89\x14B\x08\xc2\xac\xda\xb6\x88V\xd12\xb0M\xb4jWx\xde\xe2a<\
+_3\xe3(\xef\xf7\xde\x81\xb3P\xef9\xdf\xcf\x9d+\xdfs\x87\xf1<\x8f\x7f\x19\x9a\
+\x7f\xaa\xfe7\x01\x82\xc1 \xcd\xcf\xcfS<\x1e\xa7_\xbfg\xf5\x8e \x9dNSKK\x0bf\
+ffX3\xc2\xc9d\x92r\xb9\x1c\x8a\xc5"\xde\xde\xde044\x84\xbd\xbd=,--1Y\x80t:M\
+\x8c1\xdc\xde\xde\xe2\xea\xea\n\x13\x13\x13\x98\x9a\x9aj\x18\xe2\xf0\xf0\x90\
+\xe2\xf18\xee\xef\xefA\xf4s\xe3Z\xad\x16\xa3\xa3\xa3\xb0\xdb\xed\xb0\xdb\xed\
+\x00\xcf\xf35y||L\xfd\xfd\xfd\xd4\xd3\xd3C\x1c\xc7\x11\x00\xe28\x8e\xbc^/\
+\x89\xa2H\xbf\xaf\x97\xcaR\xa9D>\x9f\x8f\xccf3\x01\x90L\x8e\xe3(\x18\x0cRM\
+\xe1\xc9\xc9\t\x19\x8dF\xd9\x025\x10\x85B\x81fggI\xa7\xd3\xc9\x8a\x03 \xa3\
+\xd1H\x89D\xa2\x16\xe0\xe2\xe2\x82:::\x14\xa9\x95 \xb2\xd9,\xd9l6\xd2h4\x8a\
+\xe2f\xb3\x99vvv\x88\xe7\xf9\xefG077\xa7Xl0\x18(\x14\n}\x038;;\xa3\x81\x81\
+\x01\xc5Z\x00\xd4\xd5\xd5E\x91H\xe4\xab\xfe\x1b@*\x95\x92=\x86jZ,\x16J&\x93\
+\xc4\xf3<DQ\xa4P(D\x82 (\xd6h4\x1a\xb2\xd9l\x94\xc9dj\xe0%\xcf\xb1\xdeS\x00@\
+V\xab\x95\xb2\xd9,y<\x1e2\x18\x0c\x8ak\xb5Z-9\x9dN*\x14\n\xdf\x9e\x9c$@*\x95\
+\xaa\xbb#\xc6\x18uvv\x92V\xabU\\\xc7q\x1cy<\x1e*\x16\x8b\x92\xff\x1bY#ZYY\
+\xa1X,\x86\x8f\x8f\x0f\xc9\xdf\xd5D{{;\x96\x97\x97199)\xeb!\xb2V\xecp8~\x1aE\
+\x93!\x08\x02vww\x91L&\x99\x92\x81\xc9\x02,,,0\x97\xcb\x05A\x10\x9a\x12\xdf\
+\xda\xda\xc2\xc1\xc1A]\xe7T\x1cF\x9b\x9b\x9b\xcc\xe5rA\xa7\xd35,\xbe\xbf\xbf\
+\xaf\xca\xb6\xebN\xc3\xf1\xf1q\x0c\x0f\x0f\xab\x12\xd7h4\x98\x9e\x9eV-\xae\n\
+\xe0\xe1\xe1\x01OOO\xaa\x9aU*\x15\\__\xc3\xef\xf7S\xfd\xd5*\x00\xfc~?\x85\
+\xc3a\x94\xcbe\xb5\xfdP.\x97\x11\x0e\x87\xd5C\xc8\r\x95H$R\xd7\x0b\x94R\x10\
+\x84\x1a\xcb\x95\xcb\xffE\xbc\x11\x88\x9a\x0f\xa2(R \x10\xf8#\xe2j!j\xc4\xbd\
+^\xef\xd7%D)M&\x13\x99L&\xd5\x10f\xb3\x99|>\x9f\xe4\x18\x07\xcf\xf3\xb8\xb9\
+\xb9\xa1\xb5\xb55U\xe2\xd5\x1d\x05\x02\x01U\xeb\xab\xa9\xd7\xeb)\x16\x8bI\
+\x03\xb8\xdd\xee\xba\x97\x88\xdf\x1f\xa7(\x8a\xe4\xf1x\xea\x0e\xa3j\xf6\xf6\
+\xf6R.\x97\x93\x06\x88F\xa3\xa4\xd7\xeb\x15\x1b\xf4\xf5\xf5Q4\x1a\xadiP,\x16\
+\xc9\xe9t*\xc23\xc6hdd\xe4\xeb\xfe \tpzzJ\xad\xad\xad\xb2M\x06\x07\x07)\x9b\
+\xcdJ6\x90:>\xc6\x181\xc6\x08\x00uwwK\xee\xbc\x9a\xff\x01\xc0\xf3\xf33\xde\
+\xdf\xdf!\x15\x16\x8b\x05n\xb7\x1b\x1b\x1b\x1b\x92\xf6\xba\xb8\xb8\xc8\xf2\
+\xf9<\xb5\xb5\xb5!\x93\xc9\xe0\xf3\xf3\x13ccc\xd0\xe9tx}}\x85\xc3\xe1\xc0\
+\xea\xea\xaa\xac5\xb3\xeae2\x91H\xa0T*\xa1R\xa9|\xc14:X\xce\xcf\xcf\x89\x88\
+\xb0\xbe\xbe\xaez\x16|]H.//\xe9\xe5\xe5\x05\x8f\x8f\x8f8::\x02\x00loo#\x1a\
+\x8d6\xf5F\xd40@5\xf2\xf9<\xdd\xdd\xdd\x01\x00\xacVk\xd3\xafdM\x03\xfc\xed\
+\xf8\x01\xe9\t\x94\x8c\xa7\xf9\xf9<\x00\x00\x00\x00IEND\xaeB`\x82'
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import images
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1,
+ style=wx.NO_FULL_REPAINT_ON_RESIZE)
+ self.log = log
+
+ b = wx.Button(self, 10, "Default Button", (20, 20))
+ self.Bind(wx.EVT_BUTTON, self.OnClick, b)
+ b.SetDefault()
+ b.SetSize(b.GetBestSize())
+
+ b = wx.Button(self, 20, "HELLO AGAIN!", (20, 80), (120, 45))
+ self.Bind(wx.EVT_BUTTON, self.OnClick, b)
+ b.SetToolTipString("This is a Hello button...")
+
+ if 0: # a test case for catching wx.PyAssertionError
+
+ #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_SUPPRESS)
+ #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_EXCEPTION)
+ #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_DIALOG)
+ #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_EXCEPTION | wx.PYAPP_ASSERT_DIALOG)
+
+ try:
+ bmp = wx.Bitmap("nosuchfile.bmp", wx.BITMAP_TYPE_BMP)
+ mask = wx.MaskColour(bmp, wx.BLUE)
+ except wx.PyAssertionError:
+ self.log.write("Caught wx.PyAssertionError! I will fix the problem.\n")
+ bmp = images.getTest2Bitmap()
+ mask = wx.MaskColour(bmp, wx.BLUE)
+ else:
+ bmp = images.getTest2Bitmap()
+ mask = wx.MaskColour(bmp, wx.BLUE)
+
+ bmp.SetMask(mask)
+ wx.BitmapButton(self, 30, bmp, (160, 20),
+ (bmp.GetWidth()+10, bmp.GetHeight()+10))
+ self.Bind(wx.EVT_BUTTON, self.OnClick, id=30)
+
+
+ def OnClick(self, event):
+ self.log.write("Click! (%d)\n" % event.GetId())
+ ##wxLogDebug("debug message")
+
+
+## wxLog_SetLogLevel(wxLOG_Message) # ignore everything above wxLOG_Message
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """<html><body>
+<h2>Button</h2>
+
+A button is a control that contains a text string or a bitmap and can be
+placed on nearly any kind of window.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+#----------------------------------------------------------------------------
+# Name: wxCalendar.py
+# Purpose: Calendar control display testing on panel for wxPython demo
+#
+# Author: Lorne White (email: lwhite1@planet.eon.net)
+#
+# Version 0.9
+# Date: Feb 26, 2001
+# Licence: wxWindows license
+#----------------------------------------------------------------------------
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o Some updating of the library itself will be needed for this demo to work
+# correctly.
+#
+# 11/26/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Problems have changed a little. The print dialog requires
+# a wx.Size to work with the calendar library. wx.core doesn't
+# approve, though, so we get deprecation warnings.
+# o Ugh. AFter updating to the Bind() method, things lock up
+# on various control clicks. Will have to debug. Only seems
+# to happen on windows with calendar controls, though.
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Lockup issue clarification: it appears that the spinner is
+# the culprit.
+#
+# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o New Bind() method now fully supported.
+#
+# 12/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxCalendar renamed to Calendar
+# o Got rid of unneeded IDs where Bind() could figure it
+# out for itself.
+#
+
+import os
+
+import wx
+import wx.lib.calendar
+
+import images
+
+
+# highlighted days in month
+
+test_days ={ 0: [],
+ 1: [3, 7, 9, 21],
+ 2: [2, 10, 4, 9],
+ 3: [4, 20, 29],
+ 4: [1, 12, 22],
+ 5: [2, 10, 15],
+ 6: [4, 8, 17],
+ 7: [6, 7, 8],
+ 8: [5, 10, 20],
+ 9: [1, 2, 5, 29],
+ 10: [2, 4, 6, 22],
+ 11: [6, 9, 12, 28, 29],
+ 12: [8, 9, 10, 11, 20] }
+
+# test of full window calendar control functions
+
+def GetMonthList():
+
+ monthlist = []
+
+ for i in range(13):
+ name = wx.lib.calendar.Month[i]
+
+ if name != None:
+ monthlist.append(name)
+
+ return monthlist
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log, frame):
+ wx.Panel.__init__(self, parent, -1)
+
+ self.log = log
+ self.frame = frame
+
+ self.calend = wx.lib.calendar.Calendar(self, -1, (100, 50), (200, 180))
+
+# start_month = 2 # preselect the date for calendar
+# start_year = 2001
+
+ start_month = self.calend.GetMonth() # get the current month & year
+ start_year = self.calend.GetYear()
+
+ # month list from DateTime module
+
+ monthlist = GetMonthList()
+
+ self.date = wx.ComboBox(self, -1, "",
+ (100, 20), (90, -1),
+ monthlist, wx.CB_DROPDOWN)
+
+ self.date.SetSelection(start_month-1)
+ self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, self.date)
+
+ # set start month and year
+
+ self.calend.SetMonth(start_month)
+ self.calend.SetYear(start_year)
+
+ # set attributes of calendar
+
+ self.calend.hide_title = True
+ self.calend.HideGrid()
+ self.calend.SetWeekColor('WHITE', 'BLACK')
+
+ # display routine
+
+ self.ResetDisplay()
+
+ # mouse click event
+ self.Bind(wx.lib.calendar.EVT_CALENDAR, self.MouseClick, self.calend)
+
+ # scroll bar for month selection
+ self.scroll = wx.ScrollBar(self, -1, (100, 240), (200, 20), wx.SB_HORIZONTAL)
+ self.scroll.SetScrollbar(start_month-1, 1, 12, 1, True)
+ self.Bind(wx.EVT_COMMAND_SCROLL, self.Scroll, self.scroll)
+
+ # spin control for year selection
+
+ self.dtext = wx.TextCtrl(self, -1, str(start_year), (200, 20), (60, -1))
+ h = self.dtext.GetSize().height
+
+ self.spin = wx.SpinButton(self, -1, (270, 20), (h*2, h))
+ self.spin.SetRange(1980, 2010)
+ self.spin.SetValue(start_year)
+ self.Bind(wx.EVT_SPIN, self.OnSpin, self.spin)
+
+ # button for calendar dialog test
+
+ wx.StaticText(self, -1, "Test Calendar Dialog", (350, 50), (150, -1))
+
+ bmp = images.getCalendarBitmap()
+ self.but1 = wx.BitmapButton(self, -1, bmp, (380, 80))
+ self.Bind(wx.EVT_BUTTON, self.TestDlg, self.but1)
+
+ # button for calendar window test
+
+ wx.StaticText(self, -1, "Test Calendar Window", (350, 150), (150, -1))
+
+ self.but2 = wx.BitmapButton(self, -1, bmp, (380, 180))
+ self.Bind(wx.EVT_BUTTON, self.TestFrame, self.but2)
+
+ wx.StaticText(self, -1, "Test Calendar Print", (350, 250), (150, -1))
+
+ self.but3 = wx.BitmapButton(self, -1, bmp, (380, 280))
+ self.Bind(wx.EVT_BUTTON, self.OnPreview, self.but3)
+
+ # calendar dialog
+
+ def TestDlg(self, event): # test the date dialog
+ dlg = wx.lib.calendar.CalenDlg(self)
+ dlg.Centre()
+
+ if dlg.ShowModal() == wx.ID_OK:
+ result = dlg.result
+ day = result[1]
+ month = result[2]
+ year = result[3]
+ new_date = str(month) + '/'+ str(day) + '/'+ str(year)
+ self.log.WriteText('Date Selected: %s\n' % new_date)
+ else:
+ self.log.WriteText('No Date Selected')
+
+ # calendar window test
+
+ def TestFrame(self, event):
+ frame = CalendFrame(self, -1, "Test Calendar", self.log)
+ frame.Show(True)
+ return True
+
+ # calendar print preview
+
+ def OnPreview(self, event):
+ month = self.calend.GetMonth()
+ year = self.calend.GetYear()
+
+ prt = PrintCalend(self.frame, month, year)
+ prt.Preview()
+
+ # month and year control events
+
+ def OnSpin(self, event):
+ year = event.GetPosition()
+ self.dtext.SetValue(str(year))
+ self.calend.SetYear(year)
+ self.calend.Refresh()
+
+ def EvtComboBox(self, event):
+ name = event.GetString()
+ self.log.WriteText('EvtComboBox: %s\n' % name)
+ monthval = self.date.FindString(name)
+ self.scroll.SetScrollbar(monthval, 1, 12, 1, True)
+
+ self.calend.SetMonth(monthval+1)
+ self.ResetDisplay()
+
+ def Scroll(self, event):
+ value = self.scroll.GetThumbPosition()
+ monthval = int(value)+1
+ self.calend.SetMonth(monthval)
+ self.ResetDisplay()
+ self.log.WriteText('Month: %s\n' % value)
+
+ name = wx.lib.calendar.Month[monthval]
+ self.date.SetValue(name)
+
+ # log mouse events
+
+ def MouseClick(self, evt):
+ text = '%s CLICK %02d/%02d/%d' % (evt.click, evt.day, evt.month, evt.year) # format date
+ self.log.WriteText('Date Selected: ' + text + '\n')
+
+
+ # set the highlighted days for the calendar
+
+ def ResetDisplay(self):
+ month = self.calend.GetMonth()
+
+ try:
+ set_days = test_days[month]
+ except:
+ set_days = [1, 5, 12]
+
+ self.calend.AddSelect([4, 11], 'BLUE', 'WHITE')
+ self.calend.SetSelDay(set_days)
+ self.calend.Refresh()
+
+ # increment and decrement toolbar controls
+
+ def OnIncYear(self, event):
+ self.calend.IncYear()
+ self.ResetDisplay()
+
+ def OnDecYear(self, event):
+ self.calend.DecYear()
+ self.ResetDisplay()
+
+ def OnIncMonth(self, event):
+ self.calend.IncMonth()
+ self.ResetDisplay()
+
+ def OnDecMonth(self, event):
+ self.calend.DecMonth()
+ self.ResetDisplay()
+
+ def OnCurrent(self, event):
+ self.calend.SetCurrentDay()
+ self.ResetDisplay()
+
+# test of full window calendar control functions
+
+class CalendFrame(wx.Frame):
+ def __init__(self, parent, id, title, log):
+ wx.Frame.__init__(self, parent, id, title, size=(400, 400),
+ style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
+
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+ self.log = log
+ self.CreateStatusBar()
+ self.mainmenu = wx.MenuBar()
+ menu = wx.Menu()
+
+ menu = self.MakeFileMenu()
+ self.mainmenu.Append(menu, '&File')
+
+ self.MakeToolMenu() # toolbar
+
+ self.SetMenuBar(self.mainmenu)
+ self.calend = wx.lib.calendar.Calendar(self, -1)
+ self.calend.SetCurrentDay()
+ self.calend.grid_color = 'BLUE'
+ self.calend.SetBusType()
+# self.calend.ShowWeekEnd()
+
+ self.ResetDisplay()
+
+ self.Bind(wx.lib.calendar.EVT_CALENDAR, self.MouseClick, self.calend)
+
+ def MouseClick(self, evt):
+ text = '%s CLICK %02d/%02d/%d' % (evt.click, evt.day, evt.month, evt.year) # format date
+ self.log.WriteText('Date Selected: ' + text + '\n')
+
+ def OnCloseWindow(self, event):
+ self.Destroy()
+
+ def ResetDisplay(self):
+ month = self.calend.GetMonth()
+
+ try:
+ set_days = test_days[month]
+ except:
+ set_days = [1, 5, 12]
+
+ self.calend.AddSelect([2, 16], 'GREEN', 'WHITE')
+
+ self.calend.SetSelDay(set_days)
+ self.calend.Refresh()
+
+ def OnIncYear(self, event):
+ self.calend.IncYear()
+ self.ResetDisplay()
+
+ def OnDecYear(self, event):
+ self.calend.DecYear()
+ self.ResetDisplay()
+
+ def OnIncMonth(self, event):
+ self.calend.IncMonth()
+ self.ResetDisplay()
+
+ def OnDecMonth(self, event):
+ self.calend.DecMonth()
+ self.ResetDisplay()
+
+ def OnCurrent(self, event):
+ self.calend.SetCurrentDay()
+ self.ResetDisplay()
+
+ def MakeFileMenu(self):
+ menu = wx.Menu()
+
+ mID = wx.NewId()
+ menu.Append(mID, 'Decrement', 'Next')
+ self.Bind(wx.EVT_MENU, self.OnDecMonth, id=mID)
+
+ mID = wx.NewId()
+ menu.Append(mID, 'Increment', 'Dec')
+ self.Bind(wx.EVT_MENU, self.OnIncMonth, id=mID)
+
+ menu.AppendSeparator()
+
+ mID = wx.NewId()
+ menu.Append(mID, 'E&xit', 'Exit')
+ self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=mID)
+
+ return menu
+
+ def MakeToolMenu(self):
+ tb = self.CreateToolBar(wx.TB_HORIZONTAL|wx.NO_BORDER)
+
+ mID = wx.NewId()
+ SetToolPath(self, tb, mID, images.getDbDecBitmap(), 'Dec Year')
+ self.Bind(wx.EVT_TOOL, self.OnDecYear, id=mID)
+
+ mID = wx.NewId()
+ SetToolPath(self, tb, mID, images.getDecBitmap(), 'Dec Month')
+ self.Bind(wx.EVT_TOOL, self.OnDecMonth, id=mID)
+
+ mID = wx.NewId()
+ SetToolPath(self, tb, mID, images.getPtBitmap(), 'Current Month')
+ self.Bind(wx.EVT_TOOL, self.OnCurrent, id=mID)
+
+ mID = wx.NewId()
+ SetToolPath(self, tb, mID, images.getIncBitmap(), 'Inc Month')
+ self.Bind(wx.EVT_TOOL, self.OnIncMonth, id=mID)
+
+ mID = wx.NewId()
+ SetToolPath(self, tb, mID, images.getDbIncBitmap(), 'Inc Year')
+ self.Bind(wx.EVT_TOOL, self.OnIncYear, id=mID)
+
+ tb.Realize()
+
+#---------------------------------------------------------------------------
+
+# example class for printing/previewing calendars
+
+class PrintCalend:
+ def __init__(self, parent, month, year):
+ self.frame = parent
+ self.month = month
+ self.year = year
+
+ self.SetParms()
+ self.SetCal()
+ self.printData = wx.PrintData()
+
+ def SetCal(self):
+ self.grid_color = 'BLUE'
+ self.back_color = 'WHITE'
+ self.sel_color = 'RED'
+ self.high_color = 'LIGHT BLUE'
+ self.font = wx.SWISS
+ self.bold = wx.NORMAL
+
+ self.sel_key = None # last used by
+ self.sel_lst = [] # highlighted selected days
+
+ self.size = None
+ self.hide_title = False
+ self.hide_grid = False
+ self.set_day = None
+
+ def SetParms(self):
+ self.ymax = 1
+ self.xmax = 1
+ self.page = 1
+ self.total_pg = 1
+
+ self.preview = None
+ self.scale = 1.0
+
+ self.pagew = 8.5
+ self.pageh = 11.0
+
+ self.txt_marg = 0.1
+ self.lf_marg = 0
+ self.top_marg = 0
+
+ self.page = 0
+
+ def SetDates(self, month, year):
+ self.month = month
+ self.year = year
+
+ def SetStyleDef(self, desc):
+ self.style = desc
+
+ def SetCopies(self, copies): # number of copies of label
+ self.copies = copies
+
+ def SetStart(self, start): # start position of label
+ self.start = start
+
+ def Preview(self):
+ printout = SetPrintout(self)
+ printout2 = SetPrintout(self)
+ self.preview = wx.PrintPreview(printout, printout2, self.printData)
+
+ if not self.preview.Ok():
+ wx.MessageBox("There was a problem printing!", "Printing", wx.OK)
+ return
+
+ self.preview.SetZoom(60) # initial zoom value
+
+ frame = wx.PreviewFrame(self.preview, self.frame, "Print preview")
+
+ frame.Initialize()
+ frame.SetPosition(self.frame.GetPosition())
+ frame.SetSize(self.frame.GetSize())
+ frame.Show(True)
+
+ def Print(self):
+ pdd = wx.PrintDialogData()
+ pdd.SetPrintData(self.printData)
+ printer = wx.Printer(pdd)
+ printout = SetPrintout(self)
+ frame = wx.Frame(None, -1, "Test")
+
+ if not printer.Print(frame, printout):
+ wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK)
+ else:
+ self.printData = printer.GetPrintDialogData().GetPrintData()
+
+ printout.Destroy()
+
+ def DoDrawing(self, DC):
+ size = DC.GetSize()
+ DC.BeginDrawing()
+
+ cal = wx.lib.calendar.PrtCalDraw(self)
+
+ if self.preview is None:
+ cal.SetPSize(size[0]/self.pagew, size[1]/self.pageh)
+ cal.SetPreview(False)
+
+ else:
+ if self.preview == 1:
+ cal.SetPSize(size[0]/self.pagew, size[1]/self.pageh)
+ else:
+ cal.SetPSize(self.pwidth, self.pheight)
+
+ cal.SetPreview(self.preview)
+
+ cal.hide_title = self.hide_title # set the calendar parameters
+ cal.hide_grid = self.hide_grid
+
+ cal.grid_color = self.grid_color
+ cal.high_color = self.high_color
+ cal.back_color = self.back_color
+ cal.outer_border = False
+ cal.font = self.font
+ cal.bold = self.bold
+
+ cal_size = (3.0, 3.0)
+ cal.SetSize(cal_size)
+
+ year, month = self.year, self.month
+
+ x = 0.5
+ for i in range(2):
+ y = 0.5
+
+ for j in range(3):
+ cal.SetCal(year, month) # current month
+ cal.SetPos(x, y)
+
+ try:
+ set_days = test_days[month]
+ except:
+ set_days = [1, 5, 12]
+
+ cal.AddSelect([2, 16], 'GREEN', 'WHITE')
+
+ cal.DrawCal(DC, set_days)
+
+ year, month = self.IncMonth(year, month)
+ y = y + 3.5
+
+ x = x + 4.0 # next column
+
+ DC.EndDrawing()
+
+ self.ymax = DC.MaxY()
+ self.xmax = DC.MaxX()
+
+ def IncMonth(self, year, month): # next month
+ month = month + 1
+
+ if month > 12:
+ month = 1
+ year = year + 1
+
+ return year, month
+
+ def GetTotalPages(self):
+ self.pg_cnt = 1
+ return self.pg_cnt
+
+ def SetPage(self, page):
+ self.page = page
+
+ def SetPageSize(self, width, height):
+ self.pwidth, self.pheight = width, height
+
+ def SetTotalSize(self, width, height):
+ self.ptwidth, self.ptheight = width, height
+
+ def SetPreview(self, preview, scale):
+ self.preview = preview
+ self.scale = scale
+
+ def SetTotalSize(self, width, height):
+ self.ptwidth = width
+ self.ptheight = height
+
+def SetToolPath(self, tb, id, bmp, title):
+ tb.AddSimpleTool(id, bmp, title, title)
+
+class SetPrintout(wx.Printout):
+ def __init__(self, canvas):
+ wx.Printout.__init__(self)
+ self.canvas = canvas
+ self.end_pg = 1
+
+ def OnBeginDocument(self, start, end):
+ return self.base_OnBeginDocument(start, end)
+
+ def OnEndDocument(self):
+ self.base_OnEndDocument()
+
+ def HasPage(self, page):
+ if page <= self.end_pg:
+ return True
+ else:
+ return False
+
+ def GetPageInfo(self):
+ self.end_pg = self.canvas.GetTotalPages()
+ str_pg = 1
+
+ try:
+ end_pg = self.end_pg
+ except:
+ end_pg = 1
+
+ return (str_pg, end_pg, str_pg, end_pg)
+
+ def OnPreparePrinting(self):
+ self.base_OnPreparePrinting()
+
+ def OnBeginPrinting(self):
+ dc = self.GetDC()
+
+ self.preview = self.IsPreview()
+
+ if (self.preview):
+ self.pixelsPerInch = self.GetPPIScreen()
+ else:
+ self.pixelsPerInch = self.GetPPIPrinter()
+
+ (w, h) = dc.GetSize()
+ scaleX = float(w) / 1000
+ scaleY = float(h) / 1000
+ self.printUserScale = min(scaleX, scaleY)
+
+ self.base_OnBeginPrinting()
+
+ def GetSize(self):
+ self.psizew, self.psizeh = self.GetPPIPrinter()
+ return self.psizew, self.psizeh
+
+ def GetTotalSize(self):
+ self.ptsizew, self.ptsizeh = self.GetPageSizePixels()
+ return self.ptsizew, self.ptsizeh
+
+ def OnPrintPage(self, page):
+ dc = self.GetDC()
+ (w, h) = dc.GetSize()
+ scaleX = float(w) / 1000
+ scaleY = float(h) / 1000
+ self.printUserScale = min(scaleX, scaleY)
+ dc.SetUserScale(self.printUserScale, self.printUserScale)
+
+ self.preview = self.IsPreview()
+
+ self.canvas.SetPreview(self.preview, self.printUserScale)
+ self.canvas.SetPage(page)
+
+ self.ptsizew, self.ptsizeh = self.GetPageSizePixels()
+ self.canvas.SetTotalSize(self.ptsizew, self.ptsizeh)
+
+ self.psizew, self.psizeh = self.GetPPIPrinter()
+ self.canvas.SetPageSize(self.psizew, self.psizeh)
+
+ self.canvas.DoDrawing(dc)
+ return True
+
+class MyApp(wx.App):
+ def OnInit(self):
+ frame = CalendFrame(None, -1, "Test Calendar", log)
+ frame.Show(True)
+ self.SetTopWindow(frame)
+ return True
+
+#---------------------------------------------------------------------------
+
+def MessageDlg(self, message, type = 'Message'):
+ dlg = wx.MessageDialog(self, message, type, wx.OK | wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log, frame)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This control provides a Calendar control class for displaying and selecting dates.
+In addition, the class is extended and can be used for printing/previewing.
+
+Additional features include weekend highlighting and business type Monday-Sunday
+format.
+
+See example for various methods used to set display month, year, and highlighted
+dates (different font and background colours).
+
+by Lorne White
+
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import wx.lib.calendar as calendar
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, ID, log):
+ wx.Panel.__init__(self, parent, ID)
+ self.log = log
+
+ cal = calendar.CalendarCtrl(self, -1, wx.DateTime_Now(), pos = (25,50),
+ style = calendar.CAL_SHOW_HOLIDAYS
+ | calendar.CAL_SUNDAY_FIRST
+ | calendar.CAL_SEQUENTIAL_MONTH_SELECTION
+ )
+
+ self.Bind(calendar.EVT_CALENDAR, self.OnCalSelected, id=cal.GetId())
+
+ b = wx.Button(self, -1, "Destroy the Calendar", pos = (250, 50))
+ self.Bind(wx.EVT_BUTTON, self.OnButton, id= b.GetId())
+ self.cal = cal
+
+ # Set up control to display a set of holidays:
+ self.Bind(calendar.EVT_CALENDAR_MONTH, self.OnChangeMonth, id=cal.GetId())
+ self.holidays = [(1,1), (10,31), (12,25) ] # (these don't move around)
+ self.OnChangeMonth()
+
+ def OnButton(self, evt):
+ self.cal.Destroy()
+ self.cal = None
+
+ def OnCalSelected(self, evt):
+ self.log.write('OnCalSelected: %s\n' % evt.GetDate())
+
+ def OnChangeMonth(self, evt=None):
+ cur_month = self.cal.GetDate().GetMonth() + 1 # convert wxDateTime 0-11 => 1-12
+
+ for month, day in self.holidays:
+ if month == cur_month:
+ self.cal.SetHoliday(day)
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, -1, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+<h2>wxCalendarCtrl</h2>
+
+Yet <i>another</i> calendar control. This one is a wrapper around the C++
+version described in the docs. This one will probably be a bit more efficient
+than the one in wxPython.lib.calendar, but I like a few things about it better,
+so I think both will stay in wxPython.
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestCheckBox(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ wx.StaticText(self, -1, "This example uses the wxCheckBox control.", (10, 10))
+
+ cID = wx.NewId()
+ cb1 = wx.CheckBox(self, cID, " Apples", (65, 40), (150, 20), wx.NO_BORDER)
+ cb2 = wx.CheckBox(self, cID+1, " Oranges", (65, 60), (150, 20), wx.NO_BORDER)
+ cb2.SetValue(True)
+ cb3 = wx.CheckBox(self, cID+2, " Pears", (65, 80), (150, 20), wx.NO_BORDER)
+
+ self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb1)
+ self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb2)
+ self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb3)
+
+ def EvtCheckBox(self, event):
+ self.log.WriteText('EvtCheckBox: %d\n' % event.IsChecked())
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestCheckBox(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+
+
+overview = """\
+A checkbox is a labelled box which is either on (checkmark is visible) or off (no checkmark).
+
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o Why is there a popup menu in this demo?
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
+ 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
+ 'twelve', 'thirteen', 'fourteen']
+
+ wx.StaticText(self, -1, "This example uses the wxCheckListBox control.", (45, 15))
+
+ lb = wx.CheckListBox(self, 60, (80, 50), (80, 120), sampleList)
+ self.Bind(wx.EVT_LISTBOX, self.EvtListBox, id=60)
+ self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, id=60)
+ lb.SetSelection(0)
+ self.lb = lb
+
+ pos = lb.GetPosition().x + lb.GetSize().width + 25
+ btn = wx.Button(self, -1, "Test SetString", (pos, 50))
+ self.Bind(wx.EVT_BUTTON, self.OnTestButton, id=btn.GetId())
+ self.Bind(wx.EVT_RIGHT_UP, self.OnDoPopup)
+
+ def EvtListBox(self, event):
+ self.log.WriteText('EvtListBox: %s\n' % event.GetString())
+
+ def EvtListBoxDClick(self, event):
+ self.log.WriteText('EvtListBoxDClick:\n')
+
+ def OnTestButton(self, evt):
+ self.lb.SetString(4, "FUBAR")
+
+
+ def OnDoPopup(self, evt):
+ menu = wx.Menu()
+ # Make this first item bold
+ item = wx.MenuItem(menu, wx.NewId(), "If supported, this is bold")
+ df = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
+
+ nf = wx.Font(
+ df.GetPointSize(), df.GetFamily(), df.GetStyle(),
+ wx.BOLD, False, df.GetFaceName()
+ )
+
+ item.SetFont(nf)
+ menu.AppendItem(item)
+
+ menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &1"))
+ menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &2"))
+ menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &3"))
+ menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &4"))
+
+ self.PopupMenu(menu, evt.GetPosition())
+ menu.Destroy()
+ evt.Skip()
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+A checklistbox is like a Listbox, but allows items to be checked or unchecked rather
+than relying on extended selection (e.g. shift-select) to select multiple items in
+the list.
+
+This class is currently implemented under Windows and GTK.
+
+This demo shows the basic CheckListBox and how to use the SetString method to change
+labels dynamically.
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestChoice(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
+ 'six', 'seven', 'eight']
+
+ wx.StaticText(self, -1, "This example uses the wxChoice control.", (15, 10))
+ wx.StaticText(self, -1, "Select one:", (15, 50), (75, 20))
+ self.ch = wx.Choice(self, -1, (80, 50), choices = sampleList)
+ self.Bind(wx.EVT_CHOICE, self.EvtChoice, self.ch)
+
+
+ def EvtChoice(self, event):
+ self.log.WriteText('EvtChoice: %s\n' % event.GetString())
+ self.ch.Append("A new item")
+
+ if event.GetString() == 'one':
+ self.log.WriteText('Well done!\n')
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestChoice(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+overview = """
+A Choice control is used to select one of a list of strings. Unlike a listbox,
+only the current selection is visible until the user pulls down the menu of
+choices.
+
+This demo illustrates how to set up the Choice control and how to extract the
+selected choice once it is selected.
+
+Note that the syntax of the constructor is different than the C++ implementation.
+The number of choices and the choice array are consilidated into one python
+<code>list</code>.
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
dc.EndDrawing()
-# On wxGTK there needs to be a panel under wxScrolledWindows if they are
-# going to be in a wxNotebook. And, in the demo, we are.
+# On wxGTK there needs to be a panel under wx.ScrolledWindows if they are
+# going to be in a wxNotebook. And, in this demo, we are.
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ dlg = wx.ColourDialog(frame)
+
+ # Ensure the full colour dialog is displayed,
+ # not the abbreviated version.
+ dlg.GetColourData().SetChooseFull(True)
+
+ if dlg.ShowModal() == wx.ID_OK:
+
+ # If the user selected OK, then the dialog's wx.ColourData will
+ # contain valid information. Fetch the data ...
+ data = dlg.GetColourData()
+
+ # ... then do something with it. The actual colour data will be
+ # returned as a three-tuple (r, g, b) in this particular case.
+ log.WriteText('You selected: %s\n' % str(data.GetColour().Get()))
+
+ # Once the dialog is destroyed, Mr. wx.ColourData is no longer your
+ # friend. Don't use it again!
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class represents the colour chooser dialog.
+
+Use of this dialog is a multi-stage process.
+
+The actual information about how to display the dialog and the colors in the
+dialog's 'registers' are contained in a wx.ColourData instance that is created by
+the dialog at init time. Before displaying the dialog, you may alter these settings
+to suit your needs. In the example, we set the dialog up to show the extended colour
+data selection pane. Otherwise, only the more compact and less extensive colour
+dialog is shown. You may also preset the colour as well as other items.
+
+If the user selects something and selects OK, then the wxColourData instance contains
+the colour data that the user selected. Before destroying the dialog, retrieve the data.
+<b>Do not try to retain the wx.ColourData instance.</b> It will probably not be valid
+after the dialog is destroyed.
+
+Along with he wxColourDialog documentation, see also the wx.ColourData documentation
+for details.
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestComboBox(wx.Panel):
+ def OnSetFocus(self, evt):
+ print "OnSetFocus"
+ evt.Skip()
+
+ def OnKillFocus(self, evt):
+ print "OnKillFocus"
+ evt.Skip()
+
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
+ #'this is a long item that needs a scrollbar...',
+ 'six', 'seven', 'eight']
+
+ wx.StaticText(self, -1, "This example uses the wxComboBox control.", (8, 10))
+ wx.StaticText(self, -1, "Select one:", (15, 50), (75, 18))
+
+ # This combobox is created with a preset list of values.
+ cb = wx.ComboBox(
+ self, 500, "default value", (90, 50),
+ (95, -1), sampleList, wx.CB_DROPDOWN #|wxTE_PROCESS_ENTER
+ )
+
+ ##import win32api, win32con
+ ##win32api.SendMessage(cb.GetHandle(),
+ ## win32con.CB_SETHORIZONTALEXTENT,
+ ## 200, 0)
+
+ self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, cb)
+ self.Bind(wx.EVT_TEXT, self.EvtText, cb)
+ self.Bind(wx.EVT_TEXT_ENTER, self.EvtTextEnter, cb)
+ cb.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
+ cb.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
+
+ # Once the combobox is set up, we append some more data to it.
+ cb.Append("foo", "This is some client data for this item")
+
+ # This combobox is created with no values initially.
+ cb = wx.ComboBox(
+ self, 501, "default value", (90, 80), (95, -1), [], wx.CB_SIMPLE)
+
+ # Here we dynamically add our values to the second combobox.
+ for item in sampleList:
+ cb.Append(item, item.upper())
+
+ self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, cb)
+ self.Bind(wx.EVT_COMBOBOX, self.EvtText, cb)
+
+ # The user selects something, we go here.
+ def EvtComboBox(self, evt):
+ cb = evt.GetEventObject()
+ data = cb.GetClientData(cb.GetSelection())
+ self.log.WriteText('EvtComboBox: %s\nClientData: %s\n' % (evt.GetString(), data))
+
+ if evt.GetString() == 'one':
+ self.log.WriteText("You follow directions well!\n\n")
+
+ # Capture events every time a user hits a key in the text entry field.
+ def EvtText(self, evt):
+ self.log.WriteText('EvtText: %s\n' % evt.GetString())
+
+ # Capture events when the user types something into the control then
+ # hits ENTER.
+ def EvtTextEnter(self, evt):
+ self.log.WriteText('EvtTextEnter: %s' % evt.GetString())
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestComboBox(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+A ComboBox is like a combination of an edit control and a listbox. It can be
+displayed as static list with editable or read-only text field; or a drop-down
+list with text field; or a drop-down list without a text field.
+
+This example shows both a preset ComboBox and one that is dynamically created
+(that is, it is initially empty but then we 'grow' it out of program-supplied
+data). The former is common for read-only controls.
+
+This example also shows the two form factors for the ComboBox. The first is more
+common, and resembles a Choice control. The latter, although less common, shows
+how all the values in the ComboBox can be visible, yet the functionality is the
+same for both.
+
+Finally, this demo shows how event handling can differ. The first ComboBox is set
+up to handle EVT_TEXT_ENTER events, in which text is typed in and then ENTER is
+hit by the user. This allows the user to enter a line of text which can then be
+processed by the program. EVT_TEXT can also be processed, but in that case the
+event is generated every time that the user hits a key in the ComboBox entry field.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+# Create and set a help provider. Normally you would do this in
+# the app's OnInit as it must be done before any SetHelpText calls.
+provider = wx.SimpleHelpProvider()
+wx.HelpProvider_Set(provider)
+
+#---------------------------------------------------------------------------
+
+class TestDialog(wx.Dialog):
+ def __init__(
+ self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition,
+ style=wx.DEFAULT_DIALOG_STYLE
+ ):
+
+ # Instead of calling wxDialog.__init__ we precreate the dialog
+ # so we can set an extra style that must be set before
+ # creation, and then we create the GUI dialog using the Create
+ # method.
+ pre = wx.PreDialog()
+ pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
+ pre.Create(parent, ID, title, pos, size, style)
+
+ # This next step is the most important, it turns this Python
+ # object into the real wrapper of the dialog (instead of pre)
+ # as far as the wxPython extension is concerned.
+ self.this = pre.this
+
+ # Now continue with the normal construction of the dialog
+ # contents
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ label = wx.StaticText(self, -1, "This is a wxDialog")
+ label.SetHelpText("This is the help text for the label")
+ sizer.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ box = wx.BoxSizer(wx.HORIZONTAL)
+
+ label = wx.StaticText(self, -1, "Field #1:")
+ label.SetHelpText("This is the help text for the label")
+ box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ text = wx.TextCtrl(self, -1, "", size=(80,-1))
+ text.SetHelpText("Here's some help text for field #1")
+ box.Add(text, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ sizer.AddSizer(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+
+ box = wx.BoxSizer(wx.HORIZONTAL)
+
+ label = wx.StaticText(self, -1, "Field #2:")
+ label.SetHelpText("This is the help text for the label")
+ box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ text = wx.TextCtrl(self, -1, "", size=(80,-1))
+ text.SetHelpText("Here's some help text for field #2")
+ box.Add(text, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ sizer.AddSizer(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+
+ line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
+ sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
+
+ box = wx.BoxSizer(wx.HORIZONTAL)
+
+ if wx.Platform != "__WXMSW__":
+ btn = wx.ContextHelpButton(self)
+ box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ btn = wx.Button(self, wx.ID_OK, " OK ")
+ btn.SetDefault()
+ btn.SetHelpText("The OK button completes the dialog")
+ box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ btn = wx.Button(self, wx.ID_CANCEL, " Cancel ")
+ btn.SetHelpText("The Cancel button cnacels the dialog. (Cool, huh?)")
+ box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+
+ sizer.Add(box, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+
+ self.SetSizer(sizer)
+ self.SetAutoLayout(True)
+ sizer.Fit(self)
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestDialog(frame, -1, "This is a Dialog", size=(350, 200),
+ #style = wxCAPTION | wxSYSTEM_MENU | wxTHICK_FRAME
+ style = wx.DEFAULT_DIALOG_STYLE
+ )
+ win.CenterOnScreen()
+ val = win.ShowModal()
+
+ if val == wx.ID_OK:
+ log.WriteText("You pressed OK\n")
+ else:
+ log.WriteText("You pressed Cancel\n")
+
+ win.Destroy()
+
+
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+wxPython offers quite a few general purpose dialogs for useful data input from
+the user; they are all based on the wx.Dialog class, which you can also subclass
+to create custom dialogs to suit your needs.
+
+The Dialog class, in addition to dialog-like behaviors, also supports the full
+wxWindows layout featureset, which means that you can incorporate sizers or
+layout constraints as needed to achieve the look and feel desired. It even supports
+context-sensitive help, which is illustrated in this example.
+
+The example is very simple; in real world situations, a dialog that had input
+fields such as this would no doubt be required to deliver those values back to
+the calling function. The Dialog class supports data retrieval in this manner.
+<b>However, the data must be retrieved prior to the dialog being destroyed.</b>
+The example shown here is <i>modal</i>; non-modal dialogs are possible as well.
+
+See the documentation for the <code>Dialog</code> class for more details.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+
+ # In this case we include a "New directory" button.
+ dlg = wx.DirDialog(frame, "Choose a directory:",
+ style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
+
+ # If the user selects OK, then we process the dialog's data.
+ # This is done by getting the path data from the dialog - BEFORE
+ # we destroy it.
+ if dlg.ShowModal() == wx.ID_OK:
+ log.WriteText('You selected: %s\n' % dlg.GetPath())
+
+ # Only destroy a dialog after you're done with it.
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+This class represents the directory chooser dialog. It is used when all you
+need from the user is the name of a directory. Data is retrieved via utility
+methods; see the <code>DirDialog</code> documentation for specifics.
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import images
+
+#----------------------------------------------------------------------
+
+class DragShape:
+ def __init__(self, bmp):
+ self.bmp = bmp
+ self.pos = (0,0)
+ self.shown = True
+ self.text = None
+ self.fullscreen = False
+
+ def HitTest(self, pt):
+ rect = self.GetRect()
+ return rect.InsideXY(pt.x, pt.y)
+
+ def GetRect(self):
+ return wx.Rect(self.pos[0], self.pos[1],
+ self.bmp.GetWidth(), self.bmp.GetHeight())
+
+ def Draw(self, dc, op = wx.COPY):
+ if self.bmp.Ok():
+ memDC = wx.MemoryDC()
+ memDC.SelectObject(self.bmp)
+
+ dc.Blit((self.pos[0], self.pos[1]),
+ (self.bmp.GetWidth(), self.bmp.GetHeight()),
+ memDC, (0, 0), op, True)
+
+ return True
+ else:
+ return False
+
+
+
+#----------------------------------------------------------------------
+
+class DragCanvas(wx.ScrolledWindow):
+ def __init__(self, parent, ID):
+ wx.ScrolledWindow.__init__(self, parent, ID)
+ self.shapes = []
+ self.dragImage = None
+ self.dragShape = None
+ self.hiliteShape = None
+
+ self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
+ self.bg_bmp = images.getBackgroundBitmap()
+
+ # Make a shape from an image and mask. This one will demo
+ # dragging outside the window
+ bmp = images.getTestStarBitmap()
+ shape = DragShape(bmp)
+ shape.pos = (5, 5)
+ shape.fullscreen = True
+ self.shapes.append(shape)
+
+ # Make a shape from some text
+ text = "Some Text"
+ bg_colour = wx.Colour(57, 115, 57) # matches the bg image
+ font = wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
+ textExtent = self.GetFullTextExtent(text, font)
+
+ # create a bitmap the same size as our text
+ bmp = wx.EmptyBitmap(textExtent[0], textExtent[1])
+
+ # 'draw' the text onto the bitmap
+ dc = wx.MemoryDC()
+ dc.SelectObject(bmp)
+ dc.SetBackground(wx.Brush(bg_colour, wx.SOLID))
+ dc.Clear()
+ dc.SetTextForeground(wx.RED)
+ dc.SetFont(font)
+ dc.DrawText(text, (0, 0))
+ dc.SelectObject(wx.NullBitmap)
+ mask = wx.MaskColour(bmp, bg_colour)
+ bmp.SetMask(mask)
+ shape = DragShape(bmp)
+ shape.pos = (5, 100)
+ shape.text = "Some dragging text"
+ self.shapes.append(shape)
+
+
+ # Make some shapes from some playing card images.
+ x = 200
+
+ for card in ['_01c_', '_12h_', '_13d_', '_10s_']:
+ bmpFunc = getattr(images, "get%sBitmap" % card)
+ bmp = bmpFunc()
+ shape = DragShape(bmp)
+ shape.pos = (x, 5)
+ self.shapes.append(shape)
+ x = x + 80
+
+
+ self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
+ self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+ self.Bind(wx.EVT_MOTION, self.OnMotion)
+ self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
+
+
+ # We're not doing anything here, but you might have reason to.
+ # for example, if you were dragging something, you might elect to
+ # 'drop it' when the cursor left the window.
+ def OnLeaveWindow(self, evt):
+ pass
+
+
+ # tile the background bitmap
+ def TileBackground(self, dc):
+ sz = self.GetClientSize()
+ w = self.bg_bmp.GetWidth()
+ h = self.bg_bmp.GetHeight()
+
+ x = 0
+
+ while x < sz.width:
+ y = 0
+
+ while y < sz.height:
+ dc.DrawBitmap(self.bg_bmp, (x, y))
+ y = y + h
+
+ x = x + w
+
+
+ # Go through our list of shapes and draw them in whatever place they are.
+ def DrawShapes(self, dc):
+ for shape in self.shapes:
+ if shape.shown:
+ shape.Draw(dc)
+
+ # This is actually a sophisticated 'hit test', but in this
+ # case we're also determining which shape, if any, was 'hit'.
+ def FindShape(self, pt):
+ for shape in self.shapes:
+ if shape.HitTest(pt):
+ return shape
+ return None
+
+ # Remove a shape from the display
+ def EraseShape(self, shape, dc):
+ r = shape.GetRect()
+ dc.SetClippingRect(r)
+ self.TileBackground(dc)
+ self.DrawShapes(dc)
+ dc.DestroyClippingRegion()
+
+ # Clears the background, then redraws it. If the DC is passed, then
+ # we only do so in the area so designated. Otherwise, it's the whole thing.
+ def OnEraseBackground(self, evt):
+ dc = evt.GetDC()
+
+ if not dc:
+ dc = wxClientDC(self)
+ rect = self.GetUpdateRegion().GetBox()
+ dc.SetClippingRect(rect)
+ self.TileBackground(dc)
+
+ # Fired whenever a paint event occurs
+ def OnPaint(self, evt):
+ dc = wx.PaintDC(self)
+ self.PrepareDC(dc)
+ self.DrawShapes(dc)
+
+ # Left mouse button is down.
+ def OnLeftDown(self, evt):
+ # Did the mouse go down on one of our shapes?
+ shape = self.FindShape(evt.GetPosition())
+
+ # If a shape was 'hit', then set that as the shape we're going to
+ # drag around. Get our start position. Dragging has not yet started.
+ # That will happen once the mouse moves, OR the mouse is released.
+ if shape:
+ self.dragShape = shape
+ self.dragStartPos = evt.GetPosition()
+
+ # Left mouse button up.
+ def OnLeftUp(self, evt):
+ if not self.dragImage or not self.dragShape:
+ self.dragImage = None
+ self.dragShape = None
+ return
+
+ # Hide the image, end dragging, and nuke out the drag image.
+ self.dragImage.Hide()
+ self.dragImage.EndDrag()
+ self.dragImage = None
+
+ dc = wx.ClientDC(self)
+
+ if self.hiliteShape:
+ self.hiliteShape.Draw(dc)
+ self.hiliteShape = None
+
+ # reposition and draw the shape
+
+ # Note by jmg 11/28/03
+ # Here's the original:
+ #
+ # self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - self.dragStartPos
+ #
+ # So if there are any problems associated with this, use that as
+ # a starting place in your investigation. I've tried to simulate the
+ # wx.Point __add__ method here -- it won't work for tuples as we
+ # have now from the various methods
+ #
+ # There must be a better way to do this :-)
+ #
+
+ self.dragShape.pos = (
+ self.dragShape.pos[0] + evt.GetPosition()[0] - self.dragStartPos[0],
+ self.dragShape.pos[1] + evt.GetPosition()[1] - self.dragStartPos[1]
+ )
+
+ self.dragShape.shown = True
+ self.dragShape.Draw(dc)
+ self.dragShape = None
+
+ # The mouse is moving
+ def OnMotion(self, evt):
+ # Ignore mouse movement if we're not dragging.
+ if not self.dragShape or not evt.Dragging() or not evt.LeftIsDown():
+ return
+
+ # if we have a shape, but haven't started dragging yet
+ if self.dragShape and not self.dragImage:
+
+ # only start the drag after having moved a couple pixels
+ tolerance = 2
+ pt = evt.GetPosition()
+ dx = abs(pt.x - self.dragStartPos.x)
+ dy = abs(pt.y - self.dragStartPos.y)
+ if dx <= tolerance and dy <= tolerance:
+ return
+
+ # erase the shape since it will be drawn independently now
+ dc = wx.ClientDC(self)
+ self.dragShape.shown = False
+ self.EraseShape(self.dragShape, dc)
+
+
+ if self.dragShape.text:
+ self.dragImage = wx.DragString(self.dragShape.text,
+ wx.StockCursor(wx.CURSOR_HAND))
+ else:
+ self.dragImage = wx.DragImage(self.dragShape.bmp,
+ wx.StockCursor(wx.CURSOR_HAND))
+
+ hotspot = self.dragStartPos - self.dragShape.pos
+ self.dragImage.BeginDrag(hotspot, self, self.dragShape.fullscreen)
+
+ self.dragImage.Move(pt)
+ self.dragImage.Show()
+
+
+ # if we have shape and image then move it, posibly highlighting another shape.
+ elif self.dragShape and self.dragImage:
+ onShape = self.FindShape(evt.GetPosition())
+ unhiliteOld = False
+ hiliteNew = False
+
+ # figure out what to hilite and what to unhilite
+ if self.hiliteShape:
+ if onShape is None or self.hiliteShape is not onShape:
+ unhiliteOld = True
+
+ if onShape and onShape is not self.hiliteShape and onShape.shown:
+ hiliteNew = True
+
+ # if needed, hide the drag image so we can update the window
+ if unhiliteOld or hiliteNew:
+ self.dragImage.Hide()
+
+ if unhiliteOld:
+ dc = wx.ClientDC(self)
+ self.hiliteShape.Draw(dc)
+ self.hiliteShape = None
+
+ if hiliteNew:
+ dc = wx.ClientDC(self)
+ self.hiliteShape = onShape
+ self.hiliteShape.Draw(dc, wx.INVERT)
+
+ # now move it and show it again if needed
+ self.dragImage.Move(evt.GetPosition())
+ if unhiliteOld or hiliteNew:
+ self.dragImage.Show()
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+
+ win = wx.Panel(nb, -1)
+ canvas = DragCanvas(win, -1)
+
+ def onSize(evt, panel=win, canvas=canvas):
+ canvas.SetSize(panel.GetSize())
+
+ win.Bind(wx.EVT_SIZE, onSize)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """\
+DragImage is used when you wish to drag an object on the screen, and a simple
+cursor is not enough.
+
+On Windows, the WIN32 API is used to do achieve smooth dragging. On other
+platforms, <code>GenericDragImage</code> is used. Applications may also prefer to use
+<code>GenericDragImage</code> on Windows, too.
+
+<b>wxPython note</b>: wxPython uses <code>GenericDragImage</code> on all
+platforms, but uses the <code>DragImage</code> name.
+
+To use this class, when you wish to start dragging an image, create a
+<code>DragImage</code> object and store it somewhere you can access it as the
+drag progresses. Call BeginDrag to start, and EndDrag to stop the drag. To move
+the image, initially call Show and then Move. If you wish to update the screen
+contents during the drag (for example, highlight an item as in the example), first
+call Hide, update the screen, call Move, and then call Show.
+
+You can drag within one window, or you can use full-screen dragging either across
+the whole screen, or just restricted to one area of the screen to save resources.
+If you want the user to drag between two windows, then you will need to use
+full-screen dragging.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import wx.gizmos as gizmos
+import wx.stc as stc
+
+#----------------------------------------------------------------------
+# This is an example of the complex view that manages its own scrollbars
+# as described in the overview below.
+
+class TestView(stc.StyledTextCtrl):
+ def __init__(self, parent, ID, log):
+ stc.StyledTextCtrl.__init__(self, parent, ID, style=wx.NO_BORDER)
+ self.dyn_sash = parent
+ self.log = log
+ self.SetupScrollBars()
+ self.SetMarginWidth(1,0)
+
+ self.StyleSetFont(stc.STC_STYLE_DEFAULT,
+ wx.Font(10, wx.MODERN, wx.NORMAL, wx.NORMAL))
+
+ self.Bind(gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnSplit)
+ self.Bind(gizmos.EVT_DYNAMIC_SASH_UNIFY, self.OnUnify)
+ #self.SetScrollWidth(500)
+
+ def SetupScrollBars(self):
+ # hook the scrollbars provided by the wxDynamicSashWindow
+ # to this view
+ v_bar = self.dyn_sash.GetVScrollBar(self)
+ h_bar = self.dyn_sash.GetHScrollBar(self)
+ v_bar.Bind(wx.EVT_SCROLL, self.OnSBScroll)
+ h_bar.Bind(wx.EVT_SCROLL, self.OnSBScroll)
+ v_bar.Bind(wx.EVT_SET_FOCUS, self.OnSBFocus)
+ h_bar.Bind(wx.EVT_SET_FOCUS, self.OnSBFocus)
+
+ # And set the wxStyledText to use these scrollbars instead
+ # of its built-in ones.
+ self.SetVScrollBar(v_bar)
+ self.SetHScrollBar(h_bar)
+
+
+ def __del__(self):
+ self.log.write("TestView.__del__\n")
+
+ def OnSplit(self, evt):
+ self.log.write("TestView.OnSplit\n");
+ newview = TestView(self.dyn_sash, -1, self.log)
+ newview.SetDocPointer(self.GetDocPointer()) # use the same document
+ self.SetupScrollBars()
+
+
+ def OnUnify(self, evt):
+ self.log.write("TestView.OnUnify\n");
+ self.SetupScrollBars()
+
+
+ def OnSBScroll(self, evt):
+ # redirect the scroll events from the dyn_sash's scrollbars to the STC
+ self.GetEventHandler().ProcessEvent(evt)
+
+ def OnSBFocus(self, evt):
+ # when the scrollbar gets the focus move it back to the STC
+ self.SetFocus()
+
+
+sampleText="""\
+You can drag the little tabs above the vertical scrollbar, or to the
+left of the horizontal scrollbar to split this view, and you can
+continue splitting the new views as much as you like. Try it and see.
+
+In this case the views also share the same document so changes in one
+are instantly seen in the others. This is a feature of the
+StyledTextCtrl that is used for the view class in this sample.
+"""
+
+#----------------------------------------------------------------------
+# This one is simpler, but doesn't do anything with the scrollbars
+# except the default wxDynamicSashWindow behaviour
+
+class SimpleView(wx.Panel):
+ def __init__(self, parent, ID, log):
+ wx.Panel.__init__(self, parent, ID)
+ self.dyn_sash = parent
+ self.log = log
+ self.SetBackgroundColour("LIGHT BLUE")
+ self.Bind(gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnSplit)
+
+ def OnSplit(self, evt):
+ v = SimpleView(self.dyn_sash, -1, self.log)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ if wx.Platform == "__WXMAC__":
+ wx.MessageBox("This demo currently fails on the Mac. The problem is being looked into...", "Sorry")
+ return
+
+ if 1:
+ win = gizmos.DynamicSashWindow(nb, -1, style = wx.CLIP_CHILDREN
+ #| wxDS_MANAGE_SCROLLBARS
+ #| wxDS_DRAG_CORNER
+ )
+
+ win.SetFont(wx.Font(10, wx.MODERN, wx.NORMAL, wx.NORMAL))
+ view = TestView(win, -1, log)
+ view.SetText(sampleText)
+ else:
+ win = wx.DynamicSashWindow(nb, -1)
+ view = SimpleView(win, -1, log)
+ return win
+
+#----------------------------------------------------------------------
+
+overview = """\
+<html><body>
+<h2>DynamicSashWindow</h2>
+<p>
+wxDynamicSashWindow widgets manages the way other widgets are viewed.
+When a wxDynamicSashWindow is first shown, it will contain one child
+view, a viewport for that child, and a pair of scrollbars to allow the
+user to navigate the child view area. Next to each scrollbar is a small
+tab. By clicking on either tab and dragging to the appropriate spot, a
+user can split the view area into two smaller views separated by a
+draggable sash. Later, when the user wishes to reunify the two subviews,
+the user simply drags the sash to the side of the window.
+wxDynamicSashWindow will automatically reparent the appropriate child
+view back up the window hierarchy, and the wxDynamicSashWindow will have
+only one child view once again.
+<p>
+As an application developer, you will simply create a wxDynamicSashWindow
+using either the Create() function or the more complex constructor
+provided below, and then create a view window whose parent is the
+wxDynamicSashWindow. The child should respond to
+wxDynamicSashSplitEvents -- perhaps with an OnSplit() event handler -- by
+constructing a new view window whose parent is also the
+wxDynamicSashWindow. That's it! Now your users can dynamically split
+and reunify the view you provided.
+<p>
+If you wish to handle the scrollbar events for your view, rather than
+allowing wxDynamicSashWindow to do it for you, things are a bit more
+complex. (You might want to handle scrollbar events yourself, if,
+for instance, you wish to scroll a subwindow of the view you add to
+your wxDynamicSashWindow object, rather than scrolling the whole view.)
+In this case, you will need to construct your wxDynamicSashWindow without
+the wxDS_MANAGE_SCROLLBARS style and you will need to use the
+GetHScrollBar() and GetVScrollBar() methods to retrieve the scrollbar
+controls and call SetEventHanler() on them to redirect the scrolling
+events whenever your window is reparented by wxDyanmicSashWindow.
+You will need to set the scrollbars' event handler at three times:
+<p>
+<ul>
+<li> When your view is created
+<li> When your view receives a wxDynamicSashSplitEvent
+<li> When your view receives a wxDynamicSashUnifyEvent
+</ul>
+</body></html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o Added overview text based on source code delving.
+#
+
+import wx
+import wx.gizmos as gizmos
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ self.elb = gizmos.EditableListBox(
+ self, -1, "List of Stuff", (50,50), (250, 250)
+ )
+ #style=wx.EL_ALLOW_NEW | wx.EL_ALLOW_EDIT | wx.EL_ALLOW_DELETE)
+
+ self.elb.SetStrings(["This is a nifty ListBox widget",
+ "that is editable by the user.",
+ "",
+ "Use the buttons above to",
+ "manipulate items in the list",
+ "Or to add new ones.",
+ ])
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """\
+<html>
+<body>
+This class provides a composite control that lets the user easily enter and edit
+a list of strings.
+
+<p><b>Styles supported:</b><p>
+
+<ul>
+<li><b>EL_ALLOW_NEW</b> - Allow user to create new items.
+<li><b>EL_ALLOW_EDIT</b> - Allow user to edit text in the control.
+<li><b>EL_ALLOW_DELETE</b> - Allow user to delete text from the control.
+</ul>
+
+<p><b>Init:</b>
+<pre>
+ EditableListBox(wxWindow *parent, wxWindowID id=-1,
+ const wxString& label,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = EL_ALLOW_NEW | EL_ALLOW_EDIT | EL_ALLOW_DELETE,
+ const wxString& name = "editableListBox")
+</pre>
+
+<p><b>Methods:</b>
+<ul>
+ <li><b>SetStrings(const wxArrayString& strings)</b> - Set an array of strings
+ into the control. <b>Note</b>: The wxPython method accepts a Python list instead
+ of an array of strings.
+
+ <li><b>void GetStrings(wxArrayString& strings)</b> - Retrieves an array
+ of strings from the control. The wxPython version returns a list of strings.
+
+ <li><b>GetListCtrl()</b> - Retrieves a reference to the actual list control
+ portion of the custom control.
+
+ <li><b>GetDelButton()</b> - Retrieves a reference to the BitmapButton that is used
+ as the 'delete' button in the control.
+
+ <li><b>GetNewButton()</b> - Retrieves a reference to the BitmapButton that is used
+ as the 'new' button in the control.
+
+ <li><b>GetUpButton()</b> - Retrieves a reference to the BitmapButton that is used
+ as the 'up' button in the control.
+
+ <li><b>GetDownButton()</b> - Retrieves a reference to the BitmapButton that is used
+ as the 'down' button in the control.
+
+ <li><b>GetEditButton()</b> - Retrieves a reference to the BitmapButton that is used
+ as the 'edit' button in the control.
+</ul>
+</body>
+</html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o editor lib hasn't been hit by the renamer yet.
+#
+# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxEditor -> Editor
+#
+
+import wx
+import wx.lib.editor as editor
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = wx.Panel(nb, -1)
+ ed = editor.Editor(win, -1, style=wx.SUNKEN_BORDER)
+ box = wx.BoxSizer(wx.VERTICAL)
+ box.Add(ed, 1, wx.ALL|wx.GROW, 1)
+ win.SetSizer(box)
+ win.SetAutoLayout(True)
+
+ ed.SetText(["",
+ "This is a simple text editor, the class name is",
+ "Editor. Type a few lines and try it out.",
+ "",
+ "It uses Windows-style key commands that can be overridden by subclassing.",
+ "Mouse select works. Here are the key commands:",
+ "",
+ "Cursor movement: Arrow keys or mouse",
+ "Beginning of line: Home",
+ "End of line: End",
+ "Beginning of buffer: Control-Home",
+ "End of the buffer: Control-End",
+ "Select text: Hold down Shift while moving the cursor",
+ "Copy: Control-Insert, Control-C",
+ "Cut: Shift-Delete, Control-X",
+ "Paste: Shift-Insert, Control-V",
+ ""])
+
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """
+The Editor class implements a simple text editor using wxPython. You
+can create a custom editor by subclassing Editor. Even though much of
+the editor is implemented in Python, it runs surprisingly smoothly on
+normal hardware with small files.
+
+How to use it
+-------------
+The demo code (demo/Editor.py) shows how to use Editor as a simple text
+box. Use the SetText() and GetText() methods to set or get text from
+the component; these both use a list of strings.
+
+The samples/FrogEdit directory has an example of a simple text editor
+application that uses the Editor component.
+
+Subclassing
+-----------
+To add or change functionality, you can subclass this
+component. One example of this might be to change the key
+Alt key commands. In that case you would (for example) override the
+SetAltFuncs() method.
+
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import os
+import wx
+
+#---------------------------------------------------------------------------
+
+# This is how you pre-establish a file filter so that the dialog
+# only shows the extention(s) you want it to.
+wildcard = "Python source (*.py)|*.py|" \
+ "Compiled Python (*.pyc)|*.pyc|" \
+ "All files (*.*)|*.*"
+
+def runTest(frame, nb, log):
+ log.WriteText("CWD: %s\n" % os.getcwd())
+
+ # Create the dialog. In this case the current directory is forced as the starting
+ # directory for the dialog, and no default file name is forced. This can easilly
+ # be changed in your program. This is an 'open' dialog, and allows multitple
+ # file selection to boot.
+ #
+ # Finally, of the directory is changed in the process of getting files, this
+ # dialog is set up to change the current working directory to the path chosen.
+ dlg = wx.FileDialog(
+ frame, message="Choose a file", defaultDir=os.getcwd(),
+ defaultFile="", wildcard=wildcard, style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR
+ )
+
+ # Show the dialog and retrieve the user response. If it is the OK response,
+ # process the data.
+ if dlg.ShowModal() == wx.ID_OK:
+ # This returns a Python list of files that were selected.
+ paths = dlg.GetPaths()
+
+ log.WriteText('You selected %d files:' % len(paths))
+
+ for path in paths:
+ log.WriteText(' %s\n' % path)
+
+ # Compare this with the debug above; did we change working dirs?
+ log.WriteText("CWD: %s\n" % os.getcwd())
+
+ # Destroy the dialog. Don't do this until you are done with it!
+ # BAD things can happen otherwise!
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class provides the file selection dialog. It incorporates OS-native features
+depending on the OS in use, and can be used both for open and save operations.
+The files displayed can be filtered by setting up a wildcard filter, multiple files
+can be selected (open only), and files can be forced in a read-only mode.
+
+There are two ways to get the results back from the dialog. GetFiles() returns only
+the file names themselves, in a Python list. GetPaths() returns the full path and
+filenames combined as a Python list.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import os
+import wx
+
+#---------------------------------------------------------------------------
+
+# This is how you pre-establish a file filter so that the dialog
+# only shows the extention(s) you want it to.
+wildcard = "Python source (*.py)|*.py|" \
+ "Compiled Python (*.pyc)|*.pyc|" \
+ "SPAM files (*.spam)|*.spam|" \
+ "Egg file (*.egg)|*.egg|" \
+ "All files (*.*)|*.*"
+
+def runTest(frame, nb, log):
+ log.WriteText("CWD: %s\n" % os.getcwd())
+
+ # Create the dialog. In this case the current directory is forced as the starting
+ # directory for the dialog, and no default file name is forced. This can easilly
+ # be changed in your program. This is an 'save' dialog.
+ #
+ # Unlike the 'open dialog' example found elsewhere, this example does NOT
+ # force the current working directory to change if the user chooses a different
+ # directory than the one initially set.
+ dlg = wx.FileDialog(
+ frame, message="Save file as ...", defaultDir=os.getcwd(),
+ defaultFile="", wildcard=wildcard, style=wx.SAVE
+ )
+
+ # This sets the default filter that the user will initially see. Otherwise,
+ # the first filter in the list will be used by default.
+ dlg.SetFilterIndex(2)
+
+ # Show the dialog and retrieve the user response. If it is the OK response,
+ # process the data.
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ log.WriteText('You selected "%s"' % path)
+
+ # Normally, at this point you would save your data using the file and path
+ # data that the user provided to you, but since we didn't actually start
+ # with any data to work with, that would be difficult.
+ #
+ # The code to do so would be similar to this, assuming 'data' contains
+ # the data you want to save:
+ #
+ # fp = file(path, 'w') # Create file anew
+ # fp.write(data)
+ # fp.close()
+ #
+ # You might want to add some error checking :-)
+ #
+
+ # Note that the current working dir didn't change. This is good since
+ # that's the way we set it up.
+ log.WriteText("CWD: %s\n" % os.getcwd())
+
+ # Destroy the dialog. Don't do this until you are done with it!
+ # BAD things can happen otherwise!
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class provides the file selection dialog. It incorporates OS-native features
+depending on the OS in use, and can be used both for open and save operations.
+The files displayed can be filtered by setting up a wildcard filter, multiple files
+can be selected (open only), and files can be forced in a read-only mode.
+
+There are two ways to get the results back from the dialog. GetFiles() returns only
+the file names themselves, in a Python list. GetPaths() returns the full path and
+filenames combined as a Python list.
+
+One important thing to note: if you use the file extention filters, then files saved
+with the filter set to something will automatically get that extention appended to them
+if it is not already there. For example, suppose the dialog was displaying the 'egg'
+extention and you entered a file name of 'fried'. It would be saved as 'fried.egg.'
+Yum!
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import os
+import wx
+
+#----------------------------------------------------------------------
+
+text = """\
+Right-click on the panel above the line to get a menu. This menu will
+be managed by a FileHistory object and so the files you select will
+automatically be added to the end of the menu and will be selectable
+the next time the menu is viewed. The filename selected, either via the
+Open menu item, or from the history, will be displayed in the log
+window below.
+"""
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+ box = wx.BoxSizer(wx.VERTICAL)
+
+ # Make and layout the controls
+ fs = self.GetFont().GetPointSize()
+ bf = wx.Font(fs+4, wx.SWISS, wx.NORMAL, wx.BOLD)
+ nf = wx.Font(fs+2, wx.SWISS, wx.NORMAL, wx.NORMAL)
+
+ t = wx.StaticText(self, -1, "FileHistory")
+ t.SetFont(bf)
+ box.Add(t, 0, wx.CENTER|wx.ALL, 5)
+
+ box.Add(wx.StaticLine(self, -1), 0, wx.EXPAND)
+ box.Add((10,20))
+
+ t = wx.StaticText(self, -1, text)
+ t.SetFont(nf)
+ box.Add(t, 0, wx.CENTER|wx.ALL, 5)
+
+ self.SetSizer(box)
+ self.SetAutoLayout(True)
+
+ # Make a menu
+ self.menu = m = wx.Menu()
+
+ # Little know wx Fact #42: there are a number of pre-set IDs
+ # in the wx package, to be used for common controls such as those
+ # illustrated below. Neat, huh?
+ m.Append(wx.ID_NEW, "&New")
+ m.Append(wx.ID_OPEN, "&Open...")
+ m.Append(wx.ID_CLOSE, "&Close")
+ m.Append(wx.ID_SAVE, "&Save")
+ m.Append(wx.ID_SAVEAS, "Save &as...")
+ m.Enable(wx.ID_NEW, False)
+ m.Enable(wx.ID_CLOSE, False)
+ m.Enable(wx.ID_SAVE, False)
+ m.Enable(wx.ID_SAVEAS, False)
+
+ # and a file history
+ self.filehistory = wx.FileHistory()
+ self.filehistory.UseMenu(self.menu)
+
+ # and finally the event handler bindings
+ self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
+
+ self.Bind(wx.EVT_MENU, self.OnFileOpenDialog, id=wx.ID_OPEN)
+
+ self.Bind(
+ wx.EVT_MENU_RANGE, self.OnFileHistory, id=wx.ID_FILE1, id2=wx.ID_FILE9
+ )
+
+ self.Bind(wx.EVT_WINDOW_DESTROY, self.Cleanup)
+
+
+ def Cleanup(self, *args):
+ # A little extra cleanup is required for the FileHistory control
+ del self.filehistory
+ self.menu.Destroy()
+
+
+ def OnRightClick(self, evt):
+ self.PopupMenu(self.menu, evt.GetPosition())
+
+
+ def OnFileOpenDialog(self, evt):
+ dlg = wx.FileDialog(self,
+ defaultDir = os.getcwd(),
+ wildcard = "All Files|*",
+ style = wx.OPEN | wx.CHANGE_DIR)
+
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ self.log.write("You selected %s\n" % path)
+
+ # add it to the history
+ self.filehistory.AddFileToHistory(path)
+
+ dlg.Destroy()
+
+
+ def OnFileHistory(self, evt):
+ # get the file based on the menu ID
+ fileNum = evt.GetId() - wx.ID_FILE1
+ path = self.filehistory.GetHistoryFile(fileNum)
+ self.log.write("You selected %s\n" % path)
+
+ # add it back to the history so it will be moved up the list
+ self.filehistory.AddFileToHistory(path)
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h3>FileHistory</h3>
+
+wxFileHistory encapsulates functionality to record the last few files
+visited, and to allow the user to quickly load these files using the
+list appended to a menu, such as the File menu.
+
+<p>Note that this inclusion is not automatic; as illustrated in this example,
+you must add files (and remove them) as deemed necessary within the framework
+of your program.
+
+<p>Note also the additional cleanup required for this class, namely trapping the
+enclosing window's Destroy event and deleting the file history control and its
+associated menu.
+</body></html>
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Changed the event binding slightly.
+# o There are issues with the GetReplaceText() method of the
+# FindDialogEvent. Must be retested when this is fixed.
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ b = wx.Button(self, -1, "Show Find Dialog", (25, 50))
+ self.Bind(wx.EVT_BUTTON, self.OnShowFind, b)
+
+ b = wx.Button(self, -1, "Show Find && Replace Dialog", (25, 90))
+ self.Bind(wx.EVT_BUTTON, self.OnShowFindReplace, b)
+
+
+ # jg - 11/28/03 - corrected a long standing issue here where
+ # EVT_COMMAND_FIND_* was being used for these event binders
+ # instead of the actual event IDs shown below. As a result,
+ # onFind() was never showing the appropriate type. I guess
+ # nobody really paid much attention to that little
+ # debugging window :-)
+ #
+ self.Bind(wx.EVT_FIND, self.OnFind)
+ self.Bind(wx.EVT_FIND_NEXT, self.OnFind)
+ self.Bind(wx.EVT_FIND_REPLACE, self.OnFind)
+ self.Bind(wx.EVT_FIND_REPLACE_ALL, self.OnFind)
+ self.Bind(wx.EVT_FIND_CLOSE, self.OnFindClose)
+
+
+ def OnShowFind(self, evt):
+ data = wx.FindReplaceData()
+ dlg = wx.FindReplaceDialog(self, data, "Find")
+ dlg.data = data # save a reference to it...
+ dlg.Show(True)
+
+
+ def OnShowFindReplace(self, evt):
+ data = wx.FindReplaceData()
+ dlg = wx.FindReplaceDialog(self, data, "Find & Replace", wx.FR_REPLACEDIALOG)
+ dlg.data = data # save a reference to it...
+ dlg.Show(True)
+
+
+ def OnFind(self, evt):
+ map = {
+ wx.wxEVT_COMMAND_FIND : "FIND",
+ wx.wxEVT_COMMAND_FIND_NEXT : "FIND_NEXT",
+ wx.wxEVT_COMMAND_FIND_REPLACE : "REPLACE",
+ wx.wxEVT_COMMAND_FIND_REPLACE_ALL : "REPLACE_ALL",
+ }
+
+ et = evt.GetEventType()
+
+ #print evt.GetReplaceString()
+
+ if et in map:
+ evtType = map[et]
+ else:
+ evtType = "**Unknown Event Type**"
+
+ #>> Todo: the GetReplaceString() method is broken. Has to be
+ # fixed.
+ if et == wx.EVT_COMMAND_FIND_REPLACE or et == wx.EVT_COMMAND_FIND_REPLACE_ALL:
+ replaceTxt = "Replace text: %s" % evt.GetReplaceString()
+ else:
+ replaceTxt = ""
+
+ self.log.write("%s -- Find text: %s %s Flags: %d \n" %
+ (evtType, evt.GetFindString(), replaceTxt, evt.GetFlags()))
+
+
+ def OnFindClose(self, evt):
+ self.log.write("FindReplaceDialog closing...\n")
+ evt.GetDialog().Destroy()
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+
+overview = """\
+FindReplaceDialog is a standard modeless dialog which is used to allow the user
+to search for some text (and possibly replace it with something else). The actual
+searching is supposed to be done in the owner window which is the parent of this
+dialog. Note that it means that unlike for the other standard dialogs this one
+<u>must have a parent window</u>. Also note that there is no way to use this
+dialog in a modal way; <b>it is always, by design and implementation, modeless</b>.
+
+FileReplaceDialog requires the use of <b>FindReplaceData</b>. This holds the
+data for the dialog. It is used to initialize the dialog with the default values
+and will keep the last values from the dialog when it is closed. It is also
+updated each time a FindDialogEvent is generated so instead of using the
+FindDialogEvent methods you can also directly query this object. <b>Care must be
+taken not to use this object after the dialog is destroyed.</b> The data within
+will be invalid after the parent dialog is destroyed.
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o OK, Main.py indicates this is deprecated. But I don't see a
+# replacement yet. So conversion is done anyway.
+#
+# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Issues - library has to be converted to work properly
+# with new namespace.
+#
+# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxFloatBar -> FloatBar
+#
+
+import wx
+import wx.lib.floatbar
+
+import images
+
+
+class TestFloatBar(wx.Frame):
+ def __init__(self, parent, log):
+ wx.Frame.__init__(
+ self, parent, -1, 'Test ToolBar', wx.DefaultPosition, (500, 300)
+ )
+
+ self.log = log
+
+ win = wx.Window(self, -1)
+ win.SetBackgroundColour("WHITE")
+ wx.StaticText(
+ win, -1, "Drag the toolbar to float it,\n"
+ "Toggle the last tool to remove\nthe title.", (15,15)
+ )
+
+ tb = wx.lib.floatbar.FloatBar(self, -1)
+ self.SetToolBar(tb)
+ tb.SetFloatable(1)
+ tb.SetTitle("Floating!")
+ self.CreateStatusBar()
+
+ tb.AddSimpleTool(10, images.getNewBitmap(), "New", "Long help for 'New'")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=10)
+
+ tb.AddSimpleTool(20, images.getOpenBitmap(), "Open")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=20)
+
+ tb.AddSeparator()
+ tb.AddSimpleTool(30, images.getCopyBitmap(), "Copy")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=30)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=30)
+
+ tb.AddSimpleTool(40, images.getPasteBitmap(), "Paste")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=40)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=40)
+
+ tb.AddSeparator()
+
+ tb.AddCheckTool(60, images.getTog1Bitmap(), images.getTog2Bitmap())
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=60)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=60)
+
+ tb.Realize()
+
+ self.tb = tb
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+
+ def OnCloseWindow(self, event):
+ self.Destroy()
+
+ def OnToolClick(self, event):
+ self.log.WriteText("tool %s clicked\n" % event.GetId())
+
+ if event.GetId() == 60:
+ print event.GetExtraLong(), event.IsChecked(), event.GetInt(), self.tb.GetToolState(60)
+
+ if event.GetExtraLong():
+ self.tb.SetTitle("")
+ else:
+ self.tb.SetTitle("Floating!")
+
+ def OnToolRClick(self, event):
+ self.log.WriteText("tool %s right-clicked\n" % event.GetId())
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestFloatBar(frame, log)
+ frame.otherWin = win
+ win.Show(True)
+
+#---------------------------------------------------------------------------
+
+overview = """\
+FloatBar is a subclass of wx.ToolBar, implemented in Python, which
+can be detached from its frame.
+
+Drag the toolbar with the mouse to make it float, and drag it back, or
+close it to make the toolbar return to its original position.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ btn = wx.Button(self, -1, "Select Font")
+ self.Bind(wx.EVT_BUTTON, self.OnSelectFont, btn)
+
+ self.sampleText = wx.TextCtrl(self, -1, "Sample Text")
+ #from wxPython.lib.stattext import wxGenStaticText
+ #self.sampleText = wxGenStaticText(self, -1, "Sample Text")
+
+ self.curFont = self.sampleText.GetFont()
+ self.curClr = wx.BLACK
+
+ fgs = wx.FlexGridSizer(cols=2, vgap=5, hgap=5)
+ fgs.AddGrowableCol(1)
+ fgs.AddGrowableRow(0)
+
+ fgs.Add(btn)
+ fgs.Add(self.sampleText, 0, wx.ADJUST_MINSIZE|wx.GROW)
+
+ fgs.Add((15,15)); fgs.Add((15,15)) # an empty row
+
+ fgs.Add(wx.StaticText(self, -1, "PointSize:"))
+ self.ps = wx.StaticText(self, -1, "")
+ font = self.ps.GetFont()
+ font.SetWeight(wx.BOLD)
+ self.ps.SetFont(font)
+ fgs.Add(self.ps, 0, wx.ADJUST_MINSIZE)
+
+ fgs.Add(wx.StaticText(self, -1, "Family:"))
+ self.family = wx.StaticText(self, -1, "")
+ self.family.SetFont(font)
+ fgs.Add(self.family, 0, wx.ADJUST_MINSIZE)
+
+ fgs.Add(wx.StaticText(self, -1, "Style:"))
+ self.style = wx.StaticText(self, -1, "")
+ self.style.SetFont(font)
+ fgs.Add(self.style, 0, wx.ADJUST_MINSIZE)
+
+ fgs.Add(wx.StaticText(self, -1, "Weight:"))
+ self.weight = wx.StaticText(self, -1, "")
+ self.weight.SetFont(font)
+ fgs.Add(self.weight, 0, wx.ADJUST_MINSIZE)
+
+ fgs.Add(wx.StaticText(self, -1, "Face:"))
+ self.face = wx.StaticText(self, -1, "")
+ self.face.SetFont(font)
+ fgs.Add(self.face, 0, wx.ADJUST_MINSIZE)
+
+ fgs.Add((15,15)); fgs.Add((15,15)) # an empty row
+
+ fgs.Add(wx.StaticText(self, -1, "wx.NativeFontInfo:"))
+ self.nfi = wx.StaticText(self, -1, "")
+ self.nfi.SetFont(font)
+ fgs.Add(self.nfi, 0, wx.ADJUST_MINSIZE)
+
+ # give it some border space
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(fgs, 0, wx.GROW|wx.ADJUST_MINSIZE|wx.ALL, 25)
+
+ self.SetSizer(sizer)
+ self.UpdateUI()
+
+
+ def UpdateUI(self):
+ self.sampleText.SetFont(self.curFont)
+ self.ps.SetLabel(str(self.curFont.GetPointSize()))
+ self.family.SetLabel(self.curFont.GetFamilyString())
+ self.style.SetLabel(self.curFont.GetStyleString())
+ self.weight.SetLabel(self.curFont.GetWeightString())
+ self.face.SetLabel(self.curFont.GetFaceName())
+ self.nfi.SetLabel(self.curFont.GetNativeFontInfo().ToString())
+ self.Layout()
+
+
+ def OnSelectFont(self, evt):
+ data = wx.FontData()
+ data.EnableEffects(True)
+ data.SetColour(self.curClr) # set colour
+ data.SetInitialFont(self.curFont)
+
+ dlg = wx.FontDialog(self, data)
+
+ if dlg.ShowModal() == wx.ID_OK:
+ data = dlg.GetFontData()
+ font = data.GetChosenFont()
+ colour = data.GetColour()
+
+ self.log.WriteText('You selected: "%s", %d points, color %s\n' %
+ (font.GetFaceName(), font.GetPointSize(),
+ colour.Get()))
+
+ self.curFont = font
+ self.curClr = colour
+ self.UpdateUI()
+
+ # Don't destroy the dialog until you get everything you need from the
+ # dialog!
+ dlg.Destroy()
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class allows you to use the system font selection dialog
+from within your program. Generally speaking, this allows you
+to select a font by its name, font size, and weight, and
+on some systems such things as strikethrough and underline.
+
+As with other dialogs used in wxPython, it is important to
+use the class' methods to extract the information you need
+about the font <b>before</b> you destroy the dialog. Failure
+to observe this almost always leads to a program failure of
+some sort, often ugly.
+
+This demo serves two purposes; it shows how to use the dialog
+to GET font information from the user, but also shows how
+to APPLY that information once you get it.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class MyFrame(wx.Frame):
+ def __init__(
+ self, parent, ID, title, pos=wx.DefaultPosition,
+ size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE
+ ):
+
+ wx.Frame.__init__(self, parent, ID, title, pos, size, style)
+ panel = wx.Panel(self, -1)
+
+ button = wx.Button(panel, 1003, "Close Me")
+ button.SetPosition((15, 15))
+ self.Bind(wx.EVT_BUTTON, self.OnCloseMe, button)
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+
+ def OnCloseMe(self, event):
+ self.Close(True)
+
+ def OnCloseWindow(self, event):
+ self.Destroy()
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = MyFrame(frame, -1, "This is a wxFrame", size=(350, 200),
+ style = wx.DEFAULT_FRAME_STYLE)# | wx.FRAME_TOOL_WINDOW )
+ frame.otherWin = win
+ win.Show(True)
+
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+A Frame is a window whose size and position can (usually) be changed by
+the user. It usually has thick borders and a title bar, and can optionally
+contain a menu bar, toolbar and status bar. A frame can contain any window
+that is not a Frame or Dialog. It is one of the most fundamental of the
+wxWindows components.
+
+A Frame that has a status bar and toolbar created via the
+<code>CreateStatusBar</code> / <code>CreateToolBar</code> functions manages
+these windows, and adjusts the value returned by <code>GetClientSize</code>
+to reflect the remaining size available to application windows.
+
+By itself, a Frame is not too useful, but with the addition of Panels and
+other child objects, it encompasses the framework around which most user
+interfaces are constructed.
+
+If you plan on using Sizers and auto-layout features, be aware that the Frame
+class lacks the ability to handle these features unless it contains a Panel.
+The Panel has all the necessary functionality to both control the size of
+child components, and also communicate that information in a useful way to
+the Frame itself.
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o Note: unable to install PyOpenGL on my system as I am running Python 2.3
+# and PyOpenGL does not support anything above Python 2.2. Did what I could,
+# but odds are good there are problems.
+#
+
+import wx
+
+try:
+ import wx.glcanvas as glcanvas
+ haveGLCanvas = True
+except ImportError:
+ haveGLCanvas = False
+
+try:
+ # The Python OpenGL package can be found at
+ # http://PyOpenGL.sourceforge.net/
+
+ import OpenGL.GL as gl
+ import OpenGL.GLUT as glut
+ haveOpenGL = True
+except ImportError:
+ haveOpenGL = False
+
+#----------------------------------------------------------------------
+
+if not haveGLCanvas:
+ def runTest(frame, nb, log):
+ dlg = wx.MessageDialog(
+ frame, 'The wxGLCanvas has not been included with this build of wxPython!',
+ 'Sorry', wx.OK | wx.ICON_INFORMATION
+ )
+
+ dlg.ShowModal()
+ dlg.Destroy()
+
+elif not haveOpenGL:
+ def runTest(frame, nb, log):
+ dlg = wx.MessageDialog(
+ frame, 'The OpenGL package was not found. You can get it at\n'
+ 'http://PyOpenGL.sourceforge.net/', 'Sorry', wx.OK | wx.ICON_INFORMATION
+ )
+
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+else:
+ buttonDefs = {
+ wx.NewId() : ('CubeCanvas', 'Cube'),
+ wx.NewId() : ('ConeCanvas', 'Cone'),
+ }
+
+ class ButtonPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ box = wx.BoxSizer(wx.VERTICAL)
+ box.Add((20, 30))
+ keys = buttonDefs.keys()
+ keys.sort()
+
+ for k in keys:
+ text = buttonDefs[k][1]
+ btn = wx.Button(self, k, text)
+ box.Add(btn, 0, wx.ALIGN_CENTER|wx.ALL, 15)
+ self.Bind(wx.EVT_BUTTON, self.OnButton, id=k)
+
+ #** Enable this to show putting a wxGLCanvas on the wxPanel
+ if 0:
+ c = CubeCanvas(self)
+ c.SetSize((200, 200))
+ box.Add(c, 0, wx.ALIGN_CENTER|wx.ALL, 15)
+
+ self.SetAutoLayout(True)
+ self.SetSizer(box)
+
+
+ def OnButton(self, evt):
+ canvasClassName = buttonDefs[evt.GetId()][0]
+ canvasClass = eval(canvasClassName)
+ frame = wx.Frame(None, -1, canvasClassName, size=(400,400))
+ canvas = canvasClass(frame)
+ frame.Show(True)
+
+
+
+ def runTest(frame, nb, log):
+ win = ButtonPanel(nb, log)
+ return win
+
+
+
+
+ class MyCanvasBase(glcanvas.GLCanvas):
+ def __init__(self, parent):
+ glcanvas.GLCanvas.__init__(self, parent, -1)
+ self.init = False
+ # initial mouse position
+ self.lastx = self.x = 30
+ self.lasty = self.y = 30
+ self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown) # needs fixing...
+ self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)
+ self.Bind(wx.EVT_MOTION, self.OnMouseMotion)
+
+ def OnEraseBackground(self, event):
+ pass # Do nothing, to avoid flashing on MSW.
+
+ def OnSize(self, event):
+ size = self.GetClientSize()
+
+ if self.GetContext():
+ self.SetCurrent()
+ glcanvas.glViewport(0, 0, size.width, size.height)
+
+ def OnPaint(self, event):
+ dc = wx.PaintDC(self)
+ self.SetCurrent()
+
+ if not self.init:
+ self.InitGL()
+ self.init = True
+
+ self.OnDraw()
+
+ def OnMouseDown(self, evt):
+ self.CaptureMouse()
+
+ def OnMouseUp(self, evt):
+ self.ReleaseMouse()
+
+ def OnMouseMotion(self, evt):
+ if evt.Dragging() and evt.LeftIsDown():
+ self.x, self.y = self.lastx, self.lasty
+ self.x, self.y = evt.GetPosition()
+ self.Refresh(False)
+
+
+ class CubeCanvas(MyCanvasBase):
+ def InitGL(self):
+ # set viewing projection
+ glcanvas.glMatrixMode(glcanvas.GL_PROJECTION);
+ glcanvas.glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0);
+
+ # position viewer
+ glcanvas.glMatrixMode(glcanvas.GL_MODELVIEW);
+ glcanvas.glTranslatef(0.0, 0.0, -2.0);
+
+ # position object
+ glcanvas.glRotatef(self.y, 1.0, 0.0, 0.0);
+ glcanvas.glRotatef(self.x, 0.0, 1.0, 0.0);
+
+ glcanvas.glEnable(glcanvas.GL_DEPTH_TEST);
+ glcanvas.glEnable(glcanvas.GL_LIGHTING);
+ glcanvas.glEnable(glcanvas.GL_LIGHT0);
+
+
+ def OnDraw(self):
+ # clear color and depth buffers
+ glcanvas.glClear(glcanvas.GL_COLOR_BUFFER_BIT | glcanvas.GL_DEPTH_BUFFER_BIT)
+
+ # draw six faces of a cube
+ glcanvas.glBegin(glcanvas.GL_QUADS)
+ glcanvas.glNormal3f( 0.0, 0.0, 1.0)
+ glcanvas.glVertex3f( 0.5, 0.5, 0.5)
+ glcanvas.glVertex3f(-0.5, 0.5, 0.5)
+ glcanvas.glVertex3f(-0.5,-0.5, 0.5)
+ glcanvas.glVertex3f( 0.5,-0.5, 0.5)
+
+ glcanvas.glNormal3f( 0.0, 0.0,-1.0)
+ glcanvas.glVertex3f(-0.5,-0.5,-0.5)
+ glcanvas.glVertex3f(-0.5, 0.5,-0.5)
+ glcanvas.glVertex3f( 0.5, 0.5,-0.5)
+ glcanvas.glVertex3f( 0.5,-0.5,-0.5)
+
+ glcanvas.glNormal3f( 0.0, 1.0, 0.0)
+ glcanvas.glVertex3f( 0.5, 0.5, 0.5)
+ glcanvas.glVertex3f( 0.5, 0.5,-0.5)
+ glcanvas.glVertex3f(-0.5, 0.5,-0.5)
+ glcanvas.glVertex3f(-0.5, 0.5, 0.5)
+
+ glcanvas.glNormal3f( 0.0,-1.0, 0.0)
+ glcanvas.glVertex3f(-0.5,-0.5,-0.5)
+ glcanvas.glVertex3f( 0.5,-0.5,-0.5)
+ glcanvas.glVertex3f( 0.5,-0.5, 0.5)
+ glcanvas.glVertex3f(-0.5,-0.5, 0.5)
+
+ glcanvas.glNormal3f( 1.0, 0.0, 0.0)
+ glcanvas.glVertex3f( 0.5, 0.5, 0.5)
+ glcanvas.glVertex3f( 0.5,-0.5, 0.5)
+ glcanvas.glVertex3f( 0.5,-0.5,-0.5)
+ glcanvas.glVertex3f( 0.5, 0.5,-0.5)
+
+ glcanvas.glNormal3f(-1.0, 0.0, 0.0)
+ glcanvas.glVertex3f(-0.5,-0.5,-0.5)
+ glcanvas.glVertex3f(-0.5,-0.5, 0.5)
+ glcanvas.glVertex3f(-0.5, 0.5, 0.5)
+ glcanvas.glVertex3f(-0.5, 0.5,-0.5)
+ glcanvas.glEnd()
+
+ glcanvas.glRotatef((self.lasty - self.y)/100., 1.0, 0.0, 0.0);
+ glcanvas.glRotatef((self.lastx - self.x)/100., 0.0, 1.0, 0.0);
+
+ self.SwapBuffers()
+
+
+ class ConeCanvas(MyCanvasBase):
+ def InitGL( self ):
+ glcanvas.glMatrixMode(glcanvas.GL_PROJECTION);
+ # camera frustrum setup
+ glcanvas.glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0);
+ glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
+ glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0])
+ glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_SPECULAR, [1.0, 0.0, 1.0, 1.0])
+ glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_SHININESS, 50.0)
+ glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_AMBIENT, [0.0, 1.0, 0.0, 1.0])
+ glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0])
+ glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
+ glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_POSITION, [1.0, 1.0, 1.0, 0.0]);
+ glcanvas.glLightModel(glcanvas.GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
+ glcanvas.glEnable(glcanvas.GL_LIGHTING)
+ glcanvas.glEnable(glcanvas.GL_LIGHT0)
+ glcanvas.glDepthFunc(glcanvas.GL_LESS)
+ glcanvas.glEnable(glcanvas.GL_DEPTH_TEST)
+ glcanvas.glClear(glcanvas.GL_COLOR_BUFFER_BIT | glcanvas.GL_DEPTH_BUFFER_BIT)
+ # position viewer
+ glcanvas.glMatrixMode(glcanvas.GL_MODELVIEW);
+
+
+ def OnDraw(self):
+ # clear color and depth buffers
+ glcanvas.glClear(glcanvas.GL_COLOR_BUFFER_BIT | glcanvas.GL_DEPTH_BUFFER_BIT);
+ # use a fresh transformation matrix
+ glcanvas.glPushMatrix()
+ # position object
+ glcanvas.glTranslate(0.0, 0.0, -2.0);
+ glcanvas.glRotate(30.0, 1.0, 0.0, 0.0);
+ glcanvas.glRotate(30.0, 0.0, 1.0, 0.0);
+
+ glcanvas.glTranslate(0, -1, 0)
+ glcanvas.glRotate(250, 1, 0, 0)
+ glcanvas.glutSolidCone(0.5, 1, 30, 5)
+ glcanvas.glPopMatrix()
+ glcanvas.glRotatef((self.lasty - self.y)/100., 0.0, 0.0, 1.0);
+ glcanvas.glRotatef(0.0, (self.lastx - self.x)/100., 1.0, 0.0);
+ # push into visible buffer
+ self.SwapBuffers()
+
+
+
+
+#----------------------------------------------------------------------
+
+
+
+overview = """\
+"""
+
+
+#----------------------------------------------------------------------
+
+def _test():
+ class MyApp(wxApp):
+ def OnInit(self):
+ frame = wx.Frame(None, -1, "GL Demos", wx.DefaultPosition, (600,300))
+ #win = ConeCanvas(frame)
+ MySplitter(frame)
+ frame.Show(True)
+ self.SetTopWindow(frame)
+ return True
+
+ app = MyApp(0)
+ app.MainLoop()
+
+if __name__ == '__main__':
+ _test()
+
--- /dev/null
+# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+ self.count = 0
+
+ wx.StaticText(self, -1, "This example shows the wxGauge control.", (45, 15))
+
+ self.g1 = wx.Gauge(self, -1, 50, (110, 50), (250, 25))
+ self.g1.SetBezelFace(3)
+ self.g1.SetShadowWidth(3)
+
+ self.g2 = wx.Gauge(
+ self, -1, 50, (110, 95), (250, 25),
+ wx.GA_HORIZONTAL|wx.GA_SMOOTH
+ )
+
+ self.g2.SetBezelFace(5)
+ self.g2.SetShadowWidth(5)
+
+ self.Bind(wx.EVT_IDLE, self.IdleHandler)
+
+
+ def IdleHandler(self, event):
+ self.count = self.count + 1
+
+ if self.count >= 50:
+ self.count = 0
+
+ self.g1.SetValue(self.count)
+ self.g2.SetValue(self.count)
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+A Gauge is a horizontal or vertical bar which shows a quantity in a graphical
+fashion. It is often used to indicate progress through lengthy tasks, such as
+file copying or data analysis.
+
+When the Gauge is initialized, it's "complete" value is usually set; at any rate,
+before using the Gauge, the maximum value of the control must be set. As the task
+progresses, the Gauge is updated by the program via the <code>SetValue</code> method.
+
+This control is for use within a GUI; there is a seperate ProgressDialog class
+to present the same sort of control as a dialog to the user.
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ txt1 = wx.StaticText(self, -1, "style=0")
+ dir1 = wx.GenericDirCtrl(self, -1, size=(200,225), style=0)
+
+ txt2 = wx.StaticText(self, -1, "wx.DIRCTRL_DIR_ONLY")
+ dir2 = wx.GenericDirCtrl(self, -1, size=(200,225), style=wx.DIRCTRL_DIR_ONLY)
+
+ txt3 = wx.StaticText(self, -1, "wx.DIRCTRL_SHOW_FILTERS")
+ dir3 = wx.GenericDirCtrl(self, -1, size=(200,225), style=wx.DIRCTRL_SHOW_FILTERS,
+ filter="All files (*.*)|*.*|Python files (*.py)|*.py")
+
+ sz = wx.FlexGridSizer(cols=3, hgap=5, vgap=5)
+ sz.Add((35, 35)) # some space above
+ sz.Add((35, 35))
+ sz.Add((35, 35))
+
+ sz.Add(txt1)
+ sz.Add(txt2)
+ sz.Add(txt3)
+
+ sz.Add(dir1, 0, wx.EXPAND)
+ sz.Add(dir2, 0, wx.EXPAND)
+ sz.Add(dir3, 0, wx.EXPAND)
+
+ sz.Add((35,35)) # some space below
+
+ sz.AddGrowableRow(2)
+ sz.AddGrowableCol(0)
+ sz.AddGrowableCol(1)
+ sz.AddGrowableCol(2)
+
+ self.SetSizer(sz)
+ self.SetAutoLayout(True)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+This control can be used to place a directory listing (with optional files)
+on an arbitrary window. The control contains a TreeCtrl window representing
+the directory hierarchy, and optionally, a Choice window containing a list
+of filters.
+
+The filters work in the same manner as in FileDialog.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+buttonDefs = {
+ 814 : ('GridSimple', ' Simple wxGrid, catching all events '),
+ 815 : ('GridStdEdRend', ' wxGrid showing Editors and Renderers '),
+ 818 : ('GridHugeTable', ' A wxGrid with a HUGE table (100 MILLION cells!) '),
+ 817 : ('GridCustTable', ' wxGrid using a custom Table, with non-string data '),
+ 819 : ('GridEnterHandler',' Remapping keys to behave differently '),
+ 820 : ('GridCustEditor', ' Shows how to create a custom Cell Editor '),
+ 821 : ('GridDragable', ' A wxGrid with dragable rows and columns '),
+ 822 : ('GridDragAndDrop', ' Shows how to make a grid a drop target for files'),
+ }
+
+
+class ButtonPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ box = wx.BoxSizer(wx.VERTICAL)
+ box.Add((20, 20))
+ keys = buttonDefs.keys()
+ keys.sort()
+
+ for k in keys:
+ text = buttonDefs[k][1]
+ btn = wx.Button(self, k, text)
+ box.Add(btn, 0, wx.ALIGN_CENTER|wx.ALL, 10)
+ self.Bind(wx.EVT_BUTTON, self.OnButton, btn)
+
+ self.SetAutoLayout(True)
+ self.SetSizer(box)
+
+
+ def OnButton(self, evt):
+ modName = buttonDefs[evt.GetId()][0]
+ module = __import__(modName)
+ frame = module.TestFrame(None, self.log)
+ frame.Show(True)
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = ButtonPanel(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+<html><body>
+<h2>wxGrid</h2>
+
+This demo shows various ways of using the <b><i>new and
+improved</i></b> wxGrid class. Unfortunatly it has not been
+documented yet, and while it is somewhat backwards compatible, if you
+try to go by the current wxGrid documentation you will probably just
+confuse yourself.
+<p>
+You can look at the sources for these samples to learn a lot about how
+the new classes work.
+<p><ol>
+<li><a href="GridSimple.py">GridSimple.py</a> A simple grid that shows
+how to catch all the various events.
+
+<p>
+<li><a href="GridStdEdRend.py">GridStdEdRend.py</a> A grid that
+uses non-default Cell Editors and Cell Renderers.
+
+<p>
+<li><a href="GridHugeTable.py">GridHugeTable.py</a> A grid that
+uses a non-default Grid Table. This table is read-only and simply
+generates on the fly a unique string for each cell.
+
+<p>
+<li><a href="GridCustTable.py">GridCustTable.py</a> This grid
+shows how to deal with tables that have non-string data, and how Cell
+Editors and Cell Renderers are automatically chosen based on the data
+type.
+
+<p>
+<li><a href="GridEnterHandler.py">GridEnterHandler.py</a>This one
+changes how the ENTER key works, moving the current cell left to right
+and wrapping around to the next row when needed.
+</ol>
+<p>
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+
+import wx # This module uses the new wx namespace
+
+#----------------------------------------------------------------------
+gbsDescription = """\
+The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned
+in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this
+static text is positioned at (0,0) and it spans 7 columns.
+"""
+
+
+class TestFrame(wx.Frame):
+ def __init__(self):
+ wx.Frame.__init__(self, None, -1, "wxGridBagSizer")
+ p = wx.Panel(self, -1)
+ p.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
+
+ gbs = self.gbs = wx.GridBagSizer(5, 5)
+
+ gbs.Add( wx.StaticText(p, -1, gbsDescription),
+ (0,0), (1,7), wx.ALIGN_CENTER | wx.ALL, 5)
+
+ gbs.Add( wx.TextCtrl(p, -1, "pos(1,0)"), (1,0) )
+ gbs.Add( wx.TextCtrl(p, -1, "pos(1,1)"), (1,1) )
+ gbs.Add( wx.TextCtrl(p, -1, "pos(2,0)"), (2,0) )
+ gbs.Add( wx.TextCtrl(p, -1, "pos(2,1)"), (2,1) )
+
+ gbs.Add( wx.TextCtrl(p, -1, "pos(3,2), span(1,2)\nthis row and col are growable", style=wx.TE_MULTILINE),
+ (3,2), (1,2), flag=wx.EXPAND )
+
+ gbs.Add( wx.TextCtrl(p, -1, "pos(4,3), span(3,1)", style=wx.TE_MULTILINE),
+ (4,3), (3,1), wx.EXPAND)
+
+ gbs.Add( wx.TextCtrl(p, -1, "pos(5,4)"), (5,4), flag=wx.EXPAND )
+ gbs.Add( wx.TextCtrl(p, -1, "pos(6,5)"), (6,5), flag=wx.EXPAND )
+ gbs.Add( wx.TextCtrl(p, -1, "pos(7,6)"), (7,6) )
+
+ moveBtn1 = wx.Button(p, -1, "Move this to (3,6)")
+ moveBtn2 = wx.Button(p, -1, "Move this to (3,6)");
+ gbs.Add( moveBtn1, (10,2) )
+ gbs.Add( moveBtn2, (10,3) )
+
+ hideBtn = wx.Button(p, -1, "Hide this item -->")
+ gbs.Add(hideBtn, (12, 3))
+
+ hideTxt = wx.TextCtrl(p, -1, "pos(12,4), size(150, -1)", size = (150,-1))
+ gbs.Add( hideTxt, (12,4) )
+
+ showBtn = wx.Button(p, -1, "<-- Show it again")
+ gbs.Add(showBtn, (12, 5))
+ showBtn.Disable()
+ self.hideBtn = hideBtn
+ self.showBtn = showBtn
+ self.hideTxt = hideTxt
+
+ self.Bind(wx.EVT_BUTTON, self.OnHideButton, hideBtn)
+ self.Bind(wx.EVT_BUTTON, self.OnShowButton, showBtn)
+ self.Bind(wx.EVT_BUTTON, self.OnMoveButton, moveBtn1)
+ self.Bind(wx.EVT_BUTTON, self.OnMoveButton, moveBtn2)
+
+ # Add a spacer at the end to ensure some extra space at the bottom
+ gbs.Add((10,10), (14,7))
+
+ gbs.AddGrowableRow(3)
+ gbs.AddGrowableCol(2)
+
+ p.SetSizerAndFit(gbs)
+ self.SetClientSize(p.GetSize())
+
+
+ def OnHideButton(self, evt):
+ self.gbs.Hide(self.hideTxt)
+ self.hideBtn.Disable()
+ self.showBtn.Enable()
+ self.gbs.Layout()
+
+
+ def OnShowButton(self, evt):
+ self.gbs.Show(self.hideTxt)
+ self.hideBtn.Enable()
+ self.showBtn.Disable()
+ self.gbs.Layout()
+
+
+ def OnMoveButton(self, evt):
+ btn = evt.GetEventObject()
+ curPos = self.gbs.GetItemPosition(btn)
+
+ # if it's already at the "other" spot then move it back
+ if curPos == (3,6):
+ self.gbs.SetItemPosition(btn, self.lastPos)
+ btn.SetLabel("Move this to (3,6)")
+ else:
+ if self.gbs.CheckForIntersection( (3,6), (1,1) ):
+ wx.MessageBox("""\
+wxGridBagSizer will not allow items to be in the same cell as
+another item, so this operation will fail. You will also get an assert
+when compiled in debug mode.""",
+ "Warning", wx.OK | wx.ICON_INFORMATION)
+
+ try:
+ if self.gbs.SetItemPosition(btn, (3,6)):
+ self.lastPos = curPos
+ btn.SetLabel("Move it back")
+ except wx.PyAssertionError:
+ pass
+
+ self.gbs.Layout()
+
+
+ def OnLeftDown(self, evt):
+ pt = evt.GetPosition()
+ item = self.gbs.FindItemAtPoint(pt)
+ if item is None:
+ print "no item at", `pt`
+ else:
+ print "item found: ", `item.GetPos()`, "--", `item.GetSpan()`
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestFrame()
+ frame.otherWin = win
+ win.Show(True)
+
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>wxGridBagSizer</center></h2>
+
+The wxGridBagSizer is more or less a port of the the RowColSizer (that
+has been in the wxPython.lib package for quite some time) to C++. It
+allows items to be placed at specific layout grid cells, and items can
+span across more than one row or column.
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import wx.grid as Grid
+
+import images
+
+class MegaTable(Grid.PyGridTableBase):
+ """
+ A custom wxGrid Table using user supplied data
+ """
+ def __init__(self, data, colnames, plugins):
+ """data is a list of the form
+ [(rowname, dictionary),
+ dictionary.get(colname, None) returns the data for column
+ colname
+ """
+ # The base class must be initialized *first*
+ Grid.PyGridTableBase.__init__(self)
+ self.data = data
+ self.colnames = colnames
+ self.plugins = plugins or {}
+ # XXX
+ # we need to store the row length and column length to
+ # see if the table has changed size
+ self._rows = self.GetNumberRows()
+ self._cols = self.GetNumberCols()
+
+ def GetNumberCols(self):
+ return len(self.colnames)
+
+ def GetNumberRows(self):
+ return len(self.data)
+
+ def GetColLabelValue(self, col):
+ return self.colnames[col]
+
+ def GetRowLabelValue(self, row):
+ return "row %03d" % int(self.data[row][0])
+
+ def GetValue(self, row, col):
+ return str(self.data[row][1].get(self.GetColLabelValue(col), ""))
+
+ def GetRawValue(self, row, col):
+ return self.data[row][1].get(self.GetColLabelValue(col), "")
+
+ def SetValue(self, row, col, value):
+ self.data[row][1][self.GetColLabelValue(col)] = value
+
+ def ResetView(self, grid):
+ """
+ (Grid) -> Reset the grid view. Call this to
+ update the grid if rows and columns have been added or deleted
+ """
+ grid.BeginBatch()
+
+ for current, new, delmsg, addmsg in [
+ (self._rows, self.GetNumberRows(), Grid.GRIDTABLE_NOTIFY_ROWS_DELETED, Grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
+ (self._cols, self.GetNumberCols(), Grid.GRIDTABLE_NOTIFY_COLS_DELETED, Grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
+ ]:
+
+ if new < current:
+ msg = Grid.GridTableMessage(self,delmsg,new,current-new)
+ grid.ProcessTableMessage(msg)
+ elif new > current:
+ msg = Grid.GridTableMessage(self,addmsg,new-current)
+ grid.ProcessTableMessage(msg)
+ self.UpdateValues(grid)
+
+ grid.EndBatch()
+
+ self._rows = self.GetNumberRows()
+ self._cols = self.GetNumberCols()
+ # update the column rendering plugins
+ self._updateColAttrs(grid)
+
+ # update the scrollbars and the displayed part of the grid
+ grid.AdjustScrollbars()
+ grid.ForceRefresh()
+
+
+ def UpdateValues(self, grid):
+ """Update all displayed values"""
+ # This sends an event to the grid table to update all of the values
+ msg = Grid.GridTableMessage(self, Grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
+ grid.ProcessTableMessage(msg)
+
+ def _updateColAttrs(self, grid):
+ """
+ wxGrid -> update the column attributes to add the
+ appropriate renderer given the column name. (renderers
+ are stored in the self.plugins dictionary)
+
+ Otherwise default to the default renderer.
+ """
+ col = 0
+
+ for colname in self.colnames:
+ attr = Grid.GridCellAttr()
+ if colname in self.plugins:
+ renderer = self.plugins[colname](self)
+
+ if renderer.colSize:
+ grid.SetColSize(col, renderer.colSize)
+
+ if renderer.rowSize:
+ grid.SetDefaultRowSize(renderer.rowSize)
+
+ attr.SetReadOnly(True)
+ attr.SetRenderer(renderer)
+
+ grid.SetColAttr(col, attr)
+ col += 1
+
+ # ------------------------------------------------------
+ # begin the added code to manipulate the table (non wx related)
+ def AppendRow(self, row):
+ #print 'append'
+ entry = {}
+
+ for name in self.colnames:
+ entry[name] = "Appended_%i"%row
+
+ # XXX Hack
+ # entry["A"] can only be between 1..4
+ entry["A"] = random.choice(range(4))
+ self.data.insert(row, ["Append_%i"%row, entry])
+
+ def DeleteCols(self, cols):
+ """
+ cols -> delete the columns from the dataset
+ cols hold the column indices
+ """
+ # we'll cheat here and just remove the name from the
+ # list of column names. The data will remain but
+ # it won't be shown
+ deleteCount = 0
+ cols = cols[:]
+ cols.sort()
+
+ for i in cols:
+ self.colnames.pop(i-deleteCount)
+ # we need to advance the delete count
+ # to make sure we delete the right columns
+ deleteCount += 1
+
+ if not len(self.colnames):
+ self.data = []
+
+ def DeleteRows(self, rows):
+ """
+ rows -> delete the rows from the dataset
+ rows hold the row indices
+ """
+ deleteCount = 0
+ rows = rows[:]
+ rows.sort()
+
+ for i in rows:
+ self.data.pop(i-deleteCount)
+ # we need to advance the delete count
+ # to make sure we delete the right rows
+ deleteCount += 1
+
+ def SortColumn(self, col):
+ """
+ col -> sort the data based on the column indexed by col
+ """
+ name = self.colnames[col]
+ _data = []
+
+ for row in self.data:
+ rowname, entry = row
+ _data.append((entry.get(name, None), row))
+
+ _data.sort()
+ self.data = []
+
+ for sortvalue, row in _data:
+ self.data.append(row)
+
+ # end table manipulation code
+ # ----------------------------------------------------------
+
+
+# --------------------------------------------------------------------
+# Sample wxGrid renderers
+
+class MegaImageRenderer(Grid.PyGridCellRenderer):
+ def __init__(self, table):
+ """
+ Image Renderer Test. This just places an image in a cell
+ based on the row index. There are N choices and the
+ choice is made by choice[row%N]
+ """
+ Grid.PyGridCellRenderer.__init__(self)
+ self.table = table
+ self._choices = [images.getSmilesBitmap,
+ images.getMondrianBitmap,
+ images.get_10s_Bitmap,
+ images.get_01c_Bitmap]
+
+ self.colSize = None
+ self.rowSize = None
+
+ def Draw(self, grid, attr, dc, rect, row, col, isSelected):
+ choice = self.table.GetRawValue(row, col)
+ bmp = self._choices[ choice % len(self._choices)]()
+ image = wx.MemoryDC()
+ image.SelectObject(bmp)
+
+ # clear the background
+ dc.SetBackgroundMode(wx.SOLID)
+
+ if isSelected:
+ dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
+ dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
+ else:
+ dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
+ dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
+ dc.DrawRectangleRect(rect)
+
+ #dc.DrawRectangle((rect.x, rect.y), (rect.width, rect.height))
+
+ # copy the image but only to the size of the grid cell
+ width, height = bmp.GetWidth(), bmp.GetHeight()
+
+ if width > rect.width-2:
+ width = rect.width-2
+
+ if height > rect.height-2:
+ height = rect.height-2
+
+ dc.Blit((rect.x+1, rect.y+1), (width, height),
+ image,
+ (0, 0), wx.COPY, True)
+
+
+class MegaFontRenderer(Grid.PyGridCellRenderer):
+ def __init__(self, table, color="blue", font="ARIAL", fontsize=8):
+ """Render data in the specified color and font and fontsize"""
+ Grid.PyGridCellRenderer.__init__(self)
+ self.table = table
+ self.color = color
+ self.font = wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, font)
+ self.selectedBrush = wx.Brush("blue", wx.SOLID)
+ self.normalBrush = wx.Brush(wx.WHITE, wx.SOLID)
+ self.colSize = None
+ self.rowSize = 50
+
+ def Draw(self, grid, attr, dc, rect, row, col, isSelected):
+ # Here we draw text in a grid cell using various fonts
+ # and colors. We have to set the clipping region on
+ # the grid's DC, otherwise the text will spill over
+ # to the next cell
+ dc.SetClippingRect(rect)
+
+ # clear the background
+ dc.SetBackgroundMode(wx.SOLID)
+
+ if isSelected:
+ dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
+ dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
+ else:
+ dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
+ dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
+ dc.DrawRectangleRect(rect)
+
+ #dc.DrawRectangle((rect.x, rect.y), (rect.width, rect.height))
+
+ text = self.table.GetValue(row, col)
+ dc.SetBackgroundMode(wx.SOLID)
+
+ # change the text background based on whether the grid is selected
+ # or not
+ if isSelected:
+ dc.SetBrush(self.selectedBrush)
+ dc.SetTextBackground("blue")
+ else:
+ dc.SetBrush(self.normalBrush)
+ dc.SetTextBackground("white")
+
+ dc.SetTextForeground(self.color)
+ dc.SetFont(self.font)
+ dc.DrawText(text, (rect.x+1, rect.y+1))
+
+ # Okay, now for the advanced class :)
+ # Let's add three dots "..."
+ # to indicate that that there is more text to be read
+ # when the text is larger than the grid cell
+
+ width, height = dc.GetTextExtent(text)
+
+ if width > rect.width-2:
+ width, height = dc.GetTextExtent("...")
+ x = rect.x+1 + rect.width-2 - width
+ dc.DrawRectangle((x, rect.y+1), (width+1, height))
+ dc.DrawText("...", (x, rect.y+1))
+
+ dc.DestroyClippingRegion()
+
+
+# --------------------------------------------------------------------
+# Sample Grid using a specialized table and renderers that can
+# be plugged in based on column names
+
+class MegaGrid(Grid.Grid):
+ def __init__(self, parent, data, colnames, plugins=None):
+ """parent, data, colnames, plugins=None
+ Initialize a grid using the data defined in data and colnames
+ (see MegaTable for a description of the data format)
+ plugins is a dictionary of columnName -> column renderers.
+ """
+
+ # The base class must be initialized *first*
+ Grid.Grid.__init__(self, parent, -1)
+ self._table = MegaTable(data, colnames, plugins)
+ self.SetTable(self._table)
+ self._plugins = plugins
+
+ self.Bind(Grid.EVT_GRID_LABEL_RIGHT_CLICK, self.OnLabelRightClicked)
+
+ def Reset(self):
+ """reset the view based on the data in the table. Call
+ this when rows are added or destroyed"""
+ self._table.ResetView(self)
+
+ def OnLabelRightClicked(self, evt):
+ # Did we click on a row or a column?
+ row, col = evt.GetRow(), evt.GetCol()
+ if row == -1: self.colPopup(col, evt)
+ elif col == -1: self.rowPopup(row, evt)
+
+ def rowPopup(self, row, evt):
+ """(row, evt) -> display a popup menu when a row label is right clicked"""
+ appendID = wx.NewId()
+ deleteID = wx.NewId()
+ x = self.GetRowSize(row)/2
+
+ if not self.GetSelectedRows():
+ self.SelectRow(row)
+
+ menu = wx.Menu()
+ xo, yo = evt.GetPosition()
+ menu.Append(appendID, "Append Row")
+ menu.Append(deleteID, "Delete Row(s)")
+
+ def append(event, self=self, row=row):
+ self._table.AppendRow(row)
+ self.Reset()
+
+ def delete(event, self=self, row=row):
+ rows = self.GetSelectedRows()
+ self._table.DeleteRows(rows)
+ self.Reset()
+
+ self.Bind(wx.EVT_MENU, append, id=appendID)
+ self.Bind(wx.EVT_MENU, delete, id=deleteID)
+ self.PopupMenu(menu, (x, yo))
+ menu.Destroy()
+ return
+
+
+ def colPopup(self, col, evt):
+ """(col, evt) -> display a popup menu when a column label is
+ right clicked"""
+ x = self.GetColSize(col)/2
+ menu = wx.Menu()
+ id1 = wx.NewId()
+ sortID = wx.NewId()
+
+ xo, yo = evt.GetPosition()
+ self.SelectCol(col)
+ cols = self.GetSelectedCols()
+ self.Refresh()
+ menu.Append(id1, "Delete Col(s)")
+ menu.Append(sortID, "Sort Column")
+
+ def delete(event, self=self, col=col):
+ cols = self.GetSelectedCols()
+ self._table.DeleteCols(cols)
+ self.Reset()
+
+ def sort(event, self=self, col=col):
+ self._table.SortColumn(col)
+ self.Reset()
+
+ self.Bind(wx.EVT_MENU, delete, id=id1)
+
+ if len(cols) == 1:
+ self.Bind(wx.EVT_MENU, sort, id=sortID)
+
+ self.PopupMenu(menu, (xo, 0))
+ menu.Destroy()
+ return
+
+# -----------------------------------------------------------------
+# Test data
+# data is in the form
+# [rowname, dictionary]
+# where dictionary.get(colname, None) -> returns the value for the cell
+#
+# the colname must also be supplied
+import random
+colnames = ["Row", "This", "Is", "A", "Test"]
+
+data = []
+
+for row in range(1000):
+ d = {}
+ for name in ["This", "Test", "Is"]:
+ d[name] = random.random()
+
+ d["Row"] = len(data)
+ # XXX
+ # the "A" column can only be between one and 4
+ d["A"] = random.choice(range(4))
+ data.append((str(row), d))
+
+class MegaFontRendererFactory:
+ def __init__(self, color, font, fontsize):
+ """
+ (color, font, fontsize) -> set of a factory to generate
+ renderers when called.
+ func = MegaFontRenderFactory(color, font, fontsize)
+ renderer = func(table)
+ """
+ self.color = color
+ self.font = font
+ self.fontsize = fontsize
+
+ def __call__(self, table):
+ return MegaFontRenderer(table, self.color, self.font, self.fontsize)
+
+
+#---------------------------------------------------------------------------
+
+class TestFrame(wx.Frame):
+ def __init__(self, parent, plugins={"This":MegaFontRendererFactory("red", "ARIAL", 8),
+ "A":MegaImageRenderer,
+ "Test":MegaFontRendererFactory("orange", "TIMES", 24),}):
+ wx.Frame.__init__(self, parent, -1,
+ "Test Frame", size=(640,480))
+
+ grid = MegaGrid(self, data, colnames, plugins)
+ grid.Reset()
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestFrame(frame)
+ frame.otherWin = win
+ win.Show(True)
+
+
+
+overview = """Mega Grid Example
+
+This example attempts to show many examples and tricks of
+using a virtual grid object. Hopefully the source isn't too jumbled.
+
+Features:
+<ol>
+ <li>Uses a virtual grid
+ <li>Columns and rows have popup menus (right click on labels)
+ <li>Columns and rows can be deleted (i.e. table can be
+ resized)
+ <li>Dynamic renderers. Renderers are plugins based on
+ column header name. Shows a simple Font Renderer and
+ an Image Renderer.
+</ol>
+
+Look for 'XXX' in the code to indicate some workarounds for non-obvious
+behavior and various hacks.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 12/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o got the wxpTag stuff working right.
+#
+# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxScrolledMessageDialog -> ScrolledMessageDialog
+#
+
+import os
+import sys
+
+import wx
+import wx.html as html
+import wx.lib.wxpTag
+
+from Main import opj
+
+#----------------------------------------------------------------------
+
+# This shows how to catch the OnLinkClicked non-event. (It's a virtual
+# method in the C++ code...)
+class MyHtmlWindow(html.HtmlWindow):
+ def __init__(self, parent, id, log):
+ html.HtmlWindow.__init__(self, parent, id, style=wx.NO_FULL_REPAINT_ON_RESIZE)
+ self.log = log
+ self.Bind(wx.EVT_SCROLLWIN, self.OnScroll )
+
+ def OnScroll( self, event ):
+ #print 'event.GetOrientation()',event.GetOrientation()
+ #print 'event.GetPosition()',event.GetPosition()
+ event.Skip()
+
+ def OnLinkClicked(self, linkinfo):
+ self.log.WriteText('OnLinkClicked: %s\n' % linkinfo.GetHref())
+
+ # Virtuals in the base class have been renamed with base_ on the front.
+ self.base_OnLinkClicked(linkinfo)
+
+
+ def OnSetTitle(self, title):
+ self.log.WriteText('OnSetTitle: %s\n' % title)
+ self.base_OnSetTitle(title)
+
+ def OnCellMouseHover(self, cell, x, y):
+ self.log.WriteText('OnCellMouseHover: %s, (%d %d)\n' % (cell, x, y))
+ self.base_OnCellMouseHover(cell, x, y)
+
+ def OnCellClicked(self, cell, x, y, evt):
+ self.log.WriteText('OnCellClicked: %s, (%d %d)\n' % (cell, x, y))
+ self.base_OnCellClicked(cell, x, y, evt)
+
+
+# This filter doesn't really do anything but show how to use filters
+class MyHtmlFilter(html.HtmlFilter):
+ def __init__(self, log):
+ html.HtmlFilter.__init__(self)
+ self.log = log
+
+ # This method decides if this filter is able to read the file
+ def CanRead(self, fsfile):
+ self.log.write("CanRead: %s\n" % fsfile.GetMimeType())
+ return False
+
+ # If CanRead returns True then this method is called to actually
+ # read the file and return the contents.
+ def ReadFile(self, fsfile):
+ return ""
+
+
+class TestHtmlPanel(wx.Panel):
+ def __init__(self, parent, frame, log):
+ wx.Panel.__init__(self, parent, -1, style=wx.NO_FULL_REPAINT_ON_RESIZE)
+ self.log = log
+ self.frame = frame
+ self.cwd = os.path.split(sys.argv[0])[0]
+
+ if not self.cwd:
+ self.cwd = os.getcwd()
+ if frame:
+ self.titleBase = frame.GetTitle()
+
+ html.HtmlWindow_AddFilter(MyHtmlFilter(log))
+
+ self.html = MyHtmlWindow(self, -1, log)
+ self.html.SetRelatedFrame(frame, self.titleBase + " -- %s")
+ self.html.SetRelatedStatusBar(0)
+
+ self.printer = html.HtmlEasyPrinting()
+
+ self.box = wx.BoxSizer(wx.VERTICAL)
+ self.box.Add(self.html, 1, wx.GROW)
+
+ subbox = wx.BoxSizer(wx.HORIZONTAL)
+
+ btn = wx.Button(self, -1, "Load File")
+ self.Bind(wx.EVT_BUTTON, self.OnLoadFile, btn)
+ subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
+
+ btn = wx.Button(self, -1, "Load URL")
+ self.Bind(wx.EVT_BUTTON, self.OnLoadURL, btn)
+ subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
+
+ btn = wx.Button(self, -1, "With Widgets")
+ self.Bind(wx.EVT_BUTTON, self.OnWithWidgets, btn)
+ subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
+
+ btn = wx.Button(self, -1, "Back")
+ self.Bind(wx.EVT_BUTTON, self.OnBack, btn)
+ subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
+
+ btn = wx.Button(self, -1, "Forward")
+ self.Bind(wx.EVT_BUTTON, self.OnForward, btn)
+ subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
+
+ btn = wx.Button(self, -1, "Print")
+ self.Bind(wx.EVT_BUTTON, self.OnPrint, btn)
+ subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
+
+ btn = wx.Button(self, -1, "View Source")
+ self.Bind(wx.EVT_BUTTON, self.OnViewSource, btn)
+ subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
+
+ self.box.Add(subbox, 0, wx.GROW)
+ self.SetSizer(self.box)
+ self.SetAutoLayout(True)
+
+ # A button with this ID is created on the widget test page.
+ self.Bind(wx.EVT_BUTTON, self.OnOk, id=wx.ID_OK)
+
+ self.OnShowDefault(None)
+
+
+ def ShutdownDemo(self):
+ # put the frame title back
+ if self.frame:
+ self.frame.SetTitle(self.titleBase)
+
+
+ def OnShowDefault(self, event):
+ name = os.path.join(self.cwd, opj('data/test.htm'))
+ self.html.LoadPage(name)
+
+
+ def OnLoadFile(self, event):
+ dlg = wx.FileDialog(self, wildcard = '*.htm*', style=wx.OPEN)
+
+ if dlg.ShowModal():
+ path = dlg.GetPath()
+ self.html.LoadPage(path)
+
+ dlg.Destroy()
+
+
+ def OnLoadURL(self, event):
+ dlg = wx.TextEntryDialog(self, "Enter a URL")
+
+ if dlg.ShowModal():
+ url = dlg.GetValue()
+ self.html.LoadPage(url)
+
+ dlg.Destroy()
+
+
+ def OnWithWidgets(self, event):
+ os.chdir(self.cwd)
+ name = os.path.join(self.cwd, opj('data/widgetTest.htm'))
+ self.html.LoadPage(name)
+
+
+ def OnOk(self, event):
+ self.log.WriteText("It works!\n")
+
+ def OnBack(self, event):
+ if not self.html.HistoryBack():
+ wx.MessageBox("No more items in history!")
+
+
+ def OnForward(self, event):
+ if not self.html.HistoryForward():
+ wx.MessageBox("No more items in history!")
+
+
+ def OnViewSource(self, event):
+ import wx.lib.dialogs
+
+ source = self.html.GetParser().GetSource()
+
+ dlg = wx.lib.dialogs.ScrolledMessageDialog(self, source, 'HTML Source')
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+ def OnPrint(self, event):
+ self.printer.GetPrintData().SetPaperId(wx.PAPER_LETTER)
+ self.printer.PrintFile(self.html.GetOpenedPage())
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestHtmlPanel(nb, frame, log)
+ print wx.Window_FindFocus()
+ return win
+
+
+#----------------------------------------------------------------------
+
+
+overview = """<html><body>
+<h2>wxHtmlWindow</h2>
+
+<p>wxHtmlWindow is capable of parsing and rendering most
+simple HTML tags.
+
+<p>It is not intended to be a high-end HTML browser. If you're
+looking for something like that see the IEHtmlWin class, which
+wraps the core MSIE HTML viewer.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+
+
+
+
+
+
+
--- /dev/null
+# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o iewin.py is missing
+#
+
+import wx
+
+if wx.Platform == '__WXMSW__':
+ import wx.iewin as iewin
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Window):
+ def __init__(self, parent, log, frame=None):
+ wx.Window.__init__(
+ self, parent, -1,
+ style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN|wx.NO_FULL_REPAINT_ON_RESIZE
+ )
+
+ self.log = log
+ self.current = "http://wxPython.org/"
+ self.frame = frame
+
+ if frame:
+ self.titleBase = frame.GetTitle()
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ self.ie = iewin.IEHtmlWin(self, -1, style = wx.NO_FULL_REPAINT_ON_RESIZE)
+
+
+ btn = wx.Button(self, wx.NewId(), "Open", style=wx.BU_EXACTFIT)
+ wx.EVT_BUTTON(self, btn.GetId(), self.OnOpenButton)
+ btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
+
+ btn = wx.Button(self, wx.NewId(), "Home", style=wx.BU_EXACTFIT)
+ wx.EVT_BUTTON(self, btn.GetId(), self.OnHomeButton)
+ btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
+
+ btn = wx.Button(self, wx.NewId(), "<--", style=wx.BU_EXACTFIT)
+ wx.EVT_BUTTON(self, btn.GetId(), self.OnPrevPageButton)
+ btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
+
+ btn = wx.Button(self, wx.NewId(), "-->", style=wx.BU_EXACTFIT)
+ wx.EVT_BUTTON(self, btn.GetId(), self.OnNextPageButton)
+ btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
+
+ btn = wx.Button(self, wx.NewId(), "Stop", style=wx.BU_EXACTFIT)
+ wx.EVT_BUTTON(self, btn.GetId(), self.OnStopButton)
+ btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
+
+ btn = wx.Button(self, wx.NewId(), "Search", style=wx.BU_EXACTFIT)
+ wx.EVT_BUTTON(self, btn.GetId(), self.OnSearchPageButton)
+ btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
+
+ btn = wx.Button(self, wx.NewId(), "Refresh", style=wx.BU_EXACTFIT)
+ wx.EVT_BUTTON(self, btn.GetId(), self.OnRefreshPageButton)
+ btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
+
+ txt = wx.StaticText(self, -1, "Location:")
+ btnSizer.Add(txt, 0, wx.CENTER|wx.ALL, 2)
+
+ self.location = wx.ComboBox(
+ self, wx.NewId(), "", style=wx.CB_DROPDOWN|wx.PROCESS_ENTER
+ )
+
+ wx.EVT_COMBOBOX(self, self.location.GetId(), self.OnLocationSelect)
+ wx.EVT_KEY_UP(self.location, self.OnLocationKey)
+ wx.EVT_CHAR(self.location, self.IgnoreReturn)
+ btnSizer.Add(self.location, 1, wx.EXPAND|wx.ALL, 2)
+
+ sizer.Add(btnSizer, 0, wx.EXPAND)
+ sizer.Add(self.ie, 1, wx.EXPAND)
+
+ self.ie.Navigate(self.current)
+ self.location.Append(self.current)
+
+ self.SetSizer(sizer)
+ self.SetAutoLayout(True)
+ wx.EVT_SIZE(self, self.OnSize)
+
+ # Hook up the event handlers for the IE window
+ iewin.EVT_MSHTML_BEFORENAVIGATE2(self, -1, self.OnBeforeNavigate2)
+ iewin.EVT_MSHTML_NEWWINDOW2(self, -1, self.OnNewWindow2)
+ iewin.EVT_MSHTML_DOCUMENTCOMPLETE(self, -1, self.OnDocumentComplete)
+ #EVT_MSHTML_PROGRESSCHANGE(self, -1, self.OnProgressChange)
+ iewin.EVT_MSHTML_STATUSTEXTCHANGE(self, -1, self.OnStatusTextChange)
+ iewin.EVT_MSHTML_TITLECHANGE(self, -1, self.OnTitleChange)
+
+
+ def ShutdownDemo(self):
+ # put the frame title back
+ if self.frame:
+ self.frame.SetTitle(self.titleBase)
+
+
+ def OnSize(self, evt):
+ self.Layout()
+
+
+ def OnLocationSelect(self, evt):
+ url = self.location.GetStringSelection()
+ self.log.write('OnLocationSelect: %s\n' % url)
+ self.ie.Navigate(url)
+
+ def OnLocationKey(self, evt):
+ if evt.KeyCode() == wx.WXK_RETURN:
+ URL = self.location.GetValue()
+ self.location.Append(URL)
+ self.ie.Navigate(URL)
+ else:
+ evt.Skip()
+
+
+ def IgnoreReturn(self, evt):
+ if evt.GetKeyCode() != wx.WXK_RETURN:
+ evt.Skip()
+
+ def OnOpenButton(self, event):
+ dlg = wx.TextEntryDialog(self, "Open Location",
+ "Enter a full URL or local path",
+ self.current, wx.OK|wx.CANCEL)
+ dlg.CentreOnParent()
+
+ if dlg.ShowModal() == wx.ID_OK:
+ self.current = dlg.GetValue()
+ self.ie.Navigate(self.current)
+
+ dlg.Destroy()
+
+ def OnHomeButton(self, event):
+ self.ie.GoHome() ## ET Phone Home!
+
+ def OnPrevPageButton(self, event):
+ self.ie.GoBack()
+
+ def OnNextPageButton(self, event):
+ self.ie.GoForward()
+
+ def OnStopButton(self, evt):
+ self.ie.Stop()
+
+ def OnSearchPageButton(self, evt):
+ self.ie.GoSearch()
+
+ def OnRefreshPageButton(self, evt):
+ self.ie.Refresh(iewin.IEHTML_REFRESH_COMPLETELY)
+
+
+ def logEvt(self, name, event):
+ self.log.write('%s: %s\n' %
+ (name, (event.GetLong1(), event.GetLong2(), event.GetText1())))
+
+ def OnBeforeNavigate2(self, evt):
+ self.logEvt('OnBeforeNavigate2', evt)
+
+ def OnNewWindow2(self, evt):
+ self.logEvt('OnNewWindow2', evt)
+ evt.Veto() # don't allow it
+
+ def OnDocumentComplete(self, evt):
+ self.logEvt('OnDocumentComplete', evt)
+ self.current = evt.GetText1()
+ self.location.SetValue(self.current)
+
+ def OnTitleChange(self, evt):
+ self.logEvt('OnTitleChange', evt)
+ if self.frame:
+ self.frame.SetTitle(self.titleBase + ' -- ' + evt.GetText1())
+
+ def OnStatusTextChange(self, evt):
+ self.logEvt('OnStatusTextChange', evt)
+ if self.frame:
+ self.frame.SetStatusText(evt.GetText1())
+
+
+#----------------------------------------------------------------------
+# for the demo framework...
+
+def runTest(frame, nb, log):
+ if wx.Platform == '__WXMSW__':
+ win = TestPanel(nb, log, frame)
+ return win
+ else:
+ dlg = wx.MessageDialog(frame, 'This demo only works on MSW.',
+ 'Sorry', wx.OK | wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+
+overview = """\
+<html><body>
+<h2>wxIEHtmlWin</h2>
+
+The wxIEHtmlWin class is the first example of using a contributed
+wxActiveX class in wxWindows C++. It is still experimental, but
+I think it is useful.
+
+<p> Using this class is simpler than ActiveXWrapper, doesn't rely on
+the win32all extensions, and is more "wx\'ish", meaning that it uses
+events and etc. as would be expected from any other wx window.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+
+#----------------------------------------------------------------------
+
--- /dev/null
+# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+from Main import opj
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ bmp = wx.Image(opj('bitmaps/image.bmp'), wx.BITMAP_TYPE_BMP).ConvertToBitmap()
+ gif = wx.Image(opj('bitmaps/image.gif'), wx.BITMAP_TYPE_GIF).ConvertToBitmap()
+ png = wx.Image(opj('bitmaps/image.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
+ jpg = wx.Image(opj('bitmaps/image.jpg'), wx.BITMAP_TYPE_JPEG).ConvertToBitmap()
+
+ panel = wx.Panel(nb, -1)
+
+ pos = 10
+ wx.StaticBitmap(panel, -1, bmp, (10, pos), (bmp.GetWidth(), bmp.GetHeight()))
+
+ pos = pos + bmp.GetHeight() + 10
+ wx.StaticBitmap(panel, -1, gif, (10, pos), (gif.GetWidth(), gif.GetHeight()))
+
+ pos = pos + gif.GetHeight() + 10
+ wx.StaticBitmap(panel, -1, png, (10, pos), (png.GetWidth(), png.GetHeight()))
+
+ pos = pos + png.GetHeight() + 10
+ wx.StaticBitmap(panel, -1, jpg, (10, pos), (jpg.GetWidth(), jpg.GetHeight()))
+
+ return panel
+
+#----------------------------------------------------------------------
+
+
+
+overview = """\
+<html>
+<body>
+This class encapsulates a platform-independent image. An image can be created
+from data, or using <code>wxBitmap.ConvertToImage</code>. An image can be loaded from
+a file in a variety of formats, and is extensible to new formats via image
+format handlers. Functions are available to set and get image bits, so it can
+be used for basic image manipulation.
+
+<p>The following image handlers are available. wxBMPHandler is always installed
+by default. To use other image formats, install the appropriate handler or use
+<code>wx.InitAllImageHandlers()</code>.
+
+<p>
+<table>
+<tr><td width=25%>wxBMPHandler</td> <td>For loading and saving, always installed.</td></tr>
+<tr><td>wxPNGHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxJPEGHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxGIFHandler</td> <td>Only for loading, due to legal issues.</td> </tr>
+<tr><td>wxPCXHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxPNMHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxTIFFHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxIFFHandler</td> <td>For loading only.</td> </tr>
+<tr><td>wxXPMHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxICOHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxCURHandler</td> <td>For loading and saving.</td> </tr>
+<tr><td>wxANIHandler</td> <td>For loading only.</td> </tr>
+</table>
+
+<p>When saving in PCX format, wxPCXHandler will count the number of different
+colours in the image; if there are 256 or less colours, it will save as 8 bit,
+else it will save as 24 bit.
+
+<p>Loading PNMs only works for ASCII or raw RGB images. When saving in PNM format,
+wxPNMHandler will always save as raw RGB.
+
+</body>
+</html>"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import cStringIO
+
+import wx
+
+from Main import opj
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+
+ data = open(opj('bitmaps/image.png'), "rb").read()
+ stream = cStringIO.StringIO(data)
+
+ bmp = wx.BitmapFromImage( wx.ImageFromStream( stream ))
+
+ wx.StaticText(
+ self, -1, "This image was loaded from a Python file-like object:",
+ (15, 15)
+ )
+
+ wx.StaticBitmap(self, -1, bmp, (15, 45))#, (bmp.GetWidth(), bmp.GetHeight()))
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+At long last there is finally a way to load any supported image type
+directly from any Python file-like object, such as a memory buffer
+using StringIO. """
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o intctrl needs the renamer applied.
+# o intctrl needs new event binders.
+#
+# 12/08/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o All issues corrected
+#
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxIntCtrl -> IntCtrl
+#
+
+import wx
+import wx.lib.intctrl
+
+#----------------------------------------------------------------------
+
+class TestPanel( wx.Panel ):
+ def __init__( self, parent, log ):
+
+ wx.Panel.__init__( self, parent, -1 )
+ self.log = log
+ panel = wx.Panel( self, -1 )
+
+ self.set_min = wx.CheckBox( panel, -1, "Set minimum value:" )
+ self.min = wx.lib.intctrl.IntCtrl( panel, size=( 50, -1 ) )
+ self.min.Enable( False )
+
+ self.set_max = wx.CheckBox( panel, -1, "Set maximum value:" )
+ self.max = wx.lib.intctrl.IntCtrl( panel, size=( 50, -1 ) )
+ self.max.Enable( False )
+
+ self.limit_target = wx.CheckBox( panel, -1, "Limit control" )
+ self.allow_none = wx.CheckBox( panel, -1, "Allow empty control" )
+ self.allow_long = wx.CheckBox( panel, -1, "Allow long integers" )
+
+ label = wx.StaticText( panel, -1, "Resulting integer control:" )
+ self.target_ctl = wx.lib.intctrl.IntCtrl( panel )
+
+ grid = wx.FlexGridSizer( 0, 2, 0, 0 )
+ grid.Add( self.set_min, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid.Add( self.min, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid.Add(self.set_max, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid.Add( self.max, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid.Add( self.limit_target, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid.Add( self.allow_none, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid.Add( self.allow_long, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid.Add( label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid.Add( self.target_ctl, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ outer_box = wx.BoxSizer( wx.VERTICAL )
+ outer_box.AddSizer( grid, 0, wx.ALIGN_CENTRE|wx.ALL, 20 )
+
+ panel.SetAutoLayout( True )
+ panel.SetSizer( outer_box )
+ outer_box.Fit( panel )
+ panel.Move( (50,50) )
+ self.panel = panel
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetMin, self.set_min)
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetMax, self.set_max)
+ self.Bind(wx.EVT_CHECKBOX, self.SetTargetMinMax, self.limit_target)
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowNone, self.allow_none)
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowLong, self.allow_long)
+
+ self.Bind(wx.lib.intctrl.EVT_INT, self.SetTargetMinMax, self.min)
+ self.Bind(wx.lib.intctrl.EVT_INT, self.SetTargetMinMax, self.max)
+ self.Bind(wx.lib.intctrl.EVT_INT, self.OnTargetChange, self.target_ctl)
+
+
+ def OnSetMin( self, event ):
+ self.min.Enable( self.set_min.GetValue() )
+ self.SetTargetMinMax()
+
+ def OnSetMax( self, event ):
+ self.max.Enable( self.set_max.GetValue() )
+ self.SetTargetMinMax()
+
+
+ def SetTargetMinMax( self, event=None ):
+ min = max = None
+ self.target_ctl.SetLimited( self.limit_target.GetValue() )
+
+ if self.set_min.GetValue():
+ min = self.min.GetValue()
+
+ if self.set_max.GetValue():
+ max = self.max.GetValue()
+
+ cur_min, cur_max = self.target_ctl.GetBounds()
+
+ if min != cur_min and not self.target_ctl.SetMin( min ):
+ self.log.write( "min (%d) > current max (%d) -- bound not set\n" % ( min, self.target_ctl.GetMax() ) )
+ self.min.SetForegroundColour( wx.RED )
+ else:
+ self.min.SetForegroundColour( wx.BLACK )
+
+ self.min.Refresh()
+
+ if max != cur_max and not self.target_ctl.SetMax( max ):
+ self.log.write( "max (%d) < current min (%d) -- bound not set\n" % ( max, self.target_ctl.GetMin() ) )
+ self.max.SetForegroundColour( wx.RED )
+ else:
+ self.max.SetForegroundColour( wx.BLACK )
+
+ self.max.Refresh()
+
+ if min != cur_min or max != cur_max:
+ new_min, new_max = self.target_ctl.GetBounds()
+ self.log.write( "current min, max: (%s, %s)\n" % ( str(new_min), str(new_max) ) )
+
+
+ def OnSetAllowNone( self, event ):
+ self.target_ctl.SetNoneAllowed( self.allow_none.GetValue() )
+
+
+ def OnSetAllowLong( self, event ):
+ self.target_ctl.SetLongAllowed( self.allow_long.GetValue() )
+
+
+ def OnTargetChange( self, event ):
+ ctl = event.GetEventObject()
+ value = ctl.GetValue()
+ ib_str = [ " (out of bounds)", "" ]
+ self.log.write( "integer value = %s%s\n" % ( str(value), ib_str[ ctl.IsInBounds(value) ] ) )
+
+
+#----------------------------------------------------------------------
+
+def runTest( frame, nb, log ):
+ win = TestPanel( nb, log )
+ return win
+
+#----------------------------------------------------------------------
+
+overview = """<html><body>
+<P>
+<B>IntCtrl</B> provides a control that takes and returns integers as
+value, and provides bounds support and optional value limiting.
+<P>
+<P>
+Here's the API for IntCtrl:
+<DL><PRE>
+ <B>IntCtrl</B>(
+ parent, id = -1,
+ <B>value</B> = 0,
+ <B>min</B> = None,
+ <B>max</B> = None,
+ <B>limited</B> = False,
+ <B>allow_none</B> = False,
+ <B>allow_long</B> = False,
+ <B>default_color</B> = wxBLACK,
+ <B>oob_color</B> = wxRED,
+ pos = wxDefaultPosition,
+ size = wxDefaultSize,
+ style = 0,
+ name = "integer")
+</PRE>
+<UL>
+ <DT><B>value</B>
+ <DD>If no initial value is set, the default will be zero, or
+ the minimum value, if specified. If an illegal string is specified,
+ a ValueError will result. (You can always later set the initial
+ value with SetValue() after instantiation of the control.)
+ <BR>
+ <DL><B>min</B>
+ <DD>The minimum value that the control should allow. This can be
+ adjusted with SetMin(). If the control is not limited, any value
+ below this bound will be colored with the current out-of-bounds color.
+ <BR>
+ <DT><B>max</B>
+ <DD>The maximum value that the control should allow. This can be
+ adjusted with SetMax(). If the control is not limited, any value
+ above this bound will be colored with the current out-of-bounds color.
+ <BR>
+ <DT><B>limited</B>
+ <DD>Boolean indicating whether the control prevents values from
+ exceeding the currently set minimum and maximum values (bounds).
+ If <I>False</I> and bounds are set, out-of-bounds values will
+ be colored with the current out-of-bounds color.
+ <BR>
+ <DT><B>allow_none</B>
+ <DD>Boolean indicating whether or not the control is allowed to be
+ empty, representing a value of <I>None</I> for the control.
+ <BR>
+ <DT><B>allow_long</B>
+ <DD>Boolean indicating whether or not the control is allowed to hold
+ and return a value of type long as well as int. If False, the
+ control will be implicitly limited to have a value such that
+ -sys.maxint-1 <= n <= sys.maxint.
+ <BR>
+ <DT><B>default_color</B>
+ <DD>Color value used for in-bounds values of the control.
+ <BR>
+ <DT><B>oob_color</B>
+ <DD>Color value used for out-of-bounds values of the control
+ when the bounds are set but the control is not limited.
+</UL>
+<BR>
+<BR>
+<DT><B>EVT_INT(win, id, func)</B>
+<DD>Respond to a wxEVT_COMMAND_INT_UPDATED event, generated when the
+value changes. Notice that this event will always be sent when the
+control's contents changes - whether this is due to user input or
+comes from the program itself (for example, if SetValue() is called.)
+<BR>
+<BR>
+<DT><B>SetValue(int)</B>
+<DD>Sets the value of the control to the integer value specified.
+The resulting actual value of the control may be altered to
+conform with the bounds set on the control if limited,
+or colored if not limited but the value is out-of-bounds.
+A ValueError exception will be raised if an invalid value
+is specified.
+<BR>
+<DT><B>GetValue()</B>
+<DD>Retrieves the integer value from the control. The value
+retrieved will be sized as an int if possible or a long,
+if necessary.
+<BR>
+<BR>
+<DT><B>SetMin(min=None)</B>
+<DD>Sets the expected minimum value, or lower bound, of the control.
+(The lower bound will only be enforced if the control is
+configured to limit its values to the set bounds.)
+If a value of <I>None</I> is provided, then the control will have
+no explicit lower bound. If the value specified is greater than
+the current lower bound, then the function returns 0 and the
+lower bound will not change from its current setting. On success,
+the function returns 1.
+<DT><DD>If successful and the current value is
+lower than the new lower bound, if the control is limited, the
+value will be automatically adjusted to the new minimum value;
+if not limited, the value in the control will be colored with
+the current out-of-bounds color.
+<BR>
+<DT><B>GetMin()</B>
+<DD>Gets the current lower bound value for the control.
+It will return None if no lower bound is currently specified.
+<BR>
+<BR>
+<DT><B>SetMax(max=None)</B>
+<DD>Sets the expected maximum value, or upper bound, of the control.
+(The upper bound will only be enforced if the control is
+configured to limit its values to the set bounds.)
+If a value of <I>None</I> is provided, then the control will
+have no explicit upper bound. If the value specified is less
+than the current lower bound, then the function returns 0 and
+the maximum will not change from its current setting. On success,
+the function returns 1.
+<DT><DD>If successful and the current value
+is greater than the new upper bound, if the control is limited
+the value will be automatically adjusted to the new maximum value;
+if not limited, the value in the control will be colored with the
+current out-of-bounds color.
+<BR>
+<DT><B>GetMax()</B>
+<DD>Gets the current upper bound value for the control.
+It will return None if no upper bound is currently specified.
+<BR>
+<BR>
+<DT><B>SetBounds(min=None,max=None)</B>
+<DD>This function is a convenience function for setting the min and max
+values at the same time. The function only applies the maximum bound
+if setting the minimum bound is successful, and returns True
+only if both operations succeed. <B><I>Note:</I></B> leaving out an argument
+will remove the corresponding bound.
+<DT><B>GetBounds()</B>
+<DD>This function returns a two-tuple (min,max), indicating the
+current bounds of the control. Each value can be None if
+that bound is not set.
+<BR>
+<BR>
+<DT><B>IsInBounds(value=None)</B>
+<DD>Returns <I>True</I> if no value is specified and the current value
+of the control falls within the current bounds. This function can also
+be called with a value to see if that value would fall within the current
+bounds of the given control.
+<BR>
+<BR>
+<DT><B>SetLimited(bool)</B>
+<DD>If called with a value of True, this function will cause the control
+to limit the value to fall within the bounds currently specified.
+If the control's value currently exceeds the bounds, it will then
+be limited accordingly.
+If called with a value of 0, this function will disable value
+limiting, but coloring of out-of-bounds values will still take
+place if bounds have been set for the control.
+<DT><B>IsLimited()</B>
+<DD>Returns <I>True</I> if the control is currently limiting the
+value to fall within the current bounds.
+<BR>
+<BR>
+<DT><B>SetNoneAllowed(bool)</B>
+<DD>If called with a value of True, this function will cause the control
+to allow the value to be empty, representing a value of None.
+If called with a value of false, this function will prevent the value
+from being None. If the value of the control is currently None,
+ie. the control is empty, then the value will be changed to that
+of the lower bound of the control, or 0 if no lower bound is set.
+<DT><B>IsNoneAllowed()</B>
+<DD>Returns <I>True</I> if the control currently allows its
+value to be None.
+<BR>
+<BR>
+<DT><B>SetLongAllowed(bool)</B>
+<DD>If called with a value of True, this function will cause the
+control to allow the value to be a long. If called with a value
+of False, and the value of the control is currently a long value,
+the value of the control will be adjusted to fall within the
+size of an integer type, at either the sys.maxint or -sys.maxint-1,
+for positive and negative values, respectively.
+<DT><B>IsLongAllowed()</B>
+<DD>Returns <I>True</I> if the control currently allows its
+value to be of type long.
+<BR>
+<BR>
+<DT><B>SetColors(default_color=wxBLACK, oob_color=wxRED)</B>
+<DD>Tells the control what colors to use for normal and out-of-bounds
+values. If the value currently exceeds the bounds, it will be
+recolored accordingly.
+<DT><B>GetColors()</B>
+<DD>Returns a tuple of <I>(default_color, oob_color)</I> indicating
+the current color settings for the control.
+<BR>
+<BR>
+<DT><B>Cut()</B>
+<DD>Will allow cuts to the clipboard of the text portion of the value,
+leaving the value of zero if the entire contents are "cut."
+<DT><B>Paste()</B>
+<DD>Will paste the contents of the clipboard to the selected portion
+of the value; if the resulting string does not represent a legal
+value, a ValueError will result. If the result is out-of bounds,
+it will either be adjusted or colored as appropriate.
+</DL>
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+
+#----------------------------------------------------------------------------
+
+from wxPython.wx import *
+from joystick_wdr import *
+
+
+class JoystickTestPanel(wxPanel):
+ def __init__(self, parent, id,
+ pos = wxDefaultPosition, size = wxDefaultSize,
+ style = wxTAB_TRAVERSAL ):
+ wxPanel.__init__(self, parent, id, pos, size, style)
+
+ MakeJoystickTestPanel( self, True )
+
+ try:
+ self.stick = wxJoystick()
+ self.stick.SetCapture(self)
+ EVT_JOYSTICK_EVENTS(self, self.OnJoystick)
+ self.UpdateFields()
+ except NotImplementedError, v:
+ wxMessageBox(str(v), "Exception Message")
+
+
+ def UpdateFields(self):
+ s = self.stick
+ self.GetXPositionCtrl().SetValue(str(s.GetPosition().x))
+ self.GetYPositionCtrl().SetValue(str(s.GetPosition().y))
+ self.GetZPositionCtrl().SetValue(str(s.GetZPosition()))
+ self.GetPovCtsPosCtrl().SetValue(str(s.GetPOVPosition()))
+ self.GetRudderPosCtrl().SetValue(str(s.GetRudderPosition()))
+ self.GetHasRudderCtrl().SetValue(str(s.HasRudder()))
+ self.GetHasZCtrl().SetValue(str(s.HasZ()))
+ self.GetHasPovCtrl().SetValue(str(s.HasPOV()))
+ self.GetHasPov4dirCtrl().SetValue(str(s.HasPOV4Dir()))
+ self.GetMfgIdCtrl().SetValue(str(s.GetManufacturerId()))
+ self.GetProdNameCtrl().SetValue(str(s.GetProductName()))
+ self.GetZMinCtrl().SetValue(str(s.GetZMin()))
+ self.GetXMaxCtrl().SetValue(str(s.GetXMax()))
+ self.GetNumButtonsCtrl().SetValue(str(s.GetNumberButtons()))
+ self.GetNumAxesCtrl().SetValue(str(s.GetNumberAxes()))
+ self.GetPollingMinCtrl().SetValue(str(s.GetPollingMin()))
+ self.GetPollingMaxCtrl().SetValue(str(s.GetPollingMax()))
+ self.GetUMinCtrl().SetValue(str(s.GetUMin()))
+ self.GetUMaxCtrl().SetValue(str(s.GetUMax()))
+ self.GetButtonStateCtrl().SetValue(str(s.GetButtonState()))
+ self.GetPovPositionCtrl().SetValue(str(s.GetPOVPosition()))
+ self.GetUPositionCtrl().SetValue(str(s.GetUPosition()))
+ self.GetVPositionCtrl().SetValue(str(s.GetVPosition()))
+ self.GetHasUCtrl().SetValue(str(s.HasU()))
+ self.GetHasVCtrl().SetValue(str(s.HasV()))
+ self.GetHasPovCtsCtrl().SetValue(str(s.HasPOVCTS()))
+ self.GetNumSticksCtrl().SetValue(str(s.GetNumberJoysticks()))
+ self.GetXMinCtrl().SetValue(str(s.GetXMin()))
+ self.GetYMinCtrl().SetValue(str(s.GetYMin()))
+ self.GetYMaxCtrl().SetValue(str(s.GetYMax()))
+ self.GetZMaxCtrl().SetValue(str(s.GetZMax()))
+ self.GetMaxButtonsCtrl().SetValue(str(s.GetMaxButtons()))
+ self.GetMaxAxesCtrl().SetValue(str(s.GetMaxAxes()))
+ self.GetRudderMinCtrl().SetValue(str(s.GetRudderMin()))
+ self.GetRudderMaxCtrl().SetValue(str(s.GetRudderMax()))
+ self.GetVMinCtrl().SetValue(str(s.GetVMin()))
+ self.GetVMaxCtrl().SetValue(str(s.GetVMax()))
+
+
+ def OnJoystick(self, evt):
+ self.UpdateFields()
+
+
+ # WDR: methods for JoystickTestPanel
+
+ def GetYPositionCtrl(self):
+ return self.FindWindowById(ID_Y_Position_Ctrl)
+
+ def GetXPositionCtrl(self):
+ return self.FindWindowById(ID_X_Position_Ctrl)
+
+
+ def GetVMaxCtrl(self):
+ return self.FindWindowById(ID_V_Max_Ctrl)
+
+ def GetVMinCtrl(self):
+ return self.FindWindowById(ID_V_Min_Ctrl)
+
+ def GetRudderMaxCtrl(self):
+ return self.FindWindowById(ID_Rudder_Max_Ctrl)
+
+ def GetRudderMinCtrl(self):
+ return self.FindWindowById(ID_Rudder_Min_Ctrl)
+
+ def GetMaxAxesCtrl(self):
+ return self.FindWindowById(ID_Max_Axes_Ctrl)
+
+ def GetMaxButtonsCtrl(self):
+ return self.FindWindowById(ID_Max_Buttons_Ctrl)
+
+ def GetZMaxCtrl(self):
+ return self.FindWindowById(ID_Z_Max_Ctrl)
+
+ def GetYMaxCtrl(self):
+ return self.FindWindowById(ID_Y_Max_Ctrl)
+
+ def GetYMinCtrl(self):
+ return self.FindWindowById(ID_Y_Min_Ctrl)
+
+ def GetXMinCtrl(self):
+ return self.FindWindowById(ID_X_Min_Ctrl)
+
+ def GetNumSticksCtrl(self):
+ return self.FindWindowById(ID_Num_Sticks_Ctrl)
+
+ def GetHasPovCtsCtrl(self):
+ return self.FindWindowById(ID_Has_POV_CTS_Ctrl)
+
+ def GetHasVCtrl(self):
+ return self.FindWindowById(ID_Has_V_Ctrl)
+
+ def GetHasUCtrl(self):
+ return self.FindWindowById(ID_Has_U_Ctrl)
+
+ def GetVPositionCtrl(self):
+ return self.FindWindowById(ID_V_Position_Ctrl)
+
+ def GetUPositionCtrl(self):
+ return self.FindWindowById(ID_U_Position_Ctrl)
+
+ def GetPovPositionCtrl(self):
+ return self.FindWindowById(ID_POV_Position_Ctrl)
+
+ def GetButtonStateCtrl(self):
+ return self.FindWindowById(ID_Button_State_Ctrl)
+
+ def GetUMaxCtrl(self):
+ return self.FindWindowById(ID_U_Max_Ctrl)
+
+ def GetUMinCtrl(self):
+ return self.FindWindowById(ID_U_Min_Ctrl)
+
+ def GetPollingMaxCtrl(self):
+ return self.FindWindowById(ID_Polling_Max_Ctrl)
+
+ def GetPollingMinCtrl(self):
+ return self.FindWindowById(ID_Polling_Min_Ctrl)
+
+ def GetNumAxesCtrl(self):
+ return self.FindWindowById(ID_Num_Axes_Ctrl)
+
+ def GetNumButtonsCtrl(self):
+ return self.FindWindowById(ID_Num_Buttons_Ctrl)
+
+ def GetXMaxCtrl(self):
+ return self.FindWindowById(ID_X_Max_Ctrl)
+
+ def GetZMinCtrl(self):
+ return self.FindWindowById(ID_Z_Min_Ctrl)
+
+ def GetProdNameCtrl(self):
+ return self.FindWindowById(ID_Prod_Name_Ctrl)
+
+ def GetMfgIdCtrl(self):
+ return self.FindWindowById(ID_Mfg_ID_Ctrl)
+
+ def GetHasPov4dirCtrl(self):
+ return self.FindWindowById(ID_Has_POV_4DIR_Ctrl)
+
+ def GetHasPovCtrl(self):
+ return self.FindWindowById(ID_Has_POV_Ctrl)
+
+ def GetHasZCtrl(self):
+ return self.FindWindowById(ID_Has_Z_Ctrl)
+
+ def GetHasRudderCtrl(self):
+ return self.FindWindowById(ID_Has_Rudder_Ctrl)
+
+ def GetRudderPosCtrl(self):
+ return self.FindWindowById(ID_Rudder_Pos_Ctrl)
+
+ def GetPovCtsPosCtrl(self):
+ return self.FindWindowById(ID_POV_CTS_Pos_Ctrl)
+
+ def GetZPositionCtrl(self):
+ return self.FindWindowById(ID_Z_Position_Ctrl)
+
+ # WDR: handler implementations for JoysticktestPanel
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = JoystickTestPanel(nb, -1)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o lib.mixins.listctrl needs wx renamer applied.
+#
+# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxListCtrlAutoWidthMixin -> ListCtrlAutoWidthMixin
+#
+
+import wx
+import wx.lib.mixins.listctrl as listmix
+
+#----------------------------------------------------------------------
+
+keyMap = {
+ wx.WXK_BACK : "wx.WXK_BACK",
+ wx.WXK_TAB : "wx.WXK_TAB",
+ wx.WXK_RETURN : "wx.WXK_RETURN",
+ wx.WXK_ESCAPE : "wx.WXK_ESCAPE",
+ wx.WXK_SPACE : "wx.WXK_SPACE",
+ wx.WXK_DELETE : "wx.WXK_DELETE",
+ wx.WXK_START : "wx.WXK_START",
+ wx.WXK_LBUTTON : "wx.WXK_LBUTTON",
+ wx.WXK_RBUTTON : "wx.WXK_RBUTTON",
+ wx.WXK_CANCEL : "wx.WXK_CANCEL",
+ wx.WXK_MBUTTON : "wx.WXK_MBUTTON",
+ wx.WXK_CLEAR : "wx.WXK_CLEAR",
+ wx.WXK_SHIFT : "wx.WXK_SHIFT",
+ wx.WXK_ALT : "wx.WXK_ALT",
+ wx.WXK_CONTROL : "wx.WXK_CONTROL",
+ wx.WXK_MENU : "wx.WXK_MENU",
+ wx.WXK_PAUSE : "wx.WXK_PAUSE",
+ wx.WXK_CAPITAL : "wx.WXK_CAPITAL",
+ wx.WXK_PRIOR : "wx.WXK_PRIOR",
+ wx.WXK_NEXT : "wx.WXK_NEXT",
+ wx.WXK_END : "wx.WXK_END",
+ wx.WXK_HOME : "wx.WXK_HOME",
+ wx.WXK_LEFT : "wx.WXK_LEFT",
+ wx.WXK_UP : "wx.WXK_UP",
+ wx.WXK_RIGHT : "wx.WXK_RIGHT",
+ wx.WXK_DOWN : "wx.WXK_DOWN",
+ wx.WXK_SELECT : "wx.WXK_SELECT",
+ wx.WXK_PRINT : "wx.WXK_PRINT",
+ wx.WXK_EXECUTE : "wx.WXK_EXECUTE",
+ wx.WXK_SNAPSHOT : "wx.WXK_SNAPSHOT",
+ wx.WXK_INSERT : "wx.WXK_INSERT",
+ wx.WXK_HELP : "wx.WXK_HELP",
+ wx.WXK_NUMPAD0 : "wx.WXK_NUMPAD0",
+ wx.WXK_NUMPAD1 : "wx.WXK_NUMPAD1",
+ wx.WXK_NUMPAD2 : "wx.WXK_NUMPAD2",
+ wx.WXK_NUMPAD3 : "wx.WXK_NUMPAD3",
+ wx.WXK_NUMPAD4 : "wx.WXK_NUMPAD4",
+ wx.WXK_NUMPAD5 : "wx.WXK_NUMPAD5",
+ wx.WXK_NUMPAD6 : "wx.WXK_NUMPAD6",
+ wx.WXK_NUMPAD7 : "wx.WXK_NUMPAD7",
+ wx.WXK_NUMPAD8 : "wx.WXK_NUMPAD8",
+ wx.WXK_NUMPAD9 : "wx.WXK_NUMPAD9",
+ wx.WXK_MULTIPLY : "wx.WXK_MULTIPLY",
+ wx.WXK_ADD : "wx.WXK_ADD",
+ wx.WXK_SEPARATOR : "wx.WXK_SEPARATOR",
+ wx.WXK_SUBTRACT : "wx.WXK_SUBTRACT",
+ wx.WXK_DECIMAL : "wx.WXK_DECIMAL",
+ wx.WXK_DIVIDE : "wx.WXK_DIVIDE",
+ wx.WXK_F1 : "wx.WXK_F1",
+ wx.WXK_F2 : "wx.WXK_F2",
+ wx.WXK_F3 : "wx.WXK_F3",
+ wx.WXK_F4 : "wx.WXK_F4",
+ wx.WXK_F5 : "wx.WXK_F5",
+ wx.WXK_F6 : "wx.WXK_F6",
+ wx.WXK_F7 : "wx.WXK_F7",
+ wx.WXK_F8 : "wx.WXK_F8",
+ wx.WXK_F9 : "wx.WXK_F9",
+ wx.WXK_F10 : "wx.WXK_F10",
+ wx.WXK_F11 : "wx.WXK_F11",
+ wx.WXK_F12 : "wx.WXK_F12",
+ wx.WXK_F13 : "wx.WXK_F13",
+ wx.WXK_F14 : "wx.WXK_F14",
+ wx.WXK_F15 : "wx.WXK_F15",
+ wx.WXK_F16 : "wx.WXK_F16",
+ wx.WXK_F17 : "wx.WXK_F17",
+ wx.WXK_F18 : "wx.WXK_F18",
+ wx.WXK_F19 : "wx.WXK_F19",
+ wx.WXK_F20 : "wx.WXK_F20",
+ wx.WXK_F21 : "wx.WXK_F21",
+ wx.WXK_F22 : "wx.WXK_F22",
+ wx.WXK_F23 : "wx.WXK_F23",
+ wx.WXK_F24 : "wx.WXK_F24",
+ wx.WXK_NUMLOCK : "wx.WXK_NUMLOCK",
+ wx.WXK_SCROLL : "wx.WXK_SCROLL",
+ wx.WXK_PAGEUP : "wx.WXK_PAGEUP",
+ wx.WXK_PAGEDOWN : "wx.WXK_PAGEDOWN",
+ wx.WXK_NUMPAD_SPACE : "wx.WXK_NUMPAD_SPACE",
+ wx.WXK_NUMPAD_TAB : "wx.WXK_NUMPAD_TAB",
+ wx.WXK_NUMPAD_ENTER : "wx.WXK_NUMPAD_ENTER",
+ wx.WXK_NUMPAD_F1 : "wx.WXK_NUMPAD_F1",
+ wx.WXK_NUMPAD_F2 : "wx.WXK_NUMPAD_F2",
+ wx.WXK_NUMPAD_F3 : "wx.WXK_NUMPAD_F3",
+ wx.WXK_NUMPAD_F4 : "wx.WXK_NUMPAD_F4",
+ wx.WXK_NUMPAD_HOME : "wx.WXK_NUMPAD_HOME",
+ wx.WXK_NUMPAD_LEFT : "wx.WXK_NUMPAD_LEFT",
+ wx.WXK_NUMPAD_UP : "wx.WXK_NUMPAD_UP",
+ wx.WXK_NUMPAD_RIGHT : "wx.WXK_NUMPAD_RIGHT",
+ wx.WXK_NUMPAD_DOWN : "wx.WXK_NUMPAD_DOWN",
+ wx.WXK_NUMPAD_PRIOR : "wx.WXK_NUMPAD_PRIOR",
+ wx.WXK_NUMPAD_PAGEUP : "wx.WXK_NUMPAD_PAGEUP",
+ wx.WXK_NUMPAD_NEXT : "wx.WXK_NUMPAD_NEXT",
+ wx.WXK_NUMPAD_PAGEDOWN : "wx.WXK_NUMPAD_PAGEDOWN",
+ wx.WXK_NUMPAD_END : "wx.WXK_NUMPAD_END",
+ wx.WXK_NUMPAD_BEGIN : "wx.WXK_NUMPAD_BEGIN",
+ wx.WXK_NUMPAD_INSERT : "wx.WXK_NUMPAD_INSERT",
+ wx.WXK_NUMPAD_DELETE : "wx.WXK_NUMPAD_DELETE",
+ wx.WXK_NUMPAD_EQUAL : "wx.WXK_NUMPAD_EQUAL",
+ wx.WXK_NUMPAD_MULTIPLY : "wx.WXK_NUMPAD_MULTIPLY",
+ wx.WXK_NUMPAD_ADD : "wx.WXK_NUMPAD_ADD",
+ wx.WXK_NUMPAD_SEPARATOR : "wx.WXK_NUMPAD_SEPARATOR",
+ wx.WXK_NUMPAD_SUBTRACT : "wx.WXK_NUMPAD_SUBTRACT",
+ wx.WXK_NUMPAD_DECIMAL : "wx.WXK_NUMPAD_DECIMAL",
+ wx.WXK_NUMPAD_DIVIDE : "wx.WXK_NUMPAD_DIVIDE",
+}
+
+
+#----------------------------------------------------------------------
+
+class KeySink(wx.Window):
+ def __init__(self, parent):
+ wx.Window.__init__(self, parent, -1, style=wx.WANTS_CHARS
+ #| wx.RAISED_BORDER
+ #| wx.SUNKEN_BORDER
+ )
+
+ self.SetBackgroundColour(wx.BLUE)
+ self.haveFocus = False
+ self.callSkip = False
+ self.logKeyDn = True
+ self.logKeyUp = True
+ self.logChar = True
+
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+ self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
+ self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
+ self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
+
+ self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+ self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
+ self.Bind(wx.EVT_CHAR, self.OnChar)
+
+
+ def SetCallSkip(self, skip):
+ self.callSkip = skip
+
+ def SetLogKeyUp(self, val):
+ self.logKeyUp = val
+
+ def SetLogKeyDn(self, val):
+ self.logKeyDn = val
+
+ def SetLogChar(self, val):
+ self.logChar = val
+
+
+ def OnPaint(self, evt):
+ dc = wx.PaintDC(self)
+ rect = self.GetClientRect()
+ dc.SetTextForeground(wx.WHITE)
+ dc.DrawLabel("Click here and then press some keys",
+ rect, wx.ALIGN_CENTER | wx.ALIGN_TOP)
+ if self.haveFocus:
+ dc.SetTextForeground(wx.GREEN)
+ dc.DrawLabel("Have Focus", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM)
+ else:
+ dc.SetTextForeground(wx.RED)
+ dc.DrawLabel("Need Focus!", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM)
+
+
+ def OnSetFocus(self, evt):
+ self.haveFocus = True
+ self.Refresh()
+
+ def OnKillFocus(self, evt):
+ self.haveFocus = False
+ self.Refresh()
+
+ def OnMouse(self, evt):
+ if evt.ButtonDown():
+ self.SetFocus()
+
+
+ def OnKeyDown(self, evt):
+ if self.logKeyDn:
+ self.GetParent().keylog.LogKeyEvent("KeyDown", evt)
+ if self.callSkip:
+ evt.Skip()
+
+ def OnKeyUp(self, evt):
+ if self.logKeyUp:
+ self.GetParent().keylog.LogKeyEvent("KeyUp", evt)
+ if self.callSkip:
+ evt.Skip()
+
+ def OnChar(self, evt):
+ if self.logChar:
+ self.GetParent().keylog.LogKeyEvent("Char", evt)
+
+
+#----------------------------------------------------------------------
+
+class KeyLog(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
+
+ def __init__(self, parent):
+ wx.ListCtrl.__init__(self, parent, -1,
+ style = wx.LC_REPORT|wx.LC_VRULES|wx.LC_HRULES)
+ listmix.ListCtrlAutoWidthMixin.__init__(self)
+
+ self.InsertColumn(0, "Event Type")
+ self.InsertColumn(1, "Key Name")
+ self.InsertColumn(2, "Key Code")
+ self.InsertColumn(3, "Modifiers")
+ self.InsertColumn(4, "RawKeyCode")
+ self.InsertColumn(5, "RawKeyFlags")
+ self.InsertColumn(6, "")
+
+ for x in range(6):
+ self.SetColumnWidth(x, wx.LIST_AUTOSIZE_USEHEADER)
+
+ self.SetColumnWidth(1, 125)
+
+
+ def LogKeyEvent(self, evType, evt):
+ keycode = evt.GetKeyCode()
+ keyname = keyMap.get(keycode, None)
+ if keyname is None:
+ if keycode < 256:
+ if keycode == 0:
+ keyname = "NUL"
+ elif keycode < 27:
+ keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
+ else:
+ keyname = "\"%s\"" % chr(keycode)
+ else:
+ keyname = "unknown (%s)" % keycode
+
+ modifiers = ""
+ for mod, ch in [(evt.ControlDown(), 'C'),
+ (evt.AltDown(), 'A'),
+ (evt.ShiftDown(), 'S'),
+ (evt.MetaDown(), 'M')]:
+ if mod:
+ modifiers += ch
+ else:
+ modifiers += '-'
+
+ id = self.InsertStringItem(self.GetItemCount(), evType)
+ self.SetStringItem(id, 1, keyname)
+ self.SetStringItem(id, 2, str(keycode))
+ self.SetStringItem(id, 3, modifiers)
+ self.SetStringItem(id, 4, str(evt.GetRawKeyCode()))
+ self.SetStringItem(id, 5, str(evt.GetRawKeyFlags()))
+
+ #print ( id, evType, keyname, str(keycode), modifiers, str(evt.GetRawKeyCode()), str(evt.GetRawKeyFlags()))
+
+ self.EnsureVisible(id)
+
+
+ def ClearLog(self):
+ self.DeleteAllItems()
+
+
+#----------------------------------------------------------------------
+
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1, style=0)
+ self.keysink = KeySink(self)
+ self.keysink.SetSize((100, 65))
+ self.keylog = KeyLog(self)
+
+ btn = wx.Button(self, -1, "Clear Log")
+ self.Bind(wx.EVT_BUTTON, self.OnClearBtn, btn)
+
+ cb1 = wx.CheckBox(self, -1, "Call evt.Skip for Key Up/Dn events")
+ self.Bind(wx.EVT_CHECKBOX, self.OnSkipCB, cb1)
+
+ cb2 = wx.CheckBox(self, -1, "EVT_KEY_UP")
+ self.Bind(wx.EVT_CHECKBOX, self.OnKeyUpCB, cb2)
+ cb2.SetValue(True)
+
+ cb3 = wx.CheckBox(self, -1, "EVT_KEY_DOWN")
+ self.Bind(wx.EVT_CHECKBOX, self.OnKeyDnCB, cb3)
+ cb3.SetValue(True)
+
+ cb4 = wx.CheckBox(self, -1, "EVT_CHAR")
+ self.Bind(wx.EVT_CHECKBOX, self.OnCharCB, cb4)
+ cb4.SetValue(True)
+
+ buttons = wx.BoxSizer(wx.HORIZONTAL)
+ buttons.Add(btn, 0, wx.ALL, 4)
+ buttons.Add(cb1, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 6)
+ buttons.Add(cb2, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
+ buttons.Add(cb3, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
+ buttons.Add(cb4, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(self.keysink, 0, wx.GROW)
+ sizer.Add(buttons)
+ sizer.Add(self.keylog, 1, wx.GROW)
+
+ self.SetSizer(sizer)
+
+
+ def OnClearBtn(self, evt):
+ self.keylog.ClearLog()
+
+ def OnSkipCB(self, evt):
+ self.keysink.SetCallSkip(evt.GetInt())
+
+ def OnKeyUpCB(self, evt):
+ self.keysink.SetLogKeyUp(evt.GetInt())
+
+ def OnKeyDnCB(self, evt):
+ self.keysink.SetLogKeyDn(evt.GetInt())
+
+ def OnCharCB(self, evt):
+ self.keysink.SetLogChar(evt.GetInt())
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>wxKeyEvents</center></h2>
+
+This demo simply catches all key events and prints info about them.
+It is meant to be used as a compatibility test for cross platform work.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import time
+
+import wx
+import wx.gizmos as gizmos
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ led = gizmos.LEDNumberCtrl(self, -1, (25,25), (280, 50))
+ led.SetValue("01234")
+
+ led = gizmos.LEDNumberCtrl(self, -1, (25,100), (280, 50))
+ led.SetValue("56789")
+ led.SetAlignment(gizmos.LED_ALIGN_RIGHT)
+ led.SetDrawFaded(False)
+
+ led = gizmos.LEDNumberCtrl(self, -1, (25,175), (280, 50),
+ gizmos.LED_ALIGN_CENTER)# | gizmos.LED_DRAW_FADED)
+ self.clock = led
+ self.OnTimer(None)
+
+ self.timer = wx.Timer(self)
+ self.timer.Start(1000)
+ self.Bind(wx.EVT_TIMER, self.OnTimer)
+
+
+ def OnTimer(self, evt):
+ t = time.localtime(time.time())
+ st = time.strftime("%I-%M-%S", t)
+ self.clock.SetValue(st)
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+overview = """\
+<html>
+<body>
+<font size=-1>The following was gleaned as best I could from the wxWindows
+source, which was a bit reluctant to reveal its secrets. My appologies if
+I missed anything - jmg</font>
+<p>
+<code><b>wxLEDNumberCtrl</b>( parent, id=-1, pos=wx.DefaultPosition,
+size=wx.DefaultSize, style=LED_ALIGN_LEFT | LED_DRAW_FADED)</code>
+
+<p>This is a control that simulates an LED clock display. It only accepts
+numeric input.
+
+<p><b>Styles</b>
+
+<p><dl>
+<dt><b>LED_ALIGN_LEFT</b>
+<dd>Align to the left.
+
+<dt><b>LED_ALIGN_RIGHT</b>
+<dd>Align to the right.
+
+<dt><b>LED_ALIGN_CENTER</b>
+<dd>Center on display.
+
+<dt><b>LED_DRAW_FADED</b>
+<dd>Not implemented.
+
+</dl>
+
+<p><b>Methods</b> (and best guesses at what they do)
+
+<p><dl>
+<dt><b>GetAlignment()</b>
+<dd>Returns the alignment attribute for the control.
+
+<dt><b>GetDrawFaded()</b>
+<dd>Returns the DrawFaded attribute for the control.
+
+<dt><b>GetValue()</b>
+<dd>Returns the current value of the control.
+
+<dt><b>SetAlignment(alignment)</b>
+<dd>Set the alignment attribute for the control.
+
+<dt><b>SetDrawFaded(value)</b>
+<dd>Set the DrawFaded attribute for the control.
+
+<dt><b>SetValue(number)</b>
+<dd>Set the value for the control. Only numeric values are accepted.
+
+</dl>
+
+<p>Additionally, several methods of wx.Window are available as well.
+
+</body>
+</html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestLayoutConstraints(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent, -1)
+ self.SetAutoLayout(True)
+ self.Bind(wx.EVT_BUTTON, self.OnButton, id=100)
+
+ self.SetBackgroundColour(wx.NamedColour("MEDIUM ORCHID"))
+
+ self.panelA = wx.Window(self, -1, style=wx.SIMPLE_BORDER)
+ self.panelA.SetBackgroundColour(wx.BLUE)
+
+ txt = wx.StaticText(
+ self.panelA, -1,
+ "Resize the window and see\n"
+ "what happens... Notice that\n"
+ "there is no OnSize handler.",
+ (5,5), (-1, 50)
+ )
+
+ txt.SetBackgroundColour(wx.BLUE)
+ txt.SetForegroundColour(wx.WHITE)
+
+ lc = wx.LayoutConstraints()
+ lc.top.SameAs(self, wx.Top, 10)
+ lc.left.SameAs(self, wx.Left, 10)
+ lc.bottom.SameAs(self, wx.Bottom, 10)
+ lc.right.PercentOf(self, wx.Right, 50)
+ self.panelA.SetConstraints(lc)
+
+ self.panelB = wx.Window(self, -1, style=wx.SIMPLE_BORDER)
+ self.panelB.SetBackgroundColour(wx.RED)
+ lc = wx.LayoutConstraints()
+ lc.top.SameAs(self, wx.Top, 10)
+ lc.right.SameAs(self, wx.Right, 10)
+ lc.bottom.PercentOf(self, wx.Bottom, 30)
+ lc.left.RightOf(self.panelA, 10)
+ self.panelB.SetConstraints(lc)
+
+ self.panelC = wx.Window(self, -1, style=wx.SIMPLE_BORDER)
+ self.panelC.SetBackgroundColour(wx.WHITE)
+ lc = wx.LayoutConstraints()
+ lc.top.Below(self.panelB, 10)
+ lc.right.SameAs(self, wx.Right, 10)
+ lc.bottom.SameAs(self, wx.Bottom, 10)
+ lc.left.RightOf(self.panelA, 10)
+ self.panelC.SetConstraints(lc)
+
+ b = wx.Button(self.panelA, 100, ' Panel A ')
+ lc = wx.LayoutConstraints()
+ lc.centreX.SameAs (self.panelA, wx.CentreX)
+ lc.centreY.SameAs (self.panelA, wx.CentreY)
+ lc.height.AsIs ()
+ lc.width.PercentOf (self.panelA, wx.Width, 50)
+ b.SetConstraints(lc);
+
+ b = wx.Button(self.panelB, 100, ' Panel B ')
+ lc = wx.LayoutConstraints()
+ lc.top.SameAs (self.panelB, wx.Top, 2)
+ lc.right.SameAs (self.panelB, wx.Right, 4)
+ lc.height.AsIs ()
+ lc.width.AsIs ()
+ b.SetConstraints(lc);
+
+ self.panelD = wx.Window(self.panelC, -1, style=wx.SIMPLE_BORDER)
+ self.panelD.SetBackgroundColour(wx.GREEN)
+ wx.StaticText(
+ self.panelD, -1, "Panel D", (4, 4)
+ ).SetBackgroundColour(wx.GREEN)
+
+ b = wx.Button(self.panelC, 100, ' Panel C ')
+ lc = wx.LayoutConstraints()
+ lc.top.Below (self.panelD)
+ lc.left.RightOf (self.panelD)
+ lc.height.AsIs ()
+ lc.width.AsIs ()
+ b.SetConstraints(lc);
+
+ lc = wx.LayoutConstraints()
+ lc.bottom.PercentOf (self.panelC, wx.Height, 50)
+ lc.right.PercentOf (self.panelC, wx.Width, 50)
+ lc.height.SameAs (b, wx.Height)
+ lc.width.SameAs (b, wx.Width)
+ self.panelD.SetConstraints(lc);
+
+
+ def OnButton(self, event):
+ wx.Bell()
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestLayoutConstraints(nb)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+<html><body>
+Objects of this class can be associated with a window to define its
+layout constraints, with respect to siblings or its parent.
+
+<p>The class consists of the following eight constraints of class
+wxIndividualLayoutConstraint, some or all of which should be accessed
+directly to set the appropriate constraints.
+
+<p><ul>
+<li>left: represents the left hand edge of the window
+
+<li>right: represents the right hand edge of the window
+
+<li>top: represents the top edge of the window
+
+<li>bottom: represents the bottom edge of the window
+
+<li>width: represents the width of the window
+
+<li>height: represents the height of the window
+
+<li>centreX: represents the horizontal centre point of the window
+
+<li>centreY: represents the vertical centre point of the window
+</ul>
+<p>Most constraints are initially set to have the relationship
+wxUnconstrained, which means that their values should be calculated by
+looking at known constraints. The exceptions are width and height,
+which are set to wxAsIs to ensure that if the user does not specify a
+constraint, the existing width and height will be used, to be
+compatible with panel items which often have take a default size. If
+the constraint is wxAsIs, the dimension will not be changed.
+
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+# This listbox subclass lets you type the starting letters of what you want to
+# select, and scrolls the list to the match if it is found.
+class FindPrefixListBox(wx.ListBox):
+ def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize,
+ choices=[], style=0, validator=wx.DefaultValidator):
+ wx.ListBox.__init__(self, parent, id, pos, size, choices, style, validator)
+ self.typedText = ''
+ self.log = parent.log
+ self.Bind(wx.EVT_KEY_DOWN, self.OnKey)
+
+
+ def FindPrefix(self, prefix):
+ self.log.WriteText('Looking for prefix: %s\n' % prefix)
+
+ if prefix:
+ prefix = prefix.lower()
+ length = len(prefix)
+
+ # Changed in 2.5 because ListBox.Number() is no longer supported.
+ # ListBox.GetCount() is now the appropriate way to go.
+ for x in range(self.GetCount()):
+ text = self.GetString(x)
+ text = text.lower()
+
+ if text[:length] == prefix:
+ self.log.WriteText('Prefix %s is found.\n' % prefix)
+ return x
+
+ self.log.WriteText('Prefix %s is not found.\n' % prefix)
+ return -1
+
+
+ def OnKey(self, evt):
+ key = evt.GetKeyCode()
+
+ if key >= 32 and key <= 127:
+ self.typedText = self.typedText + chr(key)
+ item = self.FindPrefix(self.typedText)
+
+ if item != -1:
+ self.SetSelection(item)
+
+ elif key == wx.WXK_BACK: # backspace removes one character and backs up
+ self.typedText = self.typedText[:-1]
+
+ if not self.typedText:
+ self.SetSelection(0)
+ else:
+ item = self.FindPrefix(self.typedText)
+
+ if item != -1:
+ self.SetSelection(item)
+ else:
+ self.typedText = ''
+ evt.Skip()
+
+ def OnKeyDown(self, evt):
+ pass
+
+
+#---------------------------------------------------------------------------
+
+class TestListBox(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
+ 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
+ 'twelve', 'thirteen', 'fourteen']
+
+ wx.StaticText(self, -1, "This example uses the wxListBox control.", (45, 10))
+ wx.StaticText(self, -1, "Select one:", (15, 50), (65, 18))
+ self.lb1 = wx.ListBox(self, 60, (80, 50), (80, 120), sampleList, wx.LB_SINGLE)
+ self.Bind(wx.EVT_LISTBOX, self.EvtListBox, self.lb1)
+ self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, self.lb1)
+ self.lb1.Bind(wx.EVT_RIGHT_UP, self.EvtRightButton)
+ self.lb1.SetSelection(3)
+ self.lb1.Append("with data", "This one has data");
+ self.lb1.SetClientData(2, "This one has data");
+
+
+ wx.StaticText(self, -1, "Select many:", (200, 50), (65, 18))
+ self.lb2 = wx.ListBox(self, 70, (280, 50), (80, 120), sampleList, wx.LB_EXTENDED)
+ self.Bind(wx.EVT_LISTBOX, self.EvtMultiListBox, self.lb2)
+ self.lb2.Bind(wx.EVT_RIGHT_UP, self.EvtRightButton)
+ self.lb2.SetSelection(0)
+
+ sampleList = sampleList + ['test a', 'test aa', 'test aab',
+ 'test ab', 'test abc', 'test abcc',
+ 'test abcd' ]
+ sampleList.sort()
+ wx.StaticText(self, -1, "Find Prefix:", (15, 250))
+ fp = FindPrefixListBox(self, -1, (80, 250), (80, 120), sampleList, wx.LB_SINGLE)
+ fp.SetSelection(0)
+
+
+ def EvtListBox(self, event):
+ self.log.WriteText('EvtListBox: %s, %s, %s\n' %
+ (event.GetString(), event.IsSelection(), event.GetSelection()))
+
+ lb = event.GetEventObject()
+ data = lb.GetClientData(lb.GetSelection())
+
+ if data is not None:
+ self.log.WriteText('\tdata: %s\n' % data)
+
+
+ def EvtListBoxDClick(self, event):
+ self.log.WriteText('EvtListBoxDClick: %s\n' % self.lb1.GetSelection())
+ self.lb1.Delete(self.lb1.GetSelection())
+
+ def EvtMultiListBox(self, event):
+ self.log.WriteText('EvtMultiListBox: %s\n' % str(self.lb2.GetSelections()))
+
+ def EvtRightButton(self, event):
+ self.log.WriteText('EvtRightButton: %s\n' % event.GetPosition())
+
+ if event.GetEventObject().GetId() == 70:
+ selections = list(self.lb2.GetSelections())
+ selections.reverse()
+
+ for index in selections:
+ self.lb2.Delete(index)
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestListBox(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+
+overview = """<html><body>
+A listbox is used to select one or more of a list of
+strings. The strings are displayed in a scrolling box, with the
+selected string(s) marked in reverse video. A listbox can be single
+selection (if an item is selected, the previous selection is removed)
+or multiple selection (clicking an item toggles the item on or off
+independently of other selections).
+</body></html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+#----------------------------------------------------------------------------
+# Name: ListCtrl.py
+# Purpose: Testing lots of stuff, controls, window types, etc.
+#
+# Author: Robin Dunn & Gary Dumer
+#
+# Created:
+# RCS-ID: $Id$
+# Copyright: (c) 1998 by Total Control Software
+# Licence: wxWindows license
+#----------------------------------------------------------------------------
+#
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o listctrl mixin needs wx renamer.
+# o wx.ListItem.GetText() returns a wxString pointer, not the text.
+#
+# 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o ColumnSorterMixin implementation was broke - added event.Skip()
+# to column click event to allow event to fall through to mixin.
+#
+# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxColumnSorterMixin -> ColumnSorterMixin
+# o wxListCtrlAutoWidthMixin -> ListCtrlAutoWidthMixin
+#
+
+import wx
+import wx.lib.mixins.listctrl as listmix
+
+import images
+
+#---------------------------------------------------------------------------
+
+musicdata = {
+1 : ("Bad English", "The Price Of Love", "Rock"),
+2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
+3 : ("George Michael", "Praying For Time", "Rock"),
+4 : ("Gloria Estefan", "Here We Are", "Rock"),
+5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
+6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
+7 : ("Paul Young", "Oh Girl", "Rock"),
+8 : ("Paula Abdul", "Opposites Attract", "Rock"),
+9 : ("Richard Marx", "Should've Known Better", "Rock"),
+10: ("Rod Stewart", "Forever Young", "Rock"),
+11: ("Roxette", "Dangerous", "Rock"),
+12: ("Sheena Easton", "The Lover In Me", "Rock"),
+13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
+14: ("Stevie B.", "Because I Love You", "Rock"),
+15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
+16: ("The Bangles", "Eternal Flame", "Rock"),
+17: ("Wilson Phillips", "Release Me", "Rock"),
+18: ("Billy Joel", "Blonde Over Blue", "Rock"),
+19: ("Billy Joel", "Famous Last Words", "Rock"),
+20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
+21: ("Billy Joel", "The River Of Dreams", "Rock"),
+22: ("Billy Joel", "Two Thousand Years", "Rock"),
+23: ("Janet Jackson", "Alright", "Rock"),
+24: ("Janet Jackson", "Black Cat", "Rock"),
+25: ("Janet Jackson", "Come Back To Me", "Rock"),
+26: ("Janet Jackson", "Escapade", "Rock"),
+27: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
+28: ("Janet Jackson", "Miss You Much", "Rock"),
+29: ("Janet Jackson", "Rhythm Nation", "Rock"),
+30: ("Janet Jackson", "State Of The World", "Rock"),
+31: ("Janet Jackson", "The Knowledge", "Rock"),
+32: ("Spyro Gyra", "End of Romanticism", "Jazz"),
+33: ("Spyro Gyra", "Heliopolis", "Jazz"),
+34: ("Spyro Gyra", "Jubilee", "Jazz"),
+35: ("Spyro Gyra", "Little Linda", "Jazz"),
+36: ("Spyro Gyra", "Morning Dance", "Jazz"),
+37: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
+38: ("Yes", "Owner Of A Lonely Heart", "Rock"),
+39: ("Yes", "Rhythm Of Love", "Rock"),
+40: ("Cusco", "Dream Catcher", "New Age"),
+41: ("Cusco", "Geronimos Laughter", "New Age"),
+42: ("Cusco", "Ghost Dance", "New Age"),
+43: ("Blue Man Group", "Drumbone", "New Age"),
+44: ("Blue Man Group", "Endless Column", "New Age"),
+45: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
+46: ("Kenny G", "Silhouette", "Jazz"),
+47: ("Sade", "Smooth Operator", "Jazz"),
+48: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)", "New Age"),
+49: ("David Arkenstone", "Stepping Stars", "New Age"),
+50: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
+51: ("David Lanz", "Behind The Waterfall", "New Age"),
+52: ("David Lanz", "Cristofori's Dream", "New Age"),
+53: ("David Lanz", "Heartsounds", "New Age"),
+54: ("David Lanz", "Leaves on the Seine", "New Age"),
+}
+
+#---------------------------------------------------------------------------
+
+class TestListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
+ def __init__(self, parent, ID, pos=wx.DefaultPosition,
+ size=wx.DefaultSize, style=0):
+ wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
+ listmix.ListCtrlAutoWidthMixin.__init__(self)
+
+
+class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
+
+ self.log = log
+ tID = wx.NewId()
+
+ self.il = wx.ImageList(16, 16)
+
+ self.idx1 = self.il.Add(images.getSmilesBitmap())
+ self.sm_up = self.il.Add(images.getSmallUpArrowBitmap())
+ self.sm_dn = self.il.Add(images.getSmallDnArrowBitmap())
+
+ self.list = TestListCtrl(self, tID,
+ style=wx.LC_REPORT
+ | wx.SUNKEN_BORDER
+ | wx.LC_EDIT_LABELS
+ #| wxLC_NO_HEADER
+ #| wxLC_VRULES | wxLC_HRULES
+ )
+
+ self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+
+ self.PopulateList()
+
+ # Now that the list exists we can init the other base class,
+ # see wxPython/lib/mixins/listctrl.py
+ self.itemDataMap = musicdata
+ listmix.ColumnSorterMixin.__init__(self, 3)
+ #self.SortListItems(0, True)
+
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
+ self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.list)
+ self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list)
+ self.Bind(wx.EVT_LIST_DELETE_ITEM, self.OnItemDelete, self.list)
+ self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
+ self.Bind(wx.EVT_LIST_COL_RIGHT_CLICK, self.OnColRightClick, self.list)
+ self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.OnColBeginDrag, self.list)
+ self.Bind(wx.EVT_LIST_COL_DRAGGING, self.OnColDragging, self.list)
+ self.Bind(wx.EVT_LIST_COL_END_DRAG, self.OnColEndDrag, self.list)
+ self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list)
+
+ self.list.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
+ self.list.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
+
+ # for wxMSW
+ self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
+
+ # for wxGTK
+ self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
+
+
+ def PopulateList(self):
+ if 0:
+ # for normal, simple columns, you can add them like this:
+ self.list.InsertColumn(0, "Artist")
+ self.list.InsertColumn(1, "Title", wx.LIST_FORMAT_RIGHT)
+ self.list.InsertColumn(2, "Genre")
+ else:
+ # but since we want images on the column header we have to do it the hard way:
+ info = wx.ListItem()
+ info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
+ info.m_image = -1
+ info.m_format = 0
+ info.m_text = "Artist"
+ self.list.InsertColumnInfo(0, info)
+
+ info.m_format = wx.LIST_FORMAT_RIGHT
+ info.m_text = "Title"
+ self.list.InsertColumnInfo(1, info)
+
+ info.m_format = 0
+ info.m_text = "Genre"
+ self.list.InsertColumnInfo(2, info)
+
+ items = musicdata.items()
+ for x in range(len(items)):
+ key, data = items[x]
+ self.list.InsertImageStringItem(x, data[0], self.idx1)
+ self.list.SetStringItem(x, 1, data[1])
+ self.list.SetStringItem(x, 2, data[2])
+ self.list.SetItemData(x, key)
+
+ self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+ self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+ self.list.SetColumnWidth(2, 100)
+
+ # show how to select an item
+ self.list.SetItemState(5, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
+
+ # show how to change the colour of a couple items
+ item = self.list.GetItem(1)
+ item.SetTextColour(wx.BLUE)
+ self.list.SetItem(item)
+ item = self.list.GetItem(4)
+ item.SetTextColour(wx.RED)
+ self.list.SetItem(item)
+
+ self.currentItem = 0
+
+
+ # Used by the ColumnSorterMixin, see wxPython/lib/mixins/listctrl.py
+ def GetListCtrl(self):
+ return self.list
+
+ # Used by the ColumnSorterMixin, see wxPython/lib/mixins/listctrl.py
+ def GetSortImages(self):
+ return (self.sm_dn, self.sm_up)
+
+
+ def OnRightDown(self, event):
+ self.x = event.GetX()
+ self.y = event.GetY()
+ self.log.WriteText("x, y = %s\n" % str((self.x, self.y)))
+ item, flags = self.list.HitTest((self.x, self.y))
+
+ if flags & wx.LIST_HITTEST_ONITEM:
+ self.list.Select(item)
+
+ event.Skip()
+
+
+ def getColumnText(self, index, col):
+ item = self.list.GetItem(index, col)
+ return item.GetText()
+
+
+ def OnItemSelected(self, event):
+ ##print event.GetItem().GetTextColour()
+ self.currentItem = event.m_itemIndex
+ self.log.WriteText("OnItemSelected: %s, %s, %s, %s\n" %
+ (self.currentItem,
+ self.list.GetItemText(self.currentItem),
+ self.getColumnText(self.currentItem, 1),
+ self.getColumnText(self.currentItem, 2)))
+
+ if self.currentItem == 10:
+ self.log.WriteText("OnItemSelected: Veto'd selection\n")
+ #event.Veto() # doesn't work
+ # this does
+ self.list.SetItemState(10, 0, wx.LIST_STATE_SELECTED)
+
+ event.Skip()
+
+
+ def OnItemDeselected(self, evt):
+ item = evt.GetItem()
+ self.log.WriteText("OnItemDeselected: %d" % evt.m_itemIndex)
+
+ # Show how to reselect something we don't want deselected
+ if evt.m_itemIndex == 11:
+ wx.CallAfter(self.list.SetItemState, 11, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
+
+
+ def OnItemActivated(self, event):
+ self.currentItem = event.m_itemIndex
+ self.log.WriteText("OnItemActivated: %s\nTopItem: %s" %
+ (self.list.GetItemText(self.currentItem), self.list.GetTopItem()))
+
+ def OnBeginEdit(self, event):
+ self.log.WriteText("OnBeginEdit")
+ event.Allow()
+
+ def OnItemDelete(self, event):
+ self.log.WriteText("OnItemDelete\n")
+
+ def OnColClick(self, event):
+ self.log.WriteText("OnColClick: %d\n" % event.GetColumn())
+ event.Skip()
+
+ def OnColRightClick(self, event):
+ item = self.list.GetColumn(event.GetColumn())
+ self.log.WriteText("OnColRightClick: %d %s\n" %
+ (event.GetColumn(), (item.GetText(), item.GetAlign(),
+ item.GetWidth(), item.GetImage())))
+
+ def OnColBeginDrag(self, event):
+ self.log.WriteText("OnColBeginDrag\n")
+ ## Show how to not allow a column to be resized
+ #if event.GetColumn() == 0:
+ # event.Veto()
+
+
+ def OnColDragging(self, event):
+ self.log.WriteText("OnColDragging\n")
+
+ def OnColEndDrag(self, event):
+ self.log.WriteText("OnColEndDrag\n")
+
+ def OnDoubleClick(self, event):
+ self.log.WriteText("OnDoubleClick item %s\n" % self.list.GetItemText(self.currentItem))
+ event.Skip()
+
+ def OnRightClick(self, event):
+ self.log.WriteText("OnRightClick %s\n" % self.list.GetItemText(self.currentItem))
+
+ # only do this part the first time so the events are only bound once
+ if not hasattr(self, "popupID1"):
+ self.popupID1 = wx.NewId()
+ self.popupID2 = wx.NewId()
+ self.popupID3 = wx.NewId()
+ self.popupID4 = wx.NewId()
+ self.popupID5 = wx.NewId()
+ self.popupID6 = wx.NewId()
+
+ self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
+ self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
+ self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
+ self.Bind(wx.EVT_MENU, self.OnPopupFour, id=self.popupID4)
+ self.Bind(wx.EVT_MENU, self.OnPopupFive, id=self.popupID5)
+ self.Bind(wx.EVT_MENU, self.OnPopupSix, id=self.popupID6)
+
+ # make a menu
+ menu = wx.Menu()
+ # add some items
+ menu.Append(self.popupID1, "FindItem tests")
+ menu.Append(self.popupID2, "Iterate Selected")
+ menu.Append(self.popupID3, "ClearAll and repopulate")
+ menu.Append(self.popupID4, "DeleteAllItems")
+ menu.Append(self.popupID5, "GetItem")
+ menu.Append(self.popupID6, "Edit")
+
+ # Popup the menu. If an item is selected then its handler
+ # will be called before PopupMenu returns.
+ self.PopupMenu(menu, (self.x, self.y))
+ menu.Destroy()
+
+
+ def OnPopupOne(self, event):
+ self.log.WriteText("Popup one\n")
+ print "FindItem:", self.list.FindItem(-1, "Roxette")
+ print "FindItemData:", self.list.FindItemData(-1, 11)
+
+ def OnPopupTwo(self, event):
+ self.log.WriteText("Selected items:\n")
+ index = self.list.GetFirstSelected()
+
+ while index != -1:
+ self.log.WriteText(" %s: %s\n" % (self.list.GetItemText(index), self.getColumnText(index, 1)))
+ index = self.list.GetNextSelected(index)
+
+ def OnPopupThree(self, event):
+ self.log.WriteText("Popup three\n")
+ self.list.ClearAll()
+ wx.CallAfter(self.PopulateList)
+
+ def OnPopupFour(self, event):
+ self.list.DeleteAllItems()
+
+ def OnPopupFive(self, event):
+ item = self.list.GetItem(self.currentItem)
+ print item.m_text, item.m_itemId, self.list.GetItemData(self.currentItem)
+
+ def OnPopupSix(self, event):
+ self.list.EditLabel(self.currentItem)
+
+
+ def OnSize(self, event):
+ w,h = self.GetClientSizeTuple()
+ self.list.SetDimensions(0, 0, w, h)
+
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestListCtrlPanel(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+<html>
+<body>
+A list control presents lists in a number of formats: list view, report view,
+icon view and small icon view. In any case, elements are numbered from zero.
+For all these modes (but not for virtual list controls), the items are stored
+in the control and must be added to it using InsertItem method.
+
+<p>To intercept events from a list control, use the event table macros described in
+<code>wxListEvent.</code>
+
+<h3>Mix-ins</h3>
+This example demonstrates how to use mixins. The following mixins are available.
+
+<h4>ColumnSorterMixin</h4>
+
+<code><b>ColumnSorterMixin(numColumns)</b></code>
+
+<p>A mixin class that handles sorting of a wxListCtrl in REPORT mode when the column
+header is clicked on.
+
+<p>There are a few requirments needed in order for this to work genericly:
+<p><ol>
+ <li>The combined class must have a <code>GetListCtrl</code> method that returns
+ the ListCtrl to be sorted, and the list control must exist at the time the
+ <code>ColumnSorterMixin.__init__()</code>method is called because it uses
+ <code>GetListCtrl</code>.
+
+ <li>Items in the list control must have a unique data value set with
+ <code>list.SetItemData</code>.
+
+ <li>The combined class must have an attribute named <code>itemDataMap</code>
+ that is a dictionary mapping the data values to a sequence of objects
+ representing the values in each column. These valuesare compared in
+ the column sorter to determine sort order.
+</ol>
+
+<p>Interesting methods to override are <code>GetColumnSorter</code>,
+<code>GetSecondarySortValues</code>, and <code>GetSortImages</code>.
+
+<h5>Methods</h5>
+<dl>
+<dt><code>SetColumnCount(newNumColumns)</code>
+<dd>Informs the mixin as to the number of columns in the control. When it is
+set, it also sets up an event handler for <code>EVT_LIST_COL_CLICK</code> events.
+
+<dt><code>SortListItems(col=-1, ascending=1)</code>
+<dd>Sort the list on demand. Can also be used to set the sort column and order.
+
+<dt><code>GetColumnWidths()</code>
+<dd>Returns a list of column widths. Can be used to help restore the current
+view later.
+
+<dt><code>GetSortImages()</code>
+<dd>Returns a tuple of image list indexes the indexes in the image list for an
+image to be put on the column header when sorting in descending order
+
+<dt><code>GetColumnSorter()</code>
+<dd>Returns a callable object to be used for comparing column values when sorting.
+
+<dt><code>GetSecondarySortValues(col, key1, key2)</code>
+<dd>Returns a tuple of 2 values to use for secondary sort values when the
+items in the selected column match equal. The default just returns the
+item data values.
+
+</dl>
+
+<h4>ListCtrlAutoWidthMixin</h4>
+
+<code><b>ListCtrlAutoWidthMixin()</b></code>
+
+<p>A mix-in class that automatically resizes the last column to take up the
+remaining width of the ListCtrl.
+
+<p>This causes the ListCtrl to automatically take up the full width of the list,
+without either a horizontal scroll bar (unless absolutely necessary) or empty
+space to the right of the last column.
+
+<p><b>NOTE:</b> This only works for report-style lists.
+
+<p><b>WARNING:</b> If you override the <code>EVT_SIZE</code> event in your ListCtrl,
+make sure you call event.Skip() to ensure that the mixin's _OnResize method is
+called.
+
+<p>This mix-in class was written by <a href='mailto:ewestra@wave.co.nz'>Erik Westra </a>
+
+<h5>Methods</h5>
+<dl>
+
+<dt><code>resizeLastColumn(minWidth)</code>
+<dd>Resize the last column appropriately. If the list's columns are too wide to
+fit within the window, we use a horizontal scrollbar. Otherwise, we expand the
+right-most column to take up the remaining free space in the list. This method is
+called automatically when the ListCtrl is resized; you can also call it yourself
+whenever you want the last column to be resized appropriately (eg, when adding,
+removing or resizing columns). 'minWidth' is the preferred minimum width for
+the last column.
+
+</dl>
+
+
+<h4>ListCtrlSelectionManagerMix</h4>
+
+<code><b>ListCtrlSelectionManagerMix()</b></code>
+
+<p>Mixin that defines a platform independent selection policy
+
+<p>As selection single and multi-select list return the item index or a
+list of item indexes respectively.
+
+<h5>Methods</h5>
+<dl>
+
+<dt><code>getPopupMenu()</code>
+<dd>Override to implement dynamic menus (create)
+
+<dt><code>setPopupMenu(menu)</code>
+<dd>Must be set for default behaviour.
+
+<dt><code>afterPopupMenu()</code>
+<dd>Override to implement dynamic menus (destroy).
+
+<dt><code>getSelection()</code>
+<dd>Returns the current selection (or selections as a Python list if extended
+selection is enabled)
+
+
+</body>
+</html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wx.ListItem.GetText() returns a wxString pointer, not the text.
+#
+
+import wx
+import images
+
+#----------------------------------------------------------------------
+
+class TestVirtualList(wx.ListCtrl):
+ def __init__(self, parent, log):
+ wx.ListCtrl.__init__(
+ self, parent, -1,
+ style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES
+ )
+
+ self.log = log
+
+ self.il = wx.ImageList(16, 16)
+ self.idx1 = self.il.Add(images.getSmilesBitmap())
+ self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+
+
+ self.InsertColumn(0, "First")
+ self.InsertColumn(1, "Second")
+ self.InsertColumn(2, "Third")
+ self.SetColumnWidth(0, 175)
+ self.SetColumnWidth(1, 175)
+ self.SetColumnWidth(2, 175)
+
+ self.SetItemCount(1000000)
+
+ self.attr1 = wx.ListItemAttr()
+ self.attr1.SetBackgroundColour("yellow")
+
+ self.attr2 = wx.ListItemAttr()
+ self.attr2.SetBackgroundColour("light blue")
+
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
+ self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
+ self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected)
+
+
+ def OnItemSelected(self, event):
+ self.currentItem = event.m_itemIndex
+ self.log.WriteText('OnItemSelected: "%s", "%s", "%s", "%s"\n' %
+ (self.currentItem,
+ self.GetItemText(self.currentItem),
+ self.getColumnText(self.currentItem, 1),
+ self.getColumnText(self.currentItem, 2)))
+
+ def OnItemActivated(self, event):
+ self.currentItem = event.m_itemIndex
+ self.log.WriteText("OnItemActivated: %s\nTopItem: %s\n" %
+ (self.GetItemText(self.currentItem), self.GetTopItem()))
+
+ def getColumnText(self, index, col):
+ item = self.GetItem(index, col)
+ return item.GetText()
+
+ def OnItemDeselected(self, evt):
+ self.log.WriteText("OnItemDeselected: %s" % evt.m_itemIndex)
+
+
+ #---------------------------------------------------
+ # These methods are callbacks for implementing the
+ # "virtualness" of the list... Normally you would
+ # determine the text, attributes and/or image based
+ # on values from some external data source, but for
+ # this demo we'll just calculate them
+ def OnGetItemText(self, item, col):
+ return "Item %d, column %d" % (item, col)
+
+ def OnGetItemImage(self, item):
+ if item % 3 == 0:
+ return self.idx1
+ else:
+ return -1
+
+ def OnGetItemAttr(self, item):
+ if item % 3 == 1:
+ return self.attr1
+ elif item % 3 == 2:
+ return self.attr2
+ else:
+ return None
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestVirtualList(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+This example demonstrates the ListCtrl's Virtual List features. A Virtual list
+can contain any number of cells, but data is not loaded into the control itself.
+It is loaded on demand via virtual methods <code>OnGetItemText(), OnGetItemImage()</code>,
+and <code>OnGetItemAttr()</code>. This greatly reduces the amount of memory required
+without limiting what can be done with the list control itself.
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Bunches of imports that might need to go away for the final roll-out.
+#
+
+import sys
+
+import wx
+
+import images
+
+import ColorPanel
+
+colourList = [ "Aquamarine", "Black", "Blue", "Blue Violet", "Brown", "Cadet Blue",
+ "Coral", "Cornflower Blue", "Cyan", "Dark Grey", "Dark Green",
+ "Dark Olive Green", "Dark Orchid", "Dark Slate Blue",
+ "Dark Slate Grey", "Dark Turquoise", "Dim Grey", "Firebrick",
+ "Forest Green", "Gold", "Goldenrod", "Grey", "Green", "Green Yellow",
+ "Indian Red", "Khaki", "Light Blue", "Light Grey", "Light Steel Blue",
+ "Lime Green", "Magenta", "Maroon", "Medium Aquamarine", "Medium Blue",
+ "Medium Forest Green", "Medium Goldenrod", "Medium Orchid",
+ "Medium Sea Green", "Medium Slate Blue", "Medium Spring Green",
+ "Medium Turquoise", "Medium Violet Red", "Midnight Blue", "Navy",
+ "Orange", "Orange Red", "Orchid", "Pale Green", "Pink", "Plum",
+ "Purple", "Red", "Salmon", "Sea Green", "Sienna", "Sky Blue",
+ "Slate Blue", "Spring Green", "Steel Blue", "Tan", "Thistle",
+ "Turquoise", "Violet", "Violet Red", "Wheat", "White", "Yellow",
+ "Yellow Green"
+ ]
+
+#----------------------------------------------------------------------------
+
+class TestLB(wx.Listbook):
+ def __init__(self, parent, id, log):
+ wx.Listbook.__init__(self, parent, id, style=
+ wx.LB_DEFAULT
+ #wxLB_TOP
+ #wxLB_BOTTOM
+ #wxLB_LEFT
+ #wxLB_RIGHT
+ )
+ self.log = log
+
+
+ # make an image list using the BlomXX images
+ il = wx.ImageList(32, 32)
+ for x in range(1, 15):
+ f = getattr(images, 'getBlom%02dBitmap' % x)
+ bmp = f()
+ il.Add(bmp)
+ self.AssignImageList(il)
+
+ # Now make a bunch of panels for the list book
+ first = True
+ imID = 0
+ for colour in colourList:
+ win = self.makeColorPanel(colour)
+ self.AddPage(win, colour, imageId=imID)
+ imID += 1
+ if imID == il.GetImageCount(): imID = 0
+ if first:
+ st = wx.StaticText(win.win, -1,
+ "You can put nearly any type of window here,\n"
+ "and the list can be on any side of the Listbook",
+ wx.Point(10, 10))
+ #st.SetForegroundColour(wxWHITE)
+ #st.SetBackgroundColour(wxBLUE)
+ first = False
+
+
+
+ wx.EVT_LISTBOOK_PAGE_CHANGED(self, self.GetId(), self.OnPageChanged)
+ wx.EVT_LISTBOOK_PAGE_CHANGING(self, self.GetId(), self.OnPageChanging)
+
+
+ def makeColorPanel(self, color):
+ p = wx.Panel(self, -1)
+ win = ColorPanel.ColoredPanel(p, color)
+ p.win = win
+ def OnCPSize(evt, win=win):
+ win.SetSize(evt.GetSize())
+ p.Bind(wx.EVT_SIZE, OnCPSize)
+ return p
+
+
+ def OnPageChanged(self, event):
+ old = event.GetOldSelection()
+ new = event.GetSelection()
+ sel = self.GetSelection()
+ self.log.write('OnPageChanged, old:%d, new:%d, sel:%d\n' % (old, new, sel))
+ event.Skip()
+
+ def OnPageChanging(self, event):
+ old = event.GetOldSelection()
+ new = event.GetSelection()
+ sel = self.GetSelection()
+ self.log.write('OnPageChanging, old:%d, new:%d, sel:%d\n' % (old, new, sel))
+ event.Skip()
+
+#----------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ testWin = TestLB(nb, -1, log)
+ return testWin
+
+#----------------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+<h2>wxListbook</h2>
+<p>
+This class is a control similar to a notebook control, but with a
+wxListCtrl instead of a set of tabs.
+
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+
import wx
-# Importing wxScrolledWindow demo to make use of the MyCanvas
+# Importing ScrolledWindow demo to make use of the MyCanvas
# class defined within.
-import wxScrolledWindow
+import ScrolledWindow
import images
SHOW_BACKGROUND = 1
def OnNewWindow(self, evt):
self.winCount = self.winCount + 1
win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount)
- canvas = wxScrolledWindow.MyCanvas(win)
+ canvas = ScrolledWindow.MyCanvas(win)
win.Show(True)
import wx
-import wxScrolledWindow
+import ScrolledWindow
#----------------------------------------------------------------------
# There are better ways to do IDs, but this demo requires that the window
def OnNewWindow(self, evt):
self.winCount = self.winCount + 1
win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount)
- canvas = wxScrolledWindow.MyCanvas(win)
+ canvas = ScrolledWindow.MyCanvas(win)
win.Show(True)
--- /dev/null
+# 11/12/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+import MDIDemo
+import MDISashDemo
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ b1 = wx.Button(self, -1, "MDI demo")
+ self.Bind(wx.EVT_BUTTON, self.ShowMDIDemo, b1)
+
+ b2 = wx.Button(self, -1, "MDI with SashWindows demo")
+ self.Bind(wx.EVT_BUTTON, self.ShowMDISashDemo, b2)
+
+ box = wx.BoxSizer(wx.VERTICAL)
+ box.Add((20, 30))
+ box.Add(b1, 0, wx.ALIGN_CENTER|wx.ALL, 15)
+ box.Add(b2, 0, wx.ALIGN_CENTER|wx.ALL, 15)
+ self.SetAutoLayout(True)
+ self.SetSizer(box)
+
+
+ def ShowMDIDemo(self, evt):
+ frame = MDIDemo.MyParentFrame()
+ frame.Show()
+
+ def ShowMDISashDemo(self, evt):
+ frame = MDISashDemo.MyParentFrame()
+ frame.Show()
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>Multiple Document Interface</center></h2>
+
+Although Microsoft has deprecated the MDI model, wxWindows still supports
+it. Here are a couple samples of how to use it - one straightforward, the other
+showing how the MDI interface can be integrated into a SashWindow interface.
+
+</body></html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Library must be updated for this to run.
+#
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxMVCTree -> MVCTree
+#
+
+import os
+import sys
+
+import wx
+import wx.lib.mvctree as tree
+
+logger = None
+def selchanging(evt):
+ logger.write("SelChanging!\n")
+
+def selchanged(evt):
+ logger.write("SelChange!\n")
+ logger.write(str(evt.node))
+def expanded(evt):
+ logger.write("Expanded\n")
+def closed(evt):
+ logger.write("Closed!\n")
+def key(evt):
+ logger.write("Key\n")
+def add(evt):
+ logger.write("Add\n")
+def delitem(evt):
+ logger.write("Delete\n")
+
+def runTest(frame, nb, log):
+ #f = wx.Frame(frame, -1, "MVCTree", (0,0), (200,500))
+ global logger
+ logger = log
+ p = tree.MVCTree(nb, -1)
+ #f = wx.Frame(frame, -1, "MVCTree")
+ #p = tree.MVCTree(f, -1)
+ p.SetAssumeChildren(True)
+ p.SetModel(tree.LateFSTreeModel(os.path.normpath(os.getcwd() + os.sep +'..')))
+
+ #Uncomment this to enable live filename editing!
+# p.AddEditor(FileEditor(p))
+
+ p.SetMultiSelect(True)
+ tree.EVT_MVCTREE_SEL_CHANGING(p, p.GetId(), selchanging)
+ tree.EVT_MVCTREE_SEL_CHANGED(p, p.GetId(), selchanged)
+ tree.EVT_MVCTREE_ITEM_EXPANDED(p, p.GetId(), expanded)
+ tree.EVT_MVCTREE_ITEM_COLLAPSED(p, p.GetId(), closed)
+ tree.EVT_MVCTREE_ADD_ITEM(p, p.GetId(), add)
+ tree.EVT_MVCTREE_DELETE_ITEM(p, p.GetId(), delitem)
+ tree.EVT_MVCTREE_KEY_DOWN(p, p.GetId(), key)
+
+ return p
+ #frame.otherWin = f
+ #f.Show(True)
+ #return None
+
+
+overview = """\
+
+MVCTree is a control which handles hierarchical data. It is
+constructed in model-view-controller architecture, so the display of
+that data, and the content of the data can be changed greatly without
+affecting the other parts.
+
+Multiple selections are possible by holding down the Ctrl key.
+
+This demo shows the wxPython directory structure. The interesting part
+is that the tree model is late-bound to the filesystem, so the
+filenames are not retrieved until the directory is expanded. In
+mvctree.py are models for generic data, and both the early and
+late-bound filesystem models.
+
+There is also support for editing, though it's not enabled in this
+demo, to avoid accidentally renaming files!
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
_treeList = [
# new stuff
('Recent Additions', [
- 'wxVListBox',
- 'wxListbook',
- 'wxMaskedNumCtrl',
+ 'VListBox',
+ 'Listbook',
+ 'MaskedNumCtrl',
'FloatCanvas',
- 'wxXmlResourceSubclass',
- 'wxGridBagSizer',
+ 'XmlResourceSubclass',
+ 'GridBagSizer',
'Cursor',
'PyPlot',
]),
# managed windows == things with a (optional) caption you can close
('Base Frames and Dialogs', [
- 'wxDialog',
- 'wxFrame',
- 'wxMDIWindows',
- 'wxMiniFrame',
- 'wxWizard',
+ 'Dialog',
+ 'Frame',
+ 'MDIWindows',
+ 'MiniFrame',
+ 'Wizard',
]),
# the common dialogs
('Common Dialogs', [
- 'wxColourDialog',
- 'wxDirDialog',
- 'wxFileDialog',
- 'wxFileDialog_Save',
- 'wxFindReplaceDialog',
- 'wxFontDialog',
- 'wxMessageDialog',
- 'wxPageSetupDialog',
- 'wxPrintDialog',
- 'wxProgressDialog',
- 'wxSingleChoiceDialog',
- 'wxTextEntryDialog',
+ 'ColourDialog',
+ 'DirDialog',
+ 'FileDialog',
+ 'FileDialog_Save',
+ 'FindReplaceDialog',
+ 'FontDialog',
+ 'MessageDialog',
+ 'PageSetupDialog',
+ 'PrintDialog',
+ 'ProgressDialog',
+ 'SingleChoiceDialog',
+ 'TextEntryDialog',
]),
# dialogs from libraries
('More Dialogs', [
'ErrorDialogs',
'ImageBrowser',
- 'wxMultipleChoiceDialog',
- 'wxScrolledMessageDialog',
+ 'MultipleChoiceDialog',
+ 'ScrolledMessageDialog',
]),
# core controls
('Core Windows/Controls', [
+ 'Button',
+ 'CheckBox',
+ 'CheckListBox',
+ 'Choice',
+ 'ComboBox',
+ 'Gauge',
+ 'Grid',
+ 'Grid_MegaExample',
+ 'ListBox',
+ 'ListCtrl',
+ 'ListCtrl_virtual',
+ 'Listbook',
+ 'Menu',
+ 'Notebook',
'PopupMenu',
- 'wxButton',
- 'wxCheckBox',
- 'wxCheckListBox',
- 'wxChoice',
- 'wxComboBox',
- 'wxGauge',
- 'wxGrid',
- 'wxGrid_MegaExample',
- 'wxListbook',
- 'wxListBox',
- 'wxListCtrl',
- 'wxListCtrl_virtual',
- 'wxMenu',
- 'wxNotebook',
- 'wxPopupWindow',
- 'wxRadioBox',
- 'wxRadioButton',
- 'wxSashWindow',
- 'wxScrolledWindow',
- 'wxSlider',
- 'wxSpinButton',
- 'wxSpinCtrl',
- 'wxSplitterWindow',
- 'wxStaticBitmap',
- 'wxStaticText',
- 'wxStatusBar',
- 'wxTextCtrl',
- 'wxToggleButton',
- 'wxToolBar',
- 'wxTreeCtrl',
- 'wxValidator',
+ 'PopupWindow',
+ 'RadioBox',
+ 'RadioButton',
+ 'SashWindow',
+ 'ScrolledWindow',
+ 'Slider',
+ 'SpinButton',
+ 'SpinCtrl',
+ 'SplitterWindow',
+ 'StaticBitmap',
+ 'StaticText',
+ 'StatusBar',
+ 'TextCtrl',
+ 'ToggleButton',
+ 'ToolBar',
+ 'TreeCtrl',
+ 'Validator',
]),
('Custom Controls', [
'AnalogClockWindow',
'ColourSelect',
+ 'Editor',
'GenericButtons',
- 'wxEditor',
- 'wxGenericDirCtrl',
- 'wxLEDNumberCtrl',
- 'wxMultiSash',
- 'wxPopupControl',
- 'wxPyColourChooser',
- 'wxTreeListCtrl',
+ 'GenericDirCtrl',
+ 'LEDNumberCtrl',
+ 'MultiSash',
+ 'PopupControl',
+ 'PyColourChooser',
+ 'TreeListCtrl',
]),
# controls coming from other libraries
('More Windows/Controls', [
- #'wxFloatBar', deprecated
- #'wxMVCTree', deprecated
- #'wxRightTextCtrl', deprecated as we have wxTE_RIGHT now.
+ #'RightTextCtrl', deprecated as we have wxTE_RIGHT now.
+ 'Calendar',
+ 'CalendarCtrl',
'ContextHelp',
+ 'DynamicSashWindow',
+ 'EditableListBox',
'FancyText',
- 'FloatCanvas',
'FileBrowseButton',
+ 'FloatBar',
+ 'FloatCanvas',
+ 'HtmlWindow',
+ 'IEHtmlWin',
+ 'IntCtrl',
+ 'MVCTree',
'MaskedEditControls',
- 'PyShell',
+ 'MaskedNumCtrl',
+ 'MimeTypesManager',
'PyCrust',
'PyPlot',
+ 'PyShell',
+ 'ScrolledPanel',
'SplitTree',
+ 'StyledTextCtrl_1',
+ 'StyledTextCtrl_2',
'TablePrint',
'Throbber',
- 'wxCalendar',
- 'wxCalendarCtrl',
- 'wxDynamicSashWindow',
- 'wxEditableListBox',
- 'wxHtmlWindow',
- 'wxIEHtmlWin',
- 'wxIntCtrl',
- 'wxMimeTypesManager',
- 'wxMaskedNumCtrl',
- 'wxScrolledPanel',
- 'wxStyledTextCtrl_1',
- 'wxStyledTextCtrl_2',
- 'wxTimeCtrl',
- 'wxVListBox',
+ 'TimeCtrl',
+ 'VListBox',
]),
# How to lay out the controls in a frame/dialog
('Window Layout', [
+ 'GridBagSizer',
'LayoutAnchors',
+ 'LayoutConstraints',
'Layoutf',
'RowColSizer',
+ 'ScrolledPanel',
'Sizers',
- 'wxGridBagSizer',
- 'wxLayoutConstraints',
- 'wxScrolledPanel',
- 'wxXmlResource',
- 'wxXmlResourceHandler',
- 'wxXmlResourceSubclass',
+ 'XmlResource',
+ 'XmlResourceHandler',
+ 'XmlResourceSubclass',
]),
# ditto
('Process and Events', [
'EventManager',
- 'infoframe',
+ 'KeyEvents',
'OOR',
+ 'Process',
'PythonEvents',
'Threads',
- 'wxKeyEvents',
- 'wxProcess',
- 'wxTimer',
+ 'Timer',
+ 'infoframe',
]),
# Clipboard and DnD
# Images
('Using Images', [
+ 'ArtProvider',
'Cursor',
+ 'DragImage',
+ 'Image',
+ 'ImageFromStream',
+ 'Mask',
'Throbber',
- 'wxArtProvider',
- 'wxDragImage',
- 'wxImage',
- 'wxImageFromStream',
- 'wxMask',
]),
# Other stuff
'ColourDB',
'DialogUnits',
'DrawXXXList',
+ 'FileHistory',
'FontEnumerator',
+ 'Joystick',
'NewNamespace',
+ 'OGL',
'PrintFramework',
'ShapedWindow',
'Throbber',
'Unicode',
- 'wxFileHistory',
- 'wxJoystick',
- 'wxOGL',
- 'wxWave',
+ 'Wave',
]),
# need libs not coming with the demo
('Objects using an external library', [
'ActiveXWrapper_Acrobat',
'ActiveXWrapper_IE',
- 'wxGLCanvas',
- #'wxPlotCanvas', # deprecated, use PyPlot
+ 'GLCanvas',
+ #'PlotCanvas', # deprecated, use PyPlot
]),
#---------------------------------------------------------------------------
# A class to be used to display source code in the demo. Try using the
-# wxSTC in the wxStyledTextCtrl_2 sample first, fall back to wxTextCtrl
+# wxSTC in the StyledTextCtrl_2 sample first, fall back to wxTextCtrl
# if there is an error, such as the stc module not being present.
#
try:
##raise ImportError
from wx import stc
- from wxStyledTextCtrl_2 import PythonSTC
+ from StyledTextCtrl_2 import PythonSTC
class DemoCodeViewer(PythonSTC):
def __init__(self, parent, ID):
PythonSTC.__init__(self, parent, ID)
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+logicList = [
+ ('wx.AND', wx.AND),
+ ('wx.AND_INVERT', wx.AND_INVERT),
+ ('wx.AND_REVERSE', wx.AND_REVERSE),
+ ('wx.CLEAR', wx.CLEAR),
+ ('wx.COPY', wx.COPY),
+ ('wx.EQUIV', wx.EQUIV),
+ ('wx.INVERT', wx.INVERT),
+ ('wx.NAND', wx.NAND),
+
+ # this one causes an assert on wxGTK, and doesn't seem to
+ # do much on MSW anyway, so I'll just take it out....
+ #('wxNOR', wxNOR),
+
+ ('wx.NO_OP', wx.NO_OP),
+ ('wx.OR', wx.OR),
+ ('wx.OR_INVERT', wx.OR_INVERT),
+ ('wx.OR_REVERSE', wx.OR_REVERSE),
+ ('wx.SET', wx.SET),
+ ('wx.SRC_INVERT', wx.SRC_INVERT),
+ ('wx.XOR', wx.XOR),
+]
+
+import images
+
+class TestMaskWindow(wx.ScrolledWindow):
+ def __init__(self, parent):
+ wx.ScrolledWindow.__init__(self, parent, -1)
+ self.SetBackgroundColour(wx.Colour(0,128,0))
+
+ # A reference bitmap that we won't mask
+ self.bmp_nomask = images.getTestStar2Bitmap()
+
+ # One that we will
+ self.bmp_withmask = images.getTestStar2Bitmap()
+
+ # this mask comes from a monochrome bitmap
+ self.bmp_themask = wx.BitmapFromImage(images.getTestMaskImage(), 1)
+ mask = wx.Mask(self.bmp_themask)
+
+ # set the mask on our bitmap
+ self.bmp_withmask.SetMask(mask)
+
+ # Now we'll create a mask in a bit of an easier way, by picking a
+ # colour in the image that is to be the transparent colour.
+ self.bmp_withcolourmask = images.getTestStar2Bitmap()
+ mask = wx.MaskColour(self.bmp_withcolourmask, wx.WHITE)
+ self.bmp_withcolourmask.SetMask(mask)
+
+ self.SetScrollbars(20, 20, 700/20, 460/20)
+
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+
+
+ def OnPaint (self, e):
+ dc = wx.PaintDC(self)
+ self.PrepareDC(dc)
+ dc.SetTextForeground(wx.WHITE)
+
+ # make an interesting background...
+ dc.SetPen(wx.MEDIUM_GREY_PEN)
+ for i in range(100):
+ dc.DrawLine((0,i*10), (i*10,0))
+
+ # draw raw image, mask, and masked images
+ dc.DrawText('original image', (0,0))
+ dc.DrawBitmap(self.bmp_nomask, (0,20), 0)
+ dc.DrawText('with colour mask', (0,100))
+ dc.DrawBitmap(self.bmp_withcolourmask, (0,120), 1)
+ dc.DrawText('the mask image', (0,200))
+ dc.DrawBitmap(self.bmp_themask, (0,220), 0)
+ dc.DrawText('masked image', (0,300))
+ dc.DrawBitmap(self.bmp_withmask, (0,320), 1)
+
+ cx,cy = self.bmp_themask.GetWidth(), self.bmp_themask.GetHeight()
+
+ # draw array of assorted blit operations
+ mdc = wx.MemoryDC()
+ i = 0
+
+ for text, code in logicList:
+ x,y = 120+150*(i%4), 20+100*(i/4)
+ dc.DrawText(text, (x, y-20))
+ mdc.SelectObject(self.bmp_withcolourmask)
+ dc.Blit((x,y), (cx,cy), mdc, (0,0), code, True)
+ i = i + 1
+
+
+# On wxGTK there needs to be a panel under wx.ScrolledWindows if they are
+# going to be in a wxNotebook...
+class TestPanel(wx.Panel):
+ def __init__(self, parent, ID):
+ wx.Panel.__init__(self, parent, ID)
+ self.win = TestMaskWindow(self)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+
+ def OnSize(self, evt):
+ self.win.SetSize(evt.GetSize())
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, -1)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+This class encapsulates a monochrome mask bitmap, where the masked area is black
+and the unmasked area is white. When associated with a bitmap and drawn in a device
+context, the unmasked area of the bitmap will be drawn, and the masked area will
+not be drawn.
+
+This example shows not only how to create a Mask, but the effects of the Device
+Context (dc) <code>Blit()</code> method's logic codes.
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wx.lib.maskednumctrl needs hit up with the renamer and new binders
+#
+# 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Issues with lib corrected.
+#
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxMaskedNumCtrl -> MaskedNumCtrl
+#
+
+import string
+import sys
+import traceback
+
+import wx
+import wx.lib.maskednumctrl as mnum
+#----------------------------------------------------------------------
+
+class TestPanel( wx.Panel ):
+ def __init__( self, parent, log ):
+
+ wx.Panel.__init__( self, parent, -1 )
+ self.log = log
+ panel = wx.Panel( self, -1 )
+
+ header = wx.StaticText(panel, -1, """\
+This shows the various options for MaskedNumCtrl.
+The controls at the top reconfigure the resulting control at the bottom.
+""")
+ header.SetForegroundColour( "Blue" )
+
+ intlabel = wx.StaticText( panel, -1, "Integer width:" )
+ self.integerwidth = mnum.MaskedNumCtrl(
+ panel, value=10, integerWidth=2, allowNegative=False
+ )
+
+ fraclabel = wx.StaticText( panel, -1, "Fraction width:" )
+ self.fractionwidth = mnum.MaskedNumCtrl(
+ panel, value=0, integerWidth=2, allowNegative=False
+ )
+
+ groupcharlabel = wx.StaticText( panel,-1, "Grouping char:" )
+ self.groupchar = mnum.MaskedTextCtrl(
+ panel, -1, value=',', mask='&', excludeChars = '-()',
+ formatcodes='F', emptyInvalid=True, validRequired=True
+ )
+
+ decimalcharlabel = wx.StaticText( panel,-1, "Decimal char:" )
+ self.decimalchar = mnum.MaskedTextCtrl(
+ panel, -1, value='.', mask='&', excludeChars = '-()',
+ formatcodes='F', emptyInvalid=True, validRequired=True
+ )
+
+ self.set_min = wx.CheckBox( panel, -1, "Set minimum value:" )
+ # Create this MaskedNumCtrl using factory, to show how:
+ self.min = mnum.MaskedNumCtrl( panel, integerWidth=5, fractionWidth=2 )
+ self.min.Enable( False )
+
+ self.set_max = wx.CheckBox( panel, -1, "Set maximum value:" )
+ self.max = mnum.MaskedNumCtrl( panel, integerWidth=5, fractionWidth=2 )
+ self.max.Enable( False )
+
+
+ self.limit_target = wx.CheckBox( panel, -1, "Limit control" )
+ self.allow_none = wx.CheckBox( panel, -1, "Allow empty control" )
+ self.group_digits = wx.CheckBox( panel, -1, "Group digits" )
+ self.group_digits.SetValue( True )
+ self.allow_negative = wx.CheckBox( panel, -1, "Allow negative values" )
+ self.allow_negative.SetValue( True )
+ self.use_parens = wx.CheckBox( panel, -1, "Use parentheses" )
+ self.select_on_entry = wx.CheckBox( panel, -1, "Select on entry" )
+ self.select_on_entry.SetValue( True )
+
+ label = wx.StaticText( panel, -1, "Resulting numeric control:" )
+ font = label.GetFont()
+ font.SetWeight(wx.BOLD)
+ label.SetFont(font)
+
+ self.target_ctl = mnum.MaskedNumCtrl( panel, -1, name="target control" )
+
+ label_numselect = wx.StaticText( panel, -1, """\
+Programmatically set the above
+value entry ctrl:""")
+ self.numselect = wx.ComboBox(panel, -1, choices = [ '0', '111', '222.22', '-3', '54321.666666666', '-1353.978',
+ '1234567', '-1234567', '123456789', '-123456789.1',
+ '1234567890.', '-9876543210.9' ])
+
+ grid1 = wx.FlexGridSizer( 0, 4, 0, 0 )
+ grid1.Add( intlabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+ grid1.Add( self.integerwidth, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid1.Add( groupcharlabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+ grid1.Add( self.groupchar, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid1.Add( fraclabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid1.Add( self.fractionwidth, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid1.Add( decimalcharlabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+ grid1.Add( self.decimalchar, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid1.Add( self.set_min, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid1.Add( self.min, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+
+ grid1.Add( self.set_max, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid1.Add( self.max, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+
+
+ grid1.Add( self.limit_target, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid1.Add( self.allow_none, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ hbox1 = wx.BoxSizer( wx.HORIZONTAL )
+ hbox1.Add( (17,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ hbox1.Add( self.group_digits, 0, wx.ALIGN_LEFT|wx.LEFT, 5 )
+ grid1.Add( hbox1, 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+
+ grid1.Add( self.allow_negative, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid1.Add( self.use_parens, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ hbox2 = wx.BoxSizer( wx.HORIZONTAL )
+ hbox2.Add( (17,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ hbox2.Add( self.select_on_entry, 0, wx.ALIGN_LEFT|wx.LEFT, 5 )
+ grid1.Add( hbox2, 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+
+
+ grid2 = wx.FlexGridSizer( 0, 2, 0, 0 )
+ grid2.Add( label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid2.Add( self.target_ctl, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid2.Add( label_numselect, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid2.Add( self.numselect, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ grid2.AddGrowableCol(1)
+
+ self.outer_box = wx.BoxSizer( wx.VERTICAL )
+ self.outer_box.Add(header, 0, wx.ALIGN_LEFT|wx.TOP|wx.LEFT, 20)
+ self.outer_box.Add( grid1, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.BOTTOM|wx.RIGHT, 20 )
+ self.outer_box.Add( grid2, 0, wx.ALIGN_LEFT|wx.ALL, 20 )
+ self.grid2 = grid2
+
+ panel.SetAutoLayout( True )
+ panel.SetSizer( self.outer_box )
+ self.outer_box.Fit( panel )
+ panel.Move( (50,10) )
+ self.panel = panel
+
+ self.Bind(mnum.EVT_MASKEDNUM, self.OnSetIntWidth, self.integerwidth )
+ self.Bind(mnum.EVT_MASKEDNUM, self.OnSetFractionWidth, self.fractionwidth )
+ self.Bind(wx.EVT_TEXT, self.OnSetGroupChar, self.groupchar )
+ self.Bind(wx.EVT_TEXT, self.OnSetDecimalChar, self.decimalchar )
+
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetMin, self.set_min )
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetMax, self.set_max )
+ self.Bind(mnum.EVT_MASKEDNUM, self.SetTargetMinMax, self.min )
+ self.Bind(mnum.EVT_MASKEDNUM, self.SetTargetMinMax, self.max )
+
+ self.Bind(wx.EVT_CHECKBOX, self.SetTargetMinMax, self.limit_target )
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowNone, self.allow_none )
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetGroupDigits, self.group_digits )
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowNegative, self.allow_negative )
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetUseParens, self.use_parens )
+ self.Bind(wx.EVT_CHECKBOX, self.OnSetSelectOnEntry, self.select_on_entry )
+
+ self.Bind(mnum.EVT_MASKEDNUM, self.OnTargetChange, self.target_ctl )
+ self.Bind(wx.EVT_COMBOBOX, self.OnNumberSelect, self.numselect )
+
+
+ def OnSetIntWidth(self, event ):
+ width = self.integerwidth.GetValue()
+
+ if width < 1:
+ self.log.write("integer width must be positive\n")
+ self.integerwidth.SetForegroundColour(wx.RED)
+ else:
+ self.integerwidth.SetForegroundColour(wx.BLACK)
+ self.log.write("setting integer width to %d\n" % width)
+ self.target_ctl.SetParameters( integerWidth = width)
+ # Now resize and fit the dialog as appropriate:
+ self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
+ self.outer_box.Fit( self.panel )
+ self.outer_box.SetSizeHints( self.panel )
+
+
+ def OnSetFractionWidth(self, event ):
+ width = self.fractionwidth.GetValue()
+ self.log.write("setting fraction width to %d\n" % width)
+ self.target_ctl.SetParameters( fractionWidth = width)
+ # Now resize and fit the dialog as appropriate:
+ self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
+ self.outer_box.Fit( self.panel )
+ self.outer_box.SetSizeHints( self.panel )
+
+
+ def OnSetGroupChar( self, event ):
+ char = self.groupchar.GetValue()
+ if self.target_ctl.GetDecimalChar() == char:
+ self.log.write("group and decimal chars must be different\n")
+ self.groupchar.SetForegroundColour(wx.RED)
+ else:
+ self.groupchar.SetForegroundColour(wx.BLACK)
+ self.log.write("setting group char to %s\n" % char)
+ self.target_ctl.SetGroupChar( char )
+
+ def OnSetDecimalChar( self, event ):
+ char = self.decimalchar.GetValue()
+ if self.target_ctl.GetGroupChar() == char:
+ self.log.write("group and decimal chars must be different\n")
+ self.decimalchar.SetForegroundColour(wx.RED)
+ else:
+ self.decimalchar.SetForegroundColour(wx.BLACK)
+ self.log.write("setting decimal char to %s\n" % char)
+ self.target_ctl.SetDecimalChar( char )
+
+
+ def OnSetMin( self, event ):
+ self.min.Enable( self.set_min.GetValue() )
+ self.SetTargetMinMax()
+
+ def OnSetMax( self, event ):
+ self.max.Enable( self.set_max.GetValue() )
+ self.SetTargetMinMax()
+
+
+ def SetTargetMinMax( self, event=None ):
+ min = max = None
+ self.target_ctl.SetLimited( self.limit_target.GetValue() )
+
+ if self.set_min.GetValue():
+ min = self.min.GetValue()
+ if self.set_max.GetValue():
+ max = self.max.GetValue()
+
+ cur_min, cur_max = self.target_ctl.GetBounds()
+
+ if min != cur_min and not self.target_ctl.SetMin( min ):
+ if self.target_ctl.GetMax() is None and cur_max > min:
+ self.log.write( "min (%d) won't fit in control -- bound not set\n" % min )
+ else:
+ self.log.write( "min (%d) > current max (%d) -- bound not set\n" % ( min, self.target_ctl.GetMax() ) )
+ self.min.SetParameters( signedForegroundColour=wx.RED, foregroundColour=wx.RED )
+ else:
+ self.min.SetParameters( signedForegroundColour=wx.BLACK, foregroundColour=wx.BLACK )
+ self.min.Refresh()
+
+ if max != cur_max and not self.target_ctl.SetMax( max ):
+ if self.target_ctl.GetMax() is None and cur_min < max:
+ self.log.write( "max (%d) won't fit in control -- bound not set\n" % max )
+ else:
+ self.log.write( "max (%d) < current min (%d) -- bound not set\n" % ( max, self.target_ctl.GetMin() ) )
+ self.max.SetParameters( signedForegroundColour=wx.RED, foregroundColour=wx.RED )
+ else:
+ self.max.SetParameters( signedForegroundColour=wx.BLACK, foregroundColour=wx.BLACK )
+ self.max.Refresh()
+
+ if min != cur_min or max != cur_max:
+ new_min, new_max = self.target_ctl.GetBounds()
+ self.log.write( "current min, max: (%s, %s)\n" % ( str(new_min), str(new_max) ) )
+
+
+ def OnSetAllowNone( self, event ):
+ self.target_ctl.SetAllowNone( self.allow_none.GetValue() )
+
+
+ def OnSetGroupDigits( self, event ):
+ self.target_ctl.SetGroupDigits( self.group_digits.GetValue() )
+ # Now resize and fit the dialog as appropriate:
+ self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
+ self.outer_box.Fit( self.panel )
+ self.outer_box.SetSizeHints( self.panel )
+
+
+ def OnSetAllowNegative( self, event ):
+ if self.allow_negative.GetValue():
+ self.use_parens.Enable(True)
+ self.target_ctl.SetParameters(allowNegative=True,
+ useParensForNegatives = self.use_parens.GetValue())
+ else:
+ self.target_ctl.SetAllowNegative(False)
+ # Now resize and fit the dialog as appropriate:
+ self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
+ self.outer_box.Fit( self.panel )
+ self.outer_box.SetSizeHints( self.panel )
+
+
+ def OnSetUseParens( self, event ):
+ self.target_ctl.SetUseParensForNegatives( self.use_parens.GetValue() )
+ # Now resize and fit the dialog as appropriate:
+ self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
+ self.outer_box.Fit( self.panel )
+ self.outer_box.SetSizeHints( self.panel )
+
+
+ def OnSetSelectOnEntry( self, event ):
+ self.target_ctl.SetSelectOnEntry( self.select_on_entry.GetValue() )
+
+
+ def OnTargetChange( self, event ):
+ ctl = event.GetEventObject()
+ value = ctl.GetValue()
+ ib_str = [ " (out of bounds)", "" ]
+ self.log.write( "value = %s (%s)%s\n" % ( repr(value), repr(type(value)), ib_str[ ctl.IsInBounds(value) ] ) )
+
+
+ def OnNumberSelect( self, event ):
+ value = event.GetString()
+ if value:
+ if value.find('.') != -1:
+ numvalue = float(value)
+ else:
+ numvalue = long(value)
+ else:
+ numvalue = value # try to clear the value again
+
+ try:
+ self.target_ctl.SetValue(numvalue)
+ except:
+ type, value, tb = sys.exc_info()
+ for line in traceback.format_exception_only(type, value):
+ self.log.write(line)
+
+
+#----------------------------------------------------------------------
+
+def runTest( frame, nb, log ):
+ win = TestPanel( nb, log )
+ return win
+
+#----------------------------------------------------------------------
+overview = mnum.__doc__
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+#-------------------------------------------------------------------
+# essaimenu.py
+#
+# menus in wxPython 2.3.3
+#
+#-------------------------------------------------------------------
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import time
+import wx
+import images
+
+#-------------------------------------------------------------------
+
+class MyFrame(wx.Frame):
+
+ def __init__(self, parent, id, log):
+ wx.Frame.__init__(self, parent, id, 'Playing with menus', size=(400, 200))
+ self.log = log
+ self.CenterOnScreen()
+
+ self.CreateStatusBar()
+ self.SetStatusText("This is the statusbar")
+
+ tc = wx.TextCtrl(self, -1, """
+A bunch of bogus menus have been created for this frame. You
+can play around with them to see how they behave and then
+check the source for this sample to see how to implement them.
+""", style=wx.TE_READONLY|wx.TE_MULTILINE)
+
+ # Prepare the menu bar
+ menuBar = wx.MenuBar()
+
+ # 1st menu from left
+ menu1 = wx.Menu()
+ menu1.Append(101, "&Mercury", "This the text in the Statusbar")
+ menu1.Append(102, "&Venus", "")
+ menu1.Append(103, "&Earth", "You may select Earth too")
+ menu1.AppendSeparator()
+ menu1.Append(104, "&Close", "Close this frame")
+ # Add menu to the menu bar
+ menuBar.Append(menu1, "&Planets")
+
+ # 2nd menu from left
+ menu2 = wx.Menu()
+ menu2.Append(201, "Hydrogen")
+ menu2.Append(202, "Helium")
+ # a submenu in the 2nd menu
+ submenu = wx.Menu()
+ submenu.Append(2031,"Lanthanium")
+ submenu.Append(2032,"Cerium")
+ submenu.Append(2033,"Praseodymium")
+ menu2.AppendMenu(203, "Lanthanides", submenu)
+ # Append 2nd menu
+ menuBar.Append(menu2, "&Elements")
+
+ menu3 = wx.Menu()
+ # Radio items
+ menu3.Append(301, "IDLE", "a Python shell using tcl/tk as GUI", wx.ITEM_RADIO)
+ menu3.Append(302, "PyCrust", "a Python shell using wxPython as GUI", wx.ITEM_RADIO)
+ menu3.Append(303, "psi", "a simple Python shell using wxPython as GUI", wx.ITEM_RADIO)
+ menu3.AppendSeparator()
+ menu3.Append(304, "project1", "", wx.ITEM_NORMAL)
+ menu3.Append(305, "project2", "", wx.ITEM_NORMAL)
+ menuBar.Append(menu3, "&Shells")
+
+ menu4 = wx.Menu()
+ # Check menu items
+ menu4.Append(401, "letters", "abcde...", wx.ITEM_CHECK)
+ menu4.Append(402, "digits", "123...", wx.ITEM_CHECK)
+ menu4.Append(403, "letters and digits", "abcd... + 123...", wx.ITEM_CHECK)
+ menuBar.Append(menu4, "Chec&k")
+
+ menu5 = wx.Menu()
+ # Show how to put an icon in the menu
+ item = wx.MenuItem(menu5, 500, "&Smile!\tCtrl+S", "This one has an icon")
+ item.SetBitmap(images.getSmilesBitmap())
+ menu5.AppendItem(item)
+
+ # Shortcuts
+ menu5.Append(501, "Interesting thing\tCtrl+A", "Note the shortcut!")
+ menu5.AppendSeparator()
+ menu5.Append(502, "Hello\tShift+H")
+ menu5.AppendSeparator()
+ menu5.Append(503, "remove the submenu")
+ menu6 = wx.Menu()
+ menu6.Append(601, "Submenu Item")
+ menu5.AppendMenu(504, "submenu", menu6)
+ menu5.Append(505, "remove this menu")
+ menu5.Append(506, "this is updated")
+ menu5.Append(507, "insert after this...")
+ menu5.Append(508, "...and before this")
+ menuBar.Append(menu5, "&Fun")
+
+ self.SetMenuBar(menuBar)
+
+ # Menu events
+ self.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuHighlight)
+
+ self.Bind(wx.EVT_MENU, self.Menu101, id=101)
+ self.Bind(wx.EVT_MENU, self.Menu102, id=102)
+ self.Bind(wx.EVT_MENU, self.Menu103, id=103)
+ self.Bind(wx.EVT_MENU, self.CloseWindow, id=104)
+
+ self.Bind(wx.EVT_MENU, self.Menu201, id=201)
+ self.Bind(wx.EVT_MENU, self.Menu202, id=202)
+ self.Bind(wx.EVT_MENU, self.Menu2031, id=2031)
+ self.Bind(wx.EVT_MENU, self.Menu2032, id=2032)
+ self.Bind(wx.EVT_MENU, self.Menu2033, id=2033)
+
+ self.Bind(wx.EVT_MENU, self.Menu301To303, id=301)
+ self.Bind(wx.EVT_MENU, self.Menu301To303, id=302)
+ self.Bind(wx.EVT_MENU, self.Menu301To303, id=303)
+ self.Bind(wx.EVT_MENU, self.Menu304, id=304)
+ self.Bind(wx.EVT_MENU, self.Menu305, id=305)
+
+ # Range of menu items
+ self.Bind(wx.EVT_MENU_RANGE, self.Menu401To403, id=401, id2=403)
+
+ self.Bind(wx.EVT_MENU, self.Menu500, id=500)
+ self.Bind(wx.EVT_MENU, self.Menu501, id=501)
+ self.Bind(wx.EVT_MENU, self.Menu502, id=502)
+ self.Bind(wx.EVT_MENU, self.TestRemove, id=503)
+ self.Bind(wx.EVT_MENU, self.TestRemove2, id=505)
+ self.Bind(wx.EVT_MENU, self.TestInsert, id=507)
+ self.Bind(wx.EVT_MENU, self.TestInsert, id=508)
+
+ wx.GetApp().Bind(wx.EVT_UPDATE_UI, self.TestUpdateUI, id=506)
+
+ # Methods
+
+ def OnMenuHighlight(self, event):
+ # Show how to get menu item imfo from this event handler
+ id = event.GetMenuId()
+ item = self.GetMenuBar().FindItemById(id)
+ text = item.GetText()
+ help = item.GetHelp()
+
+ #print text, help
+ # but in this case just call Skip so the default is done
+ event.Skip()
+
+
+ def Menu101(self, event):
+ self.log.write('Welcome to Mercury\n')
+
+ def Menu102(self, event):
+ self.log.write('Welcome to Venus\n')
+
+ def Menu103(self, event):
+ self.log.write('Welcome to the Earth\n')
+
+ def CloseWindow(self, event):
+ self.Close()
+
+ def Menu201(self, event):
+ self.log.write('Chemical element number 1\n')
+
+ def Menu202(self, event):
+ self.log.write('Chemical element number 2\n')
+
+ def Menu2031(self, event):
+ self.log.write('Element number 57\n')
+
+ def Menu2032(self, event):
+ self.log.write('Element number 58\n')
+
+ def Menu2033(self, event):
+ self.log.write('Element number 59\n')
+
+ def Menu301To303(self, event):
+ id = event.GetId()
+ self.log.write('Event id: %d\n' % id)
+
+ def Menu304(self, event):
+ self.log.write('Not yet available\n')
+
+ def Menu305(self, event):
+ self.log.write('Still vapour\n')
+
+ def Menu401To403(self, event):
+ self.log.write('From a EVT_MENU_RANGE event\n')
+
+ def Menu500(self, event):
+ self.log.write('Have a happy day!\n')
+
+ def Menu501(self, event):
+ self.log.write('Look in the code how the shortcut has been realized\n')
+
+ def Menu502(self, event):
+ self.log.write('Hello from Jean-Michel\n')
+
+
+ def TestRemove(self, evt):
+ mb = self.GetMenuBar()
+ submenuItem = mb.FindItemById(601)
+
+ if not submenuItem:
+ return
+
+ submenu = submenuItem.GetMenu()
+ menu = submenu.GetParent()
+
+ # This works
+ #menu.Remove(504)
+
+ # this also works
+ menu.RemoveItem(mb.FindItemById(504))
+
+ # This doesn't work, as expected since submenuItem is not on menu
+ #menu.RemoveItem(submenuItem)
+
+
+ def TestRemove2(self, evt):
+ mb = self.GetMenuBar()
+ mb.Remove(4)
+
+
+ def TestUpdateUI(self, evt):
+ text = time.ctime()
+ evt.SetText(text)
+
+
+ def TestInsert(self, evt):
+ theID = 508
+ # get the menu
+ mb = self.GetMenuBar()
+ menuItem = mb.FindItemById(theID)
+ menu = menuItem.GetMenu()
+
+ # figure out the position to insert at
+ pos = 0
+
+ for i in menu.GetMenuItems():
+ if i.GetId() == theID:
+ break
+
+ pos += 1
+
+ # now insert the new item
+ ID = wx.NewId()
+ ##menu.Insert(pos, ID, "NewItem " + str(ID))
+ item = wx.MenuItem(menu)
+ item.SetId(ID)
+ item.SetText("NewItem " + str(ID))
+ menu.InsertItem(pos, item)
+
+
+#-------------------------------------------------------------------
+
+wx.RegisterId(10000)
+
+def runTest(frame, nb, log):
+ win = MyFrame(frame, -1, log)
+ frame.otherWin = win
+ win.Show(True)
+
+
+#-------------------------------------------------------------------
+
+
+overview = """\
+A demo of using wxMenuBar and wxMenu in various ways.
+
+A menu is a popup (or pull down) list of items, one of which may be selected
+before the menu goes away (clicking elsewhere dismisses the menu). Menus may be
+used to construct either menu bars or popup menus.
+
+A menu item has an integer ID associated with it which can be used to identify
+the selection, or to change the menu item in some way. A menu item with a special
+identifier -1 is a separator item and doesn't have an associated command but just
+makes a separator line appear in the menu.
+
+Menu items may be either normal items, check items or radio items. Normal items
+don't have any special properties while the check items have a boolean flag associated
+to them and they show a checkmark in the menu when the flag is set. wxWindows
+automatically toggles the flag value when the item is clicked and its value may
+be retrieved using either IsChecked method of wxMenu or wxMenuBar itself or by
+using wxEvent.IsChecked when you get the menu notification for the item in question.
+
+The radio items are similar to the check items except that all the other items
+in the same radio group are unchecked when a radio item is checked. The radio group
+is formed by a contiguous range of radio items, i.e. it starts at the first item of
+this kind and ends with the first item of a different kind (or the end of the menu).
+Notice that because the radio groups are defined in terms of the item positions
+inserting or removing the items in the menu containing the radio items risks to not
+work correctly. Finally note that the radio items are only supported under Windows
+and GTK+ currently.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ dlg = wx.MessageDialog(frame, 'Hello from Python and wxPython!',
+ 'A Message Box', wx.OK | wx.ICON_INFORMATION)
+ #wxYES_NO | wxNO_DEFAULT | wxCANCEL | wxICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+This class represents a dialog that shows a single or multi-line message, with a
+choice of OK, Yes, No and Cancel buttons.
+
+Additionally, various style flags can determine whether an icon is displayed,
+and, if so, what kind.
+
+The dialog can be modal or not; of modal, the user's response is in the return
+code of ShowModal(). If not, the response can be taken from GetReturnCode() (inherited
+from the wxDialog super class). If not modal and the return code is required, it
+must be retrieved before the dialog is destroyed.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+#----------------------------------------------------------------------
+# Name: wxMimeTypesManager
+# Purpose: Demonstrate use of wx.MimeTypesManager, wx.FileType
+#
+# Author: Jeff Grimmett (grimmtoo@softhome.net), adapted from original
+# .wdr-derived demo
+#
+# Created: 12/31/03
+# RCS-ID: $Id$
+# Copyright:
+# Licence: wxWindows license
+#----------------------------------------------------------------------
+#
+
+
+import pprint
+import wx
+import images
+
+#----------------------------------------------------------------------------
+
+# A convenient wrapper around wx.TextCtrl to give it a spiffy label.
+class ExtStr(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent, -1)
+ sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, 'Extension'), wx.HORIZONTAL)
+ self.ctl = wx.TextCtrl(self, -1, value="wav", style = wx.TE_PROCESS_ENTER )
+ sizer.Add(self.ctl, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 3)
+ self.Enable(True)
+
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+
+ def Enable(self, value):
+ self.ctl.Enable(value)
+
+ def SetValue(self, value):
+ self.ctl.SetValue(value)
+
+ def GetValue(self):
+ return(self.ctl.GetValue())
+
+
+class MimeTypesDemoPanel(wx.Panel):
+ def __init__(self, parent, log):
+
+ self.log = log
+
+ wx.Panel.__init__(self, parent, -1)
+
+ # Contains everything
+ tsizer = wx.BoxSizer(wx.VERTICAL)
+
+ # Contains upper controls
+ usizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ # A little fancy stuff to make things align right.
+ self.ext = ExtStr(self)
+ usizer.Add(self.ext, 0, wx.ALL | wx.ALIGN_TOP, 4)
+ self.ext.Bind(wx.EVT_TEXT_ENTER, self.OnLookup)
+
+ # Select how to look it up
+ self.how = wx.RadioBox(
+ self, -1, "Lookup method", choices=['By extension', 'By MIME type'],
+ majorDimension=2, style=wx.RA_SPECIFY_COLS
+ )
+ usizer.Add(self.how, 0, wx.ALL | wx.ALIGN_TOP, 4)
+ self.how.SetSelection(0)
+
+ # Trigger a lookup (hitting ENTER in the text ctrl will do the same thing)
+ self.go = wx.Button(self, -1, "Go get it!")
+ usizer.Add(self.go, 0, wx.ALL | wx.ALIGN_CENTER, 4)
+ self.Bind(wx.EVT_BUTTON, self.OnLookup, self.go)
+
+ # StaticBox with larger label than usual
+ lbox = wx.StaticBox(self, -1, 'wx.FileType')
+ lbox.SetFont(
+ wx.Font(
+ self.GetFont().GetPointSize() * 2,
+ self.GetFont().GetFamily(),
+ self.GetFont().GetStyle(),
+ wx.BOLD
+ ))
+
+ lsizer = wx.StaticBoxSizer(lbox, wx.HORIZONTAL)
+
+ # Contains the wx.FileType info
+ llsizer = wx.GridBagSizer(2, 2)
+ llsizer.AddGrowableCol(2)
+
+ # This will be used for all of the labels that follow (bold label)
+ bfont = wx.Font(
+ self.GetFont().GetPointSize(),
+ self.GetFont().GetFamily(),
+ self.GetFont().GetStyle(),
+ wx.BOLD
+ )
+
+ #------- Icon info
+
+ t = wx.StaticText(self, -1, 'GetIconInfo: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (0, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.icon = wx.StaticBitmap(self, -1, images.getNoIconBitmap())
+ llsizer.Add(self.icon, (0, 1), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.iconsource = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
+ llsizer.Add(self.iconsource, (0, 2), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.iconoffset = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
+ llsizer.Add(self.iconoffset, (0, 3), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ #------- MIME Type
+
+ t = wx.StaticText(self, -1, 'GetMimeType: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (1, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.mimetype = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
+ llsizer.Add(self.mimetype, (1, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ #------- MIME Types
+
+ t = wx.StaticText(self, -1, 'GetMimeTypes: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (2, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.mimetypes = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
+ llsizer.Add(self.mimetypes, (2, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ #------- Extensions
+
+ t = wx.StaticText(self, -1, 'GetExtensions: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (3, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.extensions = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
+ llsizer.Add(self.extensions, (3, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ #------- Description
+
+ t = wx.StaticText(self, -1, 'GetDescription: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (4, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.description = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY)
+ llsizer.Add(self.description, (4, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ #------- Open command
+
+ t = wx.StaticText(self, -1, 'GetOpenCommand: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (5, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.opencommand = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
+ llsizer.Add(self.opencommand, (5, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ #------- Print command
+
+ t = wx.StaticText(self, -1, 'GetPrintCommand: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (6, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.printcommand = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
+ llsizer.Add(self.printcommand, (6, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ #------- All commands
+
+ t = wx.StaticText(self, -1, 'GetAllCommands: ', style = wx.ALIGN_RIGHT )
+ t.SetFont(bfont)
+ llsizer.Add(t, (7, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
+
+ self.allcommands = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY | wx.TE_DONTWRAP | wx.TE_MULTILINE )
+
+ # Set the default height to be smaller than normal (for
+ # multi-line) so the sizer can then expand it to whatever
+ # space is available
+ self.allcommands.SetSize((-1, 20))
+
+ llsizer.Add(self.allcommands, (7, 1), (1, 3), wx.ALL | wx.GROW | wx.ALIGN_CENTER, 2)
+
+ # Tell the sizer to expand this row as needed
+ llsizer.AddGrowableRow(7)
+
+ #----------------------------------------------------------------------------
+
+ lrsizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, 'Known MIME types'), wx.HORIZONTAL)
+
+ #------- List box with known MIME types
+ self.mimelist = wx.ListBox(self, -1, choices=[], style = wx.LB_SINGLE | wx.LB_SORT)
+ lrsizer.Add(self.mimelist, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
+ self.Bind(wx.EVT_LISTBOX, self.OnListbox, self.mimelist)
+
+ #----------------------------------------------------------------------------
+
+ lsizer.Add(llsizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
+ lsizer.Add(lrsizer, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
+
+ #----------------------------------------------------------------------------
+
+ tsizer.Add(usizer, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
+ tsizer.Add(lsizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
+
+ #----------------------------------------------------------------------------
+
+ self.SetSizer(tsizer)
+ tsizer.Fit(self)
+
+ # Populate the Known MIME types list with what is in the database
+ mtypes = wx.TheMimeTypesManager.EnumAllFileTypes()
+ for mt in mtypes:
+ self.mimelist.Append(mt)
+
+ # Do a lookup of *.wav for a starting position
+ self.OnLookup()
+
+ # Grab the selection from the listbox, push that into
+ # the text box at top, select 'MIME', and then look it up.
+ def OnListbox(self, event):
+ mimetype = event.GetString()
+ self.ext.SetValue(mimetype)
+ self.how.SetSelection(1)
+ self.OnLookup()
+
+ # Look up a given file extension or MIME type.
+ def OnLookup(self, event=None):
+ txt = self.ext.GetValue()
+
+ # For MIME lookups
+ if self.how.GetSelection() == 1:
+ fileType = wx.TheMimeTypesManager.GetFileTypeFromMimeType(txt)
+ msg = "Mime type"
+
+ # Select the entered value in the list
+ if fileType:
+ if self.mimelist.FindString(txt) != -1:
+ self.mimelist.SetSelection(self.mimelist.FindString(txt))
+
+ # Must be an extension lookup
+ else:
+ fileType = wx.TheMimeTypesManager.GetFileTypeFromExtension(txt)
+ msg = "File extension"
+
+ # Select the entered value in the list
+ if fileType:
+ if self.mimelist.FindString(str(fileType.GetMimeType())) != -1:
+ # Using CallAfter to ensure that GUI is ready before trying to
+ # select it (otherwise, it's selected but not visible)
+ wx.CallAfter(self.mimelist.SetSelection, self.mimelist.FindString(str(fileType.GetMimeType())))
+
+
+ if fileType is None:
+ wx.MessageBox(msg + " not found.", "Oops!")
+ else:
+ self.Update(fileType)
+
+ # Populate the wx.FileType fields with actual values.
+ def Update(self, ft):
+
+ #------- Icon info
+ info = ft.GetIconInfo()
+
+ if info is None:
+ bmp = images.getNoIconBitmap()
+ self.icon.SetBitmap(bmp)
+ self.iconsource.SetValue("")
+ self.iconoffset.SetValue("")
+ else:
+ icon, file, idx = info
+ if icon.Ok():
+ self.icon.SetIcon(icon)
+ else:
+ bmp = images.getNoIconBitmap()
+ self.icon.SetBitmap(bmp)
+ self.iconsource.SetValue(file)
+ self.iconoffset.SetValue(str(idx))
+
+ #------- MIME type
+ self.mimetype.SetValue(str(ft.GetMimeType()))
+ #------- MIME types
+ self.mimetypes.SetValue(str(ft.GetMimeTypes()))
+ #------- Associated extensions
+ self.extensions.SetValue(str(ft.GetExtensions()))
+ #------- Description of file type
+ self.description.SetValue(str(ft.GetDescription()))
+
+ #------- Prep a fake command line command
+ extList = ft.GetExtensions()
+
+ if extList:
+ ext = extList[0]
+ if ext[0] == ".": ext = ext[1:]
+ else:
+ ext = ""
+
+ filename = "SPAM" + "." + ext
+ mime = ft.GetMimeType() or ""
+
+ #------- OPEN command
+ cmd = ft.GetOpenCommand(filename, mime)
+ self.opencommand.SetValue(str(cmd))
+
+ #------- PRINT command
+ cmd = ft.GetPrintCommand(filename, mime)
+ self.printcommand.SetValue(str(cmd))
+
+ #------- All commands
+ all = ft.GetAllCommands(filename, mime)
+
+ if all is None:
+ self.allcommands.SetValue("")
+ else:
+ verbs, commands = all
+ text = pprint.pformat(map(None, verbs, commands))
+ self.allcommands.SetValue(text)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = MimeTypesDemoPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+overview = """\
+
+The <b>wx.MimeTypesManager</b> class allows the application to retrieve the
+information about all known MIME types from a system-specific location and the
+filename extensions to the MIME types and vice versa. After initialization the
+methods <b>GetFileTypeFromMimeType()</b> and <b>GetFileTypeFromExtension()</b>
+may be called: they will return a <b>wx.FileType</b> object which may be further
+queried for file description, icon and other attributes.
+
+A global instance of <b>wx.MimeTypesManager</b> is always available as
+<b>wx.TheMimeTypesManager</b>. It is recommended to use this instance instead
+of creating your own because gathering MIME information may take quite a long
+on Unix systems.
+
+This demo shows how to use wx.TheMimeTypesManager to list all known MIME types
+and retrieve that information as a wx.FileType from either an extension or
+MIME type.
+
+For further information please consult the wxWindows documentation for
+<b>wx.MimeTypesManager</b> and <b>wx.FileType</b>.
+
+"""
+
+#----------------------------------------------------------------------
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+class MyMiniFrame(wx.MiniFrame):
+ def __init__(
+ self, parent, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
+ style=wx.DEFAULT_FRAME_STYLE
+ ):
+
+ wx.MiniFrame.__init__(self, parent, -1, title, pos, size, style)
+ panel = wx.Panel(self, -1)
+
+ button = wx.Button(panel, -1, "Close Me")
+ button.SetPosition((15, 15))
+ self.Bind(wx.EVT_BUTTON, self.OnCloseMe, button)
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+ def OnCloseMe(self, event):
+ self.Close(True)
+
+ def OnCloseWindow(self, event):
+ print "OnCloseWindow"
+ self.Destroy()
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = MyMiniFrame(frame, "This is a wxMiniFrame",
+ #pos=(250,250), size=(200,200),
+ style=wx.DEFAULT_FRAME_STYLE | wx.TINY_CAPTION_HORIZ)
+ win.SetSize((200, 200))
+ win.CenterOnParent(wx.BOTH)
+ frame.otherWin = win
+ win.Show(True)
+
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+A miniframe is a frame with a small title bar. It is suitable for floating
+toolbars that must not take up too much screen area. In other respects, it's the
+same as a wxFrame.
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wx renamer needs to be applied to multisash lib.
+# o There appears to be a problem with the image that
+# the library is trying to use for the alternate cursor
+#
+# 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o renamer issue shelved.
+#
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxMultiSash -> MultiSash
+#
+
+import wx
+import wx.lib.multisash as sash
+import wx.stc as stc
+
+#---------------------------------------------------------------------------
+
+sampleText="""\
+You can drag the little tab on the vertical sash left to create another view,
+or you can drag the tab on the horizontal sash to the top to create another
+horizontal view.
+
+The red blocks on the sashes will destroy the view (bottom,left) this block
+belongs to.
+
+A yellow rectangle also highlights the current selected view.
+
+By calling GetSaveData on the multiSash control the control will return its
+contents and the positions of each sash as a dictionary.
+Calling SetSaveData with such a dictionary will restore the control to the
+state it was in when it was saved.
+
+If the class, that is used as a view, has GetSaveData/SetSaveData implemented,
+these will also be called to save/restore their state. Any object can be
+returned by GetSaveData, as it is just another object in the dictionary.
+"""
+
+#---------------------------------------------------------------------------
+
+class TestWindow(stc.StyledTextCtrl):
+
+ # shared document reference
+ doc = None
+
+ def __init__(self, parent):
+ stc.StyledTextCtrl.__init__(self, parent, -1, style=wx.NO_BORDER)
+ self.SetMarginWidth(1,0)
+
+ if wx.Platform == '__WXMSW__':
+ fSize = 10
+ else:
+ fSize = 12
+
+ self.StyleSetFont(
+ stc.STC_STYLE_DEFAULT,
+ wx.Font(fSize, wx.MODERN, wx.NORMAL, wx.NORMAL)
+ )
+
+ if self.doc:
+ self.SetDocPointer(self.doc)
+ else:
+ self.SetText(sampleText)
+ TestWindow.doc = self.GetDocPointer()
+
+
+ def SutdownDemo(self):
+ # Reset doc reference in case this demo is run again
+ TestWindow.doc = None
+
+
+#---------------------------------------------------------------------------
+
+
+def runTest(frame, nb, log):
+ multi = sash.MultiSash(nb, -1, pos = (0,0), size = (640,480))
+
+ # Use this method to set the default class that will be created when
+ # a new sash is created. The class's constructor needs 1 parameter
+ # which is the parent of the window
+ multi.SetDefaultChildClass(TestWindow)
+
+ return multi
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>MultiSash</center></h2>
+
+MultiSash allows the user to split a window any number of times
+either horizontally or vertically, and to close the split off windows
+when desired.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wx renamer not applied to lib.
+#
+# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxMultipleChoiceDialog -> MultipleChoiceDialog
+#
+
+import wx
+import wx.lib.dialogs
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ lst = [ 'apple', 'pear', 'banana', 'coconut', 'orange',
+ 'etc', 'etc..', 'etc...' ]
+
+ dlg = wx.lib.dialogs.MultipleChoiceDialog(
+ frame,
+ "Pick some from\n this list\nblah blah...",
+ "m.s.d.", lst)
+
+ if (dlg.ShowModal() == wx.ID_OK):
+ print "Selection:", dlg.GetValue(), " -> ", dlg.GetValueString()
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+<html>
+<body>
+
+This is a Python implementation of a dialog that is not yet implemented in wxWindows
+proper, so don't let the wxWindows documentation mislead you.
+
+<p><code><b>MultipleChoiceDialog</b>(self, parent, msg, title, lst,
+pos = wx.wxDefaultPosition, size = (200,200), style = wx.wxDEFAULT_DIALOG_STYLE)
+</code>
+
+<dl>
+<dt><code>parent</code>
+<dd>The parent window
+
+<dt><code>msg</code>
+<dd>The message that will be displayed above the list
+
+<dt><code>title</code>
+<dd>The text that will appear on the title bar
+
+<dt><code>lst</code>
+<dd>A Python list of choices that will appear in the dialog.
+
+<dt><code>pos</code>
+<dd>The position of the dialog
+
+<dt><code>size</code>
+<dd>The size of the dialog
+
+<dt><code>style</code>
+<dd>The style for the dialog. Only styles normally available to wxDialog are
+available.
+
+</dl>
+
+<b><font size=+1><code>Methods</code></font></b>
+
+<dl>
+<dt><code>GetValue</code>
+<dd>Returns a tuple containing the indices of the selected items
+
+<dt><code>GetValueString</code>
+<dd>Returns a tuple containing the text of the selected items
+
+</dl>
+
+Additionally, MultipleChoiceDialog.lbox is a standard wx.ListBox which supports all
+methods applicable to that class.
+
+</body>
+</html>
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import sys
+
+import wx
+
+import ColorPanel
+import GridSimple
+import ListCtrl
+import ScrolledWindow
+import images
+
+#----------------------------------------------------------------------------
+
+class TestNB(wx.Notebook):
+ def __init__(self, parent, id, log):
+ wx.Notebook.__init__(self, parent, id, style=
+ #wxNB_TOP
+ wx.NB_BOTTOM
+ #wxNB_LEFT
+ #wxNB_RIGHT
+ )
+ self.log = log
+
+ win = self.makeColorPanel(wx.BLUE)
+ self.AddPage(win, "Blue")
+ st = wx.StaticText(win.win, -1,
+ "You can put nearly any type of window here,\n"
+ "and if the platform supports it then the\n"
+ "tabs can be on any side of the notebook.",
+ (10, 10))
+
+ st.SetForegroundColour(wx.WHITE)
+ st.SetBackgroundColour(wx.BLUE)
+
+ # Show how to put an image on one of the notebook tabs,
+ # first make the image list:
+ il = wx.ImageList(16, 16)
+ idx1 = il.Add(images.getSmilesBitmap())
+ self.AssignImageList(il)
+
+ # now put an image on the first tab we just created:
+ self.SetPageImage(0, idx1)
+
+
+ win = self.makeColorPanel(wx.RED)
+ self.AddPage(win, "Red")
+
+ win = ScrolledWindow.MyCanvas(self)
+ self.AddPage(win, 'ScrolledWindow')
+
+ win = self.makeColorPanel(wx.GREEN)
+ self.AddPage(win, "Green")
+
+ win = GridSimple.SimpleGrid(self, log)
+ self.AddPage(win, "Grid")
+
+ win = ListCtrl.TestListCtrlPanel(self, log)
+ self.AddPage(win, 'List')
+
+ win = self.makeColorPanel(wx.CYAN)
+ self.AddPage(win, "Cyan")
+
+# win = self.makeColorPanel(wxWHITE)
+# self.AddPage(win, "White")
+
+# win = self.makeColorPanel(wxBLACK)
+# self.AddPage(win, "Black")
+
+ win = self.makeColorPanel(wx.NamedColour('MIDNIGHT BLUE'))
+ self.AddPage(win, "MIDNIGHT BLUE")
+
+ win = self.makeColorPanel(wx.NamedColour('INDIAN RED'))
+ self.AddPage(win, "INDIAN RED")
+
+ self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
+ self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
+
+
+ def makeColorPanel(self, color):
+ p = wx.Panel(self, -1)
+ win = ColorPanel.ColoredPanel(p, color)
+ p.win = win
+
+ def OnCPSize(evt, win=win):
+ win.SetSize(evt.GetSize())
+
+ p.Bind(wx.EVT_SIZE, OnCPSize)
+ return p
+
+ def OnPageChanged(self, event):
+ old = event.GetOldSelection()
+ new = event.GetSelection()
+ sel = self.GetSelection()
+ self.log.write('OnPageChanged, old:%d, new:%d, sel:%d\n' % (old, new, sel))
+ event.Skip()
+
+ def OnPageChanging(self, event):
+ old = event.GetOldSelection()
+ new = event.GetSelection()
+ sel = self.GetSelection()
+ self.log.write('OnPageChanging, old:%d, new:%d, sel:%d\n' % (old, new, sel))
+ event.Skip()
+
+#----------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ testWin = TestNB(nb, -1, log)
+ return testWin
+
+#----------------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+<h2>wxNotebook</h2>
+<p>
+This class represents a notebook control, which manages multiple
+windows with associated tabs.
+<p>
+To use the class, create a wxNotebook object and call AddPage or
+InsertPage, passing a window to be used as the page. Do not explicitly
+delete the window for a page that is currently managed by wxNotebook.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+
+
+
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o OGL's busted bigtime. Can't even use OGLInitialize() without a
+# program error on w2k.
+#
+
+import wx
+import wx.ogl as ogl
+
+import images
+
+##wx.Trap()
+
+#----------------------------------------------------------------------
+# This creates some pens and brushes that the OGL library uses.
+
+ogl.OGLInitialize()
+
+#----------------------------------------------------------------------
+
+class DiamondShape(ogl.PolygonShape):
+ def __init__(self, w=0.0, h=0.0):
+ ogl.PolygonShape.__init__(self)
+ if w == 0.0:
+ w = 60.0
+ if h == 0.0:
+ h = 60.0
+
+ # Either ogl.RealPoints or 2-tuples of floats works.
+
+ #points = [ ogl.RealPoint(0.0, -h/2.0),
+ # ogl.RealPoint(w/2.0, 0.0),
+ # ogl.RealPoint(0.0, h/2.0),
+ # ogl.RealPoint(-w/2.0, 0.0),
+ # ]
+ points = [ (0.0, -h/2.0),
+ (w/2.0, 0.0),
+ (0.0, h/2.0),
+ (-w/2.0, 0.0),
+ ]
+
+ self.Create(points)
+
+
+#----------------------------------------------------------------------
+
+class RoundedRectangleShape(ogl.RectangleShape):
+ def __init__(self, w=0.0, h=0.0):
+ ogl.RectangleShape.__init__(self, w, h)
+ self.SetCornerRadius(-0.3)
+
+
+#----------------------------------------------------------------------
+
+class DividedShape(ogl.DividedShape):
+ def __init__(self, width, height, canvas):
+ ogl.DividedShape.__init__(self, width, height)
+
+ region1 = ogl.ShapeRegion()
+ region1.SetText('DividedShape')
+ region1.SetProportions(0.0, 0.2)
+ region1.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ)
+ self.AddRegion(region1)
+
+ region2 = ogl.ShapeRegion()
+ region2.SetText('This is Region number two.')
+ region2.SetProportions(0.0, 0.3)
+ region2.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ|ogl.FORMAT_CENTRE_VERT)
+ self.AddRegion(region2)
+
+ region3 = ogl.ShapeRegion()
+ region3.SetText('Region 3\nwith embedded\nline breaks')
+ region3.SetProportions(0.0, 0.5)
+ region3.SetFormatMode(ogl.FORMAT_NONE)
+ self.AddRegion(region3)
+
+ self.SetRegionSizes()
+ self.ReformatRegions(canvas)
+
+
+ def ReformatRegions(self, canvas=None):
+ rnum = 0
+
+ if canvas is None:
+ canvas = self.GetCanvas()
+
+ dc = wx.ClientDC(canvas) # used for measuring
+
+ for region in self.GetRegions():
+ text = region.GetText()
+ self.FormatText(dc, text, rnum)
+ rnum += 1
+
+
+ def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
+ print "***", self
+ self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
+ self.SetRegionSizes()
+ self.ReformatRegions()
+ self.GetCanvas().Refresh()
+
+
+#----------------------------------------------------------------------
+
+class MyEvtHandler(ogl.ShapeEvtHandler):
+ def __init__(self, log, frame):
+ ogl.ShapeEvtHandler.__init__(self)
+ self.log = log
+ self.statbarFrame = frame
+
+ def UpdateStatusBar(self, shape):
+ x,y = shape.GetX(), shape.GetY()
+ width, height = shape.GetBoundingBoxMax()
+ self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" %
+ (x, y, width, height))
+
+
+ def OnLeftClick(self, x, y, keys = 0, attachment = 0):
+ shape = self.GetShape()
+ print shape.__class__, shape.GetClassName()
+ canvas = shape.GetCanvas()
+ dc = wx.ClientDC(canvas)
+ canvas.PrepareDC(dc)
+
+ if shape.Selected():
+ shape.Select(False, dc)
+ canvas.Redraw(dc)
+ else:
+ redraw = False
+ shapeList = canvas.GetDiagram().GetShapeList()
+ toUnselect = []
+
+ for s in shapeList:
+ if s.Selected():
+ # If we unselect it now then some of the objects in
+ # shapeList will become invalid (the control points are
+ # shapes too!) and bad things will happen...
+ toUnselect.append(s)
+
+ shape.Select(True, dc)
+
+ if toUnselect:
+ for s in toUnselect:
+ s.Select(False, dc)
+
+ canvas.Redraw(dc)
+
+ self.UpdateStatusBar(shape)
+
+
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
+ shape = self.GetShape()
+ self.base_OnEndDragLeft(x, y, keys, attachment)
+
+ if not shape.Selected():
+ self.OnLeftClick(x, y, keys, attachment)
+
+ self.UpdateStatusBar(shape)
+
+
+ def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
+ self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
+ self.UpdateStatusBar(self.GetShape())
+
+
+ def OnMovePost(self, dc, x, y, oldX, oldY, display):
+ self.base_OnMovePost(dc, x, y, oldX, oldY, display)
+ self.UpdateStatusBar(self.GetShape())
+
+
+ def OnRightClick(self, *dontcare):
+ self.log.WriteText("%s\n" % self.GetShape())
+
+
+#----------------------------------------------------------------------
+
+class TestWindow(ogl.ShapeCanvas):
+ def __init__(self, parent, log, frame):
+ ogl.ShapeCanvas.__init__(self, parent)
+
+ maxWidth = 1000
+ maxHeight = 1000
+ self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
+
+ self.log = log
+ self.frame = frame
+ self.SetBackgroundColour("LIGHT BLUE") #wx.WHITE)
+ self.diagram = ogl.Diagram()
+ self.SetDiagram(self.diagram)
+ self.diagram.SetCanvas(self)
+ self.shapes = []
+ self.save_gdi = []
+
+ rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID)
+ dsBrush = wx.Brush("WHEAT", wx.SOLID)
+
+ self.MyAddShape(
+ ogl.CircleShape(80),
+ 100, 100, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle"
+ )
+
+ self.MyAddShape(
+ ogl.RectangleShape(85, 50),
+ 305, 60, wx.BLACK_PEN, wx.LIGHT_GREY_BRUSH, "Rectangle"
+ )
+
+ ds = self.MyAddShape(
+ DividedShape(140, 150, self),
+ 495, 145, wx.BLACK_PEN, dsBrush, ''
+ )
+
+ self.MyAddShape(
+ DiamondShape(90, 90),
+ 345, 235, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon"
+ )
+
+ self.MyAddShape(
+ RoundedRectangleShape(95,70),
+ 140, 255, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect"
+ )
+
+ bmp = images.getTest2Bitmap()
+ mask = wx.MaskColour(bmp, wx.BLUE)
+ bmp.SetMask(mask)
+
+ s = ogl.BitmapShape()
+ s.SetBitmap(bmp)
+ self.MyAddShape(s, 225, 150, None, None, "Bitmap")
+
+ dc = wx.ClientDC(self)
+ self.PrepareDC(dc)
+
+ for x in range(len(self.shapes)):
+ fromShape = self.shapes[x]
+ if x+1 == len(self.shapes):
+ toShape = self.shapes[0]
+ else:
+ toShape = self.shapes[x+1]
+
+ line = ogl.LineShape()
+ line.SetCanvas(self)
+ line.SetPen(wx.BLACK_PEN)
+ line.SetBrush(wx.BLACK_BRUSH)
+ line.AddArrow(ogl.ARROW_ARROW)
+ line.MakeLineControlPoints(2)
+ fromShape.AddLine(line, toShape)
+ self.diagram.AddShape(line)
+ line.Show(True)
+
+ # for some reason, the shapes have to be moved for the line to show up...
+ fromShape.Move(dc, fromShape.GetX(), fromShape.GetY())
+
+ wx.EVT_WINDOW_DESTROY(self, self.OnDestroy)
+
+
+ def MyAddShape(self, shape, x, y, pen, brush, text):
+ shape.SetDraggable(True, True)
+ shape.SetCanvas(self)
+ shape.SetX(x)
+ shape.SetY(y)
+ if pen: shape.SetPen(pen)
+ if brush: shape.SetBrush(brush)
+ if text: shape.AddText(text)
+ #shape.SetShadowMode(ogl.SHADOW_RIGHT)
+ self.diagram.AddShape(shape)
+ shape.Show(True)
+
+ evthandler = MyEvtHandler(self.log, self.frame)
+ evthandler.SetShape(shape)
+ evthandler.SetPreviousHandler(shape.GetEventHandler())
+ shape.SetEventHandler(evthandler)
+
+ self.shapes.append(shape)
+ return shape
+
+
+ def OnDestroy(self, evt):
+ # Do some cleanup
+ for shape in self.diagram.GetShapeList():
+ if shape.GetParent() == None:
+ shape.SetCanvas(None)
+ shape.Destroy()
+
+ self.diagram.Destroy()
+
+
+ def OnBeginDragLeft(self, x, y, keys):
+ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
+
+ def OnEndDragLeft(self, x, y, keys):
+ self.log.write("OnEndDragLeft: %s, %s, %s\n" % (x, y, keys))
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ # This creates some pens and brushes that the OGL library uses.
+ # It should be called after the app object has been created, but
+ # before OGL is used.
+ ogl.OGLInitialize()
+
+ win = TestWindow(nb, log, frame)
+ return win
+
+#----------------------------------------------------------------------
+
+class __Cleanup:
+ cleanup = ogl.OGLCleanUp
+ def __del__(self):
+ self.cleanup()
+
+# when this module gets cleaned up then wxOGLCleanUp() will get called
+__cu = __Cleanup()
+
+
+overview = """\
+The Object Graphics Library is a library supporting the creation and
+manipulation of simple and complex graphic images on a canvas.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ data = wx.PageSetupDialogData()
+ data.SetMarginTopLeft( (15, 15) )
+ data.SetMarginBottomRight( (15, 15) )
+ #data.SetDefaultMinMargins(True)
+ data.SetPaperId(wx.PAPER_LETTER)
+
+ dlg = wx.PageSetupDialog(frame, data)
+
+ if dlg.ShowModal() == wx.ID_OK:
+ data = dlg.GetPageSetupData()
+ tl = data.GetMarginTopLeft()
+ br = data.GetMarginBottomRight()
+ log.WriteText('Margins are: %s %s\n' % (str(tl), str(br)))
+
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class represents the page setup common dialog. The page setup dialog is standard
+from Windows 95 on, replacing the print setup dialog (which is retained in Windows
+and wxWindows for backward compatibility). On Windows 95 and NT 4.0 and above,
+the page setup dialog is native to the windowing system, otherwise it is emulated.
+
+The page setup dialog contains controls for paper size (A4, A5 etc.), orientation
+(landscape or portrait), and controls for setting left, top, right and bottom margin
+sizes in millimetres.
+
+When the dialog has been closed, you need to query the <code>wxPageSetupDialogData</code> object
+associated with the dialog.
+
+Note that the OK and Cancel buttons do not destroy the dialog; this must be done by
+the application. As with other dialogs, do not destroy the dialog until you are done
+with the data, and, conversely, do not use the wxPageSetupDialogData after the
+dialog is destroyed.
+
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxPlotCanvas must be updated with new draw mechanics (tuples) before
+# it can be used with 2.5.
+#
+
+import wx
+import wx.lib.wxPlotCanvas as plot
+
+import Numeric
+
+#---------------------------------------------------------------------------
+
+def _InitObjects():
+ # 100 points sin function, plotted as green circles
+ data1 = 2.*Numeric.pi*Numeric.arange(200)/200.
+ data1.shape = (100, 2)
+ data1[:,1] = Numeric.sin(data1[:,0])
+ markers1 = plot.PolyMarker(data1, color='green', marker='circle',size=1)
+
+ # 50 points cos function, plotted as red line
+ data1 = 2.*Numeric.pi*Numeric.arange(100)/100.
+ data1.shape = (50,2)
+ data1[:,1] = Numeric.cos(data1[:,0])
+ lines = plot.PolyLine(data1, color='red')
+
+ # A few more points...
+ pi = Numeric.pi
+ markers2 = plot.PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.),
+ (3.*pi/4., -1)], color='blue',
+ fillcolor='green', marker='cross')
+
+ return plot.PlotGraphics([markers1, lines, markers2])
+
+
+#---------------------------------------------------------------------------
+
+
+def runTest(frame, nb, log):
+ win = plot.PlotCanvas(nb)
+ win.draw(_InitObjects(),'automatic','automatic');
+ return win
+
+overview = plot.__doc__
+
+#---------------------------------------------------------------------------
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Is it just me or are the graphics for the control not lining up right?
+#
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxPopupControl -> PopupControl
+#
+
+import wx
+import wx.lib.popupctl as pop
+import wx.calendar as cal
+
+class TestDateControl(pop.PopupControl):
+ def __init__(self,*_args,**_kwargs):
+ apply(pop.PopupControl.__init__,(self,) + _args,_kwargs)
+
+ self.win = wx.Window(self,-1,pos = (0,0),style = 0)
+ self.cal = cal.CalendarCtrl(self.win,-1,pos = (0,0))
+
+ bz = self.cal.GetBestSize()
+ self.win.SetSize(bz)
+
+ # This method is needed to set the contents that will be displayed
+ # in the popup
+ self.SetPopupContent(self.win)
+
+ # Event registration for date selection
+ self.cal.Bind(cal.EVT_CALENDAR_DAY, self.OnCalSelected)
+
+ # Method called when a day is selected in the calendar
+ def OnCalSelected(self,evt):
+ self.PopDown()
+ date = self.cal.GetDate()
+
+ # Format the date that was selected for the text part of the control
+ self.SetValue('%02d/%02d/%04d' % (date.GetDay(),
+ date.GetMonth()+1,
+ date.GetYear()))
+ evt.Skip()
+
+ # Method overridden from PopupControl
+ # This method is called just before the popup is displayed
+ # Use this method to format any controls in the popup
+ def FormatContent(self):
+ # I parse the value in the text part to resemble the correct date in
+ # the calendar control
+ txtValue = self.GetValue()
+ dmy = txtValue.split('/')
+ didSet = False
+
+ if len(dmy) == 3:
+ date = self.cal.GetDate()
+ d = int(dmy[0])
+ m = int(dmy[1]) - 1
+ y = int(dmy[2])
+
+ if d > 0 and d < 31:
+ if m >= 0 and m < 12:
+ if y > 1000:
+ self.cal.SetDate(wx.DateTimeFromDMY(d,m,y))
+ didSet = True
+
+ if not didSet:
+ self.cal.SetDate(wx.DateTime_Today())
+
+
+#---------------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+ date = TestDateControl(self, -1, pos = (30,30), size = (100,22))
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+overview = """<html><body>
+<h2><center>PopupControl</center></h2>
+
+PopupControl is a class that can display a value and has a button
+that will popup another window similar to how a wxComboBox works. The
+popup window can contain whatever is needed to edit the value. This
+example uses a wxCalendarCtrl.
+
+<p>Currently a wxDialog is used for the popup. Eventually a
+wxPopupWindow should be used...
+
+</body></html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Some issues with the listbox example; I tried correcting
+# it but it's still not working the way it should. Commented
+# out for now but will be revisited.
+# o The math in determining the popup window's position is
+# a bit off.
+#
+
+import wx
+
+havePopupWindow = 1
+try:
+ wx.PopupWindow
+except NameError:
+ havePopupWindow = 0
+ wx.PopupWindow = wx.PopupTransientWindow = wx.Window
+
+#---------------------------------------------------------------------------
+
+class TestPopup(wx.PopupWindow):
+ """Adds a bit of text and mouse movement to the wxPopupWindow"""
+ def __init__(self, parent, style):
+ wx.PopupWindow.__init__(self, parent, style)
+ self.SetBackgroundColour("CADET BLUE")
+
+ st = wx.StaticText(self, -1,
+ "This is a special kind of top level\n"
+ "window that can be used for\n"
+ "popup menus, combobox popups\n"
+ "and such.\n\n"
+ "Try positioning the demo near\n"
+ "the bottom of the screen and \n"
+ "hit the button again.\n\n"
+ "In this demo this window can\n"
+ "be dragged with the left button\n"
+ "and closed with the right."
+ ,
+ pos=(10,10))
+
+ sz = st.GetBestSize()
+ self.SetSize( (sz.width+20, sz.height+20) )
+
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
+ self.Bind(wx.EVT_MOTION, self.OnMouseMotion)
+ self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
+ self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
+
+ st.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
+ st.Bind(wx.EVT_MOTION, self.OnMouseMotion)
+ st.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
+ st.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
+
+ def OnMouseLeftDown(self, evt):
+ self.ldPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
+ self.wPos = self.ClientToScreen((0,0))
+ self.CaptureMouse()
+
+ def OnMouseMotion(self, evt):
+ if evt.Dragging() and evt.LeftIsDown():
+ dPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
+ nPos = (self.wPos.x + (dPos.x - self.ldPos.x),
+ self.wPos.y + (dPos.y - self.ldPos.y))
+ self.Move(nPos)
+
+ def OnMouseLeftUp(self, evt):
+ self.ReleaseMouse()
+
+ def OnRightUp(self, evt):
+ self.Show(False)
+ self.Destroy()
+
+
+class TestTransientPopup(wx.PopupTransientWindow):
+ """Adds a bit of text and mouse movement to the wxPopupWindow"""
+ def __init__(self, parent, style, log):
+ wx.PopupTransientWindow.__init__(self, parent, style)
+ self.log = log
+ panel = wx.Panel(self, -1)
+ panel.SetBackgroundColour("#FFB6C1")
+ st = wx.StaticText(panel, -1,
+ "wxPopupTransientWindow is a\n"
+ "wxPopupWindow which disappears\n"
+ "automatically when the user\n"
+ "clicks the mouse outside it or if it\n"
+ "(or its first child) loses focus in \n"
+ "any other way."
+ ,
+ pos=(10,10))
+ sz = st.GetBestSize()
+ panel.SetSize( (sz.width+20, sz.height+20) )
+ self.SetSize(panel.GetSize())
+
+ def ProcessLeftDown(self, evt):
+ self.log.write("ProcessLeftDown\n")
+ return False
+
+ def OnDismiss(self):
+ self.log.write("OnDismiss\n")
+
+
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ b = wx.Button(self, -1, "Show wxPopupWindow", (25, 50))
+ self.Bind(wx.EVT_BUTTON, self.OnShowPopup, b)
+
+ b = wx.Button(self, -1, "Show wxPopupTransientWindow", (25, 95))
+ self.Bind(wx.EVT_BUTTON, self.OnShowPopupTransient, b)
+
+ # This isn't working so well, not sure why. Commented out for
+ # now.
+
+# b = wx.Button(self, -1, "Show wxPopupWindow with listbox", (25, 140))
+# self.Bind(wx.EVT_BUTTON, self.OnShowPopupListbox, b)
+
+
+ def OnShowPopup(self, evt):
+ win = TestPopup(self, wx.SIMPLE_BORDER)
+
+ # Show the popup right below or above the button
+ # depending on available screen space...
+ btn = evt.GetEventObject()
+ pos = btn.ClientToScreen( (0,0) )
+ sz = btn.GetSize()
+ win.Position(pos, (0, sz[1]))
+
+ win.Show(True)
+
+
+ def OnShowPopupTransient(self, evt):
+ win = TestTransientPopup(self, wx.SIMPLE_BORDER, self.log)
+
+ # Show the popup right below or above the button
+ # depending on available screen space...
+ btn = evt.GetEventObject()
+ pos = btn.ClientToScreen( (0,0) )
+ sz = btn.GetSize()
+ win.Position(pos, (0, sz[1]))
+
+ win.Popup()
+
+
+ def OnShowPopupListbox(self, evt):
+ win = TestPopupWithListbox(self, wx.NO_BORDER, self.log)
+
+ # Show the popup right below or above the button
+ # depending on available screen space...
+ btn = evt.GetEventObject()
+ pos = btn.ClientToScreen( (0,0) )
+ sz = btn.GetSize()
+ win.Position(pos, (0, sz[1]))
+
+ win.Show(True)
+
+class TestPopupWithListbox(wx.PopupWindow):
+ def __init__(self, parent, style, log):
+ wx.PopupWindow.__init__(self, parent, style)
+
+ import keyword
+
+ self.lb = wx.ListBox(self, -1, choices = keyword.kwlist)
+ #sz = self.lb.GetBestSize()
+ self.SetSize((150, 75)) #sz)
+ self.lb.SetSize(self.GetClientSize())
+ self.lb.SetFocus()
+ self.Bind(wx.EVT_LISTBOX, self.OnListBox)
+ self.lb.Bind(wx.EVT_LEFT_DOWN, self.OnLeft)
+
+ def OnLeft(self, evt):
+ obj = evt.GetEventObject()
+ print "OnLeft", obj
+ print 'Selected: %s' % obj.GetStringSelection()
+ obj.Show(False)
+ evt.Skip()
+
+ def OnListBox(self, evt):
+ obj = evt.GetEventObject()
+ print "OnListBox", obj
+ print 'Selected: %s' % obj.GetString()
+ evt.Skip()
+
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ if havePopupWindow:
+ win = TestPanel(nb, log)
+ return win
+ else:
+ dlg = wx.MessageDialog(
+ frame, 'wxPopupWindow is not available on this platform.',
+ 'Sorry', wx.OK | wx.ICON_INFORMATION
+ )
+
+ dlg.ShowModal()
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ data = wx.PrintDialogData()
+
+ data.EnableSelection(True)
+ data.EnablePrintToFile(True)
+ data.EnablePageNumbers(True)
+ data.SetMinPage(1)
+ data.SetMaxPage(5)
+ data.SetAllPages(True)
+
+ dlg = wx.PrintDialog(frame, data)
+
+ if dlg.ShowModal() == wx.ID_OK:
+ data = dlg.GetPrintDialogData()
+ log.WriteText('GetAllPages: %d\n' % data.GetAllPages())
+
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class represents the print and print setup common dialogs. You may obtain
+a wxPrinterDC device context from a successfully dismissed print dialog.
+
+User information is stored in a wxPrintDialogData object that is passed to the
+dialog at creation time, and it is filled in by the user. As with other dialogs,
+do not use this data once the dialog is dismissed, and do not destroy the dialog
+until you have everything you need from it.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
#
import wx
-import wxScrolledWindow
+import ScrolledWindow
#----------------------------------------------------------------------
self.printData.SetPaperId(wx.PAPER_LETTER)
self.box = wx.BoxSizer(wx.VERTICAL)
- self.canvas = wxScrolledWindow.MyCanvas(self)
+ self.canvas = ScrolledWindow.MyCanvas(self)
self.box.Add(self.canvas, 1, wx.GROW)
subbox = wx.BoxSizer(wx.HORIZONTAL)
--- /dev/null
+# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, ID, log):
+ wx.Panel.__init__(self, parent, ID)
+ self.log = log
+
+ self.process = None
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
+
+ # We can either derive from wxProcess and override OnTerminate
+ # or we can let wxProcess send this window an event that is
+ # caught in the normal way...
+ self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
+
+
+ # Make the controls
+ prompt = wx.StaticText(self, -1, 'Command line:')
+ self.cmd = wx.TextCtrl(self, -1, 'python -u data/echo.py')
+ self.exBtn = wx.Button(self, -1, 'Execute')
+
+ self.out = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE|wx.TE_READONLY)
+
+ self.inp = wx.TextCtrl(self, -1, '', style=wx.TE_PROCESS_ENTER)
+ self.sndBtn = wx.Button(self, -1, 'Send')
+ self.termBtn = wx.Button(self, -1, 'Close Stream')
+ self.inp.Enable(False)
+ self.sndBtn.Enable(False)
+ self.termBtn.Enable(False)
+
+ # Hook up the events
+ self.Bind(wx.EVT_BUTTON, self.OnExecuteBtn, self.exBtn)
+ self.Bind(wx.EVT_BUTTON, self.OnSendText, self.sndBtn)
+ self.Bind(wx.EVT_BUTTON, self.OnCloseStream, self.termBtn)
+ self.Bind(wx.EVT_TEXT_ENTER, self.OnSendText, self.inp)
+
+
+ # Do the layout
+ box1 = wx.BoxSizer(wx.HORIZONTAL)
+ box1.Add(prompt, 0, wx.ALIGN_CENTER)
+ box1.Add(self.cmd, 1, wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
+ box1.Add(self.exBtn, 0)
+
+ box2 = wx.BoxSizer(wx.HORIZONTAL)
+ box2.Add(self.inp, 1, wx.ALIGN_CENTER)
+ box2.Add(self.sndBtn, 0, wx.LEFT, 5)
+ box2.Add(self.termBtn, 0, wx.LEFT, 5)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(box1, 0, wx.EXPAND|wx.ALL, 10)
+ sizer.Add(self.out, 1, wx.EXPAND|wx.ALL, 10)
+ sizer.Add(box2, 0, wx.EXPAND|wx.ALL, 10)
+
+ self.SetSizer(sizer)
+ self.SetAutoLayout(True)
+
+
+ def __del__(self):
+ if self.process is not None:
+ self.process.Detach()
+ self.process.CloseOutput()
+ self.process = None
+
+
+ def OnExecuteBtn(self, evt):
+ cmd = self.cmd.GetValue()
+
+ self.process = wx.Process(self)
+ self.process.Redirect();
+ pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process)
+ self.log.write('OnExecuteBtn: "%s" pid: %s\n' % (cmd, pid))
+
+ self.inp.Enable(True)
+ self.sndBtn.Enable(True)
+ self.termBtn.Enable(True)
+ self.cmd.Enable(False)
+ self.exBtn.Enable(False)
+ self.inp.SetFocus()
+
+
+ def OnSendText(self, evt):
+ text = self.inp.GetValue()
+ self.inp.SetValue('')
+ self.log.write('OnSendText: "%s"\n' % text)
+ self.process.GetOutputStream().write(text + '\n')
+ self.inp.SetFocus()
+
+
+ def OnCloseStream(self, evt):
+ self.log.write('OnCloseStream\n')
+ #print "b4 CloseOutput"
+ self.process.CloseOutput()
+ #print "after CloseOutput"
+
+ def OnIdle(self, evt):
+ if self.process is not None:
+ stream = self.process.GetInputStream()
+
+ if stream.CanRead():
+ text = stream.read()
+ self.out.AppendText(text)
+
+
+ def OnProcessEnded(self, evt):
+ self.log.write('OnProcessEnded, pid:%s, exitCode: %s\n' %
+ (evt.GetPid(), evt.GetExitCode()))
+
+ stream = self.process.GetInputStream()
+
+ if stream.CanRead():
+ text = stream.read()
+ self.out.AppendText(text)
+
+ self.process.Destroy()
+ self.process = None
+ self.inp.Enable(False)
+ self.sndBtn.Enable(False)
+ self.termBtn.Enable(False)
+ self.cmd.Enable(True)
+ self.exBtn.Enable(True)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, -1, log)
+ return win
+
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+<h2>wxProcess</h2>
+
+wxProcess lets you get notified when an asyncronous child process
+started by wxExecute terminates, and also to get input/output streams
+for the child process's stdout, stderr and stdin.
+
+<p>
+This demo launches a simple python script that echos back on stdout
+lines that it reads from stdin. You can send text to the echo
+process' stdin by typing in the lower textctrl and clicking Send.
+
+<p>
+Clicking the Close Stream button will close the demo's end of the
+stdin pipe to the child process. In our case that will cause the
+child process to exit its main loop.
+
+</body><html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wx.ProgressDialog appears to be broken. No abort button
+# and it's not possible to dismiss it otherwise.
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ max = 20
+
+ dlg = wx.ProgressDialog("Progress dialog example",
+ "An informative message",
+ maximum = max,
+ parent=frame,
+ style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL)
+
+ keepGoing = True
+ count = 0
+
+ while keepGoing and count < max:
+ count = count + 1
+ #print count
+ wx.Sleep(1)
+
+ if count == max / 2:
+ keepGoing = dlg.Update(count, "Half-time!")
+ else:
+ keepGoing = dlg.Update(count)
+
+ dlg.Destroy()
+
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class represents a dialog that shows a short message and a progress bar.
+Optionally, it can display an ABORT button
+
+This dialog indicates the progress of some event that takes a while to accomplish,
+usually, such as file copy progress, download progress, and so on. The display
+is <b>completely</b> under control of the program; you must update the dialog from
+within the program creating it.
+
+When the dialog closes, you must check to see if the user aborted the process or
+not, and act accordingly -- that is, if the PD_CAN_ABORT style flag is set.
+If not then you may progress blissfully onward.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated URL for SF link in overview.
+#
+# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxPyColorChooser -> PyColorChooser
+# o wxPyColourChooser -> PyColourChooser
+#
+
+import wx
+import wx.lib.colourchooser as cc
+
+#---------------------------------------------------------------
+
+class TestColourChooser(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ chooser = cc.PyColourChooser(self, -1)
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(chooser, 0, wx.ALL, 25)
+
+ self.SetAutoLayout(True)
+ self.SetSizer(sizer)
+
+#---------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestColourChooser(nb, log)
+ return win
+
+#---------------------------------------------------------------
+
+overview = """
+The PyColourChooser component creates a colour chooser window
+that is similar to the Microsoft Windows colour chooser dialog.
+This dialog component is drawn in a panel, and thus can be
+embedded inside any widget (although it cannot be resized).
+This colour chooser may also be substituted for the colour
+chooser on any platform that might have an ugly one :)
+
+How to use it
+------------------------------
+
+The demo (demo/PyColourChooser.py code shows how to display
+a colour chooser and retrieve its options.
+
+Contact and Author Info
+------------------------------
+
+PyColourChooser was written and is maintained by:
+
+ Michael Gilfix <mgilfix@eecs.tufts.edu>
+
+You can find the latest PyColourChooser code at
+http://sourceforge.net/projects/wxcolourchooser/. If you have
+any suggestions or want to submit a patch, please send
+it my way at: mgilfix@eecs.tufts.edu
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestRadioBox(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+ #self.SetBackgroundColour(wx.BLUE)
+
+ sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
+ 'six', 'seven', 'eight']
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ rb = wx.RadioBox(
+ self, -1, "wx.RadioBox", wx.DefaultPosition, wx.DefaultSize,
+ sampleList, 2, wx.RA_SPECIFY_COLS
+ )
+
+ self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, rb)
+ #rb.SetBackgroundColour(wx.BLUE)
+ rb.SetToolTip(wx.ToolTip("This is a ToolTip!"))
+ #rb.SetLabel("wxRadioBox")
+
+ sizer.Add(rb, 0, wx.ALL, 20)
+
+ rb = wx.RadioBox(
+ self, -1, "", wx.DefaultPosition, wx.DefaultSize,
+ sampleList, 3, wx.RA_SPECIFY_COLS | wx.NO_BORDER
+ )
+
+ self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, rb)
+ rb.SetToolTip(wx.ToolTip("This box has no label"))
+
+ sizer.Add(rb, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM, 20)
+
+ self.SetSizer(sizer)
+
+
+ def EvtRadioBox(self, event):
+ self.log.WriteText('EvtRadioBox: %d\n' % event.GetInt())
+
+# Doesn't appear to be used for anything.
+# def EvtRadioButton(self, event):
+# self.log.write('EvtRadioButton:%d\n' % event.GetId())
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestRadioBox(nb, log)
+ return win
+
+
+
+overview = """\
+A radio box item is used to select one of number of mutually exclusive
+choices. It is displayed as a vertical column or horizontal row of
+labelled buttons.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel( wx.Panel ):
+ def __init__( self, parent, log ):
+
+ wx.Panel.__init__( self, parent, -1 )
+ self.log = log
+ panel = wx.Panel( self, -1 )
+
+ # 1st group of controls:
+ self.group1_ctrls = []
+ radio1 = wx.RadioButton( panel, -1, " Radio1 ", style = wx.RB_GROUP )
+ text1 = wx.TextCtrl( panel, -1, "" )
+ radio2 = wx.RadioButton( panel, -1, " Radio2 " )
+ text2 = wx.TextCtrl( panel, -1, "" )
+ radio3 = wx.RadioButton( panel, -1, " Radio3 " )
+ text3 = wx.TextCtrl( panel, -1, "" )
+ self.group1_ctrls.append((radio1, text1))
+ self.group1_ctrls.append((radio2, text2))
+ self.group1_ctrls.append((radio3, text3))
+
+ # 2nd group of controls:
+ self.group2_ctrls = []
+ radio4 = wx.RadioButton( panel, -1, " Radio1 ", style = wx.RB_GROUP )
+ text4 = wx.TextCtrl( panel, -1, "" )
+ radio5 = wx.RadioButton( panel, -1, " Radio2 " )
+ text5 = wx.TextCtrl( panel, -1, "" )
+ radio6 = wx.RadioButton( panel, -1, " Radio3 " )
+ text6 = wx.TextCtrl( panel, -1, "" )
+ self.group2_ctrls.append((radio4, text4))
+ self.group2_ctrls.append((radio5, text5))
+ self.group2_ctrls.append((radio6, text6))
+
+ # Layout controls on panel:
+ vs = wx.BoxSizer( wx.VERTICAL )
+
+ box1_title = wx.StaticBox( panel, -1, "Group 1" )
+ box1 = wx.StaticBoxSizer( box1_title, wx.VERTICAL )
+ grid1 = wx.FlexGridSizer( 0, 2, 0, 0 )
+
+ for radio, text in self.group1_ctrls:
+ grid1.AddWindow( radio, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
+ grid1.AddWindow( text, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
+
+ box1.AddSizer( grid1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+ vs.AddSizer( box1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+
+ box2_title = wx.StaticBox( panel, -1, "Group 2" )
+ box2 = wx.StaticBoxSizer( box2_title, wx.VERTICAL )
+ grid2 = wx.FlexGridSizer( 0, 2, 0, 0 )
+
+ for radio, text in self.group2_ctrls:
+ grid2.AddWindow( radio, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
+ grid2.AddWindow( text, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
+
+ box2.AddSizer( grid2, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+ vs.AddSizer( box2, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+
+ panel.SetSizer( vs )
+ vs.Fit( panel )
+ panel.Move( (50,50) )
+ self.panel = panel
+
+ # Setup event handling and initial state for controls:
+ for radio, text in self.group1_ctrls:
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnGroup1Select, radio )
+
+ for radio, text in self.group2_ctrls:
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnGroup2Select, radio )
+
+ for radio, text in self.group1_ctrls + self.group2_ctrls:
+ radio.SetValue(0)
+ text.Enable(False)
+
+ def OnGroup1Select( self, event ):
+ radio_selected = event.GetEventObject()
+ self.log.write('Group1 %s selected\n' % radio_selected.GetLabel() )
+
+ for radio, text in self.group1_ctrls:
+ if radio is radio_selected:
+ text.Enable(True)
+ else:
+ text.Enable(False)
+
+ def OnGroup2Select( self, event ):
+ radio_selected = event.GetEventObject()
+ self.log.write('Group2 %s selected\n' % radio_selected.GetLabel() )
+
+ for radio, text in self.group2_ctrls:
+ if radio is radio_selected:
+ text.Enable(True)
+ else:
+ text.Enable(False)
+
+#----------------------------------------------------------------------
+
+def runTest( frame, nb, log ):
+ win = TestPanel( nb, log )
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+<P>
+This demo shows how individual radio buttons can be used to build
+more complicated selection mechanisms...
+<P>
+It uses 2 groups of wxRadioButtons, where the groups are defined by
+instantiation. When a wxRadioButton is created with the <I>wxRB_GROUP</I>
+style, all subsequent wxRadioButtons created without it are implicitly
+added to that group by the framework.
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o The rightalign library needs converted for this to work correctly.
+#
+# 12/11/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o All issues resolved.
+#
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxRightTextCtrl -> RightTextCtrl
+#
+
+############################################################################\
+# Note: this demo has been converted, but the control is deprecated because |
+# wx.TextCtrl now supports the wx.TE_RIGHT style flag, which makes this |
+# control completely superfluous. |
+############################################################################/
+
+import wx
+import wx.lib.rightalign as right
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent, -1)
+
+ fgs = wx.FlexGridSizer(cols=2, vgap=5, hgap=5)
+
+ txt = wx.StaticText(
+ self, -1,
+ "These text controls will align their contents to\n"
+ "the right (on wxMSW) when they don't have focus.",
+ style=wx.ALIGN_RIGHT
+ )
+
+ fgs.Add(txt)
+ fgs.Add(right.RightTextCtrl(self, -1, "", size=(75, -1)))
+
+ fgs.Add((10,10))
+ fgs.Add(right.RightTextCtrl(self, -1, "123.45", size=(75, -1)))
+
+ fgs.Add((10,10))
+ fgs.Add(right.RightTextCtrl(self, -1, "234.56", size=(75, -1)))
+
+ fgs.Add((10,10))
+ fgs.Add(right.RightTextCtrl(self, -1, "345.67", size=(75, -1)))
+
+ fgs.Add((10,10))
+ fgs.Add(right.RightTextCtrl(self, -1, "456.78", size=(75, -1)))
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(fgs, 0, wx.ALL, 25)
+
+ self.SetSizer(sizer)
+ self.SetAutoLayout(True)
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb)
+ return win
+
+#----------------------------------------------------------------------
+
+overview = right.__doc__
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o Should be renamed to wxSashLayoutWindow.py
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestSashWindow(wx.Panel):
+ ID_WINDOW_TOP = 5100
+ ID_WINDOW_LEFT1 = 5101
+ ID_WINDOW_LEFT2 = 5102
+ ID_WINDOW_BOTTOM = 5103
+
+
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+
+ self.log = log
+
+ # will occupy the space not used by the Layout Algorithm
+ self.remainingSpace = wx.Panel(self, -1, style=wx.SUNKEN_BORDER)
+
+ self.Bind(
+ wx.EVT_SASH_DRAGGED_RANGE, self.OnSashDrag,
+ id=self.ID_WINDOW_TOP, id2=self.ID_WINDOW_BOTTOM,
+ )
+
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+
+
+ # Create some layout windows
+ # A window like a toolbar
+ win = wx.SashLayoutWindow(
+ self, self.ID_WINDOW_TOP, wx.DefaultPosition, (200, 30),
+ wx.NO_BORDER|wx.SW_3D
+ )
+
+ win.SetDefaultSize((1000, 30))
+ win.SetOrientation(wx.LAYOUT_HORIZONTAL)
+ win.SetAlignment(wx.LAYOUT_TOP)
+ win.SetBackgroundColour(wx.Colour(255, 0, 0))
+ win.SetSashVisible(wx.SASH_BOTTOM, True)
+
+ self.topWindow = win
+
+
+ # A window like a statusbar
+ win = wx.SashLayoutWindow(
+ self, self.ID_WINDOW_BOTTOM, wx.DefaultPosition, (200, 30),
+ wx.NO_BORDER|wx.SW_3D
+ )
+
+ win.SetDefaultSize((1000, 30))
+ win.SetOrientation(wx.LAYOUT_HORIZONTAL)
+ win.SetAlignment(wx.LAYOUT_BOTTOM)
+ win.SetBackgroundColour(wx.Colour(0, 0, 255))
+ win.SetSashVisible(wx.SASH_TOP, True)
+
+ self.bottomWindow = win
+
+ # A window to the left of the client window
+ win = wx.SashLayoutWindow(
+ self, self.ID_WINDOW_LEFT1, wx.DefaultPosition, (200, 30),
+ wx.NO_BORDER|wx.SW_3D
+ )
+
+ win.SetDefaultSize((120, 1000))
+ win.SetOrientation(wx.LAYOUT_VERTICAL)
+ win.SetAlignment(wx.LAYOUT_LEFT)
+ win.SetBackgroundColour(wx.Colour(0, 255, 0))
+ win.SetSashVisible(wx.SASH_RIGHT, True)
+ win.SetExtraBorderSize(10)
+ textWindow = wx.TextCtrl(
+ win, -1, "", wx.DefaultPosition, wx.DefaultSize,
+ wx.TE_MULTILINE|wx.SUNKEN_BORDER
+ )
+
+ textWindow.SetValue("A sub window")
+
+ self.leftWindow1 = win
+
+
+ # Another window to the left of the client window
+ win = wx.SashLayoutWindow(
+ self, self.ID_WINDOW_LEFT2, wx.DefaultPosition, (200, 30),
+ wx.NO_BORDER|wx.SW_3D
+ )
+
+ win.SetDefaultSize((120, 1000))
+ win.SetOrientation(wx.LAYOUT_VERTICAL)
+ win.SetAlignment(wx.LAYOUT_LEFT)
+ win.SetBackgroundColour(wx.Colour(0, 255, 255))
+ win.SetSashVisible(wx.SASH_RIGHT, True)
+
+ self.leftWindow2 = win
+
+
+ def OnSashDrag(self, event):
+ if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE:
+ return
+
+ eID = event.GetId()
+
+ if eID == self.ID_WINDOW_TOP:
+ self.topWindow.SetDefaultSize((1000, event.GetDragRect().height))
+
+ elif eID == self.ID_WINDOW_LEFT1:
+ self.leftWindow1.SetDefaultSize((event.GetDragRect().width, 1000))
+
+
+ elif eID == self.ID_WINDOW_LEFT2:
+ self.leftWindow2.SetDefaultSize((event.GetDragRect().width, 1000))
+
+ elif eID == self.ID_WINDOW_BOTTOM:
+ self.bottomWindow.SetDefaultSize((1000, event.GetDragRect().height))
+
+ wx.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace)
+ self.remainingSpace.Refresh()
+
+ def OnSize(self, event):
+ wx.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace)
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestSashWindow(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+wxSashLayoutWindow responds to OnCalculateLayout events generated by
+wxLayoutAlgorithm. It allows the application to use simple accessors to
+specify how the window should be laid out, rather than having to respond
+to events. The fact that the class derives from wxSashWindow allows sashes
+to be used if required, to allow the windows to be user-resizable.
+
+The documentation for wxLayoutAlgorithm explains the purpose of this class
+in more detail.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o dialogs library needs updated to wx
+#
+# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o dialogs library converted. All is well.
+#
+# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxScrolledMessageDialog -> ScrolledMessageDialog
+#
+
+import wx
+import wx.lib.dialogs
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ f = open("Main.py", "r")
+ msg = f.read()
+ f.close()
+
+ dlg = wx.lib.dialogs.ScrolledMessageDialog(frame, msg, "message test")
+ dlg.ShowModal()
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+
+<code><b>ScrolledMessageDialog</b>(parent, msg, caption, pos=wx.DefaultPosition, size=(500,300))</code>
+
+This class represents a message dialog that uses a wxTextCtrl to display the
+message. This allows more flexible information display without having to be
+as much concerned with layout requirements. A text file can simply be used
+
+This dialog offers no special attributes or methods beyond those supported
+by wxDialog.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o scrolledpanel lib needs wx update
+#
+# 12/11/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o lib updated, all is well.
+#
+# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxScrolledPanel -> ScrolledPanel
+#
+
+import wx
+import wx.lib.scrolledpanel as scrolled
+
+#----------------------------------------------------------------------
+
+text = "one two buckle my shoe three four shut the door five six pick up sticks seven eight lay them straight nine ten big fat hen"
+
+
+class TestPanel(scrolled.ScrolledPanel):
+ def __init__(self, parent, log):
+ self.log = log
+ scrolled.ScrolledPanel.__init__(self, parent, -1)
+
+ vbox = wx.BoxSizer(wx.VERTICAL)
+ desc = wx.StaticText(self, -1,
+ "ScrolledPanel extends wx.ScrolledWindow, adding all "
+ "the necessary bits to set up scroll handling for you.\n\n"
+ "Here are three fixed size examples of its use. The "
+ "demo panel for this sample is also using it -- the \nwxStaticLine"
+ "below is intentionally made too long so a scrollbar will be "
+ "activated."
+ )
+ desc.SetForegroundColour("Blue")
+ vbox.Add(desc, 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ vbox.Add(wx.StaticLine(self, -1, size=(1024,-1)), 0, wx.ALL, 5)
+ vbox.Add((20,20))
+
+ words = text.split()
+
+ panel1 = scrolled.ScrolledPanel(self, -1, size=(120,300),
+ style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER )
+ fgs1 = wx.FlexGridSizer(cols=2, vgap=4, hgap=4)
+
+ for word in words:
+ label = wx.StaticText(panel1, -1, word+":")
+ tc = wx.TextCtrl(panel1, -1, word, size=(50,-1))
+ fgs1.Add(label, flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
+ fgs1.Add(tc, flag=wx.EXPAND|wx.RIGHT, border=25)
+
+ panel1.SetSizer( fgs1 )
+ panel1.SetAutoLayout(1)
+ panel1.SetupScrolling( scroll_x=False )
+
+ panel2 = scrolled.ScrolledPanel(self, -1, size=(350, 40),
+ style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
+ panel3 = scrolled.ScrolledPanel(self, -1, size=(200,100),
+ style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
+
+ fgs2 = wx.FlexGridSizer(cols=25, vgap=4, hgap=4)
+ fgs3 = wx.FlexGridSizer(cols=5, vgap=4, hgap=4)
+
+ for i in range(len(words)):
+ word = words[i]
+ if i % 5 != 4:
+ label2 = wx.StaticText(panel2, -1, word)
+ fgs2.Add(label2, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
+ label3 = wx.StaticText(panel3, -1, word)
+ fgs3.Add(label3, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
+ else:
+ tc2 = wx.TextCtrl(panel2, -1, word, size=(50,-1))
+ fgs2.Add(tc2, flag=wx.LEFT, border=5)
+ tc3 = wx.TextCtrl(panel3, -1, word )
+ fgs3.Add(tc3, flag=wx.LEFT, border=5)
+
+ panel2.SetSizer( fgs2 )
+ panel2.SetAutoLayout(1)
+ panel2.SetupScrolling(scroll_y = False)
+
+ panel3.SetSizer( fgs3 )
+ panel3.SetAutoLayout(1)
+ panel3.SetupScrolling()
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((20,20))
+ hbox.Add(panel1, 0)
+ hbox.Add((40, 10))
+
+ vbox2 = wx.BoxSizer(wx.VERTICAL)
+ vbox2.Add(panel2, 0)
+ vbox2.Add((20, 50))
+
+ vbox2.Add(panel3, 0)
+ vbox2.Add((20, 10))
+ hbox.Add(vbox2)
+
+ vbox.AddSizer(hbox, 0)
+ self.SetSizer(vbox)
+ self.SetAutoLayout(1)
+ self.SetupScrolling()
+
+
+#----------------------------------------------------------------------
+
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+ScrolledPanel fills a "hole" in the implementation of wx.ScrolledWindow,
+providing automatic scrollbar and scrolling behavior and the tab traversal
+mangement that wx.ScrolledWindow lacks.
+</body></html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/12/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o Rudimentary overview doc added.
+#
+
+import wx
+
+import images
+
+BUFFERED = 1
+
+#---------------------------------------------------------------------------
+
+class MyCanvas(wx.ScrolledWindow):
+ def __init__(self, parent, id = -1, size = wx.DefaultSize):
+ wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER)
+
+ self.lines = []
+ self.maxWidth = 1000
+ self.maxHeight = 1000
+ self.x = self.y = 0
+ self.curLine = []
+ self.drawing = False
+
+ self.SetBackgroundColour("WHITE")
+ self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))
+ bmp = images.getTest2Bitmap()
+ mask = wx.MaskColour(bmp, wx.BLUE)
+ bmp.SetMask(mask)
+ self.bmp = bmp
+
+ self.SetScrollbars(20, 20, self.maxWidth/20, self.maxHeight/20)
+
+ if BUFFERED:
+ # Initialize the buffer bitmap. No real DC is needed at this point.
+ self.buffer = wx.EmptyBitmap(self.maxWidth, self.maxHeight)
+ dc = wx.BufferedDC(None, self.buffer)
+ dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
+ dc.Clear()
+ self.DoDrawing(dc)
+
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftButtonEvent)
+ self.Bind(wx.EVT_LEFT_UP, self.OnLeftButtonEvent)
+ self.Bind(wx.EVT_MOTION, self.OnLeftButtonEvent)
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
+
+
+ def getWidth(self):
+ return self.maxWidth
+
+ def getHeight(self):
+ return self.maxHeight
+
+
+ def OnPaint(self, event):
+ if BUFFERED:
+ # Create a buffered paint DC. It will create the real
+ # wx.PaintDC and then blit the bitmap to it when dc is
+ # deleted. Since we don't need to draw anything else
+ # here that's all there is to it.
+ dc = wx.BufferedPaintDC(self, self.buffer)
+ else:
+ dc = wx.PaintDC(self)
+ self.PrepareDC(dc)
+ # since we're not buffering in this case, we have to
+ # paint the whole window, potentially very time consuming.
+ self.DoDrawing(dc)
+
+
+ def DoDrawing(self, dc, printing=False):
+ dc.BeginDrawing()
+ dc.SetPen(wx.Pen('RED'))
+ dc.DrawRectangle((5, 5), (50, 50))
+
+ dc.SetBrush(wx.LIGHT_GREY_BRUSH)
+ dc.SetPen(wx.Pen('BLUE', 4))
+ dc.DrawRectangle((15, 15), (50, 50))
+
+ dc.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL))
+ dc.SetTextForeground(wx.Colour(0xFF, 0x20, 0xFF))
+ te = dc.GetTextExtent("Hello World")
+ dc.DrawText("Hello World", (60, 65))
+
+ dc.SetPen(wx.Pen('VIOLET', 4))
+ dc.DrawLine((5, 65+te[1]), (60+te[0], 65+te[1]))
+
+ lst = [(100,110), (150,110), (150,160), (100,160)]
+ dc.DrawLines(lst, -60)
+ dc.SetPen(wx.GREY_PEN)
+ dc.DrawPolygon(lst, 75)
+ dc.SetPen(wx.GREEN_PEN)
+ dc.DrawSpline(lst+[(100,100)])
+
+ dc.DrawBitmap(self.bmp, (200, 20), True)
+ dc.SetTextForeground(wx.Colour(0, 0xFF, 0x80))
+ dc.DrawText("a bitmap", (200, 85))
+
+## dc.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL))
+## dc.SetTextForeground("BLACK")
+## dc.DrawText("TEST this STRING", (10, 200))
+## print dc.GetFullTextExtent("TEST this STRING")
+
+ font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
+ dc.SetFont(font)
+ dc.SetTextForeground(wx.BLACK)
+
+ for a in range(0, 360, 45):
+ dc.DrawRotatedText("Rotated text...", (300, 300), a)
+
+ dc.SetPen(wx.TRANSPARENT_PEN)
+ dc.SetBrush(wx.BLUE_BRUSH)
+ dc.DrawRectangle((50,500),(50,50))
+ dc.DrawRectangle((100,500),(50,50))
+
+ dc.SetPen(wx.Pen('RED'))
+ dc.DrawEllipticArc((200, 500), (50, 75), 0, 90)
+
+ if not printing:
+ # This has troubles when used on a print preview in wxGTK,
+ # probably something to do with the pen styles and the scaling
+ # it does...
+ y = 20
+
+ for style in [wx.DOT, wx.LONG_DASH, wx.SHORT_DASH, wx.DOT_DASH, wx.USER_DASH]:
+ pen = wx.Pen("DARK ORCHID", 1, style)
+ if style == wx.USER_DASH:
+ pen.SetCap(wx.CAP_BUTT)
+ pen.SetDashes([1,2])
+ pen.SetColour("RED")
+ dc.SetPen(pen)
+ dc.DrawLine((300, y), (400, y))
+ y = y + 10
+
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
+ dc.SetPen(wx.Pen(wx.Colour(0xFF, 0x20, 0xFF), 1, wx.SOLID))
+ dc.DrawRectangle((450, 50), (100, 100))
+ old_pen = dc.GetPen()
+ new_pen = wx.Pen("BLACK", 5)
+ dc.SetPen(new_pen)
+ dc.DrawRectangle((470, 70), (60, 60))
+ dc.SetPen(old_pen)
+ dc.DrawRectangle((490, 90), (20, 20))
+
+ self.DrawSavedLines(dc)
+ dc.EndDrawing()
+
+
+ def DrawSavedLines(self, dc):
+ dc.SetPen(wx.Pen('MEDIUM FOREST GREEN', 4))
+
+ for line in self.lines:
+ for coords in line:
+ apply(dc.DrawLine, coords)
+
+
+ def SetXY(self, event):
+ self.x, self.y = self.ConvertEventCoords(event)
+
+ def ConvertEventCoords(self, event):
+ xView, yView = self.GetViewStart()
+ xDelta, yDelta = self.GetScrollPixelsPerUnit()
+ return (event.GetX() + (xView * xDelta),
+ event.GetY() + (yView * yDelta))
+
+ def OnLeftButtonEvent(self, event):
+ if event.LeftDown():
+ self.SetFocus()
+ self.SetXY(event)
+ self.curLine = []
+ self.CaptureMouse()
+ self.drawing = True
+
+ elif event.Dragging() and self.drawing:
+ if BUFFERED:
+ # If doing buffered drawing, create the buffered DC, giving it
+ # it a real DC to blit to when done.
+ cdc = wx.ClientDC(self)
+ self.PrepareDC(cdc)
+ dc = wx.BufferedDC(cdc, self.buffer)
+ else:
+ dc = wx.ClientDC(self)
+ self.PrepareDC(dc)
+
+ dc.BeginDrawing()
+ dc.SetPen(wx.Pen('MEDIUM FOREST GREEN', 4))
+ coords = [(self.x, self.y) , self.ConvertEventCoords(event)]
+ self.curLine.append(coords)
+ apply(dc.DrawLine, coords)
+ self.SetXY(event)
+ dc.EndDrawing()
+
+
+ elif event.LeftUp() and self.drawing:
+ self.lines.append(self.curLine)
+ self.curLine = []
+ self.ReleaseMouse()
+ self.drawing = False
+
+
+## This is an example of what to do for the EVT_MOUSEWHEEL event,
+## but since wx.ScrolledWindow does this already it's not
+## necessary to do it ourselves. You would need to add an event table
+## entry to __init__() to direct wheelmouse events to this handler.
+
+## wheelScroll = 0
+## def OnWheel(self, evt):
+## delta = evt.GetWheelDelta()
+## rot = evt.GetWheelRotation()
+## linesPer = evt.GetLinesPerAction()
+## print delta, rot, linesPer
+## ws = self.wheelScroll
+## ws = ws + rot
+## lines = ws / delta
+## ws = ws - lines * delta
+## self.wheelScroll = ws
+## if lines != 0:
+## lines = lines * linesPer
+## vsx, vsy = self.GetViewStart()
+## scrollTo = vsy - lines
+## self.Scroll(-1, scrollTo)
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = MyCanvas(nb)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """
+<html>
+<body>
+The wx.ScrolledWindow class manages scrolling for its client area, transforming the
+coordinates according to the scrollbar positions, and setting the scroll positions,
+thumb sizes and ranges according to the area in view.
+</body>
+</html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ dlg = wx.SingleChoiceDialog(
+ frame, 'Test Single Choice', 'The Caption',
+ ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'],
+ wx.CHOICEDLG_STYLE
+ )
+
+ if dlg.ShowModal() == wx.ID_OK:
+ log.WriteText('You selected: %s\n' % dlg.GetStringSelection())
+
+ dlg.Destroy()
+
+#---------------------------------------------------------------------------
+
+
+
+
+overview = """\
+This class represents a dialog that shows a list of strings, and allows the user
+to select one. Double-clicking on a list item is equivalent to single-clicking
+and then pressing OK.
+
+As with all dialogs, be sure to retrieve the information you need BEFORE you
+destroy the dialog.
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+ self.count = 0
+
+ wx.StaticText(self, -1, "This is a wxSlider.", (45, 15))
+
+ slider = wx.Slider(
+ self, 100, 25, 1, 100, (30, 60), (250, -1),
+ wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS
+ )
+
+ slider.SetTickFreq(5, 1)
+
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+
+overview = """\
+A slider is a control with a handle which can be pulled back and forth to
+change the value.
+
+In Windows versions below Windows 95, a scrollbar is used to simulate the slider.
+In Windows 95, the track bar control is used.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o EVT_SPIN events (or something about them) freezes up the app.
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+ self.count = 0
+
+ wx.StaticText(self, -1, "This example uses the wxSpinButton control.", (45, 15))
+
+ self.text = wx.TextCtrl(self, -1, "1", (30, 50), (60, -1))
+ h = self.text.GetSize().height
+
+ self.spin = wx.SpinButton(self, -1, (92, 50), (h, h), wx.SP_VERTICAL)
+ self.spin.SetRange(1, 100)
+ self.spin.SetValue(1)
+
+ self.Bind(wx.EVT_SPIN, self.OnSpin, self.spin)
+
+
+ def OnSpin(self, event):
+ self.text.SetValue(str(event.GetPosition()))
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+A wxSpinButton has two small up and down (or left and right) arrow buttons.
+It is often used next to a text control for increment and decrementing a value.
+Portable programs should try to use wxSpinCtrl instead as wxSpinButton is not
+implemented for all platforms (Win32 and GTK only currently).
+
+NB: the range supported by this control (and wxSpinCtrl) depends on the platform
+but is at least -0x8000 to 0x7fff. Under GTK and Win32 with sufficiently new version
+of comctrl32.dll (at least 4.71 is required, 5.80 is recommended) the full 32 bit
+range is supported.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+ self.count = 0
+
+ wx.StaticText(self, -1, "This example uses the wxSpinCtrl control.", (45, 15))
+ sc = wx.SpinCtrl(self, -1, "", (30, 50), (80, -1))
+ sc.SetRange(1,100)
+ sc.SetValue(5)
+ #sc.Enable(False)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+wxSpinCtrl combines wxTextCtrl and wxSpinButton in one control.
+
+Portable programs should try to use wxSpinCtrl instead as wxSpinButton is not
+implemented for all platforms (Win32 and GTK only currently).
+
+NB: the range supported by this control depends on the platform
+but is at least -0x8000 to 0x7fff. Under GTK and Win32 with sufficiently new version
+of comctrl32.dll (at least 4.71 is required, 5.80 is recommended) the full 32 bit
+range is supported.
+
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class MySplitter(wx.SplitterWindow):
+ def __init__(self, parent, ID, log):
+ wx.SplitterWindow.__init__(self, parent, ID)
+ self.log = log
+
+ self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnSashChanged)
+ self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnSashChanging)
+
+ def OnSashChanged(self, evt):
+ self.log.WriteText("sash changed to %s\n" % str(evt.GetSashPosition()))
+ # uncomment this to not allow the change
+ #evt.SetSashPosition(-1)
+
+ def OnSashChanging(self, evt):
+ self.log.WriteText("sash changing to %s\n" % str(evt.GetSashPosition()))
+ # uncomment this to not allow the change
+ #evt.SetSashPosition(-1)
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ splitter = MySplitter(nb, -1, log)
+
+ p1 = wx.Window(splitter, -1)
+ p1.SetBackgroundColour(wx.RED)
+ wx.StaticText(p1, -1, "Panel One", (5,5)).SetBackgroundColour(wx.RED)
+
+ p2 = wx.Window(splitter, -1)
+ p2.SetBackgroundColour(wx.BLUE)
+ wx.StaticText(p2, -1, "Panel Two", (5,5)).SetBackgroundColour(wx.BLUE)
+
+ splitter.SetMinimumPaneSize(20)
+ splitter.SplitVertically(p1, p2, 100)
+
+ return splitter
+
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+This class manages up to two subwindows. The current view can be split
+into two programmatically (perhaps from a menu command), and unsplit
+either programmatically or via the wxSplitterWindow user interface.
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import images
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+ self.count = 0
+
+ wx.StaticText(self, -1, "This is a wxStaticBitmap.", (45, 15))
+
+ bmp = images.getTest2Bitmap()
+ mask = wx.MaskColour(bmp, wx.BLUE)
+ bmp.SetMask(mask)
+ wx.StaticBitmap(self, -1, bmp, (80, 50), (bmp.GetWidth(), bmp.GetHeight()))
+
+ bmp = images.getRobinBitmap()
+ wx.StaticBitmap(self, -1, bmp, (80, 150))
+
+ wx.StaticText(self, -1, "Hey, if Ousterhout can do it, so can I.", (200, 175))
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+overview = """\
+A static bitmap control displays a bitmap.
+
+The bitmap to be displayed should have a small number of colours, such as 16,
+to avoid palette problems.
+
+A bitmap can be derived from most image formats using the wxImage class.
+
+"""
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o Removed the USE_GENERIC code because it doesn't work unless you use
+# the 'from wx import *' methodology.
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent, -1)
+
+ wx.StaticText(self, -1, "This is an example of static text", (20, 10))
+ wx.StaticText(self, -1, "using the wxStaticText Control.", (20, 30))
+
+ wx.StaticText(
+ self, -1, "Is this yellow?", (20, 70), (90, -1)
+ ).SetBackgroundColour('Yellow')
+
+ wx.StaticText(
+ self, -1, "align center", (120, 70), (90, -1), wx.ALIGN_CENTER
+ ).SetBackgroundColour('Yellow')
+
+ wx.StaticText(
+ self, -1, "align right", (220, 70), (90, -1), wx.ALIGN_RIGHT
+ ).SetBackgroundColour('Yellow')
+
+ str = "This is a different font."
+ text = wx.StaticText(self, -1, str, (20, 100))
+ font = wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)
+ text.SetFont(font)
+ #text.SetSize(text.GetBestSize())
+
+ wx.StaticText(self, -1, "Multi-line wxStaticText\nline 2\nline 3\n\nafter empty line", (20,150))
+ wx.StaticText(self, -1, "Align right multi-line\nline 2\nline 3\n\nafter empty line", (220,150), style=wx.ALIGN_RIGHT)
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ panel = TestPanel(nb)
+ return panel
+
+
+#---------------------------------------------------------------------------
+
+
+overview = '''\
+A static text control displays one or more lines of read-only text.
+
+'''
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import time
+import wx
+
+#---------------------------------------------------------------------------
+
+class CustomStatusBar(wx.StatusBar):
+ def __init__(self, parent, log):
+ wx.StatusBar.__init__(self, parent, -1)
+
+ # This status bar has three fields
+ self.SetFieldsCount(3)
+ self.log = log
+ self.sizeChanged = False
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+ self.Bind(wx.EVT_IDLE, self.OnIdle)
+
+ # Field 0 ... just text
+ self.SetStatusText("A Custom StatusBar...", 0)
+
+ # This will fall into field 1 (the second field)
+ self.cb = wx.CheckBox(self, 1001, "toggle clock")
+ self.Bind(wx.EVT_CHECKBOX, self.OnToggleClock, self.cb)
+ self.cb.SetValue(True)
+
+ # set the initial position of the checkbox
+ self.Reposition()
+
+ # We're going to use a timer to drive a 'clock' in the last
+ # field.
+ self.timer = wx.PyTimer(self.Notify)
+ self.timer.Start(1000)
+ self.Notify()
+
+
+ # Handles events from the timer we started in __init__().
+ # We're using it to drive a 'clock' in field 2 (the third field).
+ def Notify(self):
+ t = time.localtime(time.time())
+ st = time.strftime("%d-%b-%Y %I:%M:%S", t)
+ self.SetStatusText(st, 2)
+ self.log.WriteText("tick...\n")
+
+
+ # the checkbox was clicked
+ def OnToggleClock(self, event):
+ if self.cb.GetValue():
+ self.timer.Start(1000)
+ self.Notify()
+ else:
+ self.timer.Stop()
+
+
+ def OnSize(self, evt):
+ self.Reposition() # for normal size events
+
+ # Set a flag so the idle time handler will also do the repositioning.
+ # It is done this way to get around a buglet where GetFieldRect is not
+ # accurate during the EVT_SIZE resulting from a frame maximize.
+ self.sizeChanged = True
+
+
+ def OnIdle(self, evt):
+ if self.sizeChanged:
+ self.Reposition()
+
+
+ # reposition the checkbox
+ def Reposition(self):
+ rect = self.GetFieldRect(1)
+ self.cb.SetPosition((rect.x+2, rect.y+2))
+ self.cb.SetSize((rect.width-4, rect.height-4))
+ self.sizeChanged = False
+
+
+
+class TestCustomStatusBar(wx.Frame):
+ def __init__(self, parent, log):
+ wx.Frame.__init__(self, parent, -1, 'Test Custom StatusBar')
+
+ self.sb = CustomStatusBar(self, log)
+ self.SetStatusBar(self.sb)
+ tc = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY|wx.TE_MULTILINE)
+
+ self.SetSize((500, 300))
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+ def OnCloseWindow(self, event):
+ self.sb.timer.Stop()
+ del self.sb.timer
+ self.Destroy()
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestCustomStatusBar(frame, log)
+ frame.otherWin = win
+ win.Show(True)
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+A status bar is a narrow window that can be placed along the bottom of
+a frame to give small amounts of status information. It can contain
+one or more fields, one or more of which can be variable length
+according to the size of the window.
+
+This example demonstrates how to create a custom status bar with actual
+gadgets embedded in it. In this case, the first field is just plain text,
+The second one has a checkbox that enables the timer, and the third
+field has a clock that shows the current time when it is enabled.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o EVT_STC_DRAG_OVER event GetdragResult() is not an int
+# o wx.TheClipboard.Flush() generates an error on program exit.
+#
+
+import wx
+import wx.stc as stc
+
+import images
+
+#----------------------------------------------------------------------
+
+debug = 1
+
+
+demoText = """\
+
+This editor is provided by a class named wxStyledTextCtrl. As
+the name suggests, you can define styles that can be applied to
+sections of text. This will typically be used for things like
+syntax highlighting code editors, but I'm sure that there are other
+applications as well. A style is a combination of font, point size,
+foreground and background colours. The editor can handle
+proportional fonts just as easily as monospaced fonts, and various
+styles can use different sized fonts.
+
+There are a few canned language lexers and colourizers included,
+(see the next demo) or you can handle the colourization yourself.
+If you do you can simply register an event handler and the editor
+will let you know when the visible portion of the text needs
+styling.
+
+wxStyledTextEditor also supports setting markers in the margin...
+
+
+
+
+...and indicators within the text. You can use these for whatever
+you want in your application. Cut, Copy, Paste, Drag and Drop of
+text works, as well as virtually unlimited Undo and Redo
+capabilities, (right click to try it out.)
+"""
+
+if wx.Platform == '__WXMSW__':
+ face1 = 'Arial'
+ face2 = 'Times New Roman'
+ face3 = 'Courier New'
+ pb = 10
+else:
+ face1 = 'Helvetica'
+ face2 = 'Times'
+ face3 = 'Courier'
+ pb = 10
+
+
+#----------------------------------------------------------------------
+# This shows how to catch the Modified event from the wxStyledTextCtrl
+
+class MySTC(stc.StyledTextCtrl):
+ def __init__(self, parent, ID, log):
+ stc.StyledTextCtrl.__init__(self, parent, ID)
+ self.log = log
+
+ self.Bind(stc.EVT_STC_DO_DROP, self.OnDoDrop)
+ self.Bind(stc.EVT_STC_DRAG_OVER, self.OnDragOver)
+ self.Bind(stc.EVT_STC_START_DRAG, self.OnStartDrag)
+ self.Bind(stc.EVT_STC_MODIFIED, self.OnModified)
+
+ self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
+
+ def OnDestroy(self, evt):
+ # This is how the clipboard contents can be preserved after
+ # the app has exited.
+ wx.TheClipboard.Flush()
+ evt.Skip()
+
+
+ def OnStartDrag(self, evt):
+ self.log.write("OnStartDrag: %d, %s\n"
+ % (evt.GetDragAllowMove(), evt.GetDragText()))
+
+ if debug and evt.GetPosition() < 250:
+ evt.SetDragAllowMove(False) # you can prevent moving of text (only copy)
+ evt.SetDragText("DRAGGED TEXT") # you can change what is dragged
+ #evt.SetDragText("") # or prevent the drag with empty text
+
+
+ def OnDragOver(self, evt):
+ #Todo: evt.GetdragResult() response is not an int
+
+ self.log.write(
+ "OnDragOver: x,y=(%d, %d) pos: %d DragResult: %d\n"
+ % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult())
+ )
+
+ if debug and evt.GetPosition() < 250:
+ evt.SetDragResult(wx.DragNone) # prevent dropping at the beginning of the buffer
+
+
+ def OnDoDrop(self, evt):
+ self.log.write("OnDoDrop: x,y=(%d, %d) pos: %d DragResult: %d\n"
+ "\ttext: %s\n"
+ % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult(),
+ evt.GetDragText()))
+
+ if debug and evt.GetPosition() < 500:
+ evt.SetDragText("DROPPED TEXT") # Can change text if needed
+ #evt.SetDragResult(wx.DragNone) # Can also change the drag operation, but it
+ # is probably better to do it in OnDragOver so
+ # there is visual feedback
+
+ #evt.SetPosition(25) # Can also change position, but I'm not sure why
+ # you would want to...
+
+
+
+
+ def OnModified(self, evt):
+ self.log.write("""OnModified
+ Mod type: %s
+ At position: %d
+ Lines added: %d
+ Text Length: %d
+ Text: %s\n""" % ( self.transModType(evt.GetModificationType()),
+ evt.GetPosition(),
+ evt.GetLinesAdded(),
+ evt.GetLength(),
+ repr(evt.GetText()) ))
+
+
+ def transModType(self, modType):
+ st = ""
+ table = [(stc.STC_MOD_INSERTTEXT, "InsertText"),
+ (stc.STC_MOD_DELETETEXT, "DeleteText"),
+ (stc.STC_MOD_CHANGESTYLE, "ChangeStyle"),
+ (stc.STC_MOD_CHANGEFOLD, "ChangeFold"),
+ (stc.STC_PERFORMED_USER, "UserFlag"),
+ (stc.STC_PERFORMED_UNDO, "Undo"),
+ (stc.STC_PERFORMED_REDO, "Redo"),
+ (stc.STC_LASTSTEPINUNDOREDO, "Last-Undo/Redo"),
+ (stc.STC_MOD_CHANGEMARKER, "ChangeMarker"),
+ (stc.STC_MOD_BEFOREINSERT, "B4-Insert"),
+ (stc.STC_MOD_BEFOREDELETE, "B4-Delete")
+ ]
+
+ for flag,text in table:
+ if flag & modType:
+ st = st + text + " "
+
+ if not st:
+ st = 'UNKNOWN'
+
+ return st
+
+
+
+
+#----------------------------------------------------------------------
+
+_USE_PANEL = 1
+
+def runTest(frame, nb, log):
+ if not _USE_PANEL:
+ ed = p = MySTC(nb, -1, log)
+
+ else:
+ p = wx.Panel(nb, -1, style=wx.NO_FULL_REPAINT_ON_RESIZE)
+ ed = MySTC(p, -1, log)
+ s = wx.BoxSizer(wx.HORIZONTAL)
+ s.Add(ed, 1, wx.EXPAND)
+ p.SetSizer(s)
+ p.SetAutoLayout(True)
+
+
+ #ed.SetBufferedDraw(False)
+ #ed.StyleClearAll()
+ #ed.SetScrollWidth(800)
+ #ed.SetWrapMode(True)
+
+ ed.SetText(demoText)
+
+ if wx.USE_UNICODE:
+ import codecs
+ decode = codecs.lookup("utf-8")[1]
+
+ ed.GotoPos(ed.GetLength())
+ ed.AddText("\n\nwxStyledTextCtrl can also do Unicode:\n")
+ unitext, l = decode('\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd - '
+ '\xd0\xbb\xd1\x83\xd1\x87\xd1\x88\xd0\xb8\xd0\xb9 '
+ '\xd1\x8f\xd0\xb7\xd1\x8b\xd0\xba \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f!\n\n')
+ ed.AddText('\tRussian: ')
+ ed.AddText(unitext)
+ ed.GotoPos(0)
+
+ ed.EmptyUndoBuffer()
+
+ # make some styles
+ ed.StyleSetSpec(stc.STC_STYLE_DEFAULT, "size:%d,face:%s" % (pb, face3))
+ ed.StyleSetSpec(1, "size:%d,bold,face:%s,fore:#0000FF" % (pb+2, face1))
+ ed.StyleSetSpec(2, "face:%s,italic,fore:#FF0000,size:%d" % (face2, pb))
+ ed.StyleSetSpec(3, "face:%s,bold,size:%d" % (face2, pb+2))
+ ed.StyleSetSpec(4, "face:%s,size:%d" % (face1, pb-1))
+
+ # Now set some text to those styles... Normally this would be
+ # done in an event handler that happens when text needs displayed.
+ ed.StartStyling(98, 0xff)
+ ed.SetStyling(6, 1) # set style for 6 characters using style 1
+
+ ed.StartStyling(190, 0xff)
+ ed.SetStyling(20, 2)
+
+ ed.StartStyling(310, 0xff)
+ ed.SetStyling(4, 3)
+ ed.SetStyling(2, 0)
+ ed.SetStyling(10, 4)
+
+
+ # line numbers in the margin
+ ed.SetMarginType(0, stc.STC_MARGIN_NUMBER)
+ ed.SetMarginWidth(0, 22)
+ ed.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "size:%d,face:%s" % (pb, face1))
+
+ # setup some markers
+ ed.SetMarginType(1, stc.STC_MARGIN_SYMBOL)
+ ed.MarkerDefine(0, stc.STC_MARK_ROUNDRECT, "#CCFF00", "RED")
+ #ed.MarkerDefine(1, stc.STC_MARK_CIRCLE, "FOREST GREEN", "SIENNA")
+ ed.MarkerDefineBitmap(1, images.getFolder1Bitmap())
+ ed.MarkerDefine(2, stc.STC_MARK_SHORTARROW, "blue", "blue")
+ ed.MarkerDefine(3, stc.STC_MARK_ARROW, "#00FF00", "#00FF00")
+
+ # put some markers on some lines
+ ed.MarkerAdd(17, 0)
+ ed.MarkerAdd(18, 1)
+ ed.MarkerAdd(19, 2)
+ ed.MarkerAdd(20, 3)
+ ed.MarkerAdd(20, 0)
+
+
+ # and finally, an indicator or two
+ ed.IndicatorSetStyle(0, stc.STC_INDIC_SQUIGGLE)
+ ed.IndicatorSetForeground(0, wx.RED)
+ ed.IndicatorSetStyle(1, stc.STC_INDIC_DIAGONAL)
+ ed.IndicatorSetForeground(1, wx.BLUE)
+ ed.IndicatorSetStyle(2, stc.STC_INDIC_STRIKE)
+ ed.IndicatorSetForeground(2, wx.RED)
+
+ ed.StartStyling(836, stc.STC_INDICS_MASK)
+ ed.SetStyling(10, stc.STC_INDIC0_MASK)
+ ed.SetStyling(10, stc.STC_INDIC1_MASK)
+ ed.SetStyling(10, stc.STC_INDIC2_MASK | stc.STC_INDIC1_MASK)
+
+
+ # some test stuff...
+ if debug:
+ print "GetTextLength(): ", ed.GetTextLength(), len(ed.GetText())
+ print "GetText(): ", repr(ed.GetText())
+ print
+ print "GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104))
+ print
+ print "GetCurLine(): ", repr(ed.GetCurLine())
+ ed.GotoPos(5)
+ print "GetCurLine(): ", repr(ed.GetCurLine())
+ print
+ print "GetLine(1): ", repr(ed.GetLine(1))
+ print
+ ed.SetSelection(25, 35)
+ print "GetSelectedText(): ", repr(ed.GetSelectedText())
+ print "GetTextRange(25, 35): ", repr(ed.GetTextRange(25, 35))
+ print "FindText(0, max, 'indicators'): ",
+ print ed.FindText(0, ed.GetTextLength(), "indicators")
+
+ ed.GotoPos(0)
+
+
+ return p
+
+
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a>
+and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should
+be helpful.
+</body><html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import keyword
+
+import wx
+import wx.stc as stc
+
+import images
+
+#----------------------------------------------------------------------
+
+demoText = """\
+## This version of the editor has been set up to edit Python source
+## code. Here is a copy of wxPython/demo/Main.py to play with.
+
+
+"""
+
+#----------------------------------------------------------------------
+
+
+if wx.Platform == '__WXMSW__':
+ faces = { 'times': 'Times New Roman',
+ 'mono' : 'Courier New',
+ 'helv' : 'Arial',
+ 'other': 'Comic Sans MS',
+ 'size' : 10,
+ 'size2': 8,
+ }
+else:
+ faces = { 'times': 'Times',
+ 'mono' : 'Courier',
+ 'helv' : 'Helvetica',
+ 'other': 'new century schoolbook',
+ 'size' : 12,
+ 'size2': 10,
+ }
+
+
+#----------------------------------------------------------------------
+
+class PythonSTC(stc.StyledTextCtrl):
+
+ fold_symbols = 2
+
+ def __init__(self, parent, ID):
+ stc.StyledTextCtrl.__init__(self, parent, ID,
+ style = wx.NO_FULL_REPAINT_ON_RESIZE)
+
+ self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
+ self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
+
+ self.SetLexer(stc.STC_LEX_PYTHON)
+ self.SetKeyWords(0, " ".join(keyword.kwlist))
+
+ self.SetProperty("fold", "1")
+ self.SetProperty("tab.timmy.whinge.level", "1")
+ self.SetMargins(0,0)
+
+ self.SetViewWhiteSpace(False)
+ #self.SetBufferedDraw(False)
+ #self.SetViewEOL(True)
+
+ self.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
+ self.SetEdgeColumn(78)
+
+ # Setup a margin to hold fold markers
+ #self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
+ self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
+ self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
+ self.SetMarginSensitive(2, True)
+ self.SetMarginWidth(2, 12)
+
+ if self.fold_symbols == 0:
+ # Arrow pointing right for contracted folders, arrow pointing down for expanded
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_ARROWDOWN, "black", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_ARROW, "black", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "black", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "black", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black");
+
+ elif self.fold_symbols == 1:
+ # Plus for contracted folders, minus for expanded
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_MINUS, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_PLUS, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black");
+
+ elif self.fold_symbols == 2:
+ # Like a flattened tree control using circular headers and curved joins
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_CIRCLEMINUS, "white", "#404040");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_CIRCLEPLUS, "white", "#404040");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#404040");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNERCURVE, "white", "#404040");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040");
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE, "white", "#404040");
+
+ elif self.fold_symbols == 3:
+ # Like a flattened tree control using square headers
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "#808080")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "#808080")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#808080")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "#808080")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
+ self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "#808080")
+
+
+ self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
+ self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
+ self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
+
+ # Make some styles, The lexer defines what each style is used for, we
+ # just have to define what each style looks like. This set is adapted from
+ # Scintilla sample property files.
+
+ # Global default styles for all languages
+ self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
+ self.StyleClearAll() # Reset all to be like the default
+
+ # Global default styles for all languages
+ self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
+ self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
+ self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
+ self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
+ self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
+
+ # Python styles
+ # Default
+ self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
+ # Comments
+ self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
+ # Number
+ self.StyleSetSpec(stc.STC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
+ # String
+ self.StyleSetSpec(stc.STC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
+ # Single quoted string
+ self.StyleSetSpec(stc.STC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
+ # Keyword
+ self.StyleSetSpec(stc.STC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
+ # Triple quotes
+ self.StyleSetSpec(stc.STC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
+ # Triple double quotes
+ self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
+ # Class name definition
+ self.StyleSetSpec(stc.STC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
+ # Function or method name definition
+ self.StyleSetSpec(stc.STC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
+ # Operators
+ self.StyleSetSpec(stc.STC_P_OPERATOR, "bold,size:%(size)d" % faces)
+ # Identifiers
+ self.StyleSetSpec(stc.STC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
+ # Comment-blocks
+ self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
+ # End of line where string is not closed
+ self.StyleSetSpec(stc.STC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
+
+ self.SetCaretForeground("BLUE")
+
+
+ # register some images for use in the AutoComplete box.
+ self.RegisterImage(1, images.getSmilesBitmap())
+ self.RegisterImage(2, images.getFile1Bitmap())
+ self.RegisterImage(3, images.getCopy2Bitmap())
+
+
+ def OnKeyPressed(self, event):
+ if self.CallTipActive():
+ self.CallTipCancel()
+ key = event.KeyCode()
+
+ if key == 32 and event.ControlDown():
+ pos = self.GetCurrentPos()
+
+ # Tips
+ if event.ShiftDown():
+ self.CallTipSetBackground("yellow")
+ self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
+ 'show some suff, maybe parameters..\n\n'
+ 'fubar(param1, param2)')
+ # Code completion
+ else:
+ #lst = []
+ #for x in range(50000):
+ # lst.append('%05d' % x)
+ #st = " ".join(lst)
+ #print len(st)
+ #self.AutoCompShow(0, st)
+
+ kw = keyword.kwlist[:]
+ kw.append("zzzzzz?2")
+ kw.append("aaaaa?2")
+ kw.append("__init__?3")
+ kw.append("zzaaaaa?2")
+ kw.append("zzbaaaa?2")
+ kw.append("this_is_a_longer_value")
+ #kw.append("this_is_a_much_much_much_much_much_much_much_longer_value")
+
+ kw.sort() # Python sorts are case sensitive
+ self.AutoCompSetIgnoreCase(False) # so this needs to match
+
+ # Images are specified with a appended "?type"
+ for i in range(len(kw)):
+ if kw[i] in keyword.kwlist:
+ kw[i] = kw[i] + "?1"
+
+ self.AutoCompShow(0, " ".join(kw))
+ else:
+ event.Skip()
+
+
+ def OnUpdateUI(self, evt):
+ # check for matching braces
+ braceAtCaret = -1
+ braceOpposite = -1
+ charBefore = None
+ caretPos = self.GetCurrentPos()
+
+ if caretPos > 0:
+ charBefore = self.GetCharAt(caretPos - 1)
+ styleBefore = self.GetStyleAt(caretPos - 1)
+
+ # check before
+ if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
+ braceAtCaret = caretPos - 1
+
+ # check after
+ if braceAtCaret < 0:
+ charAfter = self.GetCharAt(caretPos)
+ styleAfter = self.GetStyleAt(caretPos)
+
+ if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
+ braceAtCaret = caretPos
+
+ if braceAtCaret >= 0:
+ braceOpposite = self.BraceMatch(braceAtCaret)
+
+ if braceAtCaret != -1 and braceOpposite == -1:
+ self.BraceBadLight(braceAtCaret)
+ else:
+ self.BraceHighlight(braceAtCaret, braceOpposite)
+ #pt = self.PointFromPosition(braceOpposite)
+ #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
+ #print pt
+ #self.Refresh(False)
+
+
+ def OnMarginClick(self, evt):
+ # fold and unfold as needed
+ if evt.GetMargin() == 2:
+ if evt.GetShift() and evt.GetControl():
+ self.FoldAll()
+ else:
+ lineClicked = self.LineFromPosition(evt.GetPosition())
+
+ if self.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
+ if evt.GetShift():
+ self.SetFoldExpanded(lineClicked, True)
+ self.Expand(lineClicked, True, True, 1)
+ elif evt.GetControl():
+ if self.GetFoldExpanded(lineClicked):
+ self.SetFoldExpanded(lineClicked, False)
+ self.Expand(lineClicked, False, True, 0)
+ else:
+ self.SetFoldExpanded(lineClicked, True)
+ self.Expand(lineClicked, True, True, 100)
+ else:
+ self.ToggleFold(lineClicked)
+
+
+ def FoldAll(self):
+ lineCount = self.GetLineCount()
+ expanding = True
+
+ # find out if we are folding or unfolding
+ for lineNum in range(lineCount):
+ if self.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
+ expanding = not self.GetFoldExpanded(lineNum)
+ break;
+
+ lineNum = 0
+
+ while lineNum < lineCount:
+ level = self.GetFoldLevel(lineNum)
+ if level & stc.STC_FOLDLEVELHEADERFLAG and \
+ (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
+
+ if expanding:
+ self.SetFoldExpanded(lineNum, True)
+ lineNum = self.Expand(lineNum, True)
+ lineNum = lineNum - 1
+ else:
+ lastChild = self.GetLastChild(lineNum, -1)
+ self.SetFoldExpanded(lineNum, False)
+
+ if lastChild > lineNum:
+ self.HideLines(lineNum+1, lastChild)
+
+ lineNum = lineNum + 1
+
+
+
+ def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
+ lastChild = self.GetLastChild(line, level)
+ line = line + 1
+
+ while line <= lastChild:
+ if force:
+ if visLevels > 0:
+ self.ShowLines(line, line)
+ else:
+ self.HideLines(line, line)
+ else:
+ if doExpand:
+ self.ShowLines(line, line)
+
+ if level == -1:
+ level = self.GetFoldLevel(line)
+
+ if level & stc.STC_FOLDLEVELHEADERFLAG:
+ if force:
+ if visLevels > 1:
+ self.SetFoldExpanded(line, True)
+ else:
+ self.SetFoldExpanded(line, False)
+
+ line = self.Expand(line, doExpand, force, visLevels-1)
+
+ else:
+ if doExpand and self.GetFoldExpanded(line):
+ line = self.Expand(line, True, force, visLevels-1)
+ else:
+ line = self.Expand(line, False, force, visLevels-1)
+ else:
+ line = line + 1;
+
+ return line
+
+
+#----------------------------------------------------------------------
+
+_USE_PANEL = 1
+
+def runTest(frame, nb, log):
+ if not _USE_PANEL:
+ ed = p = PythonSTC(nb, -1)
+ else:
+ p = wx.Panel(nb, -1, style = wx.NO_FULL_REPAINT_ON_RESIZE)
+ ed = PythonSTC(p, -1)
+ s = wx.BoxSizer(wx.HORIZONTAL)
+ s.Add(ed, 1, wx.EXPAND)
+ p.SetSizer(s)
+ p.SetAutoLayout(True)
+
+
+ ed.SetText(demoText + open('Main.py').read())
+ ed.EmptyUndoBuffer()
+ ed.Colourise(0, -1)
+
+ # line numbers in the margin
+ ed.SetMarginType(1, stc.STC_MARGIN_NUMBER)
+ ed.SetMarginWidth(1, 25)
+
+ return p
+
+
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a>
+and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should
+be helpful.
+</body><html>
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+
+
+
+
+#----------------------------------------------------------------------
+#----------------------------------------------------------------------
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import sys
+import wx
+
+#---------------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def OnSetFocus(self, evt):
+ print "OnSetFocus"
+ evt.Skip()
+ def OnKillFocus(self, evt):
+ print "OnKillFocus"
+ evt.Skip()
+ def OnWindowDestroy(self, evt):
+ print "OnWindowDestroy"
+ evt.Skip()
+
+
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ l1 = wx.StaticText(self, -1, "wx.TextCtrl")
+ t1 = wx.TextCtrl(self, -1, "Test it out and see", size=(125, -1))
+ t1.SetInsertionPoint(0)
+ self.tc1 = t1
+
+ self.Bind(wx.EVT_TEXT, self.EvtText, t1)
+ t1.Bind(wx.EVT_CHAR, self.EvtChar)
+ t1.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
+ t1.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
+ t1.Bind(wx.EVT_WINDOW_DESTROY, self.OnWindowDestroy)
+
+ l2 = wx.StaticText(self, -1, "Password")
+ t2 = wx.TextCtrl(self, -1, "", size=(125, -1), style=wx.TE_PASSWORD)
+ self.Bind(wx.EVT_TEXT, self.EvtText, t2)
+
+ l3 = wx.StaticText(self, -1, "Multi-line")
+ t3 = wx.TextCtrl(self, -1,
+ "Here is a looooooooooooooong line of text set in the control.\n\n"
+ "The quick brown fox jumped over the lazy dog...",
+ size=(200, 100), style=wx.TE_MULTILINE)
+
+ t3.SetInsertionPoint(0)
+ self.Bind(wx.EVT_TEXT, self.EvtText, t3)
+ b = wx.Button(self, -1, "Test Replace")
+ self.Bind(wx.EVT_BUTTON, self.OnTestReplace, b)
+ b2 = wx.Button(self, -1, "Test GetSelection")
+ self.Bind(wx.EVT_BUTTON, self.OnTestGetSelection, b2)
+ b3 = wx.Button(self, -1, "Test WriteText")
+ self.Bind(wx.EVT_BUTTON, self.OnTestWriteText, b3)
+ self.tc = t3
+
+
+ l4 = wx.StaticText(self, -1, "Rich Text")
+ t4 = wx.TextCtrl(self, -1, "If supported by the native control, this is red, and this is a different font.",
+ size=(200, 100), style=wx.TE_MULTILINE|wx.TE_RICH2)
+ t4.SetInsertionPoint(0)
+ t4.SetStyle(44, 47, wx.TextAttr("RED", "YELLOW"))
+ points = t4.GetFont().GetPointSize() # get the current size
+ f = wx.Font(points+3, wx.ROMAN, wx.ITALIC, wx.BOLD, True)
+ t4.SetStyle(63, 77, wx.TextAttr("BLUE", wx.NullColour, f))
+
+ l5 = wx.StaticText(self, -1, "Test Positions")
+ t5 = wx.TextCtrl(self, -1, "0123456789\n" * 5, size=(200, 100),
+ style = wx.TE_MULTILINE
+ #| wx.TE_RICH
+ | wx.TE_RICH2
+ )
+ t5.Bind(wx.EVT_LEFT_DOWN, self.OnT5LeftDown)
+ self.t5 = t5
+
+ bsizer = wx.BoxSizer(wx.VERTICAL)
+ bsizer.Add(b, 0, wx.GROW|wx.ALL, 4)
+ bsizer.Add(b2, 0, wx.GROW|wx.ALL, 4)
+ bsizer.Add(b3, 0, wx.GROW|wx.ALL, 4)
+
+ sizer = wx.FlexGridSizer(cols=3, hgap=6, vgap=6)
+ sizer.AddMany([ l1, t1, (0,0),
+ l2, t2, (0,0),
+ l3, t3, bsizer,
+ l4, t4, (0,0),
+ l5, t5, (0,0),
+ ])
+ border = wx.BoxSizer(wx.VERTICAL)
+ border.Add(sizer, 0, wx.ALL, 25)
+ self.SetSizer(border)
+ self.SetAutoLayout(True)
+
+
+ def EvtText(self, event):
+ self.log.WriteText('EvtText: %s\n' % event.GetString())
+
+
+ def EvtChar(self, event):
+ self.log.WriteText('EvtChar: %d\n' % event.GetKeyCode())
+ event.Skip()
+
+
+ def OnTestReplace(self, evt):
+ self.tc.Replace(5, 9, "IS A")
+ #self.tc.Remove(5, 9)
+
+ def OnTestWriteText(self, evt):
+ self.tc.WriteText("TEXT")
+
+ def OnTestGetSelection(self, evt):
+ start, end = self.tc.GetSelection()
+ text = self.tc.GetValue()
+ if wx.Platform == "__WXMSW__": # This is why GetStringSelection was added
+ text = text.replace('\n', '\r\n')
+
+ self.log.write("multi-line GetSelection(): (%d, %d)\n"
+ "\tGetStringSelection(): %s\n"
+ "\tSelectedText: %s\n" %
+ (start, end,
+ self.tc.GetStringSelection(),
+ repr(text[start:end])))
+
+ start, end = self.tc1.GetSelection()
+ text = self.tc1.GetValue()
+
+ if wx.Platform == "__WXMSW__": # This is why GetStringSelection was added
+ text = text.replace('\n', '\r\n')
+
+ self.log.write("single-line GetSelection(): (%d, %d)\n"
+ "\tGetStringSelection(): %s\n"
+ "\tSelectedText: %s\n" %
+ (start, end,
+ self.tc1.GetStringSelection(),
+ repr(text[start:end])))
+
+
+ def OnT5LeftDown(self, evt):
+ evt.Skip()
+ wx.CallAfter(self.LogT5Position, evt)
+
+ def LogT5Position(self, evt):
+ text = self.t5.GetValue()
+ ip = self.t5.GetInsertionPoint()
+ lp = self.t5.GetLastPosition()
+ self.log.write("LogT5Position:\n"
+ "\tGetInsertionPoint:\t%d\n"
+ "\ttext[insertionpoint]:\t%s\n"
+ "\tGetLastPosition:\t%d\n"
+ "\tlen(text):\t\t%d\n"
+ % (ip, text[ip], lp, len(text)))
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+overview = """\
+A text control allows text to be displayed and (possibly) edited. It may be single
+line or multi-line, support styles or not, be read-only or not, and even supports
+text masking for such things as passwords.
+
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ dlg = wx.TextEntryDialog(
+ frame, 'What is your favorite programming language?',
+ 'Duh??', 'Python')
+
+ dlg.SetValue("Python is the best!")
+
+ if dlg.ShowModal() == wx.ID_OK:
+ log.WriteText('You entered: %s\n' % dlg.GetValue())
+
+ dlg.Destroy()
+
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+This class represents a dialog that requests a one-line text string from the user.
+It is implemented as a generic wxWindows dialog. Along with the usual wxDialog
+style flags, all of the wxTextCtrl TE_* style flags are accepted, so, for example,
+wx.TE_PASSWORD could be used to create a password dialog.
+
+As with other dialogs of this type, the user input must be retrieved prior to
+destroying the dialog.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wx renamer needed for timectrl lib
+# o presense of spin control causing probs (see spin ctrl demo for details)
+#
+# 12/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o New binders applied. Issues still exist.
+#
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxTimeCtrl -> TimeCtrl
+# o wxScrolledPanel -> ScrolledPanel
+#
+
+import wx
+import wx.lib.timectrl as timectl
+import wx.lib.scrolledpanel as scrolled
+
+#----------------------------------------------------------------------
+
+class TestPanel( scrolled.ScrolledPanel ):
+ def __init__( self, parent, log ):
+
+ scrolled.ScrolledPanel.__init__( self, parent, -1 )
+ self.log = log
+
+
+ text1 = wx.StaticText( self, -1, "12-hour format:")
+ self.time12 = timectl.TimeCtrl( self, -1, name="12 hour control" )
+ spin1 = wx.SpinButton( self, -1, wx.DefaultPosition, (-1,20), 0 )
+ self.time12.BindSpinButton( spin1 )
+
+ text2 = wx.StaticText( self, -1, "24-hour format:")
+ spin2 = wx.SpinButton( self, -1, wx.DefaultPosition, (-1,20), 0 )
+ self.time24 = timectl.TimeCtrl(
+ self, -1, name="24 hour control", fmt24hr=True,
+ spinButton = spin2
+ )
+
+ text3 = wx.StaticText( self, -1, "No seconds\nor spin button:")
+ self.spinless_ctrl = timectl.TimeCtrl(
+ self, -1, name="spinless control",
+ display_seconds = False
+ )
+
+ grid = wx.FlexGridSizer( 0, 2, 10, 5 )
+ grid.Add( text1, 0, wx.ALIGN_RIGHT )
+ hbox1 = wx.BoxSizer( wx.HORIZONTAL )
+ hbox1.Add( self.time12, 0, wx.ALIGN_CENTRE )
+ hbox1.Add( spin1, 0, wx.ALIGN_CENTRE )
+ grid.Add( hbox1, 0, wx.LEFT )
+
+ grid.Add( text2, 0, wx.ALIGN_RIGHT|wx.TOP|wx.BOTTOM )
+ hbox2 = wx.BoxSizer( wx.HORIZONTAL )
+ hbox2.Add( self.time24, 0, wx.ALIGN_CENTRE )
+ hbox2.Add( spin2, 0, wx.ALIGN_CENTRE )
+ grid.Add( hbox2, 0, wx.LEFT )
+
+ grid.Add( text3, 0, wx.ALIGN_RIGHT|wx.TOP|wx.BOTTOM )
+ grid.Add( self.spinless_ctrl, 0, wx.LEFT )
+
+
+ buttonChange = wx.Button( self, -1, "Change Controls")
+ self.radio12to24 = wx.RadioButton(
+ self, -1, "Copy 12-hour time to 24-hour control",
+ wx.DefaultPosition, wx.DefaultSize, wx.RB_GROUP
+ )
+
+ self.radio24to12 = wx.RadioButton(
+ self, -1, "Copy 24-hour time to 12-hour control"
+ )
+
+ self.radioWx = wx.RadioButton( self, -1, "Set controls to 'now' using wxDateTime")
+ self.radioMx = wx.RadioButton( self, -1, "Set controls to 'now' using mxDateTime")
+
+ radio_vbox = wx.BoxSizer( wx.VERTICAL )
+ radio_vbox.Add( self.radio12to24, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ radio_vbox.Add( self.radio24to12, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ radio_vbox.Add( self.radioWx, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ radio_vbox.Add( self.radioMx, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+
+ box_label = wx.StaticBox( self, -1, "Change Controls through API" )
+ buttonbox = wx.StaticBoxSizer( box_label, wx.HORIZONTAL )
+ buttonbox.Add( buttonChange, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+ buttonbox.Add( radio_vbox, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+
+ hbox = wx.BoxSizer( wx.HORIZONTAL )
+ hbox.Add( grid, 0, wx.ALIGN_LEFT|wx.ALL, 15 )
+ hbox.Add( buttonbox, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 20 )
+
+
+ box_label = wx.StaticBox( self, -1, "Bounds Control" )
+ boundsbox = wx.StaticBoxSizer( box_label, wx.HORIZONTAL )
+ self.set_bounds = wx.CheckBox( self, -1, "Set time bounds:" )
+
+ minlabel = wx.StaticText( self, -1, "minimum time:" )
+ self.min = timectl.TimeCtrl( self, -1, name="min", display_seconds = False )
+ self.min.Enable( False )
+
+ maxlabel = wx.StaticText( self, -1, "maximum time:" )
+ self.max = timectl.TimeCtrl( self, -1, name="max", display_seconds = False )
+ self.max.Enable( False )
+
+ self.limit_check = wx.CheckBox( self, -1, "Limit control" )
+
+ label = wx.StaticText( self, -1, "Resulting time control:" )
+ self.target_ctrl = timectl.TimeCtrl( self, -1, name="new" )
+
+ grid2 = wx.FlexGridSizer( 0, 2, 0, 0 )
+ grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid2.Add( self.set_bounds, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid3 = wx.FlexGridSizer( 0, 2, 5, 5 )
+ grid3.Add(minlabel, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL )
+ grid3.Add( self.min, 0, wx.ALIGN_LEFT )
+ grid3.Add(maxlabel, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL )
+ grid3.Add( self.max, 0, wx.ALIGN_LEFT )
+ grid2.Add(grid3, 0, wx.ALIGN_LEFT )
+
+ grid2.Add( self.limit_check, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+ grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ grid2.Add( label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
+ grid2.Add( self.target_ctrl, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+ boundsbox.Add(grid2, 0, wx.ALIGN_CENTER|wx.EXPAND|wx.ALL, 5)
+
+ vbox = wx.BoxSizer( wx.VERTICAL )
+ vbox.Add( (20, 20) )
+ vbox.Add( hbox, 0, wx.ALIGN_LEFT|wx.ALL, 5)
+ vbox.Add( boundsbox, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
+
+
+ outer_box = wx.BoxSizer( wx.VERTICAL )
+ outer_box.Add( vbox, 0, wx.ALIGN_LEFT|wx.ALL, 5)
+
+
+ # Turn on mxDateTime option only if we can import the module:
+ try:
+ from mx import DateTime
+ except ImportError:
+ self.radioMx.Enable( False )
+
+
+ self.SetAutoLayout( True )
+ self.SetSizer( outer_box )
+ outer_box.Fit( self )
+ self.SetupScrolling()
+
+ self.Bind(wx.EVT_BUTTON, self.OnButtonClick, buttonChange )
+ self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.time12 )
+ self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.time24 )
+ self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.spinless_ctrl )
+ self.Bind(wx.EVT_CHECKBOX, self.OnBoundsCheck, self.set_bounds )
+ self.Bind(wx.EVT_CHECKBOX, self.SetTargetMinMax, self.limit_check )
+ self.Bind(timectl.EVT_TIMEUPDATE, self.SetTargetMinMax, self.min )
+ self.Bind(timectl.EVT_TIMEUPDATE, self.SetTargetMinMax, self.max )
+ self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.target_ctrl )
+
+
+ def OnTimeChange( self, event ):
+ timectrl = self.FindWindowById( event.GetId() )
+ ib_str = [ " (out of bounds)", "" ]
+
+ self.log.write('%s time = %s%s\n' % ( timectrl.GetName(), timectrl.GetValue(), ib_str[ timectrl.IsInBounds() ] ) )
+
+
+ def OnButtonClick( self, event ):
+ if self.radio12to24.GetValue():
+ self.time24.SetValue( self.time12.GetValue() )
+
+ elif self.radio24to12.GetValue():
+ self.time12.SetValue( self.time24.GetValue() )
+
+ elif self.radioWx.GetValue():
+ now = wx.DateTime_Now()
+ self.time12.SetValue( now )
+ # (demonstrates that G/SetValue returns/takes a wxDateTime)
+ self.time24.SetValue( self.time12.GetValue(as_wxDateTime=True) )
+
+ # (demonstrates that G/SetValue returns/takes a wxTimeSpan)
+ self.spinless_ctrl.SetValue( self.time12.GetValue(as_wxTimeSpan=True) )
+
+ elif self.radioMx.GetValue():
+ from mx import DateTime
+ now = DateTime.now()
+ self.time12.SetValue( now )
+
+ # (demonstrates that G/SetValue returns/takes a DateTime)
+ self.time24.SetValue( self.time12.GetValue(as_mxDateTime=True) )
+
+ # (demonstrates that G/SetValue returns/takes a DateTimeDelta)
+ self.spinless_ctrl.SetValue( self.time12.GetValue(as_mxDateTimeDelta=True) )
+
+
+ def OnBoundsCheck( self, event ):
+ self.min.Enable( self.set_bounds.GetValue() )
+ self.max.Enable( self.set_bounds.GetValue() )
+ self.SetTargetMinMax()
+
+
+ def SetTargetMinMax( self, event=None ):
+ min = None
+ max = None
+
+ if self.set_bounds.GetValue():
+ min = self.min.GetWxDateTime()
+ max = self.max.GetWxDateTime()
+ else:
+ min, max = None, None
+
+ cur_min, cur_max = self.target_ctrl.GetBounds()
+
+ # jmg - A little expirimental change to ensure that min
+ # or max contain valid values before we use them
+ if min and (min != cur_min): self.target_ctrl.SetMin( min )
+ if max and (max != cur_max): self.target_ctrl.SetMax( max )
+
+ self.target_ctrl.SetLimited( self.limit_check.GetValue() )
+
+ if min != cur_min or max != cur_max:
+ new_min, new_max = self.target_ctrl.GetBounds()
+
+ if new_min and new_max:
+ self.log.write( "current min, max: (%s, %s)\n" % ( new_min.FormatTime(), new_max.FormatTime() ) )
+ else:
+ self.log.write( "current min, max: (None, None)\n" )
+
+#----------------------------------------------------------------------
+
+def runTest( frame, nb, log ):
+ win = TestPanel( nb, log )
+ return win
+
+#----------------------------------------------------------------------
+
+overview = timectl.__doc__
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import time
+import wx
+
+#---------------------------------------------------------------------------
+
+## For your convenience; an example of creating your own timer class.
+##
+## class TestTimer(wxTimer):
+## def __init__(self, log = None):
+## wxTimer.__init__(self)
+## self.log = log
+## def Notify(self):
+## wxBell()
+## if self.log:
+## self.log.WriteText('beep!\n')
+
+#---------------------------------------------------------------------------
+
+ID_Start = wx.NewId()
+ID_Stop = wx.NewId()
+ID_Timer = wx.NewId()
+ID_Timer2 = wx.NewId()
+
+class TestTimerWin(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ wx.StaticText(self, -1, "This is a timer example", (15, 30))
+ wx.Button(self, ID_Start, ' Start ', (15, 75), wx.DefaultSize)
+ wx.Button(self, ID_Stop, ' Stop ', (115, 75), wx.DefaultSize)
+
+ self.timer = wx.Timer(self, # object to send the event to
+ ID_Timer) # event id to use
+
+ self.timer2 = wx.Timer(self, # object to send the event to
+ ID_Timer2) # event id to use
+
+ self.Bind(wx.EVT_BUTTON, self.OnStart, id=ID_Start)
+ self.Bind(wx.EVT_BUTTON, self.OnStop, id=ID_Stop)
+ self.Bind(wx.EVT_TIMER, self.OnTimer, id=ID_Timer)
+ self.Bind(wx.EVT_TIMER, self.OnTimer2, id=ID_Timer2)
+
+ def OnStart(self, event):
+ self.timer.Start(1000)
+ self.timer2.Start(1500)
+
+ def OnStop(self, event):
+ self.timer.Stop()
+ self.timer2.Stop()
+
+ def OnTimer(self, event):
+ wx.Bell()
+ if self.log:
+ self.log.WriteText('beep!\n')
+
+ def OnTimer2(self, event):
+ wx.Bell()
+ if self.log:
+ self.log.WriteText('beep 2!\n')
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestTimerWin(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+The wxTimer class allows you to execute code at specified intervals from
+within the wxPython event loop. Timers can be one-shot or repeating.
+
+"""
+
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+haveToggleBtn = 1
+
+try:
+ wx.ToggleButton
+except NameError:
+ haveToggleBtn = 0
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+ panel = wx.Panel(self, -1)
+ buttons = wx.BoxSizer(wx.HORIZONTAL)
+
+ for word in "These are toggle buttons".split():
+ b = wx.ToggleButton(panel, -1, word)
+ self.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggle, b)
+ buttons.Add(b, flag=wx.ALL, border=5)
+
+ panel.SetAutoLayout(True)
+ panel.SetSizer(buttons)
+ buttons.Fit(panel)
+ panel.Move((50,50))
+
+ def OnToggle(self, evt):
+ self.log.write("Button %d toggled\n" % evt.GetId())
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ if haveToggleBtn:
+ win = TestPanel(nb, log)
+ return win
+ else:
+ dlg = wx.MessageDialog(frame, 'wxToggleButton is not available on this platform.',
+ 'Sorry', wx.OK | wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+wxToggleButton is a button that stays pressed when clicked by the user.
+In other words, it is similar to wxCheckBox in functionality but looks like a
+wxButton.
+
+This class is only available under wxMSW and wxGTK currently.
+
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import images
+
+#---------------------------------------------------------------------------
+
+class TestToolBar(wx.Frame):
+ def __init__(self, parent, log):
+ wx.Frame.__init__(self, parent, -1, 'Test ToolBar', size=(500, 300))
+ self.log = log
+ self.timer = None
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+ wx.Window(self, -1).SetBackgroundColour(wx.NamedColour("WHITE"))
+
+ # Use the wxFrame internals to create the toolbar and associate it all
+ # in one tidy method call.
+ tb = self.CreateToolBar( wx.TB_HORIZONTAL
+ | wx.NO_BORDER
+ | wx.TB_FLAT
+ | wx.TB_TEXT
+ )
+
+ # Here's a 'simple' toolbar example, and how to bind it using SetToolBar()
+ #tb = wx.ToolBarSimple(self, -1, wx.DefaultPosition, wx.DefaultSize,
+ # wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
+ #self.SetToolBar(tb)
+ # But we're doing it a different way here.
+
+ log.write("Default toolbar tool size: %s\n" % tb.GetToolBitmapSize())
+
+ self.CreateStatusBar()
+
+ tb.AddSimpleTool(10, images.getNewBitmap(), "New", "Long help for 'New'")
+ #tb.AddLabelTool(10, "New", images.getNewBitmap(), shortHelp="New", longHelp="Long help for 'New'")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=10)
+
+ tb.AddSimpleTool(20, images.getOpenBitmap(), "Open", "Long help for 'Open'")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=20)
+
+ tb.AddSeparator()
+ tb.AddSimpleTool(30, images.getCopyBitmap(), "Copy", "Long help for 'Copy'")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=30)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=30)
+
+ tb.AddSimpleTool(40, images.getPasteBitmap(), "Paste", "Long help for 'Paste'")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=40)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=40)
+
+ tb.AddSeparator()
+
+ tool = tb.AddCheckTool(50, images.getTog1Bitmap(),
+ shortHelp="Toggle this")
+ self.Bind(wx.EVT_TOOL, self.OnToolClick, id=50)
+
+## tb.AddCheckTool(60, images.getTog1Bitmap(), images.getTog2Bitmap(),
+## shortHelp="Toggle with 2 bitmaps")
+## self.Bind(EVT_TOOL, self.OnToolClick, id=60)
+
+ self.Bind(wx.EVT_TOOL_ENTER, self.OnToolEnter)
+ self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick) # Match all
+ self.Bind(wx.EVT_TIMER, self.OnClearSB)
+
+ tb.AddSeparator()
+ cbID = wx.NewId()
+
+ tb.AddControl(
+ wx.ComboBox(
+ tb, cbID, "", choices=["", "This", "is a", "wxComboBox"],
+ size=(150,-1), style=wx.CB_DROPDOWN
+ ))
+
+ self.Bind(wx.EVT_COMBOBOX, self.OnCombo, id=cbID)
+ tb.AddControl(wx.TextCtrl(tb, -1, "Toolbar controls!!", size=(150, -1)))
+
+ # Final thing to do for a toolbar is call the Realize() method. This
+ # causes it to render (more or less, that is).
+ tb.Realize()
+
+
+ def OnToolClick(self, event):
+ self.log.WriteText("tool %s clicked\n" % event.GetId())
+ tb = self.GetToolBar()
+ tb.EnableTool(10, not tb.GetToolEnabled(10))
+
+ def OnToolRClick(self, event):
+ self.log.WriteText("tool %s right-clicked\n" % event.GetId())
+
+ def OnCombo(self, event):
+ self.log.WriteText("combobox item selected: %s\n" % event.GetString())
+
+ def OnToolEnter(self, event):
+ self.log.WriteText('OnToolEnter: %s, %s\n' % (event.GetId(), event.GetInt()))
+
+ if self.timer is None:
+ self.timer = wx.Timer(self)
+
+ if self.timer.IsRunning():
+ self.timer.Stop()
+
+ self.timer.Start(2000)
+ event.Skip()
+
+
+ def OnClearSB(self, event): # called for the timer event handler
+ self.SetStatusText("")
+ self.timer.Stop()
+ self.timer = None
+
+
+ def OnCloseWindow(self, event):
+ if self.timer is not None:
+ self.timer.Stop()
+ self.timer = None
+ self.Destroy()
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestToolBar(frame, log)
+ frame.otherWin = win
+ win.Show(True)
+
+#---------------------------------------------------------------------------
+
+
+
+overview = """\
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import string
+import wx
+import images
+
+#---------------------------------------------------------------------------
+
+class MyTreeCtrl(wx.TreeCtrl):
+ def __init__(self, parent, id, pos, size, style, log):
+ wx.TreeCtrl.__init__(self, parent, id, pos, size, style)
+ self.log = log
+
+ def OnCompareItems(self, item1, item2):
+ t1 = self.GetItemText(item1)
+ t2 = self.GetItemText(item2)
+ self.log.WriteText('compare: ' + t1 + ' <> ' + t2 + '\n')
+ if t1 < t2: return -1
+ if t1 == t2: return 0
+ return 1
+
+#---------------------------------------------------------------------------
+
+class TestTreeCtrlPanel(wx.Panel):
+ def __init__(self, parent, log):
+ # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
+ wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+
+ self.log = log
+ tID = wx.NewId()
+
+ self.tree = MyTreeCtrl(self, tID, wx.DefaultPosition, wx.DefaultSize,
+ wx.TR_HAS_BUTTONS
+ | wx.TR_EDIT_LABELS
+ #| wx.TR_MULTIPLE
+ #| wx.TR_HIDE_ROOT
+ , self.log)
+
+ isz = (16,16)
+ il = wx.ImageList(isz[0], isz[1])
+ fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
+ fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
+ fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_REPORT_VIEW, wx.ART_OTHER, isz))
+ smileidx = il.Add(images.getSmilesBitmap())
+
+ self.tree.SetImageList(il)
+ self.il = il
+
+ # NOTE: For some reason tree items have to have a data object in
+ # order to be sorted. Since our compare just uses the labels
+ # we don't need any real data, so we'll just use None below for
+ # the item data.
+
+ self.root = self.tree.AddRoot("The Root Item")
+ self.tree.SetPyData(self.root, None)
+ self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded)
+
+
+ for x in range(15):
+ child = self.tree.AppendItem(self.root, "Item %d" % x)
+ self.tree.SetPyData(child, None)
+ self.tree.SetItemImage(child, fldridx, wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(child, fldropenidx, wx.TreeItemIcon_Expanded)
+
+ for y in range(5):
+ last = self.tree.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y)))
+ self.tree.SetPyData(last, None)
+ self.tree.SetItemImage(last, fldridx, wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(last, fldropenidx, wx.TreeItemIcon_Expanded)
+
+ for z in range(5):
+ item = self.tree.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z))
+ self.tree.SetPyData(item, None)
+ self.tree.SetItemImage(item, fileidx, wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(item, smileidx, wx.TreeItemIcon_Selected)
+
+ self.tree.Expand(self.root)
+ self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, self.tree)
+ self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.tree)
+ self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree)
+ self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.tree)
+ self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndEdit, self.tree)
+ self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate, self.tree)
+
+ self.tree.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
+ self.tree.Bind(wx.EVT_RIGHT_DOWN, self.OnRightClick)
+ self.tree.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
+
+
+
+ def OnRightClick(self, event):
+ pt = event.GetPosition();
+ item, flags = self.tree.HitTest(pt)
+ self.log.WriteText("OnRightClick: %s, %s, %s\n" %
+ (self.tree.GetItemText(item), type(item), item.__class__))
+ self.tree.SelectItem(item)
+
+
+ def OnRightUp(self, event):
+ pt = event.GetPosition();
+ item, flags = self.tree.HitTest(pt)
+ self.log.WriteText("OnRightUp: %s (manually starting label edit)\n"
+ % self.tree.GetItemText(item))
+ self.tree.EditLabel(item)
+
+
+
+ def OnBeginEdit(self, event):
+ self.log.WriteText("OnBeginEdit\n")
+ # show how to prevent edit...
+ if self.tree.GetItemText(event.GetItem()) == "The Root Item":
+ wx.Bell()
+ self.log.WriteText("You can't edit this one...\n")
+
+ # Lets just see what's visible of its children
+ cookie = 0
+ root = event.GetItem()
+ (child, cookie) = self.tree.GetFirstChild(root, cookie)
+
+ while child.IsOk():
+ self.log.WriteText("Child [%s] visible = %d" %
+ (self.tree.GetItemText(child),
+ self.tree.IsVisible(child)))
+ (child, cookie) = self.tree.GetNextChild(root, cookie)
+
+ event.Veto()
+
+
+ def OnEndEdit(self, event):
+ self.log.WriteText("OnEndEdit\n")
+ # show how to reject edit, we'll not allow any digits
+ for x in event.GetLabel():
+ if x in string.digits:
+ self.log.WriteText("You can't enter digits...\n")
+ event.Veto()
+ return
+
+
+ def OnLeftDClick(self, event):
+ pt = event.GetPosition();
+ item, flags = self.tree.HitTest(pt)
+ self.log.WriteText("OnLeftDClick: %s\n" % self.tree.GetItemText(item))
+ parent = self.tree.GetItemParent(item)
+ self.tree.SortChildren(parent)
+ event.Skip()
+
+
+ def OnSize(self, event):
+ w,h = self.GetClientSizeTuple()
+ self.tree.SetDimensions(0, 0, w, h)
+
+
+ def OnItemExpanded(self, event):
+ item = event.GetItem()
+ self.log.WriteText("OnItemExpanded: %s\n" % self.tree.GetItemText(item))
+
+ def OnItemCollapsed(self, event):
+ item = event.GetItem()
+ self.log.WriteText("OnItemCollapsed: %s\n" % self.tree.GetItemText(item))
+
+ def OnSelChanged(self, event):
+ self.item = event.GetItem()
+ self.log.WriteText("OnSelChanged: %s\n" % self.tree.GetItemText(self.item))
+ if wx.Platform == '__WXMSW__':
+ self.log.WriteText("BoundingRect: %s\n" %
+ self.tree.GetBoundingRect(self.item, True))
+ #items = self.tree.GetSelections()
+ #print map(self.tree.GetItemText, items)
+ event.Skip()
+
+
+ def OnActivate(self, event):
+ self.log.WriteText("OnActivate: %s\n" % self.tree.GetItemText(self.item))
+
+
+#---------------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestTreeCtrlPanel(nb, log)
+ return win
+
+#---------------------------------------------------------------------------
+
+
+
+
+
+overview = """\
+A tree control presents information as a hierarchy, with items that may be
+expanded to show further items. Items in a tree control are referenced by
+wxTreeItemId handles.
+
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import wx.gizmos as gizmos
+
+import images
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+ self.Bind(wx.EVT_SIZE, self.OnSize)
+
+ self.tree = gizmos.TreeListCtrl(self, -1, style = wx.TR_DEFAULT_STYLE
+ #| wx.TR_ROW_LINES
+ #| wx.TR_NO_LINES
+ #| wx.TR_TWIST_BUTTONS
+ )
+ isz = (16,16)
+ il = wx.ImageList(isz[0], isz[1])
+ fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
+ fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
+ fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_REPORT_VIEW, wx.ART_OTHER, isz))
+ smileidx = il.Add(images.getSmilesBitmap())
+
+ self.tree.SetImageList(il)
+ self.il = il
+
+ # create some columns
+ self.tree.AddColumn("Main column")
+ self.tree.AddColumn("Column 1")
+ self.tree.AddColumn("Column 2")
+ self.tree.SetMainColumn(0) # the one with the tree in it...
+ self.tree.SetColumnWidth(0, 175)
+
+
+ self.root = self.tree.AddRoot("The Root Item")
+ self.tree.SetItemText(self.root, "col 1 root", 1)
+ self.tree.SetItemText(self.root, "col 2 root", 2)
+ self.tree.SetItemImage(self.root, fldridx, which = wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(self.root, fldropenidx, which = wx.TreeItemIcon_Expanded)
+
+
+ for x in range(15):
+ txt = "Item %d" % x
+ child = self.tree.AppendItem(self.root, txt)
+ self.tree.SetItemText(child, txt + "(c1)", 1)
+ self.tree.SetItemText(child, txt + "(c2)", 2)
+ self.tree.SetItemImage(child, fldridx, which = wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(child, fldropenidx, which = wx.TreeItemIcon_Expanded)
+
+ for y in range(5):
+ txt = "item %d-%s" % (x, chr(ord("a")+y))
+ last = self.tree.AppendItem(child, txt)
+ self.tree.SetItemText(last, txt + "(c1)", 1)
+ self.tree.SetItemText(last, txt + "(c2)", 2)
+ self.tree.SetItemImage(last, fldridx, which = wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(last, fldropenidx, which = wx.TreeItemIcon_Expanded)
+
+ for z in range(5):
+ txt = "item %d-%s-%d" % (x, chr(ord("a")+y), z)
+ item = self.tree.AppendItem(last, txt)
+ self.tree.SetItemText(item, txt + "(c1)", 1)
+ self.tree.SetItemText(item, txt + "(c2)", 2)
+ self.tree.SetItemImage(item, fileidx, which = wx.TreeItemIcon_Normal)
+ self.tree.SetItemImage(item, smileidx, which = wx.TreeItemIcon_Selected)
+
+
+ self.tree.Expand(self.root)
+
+ self.tree.GetMainWindow().Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
+
+
+ def OnRightUp(self, evt):
+ # Convert the position from being relative to the subwindow to
+ # being relative to the outer treelist window so HitTest will
+ # have the point it is expecting.
+ pos = evt.GetPosition()
+ pos = self.tree.GetMainWindow().ClientToScreen(pos)
+ pos = self.tree.ScreenToClient(pos)
+ item, flags, col = self.tree.HitTest(pos)
+
+ if item:
+ print flags, col, self.tree.GetItemText(item, col)
+
+
+ def OnSize(self, evt):
+ self.tree.SetSize(self.GetSize())
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>wxTreeListCtrl</center></h2>
+
+The wx.TreeListCtrl is essentially a wx.TreeCtrl with extra columns,
+such that the look is similar to a wx.ListCtrl.
+
+</body></html>
+"""
+
+
+if __name__ == '__main__':
+ #raw_input("Press enter...")
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+#----------------------------------------------------------------------
+
+# The wxVListBox is much like a regular wxListBox except you draw the
+# items yourself and the items can vary in height.
+class MyVListBox(wx.VListBox):
+
+ # This method must be overridden. When called it should draw the
+ # n'th item on the dc within the rect. How it is drawn, and what
+ # is drawn is entirely up to you.
+ def OnDrawItem(self, dc, rect, n):
+ if self.GetSelection() == n:
+ c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
+ else:
+ c = self.GetForegroundColour()#wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
+ dc.SetTextForeground(c)
+ dc.DrawLabel(self._getItemText(n), rect,
+ wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
+
+ # This method must be overridden. It should return the height
+ # required to draw the n'th item.
+ def OnMeasureItem(self, n):
+ height = 0
+
+ for line in self._getItemText(n).split('\n'):
+ w, h = self.GetTextExtent(line)
+ height += h
+
+ return height + 5
+
+
+ # These are also overridable:
+ #
+ # OnDrawSeparator(dc, rect, n)
+ # Draw a separator between items. Note that rect may be reduced
+ # in size if desired so OnDrawItem gets a smaller rect.
+ #
+ # OnDrawBackground(dc, rect, n)
+ # Draw the background and maybe a border if desired.
+
+
+ def _getItemText(self, item):
+ if item % 2 == 0:
+ return "This is item# %d" % item
+ else:
+ return "This is item# %d\n with an extra line" % item
+
+#----------------------------------------------------------------------
+
+# The wx.HtmlListBox derives from wx.VListBox, but draws each item
+# itself as a wx.HtmlCell.
+class MyHtmlListBox(wx.HtmlListBox):
+
+ def OnGetItem(self, n):
+ if n % 2 == 0:
+ return "This is item# <b>%d</b>" % n
+ else:
+ return "This is item# <b>%d</b> <br>Any <font color='RED'>HTML</font> is okay." % n
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+ spacer = 50
+
+ vlb = MyVListBox(self, -1, size=(150, 250), style=wx.BORDER_SUNKEN)
+ vlb.SetItemCount(50)
+ vlb.SetSelection(0)
+ vlb.SetFocus()
+ vlbSizer = wx.BoxSizer(wx.VERTICAL)
+ vlbSizer.Add((spacer, spacer))
+ vlbSizer.Add(wx.StaticText(self, -1, "wx.VListBox"), 0, 5, wx.ALL)
+ vlbSizer.Add(vlb)
+
+ hlb = MyHtmlListBox(self, -1, size=(150, 250), style=wx.BORDER_SUNKEN)
+ hlb.SetItemCount(50)
+ hlb.SetSelection(0)
+ hlbSizer = wx.BoxSizer(wx.VERTICAL)
+ hlbSizer.Add((spacer, spacer))
+ hlbSizer.Add(wx.StaticText(self, -1, "wx.HtmlListBox"), 0, 5, wx.ALL)
+ hlbSizer.Add(hlb)
+
+ sizer = wx.BoxSizer(wx.HORIZONTAL)
+ sizer.Add((spacer, spacer))
+ sizer.Add(vlbSizer)
+ sizer.Add((spacer, spacer))
+ sizer.Add((spacer, spacer))
+ sizer.Add(hlbSizer)
+
+ self.SetSizer(sizer)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>wxVListBox and wxHtmlListBox</center></h2>
+<hr>
+
+The "V" in wxVListBox stands for both "virtual" because it can have an
+unlimited number of items since it doesn't store them itself, and
+"variable" since items can vary in height. It has much the same
+interface as wxListBox and also emits the same events so you can use
+the same EVT_LISTBOX function to connect a handler.
+<p>
+
+The wxHtmlListBox derives from wxVListBox, but draws each item itself
+as a wxHtmlCell. This means that you just need to provide a snippet
+of HTML for each item when requested.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import string
+import wx
+
+
+#----------------------------------------------------------------------
+
+ALPHA_ONLY = 1
+DIGIT_ONLY = 2
+
+class MyValidator(wx.PyValidator):
+ def __init__(self, flag=None, pyVar=None):
+ wx.PyValidator.__init__(self)
+ self.flag = flag
+ self.Bind(wx.EVT_CHAR, self.OnChar)
+
+ def Clone(self):
+ return MyValidator(self.flag)
+
+ def Validate(self, win):
+ tc = self.GetWindow()
+ val = tc.GetValue()
+
+ if self.flag == ALPHA_ONLY:
+ for x in val:
+ if x not in string.letters:
+ return False
+
+ elif self.flag == DIGIT_ONLY:
+ for x in val:
+ if x not in string.digits:
+ return False
+
+ return True
+
+
+ def OnChar(self, event):
+ key = event.KeyCode()
+
+ if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
+ event.Skip()
+ return
+
+ if self.flag == ALPHA_ONLY and chr(key) in string.letters:
+ event.Skip()
+ return
+
+ if self.flag == DIGIT_ONLY and chr(key) in string.digits:
+ event.Skip()
+ return
+
+ if not wx.Validator_IsSilent():
+ wx.Bell()
+
+ # Returning without calling even.Skip eats the event before it
+ # gets to the text control
+ return
+
+#----------------------------------------------------------------------
+
+class TestValidatorPanel(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent, -1)
+ self.SetAutoLayout(True)
+ VSPACE = 10
+
+ fgs = wx.FlexGridSizer(0, 2)
+
+ fgs.Add((1,1))
+ fgs.Add(wx.StaticText(self, -1, "These controls have validators that limit\n"
+ "the type of characters that can be entered."))
+
+ fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
+
+ label = wx.StaticText(self, -1, "Alpha Only: ")
+ fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
+
+ fgs.Add(wx.TextCtrl(self, -1, "", validator = MyValidator(ALPHA_ONLY)))
+
+ fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
+
+ label = wx.StaticText(self, -1, "Digits Only: ")
+ fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
+ fgs.Add(wx.TextCtrl(self, -1, "", validator = MyValidator(DIGIT_ONLY)))
+
+ fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
+ fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
+ fgs.Add((0,0))
+ b = wx.Button(self, -1, "Test Dialog Validation")
+ self.Bind(wx.EVT_BUTTON, self.OnDoDialog, b)
+ fgs.Add(b)
+
+ border = wx.BoxSizer()
+ border.Add(fgs, 1, wx.GROW|wx.ALL, 25)
+ self.SetSizer(border)
+ self.Layout()
+
+ def OnDoDialog(self, evt):
+ dlg = TestValidateDialog(self)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+#----------------------------------------------------------------------
+
+class TextObjectValidator(wx.PyValidator):
+ """ This validator is used to ensure that the user has entered something
+ into the text object editor dialog's text field.
+ """
+ def __init__(self):
+ """ Standard constructor.
+ """
+ wx.PyValidator.__init__(self)
+
+
+
+ def Clone(self):
+ """ Standard cloner.
+
+ Note that every validator must implement the Clone() method.
+ """
+ return TextObjectValidator()
+
+
+ def Validate(self, win):
+ """ Validate the contents of the given text control.
+ """
+ textCtrl = self.GetWindow()
+ text = textCtrl.GetValue()
+
+ if len(text) == 0:
+ wx.MessageBox("A text object must contain some text!", "Error")
+ textCtrl.SetBackgroundColour("pink")
+ textCtrl.SetFocus()
+ textCtrl.Refresh()
+ return False
+ else:
+ textCtrl.SetBackgroundColour(
+ wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
+ textCtrl.Refresh()
+ return True
+
+
+ def TransferToWindow(self):
+ """ Transfer data from validator to window.
+
+ The default implementation returns False, indicating that an error
+ occurred. We simply return True, as we don't do any data transfer.
+ """
+ return True # Prevent wxDialog from complaining.
+
+
+ def TransferFromWindow(self):
+ """ Transfer data from window to validator.
+
+ The default implementation returns False, indicating that an error
+ occurred. We simply return True, as we don't do any data transfer.
+ """
+ return True # Prevent wxDialog from complaining.
+
+#----------------------------------------------------------------------
+
+class TestValidateDialog(wx.Dialog):
+ def __init__(self, parent):
+ wx.Dialog.__init__(self, parent, -1, "Validated Dialog")
+
+ self.SetAutoLayout(True)
+ VSPACE = 10
+
+ fgs = wx.FlexGridSizer(0, 2)
+
+ fgs.Add((1,1));
+ fgs.Add(wx.StaticText(self, -1,
+ "These controls must have text entered into them. Each\n"
+ "one has a validator that is checked when the Okay\n"
+ "button is clicked."))
+
+ fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
+
+ label = wx.StaticText(self, -1, "First: ")
+ fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
+
+ fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator()))
+
+ fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
+
+ label = wx.StaticText(self, -1, "Second: ")
+ fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
+ fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator()))
+
+
+ buttons = wx.BoxSizer(wx.HORIZONTAL)
+ b = wx.Button(self, wx.ID_OK, "Okay")
+ b.SetDefault()
+ buttons.Add(b, 0, wx.ALL, 10)
+ buttons.Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 0, wx.ALL, 10)
+
+ border = wx.BoxSizer(wx.VERTICAL)
+ border.Add(fgs, 1, wx.GROW|wx.ALL, 25)
+ border.Add(buttons)
+ self.SetSizer(border)
+ border.Fit(self)
+ self.Layout()
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestValidatorPanel(nb)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """\
+<html>
+<body>
+wxValidator is the base class for a family of validator classes that mediate
+between a class of control, and application data.
+
+<p>A validator has three major roles:
+
+<p><ol>
+<li>to transfer data from a C++ variable or own storage to and from a control;
+<li>to validate data in a control, and show an appropriate error message;
+<li>to filter events (such as keystrokes), thereby changing the behaviour of the associated control.
+</ol>
+<p>Validators can be plugged into controls dynamically.
+</body>
+</html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+
+from Main import opj
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent):
+ wx.Panel.__init__(self, parent, -1)
+
+ b = wx.Button(self, -1, "Play Sound 1", (25, 25))
+ self.Bind(wx.EVT_BUTTON, self.OnButton1, b)
+
+ b = wx.Button(self, -1, "Play Sound 2", (25, 65))
+ self.Bind(wx.EVT_BUTTON, self.OnButton2, b)
+
+
+ def OnButton1(self, evt):
+ try:
+ wave = wx.Wave(opj('data/anykey.wav'))
+ wave.Play()
+ except NotImplementedError, v:
+ wx.MessageBox(str(v), "Exception Message")
+
+
+ def OnButton2(self, evt):
+ try:
+ wave = wx.Wave(opj('data/plan.wav'))
+ wave.Play()
+ except NotImplementedError, v:
+ wx.MessageBox(str(v), "Exception Message")
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb)
+ return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+This class represents a short wave file, in Windows WAV format, that can
+be stored in memory and played. Currently this class is implemented on Windows
+and GTK (Linux) only.
+
+This demo offers two examples, both driven by buttons, but obviously the event
+that drives the playing of the sound can come from anywhere.
+
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+# 11/3-/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o WizardPage* doesn't support GetId()
+#
+
+import wx
+import wx.wizard as wiz
+import images
+
+#----------------------------------------------------------------------
+
+def makePageTitle(wizPg, title):
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ wizPg.SetSizer(sizer)
+ title = wx.StaticText(wizPg, -1, title)
+ title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
+ sizer.AddWindow(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ sizer.AddWindow(wx.StaticLine(wizPg, -1), 0, wx.EXPAND|wx.ALL, 5)
+ return sizer
+
+#----------------------------------------------------------------------
+
+class TitledPage(wiz.WizardPageSimple):
+ def __init__(self, parent, title):
+ wiz.WizardPageSimple.__init__(self, parent)
+ self.sizer = makePageTitle(self, title)
+
+
+#----------------------------------------------------------------------
+
+class SkipNextPage(wiz.PyWizardPage):
+ def __init__(self, parent, title):
+ wiz.PyWizardPage.__init__(self, parent)
+ self.next = self.prev = None
+ self.sizer = makePageTitle(self, title)
+
+ self.cb = wx.CheckBox(self, -1, "Skip next page")
+ self.sizer.Add(self.cb, 0, wx.ALL, 5)
+
+ def SetNext(self, next):
+ self.next = next
+
+ def SetPrev(self, prev):
+ self.prev = prev
+
+
+ # Classes derived from wxPyWizardPanel must override
+ # GetNext and GetPrev, and may also override GetBitmap
+ # as well as all those methods overridable by
+ # wx.PyWindow.
+
+ def GetNext(self):
+ """If the checkbox is set then return the next page's next page"""
+ next = self.next
+ if self.cb.GetValue():
+ next = next.GetNext()
+ return next
+
+ def GetPrev(self):
+ return self.prev
+
+#----------------------------------------------------------------------
+
+class UseAltBitmapPage(wiz.PyWizardPage):
+ def __init__(self, parent, title):
+ wiz.PyWizardPage.__init__(self, parent)
+ self.next = self.prev = None
+ self.sizer = makePageTitle(self, title)
+
+ self.sizer.Add(wx.StaticText(self, -1, "This page uses a different bitmap"),
+ 0, wx.ALL, 5)
+
+ def SetNext(self, next):
+ self.next = next
+
+ def SetPrev(self, prev):
+ self.prev = prev
+
+ def GetNext(self):
+ return self.next
+
+ def GetPrev(self):
+ return self.prev
+
+ def GetBitmap(self):
+ # You usually wouldn't need to override this method
+ # since you can set a non-default bitmap in the
+ # wxWizardPageSimple constructor, but if you need to
+ # dynamically change the bitmap based on the
+ # contents of the wizard, or need to also change the
+ # next/prev order then it can be done by overriding
+ # GetBitmap.
+ return images.getWizTest2Bitmap()
+
+#----------------------------------------------------------------------
+
+class TestPanel(wx.Panel):
+ ID_wiz = wx.NewId()
+
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ b = wx.Button(self, -1, "Run Simple Wizard", pos=(50, 50))
+ self.Bind(wx.EVT_BUTTON, self.OnRunSimpleWizard, b)
+
+ b = wx.Button(self, -1, "Run Dynamic Wizard", pos=(50, 100))
+ self.Bind(wx.EVT_BUTTON, self.OnRunDynamicWizard, b)
+
+ wiz.EVT_WIZARD_PAGE_CHANGED(self, self.ID_wiz, self.OnWizPageChanged)
+ wiz.EVT_WIZARD_PAGE_CHANGING(self, self.ID_wiz, self.OnWizPageChanging)
+ wiz.EVT_WIZARD_CANCEL(self, self.ID_wiz, self.OnWizCancel)
+
+
+ def OnWizPageChanged(self, evt):
+ if evt.GetDirection():
+ dir = "forward"
+ else:
+ dir = "backward"
+
+ page = evt.GetPage()
+ self.log.write("OnWizPageChanged: %s, %s\n" % (dir, page.__class__))
+
+
+ def OnWizPageChanging(self, evt):
+ if evt.GetDirection():
+ dir = "forward"
+ else:
+ dir = "backward"
+
+ page = evt.GetPage()
+ self.log.write("OnWizPageChanging: %s, %s\n" % (dir, page.__class__))
+
+
+ def OnWizCancel(self, evt):
+ page = evt.GetPage()
+ self.log.write("OnWizCancel: %s\n" % page.__class__)
+
+ # Show how to prevent cancelling of the wizard. The
+ # other events can be Veto'd too.
+ if page is self.page1:
+ wx.MessageBox("Cancelling on the first page has been prevented.", "Sorry")
+ evt.Veto()
+
+ def OnWizFinished(self, evt):
+ self.log.write("OnWizFinished\n")
+
+
+ def OnRunSimpleWizard(self, evt):
+ # Create the wizard and the pages
+ wizard = wiz.Wizard(self, self.ID_wiz, "Simple Wizard",
+ images.getWizTest1Bitmap())
+ page1 = TitledPage(wizard, "Page 1")
+ page2 = TitledPage(wizard, "Page 2")
+ page3 = TitledPage(wizard, "Page 3")
+ page4 = TitledPage(wizard, "Page 4")
+ self.page1 = page1
+
+ page1.sizer.Add(wx.StaticText(page1, -1, """
+This wizard is totally useless, but is meant to show how to
+chain simple wizard pages together in a non-dynamic manner.
+IOW, the order of the pages never changes, and so the
+wxWizardPageSimple class can easily be used for the pages."""))
+ wizard.FitToPage(page1)
+ page4.sizer.Add(wx.StaticText(page4, -1, "\nThis is the last page."))
+
+ # Use the convenience Chain function to connect the pages
+ wiz.WizardPageSimple_Chain(page1, page2)
+ wiz.WizardPageSimple_Chain(page2, page3)
+ wiz.WizardPageSimple_Chain(page3, page4)
+
+ if wizard.RunWizard(page1):
+ wx.MessageBox("Wizard completed successfully", "That's all folks!")
+ else:
+ wx.MessageBox("Wizard was cancelled", "That's all folks!")
+
+
+
+ def OnRunDynamicWizard(self, evt):
+ # Create the wizard and the pages
+ #wizard = wx.PreWizard()
+ #wizard.SetExtraStyle(wx.WIZARD_EX_HELPBUTTON)
+ #wizard.Create(self, self.ID_wiz, "Simple Wizard",
+ # images.getWizTest1Bitmap())
+ wizard = wiz.Wizard(self, self.ID_wiz, "Simple Wizard",
+ images.getWizTest1Bitmap())
+
+ page1 = TitledPage(wizard, "Page 1")
+ page2 = SkipNextPage(wizard, "Page 2")
+ page3 = TitledPage(wizard, "Page 3")
+ page4 = UseAltBitmapPage(wizard, "Page 4")
+ page5 = TitledPage(wizard, "Page 5")
+ self.page1 = page1
+
+ page1.sizer.Add(wx.StaticText(page1, -1, """
+This wizard shows the ability to choose at runtime the order
+of the pages and also which bitmap is shown.
+"""))
+ wizard.FitToPage(page1)
+ page5.sizer.Add(wx.StaticText(page5, -1, "\nThis is the last page."))
+
+ # Set the initial order of the pages
+ page1.SetNext(page2)
+ page2.SetPrev(page1)
+ page2.SetNext(page3)
+ page3.SetPrev(page2)
+ page3.SetNext(page4)
+ page4.SetPrev(page3)
+ page4.SetNext(page5)
+ page5.SetPrev(page4)
+
+
+ if wizard.RunWizard(page1):
+ wx.MessageBox("Wizard completed successfully", "That's all folks!")
+ else:
+ wx.MessageBox("Wizard was cancelled", "That's all folks!")
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>wxWizard</center></h2>
+
+wxWizard is the central class for implementing 'wizard-like'
+dialogs. These dialogs are mostly familiar to Windows users and are
+nothing else but a sequence of 'pages' each of them displayed inside a
+dialog which has the buttons to pass to the next (and previous) pages.
+<p>
+The wizards are typically used to decompose a complex dialog into
+several simple steps and are mainly useful to the novice users, hence
+it is important to keep them as simple as possible.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import wx.xrc as xrc
+
+from Main import opj
+
+#----------------------------------------------------------------------
+
+RESFILE = opj("data/resource_wdr.xrc")
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ wx.Panel.__init__(self, parent, -1)
+ self.log = log
+
+ # make the components
+ label = wx.StaticText(self, -1, "The lower panel was built from this XML:")
+ label.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
+
+ resourceText = open(RESFILE).read()
+ text = wx.TextCtrl(self, -1, resourceText,
+ style=wx.TE_READONLY|wx.TE_MULTILINE)
+ text.SetInsertionPoint(0)
+
+ line = wx.StaticLine(self, -1)
+
+ # This shows a few different ways to load XML Resources
+ if 0:
+ # XML Resources can be loaded from a file like this:
+ res = xrc.XmlResource(RESFILE)
+
+ elif 1:
+ # or from a Virtual FileSystem:
+ wx.FileSystem_AddHandler(wx.MemoryFSHandler())
+ wx.MemoryFSHandler_AddFile("XRC_Resources/data_file", resourceText)
+ res = xrc.XmlResource("memory:XRC_Resources/data_file")
+
+ else:
+ # or from a string, like this:
+ res = xrc.EmptyXmlResource()
+ res.LoadFromString(resourceText)
+
+
+ # Now create a panel from the resource data
+ panel = res.LoadPanel(self, "MyPanel")
+
+ # and do the layout
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.LEFT, 5)
+ sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)
+ sizer.Add(line, 0, wx.EXPAND)
+ sizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
+
+ self.SetSizer(sizer)
+ self.SetAutoLayout(True)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """
+"""
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# o There are issues using the wx namespace within the xrc code.
+#
+# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Error report: "Error: No handler found for XML node 'object',
+# class 'wx.StaticText'!"; no text shows on panel.
+#
+
+import wx
+import wx.xrc as xrc
+
+#----------------------------------------------------------------------
+
+resourceText = r'''<?xml version="1.0"?>
+<resource>
+
+<!-- Notice that the class is NOT a standard wx class -->
+
+<object class="MyBluePanel" name="MyPanel">
+ <size>200,100</size>
+ <object class="wx.StaticText" name="label1">
+ <label>This blue panel is a class derived from wx.Panel,\nand is loaded by a custom XmlResourceHandler.</label>
+ <pos>10,10</pos>
+ </object>
+</object>
+</resource>
+'''
+
+#----------------------------------------------------------------------
+
+class MyBluePanel(wx.Panel):
+ def __init__(self, parent, id, pos, size, style, name):
+ wx.Panel.__init__(self, parent, id, pos, size, style, name)
+
+ # This is the little bit of customization that we do for this
+ # silly example. It could just as easily have been done in
+ # the resource.
+ self.SetBackgroundColour("BLUE")
+ self.SetForegroundColour("WHITE")
+
+
+# To do it the more complex way, (see below) we need to write the
+# class a little differently... This could obviously be done with a
+# single class, but I wanted to make separate ones to make clear what
+# the different requirements are.
+class PreMyBluePanel(wx.Panel):
+ def __init__(self):
+ p = wx.PrePanel()
+ self.PostCreate(p)
+
+ def Create(self, parent, id, pos, size, style, name):
+ wx.Panel.Create(self, parent, id, pos, size, style, name)
+ self.SetBackgroundColour("BLUE")
+ self.SetForegroundColour("WHITE")
+
+
+#----------------------------------------------------------------------
+
+class MyBluePanelXmlHandler(xrc.XmlResourceHandler):
+ def __init__(self):
+ xrc.XmlResourceHandler.__init__(self)
+ # Specify the styles recognized by objects of this type
+ self.AddStyle("wx.NO_3D", wx.NO_3D);
+ self.AddStyle("wx.TAB_TRAVERSAL", wx.TAB_TRAVERSAL);
+ self.AddStyle("wx.WS_EX_VALIDATE_RECURSIVELY", wx.WS_EX_VALIDATE_RECURSIVELY);
+ self.AddStyle("wx.CLIP_CHILDREN", wx.CLIP_CHILDREN);
+ self.AddWindowStyles();
+
+ # This method and the next one are required for XmlResourceHandlers
+ def CanHandle(self, node):
+ return self.IsOfClass(node, "MyBluePanel")
+
+ def DoCreateResource(self):
+ # NOTE: wxWindows can be created in either a single-phase or
+ # in a two-phase way. Single phase is what you normally do,
+ # and two-phase creates the instnace first, and then later
+ # creates the actual window when the Create method is called.
+ # (In wxPython the first phase is done using the wxPre*
+ # function, for example, wxPreFrame, wxPrePanel, etc.)
+ #
+ # wxXmlResource supports either method, a premade instance can
+ # be created and populated by xrc using the appropriate
+ # LoadOn* method (such as LoadOnPanel) or xrc can create the
+ # instance too, using the Load* method. However this makes
+ # the handlers a bit more complex. If you can be sure that a
+ # particular class will never be loaded using a pre-existing
+ # instance, then you can make the handle much simpler. I'll
+ # show both methods below.
+
+ if 1:
+ # The simple method assumes that there is no existing
+ # instance. Be sure of that with an assert.
+ assert self.GetInstance() is None
+
+ # Now create the object
+ panel = MyBluePanel(self.GetParentAsWindow(),
+ self.GetID(),
+ self.GetPosition(),
+ self.GetSize(),
+ self.GetStyle("style", wx.TAB_TRAVERSAL),
+ self.GetName()
+ )
+ else:
+ # When using the more complex (but more flexible) method
+ # the instance may already have been created, check for it
+ panel = self.GetInstance()
+ if panel is None:
+ # if not, then create the instance (but not the window)
+ panel = PreMyBluePanel()
+
+ # Now call the panel's Create method to actually create the window
+ panel.Create(self.GetParentAsWindow(),
+ self.GetID(),
+ self.GetPosition(),
+ self.GetSize(),
+ self.GetStyle("style", wx.TAB_TRAVERSAL),
+ self.GetName()
+ )
+
+ # These two things should be done in either case:
+ # Set standard window attributes
+ self.SetupWindow(panel)
+ # Create any child windows of this node
+ self.CreateChildren(panel)
+
+ return panel
+
+
+#----------------------------------------------------------------------
+
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ # make the components
+ label = wx.StaticText(self, -1, "The lower panel was built from this XML:")
+ label.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
+
+ text = wx.TextCtrl(self, -1, resourceText,
+ style=wx.TE_READONLY|wx.TE_MULTILINE)
+ text.SetInsertionPoint(0)
+
+ line = wx.StaticLine(self, -1)
+
+ # Load the resource
+ res = xrc.EmptyXmlResource()
+ res.InsertHandler(MyBluePanelXmlHandler())
+ res.LoadFromString(resourceText)
+
+ # Now create a panel from the resource data
+ panel = res.LoadObject(self, "MyPanel", "MyBluePanel")
+
+ # and do the layout
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.LEFT, 5)
+ sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)
+ sizer.Add(line, 0, wx.EXPAND)
+ sizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
+
+ self.SetSizer(sizer)
+ self.SetAutoLayout(True)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>wxXmlResourceHandler</center></h2>
+
+Deriving a class from wxXmlResourceHandler allows you to specify your
+own classes in XRC resources, and your handler class will then be used
+to create instances of that class when the resource is loaded.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
--- /dev/null
+# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+#
+
+import wx
+import wx.xrc as xrc
+
+#----------------------------------------------------------------------
+
+resourceText = r'''<?xml version="1.0"?>
+<resource>
+
+<!-- Notice that the class IS a standard wx class, and a custom
+ subclass is specified as "moduleName.ClassName" Try changing
+ the classname to one that does not exist and see what happens -->
+
+<object class="wxPanel" subclass="XmlResourceSubclass.MyBluePanel" name="MyPanel">
+ <size>200,100</size>
+ <object class="wxStaticText" name="label1">
+ <label>This blue panel is a class derived from wxPanel
+and is loaded by a using a subclass attribute of the object tag.</label>
+ <pos>10,10</pos>
+ </object>
+</object>
+</resource>
+'''
+
+#----------------------------------------------------------------------
+
+class MyBluePanel(wx.Panel):
+ def __init__(self):
+ p = wx.PrePanel()
+ # the Create step is done by XRC.
+ self.PostCreate(p)
+ self.Bind(wx.EVT_WINDOW_CREATE, self.OnCreate)
+
+ def OnCreate(self, evt):
+ # This is the little bit of customization that we do for this
+ # silly example. It could just as easily have been done in
+ # the resource. We do it in the EVT_WINDOW_CREATE handler
+ # because the window doesn't really exist yet in the __init__.
+ self.SetBackgroundColour("BLUE")
+ self.SetForegroundColour("WHITE")
+
+#----------------------------------------------------------------------
+
+
+class TestPanel(wx.Panel):
+ def __init__(self, parent, log):
+ self.log = log
+ wx.Panel.__init__(self, parent, -1)
+
+ # make the components
+ label = wx.StaticText(self, -1, "The lower panel was built from this XML:")
+ label.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
+
+ text = wx.TextCtrl(self, -1, resourceText,
+ style=wx.TE_READONLY|wx.TE_MULTILINE)
+ text.SetInsertionPoint(0)
+
+ line = wx.StaticLine(self, -1)
+
+ # Load the resource
+ res = xrc.EmptyXmlResource()
+ res.LoadFromString(resourceText)
+
+ # Now create a panel from the resource data
+ panel = res.LoadPanel(self, "MyPanel")
+
+ # and do the layout
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.LEFT, 5)
+ sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)
+ sizer.Add(line, 0, wx.EXPAND)
+ sizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
+
+ self.SetSizer(sizer)
+ self.SetAutoLayout(True)
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+ win = TestPanel(nb, log)
+ return win
+
+#----------------------------------------------------------------------
+
+
+
+overview = """<html><body>
+<h2><center>wxXmlResourceSubclass</center></h2>
+
+Sometimes it is necessary to use custom classes, but you still want
+them to be created from XRC. The subclass XRC attribute allows you to
+do that.
+
+</body></html>
+"""
+
+
+
+if __name__ == '__main__':
+ import sys,os
+ import run
+ run.main(['', os.path.basename(sys.argv[0])])
+
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import cStringIO
-import wx
-
-#----------------------------------------------------------------------
-
-ArtClients = [ "wx.ART_TOOLBAR",
- "wx.ART_MENU",
- "wx.ART_FRAME_ICON",
- "wx.ART_CMN_DIALOG",
- "wx.ART_HELP_BROWSER",
- "wx.ART_MESSAGE_BOX",
- "wx.ART_OTHER",
- ]
-
-ArtIDs = [ "wx.ART_ADD_BOOKMARK",
- "wx.ART_DEL_BOOKMARK",
- "wx.ART_HELP_SIDE_PANEL",
- "wx.ART_HELP_SETTINGS",
- "wx.ART_HELP_BOOK",
- "wx.ART_HELP_FOLDER",
- "wx.ART_HELP_PAGE",
- "wx.ART_GO_BACK",
- "wx.ART_GO_FORWARD",
- "wx.ART_GO_UP",
- "wx.ART_GO_DOWN",
- "wx.ART_GO_TO_PARENT",
- "wx.ART_GO_HOME",
- "wx.ART_FILE_OPEN",
- "wx.ART_PRINT",
- "wx.ART_HELP",
- "wx.ART_TIP",
- "wx.ART_REPORT_VIEW",
- "wx.ART_LIST_VIEW",
- "wx.ART_NEW_DIR",
- "wx.ART_FOLDER",
- "wx.ART_GO_DIR_UP",
- "wx.ART_EXECUTABLE_FILE",
- "wx.ART_NORMAL_FILE",
- "wx.ART_TICK_MARK",
- "wx.ART_CROSS_MARK",
- "wx.ART_ERROR",
- "wx.ART_QUESTION",
- "wx.ART_WARNING",
- "wx.ART_INFORMATION",
- ]
-
-
-#----------------------------------------------------------------------
-
-class MyArtProvider(wx.ArtProvider):
- def __init__(self, log):
- wx.ArtProvider.__init__(self)
- self.log = log
-
- def CreateBitmap(self, artid, client, size):
- # You can do anything here you want, such as using the same
- # image for any size, any client, etc., or using specific
- # images for specific sizes, whatever...
-
- # See end of file for the image data
-
- bmp = wx.NullBitmap
- # use this one for all 48x48 images
- if size.width == 48:
- bmp = makeBitmap(smile48_png)
-
- # but be more specific for these
- elif size.width == 16 and artid == wx.ART_ADD_BOOKMARK:
- bmp = makeBitmap(smile16_png)
- elif size.width == 32 and artid == wx.ART_ADD_BOOKMARK:
- bmp = makeBitmap(smile32_png)
-
- # and just ignore the size for these
- elif artid == wx.ART_GO_BACK:
- bmp = makeBitmap(left_png)
- elif artid == wx.ART_GO_FORWARD:
- bmp = makeBitmap(right_png)
- elif artid == wx.ART_GO_UP:
- bmp = makeBitmap(up_png)
- elif artid == wx.ART_GO_DOWN:
- bmp = makeBitmap(down_png)
- elif artid == wx.ART_GO_TO_PARENT:
- bmp = makeBitmap(back_png)
-
- elif artid == wx.ART_CROSS_MARK:
- bmp = makeBitmap(cross_png)
- elif artid == wx.ART_TICK_MARK:
- bmp = makeBitmap(tick_png)
-
- if bmp.Ok():
- self.log.write("MyArtProvider: providing %s:%s at %s\n" %(artid, client, size))
- return bmp
-
-
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- sizer = wx.BoxSizer(wx.VERTICAL)
-
- title = wx.StaticText(self, -1, "ArtProvider")
- title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
- sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
- sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
-
- fgs = wx.FlexGridSizer(0, 3, 10, 10)
-
- combo = wx.ComboBox(self, -1, "", choices = ArtClients,
- style = wx.CB_DROPDOWN|wx.CB_READONLY)
- fgs.Add(combo, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- self.Bind(wx.EVT_COMBOBOX, self.OnSelectClient, combo)
- combo.Select(0)
-
- combo = wx.ComboBox(self, -1, "", choices = ArtIDs,
- style = wx.CB_DROPDOWN|wx.CB_READONLY)
- fgs.Add(combo, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- self.Bind(wx.EVT_COMBOBOX, self.OnSelectID, combo)
- combo.Select(0)
-
- cb = wx.CheckBox(self, -1, "Use custom provider")
- fgs.Add(cb, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- self.Bind(wx.EVT_CHECKBOX, self.OnUseCustom, cb)
-
- fgs.Add((10, 10), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- fgs.Add((10, 10), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- fgs.Add((10, 10), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- box = wx.BoxSizer(wx.VERTICAL)
- bmp = wx.EmptyBitmap(16,16)
- self.bmp16 = wx.StaticBitmap(self, -1, bmp)
- box.Add(self.bmp16, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- text = wx.StaticText(self, -1, "16x16")
- box.Add(text, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- fgs.Add(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- box = wx.BoxSizer(wx.VERTICAL)
- bmp = wx.EmptyBitmap(32,32)
- self.bmp32 = wx.StaticBitmap(self, -1, bmp)
- box.Add(self.bmp32, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- text = wx.StaticText(self, -1, "32x32")
- box.Add(text, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- fgs.Add(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- box = wx.BoxSizer(wx.VERTICAL)
- bmp = wx.EmptyBitmap(48,48)
- self.bmp48 = wx.StaticBitmap(self, -1, bmp)
- box.Add(self.bmp48, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- text = wx.StaticText(self, -1, "48x48")
- box.Add(text, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- fgs.AddSizer(box, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- sizer.Add(fgs, 0, wx.ALL, 5)
- self.SetSizer(sizer)
-
- self.client = eval(ArtClients[0])
- self.artid = eval(ArtIDs[0])
- self.getArt()
-
-
- def OnSelectClient(self, evt):
- self.log.write("OnSelectClient\n")
- self.client = eval(evt.GetString())
- self.getArt()
-
-
- def OnSelectID(self, evt):
- self.log.write("OnSelectID\n")
- self.artid = eval(evt.GetString())
- self.getArt()
-
-
- def OnUseCustom(self, evt):
- if evt.IsChecked():
- self.log.write("Images will now be provided by MyArtProvider\n")
- wx.ArtProvider_PushProvider( MyArtProvider(self.log) )
- else:
- self.log.write("MyArtProvider deactivated\n")
- wx.ArtProvider_PopProvider()
- self.getArt()
-
-
- def getArt(self):
- self.log.write("Getting art for %s:%s\n" % (self.client, self.artid))
-
- bmp = wx.ArtProvider_GetBitmap(self.artid, self.client, (16,16))
-
- if not bmp.Ok():
- bmp = wxEmptyBitmap(16,16)
-
- self.bmp16.SetBitmap(bmp)
-
- bmp = wx.ArtProvider_GetBitmap(self.artid, self.client, (32,32))
-
- if not bmp.Ok():
- bmp = wxEmptyBitmap(32,32)
-
- self.bmp32.SetBitmap(bmp)
-
- bmp = wx.ArtProvider_GetBitmap(self.artid, self.client, (48,48))
-
- if not bmp.Ok():
- bmp = wxEmptyBitmap(48,48)
-
- self.bmp48.SetBitmap(bmp)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """<html><body>
-<h2><center>wxArtProvider</center></h2>
-
-wxArtProvider class can be used to customize the look of wxWindows
-applications. When wxWindows internal classes need to display an icon
-or a bitmap (e.g. in the standard file dialog), it does not use a
-hard-coded resource but asks wxArtProvider for it instead. This way
-the users can plug in their own wxArtProvider class and easily replace
-standard art with his/her own version. It is easy thing to do: all
-that is needed is to derive a class from wxArtProvider, override it's
-CreateBitmap method and register the provider with
-wxArtProvider_PushProvider.
-<p>
-
-This class can also be used to get the platform native icons as
-provided by wxArtProvider_GetBitmap or wxArtProvider_GetIcon methods.
-
-</body></html>
-"""
-
-
-#----------------------------------------------------------------------
-# Image data
-
-
-def makeBitmap(data):
- stream = cStringIO.StringIO(data)
- return wx.BitmapFromImage(wx.ImageFromStream(stream))
-
-
-back_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07YID\
-ATx\x9c\xa5\x97Ml\x9dG\x15\x86\x9fsf\xbe\xef^\xfb:\xaeS\xd7\xa9\x1d;!IK)\xfd\
-A\x05\x95BQ\xc5\xdf\x02\xb1(\x12\x0b\x10\x8b\x8a\x05]Vl\xd8\xb2`\xcb\x92\xee\
-Q\x85\xd8U\xaa\xba\x03\tD+@j\x91J\x11\x8aT\xd14\xfd\xa7\xf9q\x9a\xc6\x8e\xe3\
-\xd8\xb1\xefwg\xcea1s\xaf\x13;\xaa*1\xd2h4su\xe7=\xe7\xcc{\xdes>\x99\x9b\x9b\
-\x03\xe0\xf9\x17\xff\xe2[\xb6B;u\'\x86`\x19\x9299Ar\xc8\x19\xb29\xd9 \xe5\
-\xb2O\x069\x97\xb3\x03{\x1b\xff\xa7\x9c\xa5zf\xe6,\x1e\xda\xe0\xe1\xe5U\xe6g\
-\xb6\x91\xb9\xb99~\xf7\xc2i\x1f\xcc-3\xdd\x8f\xe5r\x83Q\x86\x94\xa0K\x05p\
-\xbc\x1f\xe5\xba\xff?\xcf{\xb1\xe3;_x\x17\xf9\xd3\xcb\xaf\xbb\xce>\xc2\xcctd\
-\x94*x\xca\\\xdb\xd8\xe2Fg\x98\x0b\x96\x95l\xc2\xc8 \xbb\xe0Y\xc8&\xd5+!eadB\
-JBv\xa9`R\xef\x12FYH\x19\xcc\x84.\xcb\xc4\xb0\xa5\xd9k\xc4-[f\xb1_\xc0\xdda\
-\xed\xca*k\xabg\xd9\xda\xfc\x84\xeb;\x01\x97\x1eh\x03\x12A"N\x03D\\"\xe6\x81\
-LK\xf6H\xb6H\xf6@\xb6@\xf2H\xb2\xc0(+\xd9#\xbb]$y\x00\x14\xd5\x00\x08\x00\
-\x17\xaf\xcd\x12\t\x83b\x9d\xc3\xd6\xf5\xab|\xf4\xf6+|ti\xc8\xb9+\rW\xae\xb7\
-\x88*\x1a\x14\x15E\x82"Z\xa7(\xaa\rh\x00\tH]\x11\x05Q\\\x14<\xe0\x12HV"\xe8\
-\x08\xfd6\xd3k\x03\xee\xc2(\t\xd1\xc6\x841\xf8\xf8\xc2;\\^\x1f\xf2\xda\xd9\
-\x86\xc1\xf4!V\x16gh{-\xe6J\x08\x11\t\rA\x03\x1a"\xaa\r\x12\x02\xaa\x81 \x11\
-\x82\xa2\xd5\x10\x11-\x06\x11\xe8\xb7\xca(\x0b\xef\xad\n\xeb\x9b\x86Y\xa6UgD\
-\x03@4wF\x19,\x8f\xb8\xb1u\x85w/6\xf4z\x03N\x1e\x9bc\xa7\x13.\xad\x8d\xd8\
-\xed\x04QG\xd5\x11\x8d\x88\n\xa8 \x02\xaa\x02\x9a\x01\x07\x11\x10\xc1\xa5\
-\x84\xd8\x81\xa9>\x9cZR\xbev\xbf\xf3\xea\x1b\xc6ng\xb4\xd1\xd8\xee"\xee\x82\
-\x9a\x15V\xa6,\x98\x05\xae\xef\xf69<7 [\xe0\xfc\xe5!\xdb\xbb`D\x9c\x80\x110\
-\x1a2\x01\xf32\x93+)+\xc9\xea\xbb[ \xe5\xc8(\x17\x0e\\\xdbV\xfe\xf3a\xa6\x1b\
-\x19\xcb\x0bNTc\xaa5\xc6#\x9a\x97Ts\x03B\x8b\xc6\xcc\xf4T\x8f\xcd\x1b\x86y@\
-\xb4A5V\xcf[\xd0\x88H\x99\xd40#\x91\xe1\xf6\xc7|\xf0\xfa\xb3\xe44\xac$\x13\
-\x16\x1f|\x9a\xc3+\x8fc9s\xe1\n\xdc5\x0b\x17.\x1bM(\x112\x87\x98\xcdk\x8a\
-\x00\x94\xb7\r!\xe2#\x10\x95\xcf\x04\x8e\x04\xba\xe1&\xabg\x9e\'w[\x13\xef\
-\xe6V\x9e@W\x1eC\xc4p\x87\x18 \x06\xa3\x89\x8a{\xc9\xbahUt0\n\x80\xc6B\xb2\
-\x00\xaa\xf6\x99\xc0]\xea\xbe\xa6\xd7x\x08\x86\x88\xa1bD\x15\x82B\x10\xa7\t\
-\x19K\x1d9Iy\x82\x94\xc0\x11\xa0\xe4\xbajD\x15D\xed3\x82G\x1ce\xff\x10\xbc\
-\x82\x1bA\xa5\xcc`4\x01R\xee0\x13\xa2Y\xc9\x02\x1c\x8c0y\x82\x9a\xce\x07\xc0\
-\xddAt?x\xb8\xbd\x01\xe2\x15\xdcPQT\xa0Q\xa7\t`y\x88\xe5q\x16T\xfd\xf7q\x04B\
- \x84\xe6\x00x\xeevx\xff\xb5\xdf\xb0~\xfe\xd5\x03\xe0\xb73@e\x0c\xee\x04\xf5\
-\xca\x01\xa7\t\x86\xa5\x0e\xcf\x1dj\xe6E\xbbS5@cU\xb8\x83\xe0\xef\xfc\xe3\
-\xd7|\xf8\xfa\xb3\x9cy\xf9\x17\\=\xf7\xea-\xe0\x8a\xdd\xc6\x00\xaf\xe0F\x08N\
-T\'(\xc4h\xb8\x8d\xb0\xdc\xa1\xe6%\x02E\x8e\x03\xa2-\x12""\xe1\x00\xf8\x857~\
-\x8f{fg\xe3\x03\xce\xbc\xf4s\xd6\xcf\xfd\xbd\x80\x8b\xa1d\x04?`@P+\xde\xab\
-\x13\x024\xc1\xe97\x8e\xe7\x0e\xcfCt\\zG&\xe4ZdT\x02\xaa\xb7\x07\x1f\x8f\x9d\
-\x8d\xf79\xfb\xd23\\;\xf7r\x01\x17\xdf\x1f\x00d\x1c\xfa\xeayPh\x1b\xa7\x89\
-\x0e\xdea\xd6\xa1\xee^\x940A\xf6H\x13c\xcd\xfd\xc2\xf6\x94\x86\xdc\xb1\xf4(s\
-\xcb\x8f\xdfry;}\x84\x95G\x9eA0`\x84\xe5m\xdco}\x86\x10t\xe2y\xac\xde7\x01z\
-\x11\xdc\n\x07&: \x02x\xa0m\xa4V;@\x84\xde\xccQ\x16\x1fx\x8a\xd4\xedp\xf5\
-\xfc+\x93\xcb\xd3p\x83\xde\xf4<\xf3\x9f\xfb&*\xc6\xf6\xe5\xd3\xe4\xd1\x8d\
-\xc9\xef\xb1\x99f\xee\xae{\n\xb8:M\xa8\x86D\xa1\x89`\xb9\xc3\xb2U\x1d\xc8\
-\xa0\x02f\x01Cji\x15\x10&l\xef\xcd\x9e@4\xe2\x96\x80r\xc1\xbb\xaf\xfc\x8a\
-\xb4\xb3J\x7fz\x9e\xff\x9e\xfe\xed-\xde7\xfdY\x06\xb3\x0b\x05<\x8e\xa3P\xc0\
-\xdb\x08X5 \xd7,P\x11\xdcJ\x9dV\t\x88\x08.LR\xed\xd0\xdd_e\xfa\xf0}l\xaf\xbd\
-9\x01\xd9\xdd\xfc\x88\xb7\xfe\xfaKD\xc3\xc4\xb0\xf1\xb8\xfb\xc47\x98=\xbcD\
-\x13\xbd\x86_*\t\xa1\x89\xe0\x96\xf0\x9c\xf6t\xa04\x94\x01#\x82j\x997\xe5y38\
-\xca\xd1\x87~\xc6~\xb9\x05?\x00\xde\xf4\x0e\xf1\xc5\xc7~J\xaf\r\x05<\xde\x04\
-\xde\x08m\x03\xee\t\xcb\xc3\x92\x86\xa3\xda4\x8er S\xbb\x9b}"\xa3b,\xdd\xffc\
-\x16N}\x1f\r\xed\x01\xc6\xef\xbd\xfd\x14\xf7=\xfa\x14\xcb\xa7\x1e\x9d\x80\
-\xc7\xeau\x08B\x1b\xa1\x8d\x8a\xdb\x10\xb7\xaeHqJ\x85\x03\x9e\x15s\x10\n\x07\
-\xbc\xa8\xf9$\xcf{3\x0b|\xe9\xc9\xe7X\xff\xf0\xcf\x9c;\xfd\x1c\x1b\x97N\x93j\
-\xf5\x8b\xcd\x14\xf3+_\xe1\x81\xaf?\xcd=\x0f}\x8f\xb6mn\x01\x8f*5\xfcJ\xbf\
-\xe7\x95\x037e\x81\nXR\x92\x95~\xaf\xdf+\x06LD\xa6V\xb5\xb6?\xe0\xd8\x03?d\
-\xf9\xde\xef\xb2}\xf5,\xdb\xebo\xa3df\xef<\xce\x91\x95\x87\x99\x1e\xcc\x1c\
-\xf0\xbc\t\xc2\xa1\x81\x12\x832\xd5S\xdahX\x1e\xe1y\xb8\x97\x05"\xd0\x8d"\
-\xd9\x84\x8dm\xe1\xd4Q\xe5\xd2zfk;\xdfTR\xf7\xb4\xbd\x99\x1a0=\xf82K\xc7\x1f\
-\xd9K\xb51\xe1\xf6\x81\xdfqH9\xbe\xd8pi-\xd36B\xd3\x08\xe27G \x15ju)\x90\x0c\
-.\xac\t\'\x16\x9d\'\x1e\x84s\x9f@7\xa2\xd6sAE\t\xea\x84 {\xda^E&\xdc\xcc\xf6\
-\x1a\xf6~O8~w\x83 \xacof\x8e-\x08MTR\xea\xb0<\xac\x1c\xc8P\xaaw\xc0\xdd\x19v\
-\xc6kof\x8e\x1c\x866Z\x05\xda\xabj\xb7\x14\x96O\x01\x8f\r\x88\x08\xabW2[\xbb\
-#\xa6{pbQ\xf9\xdb?/\xb2\xb9\xb9\x8d[":\xb5\x1f\x00\xdc\x85A\xdf\x18\xa5\x8c\
-\xbb\xb1\xb6Q:\xd8\x18\xac\x94Q-k[C\x1d\xa3\xd3\x8b\x8eEh\xa3 ^"iU\xc4\xd4\
-\x95&8m\x14\x16\xef\x14\x96\xe6\x95l\xc6\x0b\x7f\xf8\x17f\x1d\xb8\x11\x8f\
-\xcd]\xe5\xcc\xea\x11\xccJ#\xa9!0\x88\xd0\x84L\x1b\x85\x18tR\xc3\x83\x16\x1e\
-\xc4\x89!U\xdf\xe3\xb8\xd7s\x9a e\x8dB\xaf1\x1a\x15\xa2\n\xbbC\xe1\xf4[[\xbc\
-\xf8\xc7\x7f\xf3\xde\x07\xab\xb8\x97\xce(\x9e\xbck\x8d\x85\x99M\xce_\xbdc\
-\x12\x85\x11\xb1\xf6\xed%2f`\xa9#\xe5\x8e\x9c\x129\x15\x02y\x1eb\xb5\xa8\x94\
-\x0e\xa7+\nge?>/kWz\x00\xebp7<\x0f9yr\x19\xfd\xc9\x8f\x9e\x94o}\xfe=\xee]\
-\xf8\x04%\x17A\x1aW\xc7}_\xb5\xd9J+\xfd\xa9\xc3\r\xb7\\V\xb7\xc9\xea\x9e\x8b\
-b\xba!\x18G\x97\xe6\xf9\xc1\xb7\x97\xf9\x1f\x92tznH\x8fy\x14\x00\x00\x00\x00\
-IEND\xaeB`\x82'
-
-down_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x042ID\
-ATx\x9c\xa5\xd5Ko\x1bU\x14\xc0\xf1\xff\x8c\xe7\xe1g\xe2\xa6\x84\xa8\xa8\x82\
-\xd0\x88E\xabJ\x08\t\x8a*\xb1@\x02v\xec@l`\x87\xf8\x1e\x91\xf8\x06 \x90\xd8\
-\xb3\xe2S\xb0aS\x1ej\x8bhIe\xd2\xa8i\xa8\x13\xc7\x8f\xda\xe3\x99\xb93\xf7\
-\xcee1\x1e\xc7\xae\xed\xc4c\x16Wc\xddk\xfbw\xce\xf1\xf1\xb9\xc6\x0fw\xb5\xfe\
-h\x1b\x02\t\x91\x02\xa1 N&^+\x88\x12\x08%\x08\x99\xeeE\xa3\xf3l\t\x05~\x9c>\
-\xc3\xd1^(\'>7:\x7fqOH0\x13\r\x00\xa6\x91\xae\x82\x01F\xba5~\xca\x04\x94\x86\
-db\xa9\xd1\x92I\x1a|\x16t<\x91\x84\x18%\x15\xc4g\x81\x87Y\xa2\x12\x94R\x98J\
-\x8f\x0e\'\xb2\x11\nNzC\xfex\xb0\x8f\x17\xeb\xf4|"\xfb\xec\xfdB\x82\x17\x9fe\
-\xfcb\x05\xc6\x99gU\x12\n!\x13\xc2\x11\x8e\x14X*\x99\xc5#\x05a\x9c\xf0\xfdw\
-\xdf\xb0qe\x9bO>\xfb\x9c\xcb\x9b\x9b+\xe3\xa1L\xe8{\x01a\xa40\xdc**Iq\xad",\
-\xa5g\xf1HA\xb1R\xe3\xda\xcdw\xf8\xe5\xa7o9\xd8\xfb\x93\xdb\x1f\x7f\xc1\xdb\
-\xb7\xde\xc5)\x96s\xe1\xfda\xc0\xc0\x1b\x12)0\xdd\x1aI\xa2\xc78\xb1O\xe1\xc3\
-\xafvw\xafT\xa7q\x7f\xf4%\xf5\x8d-\xee\xfcz\x87\xb0w\xc2\xc1\xdf\xf7y\xf8\
-\xcf!Vu\x13wm\x8381\xce\xc5\xbd0\xe6\xb4\xd3a0\xf0\x90X\x18v\x19,w\nG\n\n\
-\x1f|\xb9\xbb\xbbU\x99\xc5#\tv\xa9\xc2\xa3\xc3\x16\x9d\xe6\x13\xb0\\\x82a\
-\x9f\xc7\xfb\rN\xfa!v\xf5\x12\x96[\x99\xc1\x07\xa1\xa4\xd5\xeepzz\x8a\x88\
-\x15\xda.\xa5\xb8S\xc2\x88\xa7\xf1\xb4\x07\xf4|\\(\x90\xda\xe0\xad\xdb\xef\
-\xf3\xf8\xaf\xdfP\x1a\x0c\xb7\x86L4O\x1e\xfc\xceq\xf3\x19Wo\xdc\xe2\xea\xceu\
-\x12\xd3!\x94\x9aV\xe79\'\xad\x14\xc6.\x81S\x1e\xe1e\x1cb\x84\x12S\xb8\x96\
-\x11\x96L\xe6\xe3Y\xc3m_\xbb\xc6\xfa\xab7\xe86\x0f\xc1.aXEp\xca\x88(f\xff\
-\xc1]\x8e\xdb]6^\xd9\xc1\xf3C\xfaC\x1f]pa\x84fx\xc5\xd2\x84A8\x83#E:\x07\x16\
-\xe1\x91\x02\xa3\xe0\xb2\xf3\xe6{`\x97\xc78N\x05\xc3)\x83]b\xe8y<=h\xd0\xeb\
-\x0f\xe6\xe2U\x1b,bT0\x98\xc1Q\x023N\x16\xe3Y\xb7o\xbfq\x9d\xf2KW_\xc0\'\xa0\
-\xe2\xfa\xec\xde\x08\xaf8\x90\x88!z\x0e\x8e\x8c\xd2At\xd1\x90q+kl\xbe~s>^\
-\xaa/\xc4\xab\x0eTL\x89\xef\xf5\xe7\xe2Z\nL\x99\x9c\x8fg\xdd\xfd\xca\xceu\n\
-\xe5z.|\xa3\x08\x81?D\x8a`.N\xec\xa7\x01,3\xe1\xca\xeb\x97\xa9\xbd\xfcZ.\xbc\
-h&\xf4\x9f\xf7\x16\xe2H1}\x17\x9c7\xe1\xe2\xc4\xe4\xd2\x95m\x0c\xa7\xb2\x14^\
-s@\x84>\xde\xa0\xbf\x10GE\x98?~z\xc9Xv\xb6;k\x9b\xd8\xeb[K\xe1eKs\xda\xe9\
-\xa2\xe3p!\xae\xa5\xc0\x84\xe5/\x16Up(\xd6\xb7.\xc4\xab\x0eh\x15\xd1>m\x9f\
-\x8b\x93\x05\x90\xe7J-\x94\xd60\xdc\xea\xb9x\xd5\x86V\xbbG\x14z\xe7\xe2\xc8\
-\x08\x0b\x96\xc7C\t\xca\xb01\x9c\n\xdar\x17\xe2\x16\x8a\xa3\xe6\xf1\x858jT\
-\x81e\xf1\xecL\x17\xec\x85x\xcd\x81^\xdf\xa3\xd7\xe9\\\x88\x9f\xf5@\x0e\\)\
-\x85\x11\x0b\\S\xcd\xc5\x8b\x05\xcd\xc1\xd3&*\n.\xc4\x89\xfcQ\x05r\xe0HA\xa2\
-\x04:\xf2g\xf0\x8a\rB\x08\x0e\x8f\x8e\x96\xc2\xc7M\x98\x07\xcf\xee\xf3\xa1\
-\xd7\xc7BN\xe15\x07\xf6\x8fZ\x04\x83\xeeR\xf88\x80\xbc8R\x10\x0e\x07xC\x7f\n\
-\'\x914\xf6\x1f/\x8dO\xf5@\x1e<\xbbX\x9a\xc7-\xdc\x82\x1e\xff\x14\xadn\x9f\
-\xe3\xe6\xbfK\xe3\xe3\n\xac\x82#\x05\xedv\x0b\xdf\x0f\xa8:\xb0\xeeh\xee\xed\
-\x1d\xa0\xa2pi\xfc\xeco\xb8\x02\x8e\x12D\x81O\xe3\xe91\x1bEx>\x0c\xd9k4r\xe1\
-\xe3\n\xac\x82gCf\xefQ\x83@D\xdcm<c\xd0\xeb\xe6\xc2\xb5\x14\xe9$\\\x15\'\xf6\
-\xe9u\x04?\xdf;\xe0\xfe\xc3G\xb9q"\x1f\xa3^\xafc}\xdd\xd5\xab\xe0Y\xb7\x1bIL\
-\x12\x05\xb9q&+\xb0*\xae\xc7@~|\xfc7\xfc?\xf8*e\x9f<\xfb\x0fT{\xea\xc3\x87j\
-\xf9\x90\x00\x00\x00\x00IEND\xaeB`\x82'
-
-left_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\
-\x03IDATx\x9c\xc5\xd7Mo\x1bE\x18\xc0\xf1\xff\xbe\xc4^\x9b\x86V\x81\x86\xf2\
-\x8e\x8aJ+\x90(jE\x85\x84\xd4\x03\x12G$\xee\\\xb8\xf2-\xfa9\x10_\x82\x0b\x07\
-N\xbd \xd4"\xd1&MQ\xd44iZ7N\xea$vl\xafwwv\x9e\x99\xe1\xe0\xf7\xc4i\xeb\xf4%\
-\x07k\xf6\x19\xef\xccoV\xf3\xb2\xcfz\xbf.8w\xba\x04\xb9\x05cA[0\x0e\xc4\x808\
-\x90^\xbd\xb2\xa0\xcd\xf0\x1eq\xddX\xdb\xee=\xa9t\xe3\xbc\xf7\xbf2\xbd\xd8t\
-\xafS\xe9\x96\xfd87\x90\t\x84\xa7Kpq~X\xd9\xbfa4N\xfa\x8d\xfb\xa5\x1d\xe9L \
-\xd6P\x0c\xc0\xb9\xee\xe05\xe0\x01\xb6\x17\xe7\xbd\x81j;\x8e\x1bc\xf0G;;*\
-\xde\xefP\x19\xc8\xccx\x9c\xe8n\x9d\xea\xd5\x8d\xe2\x88\xc27\xf6\xf8pgr|m\
-\x8f\x0fG\'\xf8\xc6\xbd>\x1ck\x08l>\xc0\x11\x85/\xaf\x18\xef?\\\x148\xe6J\
-\x80\xd5\x03\x1cQ\x84\xe2^\r\xde\xc9-\x99\xf1\xf1\x80\x13\x0581\xe3\xd1\x8cs\
-$\x8b\x07\xb8\x93\x9cP\xec\xcb\xc3\x13mi\xa5B\xa2\x1d\xda+R\x0c!\nav\x06D\
-\x84\xb8\xbd7\x86#\x8a\xd0\xd8\x17\xc33q4:9{\x1dE\xac,\xe2\x15\xa0P&\x1a\xc1\
-g|\xcbn\xb3\x89\xcd\xb31\x1c\xa3\x08\x95=\x1a\xdeN\x85\x9dV\x87\x9d\xbd\x0e\
-\x89v\x98\xa0\x887S>\x80\x97Bh\xc5)\x9d\xb8u\x00GrB=\x05\x9ej\xc7n3\xa6\xba]\
-\xa7\xdeN\xc9\xc4\x83\x99\x12\x14\xca\x87\xe2\x9e3\xec\xd6\xeb\x13q\xd7\x9f\
-\x82g\xe1\xad4\xa7\xb2\xb5Mu\xb3F\xb3\xddA\xc22^\xa1\xfcL\xbc\x18:6\xb7\x9b\
-\xe4ig"\x8eN\x08\xb5\x9d\x8cg\xda\xb2\xb1\xbd\xc7ze\x83\xcd\xcd-\xd2\\\xe3\
-\x82\x08J\xa7zx\xf9\xa9x\x14\x82R\x8a\xc6\xee\xee\xa1\xf8`\x1b\x8e\xe2\xb5V\
-\xc6\xea\xc3\xc7\xdc_{@\xa3^G[o\x08M\x81\x87\x9ee\xfd\xc9\x0eZ\xa5\x87\xe2\
-\x98\xde\x1aP\xe2X\xab\xd4X\\^\xe1\xd1\xfa\x1aI\x92\xe0\xc2h\x1c\x9a\x02\x8f\
-B\xd8\xad\xb7i\xee5\x9e\x8a;Q\xdd)\x88Sa\xe9\xde*k+\xcbd*?\x08M\x89G\x01\xa4\
-i\x82\xd3\xd9SqD\xe1\xfd\xf2\xa7s\xa1\xdf\x9d\x82\xda^\xcc\xfd\x07\x15\xaa\
-\x9b\x9b$\xa9\xc2\x06\xc5\xa9\xf1\xfeu\x1c\'\xdc\xb8u\xa7\xb7\x00\'\xe3H\x8e\
-\xf7\xf3\x1f\xce\x15\x83\xf1}\xde\xc9\x84Z\xa3E\xad\xd1\xa6\x9d\n\xe2\xcdL\
-\x85\x97B(\x06\x8e\xbb+\x15\x16\x96\xee\x1e\x8acTw\r87~\xc8\x18/\xe4\xc4\xc9\
-9\xfc\xf2\x1ce%\xb4SM\xa2=L\x10=\x17\x1e\x050[\xf4\xb8|\xee\x0c\x1b\x955v\
-\xb6\x1a\x13q\'j\x98\x11\x1d\xf6bq^HX(Q\x8c"B\x1f\x02\x1c\xe5\xc0=\x03\xef\
-\x96\xef\xbcY\xe0\xeb/>\xc5w2\x11\'O\xba\t\xc9\xf3\xbc\xcf\x95\x80\x88\xa1\
-\x93\xa4\xec4c\x1a\xed6\xceh\xa2\xc0M\xc4\xfb\x83\xfa\xe6\xfc{\x9c\xfd\xf8\
-\xfd\x898\xa2\xf0\xd5s\xe0\xfb3\x19\x95\xb4\xa9\xd5vX^}\xc4\xbd\xf5*\x8df\
-\x8c\xef\xcc\x01\xbc\x14\xc2\\9\xe0\x87\xab\x97(\x15\xc2\x038\xa2\xf0\xf5\
-\x11\xd2\xa8~c\x95v\xa8V\xab\xdc\xbc\xb5\xc0\xf5\x9b\x8b,\xadV\x89\x93\x8cb\
-\x0f\xef\xff\xbe\xfa\xe8\x14W.}y\x00w\xa2\x08s\xd3M\x9d\xa7\xc5G\x8fW+9\xdbO\
-Zl?^c\xb1\\\xe4\xc2\xd9\x0f\xb9\xf2\xf9\'\\xw\x96R\xe83[\xf0\xf8\xe9\xfb\xcb\
-\xfc\xf7\xef\rj\x1b\x8d\x01\x8e(\x823?^\xbb\x96\xc9\xd1\xf1\xfd\x87\x8cJ\xda\
-<\xae<\xe4\xf6\xe2\x1dV*5\\P`\xfed\x99s\xf3\x11\xfe\x1boq\xf3\xef\xbfp\x92\r\
-\xf3\x81T\x86\x1f\x0c/\x8a\x8fn\xb5\\r\x96\x97n\xb3\xbc\xf0\x0f\xbf\xcf\x9d\
-\xe4\xbb\xab\xdfr\xf1\xb3\x0f\x98?\xfd6[\x8f\xee\xf7\xda+\xbc\xf3\xbf9\xa7\
-\xed\xcb\xc5\'\xadvDQ\x08}\xf2N\x0b\'\xe9\xf8\x1a\xd8\xff\xb9\xf4*p\'\n\x95\
-\xa9\xc1\x93\x0f\xce\x81\xd7\x85\x0f\xdb\xef;\x07\x8e\x13w\xa2\xf0\x8f\x13G\
-\x14\xff\x03\xe8\x84\x1b+\xdf\xf26\x9e\x00\x00\x00\x00IEND\xaeB`\x82'
-
-right_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\nI\
-DATx\x9c\xc5\x96Ko\x1bU\x14\xc7\x7f\xf3\xb4=&\xd4mQ_H\xd0"\xdaD,\xda\x8aR\nB\
-\xa8\xb0a\x83\xc4\x82\r{>\x01_\x00\xa9;>\x04\x0b\xb6,\xd9\xb0fQ@\x08\x81BU\
-\x92\xaa\xa1\xa5\x0f\xbbQ\x12\'c{\xecy\xdf\x07\x8b\xf1\xb86u\x9c\xa4I\x95\
-\xd5\x9ds\xe6\xce\xfd\x9d9\xf7\x9c\xff\xbdF\xa3\xd1\xe0\xbb\xdf;:S \x15\xe4\
-\n\xa4\x06!Ah\x10C\x7f\xaa \x97O\xe7\x08]\xd8\xb9*\xe6\xc4\xa2\xb0\xb3\xe1\
-\xfbT\x0emY<\xc7\xa2\x18K;\x93\x90\x08\xb0\xbf\xf9\xa9\xa3/\x9dx\xea,\'\x8c\
-\xdbQ\xf9q9\xaa\xb1\xc5\x04\x0cr\xa8X\xa0u\x11|\x0e\x18\x80\x1a\xda\xd90\xd0\
-\\M\xc2\xa5\x94\x98R\xef\x1f^.\x98JH\xe4\xa4\x1d\xe5\x85/\x1d\xfa\xc6\xe1\
-\x88\x14S\xaa\xc3\x83k\x99\x15\x198,8y\x84]nA\xb9\xf8\x1fK\xf7\xb1\xaa\x1e\
-\xa7N\x9dBH\xe3\x85\xc2\x11)\xb6T\x93\x7f\xde\\\xf7\xf9\xfe\xdb\xaf9s\xe1\n\
-\xd7\xae\x7f\xc2\xf9\xf9\x0b\x98N\xe5\x85\xc0\x8b\x00\xf4d\xda\xaf]\xbd\xc2\
-\xcd\x9bW\xb9\xfb\xf3\x0f\xdc\xbf\xf5\x0b\x8d\xb3\x17Yx\xf7#\xe6\xdf\xbaHm\
-\xee(\x992\x0e\x0c\xaeE\x86-\xd4\xe4\x9eKm\xf2\xe9\xe7_\xd0\xbc\x7f\x87\xb8\
-\xd7\xc6o\xad\xf0\xebz\x8b\xc5\xdf\xcer\xf2\xcdK\xbc\xbep\x89\xa3\'N#\rg\xdf\
-pD\x8au\xfd\xcb\x1b7\x8eT\'\x0b\xce{i\x8e\x9e\xac\xd0\xfa\xf7.\xd8\x15\x8c\
-\xca\x1cBi\x02\xbfM\xeb\xf1CV76I\xa5\tN\ri:\xcf\rG\xa6\xd8#q\xf8_\xb5\xbf\
-\xf7\xc1\x87\xdc\xb9\xfd\x17\xdd\xf6*85\x0c\xbb\n\xae\x872\x1d\xfa]\x9f\xfe\
-\xd2"n\xb3\x85\xf7\xca\xab\xd4\x8e\x9d\xc1\xacx\xa4\xd2\xdc\x13\x1cQ\xb6\xe1\
-\x94V\xb3\xdd\x1a\x97?\xfe\x0c\xcbk\x8c\xe0\xb8u\x0c\xd7\x03\xc7\x03\xd7#\
-\x97\x9a^0`cm\x95\xcd\xf6&a\x94\x90\xe4z\xd7p-RL\xa1\xb6\xef\xf3\xb3o\x9c\
-\xe7\xe4\xfc;S\xe1\x86\xe3A\xad\x81\xe1zh\xabJ\xaeM2\xa1\x90\x18\xb8\xa6\xc6\
-6\x14\x86\x88g\xc2\xc9\xa3a\x11n\xd3\xe7\xb9\xb6\x98\xbf\xfc>\xbe\xdf%\x13b*\
-|\xc2\xe7z\xd4\x1d\xf0\x1c\x9b\x97\x9d:H\x9b\xa0\xd7\xa3\xd7MI\x92g\xe1\xa36\
-\x9c%2\xf5\xc6q\xce,\xbc\xcd\xa3\x95%\xb4S\xdb\x05\x1c\x1a\x15\xf0\x1c\x83\
-\xbaS\xe5\xdc\xf1*\xc8c\xf8\xdd.\xcd\'kl\xb5\xd7\xc8\xcbm\x91\x19F\xa3\xd1\
-\xe0\xab\x1f;z\x96\xc8\xf4\xa3\x8c\xbfo\xfdI\x14\xc5\xbb\x84S\xd8v1\x96\xef\
-\x1cC1\x08\x07,\xdfk\xb2\xf2\xcf\n\x9d\xcd\rl\xd8Y\xe1\x94\xe5b\xd7\x8f\x82\
-\xae<7\xbc\xee@\xa3b\xf2\xda\x919N\xcf\x9dC\xc4\x01\x8b\x1bO\x8a\x00v\x92\
-\xd7\xad\xde\x800\xcd\xf7\x05\xaf\x9a\x92\x87\xeb\x01\xb7\xef>`iy\x99\xb0\
-\xe7\x83\xc8\x8a\x00f\xc1\xc3L\xb1\xde\xdeD\x19\xce\x9e\xe1U[\x93$\x19\x0f\
-\x1e\xb5Y^\xb9\xc7\xdaj\x93<)\xdb2+\x84\x08f\x1f,[\x9d\x80$\xc9\xf6\x04wME\'\
-\x08\xb9\xf7\xf0\t\xad\xc7\x8f\x18\xf4\xb6@\x0e\xab\x7f\x0c\xae\xc50\x80\xed\
-\xe0Q&\xe9\x06\x01z(D;\xc1\x919\xcd\xad\xb1j\x8f\x82Q\xb5O\x83\x93E\xc3\x0cl\
-s\xaa\xf9\xdd\x1e\xb9d&\xbcf)\x928\xa1\xb5\xb9E\xbb\xbdA\x18\xf4&\xfa|\x16\
-\x9c2\x03\xd3\xe0\x838%\x8c\x92m\xe16\x92\xb0\x1f\xf2\xd8\xef\x10t}\xf2$|Fdv\
-\x82\x8f\x02\x98v\xa4\x06\x83\x08e\xb9\x13\xf0\x9a\r\x15r\xfc\xce\x80A\xafK\
-\x1c\xf6\xa7\xca\xebn\xe1\x1350\x0e\xefG)Y\xaeFp\xcf\xd2X*\'\xee\x87\xf8a\
-\x80L\xe3m\xb5}/\xf0Q\x06\xc6\xe1q\xae\x88\xe2\x14\x9c\x1a\xb85\x1c\x9d\x93&\
-\tQ\xdc\x1f}tP\xf0\xa7m8v\x99H2\x89\xb6*`9\x18YB&\xd3\x1d\x8f\xd4\xe7\x85\
-\x8f20~\x93\xc9q\xd0\xa6\x84<A\xed\xe2<\xdf\x0f\\\x8b\x14\xb3,\xc2\xbd\xded\
-\x0e\x02N\x16\x15\x01\x1c\x16\x9c\xf1\x0c\x1c\x06|\xb4\x05\x87\x05G\xa4\xfc\
-\x07\x8a\xed\x03}\xa8\xdcA9\x00\x00\x00\x00IEND\xaeB`\x82'
-
-smile16_png = \
-'\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\x02\xa3IDATx\x9ce\x93\xdfkSg\x18\xc7?\xe7WL\x1b\xa2\x07!U\xa9\x89\xe9j\
-\x90H\x87\x0cA\x86"\xb2\xf6B\xa1\xe0\x8d\xca\x19.\x88XJ\xa0\xb7R\xbc\x14\xbc\
-\xb2\xfb\x03z\x93u\x17\xbb\xdb\x8dcHA\x85\xe4\xa6\xec\x80\x11d\xa3\x9548WMW\
-\x10\xd9\xc4\xa2\x89\xc99=\xfdz\xd1D\x83\xbe\xf0\xde\xbc\xcf\xfb\xe1\xf9\xf2\
-\xfd>\x0f\xae\xeb\xd2\x7f\xcb\xe5\xb2\n\x85\xcb\xcaf\x0f\xc8\xb6\r9\x8e\xa9\
-\\.\xadbqZ\xbe\xef\xeb\xf3\xff&}\xc7\xf3.\xe9\xea\xd5\xf3\x8c\x8d\xfd\xc3\
-\xdd\xbb\'i\xb5~\xa0\xd9\xfc\x9e;w\x8e12r\x1f\xcf;\x85\xe7]T?c\xb8\xae\x0b\
-\xc0\x89\x13\xdf(\x93\xf9\x9f\xf9\xf9\xf38N\x004\x81w@\x04t\x80g\x84a\x8d\
-\x99\x99\x80F\xe3$\xd5\xea\xb2\x01\xec(\xf0\xbcK\xcad\xa0T\xba\x8d\xe3\xe4\
-\x81D\x17\xec5k\x03-\x1c\xc7\xa0T\xdaE&\xb3\x84\xe7]\xd8)\xfa\xbe\xaftz\xaf\
-\x82\xa0&\xe9\xb9\xa4\x07\x9a\x9d\x9d\x15 \xa9 \xa9 @\xa9TJ\xd2\xa0\xa4\x01\
-\x05\x01J\x1fD\xbe\xef\xcb(\x16\xa752\xb2\xc5\x8d\x1b7\x01\x0bx\x82a\x9c\x03\
-@*\x00\x9b\xe4\xf3OY]]E\x1a\x04E\xb0e0\xf7c\xc4Z\xa3\x80Y\xa9\xdccrr\x18\xd8\
-\x00\x9e\x01\x7f\xf6Y\xd4\x016X__\xef{\xdb\x86\xce \x93\x13I*\x95E\x0c\xc71\
-\xd5l^\xc7q\x92@\x9b\xa9\xa9\x97,,\x04\x1f\x8d\x83\xf5\xae\xa1]8\x8a`s\x88\
-\xb0m\x918\xd4\xe8\xc5\x18t\x1d\x7f\xcb\xc2B\x08l\x02\xcb@\xbd\x0f\x16h\x8b\
-\xaf\x0e\xc6!\x1c\x800\x0e\x80\x99\xcd\x0eS\xaf\xff\x0b\xbc\x02\xea\xe4\xf3\
-\x8f\x80\x87\xdd\xce\xfa\x04\x13Bd\xb2\xf6\xf2-\xb4\x92\xd4W\r\xb2\x87R\xd8\
-\xe3\xe3gY\\\xfc\x85\xb1\xb1\x18 j5H$D\xb3\xd7\x98m`\x0b"\x83\xe3G\x93\xe8\
-\xf90\xb4v\xb3\xf8\xe05\xe3g&z1\x1a\n\x82\x81nL;Q)\x1eW,\x16\x93m[J\xc4m\x1d\
-\x1b\xdd+m\x1c\x91j\xa7\x15<\xfeN\xe9\xfd1\xf9Ke\x19\xae\xeb\xe2y\x17\x14E?S\
-*\xd9}\x92\x05\xe66\xc4,&\x8e\x0eQ\xfe-\x05\xed$\x84\xbb\x98\xbeY\xc3J~\xcb\
-\xaf\xbfW\x8c\xbeQ\xfeZ\x99\xcc\x12\xf3\xf3\xe08=\xf5&\xbc\xdf\x03o\xf6C;I\
-\xd8\x8c1s\xebo\x1a\xff\x1d\xa0\xfa\xd7\xda\xa7Q\x06\xa8V\x97\r\xcb\x9abt\
-\x14\xe6\xe6`e\x05\xc2\x8eE\xd81Yy\xfa\x8e\xb9\x9f^0z\xee!\xd6\xee\xd3\x1fa\
-\x00>_O\xdf\xf7U,^S.\xb7O\x8e\x8d\x1c\x1b\xe5\x0e\x0f\xa98}E\xfe\x1fK_\xac\
-\xf3\x07\xc0b=\xfa\xc1x\xb5\x84\x00\x00\x00\x00IEND\xaeB`\x82'
-
-smile32_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\t\xc0I\
-DATx\x9c\xc5\x97il\\\xd5\x15\xc7\x7fo\xde\xbc7\xfbx6\xdb\x93L\xe2\x988\x9b\
-\x81\x10H\xd8\n\xa8-\x90PJ\xcb\xee\x90\xb0\x94B(\x08\xa9\xad\xa0\x85\x82J\
-\xa5\xaa\x1f\xa0\xa2\xa8,\x95\xba( \x81\x08!\x0b!\x86\x8a\xadI\x03\x05Z\xc2\
-\x1ah\x16\x12c\xc7`;\x1e\xc7\x9e}<3\xef\xbd\x99\xb7\xdc~\xb0\xb3\xe1\x80\xaa\
-~\xe9\x95\xae\xf4\xf4t\xef\xfd\xff\xee\xb9\xe7\x9c{\x8f\x14\x89D\xf8\x7f6\
-\xf7\x7f3h\xcd3\xcf\x8at:\x8d\xaeiH\x92D\xa1P\xa4\xd1h\xa0\xe9\x1a\xd9l\x16\
-\xaf\xd7\xcb\t\xed\xed\xa8\xaa\x8am\xdb\x04C!R\xa9\x14\x91H\x84\xe5]WI_\xb7\
-\xb6\xf4U\x16X\xfb\xecz\xd1\xdf\xdf\x8fe\x9aD\xa2Q\x12\x89\x04\xa6i\xd2\xbf\
-\x7f?\xbb\xf7\xec\xc1\xeb\xf5\x92lM\xb2{\xcfn>\xf9\xf8\x13\x96]\xb4\x8c\x13;\
-;\t75!\xcb2\xd9L\x86\\.\x8f\xdb\xedf\xee\xbc\xb9\xfc\xfcgw\x1c\x17\xe4\xb8\
-\x16x\xe4\xd1?\x88\xbe\xbe>\x96,^B"\x11G\xd3t,\xcb\xc2\xa8\x1b\xf8|>T\x8f\
-\x87P(Dkk+\xc1`\x00\x80\x83\x07\x0f2o\xee\\|>\x1f#\xe94\xd3S)\xe6\xcd\x9fO\
-\xb5Z\xe5\xa3\x0f?\xe2\xea\xaek\xc4\xb9\xe7\x9e;\x05\xe4\x18\x80u\xeb7\x8a\
-\xdd\xbbv\x91\xcdd\x08\x04\x83\x94\xc7\xcb(\x8aB\xbe\x90\'\x16\x8d100@*\x95\
-\xe2\x9co\x9c\x83n\xe8\x94\xcbe>\xeb\xed\xc50\x0c\x06\x07\x06Yz\xe1\x85L\x9b\
-6\r\xdb\xb6\xd9\xdf\xd7G\xad\xa6\xe18\x0e\xc5R\x91\xe1\xe1a\x06\x07\x07\xb9\
-\xf2\xaa.\xb1r\xe5JV\\\xd3%M\x01x\xe5\x95W\xe8\xee\xeef\xe1\xc2\x85\x94\x8aE\
-\xa2\xb1\x18~\xbf\x9f\xcf\xfb\xfbY\xb6\xec"\x92\xc9V*\x95\n\xd1h\x94x<\xcec\
-\x8f=FOO\x0f\x99L\x06\xaf\xd7\xcb\xce]\xbb\xb0,\x8bH4J\xa5R\xa5\xbb\xbb\x9bb\
-\xa9\xc8\x9c\x8e\x0e2\x99,\x8a\xa2\xa0\xeb:{\xf7\xee="\x1a\x89D\x88D"<\xb7i\
-\xb3ho\xef\x10\x1e\xaf_\xdcu\xd7="\xdc\x14\x15\xe7_\xb0T\x84\x9b\xa2Br\xb9\
-\xc5\x82\x05\'\x89\xef_z\xb9\x98={\xae\x981c\x96\xb8\xeb\xae{\x84?\x10\x12H\
-\xb2@\x92\x85\xe4r\x8b\xef\\|\x89X\xb8p\x91hk;A\x9cz\xeab\x91hn\x15H\xb2\xf0\
-\x07B\xe2\xf4\xd3\xcf\x14\x92\xcb-\xce8\xe3,\xd1\xb5|\x85\xd8\xb2u\x9b\x88D"\
-G,\xd0\xb3o\x1f\x8dF\x03\xbf\xd7\xcb\xa7\xef\xbeC\x9bdS\xfdl\x1fm\x8a\x0b\
-\x11\x8f\xe2\xd3*\x94v\xef\xc4_\xab\xe1\xb7\x1d\xde{\xa1\x9b\xd9.\x17x}\xe4M\
-\x93\x8am3\xf0\xe9^\x86GF0\x1c\x1b\xa1\xebx\x05\xc4\x90@\xd3\xe9\xed\xed\xc5\
-+\xcb\xe4\xb29Z\x93I\xca\xe5\xf2\xb1Q\xb0a\xe3&\xa1e\xb2\x046>\xcdl*\x04B!\
-\xacX+\xdbX\xcc\xe6\xfa)\xb42\xca\xaa\xe6/\x98\xa3\xd4\x10\xba\x81(\x14A\xd3\
-\x11\xe9\x0c\xf9L\x8e\xf2h\x81}\xca,^\x9b~6\xfd\xb2\x97\xcer?g\xa5\xdf!\\/\
-\x93G\xd0\x87M\xc4\xad0\xe7\xd2K\x98y\xf3\r\\\xff\x83\xeb\x8f\xf5\x81\x95+\
-\x96K\xef\xdd\xb4JL\xa3\x8a\x14\x0c E\xa3lu/&y\xe3O\xd9\xf9\x84\x865>H\xcf\
-\x80\xc2\xf3\xe7\x17\x898uDS\x18gx\x04a\xda\x04\x1a&=\xbe\x0e\x12\x8f\xaea\
-\xc7F0k\xa3\x8cU\x0e0\x16Hr\xe7\xee\xa7\t\xe3\x90@\xa2b9\x94_\xfb;\xd3N>\xe9\
-\xb0\x0b\xb8\x0e}ly\xe0A\x91\xd8\xb9\x1d\xc9\xed\xc6\x15\x0c!\xb9=\xbc\xeb\
-\xcc\xe2\xb6\'4\x1cK\x03 m\xa8\xechx\x91\x12\t\xa4D\x1c)\x1eC\xf2{q\xc5#t\'\
-\xcf\xe7\xce\x8d`\x9b\x06\x00\x02\x89\xde\xd0tz\x02\xcd\xc7\x84\xb8i\x18\x1c\
-\xe8\xfe+\x9b7l\x12\x87\x01^x\xbe[$\xb6nAih`9\x08K\x80\xc7K\x8b\xab\x80=>\
-\x88\xa3eq\xf4,\xaa\x18\'\x10\x0bL\x00\xf8\xfdH>/\xf8}\x00\xa4j\x038\x954N\
-\xa3\x84c\x14q\xac\x1a\xe1\xea\x18Q\xbd0%\xcf\x8c\xf5\xeeg\xfc\xdd\x0f\x8e\
-\xe4\x01W\xb1D =\x88p\t$\x1b\xb0\x04X\x82\xe5\x89Q\xfeU\xf8\x80>#\x82\xaah\\\
-\xb8\xc8\xcbi\x0b\xe7A~t\xca\xa2]\xe3\x1f\xb0o\x8f\xc5\xfb\xb1ET]n|\xc5^\xbe\
-}\xe0\rf:\x16\xd5/\x8dm8.\xd2\xdb\xdef\xf3\xe6\x17\x85\x1b@\x1d\x1cB\xaeV\
-\xc0\xe7A\x98\x0e\x92)\x106\xb4\xc8&\xeb\x97\n\x86|\x02Ob&\xb1\x96\x18~\xe1\
-\xe0L\x91\x87\x80S\xe7\xb7\xe9\x978\xb0\xe7y\n.\x19\xc7\xd6\xf186\xe3\xc7\
-\x19\x8b\xec\xe1`\xdf\x10\x1d\xe9\xf4\x84\x05\x94\\\x0e\xc9\xb4@U\xc0\x14\
-\xe0\x00\x15\x1d\x112p\xe9\x1a\xed\x01?\x92\xab\x01\xb9Q\x1c@\xe4r\x08MC\xe8\
-\x06h\xfa1k\'\xed\x06A[PEP9\x9e\xf8$\x80a\xb9idr\x93\x00c#XB \x8f\x1b\xa0\
-\xd6\xb1\xc7J\xb8$\x15\xf2\x05\x84\xcf;1I\xd3\x0e\xcf\x17\x9a\x86\xc8\xe5\
-\x11\xf9\x02B3p\xf2%\x84^\x07\xbd\x8e\x85\xc0\x02\xcc\xc9n\x1fG\x1c\xd9\x83-\
-\xfb1\xb2\xa5\xc90\xac\x94\xb1\xea6\xaai\xc1\xd88R\x8bLv\xd8M\x8bW\xc7\x19\
-\x1eA\xd2\x8d\t\x87;\x04\xa0\x1b\x88|a"\x0f\xe4K\xa0\x19\x88B\x05\xa17\xb0\
-\x01\x0b\x81\x89\x00\xc0\xc1M\x81\x16`\x18\x1b0\xd50\xb6\xac`\xca^*\xe9\xe2\
-\x04\x80\xddp\xb0\x1c\x81\xd1\xb0\xf1Z\x06\xaf\x0e\\\xc0j\xee\xe4\xba\xec\
-\x0b\\\xb7\xe8\x8d\t\xa1Io\x9f\xb0\x86\x8e\xd0\x0cD\xbe4\xd1\x0b\x15\xd0\xeb\
-\x18\x08L\xc0\x9a\xdc\xb9\x8e`\xb5\xfbe\xf4x\x8a\xc5c\xf7\x92P\xdf\xc4\x94=\
-\xd8j\x18I\xf6#$e\x02\xa0\xde\x9c\xc4\xb0l\x84-\x90\xab\x06#R3\x9a\x12d}\xe1\
-\n\x96|\xf6!\xf3\xdb\xb2\x90/\x1dcI\xe7\xe8\x9d\x17\xc61\xf5\x06\x06\x1c\x86\
-0\x81\xb7\xb8\x9d\x9c\xa7\x13\xbf\xa8RqM\'"{\xb0\xd5\xd0\xc41\xa8\x01\x02\
-\xd3&\xef\x02+\x1cA\xb7\x04.\xcb\xa1n;\x84\x19\xc3\xed3\xc9\x97\x9a\xb9\xd3z\
-\x88K3/qk\xcbjd\xe9\xc8\x89\n\xbd~x\xe7\xa6\xde\xa0>y\xf6:0F\x0bkx\x88\x81\
-\xe07\xa9\xd5\x82$[FH\x16\xdf\xc5RC\xd8\xb2\x8a\xa34!\x84\x89\xaf9<\t0k\x06\
-\x86\xac ;:\x02X\xc0[\xb8\x95\xbb\xf1x\x0cf\xcd\xfa\x82\x97\xd3\x97\xb0\xe5\
-\xe02f\xd4\x078\xd1\xda\xc5\x12e;\x91\xc6(\xed\xf5\x0cu\x04=\x9c\xc4\x10\x1d\
-\xec\xe1lz\xbdgR\xf2\xa4@\x92\x08\xfbJ4\x85\x8b\xa8\x8a\x8e\xdb\x93\xc7\x90C\
-8J\x13\xa6\xec!\xe0\xb1\xf1\xb7\xa7&\x00\xc4\xcc\x14F \x84S\xaa\xd1\x00b|N\
-\xdc\x9f\xa5\xaa\x86\x98?g\x1fw\xff\xf8\x01^\xddv9;\xfe}&\xaf\x16\xaf\xe2U\
-\xae\xc6\x96\xdc\xb8\x03\r\x00l[\xc1%\xdbH.\x87d\xf3(\xdf=g\r\x0b;w\xf2\xc4\
-\x9a\x9f`\xd4\xbd\xa4\xa4\xedXj\x88\x86\x1a\xc2V\xc3\x085\xc4\xf4y\x01V\xdc\
-\xbaJr\x03\\u\xcbM\xd2\xa6s\x96\nkh\x04\x81\x04\xd8,\x93\x9ed\x9dq\x1f\xdb\
-\xdf?\x0f\x10\xdc\xf6\xc3?r\xfb\xcd\x8fQ,\xc6)\x14\x13\x0c\x0e\xb7c\x9a\n\
-\x00\x01\x7f\x8d\xb6\x19\x03\x84\x82\xe3$\xe2YF3\xd3x\xf8O\xf71^\t\xa2*\x16\
-\xb1\xe2\x0645\x8c\xa3\x84\xb1d\x0f\x8a\xc7\xcf\x8c\xf3N\x86\xb7\x8f\xba\r]\
-\x97]\x8c\xf1\xe1\'\x98\xb9<&p\xca\x81\xa7\xd9\x92\\\x05\xaa\xcc\xaeOO\xe3W\
-\xf7?\xcc\xcd\xd7=\xce\x89\x0bv3}Z\x9a\x93O\xdc9%\xbf\xd4\xb4\x00o\xfc\xf3"\
-\x9e\xd9\xb8\x8aHS\x89\xf1j\x84\x94\xb4\x85\xba\x00\xc7\xe5\xc1T\xc38j\x88T\
-\xab\x9b\xd8\xe29\xc0\x97^\xc5\xeb/\xbdF\xe8\xeb\x9eCq@\x06*t\xf0Lj-\x86\xe3\
-\'\x16)ppl:\x1d\xed\xfb\xb9\xec\xe2\xcd\xcc\x99\xddK"\x9e\x01 \x93M\xb2c\xd7\
-\x19\xbc\xfe\xe6\xc5\x0c\xa5\xdb\xe9h\xefc\xff\xc0\\Z\x03\xbd\xcc5~\x8d\xa3z\
-h\xa8a\x1a\xbe\x042\x06\xe7\xafZ\xc2-\xf7\xffr\xea\x9bP]~9\xc6\xde\x1e\xf4\
-\x8fw\xe2\x06\xfc\xf4\xb3"\xdd\xc5\xdf\xda\xffL\xdf\xd0\xa9\x9c\xbap\x07~\
-\x9f\xc6\xd3\x1b~D\xb9\xdaD"\x9a\x03\xa0<\x1e\xa1)\\\xa2m\xc6\x00\xa6\xa5\
-\xb0\xff\x8by\xcc\x0e\xbd\xcet\xfd\xf1\xc3\xe2\x96\x1aB\x92\x15\xe6w*DN\xeb<\
-\xac9\xa5.x\xeew\x8f\x88\xdco\x1e\xc4\x1c\x1dC\x99$4\xf1\xf1R`5\xe3\xb1N*\
-\xb5&Z\x9b\xc7hI\x1c\xa4m\xe6 \x00C\x07N\xe0\xf3\xc1\xd9\xd4\xf4 !_\x89P\xf1\
-\x1ft\xf8\xd7b*\xe1\xc3\xe2\x96\x1a\xa0-^\xe7\xac{\xaf\xa4\xeb\xdak\xa4\xaf\
-\x04\x00Xw\xc7/\xc4\xe8\xea\xa7h\x8ceP\x8e\xfa\xdf \xc0`\xe2Z\x06\x03\xdfc\
-\xac:\x1b\x07\x19\x00\xb7\xabA\xab\xaf\x87&\xed-\xe2\xce\xdb4\xd4 \x8e\xeb\
-\xc8\xce-\x97\xcc\xccf\x87\xd3\xef\xb8\x8c\x95\xb7\xdcpL]\xf0\x95\x95\xd1\
-\xc6\x07\x7f/F\xff\xf2$\xa5O\xf7"\xec)W\n0\x91n\x1bj\x08K\xf6`\xa9!L\xd9CC\
-\x9d\x8cu5\x8c\xa5\x06q\x99e\xe6\xceS\xe9\xbc\xe5\nV\xac\xbaqJu\xf4\x95\x00\
-\x00\xcf\xaf]\'\xc6_\xdb\xc6\xe8+[)\x1d8\x80\xe3\x1c\x05"Ox\xb59\x99^\x0fe8[\
-\x9d\x085YQ\x88\x055\xe6_0\x9f\x96\xa5\xe7q\xf5\xf2\xab\x8f[\x9a}-\xc0\xa1\
-\xb6\xe9\xa95\xa2\xb4\xf5\r2\xdb\xdf\xa7:\x96\xa3VkP\xb7\x04\xb6\xdb\x87\xad\
-\x04AV\x10J\x08\xb7\xea\xc2\xe7s\x13\x9b\x91$\xf5\xadE\xc4\x96,8\xe6\xbc\xff\
-g\x80Cm\xf3\xe6\x17\x85S.S\x1f\x1a\xa6\xba\xef3L}"\x13:\xc2A\x89F\x89\x9e~\n\
-J<N\xd7\xf5+\xbfV\xf4\xe8\xf6\x1f\xef}\x9b\xb7\xd0cu}\x00\x00\x00\x00IEND\
-\xaeB`\x82'
-
-smile48_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\x08\x06\x00\
-\x00\x00W\x02\xf9\x87\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\
-\x0c4IDATx\x9c\xed\x99{\x8c]\xc5}\xc7?3\xe7}\xef=\xf7\xe1\xbb\xde\x97\xd7\
-\xbb`{\xc1\x0b\xb10\xc6(\x01\xb2n\xa9 Ai"\x82[\x05E$\xfc\x83\x10Hi\xa5(j\xd4\
-H\x95\x9a\xaa\xad\x10i\xffI\x9b\xaaJj(\x15(~cC\xc2#H\x01c\x8ay8\xc5\xbb\xe0\
-\xf7zm\xaf\xd7\xbb\xeb}\xde\xdd\xfb\xbe\xf7\xbc\xa6\x7f\xec\x82\x85H\xbb\xbb\
-\xbe+\xa1J\x1di\xa4\xa393\xe7\xf7\xfd\x9e\xdfc~3?\x91N\xa7\xf9\xbf\xdc\xe4\
-\xe7\r\xa0\xd1\xf6\xff\x04>\xef\xa6\xaf\xf4\x07\xf7\xefyF\xd5\xf2g\xa9\x15\
-\x06\x11\xc1,Am\x14+\xd1\x81\xe1\xac\xc1L\xde\x88\x11\xdf\xc07\xb7\x7fK\xac\
-\x94<\xb1RN|\xe0\xf9\xdd*w\xf9u.\x9d\xd8CX\x1b\'a{\xd8\x16d\xdc\x85\tJ \x8d\
-\x18V\xeafd\xf6~\xcc\xf4\xed+BdE\x08\x1cx~\xb7:q\xf8o\x99\xbc\xfc;\x1c\xd3\'\
-\xe3\xce\x03O\xbb\xe0X`\x9bW\xe7\xd6<\xa8\xf96\xa1\xfb\x87\xc4\xaf\xffA\xc3$\
-V\xc4\x84.\x1d\x7f\x8eK\x83G\x89Y\xc1\'\xe0\xdb\x9a\xe6\x81g\xdc\xcf\x12\x98\
--\xd6\xa8\xd5\xdf\xc0\x9f\xd9\xd4\xb0\xec\x86\x9dx\xc7?\x7f_\xf5\xbd\xf7\x02\
-\x9a\x9c\x07o[\xf3\x7f\xde6\xa1-\x0b\xd9\x14\xc4\x9d\xab=\x9b\x9a\x1f\xb7\r\
-\x0fr\x078\xb0\xe7\x17\xeas%p\xee\xc3\x17\xf1je,\xe3\xea\x1fw\x16l?\xee\xfc\
-\xfe5qg\xfe\xbd\xee_ *\x1emH~C\x04\xf6\xef}VM\x8c_\xfe\xcc\xb8m~\xdal~_\xb3M\
-p,EX9\xd7\x08\x84\xc6\x08\xa8(\xc4\xf3\xfc\x86\x00(\x7f\xb6\xa1\xf5\r\x11\
-\x98\x9d:G>_n\x08@!7\xc4\xf3\xfb~y\xcd~\xd0P\x14:=0N\xad\x1ea\xe8P\xaeA\xbe\
-\x0cRB\xa9\n\xd3ypcW\xe7\xda\xb6\x8dm\xdb\xe8\x9aF\x10\x86\x9c\x1f\xf18>Pa\
-\xf0\xca4_i\x99\xbcf\x0c\xd7L\xe0\xc5\xfd\xff\xa1\x9e\xfe\xc5\xbfp\xe0p\x04\
-\x80e\x82\xa1\xfd\xcf\xf3{z\xae\xa7\xb7\xb7\x97m\x7f\xb0\x8d\xb7\xdey\x8bCo\
-\xbeM\xdf\x87\xa7\xd0\xb4:\xb7\xf6\x9e\xe4\xd7/\xeeR\xdf\xb8\xff\xdb\xcb\xde\
-\x13\xae\xc9\x84\x9e\xfd\xa7\xef\xaa\x96\xdaO\xd9\xbc\xee\x12=\xeb\xe2$b:\
-\x86\xa1\x834P\x18\x94\xaa|\xa6W\xea\x92\xd1\xf1<o\x1cz\x97\x89\xa9<\x9af\
-\x90LX|q\xf3\x1a6\xb6\x0e\xb3V\x7f\x81}O\xff\xd9\xb2Mi\xd9\x1ax\xf6\xa9\x7fW\
-\xa3\xa7\xf7\xf0\x9fo\x0c\xd2\xda$x\xf8\x8f\x93\x94k\x82\xe6&\x87d\xc2! \xc6\
-\xe8T\x80mY\x98\x96\x85\x94&R\xea(i\x92J%X\xdf\xa1\x90!\xe4\xf3-\xcc\xe4\x12\
-\xe8\x94\x19\x1e\xec\xe7\xc3~\x8d\xd6u\xbd\xcb\x85\xb3<\x02;\x9f{Ni~\xc8\x8d\
-\x9b\xbfKP\xedd\xf0\xa3~\x08s\xe8\xa2\xce\xc8\xa8B7\x02\x1cw\x06KJt\xbd\x82\
-\xd0\x04RJ4MC\x97\x82`f\x88\x81s\x1a\xb99\x9b \x84z\x18Q*8\xf85\x87P\x18l\
-\xb8\xe5\x0e`\xef\xb2\x08,9\x17\xda\xb7w\xaf\xcaOL\xb2*\xbd\x8a\xd3\xc7\x8eq\
-\xea\xdd\xf7@\x85\x84\xf5*A\xad\x8a\n|\xd2\xe9$J)\x04\x1aa\xf4\xf1J\tRC\n\
-\x81\xd4@\x13\x12t\x89\x10\x82H\x80PP+\x97)\xe5\x8b(\xdbf\xfb\x0f\xbe\xcfw\
-\x1eyd\xc9\xbe\xb0d\x1f\x98\x19\x1f\'\x1eO0|\xfe"}\xef\xbcK\x14}\x82\x10!%\
-\xba\xae\xa3\xe9:\x86i"u\x1d\xa9ih\x0bc\x9a\xbe\xf0\xaci\xc8\x85\xae-\xbc\
-\x97\x9aF\xdcu1-\x93\xcaL\x8eC{\xf7\xf1\xc2\xc1\x83K\xf6\x85%\x99\xd0\xb3\
-\xcf<\xa3T\xbdN\xa5T\xe2\x9d\xd7\x0fQ\xcc\x17\x88[&R(\xa4RX\x96\x85!%BjD(4MC\
-H1\xaf\r\xa1\x81\x94H!\xf1B\x0fG\xd7@\x93H!@\n\x84\x04\xa1\x14\xa9t\x860TL\
-\x9f\xbf\xc8\xc0\xf1\xe3K\xc5\xbf4\r\x94f\xa6\x11\x08~\xfb\xf2\xcb\\\x1c8\
-\x87R\n?\x0c\x18\x99\x9be \x97\xe3\\\xbe@\xce0xu`\x90\xdf\x9c9G$%\x8e\xe3\
-\x10O$\xb0c\x0e\x96ms\xa5T\xe0W\'\x8eslr\x82\t\xcf\xa3\x7ft\x94\xf7/\\`\xa2P\
-\x00)\x89\xbb\t\xda\xdbZ\x11Jq\xe4W\xbf^\xb2\x16\x16\xd5\xc0\xfe={Tqr\x82\
-\xc2\xec\x0cC\xa7\xcf"\x80\x9a\xefs|r\x8c\xf3\xa3#x\x9e\x07\x80a\x18\xf8\xbe\
-\xcf\x9d\xb7\xdf\x8eeZ\x08)A\xcc;q\xa4 \xb5*\xcb\xf8\x7f\x1d\xe5\xfc\xc8\x08\
-\xba\xae\xe3\xfb>B\x08R\xae\xcb\xd6\xeen\xfeh\xe3M\x18\x9a\x8ea\x1a\xe4\xa6\
-\xa68\xf2\xe6\x9bK\xc1\xbf\xb8\x06\xfcj\x05\x15\xf8L\x8e]\x01\xa50M\x93+\x95\
-"g\x86.\x12\x04\x01\xb1X\x82\xf6\xf6N\x92\xc9\x0cn\xc2\xa5;\xe5\x12\x85\xc1<\
-\xf8\x05[\x97R\x92\xd2u\xba;:\xb0m\x87\xa6l\x0bm\xad\x1d\x98\xa6\xc5\\\xa1\
-\xc0\x91\x93\'\x99\xacV\x90RbY\x16A\xdd\xe7\xec\xb1\xbe%\x11XT\x03~\xa5\x8c\
-\nCf\'\'H\xc4\xe3\x08\xa5\xd1\x1c\xe9\xdc\xb5\xf5\x0e\xe2\xc9\x0c1\xc3\xc4\
-\xb4l\x94\n)\xcd\xcd\xe2\x196\xc5P\x91\xf9\xf8\x03B\x12\x112^\xf1\xf8\xd2\
-\xedw\xd3{\xa7A(utM\x92\x9b\x9dfrf\n+\xac\xd1\x92J#\x95"\x16\x8b\xa3P\xcc\
-\x8e\x8f\xb3c\xc7\x0e\xf5\xe8\xa3\x8f\xfe\xaf\x11iQ\x02\x91\xef\xa3K\x81\xa5\
-i\xb8\x89\x04U?\xc2p\xb2\xac5tz\xd6v\xa1\x87ut)\x90*\xc2\xbc\xa1\x9b\x81\x91\
-\x11N\x8f\\fu\xa9\xc2\xe0\xe8%R\xf1\x04\xa9\xd5\x1d\xac\xbd~#=\x9d\x9d8""\
-\xf0\xabH)\t\xda\xb3\xcc\xd5\xd630:\xc6D\xbdF\x97\xa3\x93t\x13h\xa6I\x04\x0c\
-\r\r-\xaa\x81\xc5\x9d8\x08\x88\x82\x00\xbfRf$_`Z\t\x0c)\xd9\xb4~#\xa1W\xa5^)\
-P\xc9O\x13\xd6\xab\xe0\xd7\xd9r\xd3\x17\xb8\xed\xe6[\x98\xae\xd7\x19\x99\x99\
-f\xacP\xa0s\xfdM\xdcy\xcbVb\xa6N\xe8W\x89\xc2:^%O\xe0UH\xdb\x06[\xbao`\xba\
-\x1epdd\x9c\xa9j\x15\xcb4\x91J\xe1\xd5j\x8d\x13\x88\xc2\x90Z\xb5\xc2\xdc\\\
-\x8e\xa0^\xe5\xe2\xa5A6\xae\xef\x99\x0f\x83JQ\xafU\xf1}\x8fz\xbdB\x18\x05DQ\
-\x84\x1bO20t\x91G\xbe\xfe\x15\xdc\x98\xc5\xf1\x93\x1f0W\xcc\xcf\xef\x13\x86\
-\x85&@j\x12\x15\x85h\x9a$\x93L\xd2\xde\xdcFan\x1a\xd7q\xf0\xc3\x10/\x08>\xb5\
-\xd7\\3\x01?\x8c\xa8\xd7j8v\x8c\x94&\x88\xbc:\x02\x85\x14\xf3\xf1[\xd7-\x14\
-\x02\xa5\xe9\xd4\xbd\x80\xc1\x8b\x83\xec\xd8\xf5o\xacJX|\xe7\xeb\xf7\xf2\xbd\
-\x07\xefg\xf8\xf2\x00O\xef\xfcW\xaa\xb5\n\x9a\xa1a;1\x0c\xcb\xc4t\x1c\x84\
-\x9cwt\x85\xa2\xbb\xbd\x8d\x98m3[.\x11\x08\xd0\xf4\xc5\xb7\xa9E\th\x96E\xe0\
-\x05\xd8\x8eC\xd6qp\r\x8d\xbe\x8f\x8eb[6\xae\x9b\xc6\x89\'HfZ\x88\xb9\xab\
-\x98\xadz\xec\xf9\xcd\x8b\xdc\xb7\xf9F^z\xf2\xafX\xd7\xd5\xc9\xb7\xff\xf4\
-\x9b\x1c\xfc\xc7\xbf!\xa6G\xbcz\xe8%\x94n\x10\xe9\x06\xba\xe3b\xdb\t\x9c\xb8\
-K\xc9\xf3\xe8;\xfe\x01m-\xcdxB\xa1t\r\xa5\xeb\xf3\xa1\xb8Q\x02F,\x06J\xcd\
-\xc7v"\xbe\xd0\xd2\xcc\x85\x0b\x03|p\xb2\x0faX\xa4\xb2m\xb8\xd9V\x8cx\x86\
-\xd7\xdf=DO{\x13\x7f\xff\xf0\x9f\xd0\x94r!\xf0Q\x85<\xdd\xed-\xfc\xc3c\x0fs\
-\xf4\xc3~^{\xfb0N2K<\xb5\x9ax\xa6\x99\xc8\xb0x\xff\xa3>\xdaR\x0em-\xcd\xcc\
-\x14\x0bxa\x880\x8cE\xc1\xc3\x12\xa2\x90\x93L\xe2y>RH\x0c\xc3 )%[\xdb[8}\xf2\
-\x18\xfd\'\xfbi\xce\xaefMK\x1b\xa3\x93cL\xccL\xd2\xeev\xa0+\x05\xb5\n\x9f\
-\xdaJ\xbd\x1aQ\x14\xf1\xde\x07\xefs\xfdu\x1b0\x0c\x83\xf1\x99\x19fg\'ivmn\
-\xdd\xba\x05\x84`fnv>\x1d\x89\xc7\xd0\x97`B\x8b\xce0l\x07a\x9aD*$\x1eOP*\x14\
-I\xd86w\\\xd7E\xd1\xf7\x89\x00Y\xce\xb1&n3\x9eH\xf0\xf6\xd9\x0b\xfc\xc5S\xbb\
-\xf8\xde7\xeee\xdd\x9aV\xaa\x9eO\xdf\xf9K\xfc\xdd\xae\x17\x11(\xb6\xf6t#j\
-\xd3\x10\xeat\xad\xb2\xb9\xa3g\x0b\x9a\xd4(\x97\xcb\xcc\xe4r\x8cNN\xa2[6\xd2\
-\xb2\xe9\xec\xecl\x9c\xc0\x03\xdb\xb7\x8b\xa7~\xf635~\xfe<\x86\x13C+/\x1c\
-\xe2\x85 \x1d\x8b\xa1\x1b\x06\xbaa\xa0\xe9:\xa5 `*_\xe0\x95c\'x\xa5\xef\x14m\
-\x99$\xd5\xba\xc7\x95\xb9"\xa6\xaeQ\x0b\x15]\x9d\x9dt\xb4\xb6b\xda\x16\xb6ec\
-\xd9\x16\xbe\x1f\xe0\xf9>G\xfb\xfa(U\xabd\xd7\xac\xa5\xb3\xb3\x93\xc7\x1e{l\
-\xd1\xb4zI\xd9hv\xcd\x1a\xccl\x96\xd9\xa9I\x84n@\x14"\xa4\xbc\xda\x17r\x9e\
-\xee\xd6V&K\xdd\xbc\x7f\xe2\x04\xba\x80\\\xa9\x8c@\xa0P(-\xc6\x83\xf7\xdd\
-\xcb\xf5m\xad(\x14\x9eWG\xd3t,a#\xa4\xe0\xf4\xc0Y\x06\x87/\xe3\xc4\xe3\x98n\
-\x82\xeb\xae\xbbn)\xd0\x96~\xa0yf\xc7\x0eux\xdf^\xaaS\xd3\x18BbY\xe6\xfcIkA\
-\x03\x1fk\xc1\x0fC\x86\xa6\xa6\x98,\x95\x98+\x97I\xc4b\xb465\xd1\xd5\xdcD{\
-\xf3jL\xd3@\x01a\x14\xe28q\xdc\x94\xcb\xc8\xe5\xcb\xec\x7f\xe9U\xca\xf5:M\
-\x1dkY\xb7\xb1\x87\x9d;w.\xe9P\xb3\xac\xdb\xe9\x9f\xfe\xe4\'\xea\xd0\x9e\xdd\
-\xa8r\x95t2\x89m\x99\xf3\xe0u\x1d\xdd41\x0c\x830\x8a\x08\x95B\xd3u,\xcb\xc24\
-M\x0c\xcbBHP(L\xcb$\x8a"\xbc\xc0\xc7\xb2\x1dj\xb5*\x87\xdf?\xca\xe5+\xe3\xa4\
-V\xb7`\xa53<\xf4\xd0C<\xfe\xf8\xe3K"\xb0\xac3q\xd7\r7p\xeb=\xf7p\xec\xb7\xaf\
-3\x91\x9b!f\x98\xb8\xaeK<\x11Gj\x1a\xb50D3\x0c\xcc\x05\x8d\x08!\x88\x94\xc2\
-\xab\xd7\x91\xba$\x0c|\x84\x8a0-\x13\x82\x90\xbe\xbe~>\x1c8\x8b\x1fF\xacji\
-\xc5H\xa7\xe9\xed\xed]2x\xb8\x86\xfa\xc0\xc1\x03\x07\xd4\xe0\xa9S\xbc\xf9\
-\xc2\x0b\x14FGqL\x93\xe6\xa6&\xd2\xe9\x0cB\x93W\xcdI\xd3\xd0\x16HH)\x91R\x00\
-\x11(\xc5L.G\xff\x993\x8c\xcf\xcd\xa1\x9b&\xa9\xd66\x0c7\xc9]w}\x99\'\x9f|rY\
-wC\xd7\\\xe0\xd8\xf1\xf3\x9f\xab\xc3\x07\x0f2|\xea\x14\xa6\xd4\x16\xec? \x99\
-L\x92M\xa7q\x1c\x07\xc30PBP\xad\xd5\xa8T\xca\xe4\xf3s\\\xc9\xcdP*\x14\t4\r7\
-\x9d\xc6iiEZ6\xbd\xbd\xbd<\xf1\xc4\x13\xcb\xbe\xd8j\xa8B\xf3\xfc\xfe\xfdjx\
-\xe0\x1c\xaf\xec\xdc\x89\x0c|.\x0c\x0e2\xedy\xb4$\x93$]\x17MJ\xbc \xa0\xe6yx\
-\xbe\x87\xeb8\x9c\x19\x1d\xe3\xb6u\xeb\x18\x1e\x1e&\xb3i\x137\xddr\x0b\xdb\
-\xb6m[\x96\xd9\xac\x18\x81\x8f\xdb=\xb7\xdd\xa6:\xae\\\xe1G\x99\x0c\x87-\x8b\
-]\xc5"\xd3\xc3\xc3T,\x8b \x08\xd04\x8dD\xb9\xcc\xb6\xaf}\x8d\xf5o\xbd\xc5\
-\xed\xad\xad<44\xc4\xcdw\xdd\xc5\xab\x87\x0e5TbZ\x912\xab\x93JQT\x8a\xec\xd0\
-\x10\xdf\x12\x82\xbfv]\xc6\xcbe\xb4L\x06\'\x95\xc27M\x92\x1b6\xf0h\xb1\xc8\
-\xc3--\xac\x8a\xc7\t\x95b\xd3\x96-\r\xcb^\x91\x1a\xd9\x8d\x9b61\xecy\xd4\x86\
-\x86\x90A@\xe2\xd2%\xc2Z\r16\xc6\xadMM\xbc^(\x90\xae\xd7\xf1\x84\xa0R.3U\xab\
-\x91jo\xa7\xad\xa3\xa3a\xd9+\xa2\x81\xb6\xceN\xc6fg\x99\xeb\xea"\xd6\xd6F{S\
-\x13\xc9\xd5\xab\x19*\x958\x92\xcb\xa1\x0c\x83T"\xc1\x86X\x8cX{;\x17\x85\xa0\
-\\,\x92\xcdf\x1b\x96\xbdb\x85\xee\xcbccT\xebu\x82J\x85\x1f\x9d?\xcfd\x18\xf2\
-\xe7?\xfc!\xed]]\xfc\xee\x8d78\xd6\xd7\xc7\x91\xe1a\xbe\xb4y3^\xb1H87\xb7\
-\xa4ls\xb1\xb6"\x04b\xb1\x181\xc7\xe1e\xc3`(\x97\xe3\xadL\x86\x07\xbf\xfaU\
-\xbe|\xf7\xdd<\xf0\xc0\x03b\xf7\xee\xdd\xaaX(\xf0\xf0\xe1\xc3<25\xc5P\x14\
-\xd1\x12\x8baYV\xc3\xb2W$\n\x1d<xP\xbd\xf7\xdak\x9c9s\x06]\x08\xbex\xcf=l\
-\xe8\xe9a\xfb\xf6\xed\x9fD\x98}\xfb\xf6\xa9\x93\xfd\xfd\xbc\xf9\xca+\xd8\xb6\
-\xcd\xdd\xf7\xdd\xc7_\xfe\xf8\xc7\rW\xea\xff\x1b\xd5\xe8\x0b\x01\xe7z\x82m\
-\x00\x00\x00\x00IEND\xaeB`\x82'
-
-up_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\
-\x03IDATx\x9c\xc5\xd7\xcdo\xdbd\x1c\xc0\xf1\xaf\x1d\xbb1v\xd2\xae\xac\x1b\
-\xd36\x10\x1b &!\x90V4\x06H\x1c&n\x08\xf1\x0f \xe0\xca\x15\x0e\xfb/8#.\x88\
-\x0bB\\&M\x88\x0b\x87ich\x0c!\x0e\x83\xb2\xc2\xd6\xb1\xf5}I\xd3.m\x12\xe7\
-\xf1\xe3\xe7\x85\x83\x9b\xbe\x904q\xb2\x03\xa7\xc4y\xfc\xf8c\xe7y~/v\xbe\x9b\
-m\xd9WO\x86$\x1a\xda\n\xa4\x86D\x834\x90l\x1fK\x93\xfd\x16\xa7\x90n\x8fw\xce\
-\xe9\x1c\x0b\x95\x8dw\xc6\x84\xde\xbe\x96\xca\xbew\xe6w\xce\xed8\xae\xb1\xf6\
-\x7f\xc3\xb3\x1b0\x8f\x87ol\xc5\xfc}\xef\xc1H8Z\xe2Jm\x1f\xeb\xc9\xff\x98\
-\xf9\x93\x9b?\\\xa2)\xe4\xd08*\xc15vt\xbc)4\xf7f~\xa3\xb1\xb6\xcc\xd2\xf2\
-\xca\xd0\xb8U\t\xae6\xa3\xaf\xf9j\xb5F\xbd\xb2\x80q\n,\xcc\xfd54\x8e\x8c\xb7\
-7\xe1\x88\x1bn\xee\xce,Jk\x9c\xb1\x88\xfa\xda*\xf5Fk(\x1c-q\x95\x19\r\xdfj\t\
-V\xfe\xb9\x8d\xe3\x87\x10\x8c#\x95fm\xad:\x14n\xb3=`G\n\xb5\xc5\xa5E\xda\x8d\
-:\x04\xe3P,\xe3\x04\xe3<\xaao"R\x93\x1bG%\xb8\xca\x8e\x10\xe7\xca\xb207\x8b\
-\xf5\x9e\xd8\xc1\x9dh\n\xa9\x0c\x8dv\x92\x1bG\xcb,\x0f\x0c\x9bd66\x1b4\x1e\
-\xad\xef\xc3)\x96\xb1~H[\xc8\xdc8*\xc1K\x8d\xc5\x1b\x02\x97\x1aV\x96\x16\x91\
-J\xef\xc3\x9d\xa0\x0c\xc18\n\x0f\x9b\x13G%\xb8\xd6\x0c\x87\xc7BQ]Y\xe8\x89;\
-\xc52v,\xc2C\xe5\xc2\xad\x96\xb8j\xbb\x16\xe4\xcd\xed\xd5Z\r!DO\x9cb\x99\xc8\
-\x87\xc8w@\xc9\x8182\xdeMDy\x0bKm\xad\x82-N\x1c\x88\x87>L\x85.\x91\xa7\x07\
-\xe2\xa8\x04W\xdb\xfcx#\x164c\xd1\x17?T\x84R\xd1a\xaa\\\x1c\x88\xef\xe4\x81\
-\xbc%u}c\x93\xd4\x16\xfa\xe2\xa1\x0f\x91\x0f\xc7\'C\x82\x82\xed\x8b\xa3e\xb6\
-\x04y\xf0\x964l5\xb6p\x8a\xa5\x81x\xe8\xc1\x91\xb2\xc7\xb1\'\xcb}\xf1l\t\x8c\
-\xcd\xd5L4[\x02\xa9\xc9\x85G>\x94|\x87\x17OLR\xb0\xea@\x1c\x95\xe0\xeeM@\xfd\
-\xeay3nc\xc7\xa2\\xg\xec\xf4\xd1\x88\xa3\x93\xa5\x03\xf1\x9d\x7f`\x10\xdeN4"\
-5C\xe1\x91\x0f\xc7J\x05\xa6_8q n\xb5\xcc\xa2`P\'\x13\')\xc6\x0b\x86\xc2\x0f\
-\x15\xb3\xcf\xe9\xd3SLDAO\x1c\x19\xe3*c\x07w2\x86\xbex\xe8\xdb\x9ex\xe4\xc3\
-\xa9\xc3E^9s\xaa\'\xbe\xdb\x92\xf5\xc1\x852\x98B\xd0\x13\x1fs\x0c\x0fk\x1b\
-\xcc\xcc-\xd1l\xc5]x\xe8\xc3D\xd1\xe1\xed\xb3\xcf\xe1;\xa6;\x1at\x82\xa7\x8c\
-\xed\xdbFI\xe3v\xe1\xa1\x07B\xb4\xb9\xbb\xfc\x90j\xb5\x8aM\x05\xab\x8b\xf3\
-\x9c=\xf3\x0c\x17^:N\x14z\x84>\x94\xb6\xe7\xbdvj\x82\xe7\x9f}\x9a\xdb3\xb7\
-\xf6\xe1Y?`\x0e\xc6\x13\rA\xc1\xee\xc3}4+\x95\x1a\xb7n\xdf\xa5R\xa9`S\x01*\
-\xa1\xd9\xa8\xf3\xd3\x8d\x9b|y\xf9*\xbf?\xa8\xe1\xbbv\xcffty\xef\xc2\xb9.\
-\x1c\xb5\xa7\x1f\xe8\x85\x17\xac\xa24\x96\xe1A\xc1\xd2n\xb5\x98\xbd\xb7\xc0\
-\xfd\xf9\x05R\x11w\xad\xa9M\x13\x16\xe7\x1f\xf0\xc5\xd7\x97\xf8\xfc\xf2/\xac\
-\xd6Ev\xf3\x01\xbc;}\x92\xa7\x8e\x1c\xde\x87gy\xc0\xd8\x9e8Z\x12z\x96\xc9\
-\xc0\xc15)\xcb\x955\xee\xdc\x9f\xa7\xb1\xf9h`zU\xa2\xc5\xb5kW\xb9\xf8\xd9W|{\
-\xe3>\xad\xc4\xf0\xf21\x9f\x0bo\xbd\xb9\x0fG\'8\xef\x7fS\xb1?\xd6\x8fv\xe1\
-\x05#9>\x19\xa0D\x9b\xda\xfa\x06I\xbb9\xb0\xb0\xf4\n5\'\x15\x9c?7\xcd\xa7\
-\x1f\xbc\x83\xd6\x86\x0f?\xfe\x04\xd9\xda\x04\x9d\xcd\xf1\xb4\xb5={8l\xcaz-&\
-nma\xd2\xc1U\xed\xa08\xb7*\xe1\xe7\xebW\xf8\xe8\xd7\xeb\xbc~\xfe\r|\x17\xa4\
-\xdemV<m\xbaq\xab\x12\x94\x8cQ9\xeay?|\xef\x86\x8b\xeb\r\xae|\x7fi\xe7\xc9w\
-\xdf\x0bl\xfe\x06rT|\xef\x9a\xff\xf7\xfa\xff\x02\x1b\x95\x05yYu\xd8\x0c\x00\
-\x00\x00\x00IEND\xaeB`\x82'
-
-
-tick_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x03\
-\x02IDATx\x9c\xe5\x97?HzQ\x14\xc7\xbf\xf7\xf6\x93\x1e\x0f\xc4G\x7f\x96\x86\
-\x04\xdb\x0b\x1c\x9a\xda\x83\x94H\xa1(!\x90\x8c\x0c\x87 r\x89p\n\xc1\xc9%\
-\x08\x8apI4\xa8\x1e\x91$\xe5\xd0\xd4\x14\x15A A\x04\r.\x12TC\x96\x10t~\x93\
-\xef\xa7\xe9\xf5O\xbfg\x0e\x1d\xb8\xf0x\xf7\x9c\xf3\xf9r\xee\xb9\xf7\xdd\xc7\
-\x14EA+\x8d\xb7\x94\xde\n\x01\xc1`\x90\x86\x87\x87imm\x8d\x00\xe0\xcfO\x81#\
-\x91\x08\xed\xed\xed!\x10\x08\xe0\xe9\xe9\t\x16\x8b\x05?"@UU:;;C \x10@:\x9d\
-\x06\x11\x01\x00\xde\xde\xde\x9a/@UUJ$\x12\xd8\xd8\xd8\xd0\x80\x05\xbb\xbf\
-\xbf\x07\xd0\xc4\x1e\xa8\x06\x07\x00I\x92\x9a\' \x16\x8b\xd1\xce\xce\x8e\x10\
->00\x00\xa7\xd3\t\xa0\tK\x10\x8b\xc5hss\x13\x87\x87\x87\xf8\xfc\xfc,\x9b\xef\
-\xe9\xe9\xc1\xfc\xfc<|>\x1f\x03jT`\x7f\x7f\x9f\xf4\x86\xfb\xfd~,//\xb3\xc2;\
-\xf6\xf5$TU\x95nnn\x90J\xa5`0\x18055\x05\xaf\xd7\xcb\xca\xb25\x087\x1a\x8dXY\
-YA(\x14*\xcd\xa5(\x8a6\x92\xc9$\xb9\\.2\x1a\x8d\x04\x80\x00\xd0\xd0\xd0\x10\
-\xa5R)*\xf6\xfb:\x92\xc9$\x8d\x8d\x8d\x11\xe7\\\x8b+\x1e\xb2,\xd3\xe2\xe2"\
-\x9d\x9e\x9e\x96\xe5\xd1\x1e\x8e\x8f\x8f+&\xe9\xea\xea\xa2x<.\x14P\x0b.I\x92\
-\x10\xae(\xca\xbf\x1e\xb8\xbc\xbc\xc4\xd1\xd1QY\xf9^__\xf1\xfc\xfc\\\xb1\xec\
-\xaa\xaa\xd2\xc1\xc1\x81\xb0\xec\x9cs\xd8l6\x8c\x8c\x8c\xc0\xe9tV\\FM\xc0\
-\xc5\xc5\x05>>>\xca\x1c\xf2\xf9<\x1e\x1e\x1e*\xc2\x13\x89\x04\xa2\xd1\xa8\
-\x10>::\n\x8f\xc7\x83\xf1\xf1qa\x0fi\x02\xf2\xf9\xbc\xc8\x07www\x15\xe1\xa2}\
-\xce\x18\x83\xddn\xc7\xdc\xdc\x1c\\.W\xd5\x06\xae\xeb \xcaf\xb3\xda\x96\xdc\
-\xde\xde\xa6\xad\xad-!\x1c\x00\xacV+\xdcnwM8P\xe7A\x94N\xa7\xd9\xf5\xf55\x85\
-\xc3a\n\x06\x838??\xafX\xf6\x02|ii\t3335\xe1u\x0bxyy\xa1P(\x04\xce9\xb2\xd9\
-\xac\xd0\xcfj\xb5\xc2\xef\xf7k\xa7\x9cn\x02\x00\xe0\xf1\xf1Q8\xc79\xc7\xe0\
-\xe0 \x16\x16\x16\x1a\x82\x97\x08hkkk$\xae\x04^\xe8\xf6\xe9\xe9\xe9\x86\xe0%\
-\x02\xfa\xfa\xfa\xbe\r\xaf\xa7\xdb\x859\n\x0f&\x93\t\x8c\xd5\x9fC\x0fx\x89\
-\x00\xb3\xd9\x0cY\x96\xeb\n2\x18\x0c\xba\xc0\x81\xa2%\xe8\xee\xeeFgg\'r\xb9\
-\\\xd5\x00Y\x96\xe1\xf1x`\xb3\xd9099\xf9_p\xa0\xa8\x02\x92$\xa1\xb7\xb7\xb7&\
-\xdc\xeb\xf5\xc2\xe1p\xe8\x02\x07\x8a*011\xc1\xd6\xd7\xd7\xe9\xfd\xfd\x1dWWW\
-\xda\xed\xb5`\x1d\x1d\x1dp\xbb\xdd\xb0\xdb\xed\xc2\x0f\xcbw\xac\xecB\x12\x89\
-D(\x1a\x8d\xe2\xe4\xe4\x04\xb9\\\x0e\x8c1X,\x16\xf8|>\xac\xae\xae\xea\x06\
-\x16\n\x00\x80\xdd\xdd]\xba\xbd\xbdE&\x93A{{;\xfa\xfb\xfb1;;\xab;\\(\xe0\'\
-\xed\xf7\xfd\x9c~\xb5\xbf\x8a\xf3q\xb2q\x86\xa0|\x00\x00\x00\x00IEND\xaeB`\
-\x82'
-
-
-cross_png = \
-'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
-\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x03\
-\x9fIDATx\x9c\xc5\x97OH*_\x14\xc7\xbfW~\x82\x8c\x19Sh\xc2\x80\x8b\xfe\x10\
-\x04A\x90P.\x84(r\x13ER\x14\x11\x18A\x11\x14\xba0\n\x83B\xa1\x90\\\x88\xa5\
-\x05\xe5B\x11%7\x89\x14B\x08\xc2\xac\xda\xb6\x88V\xd12\xb0M\xb4jWx\xde\xe2a<\
-_3\xe3(\xef\xf7\xde\x81\xb3P\xef9\xdf\xcf\x9d+\xdfs\x87\xf1<\x8f\x7f\x19\x9a\
-\x7f\xaa\xfe7\x01\x82\xc1 \xcd\xcf\xcfS<\x1e\xa7_\xbfg\xf5\x8e \x9dNSKK\x0bf\
-ffX3\xc2\xc9d\x92r\xb9\x1c\x8a\xc5"\xde\xde\xde044\x84\xbd\xbd=,--1Y\x80t:M\
-\x8c1\xdc\xde\xde\xe2\xea\xea\n\x13\x13\x13\x98\x9a\x9aj\x18\xe2\xf0\xf0\x90\
-\xe2\xf18\xee\xef\xefA\xf4s\xe3Z\xad\x16\xa3\xa3\xa3\xb0\xdb\xed\xb0\xdb\xed\
-\x00\xcf\xf35y||L\xfd\xfd\xfd\xd4\xd3\xd3C\x1c\xc7\x11\x00\xe28\x8e\xbc^/\
-\x89\xa2H\xbf\xaf\x97\xcaR\xa9D>\x9f\x8f\xccf3\x01\x90L\x8e\xe3(\x18\x0cRM\
-\xe1\xc9\xc9\t\x19\x8dF\xd9\x025\x10\x85B\x81fggI\xa7\xd3\xc9\x8a\x03 \xa3\
-\xd1H\x89D\xa2\x16\xe0\xe2\xe2\x82:::\x14\xa9\x95 \xb2\xd9,\xd9l6\xd2h4\x8a\
-\xe2f\xb3\x99vvv\x88\xe7\xf9\xefG077\xa7Xl0\x18(\x14\n}\x038;;\xa3\x81\x81\
-\x01\xc5Z\x00\xd4\xd5\xd5E\x91H\xe4\xab\xfe\x1b@*\x95\x92=\x86jZ,\x16J&\x93\
-\xc4\xf3<DQ\xa4P(D\x82 (\xd6h4\x1a\xb2\xd9l\x94\xc9dj\xe0%\xcf\xb1\xdeS\x00@\
-V\xab\x95\xb2\xd9,y<\x1e2\x18\x0c\x8ak\xb5Z-9\x9dN*\x14\n\xdf\x9e\x9c$@*\x95\
-\xaa\xbb#\xc6\x18uvv\x92V\xabU\\\xc7q\x1cy<\x1e*\x16\x8b\x92\xff\x1bY#ZYY\
-\xa1X,\x86\x8f\x8f\x0f\xc9\xdf\xd5D{{;\x96\x97\x97199)\xeb!\xb2V\xecp8~\x1aE\
-\x93!\x08\x02vww\x91L&\x99\x92\x81\xc9\x02,,,0\x97\xcb\x05A\x10\x9a\x12\xdf\
-\xda\xda\xc2\xc1\xc1A]\xe7T\x1cF\x9b\x9b\x9b\xcc\xe5rA\xa7\xd35,\xbe\xbf\xbf\
-\xaf\xca\xb6\xebN\xc3\xf1\xf1q\x0c\x0f\x0f\xab\x12\xd7h4\x98\x9e\x9eV-\xae\n\
-\xe0\xe1\xe1\x01OOO\xaa\x9aU*\x15\\__\xc3\xef\xf7S\xfd\xd5*\x00\xfc~?\x85\
-\xc3a\x94\xcbe\xb5\xfdP.\x97\x11\x0e\x87\xd5C\xc8\r\x95H$R\xd7\x0b\x94R\x10\
-\x84\x1a\xcb\x95\xcb\xffE\xbc\x11\x88\x9a\x0f\xa2(R \x10\xf8#\xe2j!j\xc4\xbd\
-^\xef\xd7%D)M&\x13\x99L&\xd5\x10f\xb3\x99|>\x9f\xe4\x18\x07\xcf\xf3\xb8\xb9\
-\xb9\xa1\xb5\xb55U\xe2\xd5\x1d\x05\x02\x01U\xeb\xab\xa9\xd7\xeb)\x16\x8bI\
-\x03\xb8\xdd\xee\xba\x97\x88\xdf\x1f\xa7(\x8a\xe4\xf1x\xea\x0e\xa3j\xf6\xf6\
-\xf6R.\x97\x93\x06\x88F\xa3\xa4\xd7\xeb\x15\x1b\xf4\xf5\xf5Q4\x1a\xadiP,\x16\
-\xc9\xe9t*\xc23\xc6hdd\xe4\xeb\xfe \tpzzJ\xad\xad\xad\xb2M\x06\x07\x07)\x9b\
-\xcdJ6\x90:>\xc6\x181\xc6\x08\x00uwwK\xee\xbc\x9a\xff\x01\xc0\xf3\xf33\xde\
-\xdf\xdf!\x15\x16\x8b\x05n\xb7\x1b\x1b\x1b\x1b\x92\xf6\xba\xb8\xb8\xc8\xf2\
-\xf9<\xb5\xb5\xb5!\x93\xc9\xe0\xf3\xf3\x13ccc\xd0\xe9tx}}\x85\xc3\xe1\xc0\
-\xea\xea\xaa\xac5\xb3\xeae2\x91H\xa0T*\xa1R\xa9|\xc14:X\xce\xcf\xcf\x89\x88\
-\xb0\xbe\xbe\xaez\x16|]H.//\xe9\xe5\xe5\x05\x8f\x8f\x8f8::\x02\x00loo#\x1a\
-\x8d6\xf5F\xd40@5\xf2\xf9<\xdd\xdd\xdd\x01\x00\xacVk\xd3\xafdM\x03\xfc\xed\
-\xf8\x01\xe9\t\x94\x8c\xa7\xf9\xf9<\x00\x00\x00\x00IEND\xaeB`\x82'
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
-
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import images
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1,
- style=wx.NO_FULL_REPAINT_ON_RESIZE)
- self.log = log
-
- b = wx.Button(self, 10, "Default Button", (20, 20))
- self.Bind(wx.EVT_BUTTON, self.OnClick, b)
- b.SetDefault()
- b.SetSize(b.GetBestSize())
-
- b = wx.Button(self, 20, "HELLO AGAIN!", (20, 80), (120, 45))
- self.Bind(wx.EVT_BUTTON, self.OnClick, b)
- b.SetToolTipString("This is a Hello button...")
-
- if 0: # a test case for catching wx.PyAssertionError
-
- #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_SUPPRESS)
- #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_EXCEPTION)
- #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_DIALOG)
- #wx.GetApp().SetAssertMode(wx.PYAPP_ASSERT_EXCEPTION | wx.PYAPP_ASSERT_DIALOG)
-
- try:
- bmp = wx.Bitmap("nosuchfile.bmp", wx.BITMAP_TYPE_BMP)
- mask = wx.MaskColour(bmp, wx.BLUE)
- except wx.PyAssertionError:
- self.log.write("Caught wx.PyAssertionError! I will fix the problem.\n")
- bmp = images.getTest2Bitmap()
- mask = wx.MaskColour(bmp, wx.BLUE)
- else:
- bmp = images.getTest2Bitmap()
- mask = wx.MaskColour(bmp, wx.BLUE)
-
- bmp.SetMask(mask)
- wx.BitmapButton(self, 30, bmp, (160, 20),
- (bmp.GetWidth()+10, bmp.GetHeight()+10))
- self.Bind(wx.EVT_BUTTON, self.OnClick, id=30)
-
-
- def OnClick(self, event):
- self.log.write("Click! (%d)\n" % event.GetId())
- ##wxLogDebug("debug message")
-
-
-## wxLog_SetLogLevel(wxLOG_Message) # ignore everything above wxLOG_Message
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """<html><body>
-<h2>Button</h2>
-
-A button is a control that contains a text string or a bitmap and can be
-placed on nearly any kind of window.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-#----------------------------------------------------------------------------
-# Name: wxCalendar.py
-# Purpose: Calendar control display testing on panel for wxPython demo
-#
-# Author: Lorne White (email: lwhite1@planet.eon.net)
-#
-# Version 0.9
-# Date: Feb 26, 2001
-# Licence: wxWindows license
-#----------------------------------------------------------------------------
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o Some updating of the library itself will be needed for this demo to work
-# correctly.
-#
-# 11/26/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Problems have changed a little. The print dialog requires
-# a wx.Size to work with the calendar library. wx.core doesn't
-# approve, though, so we get deprecation warnings.
-# o Ugh. AFter updating to the Bind() method, things lock up
-# on various control clicks. Will have to debug. Only seems
-# to happen on windows with calendar controls, though.
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Lockup issue clarification: it appears that the spinner is
-# the culprit.
-#
-# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o New Bind() method now fully supported.
-#
-# 12/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxCalendar renamed to Calendar
-# o Got rid of unneeded IDs where Bind() could figure it
-# out for itself.
-#
-
-import os
-
-import wx
-import wx.lib.calendar
-
-import images
-
-
-# highlighted days in month
-
-test_days ={ 0: [],
- 1: [3, 7, 9, 21],
- 2: [2, 10, 4, 9],
- 3: [4, 20, 29],
- 4: [1, 12, 22],
- 5: [2, 10, 15],
- 6: [4, 8, 17],
- 7: [6, 7, 8],
- 8: [5, 10, 20],
- 9: [1, 2, 5, 29],
- 10: [2, 4, 6, 22],
- 11: [6, 9, 12, 28, 29],
- 12: [8, 9, 10, 11, 20] }
-
-# test of full window calendar control functions
-
-def GetMonthList():
-
- monthlist = []
-
- for i in range(13):
- name = wx.lib.calendar.Month[i]
-
- if name != None:
- monthlist.append(name)
-
- return monthlist
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log, frame):
- wx.Panel.__init__(self, parent, -1)
-
- self.log = log
- self.frame = frame
-
- self.calend = wx.lib.calendar.Calendar(self, -1, (100, 50), (200, 180))
-
-# start_month = 2 # preselect the date for calendar
-# start_year = 2001
-
- start_month = self.calend.GetMonth() # get the current month & year
- start_year = self.calend.GetYear()
-
- # month list from DateTime module
-
- monthlist = GetMonthList()
-
- self.date = wx.ComboBox(self, -1, "",
- (100, 20), (90, -1),
- monthlist, wx.CB_DROPDOWN)
-
- self.date.SetSelection(start_month-1)
- self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, self.date)
-
- # set start month and year
-
- self.calend.SetMonth(start_month)
- self.calend.SetYear(start_year)
-
- # set attributes of calendar
-
- self.calend.hide_title = True
- self.calend.HideGrid()
- self.calend.SetWeekColor('WHITE', 'BLACK')
-
- # display routine
-
- self.ResetDisplay()
-
- # mouse click event
- self.Bind(wx.lib.calendar.EVT_CALENDAR, self.MouseClick, self.calend)
-
- # scroll bar for month selection
- self.scroll = wx.ScrollBar(self, -1, (100, 240), (200, 20), wx.SB_HORIZONTAL)
- self.scroll.SetScrollbar(start_month-1, 1, 12, 1, True)
- self.Bind(wx.EVT_COMMAND_SCROLL, self.Scroll, self.scroll)
-
- # spin control for year selection
-
- self.dtext = wx.TextCtrl(self, -1, str(start_year), (200, 20), (60, -1))
- h = self.dtext.GetSize().height
-
- self.spin = wx.SpinButton(self, -1, (270, 20), (h*2, h))
- self.spin.SetRange(1980, 2010)
- self.spin.SetValue(start_year)
- self.Bind(wx.EVT_SPIN, self.OnSpin, self.spin)
-
- # button for calendar dialog test
-
- wx.StaticText(self, -1, "Test Calendar Dialog", (350, 50), (150, -1))
-
- bmp = images.getCalendarBitmap()
- self.but1 = wx.BitmapButton(self, -1, bmp, (380, 80))
- self.Bind(wx.EVT_BUTTON, self.TestDlg, self.but1)
-
- # button for calendar window test
-
- wx.StaticText(self, -1, "Test Calendar Window", (350, 150), (150, -1))
-
- self.but2 = wx.BitmapButton(self, -1, bmp, (380, 180))
- self.Bind(wx.EVT_BUTTON, self.TestFrame, self.but2)
-
- wx.StaticText(self, -1, "Test Calendar Print", (350, 250), (150, -1))
-
- self.but3 = wx.BitmapButton(self, -1, bmp, (380, 280))
- self.Bind(wx.EVT_BUTTON, self.OnPreview, self.but3)
-
- # calendar dialog
-
- def TestDlg(self, event): # test the date dialog
- dlg = wx.lib.calendar.CalenDlg(self)
- dlg.Centre()
-
- if dlg.ShowModal() == wx.ID_OK:
- result = dlg.result
- day = result[1]
- month = result[2]
- year = result[3]
- new_date = str(month) + '/'+ str(day) + '/'+ str(year)
- self.log.WriteText('Date Selected: %s\n' % new_date)
- else:
- self.log.WriteText('No Date Selected')
-
- # calendar window test
-
- def TestFrame(self, event):
- frame = CalendFrame(self, -1, "Test Calendar", self.log)
- frame.Show(True)
- return True
-
- # calendar print preview
-
- def OnPreview(self, event):
- month = self.calend.GetMonth()
- year = self.calend.GetYear()
-
- prt = PrintCalend(self.frame, month, year)
- prt.Preview()
-
- # month and year control events
-
- def OnSpin(self, event):
- year = event.GetPosition()
- self.dtext.SetValue(str(year))
- self.calend.SetYear(year)
- self.calend.Refresh()
-
- def EvtComboBox(self, event):
- name = event.GetString()
- self.log.WriteText('EvtComboBox: %s\n' % name)
- monthval = self.date.FindString(name)
- self.scroll.SetScrollbar(monthval, 1, 12, 1, True)
-
- self.calend.SetMonth(monthval+1)
- self.ResetDisplay()
-
- def Scroll(self, event):
- value = self.scroll.GetThumbPosition()
- monthval = int(value)+1
- self.calend.SetMonth(monthval)
- self.ResetDisplay()
- self.log.WriteText('Month: %s\n' % value)
-
- name = wx.lib.calendar.Month[monthval]
- self.date.SetValue(name)
-
- # log mouse events
-
- def MouseClick(self, evt):
- text = '%s CLICK %02d/%02d/%d' % (evt.click, evt.day, evt.month, evt.year) # format date
- self.log.WriteText('Date Selected: ' + text + '\n')
-
-
- # set the highlighted days for the calendar
-
- def ResetDisplay(self):
- month = self.calend.GetMonth()
-
- try:
- set_days = test_days[month]
- except:
- set_days = [1, 5, 12]
-
- self.calend.AddSelect([4, 11], 'BLUE', 'WHITE')
- self.calend.SetSelDay(set_days)
- self.calend.Refresh()
-
- # increment and decrement toolbar controls
-
- def OnIncYear(self, event):
- self.calend.IncYear()
- self.ResetDisplay()
-
- def OnDecYear(self, event):
- self.calend.DecYear()
- self.ResetDisplay()
-
- def OnIncMonth(self, event):
- self.calend.IncMonth()
- self.ResetDisplay()
-
- def OnDecMonth(self, event):
- self.calend.DecMonth()
- self.ResetDisplay()
-
- def OnCurrent(self, event):
- self.calend.SetCurrentDay()
- self.ResetDisplay()
-
-# test of full window calendar control functions
-
-class CalendFrame(wx.Frame):
- def __init__(self, parent, id, title, log):
- wx.Frame.__init__(self, parent, id, title, size=(400, 400),
- style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
-
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
- self.log = log
- self.CreateStatusBar()
- self.mainmenu = wx.MenuBar()
- menu = wx.Menu()
-
- menu = self.MakeFileMenu()
- self.mainmenu.Append(menu, '&File')
-
- self.MakeToolMenu() # toolbar
-
- self.SetMenuBar(self.mainmenu)
- self.calend = wx.lib.calendar.Calendar(self, -1)
- self.calend.SetCurrentDay()
- self.calend.grid_color = 'BLUE'
- self.calend.SetBusType()
-# self.calend.ShowWeekEnd()
-
- self.ResetDisplay()
-
- self.Bind(wx.lib.calendar.EVT_CALENDAR, self.MouseClick, self.calend)
-
- def MouseClick(self, evt):
- text = '%s CLICK %02d/%02d/%d' % (evt.click, evt.day, evt.month, evt.year) # format date
- self.log.WriteText('Date Selected: ' + text + '\n')
-
- def OnCloseWindow(self, event):
- self.Destroy()
-
- def ResetDisplay(self):
- month = self.calend.GetMonth()
-
- try:
- set_days = test_days[month]
- except:
- set_days = [1, 5, 12]
-
- self.calend.AddSelect([2, 16], 'GREEN', 'WHITE')
-
- self.calend.SetSelDay(set_days)
- self.calend.Refresh()
-
- def OnIncYear(self, event):
- self.calend.IncYear()
- self.ResetDisplay()
-
- def OnDecYear(self, event):
- self.calend.DecYear()
- self.ResetDisplay()
-
- def OnIncMonth(self, event):
- self.calend.IncMonth()
- self.ResetDisplay()
-
- def OnDecMonth(self, event):
- self.calend.DecMonth()
- self.ResetDisplay()
-
- def OnCurrent(self, event):
- self.calend.SetCurrentDay()
- self.ResetDisplay()
-
- def MakeFileMenu(self):
- menu = wx.Menu()
-
- mID = wx.NewId()
- menu.Append(mID, 'Decrement', 'Next')
- self.Bind(wx.EVT_MENU, self.OnDecMonth, id=mID)
-
- mID = wx.NewId()
- menu.Append(mID, 'Increment', 'Dec')
- self.Bind(wx.EVT_MENU, self.OnIncMonth, id=mID)
-
- menu.AppendSeparator()
-
- mID = wx.NewId()
- menu.Append(mID, 'E&xit', 'Exit')
- self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=mID)
-
- return menu
-
- def MakeToolMenu(self):
- tb = self.CreateToolBar(wx.TB_HORIZONTAL|wx.NO_BORDER)
-
- mID = wx.NewId()
- SetToolPath(self, tb, mID, images.getDbDecBitmap(), 'Dec Year')
- self.Bind(wx.EVT_TOOL, self.OnDecYear, id=mID)
-
- mID = wx.NewId()
- SetToolPath(self, tb, mID, images.getDecBitmap(), 'Dec Month')
- self.Bind(wx.EVT_TOOL, self.OnDecMonth, id=mID)
-
- mID = wx.NewId()
- SetToolPath(self, tb, mID, images.getPtBitmap(), 'Current Month')
- self.Bind(wx.EVT_TOOL, self.OnCurrent, id=mID)
-
- mID = wx.NewId()
- SetToolPath(self, tb, mID, images.getIncBitmap(), 'Inc Month')
- self.Bind(wx.EVT_TOOL, self.OnIncMonth, id=mID)
-
- mID = wx.NewId()
- SetToolPath(self, tb, mID, images.getDbIncBitmap(), 'Inc Year')
- self.Bind(wx.EVT_TOOL, self.OnIncYear, id=mID)
-
- tb.Realize()
-
-#---------------------------------------------------------------------------
-
-# example class for printing/previewing calendars
-
-class PrintCalend:
- def __init__(self, parent, month, year):
- self.frame = parent
- self.month = month
- self.year = year
-
- self.SetParms()
- self.SetCal()
- self.printData = wx.PrintData()
-
- def SetCal(self):
- self.grid_color = 'BLUE'
- self.back_color = 'WHITE'
- self.sel_color = 'RED'
- self.high_color = 'LIGHT BLUE'
- self.font = wx.SWISS
- self.bold = wx.NORMAL
-
- self.sel_key = None # last used by
- self.sel_lst = [] # highlighted selected days
-
- self.size = None
- self.hide_title = False
- self.hide_grid = False
- self.set_day = None
-
- def SetParms(self):
- self.ymax = 1
- self.xmax = 1
- self.page = 1
- self.total_pg = 1
-
- self.preview = None
- self.scale = 1.0
-
- self.pagew = 8.5
- self.pageh = 11.0
-
- self.txt_marg = 0.1
- self.lf_marg = 0
- self.top_marg = 0
-
- self.page = 0
-
- def SetDates(self, month, year):
- self.month = month
- self.year = year
-
- def SetStyleDef(self, desc):
- self.style = desc
-
- def SetCopies(self, copies): # number of copies of label
- self.copies = copies
-
- def SetStart(self, start): # start position of label
- self.start = start
-
- def Preview(self):
- printout = SetPrintout(self)
- printout2 = SetPrintout(self)
- self.preview = wx.PrintPreview(printout, printout2, self.printData)
-
- if not self.preview.Ok():
- wx.MessageBox("There was a problem printing!", "Printing", wx.OK)
- return
-
- self.preview.SetZoom(60) # initial zoom value
-
- frame = wx.PreviewFrame(self.preview, self.frame, "Print preview")
-
- frame.Initialize()
- frame.SetPosition(self.frame.GetPosition())
- frame.SetSize(self.frame.GetSize())
- frame.Show(True)
-
- def Print(self):
- pdd = wx.PrintDialogData()
- pdd.SetPrintData(self.printData)
- printer = wx.Printer(pdd)
- printout = SetPrintout(self)
- frame = wx.Frame(None, -1, "Test")
-
- if not printer.Print(frame, printout):
- wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK)
- else:
- self.printData = printer.GetPrintDialogData().GetPrintData()
-
- printout.Destroy()
-
- def DoDrawing(self, DC):
- size = DC.GetSize()
- DC.BeginDrawing()
-
- cal = wx.lib.calendar.PrtCalDraw(self)
-
- if self.preview is None:
- cal.SetPSize(size[0]/self.pagew, size[1]/self.pageh)
- cal.SetPreview(False)
-
- else:
- if self.preview == 1:
- cal.SetPSize(size[0]/self.pagew, size[1]/self.pageh)
- else:
- cal.SetPSize(self.pwidth, self.pheight)
-
- cal.SetPreview(self.preview)
-
- cal.hide_title = self.hide_title # set the calendar parameters
- cal.hide_grid = self.hide_grid
-
- cal.grid_color = self.grid_color
- cal.high_color = self.high_color
- cal.back_color = self.back_color
- cal.outer_border = False
- cal.font = self.font
- cal.bold = self.bold
-
- cal_size = (3.0, 3.0)
- cal.SetSize(cal_size)
-
- year, month = self.year, self.month
-
- x = 0.5
- for i in range(2):
- y = 0.5
-
- for j in range(3):
- cal.SetCal(year, month) # current month
- cal.SetPos(x, y)
-
- try:
- set_days = test_days[month]
- except:
- set_days = [1, 5, 12]
-
- cal.AddSelect([2, 16], 'GREEN', 'WHITE')
-
- cal.DrawCal(DC, set_days)
-
- year, month = self.IncMonth(year, month)
- y = y + 3.5
-
- x = x + 4.0 # next column
-
- DC.EndDrawing()
-
- self.ymax = DC.MaxY()
- self.xmax = DC.MaxX()
-
- def IncMonth(self, year, month): # next month
- month = month + 1
-
- if month > 12:
- month = 1
- year = year + 1
-
- return year, month
-
- def GetTotalPages(self):
- self.pg_cnt = 1
- return self.pg_cnt
-
- def SetPage(self, page):
- self.page = page
-
- def SetPageSize(self, width, height):
- self.pwidth, self.pheight = width, height
-
- def SetTotalSize(self, width, height):
- self.ptwidth, self.ptheight = width, height
-
- def SetPreview(self, preview, scale):
- self.preview = preview
- self.scale = scale
-
- def SetTotalSize(self, width, height):
- self.ptwidth = width
- self.ptheight = height
-
-def SetToolPath(self, tb, id, bmp, title):
- tb.AddSimpleTool(id, bmp, title, title)
-
-class SetPrintout(wx.Printout):
- def __init__(self, canvas):
- wx.Printout.__init__(self)
- self.canvas = canvas
- self.end_pg = 1
-
- def OnBeginDocument(self, start, end):
- return self.base_OnBeginDocument(start, end)
-
- def OnEndDocument(self):
- self.base_OnEndDocument()
-
- def HasPage(self, page):
- if page <= self.end_pg:
- return True
- else:
- return False
-
- def GetPageInfo(self):
- self.end_pg = self.canvas.GetTotalPages()
- str_pg = 1
-
- try:
- end_pg = self.end_pg
- except:
- end_pg = 1
-
- return (str_pg, end_pg, str_pg, end_pg)
-
- def OnPreparePrinting(self):
- self.base_OnPreparePrinting()
-
- def OnBeginPrinting(self):
- dc = self.GetDC()
-
- self.preview = self.IsPreview()
-
- if (self.preview):
- self.pixelsPerInch = self.GetPPIScreen()
- else:
- self.pixelsPerInch = self.GetPPIPrinter()
-
- (w, h) = dc.GetSize()
- scaleX = float(w) / 1000
- scaleY = float(h) / 1000
- self.printUserScale = min(scaleX, scaleY)
-
- self.base_OnBeginPrinting()
-
- def GetSize(self):
- self.psizew, self.psizeh = self.GetPPIPrinter()
- return self.psizew, self.psizeh
-
- def GetTotalSize(self):
- self.ptsizew, self.ptsizeh = self.GetPageSizePixels()
- return self.ptsizew, self.ptsizeh
-
- def OnPrintPage(self, page):
- dc = self.GetDC()
- (w, h) = dc.GetSize()
- scaleX = float(w) / 1000
- scaleY = float(h) / 1000
- self.printUserScale = min(scaleX, scaleY)
- dc.SetUserScale(self.printUserScale, self.printUserScale)
-
- self.preview = self.IsPreview()
-
- self.canvas.SetPreview(self.preview, self.printUserScale)
- self.canvas.SetPage(page)
-
- self.ptsizew, self.ptsizeh = self.GetPageSizePixels()
- self.canvas.SetTotalSize(self.ptsizew, self.ptsizeh)
-
- self.psizew, self.psizeh = self.GetPPIPrinter()
- self.canvas.SetPageSize(self.psizew, self.psizeh)
-
- self.canvas.DoDrawing(dc)
- return True
-
-class MyApp(wx.App):
- def OnInit(self):
- frame = CalendFrame(None, -1, "Test Calendar", log)
- frame.Show(True)
- self.SetTopWindow(frame)
- return True
-
-#---------------------------------------------------------------------------
-
-def MessageDlg(self, message, type = 'Message'):
- dlg = wx.MessageDialog(self, message, type, wx.OK | wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log, frame)
- return win
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This control provides a Calendar control class for displaying and selecting dates.
-In addition, the class is extended and can be used for printing/previewing.
-
-Additional features include weekend highlighting and business type Monday-Sunday
-format.
-
-See example for various methods used to set display month, year, and highlighted
-dates (different font and background colours).
-
-by Lorne White
-
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import wx.lib.calendar as calendar
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, ID, log):
- wx.Panel.__init__(self, parent, ID)
- self.log = log
-
- cal = calendar.CalendarCtrl(self, -1, wx.DateTime_Now(), pos = (25,50),
- style = calendar.CAL_SHOW_HOLIDAYS
- | calendar.CAL_SUNDAY_FIRST
- | calendar.CAL_SEQUENTIAL_MONTH_SELECTION
- )
-
- self.Bind(calendar.EVT_CALENDAR, self.OnCalSelected, id=cal.GetId())
-
- b = wx.Button(self, -1, "Destroy the Calendar", pos = (250, 50))
- self.Bind(wx.EVT_BUTTON, self.OnButton, id= b.GetId())
- self.cal = cal
-
- # Set up control to display a set of holidays:
- self.Bind(calendar.EVT_CALENDAR_MONTH, self.OnChangeMonth, id=cal.GetId())
- self.holidays = [(1,1), (10,31), (12,25) ] # (these don't move around)
- self.OnChangeMonth()
-
- def OnButton(self, evt):
- self.cal.Destroy()
- self.cal = None
-
- def OnCalSelected(self, evt):
- self.log.write('OnCalSelected: %s\n' % evt.GetDate())
-
- def OnChangeMonth(self, evt=None):
- cur_month = self.cal.GetDate().GetMonth() + 1 # convert wxDateTime 0-11 => 1-12
-
- for month, day in self.holidays:
- if month == cur_month:
- self.cal.SetHoliday(day)
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, -1, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-<html><body>
-<h2>wxCalendarCtrl</h2>
-
-Yet <i>another</i> calendar control. This one is a wrapper around the C++
-version described in the docs. This one will probably be a bit more efficient
-than the one in wxPython.lib.calendar, but I like a few things about it better,
-so I think both will stay in wxPython.
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestCheckBox(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- wx.StaticText(self, -1, "This example uses the wxCheckBox control.", (10, 10))
-
- cID = wx.NewId()
- cb1 = wx.CheckBox(self, cID, " Apples", (65, 40), (150, 20), wx.NO_BORDER)
- cb2 = wx.CheckBox(self, cID+1, " Oranges", (65, 60), (150, 20), wx.NO_BORDER)
- cb2.SetValue(True)
- cb3 = wx.CheckBox(self, cID+2, " Pears", (65, 80), (150, 20), wx.NO_BORDER)
-
- self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb1)
- self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb2)
- self.Bind(wx.EVT_CHECKBOX, self.EvtCheckBox, cb3)
-
- def EvtCheckBox(self, event):
- self.log.WriteText('EvtCheckBox: %d\n' % event.IsChecked())
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestCheckBox(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-
-
-overview = """\
-A checkbox is a labelled box which is either on (checkmark is visible) or off (no checkmark).
-
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o Why is there a popup menu in this demo?
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
- 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
- 'twelve', 'thirteen', 'fourteen']
-
- wx.StaticText(self, -1, "This example uses the wxCheckListBox control.", (45, 15))
-
- lb = wx.CheckListBox(self, 60, (80, 50), (80, 120), sampleList)
- self.Bind(wx.EVT_LISTBOX, self.EvtListBox, id=60)
- self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, id=60)
- lb.SetSelection(0)
- self.lb = lb
-
- pos = lb.GetPosition().x + lb.GetSize().width + 25
- btn = wx.Button(self, -1, "Test SetString", (pos, 50))
- self.Bind(wx.EVT_BUTTON, self.OnTestButton, id=btn.GetId())
- self.Bind(wx.EVT_RIGHT_UP, self.OnDoPopup)
-
- def EvtListBox(self, event):
- self.log.WriteText('EvtListBox: %s\n' % event.GetString())
-
- def EvtListBoxDClick(self, event):
- self.log.WriteText('EvtListBoxDClick:\n')
-
- def OnTestButton(self, evt):
- self.lb.SetString(4, "FUBAR")
-
-
- def OnDoPopup(self, evt):
- menu = wx.Menu()
- # Make this first item bold
- item = wx.MenuItem(menu, wx.NewId(), "If supported, this is bold")
- df = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
-
- nf = wx.Font(
- df.GetPointSize(), df.GetFamily(), df.GetStyle(),
- wx.BOLD, False, df.GetFaceName()
- )
-
- item.SetFont(nf)
- menu.AppendItem(item)
-
- menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &1"))
- menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &2"))
- menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &3"))
- menu.AppendItem(wx.MenuItem(menu, wx.NewId(), "Normal Item &4"))
-
- self.PopupMenu(menu, evt.GetPosition())
- menu.Destroy()
- evt.Skip()
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-A checklistbox is like a Listbox, but allows items to be checked or unchecked rather
-than relying on extended selection (e.g. shift-select) to select multiple items in
-the list.
-
-This class is currently implemented under Windows and GTK.
-
-This demo shows the basic CheckListBox and how to use the SetString method to change
-labels dynamically.
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestChoice(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
- 'six', 'seven', 'eight']
-
- wx.StaticText(self, -1, "This example uses the wxChoice control.", (15, 10))
- wx.StaticText(self, -1, "Select one:", (15, 50), (75, 20))
- self.ch = wx.Choice(self, -1, (80, 50), choices = sampleList)
- self.Bind(wx.EVT_CHOICE, self.EvtChoice, self.ch)
-
-
- def EvtChoice(self, event):
- self.log.WriteText('EvtChoice: %s\n' % event.GetString())
- self.ch.Append("A new item")
-
- if event.GetString() == 'one':
- self.log.WriteText('Well done!\n')
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestChoice(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-overview = """
-A Choice control is used to select one of a list of strings. Unlike a listbox,
-only the current selection is visible until the user pulls down the menu of
-choices.
-
-This demo illustrates how to set up the Choice control and how to extract the
-selected choice once it is selected.
-
-Note that the syntax of the constructor is different than the C++ implementation.
-The number of choices and the choice array are consilidated into one python
-<code>list</code>.
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- dlg = wx.ColourDialog(frame)
-
- # Ensure the full colour dialog is displayed,
- # not the abbreviated version.
- dlg.GetColourData().SetChooseFull(True)
-
- if dlg.ShowModal() == wx.ID_OK:
-
- # If the user selected OK, then the dialog's wx.ColourData will
- # contain valid information. Fetch the data ...
- data = dlg.GetColourData()
-
- # ... then do something with it. The actual colour data will be
- # returned as a three-tuple (r, g, b) in this particular case.
- log.WriteText('You selected: %s\n' % str(data.GetColour().Get()))
-
- # Once the dialog is destroyed, Mr. wx.ColourData is no longer your
- # friend. Don't use it again!
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class represents the colour chooser dialog.
-
-Use of this dialog is a multi-stage process.
-
-The actual information about how to display the dialog and the colors in the
-dialog's 'registers' are contained in a wx.ColourData instance that is created by
-the dialog at init time. Before displaying the dialog, you may alter these settings
-to suit your needs. In the example, we set the dialog up to show the extended colour
-data selection pane. Otherwise, only the more compact and less extensive colour
-dialog is shown. You may also preset the colour as well as other items.
-
-If the user selects something and selects OK, then the wxColourData instance contains
-the colour data that the user selected. Before destroying the dialog, retrieve the data.
-<b>Do not try to retain the wx.ColourData instance.</b> It will probably not be valid
-after the dialog is destroyed.
-
-Along with he wxColourDialog documentation, see also the wx.ColourData documentation
-for details.
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestComboBox(wx.Panel):
- def OnSetFocus(self, evt):
- print "OnSetFocus"
- evt.Skip()
-
- def OnKillFocus(self, evt):
- print "OnKillFocus"
- evt.Skip()
-
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
- #'this is a long item that needs a scrollbar...',
- 'six', 'seven', 'eight']
-
- wx.StaticText(self, -1, "This example uses the wxComboBox control.", (8, 10))
- wx.StaticText(self, -1, "Select one:", (15, 50), (75, 18))
-
- # This combobox is created with a preset list of values.
- cb = wx.ComboBox(
- self, 500, "default value", (90, 50),
- (95, -1), sampleList, wx.CB_DROPDOWN #|wxTE_PROCESS_ENTER
- )
-
- ##import win32api, win32con
- ##win32api.SendMessage(cb.GetHandle(),
- ## win32con.CB_SETHORIZONTALEXTENT,
- ## 200, 0)
-
- self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, cb)
- self.Bind(wx.EVT_TEXT, self.EvtText, cb)
- self.Bind(wx.EVT_TEXT_ENTER, self.EvtTextEnter, cb)
- cb.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
- cb.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
-
- # Once the combobox is set up, we append some more data to it.
- cb.Append("foo", "This is some client data for this item")
-
- # This combobox is created with no values initially.
- cb = wx.ComboBox(
- self, 501, "default value", (90, 80), (95, -1), [], wx.CB_SIMPLE)
-
- # Here we dynamically add our values to the second combobox.
- for item in sampleList:
- cb.Append(item, item.upper())
-
- self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, cb)
- self.Bind(wx.EVT_COMBOBOX, self.EvtText, cb)
-
- # The user selects something, we go here.
- def EvtComboBox(self, evt):
- cb = evt.GetEventObject()
- data = cb.GetClientData(cb.GetSelection())
- self.log.WriteText('EvtComboBox: %s\nClientData: %s\n' % (evt.GetString(), data))
-
- if evt.GetString() == 'one':
- self.log.WriteText("You follow directions well!\n\n")
-
- # Capture events every time a user hits a key in the text entry field.
- def EvtText(self, evt):
- self.log.WriteText('EvtText: %s\n' % evt.GetString())
-
- # Capture events when the user types something into the control then
- # hits ENTER.
- def EvtTextEnter(self, evt):
- self.log.WriteText('EvtTextEnter: %s' % evt.GetString())
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestComboBox(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-A ComboBox is like a combination of an edit control and a listbox. It can be
-displayed as static list with editable or read-only text field; or a drop-down
-list with text field; or a drop-down list without a text field.
-
-This example shows both a preset ComboBox and one that is dynamically created
-(that is, it is initially empty but then we 'grow' it out of program-supplied
-data). The former is common for read-only controls.
-
-This example also shows the two form factors for the ComboBox. The first is more
-common, and resembles a Choice control. The latter, although less common, shows
-how all the values in the ComboBox can be visible, yet the functionality is the
-same for both.
-
-Finally, this demo shows how event handling can differ. The first ComboBox is set
-up to handle EVT_TEXT_ENTER events, in which text is typed in and then ENTER is
-hit by the user. This allows the user to enter a line of text which can then be
-processed by the program. EVT_TEXT can also be processed, but in that case the
-event is generated every time that the user hits a key in the ComboBox entry field.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-# Create and set a help provider. Normally you would do this in
-# the app's OnInit as it must be done before any SetHelpText calls.
-provider = wx.SimpleHelpProvider()
-wx.HelpProvider_Set(provider)
-
-#---------------------------------------------------------------------------
-
-class TestDialog(wx.Dialog):
- def __init__(
- self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition,
- style=wx.DEFAULT_DIALOG_STYLE
- ):
-
- # Instead of calling wxDialog.__init__ we precreate the dialog
- # so we can set an extra style that must be set before
- # creation, and then we create the GUI dialog using the Create
- # method.
- pre = wx.PreDialog()
- pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
- pre.Create(parent, ID, title, pos, size, style)
-
- # This next step is the most important, it turns this Python
- # object into the real wrapper of the dialog (instead of pre)
- # as far as the wxPython extension is concerned.
- self.this = pre.this
-
- # Now continue with the normal construction of the dialog
- # contents
- sizer = wx.BoxSizer(wx.VERTICAL)
-
- label = wx.StaticText(self, -1, "This is a wxDialog")
- label.SetHelpText("This is the help text for the label")
- sizer.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- box = wx.BoxSizer(wx.HORIZONTAL)
-
- label = wx.StaticText(self, -1, "Field #1:")
- label.SetHelpText("This is the help text for the label")
- box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- text = wx.TextCtrl(self, -1, "", size=(80,-1))
- text.SetHelpText("Here's some help text for field #1")
- box.Add(text, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- sizer.AddSizer(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
-
- box = wx.BoxSizer(wx.HORIZONTAL)
-
- label = wx.StaticText(self, -1, "Field #2:")
- label.SetHelpText("This is the help text for the label")
- box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- text = wx.TextCtrl(self, -1, "", size=(80,-1))
- text.SetHelpText("Here's some help text for field #2")
- box.Add(text, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- sizer.AddSizer(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
-
- line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
- sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
-
- box = wx.BoxSizer(wx.HORIZONTAL)
-
- if wx.Platform != "__WXMSW__":
- btn = wx.ContextHelpButton(self)
- box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- btn = wx.Button(self, wx.ID_OK, " OK ")
- btn.SetDefault()
- btn.SetHelpText("The OK button completes the dialog")
- box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- btn = wx.Button(self, wx.ID_CANCEL, " Cancel ")
- btn.SetHelpText("The Cancel button cnacels the dialog. (Cool, huh?)")
- box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-
- sizer.Add(box, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
-
- self.SetSizer(sizer)
- self.SetAutoLayout(True)
- sizer.Fit(self)
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestDialog(frame, -1, "This is a Dialog", size=(350, 200),
- #style = wxCAPTION | wxSYSTEM_MENU | wxTHICK_FRAME
- style = wx.DEFAULT_DIALOG_STYLE
- )
- win.CenterOnScreen()
- val = win.ShowModal()
-
- if val == wx.ID_OK:
- log.WriteText("You pressed OK\n")
- else:
- log.WriteText("You pressed Cancel\n")
-
- win.Destroy()
-
-
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-wxPython offers quite a few general purpose dialogs for useful data input from
-the user; they are all based on the wx.Dialog class, which you can also subclass
-to create custom dialogs to suit your needs.
-
-The Dialog class, in addition to dialog-like behaviors, also supports the full
-wxWindows layout featureset, which means that you can incorporate sizers or
-layout constraints as needed to achieve the look and feel desired. It even supports
-context-sensitive help, which is illustrated in this example.
-
-The example is very simple; in real world situations, a dialog that had input
-fields such as this would no doubt be required to deliver those values back to
-the calling function. The Dialog class supports data retrieval in this manner.
-<b>However, the data must be retrieved prior to the dialog being destroyed.</b>
-The example shown here is <i>modal</i>; non-modal dialogs are possible as well.
-
-See the documentation for the <code>Dialog</code> class for more details.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
-
- # In this case we include a "New directory" button.
- dlg = wx.DirDialog(frame, "Choose a directory:",
- style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
-
- # If the user selects OK, then we process the dialog's data.
- # This is done by getting the path data from the dialog - BEFORE
- # we destroy it.
- if dlg.ShowModal() == wx.ID_OK:
- log.WriteText('You selected: %s\n' % dlg.GetPath())
-
- # Only destroy a dialog after you're done with it.
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-This class represents the directory chooser dialog. It is used when all you
-need from the user is the name of a directory. Data is retrieved via utility
-methods; see the <code>DirDialog</code> documentation for specifics.
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import images
-
-#----------------------------------------------------------------------
-
-class DragShape:
- def __init__(self, bmp):
- self.bmp = bmp
- self.pos = (0,0)
- self.shown = True
- self.text = None
- self.fullscreen = False
-
- def HitTest(self, pt):
- rect = self.GetRect()
- return rect.InsideXY(pt.x, pt.y)
-
- def GetRect(self):
- return wx.Rect(self.pos[0], self.pos[1],
- self.bmp.GetWidth(), self.bmp.GetHeight())
-
- def Draw(self, dc, op = wx.COPY):
- if self.bmp.Ok():
- memDC = wx.MemoryDC()
- memDC.SelectObject(self.bmp)
-
- dc.Blit((self.pos[0], self.pos[1]),
- (self.bmp.GetWidth(), self.bmp.GetHeight()),
- memDC, (0, 0), op, True)
-
- return True
- else:
- return False
-
-
-
-#----------------------------------------------------------------------
-
-class DragCanvas(wx.ScrolledWindow):
- def __init__(self, parent, ID):
- wx.ScrolledWindow.__init__(self, parent, ID)
- self.shapes = []
- self.dragImage = None
- self.dragShape = None
- self.hiliteShape = None
-
- self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
- self.bg_bmp = images.getBackgroundBitmap()
-
- # Make a shape from an image and mask. This one will demo
- # dragging outside the window
- bmp = images.getTestStarBitmap()
- shape = DragShape(bmp)
- shape.pos = (5, 5)
- shape.fullscreen = True
- self.shapes.append(shape)
-
- # Make a shape from some text
- text = "Some Text"
- bg_colour = wx.Colour(57, 115, 57) # matches the bg image
- font = wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)
- textExtent = self.GetFullTextExtent(text, font)
-
- # create a bitmap the same size as our text
- bmp = wx.EmptyBitmap(textExtent[0], textExtent[1])
-
- # 'draw' the text onto the bitmap
- dc = wx.MemoryDC()
- dc.SelectObject(bmp)
- dc.SetBackground(wx.Brush(bg_colour, wx.SOLID))
- dc.Clear()
- dc.SetTextForeground(wx.RED)
- dc.SetFont(font)
- dc.DrawText(text, (0, 0))
- dc.SelectObject(wx.NullBitmap)
- mask = wx.MaskColour(bmp, bg_colour)
- bmp.SetMask(mask)
- shape = DragShape(bmp)
- shape.pos = (5, 100)
- shape.text = "Some dragging text"
- self.shapes.append(shape)
-
-
- # Make some shapes from some playing card images.
- x = 200
-
- for card in ['_01c_', '_12h_', '_13d_', '_10s_']:
- bmpFunc = getattr(images, "get%sBitmap" % card)
- bmp = bmpFunc()
- shape = DragShape(bmp)
- shape.pos = (x, 5)
- self.shapes.append(shape)
- x = x + 80
-
-
- self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
- self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
- self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
- self.Bind(wx.EVT_MOTION, self.OnMotion)
- self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
-
-
- # We're not doing anything here, but you might have reason to.
- # for example, if you were dragging something, you might elect to
- # 'drop it' when the cursor left the window.
- def OnLeaveWindow(self, evt):
- pass
-
-
- # tile the background bitmap
- def TileBackground(self, dc):
- sz = self.GetClientSize()
- w = self.bg_bmp.GetWidth()
- h = self.bg_bmp.GetHeight()
-
- x = 0
-
- while x < sz.width:
- y = 0
-
- while y < sz.height:
- dc.DrawBitmap(self.bg_bmp, (x, y))
- y = y + h
-
- x = x + w
-
-
- # Go through our list of shapes and draw them in whatever place they are.
- def DrawShapes(self, dc):
- for shape in self.shapes:
- if shape.shown:
- shape.Draw(dc)
-
- # This is actually a sophisticated 'hit test', but in this
- # case we're also determining which shape, if any, was 'hit'.
- def FindShape(self, pt):
- for shape in self.shapes:
- if shape.HitTest(pt):
- return shape
- return None
-
- # Remove a shape from the display
- def EraseShape(self, shape, dc):
- r = shape.GetRect()
- dc.SetClippingRect(r)
- self.TileBackground(dc)
- self.DrawShapes(dc)
- dc.DestroyClippingRegion()
-
- # Clears the background, then redraws it. If the DC is passed, then
- # we only do so in the area so designated. Otherwise, it's the whole thing.
- def OnEraseBackground(self, evt):
- dc = evt.GetDC()
-
- if not dc:
- dc = wxClientDC(self)
- rect = self.GetUpdateRegion().GetBox()
- dc.SetClippingRect(rect)
- self.TileBackground(dc)
-
- # Fired whenever a paint event occurs
- def OnPaint(self, evt):
- dc = wx.PaintDC(self)
- self.PrepareDC(dc)
- self.DrawShapes(dc)
-
- # Left mouse button is down.
- def OnLeftDown(self, evt):
- # Did the mouse go down on one of our shapes?
- shape = self.FindShape(evt.GetPosition())
-
- # If a shape was 'hit', then set that as the shape we're going to
- # drag around. Get our start position. Dragging has not yet started.
- # That will happen once the mouse moves, OR the mouse is released.
- if shape:
- self.dragShape = shape
- self.dragStartPos = evt.GetPosition()
-
- # Left mouse button up.
- def OnLeftUp(self, evt):
- if not self.dragImage or not self.dragShape:
- self.dragImage = None
- self.dragShape = None
- return
-
- # Hide the image, end dragging, and nuke out the drag image.
- self.dragImage.Hide()
- self.dragImage.EndDrag()
- self.dragImage = None
-
- dc = wx.ClientDC(self)
-
- if self.hiliteShape:
- self.hiliteShape.Draw(dc)
- self.hiliteShape = None
-
- # reposition and draw the shape
-
- # Note by jmg 11/28/03
- # Here's the original:
- #
- # self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - self.dragStartPos
- #
- # So if there are any problems associated with this, use that as
- # a starting place in your investigation. I've tried to simulate the
- # wx.Point __add__ method here -- it won't work for tuples as we
- # have now from the various methods
- #
- # There must be a better way to do this :-)
- #
-
- self.dragShape.pos = (
- self.dragShape.pos[0] + evt.GetPosition()[0] - self.dragStartPos[0],
- self.dragShape.pos[1] + evt.GetPosition()[1] - self.dragStartPos[1]
- )
-
- self.dragShape.shown = True
- self.dragShape.Draw(dc)
- self.dragShape = None
-
- # The mouse is moving
- def OnMotion(self, evt):
- # Ignore mouse movement if we're not dragging.
- if not self.dragShape or not evt.Dragging() or not evt.LeftIsDown():
- return
-
- # if we have a shape, but haven't started dragging yet
- if self.dragShape and not self.dragImage:
-
- # only start the drag after having moved a couple pixels
- tolerance = 2
- pt = evt.GetPosition()
- dx = abs(pt.x - self.dragStartPos.x)
- dy = abs(pt.y - self.dragStartPos.y)
- if dx <= tolerance and dy <= tolerance:
- return
-
- # erase the shape since it will be drawn independently now
- dc = wx.ClientDC(self)
- self.dragShape.shown = False
- self.EraseShape(self.dragShape, dc)
-
-
- if self.dragShape.text:
- self.dragImage = wx.DragString(self.dragShape.text,
- wx.StockCursor(wx.CURSOR_HAND))
- else:
- self.dragImage = wx.DragImage(self.dragShape.bmp,
- wx.StockCursor(wx.CURSOR_HAND))
-
- hotspot = self.dragStartPos - self.dragShape.pos
- self.dragImage.BeginDrag(hotspot, self, self.dragShape.fullscreen)
-
- self.dragImage.Move(pt)
- self.dragImage.Show()
-
-
- # if we have shape and image then move it, posibly highlighting another shape.
- elif self.dragShape and self.dragImage:
- onShape = self.FindShape(evt.GetPosition())
- unhiliteOld = False
- hiliteNew = False
-
- # figure out what to hilite and what to unhilite
- if self.hiliteShape:
- if onShape is None or self.hiliteShape is not onShape:
- unhiliteOld = True
-
- if onShape and onShape is not self.hiliteShape and onShape.shown:
- hiliteNew = True
-
- # if needed, hide the drag image so we can update the window
- if unhiliteOld or hiliteNew:
- self.dragImage.Hide()
-
- if unhiliteOld:
- dc = wx.ClientDC(self)
- self.hiliteShape.Draw(dc)
- self.hiliteShape = None
-
- if hiliteNew:
- dc = wx.ClientDC(self)
- self.hiliteShape = onShape
- self.hiliteShape.Draw(dc, wx.INVERT)
-
- # now move it and show it again if needed
- self.dragImage.Move(evt.GetPosition())
- if unhiliteOld or hiliteNew:
- self.dragImage.Show()
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
-
- win = wx.Panel(nb, -1)
- canvas = DragCanvas(win, -1)
-
- def onSize(evt, panel=win, canvas=canvas):
- canvas.SetSize(panel.GetSize())
-
- win.Bind(wx.EVT_SIZE, onSize)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """\
-DragImage is used when you wish to drag an object on the screen, and a simple
-cursor is not enough.
-
-On Windows, the WIN32 API is used to do achieve smooth dragging. On other
-platforms, <code>GenericDragImage</code> is used. Applications may also prefer to use
-<code>GenericDragImage</code> on Windows, too.
-
-<b>wxPython note</b>: wxPython uses <code>GenericDragImage</code> on all
-platforms, but uses the <code>DragImage</code> name.
-
-To use this class, when you wish to start dragging an image, create a
-<code>DragImage</code> object and store it somewhere you can access it as the
-drag progresses. Call BeginDrag to start, and EndDrag to stop the drag. To move
-the image, initially call Show and then Move. If you wish to update the screen
-contents during the drag (for example, highlight an item as in the example), first
-call Hide, update the screen, call Move, and then call Show.
-
-You can drag within one window, or you can use full-screen dragging either across
-the whole screen, or just restricted to one area of the screen to save resources.
-If you want the user to drag between two windows, then you will need to use
-full-screen dragging.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import wx.gizmos as gizmos
-import wx.stc as stc
-
-#----------------------------------------------------------------------
-# This is an example of the complex view that manages its own scrollbars
-# as described in the overview below.
-
-class TestView(stc.StyledTextCtrl):
- def __init__(self, parent, ID, log):
- stc.StyledTextCtrl.__init__(self, parent, ID, style=wx.NO_BORDER)
- self.dyn_sash = parent
- self.log = log
- self.SetupScrollBars()
- self.SetMarginWidth(1,0)
-
- self.StyleSetFont(stc.STC_STYLE_DEFAULT,
- wx.Font(10, wx.MODERN, wx.NORMAL, wx.NORMAL))
-
- self.Bind(gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnSplit)
- self.Bind(gizmos.EVT_DYNAMIC_SASH_UNIFY, self.OnUnify)
- #self.SetScrollWidth(500)
-
- def SetupScrollBars(self):
- # hook the scrollbars provided by the wxDynamicSashWindow
- # to this view
- v_bar = self.dyn_sash.GetVScrollBar(self)
- h_bar = self.dyn_sash.GetHScrollBar(self)
- v_bar.Bind(wx.EVT_SCROLL, self.OnSBScroll)
- h_bar.Bind(wx.EVT_SCROLL, self.OnSBScroll)
- v_bar.Bind(wx.EVT_SET_FOCUS, self.OnSBFocus)
- h_bar.Bind(wx.EVT_SET_FOCUS, self.OnSBFocus)
-
- # And set the wxStyledText to use these scrollbars instead
- # of its built-in ones.
- self.SetVScrollBar(v_bar)
- self.SetHScrollBar(h_bar)
-
-
- def __del__(self):
- self.log.write("TestView.__del__\n")
-
- def OnSplit(self, evt):
- self.log.write("TestView.OnSplit\n");
- newview = TestView(self.dyn_sash, -1, self.log)
- newview.SetDocPointer(self.GetDocPointer()) # use the same document
- self.SetupScrollBars()
-
-
- def OnUnify(self, evt):
- self.log.write("TestView.OnUnify\n");
- self.SetupScrollBars()
-
-
- def OnSBScroll(self, evt):
- # redirect the scroll events from the dyn_sash's scrollbars to the STC
- self.GetEventHandler().ProcessEvent(evt)
-
- def OnSBFocus(self, evt):
- # when the scrollbar gets the focus move it back to the STC
- self.SetFocus()
-
-
-sampleText="""\
-You can drag the little tabs above the vertical scrollbar, or to the
-left of the horizontal scrollbar to split this view, and you can
-continue splitting the new views as much as you like. Try it and see.
-
-In this case the views also share the same document so changes in one
-are instantly seen in the others. This is a feature of the
-StyledTextCtrl that is used for the view class in this sample.
-"""
-
-#----------------------------------------------------------------------
-# This one is simpler, but doesn't do anything with the scrollbars
-# except the default wxDynamicSashWindow behaviour
-
-class SimpleView(wx.Panel):
- def __init__(self, parent, ID, log):
- wx.Panel.__init__(self, parent, ID)
- self.dyn_sash = parent
- self.log = log
- self.SetBackgroundColour("LIGHT BLUE")
- self.Bind(gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnSplit)
-
- def OnSplit(self, evt):
- v = SimpleView(self.dyn_sash, -1, self.log)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- if wx.Platform == "__WXMAC__":
- wx.MessageBox("This demo currently fails on the Mac. The problem is being looked into...", "Sorry")
- return
-
- if 1:
- win = gizmos.DynamicSashWindow(nb, -1, style = wx.CLIP_CHILDREN
- #| wxDS_MANAGE_SCROLLBARS
- #| wxDS_DRAG_CORNER
- )
-
- win.SetFont(wx.Font(10, wx.MODERN, wx.NORMAL, wx.NORMAL))
- view = TestView(win, -1, log)
- view.SetText(sampleText)
- else:
- win = wx.DynamicSashWindow(nb, -1)
- view = SimpleView(win, -1, log)
- return win
-
-#----------------------------------------------------------------------
-
-overview = """\
-<html><body>
-<h2>DynamicSashWindow</h2>
-<p>
-wxDynamicSashWindow widgets manages the way other widgets are viewed.
-When a wxDynamicSashWindow is first shown, it will contain one child
-view, a viewport for that child, and a pair of scrollbars to allow the
-user to navigate the child view area. Next to each scrollbar is a small
-tab. By clicking on either tab and dragging to the appropriate spot, a
-user can split the view area into two smaller views separated by a
-draggable sash. Later, when the user wishes to reunify the two subviews,
-the user simply drags the sash to the side of the window.
-wxDynamicSashWindow will automatically reparent the appropriate child
-view back up the window hierarchy, and the wxDynamicSashWindow will have
-only one child view once again.
-<p>
-As an application developer, you will simply create a wxDynamicSashWindow
-using either the Create() function or the more complex constructor
-provided below, and then create a view window whose parent is the
-wxDynamicSashWindow. The child should respond to
-wxDynamicSashSplitEvents -- perhaps with an OnSplit() event handler -- by
-constructing a new view window whose parent is also the
-wxDynamicSashWindow. That's it! Now your users can dynamically split
-and reunify the view you provided.
-<p>
-If you wish to handle the scrollbar events for your view, rather than
-allowing wxDynamicSashWindow to do it for you, things are a bit more
-complex. (You might want to handle scrollbar events yourself, if,
-for instance, you wish to scroll a subwindow of the view you add to
-your wxDynamicSashWindow object, rather than scrolling the whole view.)
-In this case, you will need to construct your wxDynamicSashWindow without
-the wxDS_MANAGE_SCROLLBARS style and you will need to use the
-GetHScrollBar() and GetVScrollBar() methods to retrieve the scrollbar
-controls and call SetEventHanler() on them to redirect the scrolling
-events whenever your window is reparented by wxDyanmicSashWindow.
-You will need to set the scrollbars' event handler at three times:
-<p>
-<ul>
-<li> When your view is created
-<li> When your view receives a wxDynamicSashSplitEvent
-<li> When your view receives a wxDynamicSashUnifyEvent
-</ul>
-</body></html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o Added overview text based on source code delving.
-#
-
-import wx
-import wx.gizmos as gizmos
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- self.elb = gizmos.EditableListBox(
- self, -1, "List of Stuff", (50,50), (250, 250)
- )
- #style=wx.EL_ALLOW_NEW | wx.EL_ALLOW_EDIT | wx.EL_ALLOW_DELETE)
-
- self.elb.SetStrings(["This is a nifty ListBox widget",
- "that is editable by the user.",
- "",
- "Use the buttons above to",
- "manipulate items in the list",
- "Or to add new ones.",
- ])
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """\
-<html>
-<body>
-This class provides a composite control that lets the user easily enter and edit
-a list of strings.
-
-<p><b>Styles supported:</b><p>
-
-<ul>
-<li><b>EL_ALLOW_NEW</b> - Allow user to create new items.
-<li><b>EL_ALLOW_EDIT</b> - Allow user to edit text in the control.
-<li><b>EL_ALLOW_DELETE</b> - Allow user to delete text from the control.
-</ul>
-
-<p><b>Init:</b>
-<pre>
- EditableListBox(wxWindow *parent, wxWindowID id=-1,
- const wxString& label,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = EL_ALLOW_NEW | EL_ALLOW_EDIT | EL_ALLOW_DELETE,
- const wxString& name = "editableListBox")
-</pre>
-
-<p><b>Methods:</b>
-<ul>
- <li><b>SetStrings(const wxArrayString& strings)</b> - Set an array of strings
- into the control. <b>Note</b>: The wxPython method accepts a Python list instead
- of an array of strings.
-
- <li><b>void GetStrings(wxArrayString& strings)</b> - Retrieves an array
- of strings from the control. The wxPython version returns a list of strings.
-
- <li><b>GetListCtrl()</b> - Retrieves a reference to the actual list control
- portion of the custom control.
-
- <li><b>GetDelButton()</b> - Retrieves a reference to the BitmapButton that is used
- as the 'delete' button in the control.
-
- <li><b>GetNewButton()</b> - Retrieves a reference to the BitmapButton that is used
- as the 'new' button in the control.
-
- <li><b>GetUpButton()</b> - Retrieves a reference to the BitmapButton that is used
- as the 'up' button in the control.
-
- <li><b>GetDownButton()</b> - Retrieves a reference to the BitmapButton that is used
- as the 'down' button in the control.
-
- <li><b>GetEditButton()</b> - Retrieves a reference to the BitmapButton that is used
- as the 'edit' button in the control.
-</ul>
-</body>
-</html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o editor lib hasn't been hit by the renamer yet.
-#
-# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxEditor -> Editor
-#
-
-import wx
-import wx.lib.editor as editor
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = wx.Panel(nb, -1)
- ed = editor.Editor(win, -1, style=wx.SUNKEN_BORDER)
- box = wx.BoxSizer(wx.VERTICAL)
- box.Add(ed, 1, wx.ALL|wx.GROW, 1)
- win.SetSizer(box)
- win.SetAutoLayout(True)
-
- ed.SetText(["",
- "This is a simple text editor, the class name is",
- "Editor. Type a few lines and try it out.",
- "",
- "It uses Windows-style key commands that can be overridden by subclassing.",
- "Mouse select works. Here are the key commands:",
- "",
- "Cursor movement: Arrow keys or mouse",
- "Beginning of line: Home",
- "End of line: End",
- "Beginning of buffer: Control-Home",
- "End of the buffer: Control-End",
- "Select text: Hold down Shift while moving the cursor",
- "Copy: Control-Insert, Control-C",
- "Cut: Shift-Delete, Control-X",
- "Paste: Shift-Insert, Control-V",
- ""])
-
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """
-The Editor class implements a simple text editor using wxPython. You
-can create a custom editor by subclassing Editor. Even though much of
-the editor is implemented in Python, it runs surprisingly smoothly on
-normal hardware with small files.
-
-How to use it
--------------
-The demo code (demo/Editor.py) shows how to use Editor as a simple text
-box. Use the SetText() and GetText() methods to set or get text from
-the component; these both use a list of strings.
-
-The samples/FrogEdit directory has an example of a simple text editor
-application that uses the Editor component.
-
-Subclassing
------------
-To add or change functionality, you can subclass this
-component. One example of this might be to change the key
-Alt key commands. In that case you would (for example) override the
-SetAltFuncs() method.
-
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import os
-import wx
-
-#---------------------------------------------------------------------------
-
-# This is how you pre-establish a file filter so that the dialog
-# only shows the extention(s) you want it to.
-wildcard = "Python source (*.py)|*.py|" \
- "Compiled Python (*.pyc)|*.pyc|" \
- "All files (*.*)|*.*"
-
-def runTest(frame, nb, log):
- log.WriteText("CWD: %s\n" % os.getcwd())
-
- # Create the dialog. In this case the current directory is forced as the starting
- # directory for the dialog, and no default file name is forced. This can easilly
- # be changed in your program. This is an 'open' dialog, and allows multitple
- # file selection to boot.
- #
- # Finally, of the directory is changed in the process of getting files, this
- # dialog is set up to change the current working directory to the path chosen.
- dlg = wx.FileDialog(
- frame, message="Choose a file", defaultDir=os.getcwd(),
- defaultFile="", wildcard=wildcard, style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR
- )
-
- # Show the dialog and retrieve the user response. If it is the OK response,
- # process the data.
- if dlg.ShowModal() == wx.ID_OK:
- # This returns a Python list of files that were selected.
- paths = dlg.GetPaths()
-
- log.WriteText('You selected %d files:' % len(paths))
-
- for path in paths:
- log.WriteText(' %s\n' % path)
-
- # Compare this with the debug above; did we change working dirs?
- log.WriteText("CWD: %s\n" % os.getcwd())
-
- # Destroy the dialog. Don't do this until you are done with it!
- # BAD things can happen otherwise!
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class provides the file selection dialog. It incorporates OS-native features
-depending on the OS in use, and can be used both for open and save operations.
-The files displayed can be filtered by setting up a wildcard filter, multiple files
-can be selected (open only), and files can be forced in a read-only mode.
-
-There are two ways to get the results back from the dialog. GetFiles() returns only
-the file names themselves, in a Python list. GetPaths() returns the full path and
-filenames combined as a Python list.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import os
-import wx
-
-#---------------------------------------------------------------------------
-
-# This is how you pre-establish a file filter so that the dialog
-# only shows the extention(s) you want it to.
-wildcard = "Python source (*.py)|*.py|" \
- "Compiled Python (*.pyc)|*.pyc|" \
- "SPAM files (*.spam)|*.spam|" \
- "Egg file (*.egg)|*.egg|" \
- "All files (*.*)|*.*"
-
-def runTest(frame, nb, log):
- log.WriteText("CWD: %s\n" % os.getcwd())
-
- # Create the dialog. In this case the current directory is forced as the starting
- # directory for the dialog, and no default file name is forced. This can easilly
- # be changed in your program. This is an 'save' dialog.
- #
- # Unlike the 'open dialog' example found elsewhere, this example does NOT
- # force the current working directory to change if the user chooses a different
- # directory than the one initially set.
- dlg = wx.FileDialog(
- frame, message="Save file as ...", defaultDir=os.getcwd(),
- defaultFile="", wildcard=wildcard, style=wx.SAVE
- )
-
- # This sets the default filter that the user will initially see. Otherwise,
- # the first filter in the list will be used by default.
- dlg.SetFilterIndex(2)
-
- # Show the dialog and retrieve the user response. If it is the OK response,
- # process the data.
- if dlg.ShowModal() == wx.ID_OK:
- path = dlg.GetPath()
- log.WriteText('You selected "%s"' % path)
-
- # Normally, at this point you would save your data using the file and path
- # data that the user provided to you, but since we didn't actually start
- # with any data to work with, that would be difficult.
- #
- # The code to do so would be similar to this, assuming 'data' contains
- # the data you want to save:
- #
- # fp = file(path, 'w') # Create file anew
- # fp.write(data)
- # fp.close()
- #
- # You might want to add some error checking :-)
- #
-
- # Note that the current working dir didn't change. This is good since
- # that's the way we set it up.
- log.WriteText("CWD: %s\n" % os.getcwd())
-
- # Destroy the dialog. Don't do this until you are done with it!
- # BAD things can happen otherwise!
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class provides the file selection dialog. It incorporates OS-native features
-depending on the OS in use, and can be used both for open and save operations.
-The files displayed can be filtered by setting up a wildcard filter, multiple files
-can be selected (open only), and files can be forced in a read-only mode.
-
-There are two ways to get the results back from the dialog. GetFiles() returns only
-the file names themselves, in a Python list. GetPaths() returns the full path and
-filenames combined as a Python list.
-
-One important thing to note: if you use the file extention filters, then files saved
-with the filter set to something will automatically get that extention appended to them
-if it is not already there. For example, suppose the dialog was displaying the 'egg'
-extention and you entered a file name of 'fried'. It would be saved as 'fried.egg.'
-Yum!
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import os
-import wx
-
-#----------------------------------------------------------------------
-
-text = """\
-Right-click on the panel above the line to get a menu. This menu will
-be managed by a FileHistory object and so the files you select will
-automatically be added to the end of the menu and will be selectable
-the next time the menu is viewed. The filename selected, either via the
-Open menu item, or from the history, will be displayed in the log
-window below.
-"""
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
- box = wx.BoxSizer(wx.VERTICAL)
-
- # Make and layout the controls
- fs = self.GetFont().GetPointSize()
- bf = wx.Font(fs+4, wx.SWISS, wx.NORMAL, wx.BOLD)
- nf = wx.Font(fs+2, wx.SWISS, wx.NORMAL, wx.NORMAL)
-
- t = wx.StaticText(self, -1, "FileHistory")
- t.SetFont(bf)
- box.Add(t, 0, wx.CENTER|wx.ALL, 5)
-
- box.Add(wx.StaticLine(self, -1), 0, wx.EXPAND)
- box.Add((10,20))
-
- t = wx.StaticText(self, -1, text)
- t.SetFont(nf)
- box.Add(t, 0, wx.CENTER|wx.ALL, 5)
-
- self.SetSizer(box)
- self.SetAutoLayout(True)
-
- # Make a menu
- self.menu = m = wx.Menu()
-
- # Little know wx Fact #42: there are a number of pre-set IDs
- # in the wx package, to be used for common controls such as those
- # illustrated below. Neat, huh?
- m.Append(wx.ID_NEW, "&New")
- m.Append(wx.ID_OPEN, "&Open...")
- m.Append(wx.ID_CLOSE, "&Close")
- m.Append(wx.ID_SAVE, "&Save")
- m.Append(wx.ID_SAVEAS, "Save &as...")
- m.Enable(wx.ID_NEW, False)
- m.Enable(wx.ID_CLOSE, False)
- m.Enable(wx.ID_SAVE, False)
- m.Enable(wx.ID_SAVEAS, False)
-
- # and a file history
- self.filehistory = wx.FileHistory()
- self.filehistory.UseMenu(self.menu)
-
- # and finally the event handler bindings
- self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
-
- self.Bind(wx.EVT_MENU, self.OnFileOpenDialog, id=wx.ID_OPEN)
-
- self.Bind(
- wx.EVT_MENU_RANGE, self.OnFileHistory, id=wx.ID_FILE1, id2=wx.ID_FILE9
- )
-
- self.Bind(wx.EVT_WINDOW_DESTROY, self.Cleanup)
-
-
- def Cleanup(self, *args):
- # A little extra cleanup is required for the FileHistory control
- del self.filehistory
- self.menu.Destroy()
-
-
- def OnRightClick(self, evt):
- self.PopupMenu(self.menu, evt.GetPosition())
-
-
- def OnFileOpenDialog(self, evt):
- dlg = wx.FileDialog(self,
- defaultDir = os.getcwd(),
- wildcard = "All Files|*",
- style = wx.OPEN | wx.CHANGE_DIR)
-
- if dlg.ShowModal() == wx.ID_OK:
- path = dlg.GetPath()
- self.log.write("You selected %s\n" % path)
-
- # add it to the history
- self.filehistory.AddFileToHistory(path)
-
- dlg.Destroy()
-
-
- def OnFileHistory(self, evt):
- # get the file based on the menu ID
- fileNum = evt.GetId() - wx.ID_FILE1
- path = self.filehistory.GetHistoryFile(fileNum)
- self.log.write("You selected %s\n" % path)
-
- # add it back to the history so it will be moved up the list
- self.filehistory.AddFileToHistory(path)
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h3>FileHistory</h3>
-
-wxFileHistory encapsulates functionality to record the last few files
-visited, and to allow the user to quickly load these files using the
-list appended to a menu, such as the File menu.
-
-<p>Note that this inclusion is not automatic; as illustrated in this example,
-you must add files (and remove them) as deemed necessary within the framework
-of your program.
-
-<p>Note also the additional cleanup required for this class, namely trapping the
-enclosing window's Destroy event and deleting the file history control and its
-associated menu.
-</body></html>
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/17/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Changed the event binding slightly.
-# o There are issues with the GetReplaceText() method of the
-# FindDialogEvent. Must be retested when this is fixed.
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- b = wx.Button(self, -1, "Show Find Dialog", (25, 50))
- self.Bind(wx.EVT_BUTTON, self.OnShowFind, b)
-
- b = wx.Button(self, -1, "Show Find && Replace Dialog", (25, 90))
- self.Bind(wx.EVT_BUTTON, self.OnShowFindReplace, b)
-
-
- # jg - 11/28/03 - corrected a long standing issue here where
- # EVT_COMMAND_FIND_* was being used for these event binders
- # instead of the actual event IDs shown below. As a result,
- # onFind() was never showing the appropriate type. I guess
- # nobody really paid much attention to that little
- # debugging window :-)
- #
- self.Bind(wx.EVT_FIND, self.OnFind)
- self.Bind(wx.EVT_FIND_NEXT, self.OnFind)
- self.Bind(wx.EVT_FIND_REPLACE, self.OnFind)
- self.Bind(wx.EVT_FIND_REPLACE_ALL, self.OnFind)
- self.Bind(wx.EVT_FIND_CLOSE, self.OnFindClose)
-
-
- def OnShowFind(self, evt):
- data = wx.FindReplaceData()
- dlg = wx.FindReplaceDialog(self, data, "Find")
- dlg.data = data # save a reference to it...
- dlg.Show(True)
-
-
- def OnShowFindReplace(self, evt):
- data = wx.FindReplaceData()
- dlg = wx.FindReplaceDialog(self, data, "Find & Replace", wx.FR_REPLACEDIALOG)
- dlg.data = data # save a reference to it...
- dlg.Show(True)
-
-
- def OnFind(self, evt):
- map = {
- wx.wxEVT_COMMAND_FIND : "FIND",
- wx.wxEVT_COMMAND_FIND_NEXT : "FIND_NEXT",
- wx.wxEVT_COMMAND_FIND_REPLACE : "REPLACE",
- wx.wxEVT_COMMAND_FIND_REPLACE_ALL : "REPLACE_ALL",
- }
-
- et = evt.GetEventType()
-
- #print evt.GetReplaceString()
-
- if et in map:
- evtType = map[et]
- else:
- evtType = "**Unknown Event Type**"
-
- #>> Todo: the GetReplaceString() method is broken. Has to be
- # fixed.
- if et == wx.EVT_COMMAND_FIND_REPLACE or et == wx.EVT_COMMAND_FIND_REPLACE_ALL:
- replaceTxt = "Replace text: %s" % evt.GetReplaceString()
- else:
- replaceTxt = ""
-
- self.log.write("%s -- Find text: %s %s Flags: %d \n" %
- (evtType, evt.GetFindString(), replaceTxt, evt.GetFlags()))
-
-
- def OnFindClose(self, evt):
- self.log.write("FindReplaceDialog closing...\n")
- evt.GetDialog().Destroy()
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-
-overview = """\
-FindReplaceDialog is a standard modeless dialog which is used to allow the user
-to search for some text (and possibly replace it with something else). The actual
-searching is supposed to be done in the owner window which is the parent of this
-dialog. Note that it means that unlike for the other standard dialogs this one
-<u>must have a parent window</u>. Also note that there is no way to use this
-dialog in a modal way; <b>it is always, by design and implementation, modeless</b>.
-
-FileReplaceDialog requires the use of <b>FindReplaceData</b>. This holds the
-data for the dialog. It is used to initialize the dialog with the default values
-and will keep the last values from the dialog when it is closed. It is also
-updated each time a FindDialogEvent is generated so instead of using the
-FindDialogEvent methods you can also directly query this object. <b>Care must be
-taken not to use this object after the dialog is destroyed.</b> The data within
-will be invalid after the parent dialog is destroyed.
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o OK, Main.py indicates this is deprecated. But I don't see a
-# replacement yet. So conversion is done anyway.
-#
-# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Issues - library has to be converted to work properly
-# with new namespace.
-#
-# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxFloatBar -> FloatBar
-#
-
-import wx
-import wx.lib.floatbar
-
-import images
-
-
-class TestFloatBar(wx.Frame):
- def __init__(self, parent, log):
- wx.Frame.__init__(
- self, parent, -1, 'Test ToolBar', wx.DefaultPosition, (500, 300)
- )
-
- self.log = log
-
- win = wx.Window(self, -1)
- win.SetBackgroundColour("WHITE")
- wx.StaticText(
- win, -1, "Drag the toolbar to float it,\n"
- "Toggle the last tool to remove\nthe title.", (15,15)
- )
-
- tb = wx.lib.floatbar.FloatBar(self, -1)
- self.SetToolBar(tb)
- tb.SetFloatable(1)
- tb.SetTitle("Floating!")
- self.CreateStatusBar()
-
- tb.AddSimpleTool(10, images.getNewBitmap(), "New", "Long help for 'New'")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=10)
-
- tb.AddSimpleTool(20, images.getOpenBitmap(), "Open")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=20)
-
- tb.AddSeparator()
- tb.AddSimpleTool(30, images.getCopyBitmap(), "Copy")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=30)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=30)
-
- tb.AddSimpleTool(40, images.getPasteBitmap(), "Paste")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=40)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=40)
-
- tb.AddSeparator()
-
- tb.AddCheckTool(60, images.getTog1Bitmap(), images.getTog2Bitmap())
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=60)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=60)
-
- tb.Realize()
-
- self.tb = tb
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
-
- def OnCloseWindow(self, event):
- self.Destroy()
-
- def OnToolClick(self, event):
- self.log.WriteText("tool %s clicked\n" % event.GetId())
-
- if event.GetId() == 60:
- print event.GetExtraLong(), event.IsChecked(), event.GetInt(), self.tb.GetToolState(60)
-
- if event.GetExtraLong():
- self.tb.SetTitle("")
- else:
- self.tb.SetTitle("Floating!")
-
- def OnToolRClick(self, event):
- self.log.WriteText("tool %s right-clicked\n" % event.GetId())
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestFloatBar(frame, log)
- frame.otherWin = win
- win.Show(True)
-
-#---------------------------------------------------------------------------
-
-overview = """\
-FloatBar is a subclass of wx.ToolBar, implemented in Python, which
-can be detached from its frame.
-
-Drag the toolbar with the mouse to make it float, and drag it back, or
-close it to make the toolbar return to its original position.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- btn = wx.Button(self, -1, "Select Font")
- self.Bind(wx.EVT_BUTTON, self.OnSelectFont, btn)
-
- self.sampleText = wx.TextCtrl(self, -1, "Sample Text")
- #from wxPython.lib.stattext import wxGenStaticText
- #self.sampleText = wxGenStaticText(self, -1, "Sample Text")
-
- self.curFont = self.sampleText.GetFont()
- self.curClr = wx.BLACK
-
- fgs = wx.FlexGridSizer(cols=2, vgap=5, hgap=5)
- fgs.AddGrowableCol(1)
- fgs.AddGrowableRow(0)
-
- fgs.Add(btn)
- fgs.Add(self.sampleText, 0, wx.ADJUST_MINSIZE|wx.GROW)
-
- fgs.Add((15,15)); fgs.Add((15,15)) # an empty row
-
- fgs.Add(wx.StaticText(self, -1, "PointSize:"))
- self.ps = wx.StaticText(self, -1, "")
- font = self.ps.GetFont()
- font.SetWeight(wx.BOLD)
- self.ps.SetFont(font)
- fgs.Add(self.ps, 0, wx.ADJUST_MINSIZE)
-
- fgs.Add(wx.StaticText(self, -1, "Family:"))
- self.family = wx.StaticText(self, -1, "")
- self.family.SetFont(font)
- fgs.Add(self.family, 0, wx.ADJUST_MINSIZE)
-
- fgs.Add(wx.StaticText(self, -1, "Style:"))
- self.style = wx.StaticText(self, -1, "")
- self.style.SetFont(font)
- fgs.Add(self.style, 0, wx.ADJUST_MINSIZE)
-
- fgs.Add(wx.StaticText(self, -1, "Weight:"))
- self.weight = wx.StaticText(self, -1, "")
- self.weight.SetFont(font)
- fgs.Add(self.weight, 0, wx.ADJUST_MINSIZE)
-
- fgs.Add(wx.StaticText(self, -1, "Face:"))
- self.face = wx.StaticText(self, -1, "")
- self.face.SetFont(font)
- fgs.Add(self.face, 0, wx.ADJUST_MINSIZE)
-
- fgs.Add((15,15)); fgs.Add((15,15)) # an empty row
-
- fgs.Add(wx.StaticText(self, -1, "wx.NativeFontInfo:"))
- self.nfi = wx.StaticText(self, -1, "")
- self.nfi.SetFont(font)
- fgs.Add(self.nfi, 0, wx.ADJUST_MINSIZE)
-
- # give it some border space
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(fgs, 0, wx.GROW|wx.ADJUST_MINSIZE|wx.ALL, 25)
-
- self.SetSizer(sizer)
- self.UpdateUI()
-
-
- def UpdateUI(self):
- self.sampleText.SetFont(self.curFont)
- self.ps.SetLabel(str(self.curFont.GetPointSize()))
- self.family.SetLabel(self.curFont.GetFamilyString())
- self.style.SetLabel(self.curFont.GetStyleString())
- self.weight.SetLabel(self.curFont.GetWeightString())
- self.face.SetLabel(self.curFont.GetFaceName())
- self.nfi.SetLabel(self.curFont.GetNativeFontInfo().ToString())
- self.Layout()
-
-
- def OnSelectFont(self, evt):
- data = wx.FontData()
- data.EnableEffects(True)
- data.SetColour(self.curClr) # set colour
- data.SetInitialFont(self.curFont)
-
- dlg = wx.FontDialog(self, data)
-
- if dlg.ShowModal() == wx.ID_OK:
- data = dlg.GetFontData()
- font = data.GetChosenFont()
- colour = data.GetColour()
-
- self.log.WriteText('You selected: "%s", %d points, color %s\n' %
- (font.GetFaceName(), font.GetPointSize(),
- colour.Get()))
-
- self.curFont = font
- self.curClr = colour
- self.UpdateUI()
-
- # Don't destroy the dialog until you get everything you need from the
- # dialog!
- dlg.Destroy()
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class allows you to use the system font selection dialog
-from within your program. Generally speaking, this allows you
-to select a font by its name, font size, and weight, and
-on some systems such things as strikethrough and underline.
-
-As with other dialogs used in wxPython, it is important to
-use the class' methods to extract the information you need
-about the font <b>before</b> you destroy the dialog. Failure
-to observe this almost always leads to a program failure of
-some sort, often ugly.
-
-This demo serves two purposes; it shows how to use the dialog
-to GET font information from the user, but also shows how
-to APPLY that information once you get it.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class MyFrame(wx.Frame):
- def __init__(
- self, parent, ID, title, pos=wx.DefaultPosition,
- size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE
- ):
-
- wx.Frame.__init__(self, parent, ID, title, pos, size, style)
- panel = wx.Panel(self, -1)
-
- button = wx.Button(panel, 1003, "Close Me")
- button.SetPosition((15, 15))
- self.Bind(wx.EVT_BUTTON, self.OnCloseMe, button)
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
-
- def OnCloseMe(self, event):
- self.Close(True)
-
- def OnCloseWindow(self, event):
- self.Destroy()
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = MyFrame(frame, -1, "This is a wxFrame", size=(350, 200),
- style = wx.DEFAULT_FRAME_STYLE)# | wx.FRAME_TOOL_WINDOW )
- frame.otherWin = win
- win.Show(True)
-
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-A Frame is a window whose size and position can (usually) be changed by
-the user. It usually has thick borders and a title bar, and can optionally
-contain a menu bar, toolbar and status bar. A frame can contain any window
-that is not a Frame or Dialog. It is one of the most fundamental of the
-wxWindows components.
-
-A Frame that has a status bar and toolbar created via the
-<code>CreateStatusBar</code> / <code>CreateToolBar</code> functions manages
-these windows, and adjusts the value returned by <code>GetClientSize</code>
-to reflect the remaining size available to application windows.
-
-By itself, a Frame is not too useful, but with the addition of Panels and
-other child objects, it encompasses the framework around which most user
-interfaces are constructed.
-
-If you plan on using Sizers and auto-layout features, be aware that the Frame
-class lacks the ability to handle these features unless it contains a Panel.
-The Panel has all the necessary functionality to both control the size of
-child components, and also communicate that information in a useful way to
-the Frame itself.
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o Note: unable to install PyOpenGL on my system as I am running Python 2.3
-# and PyOpenGL does not support anything above Python 2.2. Did what I could,
-# but odds are good there are problems.
-#
-
-import wx
-
-try:
- import wx.glcanvas as glcanvas
- haveGLCanvas = True
-except ImportError:
- haveGLCanvas = False
-
-try:
- # The Python OpenGL package can be found at
- # http://PyOpenGL.sourceforge.net/
-
- import OpenGL.GL as gl
- import OpenGL.GLUT as glut
- haveOpenGL = True
-except ImportError:
- haveOpenGL = False
-
-#----------------------------------------------------------------------
-
-if not haveGLCanvas:
- def runTest(frame, nb, log):
- dlg = wx.MessageDialog(
- frame, 'The wxGLCanvas has not been included with this build of wxPython!',
- 'Sorry', wx.OK | wx.ICON_INFORMATION
- )
-
- dlg.ShowModal()
- dlg.Destroy()
-
-elif not haveOpenGL:
- def runTest(frame, nb, log):
- dlg = wx.MessageDialog(
- frame, 'The OpenGL package was not found. You can get it at\n'
- 'http://PyOpenGL.sourceforge.net/', 'Sorry', wx.OK | wx.ICON_INFORMATION
- )
-
- dlg.ShowModal()
- dlg.Destroy()
-
-
-else:
- buttonDefs = {
- wx.NewId() : ('CubeCanvas', 'Cube'),
- wx.NewId() : ('ConeCanvas', 'Cone'),
- }
-
- class ButtonPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- box = wx.BoxSizer(wx.VERTICAL)
- box.Add((20, 30))
- keys = buttonDefs.keys()
- keys.sort()
-
- for k in keys:
- text = buttonDefs[k][1]
- btn = wx.Button(self, k, text)
- box.Add(btn, 0, wx.ALIGN_CENTER|wx.ALL, 15)
- self.Bind(wx.EVT_BUTTON, self.OnButton, id=k)
-
- #** Enable this to show putting a wxGLCanvas on the wxPanel
- if 0:
- c = CubeCanvas(self)
- c.SetSize((200, 200))
- box.Add(c, 0, wx.ALIGN_CENTER|wx.ALL, 15)
-
- self.SetAutoLayout(True)
- self.SetSizer(box)
-
-
- def OnButton(self, evt):
- canvasClassName = buttonDefs[evt.GetId()][0]
- canvasClass = eval(canvasClassName)
- frame = wx.Frame(None, -1, canvasClassName, size=(400,400))
- canvas = canvasClass(frame)
- frame.Show(True)
-
-
-
- def runTest(frame, nb, log):
- win = ButtonPanel(nb, log)
- return win
-
-
-
-
- class MyCanvasBase(glcanvas.GLCanvas):
- def __init__(self, parent):
- glcanvas.GLCanvas.__init__(self, parent, -1)
- self.init = False
- # initial mouse position
- self.lastx = self.x = 30
- self.lasty = self.y = 30
- self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
- self.Bind(wx.EVT_SIZE, self.OnSize)
- self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown) # needs fixing...
- self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)
- self.Bind(wx.EVT_MOTION, self.OnMouseMotion)
-
- def OnEraseBackground(self, event):
- pass # Do nothing, to avoid flashing on MSW.
-
- def OnSize(self, event):
- size = self.GetClientSize()
-
- if self.GetContext():
- self.SetCurrent()
- glcanvas.glViewport(0, 0, size.width, size.height)
-
- def OnPaint(self, event):
- dc = wx.PaintDC(self)
- self.SetCurrent()
-
- if not self.init:
- self.InitGL()
- self.init = True
-
- self.OnDraw()
-
- def OnMouseDown(self, evt):
- self.CaptureMouse()
-
- def OnMouseUp(self, evt):
- self.ReleaseMouse()
-
- def OnMouseMotion(self, evt):
- if evt.Dragging() and evt.LeftIsDown():
- self.x, self.y = self.lastx, self.lasty
- self.x, self.y = evt.GetPosition()
- self.Refresh(False)
-
-
- class CubeCanvas(MyCanvasBase):
- def InitGL(self):
- # set viewing projection
- glcanvas.glMatrixMode(glcanvas.GL_PROJECTION);
- glcanvas.glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0);
-
- # position viewer
- glcanvas.glMatrixMode(glcanvas.GL_MODELVIEW);
- glcanvas.glTranslatef(0.0, 0.0, -2.0);
-
- # position object
- glcanvas.glRotatef(self.y, 1.0, 0.0, 0.0);
- glcanvas.glRotatef(self.x, 0.0, 1.0, 0.0);
-
- glcanvas.glEnable(glcanvas.GL_DEPTH_TEST);
- glcanvas.glEnable(glcanvas.GL_LIGHTING);
- glcanvas.glEnable(glcanvas.GL_LIGHT0);
-
-
- def OnDraw(self):
- # clear color and depth buffers
- glcanvas.glClear(glcanvas.GL_COLOR_BUFFER_BIT | glcanvas.GL_DEPTH_BUFFER_BIT)
-
- # draw six faces of a cube
- glcanvas.glBegin(glcanvas.GL_QUADS)
- glcanvas.glNormal3f( 0.0, 0.0, 1.0)
- glcanvas.glVertex3f( 0.5, 0.5, 0.5)
- glcanvas.glVertex3f(-0.5, 0.5, 0.5)
- glcanvas.glVertex3f(-0.5,-0.5, 0.5)
- glcanvas.glVertex3f( 0.5,-0.5, 0.5)
-
- glcanvas.glNormal3f( 0.0, 0.0,-1.0)
- glcanvas.glVertex3f(-0.5,-0.5,-0.5)
- glcanvas.glVertex3f(-0.5, 0.5,-0.5)
- glcanvas.glVertex3f( 0.5, 0.5,-0.5)
- glcanvas.glVertex3f( 0.5,-0.5,-0.5)
-
- glcanvas.glNormal3f( 0.0, 1.0, 0.0)
- glcanvas.glVertex3f( 0.5, 0.5, 0.5)
- glcanvas.glVertex3f( 0.5, 0.5,-0.5)
- glcanvas.glVertex3f(-0.5, 0.5,-0.5)
- glcanvas.glVertex3f(-0.5, 0.5, 0.5)
-
- glcanvas.glNormal3f( 0.0,-1.0, 0.0)
- glcanvas.glVertex3f(-0.5,-0.5,-0.5)
- glcanvas.glVertex3f( 0.5,-0.5,-0.5)
- glcanvas.glVertex3f( 0.5,-0.5, 0.5)
- glcanvas.glVertex3f(-0.5,-0.5, 0.5)
-
- glcanvas.glNormal3f( 1.0, 0.0, 0.0)
- glcanvas.glVertex3f( 0.5, 0.5, 0.5)
- glcanvas.glVertex3f( 0.5,-0.5, 0.5)
- glcanvas.glVertex3f( 0.5,-0.5,-0.5)
- glcanvas.glVertex3f( 0.5, 0.5,-0.5)
-
- glcanvas.glNormal3f(-1.0, 0.0, 0.0)
- glcanvas.glVertex3f(-0.5,-0.5,-0.5)
- glcanvas.glVertex3f(-0.5,-0.5, 0.5)
- glcanvas.glVertex3f(-0.5, 0.5, 0.5)
- glcanvas.glVertex3f(-0.5, 0.5,-0.5)
- glcanvas.glEnd()
-
- glcanvas.glRotatef((self.lasty - self.y)/100., 1.0, 0.0, 0.0);
- glcanvas.glRotatef((self.lastx - self.x)/100., 0.0, 1.0, 0.0);
-
- self.SwapBuffers()
-
-
- class ConeCanvas(MyCanvasBase):
- def InitGL( self ):
- glcanvas.glMatrixMode(glcanvas.GL_PROJECTION);
- # camera frustrum setup
- glcanvas.glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0);
- glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
- glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0])
- glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_SPECULAR, [1.0, 0.0, 1.0, 1.0])
- glcanvas.glMaterial(glcanvas.GL_FRONT, glcanvas.GL_SHININESS, 50.0)
- glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_AMBIENT, [0.0, 1.0, 0.0, 1.0])
- glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0])
- glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
- glcanvas.glLight(glcanvas.GL_LIGHT0, glcanvas.GL_POSITION, [1.0, 1.0, 1.0, 0.0]);
- glcanvas.glLightModel(glcanvas.GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
- glcanvas.glEnable(glcanvas.GL_LIGHTING)
- glcanvas.glEnable(glcanvas.GL_LIGHT0)
- glcanvas.glDepthFunc(glcanvas.GL_LESS)
- glcanvas.glEnable(glcanvas.GL_DEPTH_TEST)
- glcanvas.glClear(glcanvas.GL_COLOR_BUFFER_BIT | glcanvas.GL_DEPTH_BUFFER_BIT)
- # position viewer
- glcanvas.glMatrixMode(glcanvas.GL_MODELVIEW);
-
-
- def OnDraw(self):
- # clear color and depth buffers
- glcanvas.glClear(glcanvas.GL_COLOR_BUFFER_BIT | glcanvas.GL_DEPTH_BUFFER_BIT);
- # use a fresh transformation matrix
- glcanvas.glPushMatrix()
- # position object
- glcanvas.glTranslate(0.0, 0.0, -2.0);
- glcanvas.glRotate(30.0, 1.0, 0.0, 0.0);
- glcanvas.glRotate(30.0, 0.0, 1.0, 0.0);
-
- glcanvas.glTranslate(0, -1, 0)
- glcanvas.glRotate(250, 1, 0, 0)
- glcanvas.glutSolidCone(0.5, 1, 30, 5)
- glcanvas.glPopMatrix()
- glcanvas.glRotatef((self.lasty - self.y)/100., 0.0, 0.0, 1.0);
- glcanvas.glRotatef(0.0, (self.lastx - self.x)/100., 1.0, 0.0);
- # push into visible buffer
- self.SwapBuffers()
-
-
-
-
-#----------------------------------------------------------------------
-
-
-
-overview = """\
-"""
-
-
-#----------------------------------------------------------------------
-
-def _test():
- class MyApp(wxApp):
- def OnInit(self):
- frame = wx.Frame(None, -1, "GL Demos", wx.DefaultPosition, (600,300))
- #win = ConeCanvas(frame)
- MySplitter(frame)
- frame.Show(True)
- self.SetTopWindow(frame)
- return True
-
- app = MyApp(0)
- app.MainLoop()
-
-if __name__ == '__main__':
- _test()
-
+++ /dev/null
-# 11/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
- self.count = 0
-
- wx.StaticText(self, -1, "This example shows the wxGauge control.", (45, 15))
-
- self.g1 = wx.Gauge(self, -1, 50, (110, 50), (250, 25))
- self.g1.SetBezelFace(3)
- self.g1.SetShadowWidth(3)
-
- self.g2 = wx.Gauge(
- self, -1, 50, (110, 95), (250, 25),
- wx.GA_HORIZONTAL|wx.GA_SMOOTH
- )
-
- self.g2.SetBezelFace(5)
- self.g2.SetShadowWidth(5)
-
- self.Bind(wx.EVT_IDLE, self.IdleHandler)
-
-
- def IdleHandler(self, event):
- self.count = self.count + 1
-
- if self.count >= 50:
- self.count = 0
-
- self.g1.SetValue(self.count)
- self.g2.SetValue(self.count)
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-A Gauge is a horizontal or vertical bar which shows a quantity in a graphical
-fashion. It is often used to indicate progress through lengthy tasks, such as
-file copying or data analysis.
-
-When the Gauge is initialized, it's "complete" value is usually set; at any rate,
-before using the Gauge, the maximum value of the control must be set. As the task
-progresses, the Gauge is updated by the program via the <code>SetValue</code> method.
-
-This control is for use within a GUI; there is a seperate ProgressDialog class
-to present the same sort of control as a dialog to the user.
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- txt1 = wx.StaticText(self, -1, "style=0")
- dir1 = wx.GenericDirCtrl(self, -1, size=(200,225), style=0)
-
- txt2 = wx.StaticText(self, -1, "wx.DIRCTRL_DIR_ONLY")
- dir2 = wx.GenericDirCtrl(self, -1, size=(200,225), style=wx.DIRCTRL_DIR_ONLY)
-
- txt3 = wx.StaticText(self, -1, "wx.DIRCTRL_SHOW_FILTERS")
- dir3 = wx.GenericDirCtrl(self, -1, size=(200,225), style=wx.DIRCTRL_SHOW_FILTERS,
- filter="All files (*.*)|*.*|Python files (*.py)|*.py")
-
- sz = wx.FlexGridSizer(cols=3, hgap=5, vgap=5)
- sz.Add((35, 35)) # some space above
- sz.Add((35, 35))
- sz.Add((35, 35))
-
- sz.Add(txt1)
- sz.Add(txt2)
- sz.Add(txt3)
-
- sz.Add(dir1, 0, wx.EXPAND)
- sz.Add(dir2, 0, wx.EXPAND)
- sz.Add(dir3, 0, wx.EXPAND)
-
- sz.Add((35,35)) # some space below
-
- sz.AddGrowableRow(2)
- sz.AddGrowableCol(0)
- sz.AddGrowableCol(1)
- sz.AddGrowableCol(2)
-
- self.SetSizer(sz)
- self.SetAutoLayout(True)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-This control can be used to place a directory listing (with optional files)
-on an arbitrary window. The control contains a TreeCtrl window representing
-the directory hierarchy, and optionally, a Choice window containing a list
-of filters.
-
-The filters work in the same manner as in FileDialog.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-buttonDefs = {
- 814 : ('GridSimple', ' Simple wxGrid, catching all events '),
- 815 : ('GridStdEdRend', ' wxGrid showing Editors and Renderers '),
- 818 : ('GridHugeTable', ' A wxGrid with a HUGE table (100 MILLION cells!) '),
- 817 : ('GridCustTable', ' wxGrid using a custom Table, with non-string data '),
- 819 : ('GridEnterHandler',' Remapping keys to behave differently '),
- 820 : ('GridCustEditor', ' Shows how to create a custom Cell Editor '),
- 821 : ('GridDragable', ' A wxGrid with dragable rows and columns '),
- 822 : ('GridDragAndDrop', ' Shows how to make a grid a drop target for files'),
- }
-
-
-class ButtonPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- box = wx.BoxSizer(wx.VERTICAL)
- box.Add((20, 20))
- keys = buttonDefs.keys()
- keys.sort()
-
- for k in keys:
- text = buttonDefs[k][1]
- btn = wx.Button(self, k, text)
- box.Add(btn, 0, wx.ALIGN_CENTER|wx.ALL, 10)
- self.Bind(wx.EVT_BUTTON, self.OnButton, btn)
-
- self.SetAutoLayout(True)
- self.SetSizer(box)
-
-
- def OnButton(self, evt):
- modName = buttonDefs[evt.GetId()][0]
- module = __import__(modName)
- frame = module.TestFrame(None, self.log)
- frame.Show(True)
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = ButtonPanel(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-<html><body>
-<h2>wxGrid</h2>
-
-This demo shows various ways of using the <b><i>new and
-improved</i></b> wxGrid class. Unfortunatly it has not been
-documented yet, and while it is somewhat backwards compatible, if you
-try to go by the current wxGrid documentation you will probably just
-confuse yourself.
-<p>
-You can look at the sources for these samples to learn a lot about how
-the new classes work.
-<p><ol>
-<li><a href="GridSimple.py">GridSimple.py</a> A simple grid that shows
-how to catch all the various events.
-
-<p>
-<li><a href="GridStdEdRend.py">GridStdEdRend.py</a> A grid that
-uses non-default Cell Editors and Cell Renderers.
-
-<p>
-<li><a href="GridHugeTable.py">GridHugeTable.py</a> A grid that
-uses a non-default Grid Table. This table is read-only and simply
-generates on the fly a unique string for each cell.
-
-<p>
-<li><a href="GridCustTable.py">GridCustTable.py</a> This grid
-shows how to deal with tables that have non-string data, and how Cell
-Editors and Cell Renderers are automatically chosen based on the data
-type.
-
-<p>
-<li><a href="GridEnterHandler.py">GridEnterHandler.py</a>This one
-changes how the ENTER key works, moving the current cell left to right
-and wrapping around to the next row when needed.
-</ol>
-<p>
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-
-import wx # This module uses the new wx namespace
-
-#----------------------------------------------------------------------
-gbsDescription = """\
-The wxGridBagSizer is similar to the wxFlexGridSizer except the items are explicitly positioned
-in a virtual cell of the layout grid, and column or row spanning is allowed. For example, this
-static text is positioned at (0,0) and it spans 7 columns.
-"""
-
-
-class TestFrame(wx.Frame):
- def __init__(self):
- wx.Frame.__init__(self, None, -1, "wxGridBagSizer")
- p = wx.Panel(self, -1)
- p.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
-
- gbs = self.gbs = wx.GridBagSizer(5, 5)
-
- gbs.Add( wx.StaticText(p, -1, gbsDescription),
- (0,0), (1,7), wx.ALIGN_CENTER | wx.ALL, 5)
-
- gbs.Add( wx.TextCtrl(p, -1, "pos(1,0)"), (1,0) )
- gbs.Add( wx.TextCtrl(p, -1, "pos(1,1)"), (1,1) )
- gbs.Add( wx.TextCtrl(p, -1, "pos(2,0)"), (2,0) )
- gbs.Add( wx.TextCtrl(p, -1, "pos(2,1)"), (2,1) )
-
- gbs.Add( wx.TextCtrl(p, -1, "pos(3,2), span(1,2)\nthis row and col are growable", style=wx.TE_MULTILINE),
- (3,2), (1,2), flag=wx.EXPAND )
-
- gbs.Add( wx.TextCtrl(p, -1, "pos(4,3), span(3,1)", style=wx.TE_MULTILINE),
- (4,3), (3,1), wx.EXPAND)
-
- gbs.Add( wx.TextCtrl(p, -1, "pos(5,4)"), (5,4), flag=wx.EXPAND )
- gbs.Add( wx.TextCtrl(p, -1, "pos(6,5)"), (6,5), flag=wx.EXPAND )
- gbs.Add( wx.TextCtrl(p, -1, "pos(7,6)"), (7,6) )
-
- moveBtn1 = wx.Button(p, -1, "Move this to (3,6)")
- moveBtn2 = wx.Button(p, -1, "Move this to (3,6)");
- gbs.Add( moveBtn1, (10,2) )
- gbs.Add( moveBtn2, (10,3) )
-
- hideBtn = wx.Button(p, -1, "Hide this item -->")
- gbs.Add(hideBtn, (12, 3))
-
- hideTxt = wx.TextCtrl(p, -1, "pos(12,4), size(150, -1)", size = (150,-1))
- gbs.Add( hideTxt, (12,4) )
-
- showBtn = wx.Button(p, -1, "<-- Show it again")
- gbs.Add(showBtn, (12, 5))
- showBtn.Disable()
- self.hideBtn = hideBtn
- self.showBtn = showBtn
- self.hideTxt = hideTxt
-
- self.Bind(wx.EVT_BUTTON, self.OnHideButton, hideBtn)
- self.Bind(wx.EVT_BUTTON, self.OnShowButton, showBtn)
- self.Bind(wx.EVT_BUTTON, self.OnMoveButton, moveBtn1)
- self.Bind(wx.EVT_BUTTON, self.OnMoveButton, moveBtn2)
-
- # Add a spacer at the end to ensure some extra space at the bottom
- gbs.Add((10,10), (14,7))
-
- gbs.AddGrowableRow(3)
- gbs.AddGrowableCol(2)
-
- p.SetSizerAndFit(gbs)
- self.SetClientSize(p.GetSize())
-
-
- def OnHideButton(self, evt):
- self.gbs.Hide(self.hideTxt)
- self.hideBtn.Disable()
- self.showBtn.Enable()
- self.gbs.Layout()
-
-
- def OnShowButton(self, evt):
- self.gbs.Show(self.hideTxt)
- self.hideBtn.Enable()
- self.showBtn.Disable()
- self.gbs.Layout()
-
-
- def OnMoveButton(self, evt):
- btn = evt.GetEventObject()
- curPos = self.gbs.GetItemPosition(btn)
-
- # if it's already at the "other" spot then move it back
- if curPos == (3,6):
- self.gbs.SetItemPosition(btn, self.lastPos)
- btn.SetLabel("Move this to (3,6)")
- else:
- if self.gbs.CheckForIntersection( (3,6), (1,1) ):
- wx.MessageBox("""\
-wxGridBagSizer will not allow items to be in the same cell as
-another item, so this operation will fail. You will also get an assert
-when compiled in debug mode.""",
- "Warning", wx.OK | wx.ICON_INFORMATION)
-
- try:
- if self.gbs.SetItemPosition(btn, (3,6)):
- self.lastPos = curPos
- btn.SetLabel("Move it back")
- except wx.PyAssertionError:
- pass
-
- self.gbs.Layout()
-
-
- def OnLeftDown(self, evt):
- pt = evt.GetPosition()
- item = self.gbs.FindItemAtPoint(pt)
- if item is None:
- print "no item at", `pt`
- else:
- print "item found: ", `item.GetPos()`, "--", `item.GetSpan()`
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestFrame()
- frame.otherWin = win
- win.Show(True)
-
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>wxGridBagSizer</center></h2>
-
-The wxGridBagSizer is more or less a port of the the RowColSizer (that
-has been in the wxPython.lib package for quite some time) to C++. It
-allows items to be placed at specific layout grid cells, and items can
-span across more than one row or column.
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import wx.grid as Grid
-
-import images
-
-class MegaTable(Grid.PyGridTableBase):
- """
- A custom wxGrid Table using user supplied data
- """
- def __init__(self, data, colnames, plugins):
- """data is a list of the form
- [(rowname, dictionary),
- dictionary.get(colname, None) returns the data for column
- colname
- """
- # The base class must be initialized *first*
- Grid.PyGridTableBase.__init__(self)
- self.data = data
- self.colnames = colnames
- self.plugins = plugins or {}
- # XXX
- # we need to store the row length and column length to
- # see if the table has changed size
- self._rows = self.GetNumberRows()
- self._cols = self.GetNumberCols()
-
- def GetNumberCols(self):
- return len(self.colnames)
-
- def GetNumberRows(self):
- return len(self.data)
-
- def GetColLabelValue(self, col):
- return self.colnames[col]
-
- def GetRowLabelValue(self, row):
- return "row %03d" % int(self.data[row][0])
-
- def GetValue(self, row, col):
- return str(self.data[row][1].get(self.GetColLabelValue(col), ""))
-
- def GetRawValue(self, row, col):
- return self.data[row][1].get(self.GetColLabelValue(col), "")
-
- def SetValue(self, row, col, value):
- self.data[row][1][self.GetColLabelValue(col)] = value
-
- def ResetView(self, grid):
- """
- (Grid) -> Reset the grid view. Call this to
- update the grid if rows and columns have been added or deleted
- """
- grid.BeginBatch()
-
- for current, new, delmsg, addmsg in [
- (self._rows, self.GetNumberRows(), Grid.GRIDTABLE_NOTIFY_ROWS_DELETED, Grid.GRIDTABLE_NOTIFY_ROWS_APPENDED),
- (self._cols, self.GetNumberCols(), Grid.GRIDTABLE_NOTIFY_COLS_DELETED, Grid.GRIDTABLE_NOTIFY_COLS_APPENDED),
- ]:
-
- if new < current:
- msg = Grid.GridTableMessage(self,delmsg,new,current-new)
- grid.ProcessTableMessage(msg)
- elif new > current:
- msg = Grid.GridTableMessage(self,addmsg,new-current)
- grid.ProcessTableMessage(msg)
- self.UpdateValues(grid)
-
- grid.EndBatch()
-
- self._rows = self.GetNumberRows()
- self._cols = self.GetNumberCols()
- # update the column rendering plugins
- self._updateColAttrs(grid)
-
- # update the scrollbars and the displayed part of the grid
- grid.AdjustScrollbars()
- grid.ForceRefresh()
-
-
- def UpdateValues(self, grid):
- """Update all displayed values"""
- # This sends an event to the grid table to update all of the values
- msg = Grid.GridTableMessage(self, Grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
- grid.ProcessTableMessage(msg)
-
- def _updateColAttrs(self, grid):
- """
- wxGrid -> update the column attributes to add the
- appropriate renderer given the column name. (renderers
- are stored in the self.plugins dictionary)
-
- Otherwise default to the default renderer.
- """
- col = 0
-
- for colname in self.colnames:
- attr = Grid.GridCellAttr()
- if colname in self.plugins:
- renderer = self.plugins[colname](self)
-
- if renderer.colSize:
- grid.SetColSize(col, renderer.colSize)
-
- if renderer.rowSize:
- grid.SetDefaultRowSize(renderer.rowSize)
-
- attr.SetReadOnly(True)
- attr.SetRenderer(renderer)
-
- grid.SetColAttr(col, attr)
- col += 1
-
- # ------------------------------------------------------
- # begin the added code to manipulate the table (non wx related)
- def AppendRow(self, row):
- #print 'append'
- entry = {}
-
- for name in self.colnames:
- entry[name] = "Appended_%i"%row
-
- # XXX Hack
- # entry["A"] can only be between 1..4
- entry["A"] = random.choice(range(4))
- self.data.insert(row, ["Append_%i"%row, entry])
-
- def DeleteCols(self, cols):
- """
- cols -> delete the columns from the dataset
- cols hold the column indices
- """
- # we'll cheat here and just remove the name from the
- # list of column names. The data will remain but
- # it won't be shown
- deleteCount = 0
- cols = cols[:]
- cols.sort()
-
- for i in cols:
- self.colnames.pop(i-deleteCount)
- # we need to advance the delete count
- # to make sure we delete the right columns
- deleteCount += 1
-
- if not len(self.colnames):
- self.data = []
-
- def DeleteRows(self, rows):
- """
- rows -> delete the rows from the dataset
- rows hold the row indices
- """
- deleteCount = 0
- rows = rows[:]
- rows.sort()
-
- for i in rows:
- self.data.pop(i-deleteCount)
- # we need to advance the delete count
- # to make sure we delete the right rows
- deleteCount += 1
-
- def SortColumn(self, col):
- """
- col -> sort the data based on the column indexed by col
- """
- name = self.colnames[col]
- _data = []
-
- for row in self.data:
- rowname, entry = row
- _data.append((entry.get(name, None), row))
-
- _data.sort()
- self.data = []
-
- for sortvalue, row in _data:
- self.data.append(row)
-
- # end table manipulation code
- # ----------------------------------------------------------
-
-
-# --------------------------------------------------------------------
-# Sample wxGrid renderers
-
-class MegaImageRenderer(Grid.PyGridCellRenderer):
- def __init__(self, table):
- """
- Image Renderer Test. This just places an image in a cell
- based on the row index. There are N choices and the
- choice is made by choice[row%N]
- """
- Grid.PyGridCellRenderer.__init__(self)
- self.table = table
- self._choices = [images.getSmilesBitmap,
- images.getMondrianBitmap,
- images.get_10s_Bitmap,
- images.get_01c_Bitmap]
-
- self.colSize = None
- self.rowSize = None
-
- def Draw(self, grid, attr, dc, rect, row, col, isSelected):
- choice = self.table.GetRawValue(row, col)
- bmp = self._choices[ choice % len(self._choices)]()
- image = wx.MemoryDC()
- image.SelectObject(bmp)
-
- # clear the background
- dc.SetBackgroundMode(wx.SOLID)
-
- if isSelected:
- dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
- dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
- else:
- dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
- dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
- dc.DrawRectangleRect(rect)
-
- #dc.DrawRectangle((rect.x, rect.y), (rect.width, rect.height))
-
- # copy the image but only to the size of the grid cell
- width, height = bmp.GetWidth(), bmp.GetHeight()
-
- if width > rect.width-2:
- width = rect.width-2
-
- if height > rect.height-2:
- height = rect.height-2
-
- dc.Blit((rect.x+1, rect.y+1), (width, height),
- image,
- (0, 0), wx.COPY, True)
-
-
-class MegaFontRenderer(Grid.PyGridCellRenderer):
- def __init__(self, table, color="blue", font="ARIAL", fontsize=8):
- """Render data in the specified color and font and fontsize"""
- Grid.PyGridCellRenderer.__init__(self)
- self.table = table
- self.color = color
- self.font = wx.Font(fontsize, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, font)
- self.selectedBrush = wx.Brush("blue", wx.SOLID)
- self.normalBrush = wx.Brush(wx.WHITE, wx.SOLID)
- self.colSize = None
- self.rowSize = 50
-
- def Draw(self, grid, attr, dc, rect, row, col, isSelected):
- # Here we draw text in a grid cell using various fonts
- # and colors. We have to set the clipping region on
- # the grid's DC, otherwise the text will spill over
- # to the next cell
- dc.SetClippingRect(rect)
-
- # clear the background
- dc.SetBackgroundMode(wx.SOLID)
-
- if isSelected:
- dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
- dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
- else:
- dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
- dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
- dc.DrawRectangleRect(rect)
-
- #dc.DrawRectangle((rect.x, rect.y), (rect.width, rect.height))
-
- text = self.table.GetValue(row, col)
- dc.SetBackgroundMode(wx.SOLID)
-
- # change the text background based on whether the grid is selected
- # or not
- if isSelected:
- dc.SetBrush(self.selectedBrush)
- dc.SetTextBackground("blue")
- else:
- dc.SetBrush(self.normalBrush)
- dc.SetTextBackground("white")
-
- dc.SetTextForeground(self.color)
- dc.SetFont(self.font)
- dc.DrawText(text, (rect.x+1, rect.y+1))
-
- # Okay, now for the advanced class :)
- # Let's add three dots "..."
- # to indicate that that there is more text to be read
- # when the text is larger than the grid cell
-
- width, height = dc.GetTextExtent(text)
-
- if width > rect.width-2:
- width, height = dc.GetTextExtent("...")
- x = rect.x+1 + rect.width-2 - width
- dc.DrawRectangle((x, rect.y+1), (width+1, height))
- dc.DrawText("...", (x, rect.y+1))
-
- dc.DestroyClippingRegion()
-
-
-# --------------------------------------------------------------------
-# Sample Grid using a specialized table and renderers that can
-# be plugged in based on column names
-
-class MegaGrid(Grid.Grid):
- def __init__(self, parent, data, colnames, plugins=None):
- """parent, data, colnames, plugins=None
- Initialize a grid using the data defined in data and colnames
- (see MegaTable for a description of the data format)
- plugins is a dictionary of columnName -> column renderers.
- """
-
- # The base class must be initialized *first*
- Grid.Grid.__init__(self, parent, -1)
- self._table = MegaTable(data, colnames, plugins)
- self.SetTable(self._table)
- self._plugins = plugins
-
- self.Bind(Grid.EVT_GRID_LABEL_RIGHT_CLICK, self.OnLabelRightClicked)
-
- def Reset(self):
- """reset the view based on the data in the table. Call
- this when rows are added or destroyed"""
- self._table.ResetView(self)
-
- def OnLabelRightClicked(self, evt):
- # Did we click on a row or a column?
- row, col = evt.GetRow(), evt.GetCol()
- if row == -1: self.colPopup(col, evt)
- elif col == -1: self.rowPopup(row, evt)
-
- def rowPopup(self, row, evt):
- """(row, evt) -> display a popup menu when a row label is right clicked"""
- appendID = wx.NewId()
- deleteID = wx.NewId()
- x = self.GetRowSize(row)/2
-
- if not self.GetSelectedRows():
- self.SelectRow(row)
-
- menu = wx.Menu()
- xo, yo = evt.GetPosition()
- menu.Append(appendID, "Append Row")
- menu.Append(deleteID, "Delete Row(s)")
-
- def append(event, self=self, row=row):
- self._table.AppendRow(row)
- self.Reset()
-
- def delete(event, self=self, row=row):
- rows = self.GetSelectedRows()
- self._table.DeleteRows(rows)
- self.Reset()
-
- self.Bind(wx.EVT_MENU, append, id=appendID)
- self.Bind(wx.EVT_MENU, delete, id=deleteID)
- self.PopupMenu(menu, (x, yo))
- menu.Destroy()
- return
-
-
- def colPopup(self, col, evt):
- """(col, evt) -> display a popup menu when a column label is
- right clicked"""
- x = self.GetColSize(col)/2
- menu = wx.Menu()
- id1 = wx.NewId()
- sortID = wx.NewId()
-
- xo, yo = evt.GetPosition()
- self.SelectCol(col)
- cols = self.GetSelectedCols()
- self.Refresh()
- menu.Append(id1, "Delete Col(s)")
- menu.Append(sortID, "Sort Column")
-
- def delete(event, self=self, col=col):
- cols = self.GetSelectedCols()
- self._table.DeleteCols(cols)
- self.Reset()
-
- def sort(event, self=self, col=col):
- self._table.SortColumn(col)
- self.Reset()
-
- self.Bind(wx.EVT_MENU, delete, id=id1)
-
- if len(cols) == 1:
- self.Bind(wx.EVT_MENU, sort, id=sortID)
-
- self.PopupMenu(menu, (xo, 0))
- menu.Destroy()
- return
-
-# -----------------------------------------------------------------
-# Test data
-# data is in the form
-# [rowname, dictionary]
-# where dictionary.get(colname, None) -> returns the value for the cell
-#
-# the colname must also be supplied
-import random
-colnames = ["Row", "This", "Is", "A", "Test"]
-
-data = []
-
-for row in range(1000):
- d = {}
- for name in ["This", "Test", "Is"]:
- d[name] = random.random()
-
- d["Row"] = len(data)
- # XXX
- # the "A" column can only be between one and 4
- d["A"] = random.choice(range(4))
- data.append((str(row), d))
-
-class MegaFontRendererFactory:
- def __init__(self, color, font, fontsize):
- """
- (color, font, fontsize) -> set of a factory to generate
- renderers when called.
- func = MegaFontRenderFactory(color, font, fontsize)
- renderer = func(table)
- """
- self.color = color
- self.font = font
- self.fontsize = fontsize
-
- def __call__(self, table):
- return MegaFontRenderer(table, self.color, self.font, self.fontsize)
-
-
-#---------------------------------------------------------------------------
-
-class TestFrame(wx.Frame):
- def __init__(self, parent, plugins={"This":MegaFontRendererFactory("red", "ARIAL", 8),
- "A":MegaImageRenderer,
- "Test":MegaFontRendererFactory("orange", "TIMES", 24),}):
- wx.Frame.__init__(self, parent, -1,
- "Test Frame", size=(640,480))
-
- grid = MegaGrid(self, data, colnames, plugins)
- grid.Reset()
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestFrame(frame)
- frame.otherWin = win
- win.Show(True)
-
-
-
-overview = """Mega Grid Example
-
-This example attempts to show many examples and tricks of
-using a virtual grid object. Hopefully the source isn't too jumbled.
-
-Features:
-<ol>
- <li>Uses a virtual grid
- <li>Columns and rows have popup menus (right click on labels)
- <li>Columns and rows can be deleted (i.e. table can be
- resized)
- <li>Dynamic renderers. Renderers are plugins based on
- column header name. Shows a simple Font Renderer and
- an Image Renderer.
-</ol>
-
-Look for 'XXX' in the code to indicate some workarounds for non-obvious
-behavior and various hacks.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 12/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o got the wxpTag stuff working right.
-#
-# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxScrolledMessageDialog -> ScrolledMessageDialog
-#
-
-import os
-import sys
-
-import wx
-import wx.html as html
-import wx.lib.wxpTag
-
-from Main import opj
-
-#----------------------------------------------------------------------
-
-# This shows how to catch the OnLinkClicked non-event. (It's a virtual
-# method in the C++ code...)
-class MyHtmlWindow(html.HtmlWindow):
- def __init__(self, parent, id, log):
- html.HtmlWindow.__init__(self, parent, id, style=wx.NO_FULL_REPAINT_ON_RESIZE)
- self.log = log
- self.Bind(wx.EVT_SCROLLWIN, self.OnScroll )
-
- def OnScroll( self, event ):
- #print 'event.GetOrientation()',event.GetOrientation()
- #print 'event.GetPosition()',event.GetPosition()
- event.Skip()
-
- def OnLinkClicked(self, linkinfo):
- self.log.WriteText('OnLinkClicked: %s\n' % linkinfo.GetHref())
-
- # Virtuals in the base class have been renamed with base_ on the front.
- self.base_OnLinkClicked(linkinfo)
-
-
- def OnSetTitle(self, title):
- self.log.WriteText('OnSetTitle: %s\n' % title)
- self.base_OnSetTitle(title)
-
- def OnCellMouseHover(self, cell, x, y):
- self.log.WriteText('OnCellMouseHover: %s, (%d %d)\n' % (cell, x, y))
- self.base_OnCellMouseHover(cell, x, y)
-
- def OnCellClicked(self, cell, x, y, evt):
- self.log.WriteText('OnCellClicked: %s, (%d %d)\n' % (cell, x, y))
- self.base_OnCellClicked(cell, x, y, evt)
-
-
-# This filter doesn't really do anything but show how to use filters
-class MyHtmlFilter(html.HtmlFilter):
- def __init__(self, log):
- html.HtmlFilter.__init__(self)
- self.log = log
-
- # This method decides if this filter is able to read the file
- def CanRead(self, fsfile):
- self.log.write("CanRead: %s\n" % fsfile.GetMimeType())
- return False
-
- # If CanRead returns True then this method is called to actually
- # read the file and return the contents.
- def ReadFile(self, fsfile):
- return ""
-
-
-class TestHtmlPanel(wx.Panel):
- def __init__(self, parent, frame, log):
- wx.Panel.__init__(self, parent, -1, style=wx.NO_FULL_REPAINT_ON_RESIZE)
- self.log = log
- self.frame = frame
- self.cwd = os.path.split(sys.argv[0])[0]
-
- if not self.cwd:
- self.cwd = os.getcwd()
- if frame:
- self.titleBase = frame.GetTitle()
-
- html.HtmlWindow_AddFilter(MyHtmlFilter(log))
-
- self.html = MyHtmlWindow(self, -1, log)
- self.html.SetRelatedFrame(frame, self.titleBase + " -- %s")
- self.html.SetRelatedStatusBar(0)
-
- self.printer = html.HtmlEasyPrinting()
-
- self.box = wx.BoxSizer(wx.VERTICAL)
- self.box.Add(self.html, 1, wx.GROW)
-
- subbox = wx.BoxSizer(wx.HORIZONTAL)
-
- btn = wx.Button(self, -1, "Load File")
- self.Bind(wx.EVT_BUTTON, self.OnLoadFile, btn)
- subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
-
- btn = wx.Button(self, -1, "Load URL")
- self.Bind(wx.EVT_BUTTON, self.OnLoadURL, btn)
- subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
-
- btn = wx.Button(self, -1, "With Widgets")
- self.Bind(wx.EVT_BUTTON, self.OnWithWidgets, btn)
- subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
-
- btn = wx.Button(self, -1, "Back")
- self.Bind(wx.EVT_BUTTON, self.OnBack, btn)
- subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
-
- btn = wx.Button(self, -1, "Forward")
- self.Bind(wx.EVT_BUTTON, self.OnForward, btn)
- subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
-
- btn = wx.Button(self, -1, "Print")
- self.Bind(wx.EVT_BUTTON, self.OnPrint, btn)
- subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
-
- btn = wx.Button(self, -1, "View Source")
- self.Bind(wx.EVT_BUTTON, self.OnViewSource, btn)
- subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
-
- self.box.Add(subbox, 0, wx.GROW)
- self.SetSizer(self.box)
- self.SetAutoLayout(True)
-
- # A button with this ID is created on the widget test page.
- self.Bind(wx.EVT_BUTTON, self.OnOk, id=wx.ID_OK)
-
- self.OnShowDefault(None)
-
-
- def ShutdownDemo(self):
- # put the frame title back
- if self.frame:
- self.frame.SetTitle(self.titleBase)
-
-
- def OnShowDefault(self, event):
- name = os.path.join(self.cwd, opj('data/test.htm'))
- self.html.LoadPage(name)
-
-
- def OnLoadFile(self, event):
- dlg = wx.FileDialog(self, wildcard = '*.htm*', style=wx.OPEN)
-
- if dlg.ShowModal():
- path = dlg.GetPath()
- self.html.LoadPage(path)
-
- dlg.Destroy()
-
-
- def OnLoadURL(self, event):
- dlg = wx.TextEntryDialog(self, "Enter a URL")
-
- if dlg.ShowModal():
- url = dlg.GetValue()
- self.html.LoadPage(url)
-
- dlg.Destroy()
-
-
- def OnWithWidgets(self, event):
- os.chdir(self.cwd)
- name = os.path.join(self.cwd, opj('data/widgetTest.htm'))
- self.html.LoadPage(name)
-
-
- def OnOk(self, event):
- self.log.WriteText("It works!\n")
-
- def OnBack(self, event):
- if not self.html.HistoryBack():
- wx.MessageBox("No more items in history!")
-
-
- def OnForward(self, event):
- if not self.html.HistoryForward():
- wx.MessageBox("No more items in history!")
-
-
- def OnViewSource(self, event):
- import wx.lib.dialogs
-
- source = self.html.GetParser().GetSource()
-
- dlg = wx.lib.dialogs.ScrolledMessageDialog(self, source, 'HTML Source')
- dlg.ShowModal()
- dlg.Destroy()
-
-
- def OnPrint(self, event):
- self.printer.GetPrintData().SetPaperId(wx.PAPER_LETTER)
- self.printer.PrintFile(self.html.GetOpenedPage())
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestHtmlPanel(nb, frame, log)
- print wx.Window_FindFocus()
- return win
-
-
-#----------------------------------------------------------------------
-
-
-overview = """<html><body>
-<h2>wxHtmlWindow</h2>
-
-<p>wxHtmlWindow is capable of parsing and rendering most
-simple HTML tags.
-
-<p>It is not intended to be a high-end HTML browser. If you're
-looking for something like that see the IEHtmlWin class, which
-wraps the core MSIE HTML viewer.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
-
-
-
-
-
-
-
+++ /dev/null
-# 11/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/28/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o iewin.py is missing
-#
-
-import wx
-
-if wx.Platform == '__WXMSW__':
- import wx.iewin as iewin
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Window):
- def __init__(self, parent, log, frame=None):
- wx.Window.__init__(
- self, parent, -1,
- style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN|wx.NO_FULL_REPAINT_ON_RESIZE
- )
-
- self.log = log
- self.current = "http://wxPython.org/"
- self.frame = frame
-
- if frame:
- self.titleBase = frame.GetTitle()
-
- sizer = wx.BoxSizer(wx.VERTICAL)
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
-
- self.ie = iewin.IEHtmlWin(self, -1, style = wx.NO_FULL_REPAINT_ON_RESIZE)
-
-
- btn = wx.Button(self, wx.NewId(), "Open", style=wx.BU_EXACTFIT)
- wx.EVT_BUTTON(self, btn.GetId(), self.OnOpenButton)
- btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
-
- btn = wx.Button(self, wx.NewId(), "Home", style=wx.BU_EXACTFIT)
- wx.EVT_BUTTON(self, btn.GetId(), self.OnHomeButton)
- btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
-
- btn = wx.Button(self, wx.NewId(), "<--", style=wx.BU_EXACTFIT)
- wx.EVT_BUTTON(self, btn.GetId(), self.OnPrevPageButton)
- btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
-
- btn = wx.Button(self, wx.NewId(), "-->", style=wx.BU_EXACTFIT)
- wx.EVT_BUTTON(self, btn.GetId(), self.OnNextPageButton)
- btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
-
- btn = wx.Button(self, wx.NewId(), "Stop", style=wx.BU_EXACTFIT)
- wx.EVT_BUTTON(self, btn.GetId(), self.OnStopButton)
- btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
-
- btn = wx.Button(self, wx.NewId(), "Search", style=wx.BU_EXACTFIT)
- wx.EVT_BUTTON(self, btn.GetId(), self.OnSearchPageButton)
- btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
-
- btn = wx.Button(self, wx.NewId(), "Refresh", style=wx.BU_EXACTFIT)
- wx.EVT_BUTTON(self, btn.GetId(), self.OnRefreshPageButton)
- btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
-
- txt = wx.StaticText(self, -1, "Location:")
- btnSizer.Add(txt, 0, wx.CENTER|wx.ALL, 2)
-
- self.location = wx.ComboBox(
- self, wx.NewId(), "", style=wx.CB_DROPDOWN|wx.PROCESS_ENTER
- )
-
- wx.EVT_COMBOBOX(self, self.location.GetId(), self.OnLocationSelect)
- wx.EVT_KEY_UP(self.location, self.OnLocationKey)
- wx.EVT_CHAR(self.location, self.IgnoreReturn)
- btnSizer.Add(self.location, 1, wx.EXPAND|wx.ALL, 2)
-
- sizer.Add(btnSizer, 0, wx.EXPAND)
- sizer.Add(self.ie, 1, wx.EXPAND)
-
- self.ie.Navigate(self.current)
- self.location.Append(self.current)
-
- self.SetSizer(sizer)
- self.SetAutoLayout(True)
- wx.EVT_SIZE(self, self.OnSize)
-
- # Hook up the event handlers for the IE window
- iewin.EVT_MSHTML_BEFORENAVIGATE2(self, -1, self.OnBeforeNavigate2)
- iewin.EVT_MSHTML_NEWWINDOW2(self, -1, self.OnNewWindow2)
- iewin.EVT_MSHTML_DOCUMENTCOMPLETE(self, -1, self.OnDocumentComplete)
- #EVT_MSHTML_PROGRESSCHANGE(self, -1, self.OnProgressChange)
- iewin.EVT_MSHTML_STATUSTEXTCHANGE(self, -1, self.OnStatusTextChange)
- iewin.EVT_MSHTML_TITLECHANGE(self, -1, self.OnTitleChange)
-
-
- def ShutdownDemo(self):
- # put the frame title back
- if self.frame:
- self.frame.SetTitle(self.titleBase)
-
-
- def OnSize(self, evt):
- self.Layout()
-
-
- def OnLocationSelect(self, evt):
- url = self.location.GetStringSelection()
- self.log.write('OnLocationSelect: %s\n' % url)
- self.ie.Navigate(url)
-
- def OnLocationKey(self, evt):
- if evt.KeyCode() == wx.WXK_RETURN:
- URL = self.location.GetValue()
- self.location.Append(URL)
- self.ie.Navigate(URL)
- else:
- evt.Skip()
-
-
- def IgnoreReturn(self, evt):
- if evt.GetKeyCode() != wx.WXK_RETURN:
- evt.Skip()
-
- def OnOpenButton(self, event):
- dlg = wx.TextEntryDialog(self, "Open Location",
- "Enter a full URL or local path",
- self.current, wx.OK|wx.CANCEL)
- dlg.CentreOnParent()
-
- if dlg.ShowModal() == wx.ID_OK:
- self.current = dlg.GetValue()
- self.ie.Navigate(self.current)
-
- dlg.Destroy()
-
- def OnHomeButton(self, event):
- self.ie.GoHome() ## ET Phone Home!
-
- def OnPrevPageButton(self, event):
- self.ie.GoBack()
-
- def OnNextPageButton(self, event):
- self.ie.GoForward()
-
- def OnStopButton(self, evt):
- self.ie.Stop()
-
- def OnSearchPageButton(self, evt):
- self.ie.GoSearch()
-
- def OnRefreshPageButton(self, evt):
- self.ie.Refresh(iewin.IEHTML_REFRESH_COMPLETELY)
-
-
- def logEvt(self, name, event):
- self.log.write('%s: %s\n' %
- (name, (event.GetLong1(), event.GetLong2(), event.GetText1())))
-
- def OnBeforeNavigate2(self, evt):
- self.logEvt('OnBeforeNavigate2', evt)
-
- def OnNewWindow2(self, evt):
- self.logEvt('OnNewWindow2', evt)
- evt.Veto() # don't allow it
-
- def OnDocumentComplete(self, evt):
- self.logEvt('OnDocumentComplete', evt)
- self.current = evt.GetText1()
- self.location.SetValue(self.current)
-
- def OnTitleChange(self, evt):
- self.logEvt('OnTitleChange', evt)
- if self.frame:
- self.frame.SetTitle(self.titleBase + ' -- ' + evt.GetText1())
-
- def OnStatusTextChange(self, evt):
- self.logEvt('OnStatusTextChange', evt)
- if self.frame:
- self.frame.SetStatusText(evt.GetText1())
-
-
-#----------------------------------------------------------------------
-# for the demo framework...
-
-def runTest(frame, nb, log):
- if wx.Platform == '__WXMSW__':
- win = TestPanel(nb, log, frame)
- return win
- else:
- dlg = wx.MessageDialog(frame, 'This demo only works on MSW.',
- 'Sorry', wx.OK | wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-
-
-overview = """\
-<html><body>
-<h2>wxIEHtmlWin</h2>
-
-The wxIEHtmlWin class is the first example of using a contributed
-wxActiveX class in wxWindows C++. It is still experimental, but
-I think it is useful.
-
-<p> Using this class is simpler than ActiveXWrapper, doesn't rely on
-the win32all extensions, and is more "wx\'ish", meaning that it uses
-events and etc. as would be expected from any other wx window.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
-
-#----------------------------------------------------------------------
-
+++ /dev/null
-# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-from Main import opj
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- bmp = wx.Image(opj('bitmaps/image.bmp'), wx.BITMAP_TYPE_BMP).ConvertToBitmap()
- gif = wx.Image(opj('bitmaps/image.gif'), wx.BITMAP_TYPE_GIF).ConvertToBitmap()
- png = wx.Image(opj('bitmaps/image.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
- jpg = wx.Image(opj('bitmaps/image.jpg'), wx.BITMAP_TYPE_JPEG).ConvertToBitmap()
-
- panel = wx.Panel(nb, -1)
-
- pos = 10
- wx.StaticBitmap(panel, -1, bmp, (10, pos), (bmp.GetWidth(), bmp.GetHeight()))
-
- pos = pos + bmp.GetHeight() + 10
- wx.StaticBitmap(panel, -1, gif, (10, pos), (gif.GetWidth(), gif.GetHeight()))
-
- pos = pos + gif.GetHeight() + 10
- wx.StaticBitmap(panel, -1, png, (10, pos), (png.GetWidth(), png.GetHeight()))
-
- pos = pos + png.GetHeight() + 10
- wx.StaticBitmap(panel, -1, jpg, (10, pos), (jpg.GetWidth(), jpg.GetHeight()))
-
- return panel
-
-#----------------------------------------------------------------------
-
-
-
-overview = """\
-<html>
-<body>
-This class encapsulates a platform-independent image. An image can be created
-from data, or using <code>wxBitmap.ConvertToImage</code>. An image can be loaded from
-a file in a variety of formats, and is extensible to new formats via image
-format handlers. Functions are available to set and get image bits, so it can
-be used for basic image manipulation.
-
-<p>The following image handlers are available. wxBMPHandler is always installed
-by default. To use other image formats, install the appropriate handler or use
-<code>wx.InitAllImageHandlers()</code>.
-
-<p>
-<table>
-<tr><td width=25%>wxBMPHandler</td> <td>For loading and saving, always installed.</td></tr>
-<tr><td>wxPNGHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxJPEGHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxGIFHandler</td> <td>Only for loading, due to legal issues.</td> </tr>
-<tr><td>wxPCXHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxPNMHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxTIFFHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxIFFHandler</td> <td>For loading only.</td> </tr>
-<tr><td>wxXPMHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxICOHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxCURHandler</td> <td>For loading and saving.</td> </tr>
-<tr><td>wxANIHandler</td> <td>For loading only.</td> </tr>
-</table>
-
-<p>When saving in PCX format, wxPCXHandler will count the number of different
-colours in the image; if there are 256 or less colours, it will save as 8 bit,
-else it will save as 24 bit.
-
-<p>Loading PNMs only works for ASCII or raw RGB images. When saving in PNM format,
-wxPNMHandler will always save as raw RGB.
-
-</body>
-</html>"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import cStringIO
-
-import wx
-
-from Main import opj
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
-
- data = open(opj('bitmaps/image.png'), "rb").read()
- stream = cStringIO.StringIO(data)
-
- bmp = wx.BitmapFromImage( wx.ImageFromStream( stream ))
-
- wx.StaticText(
- self, -1, "This image was loaded from a Python file-like object:",
- (15, 15)
- )
-
- wx.StaticBitmap(self, -1, bmp, (15, 45))#, (bmp.GetWidth(), bmp.GetHeight()))
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-At long last there is finally a way to load any supported image type
-directly from any Python file-like object, such as a memory buffer
-using StringIO. """
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o intctrl needs the renamer applied.
-# o intctrl needs new event binders.
-#
-# 12/08/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o All issues corrected
-#
-# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxIntCtrl -> IntCtrl
-#
-
-import wx
-import wx.lib.intctrl
-
-#----------------------------------------------------------------------
-
-class TestPanel( wx.Panel ):
- def __init__( self, parent, log ):
-
- wx.Panel.__init__( self, parent, -1 )
- self.log = log
- panel = wx.Panel( self, -1 )
-
- self.set_min = wx.CheckBox( panel, -1, "Set minimum value:" )
- self.min = wx.lib.intctrl.IntCtrl( panel, size=( 50, -1 ) )
- self.min.Enable( False )
-
- self.set_max = wx.CheckBox( panel, -1, "Set maximum value:" )
- self.max = wx.lib.intctrl.IntCtrl( panel, size=( 50, -1 ) )
- self.max.Enable( False )
-
- self.limit_target = wx.CheckBox( panel, -1, "Limit control" )
- self.allow_none = wx.CheckBox( panel, -1, "Allow empty control" )
- self.allow_long = wx.CheckBox( panel, -1, "Allow long integers" )
-
- label = wx.StaticText( panel, -1, "Resulting integer control:" )
- self.target_ctl = wx.lib.intctrl.IntCtrl( panel )
-
- grid = wx.FlexGridSizer( 0, 2, 0, 0 )
- grid.Add( self.set_min, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid.Add( self.min, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid.Add(self.set_max, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid.Add( self.max, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid.Add( self.limit_target, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid.Add( self.allow_none, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid.Add( self.allow_long, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid.Add( label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid.Add( self.target_ctl, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- outer_box = wx.BoxSizer( wx.VERTICAL )
- outer_box.AddSizer( grid, 0, wx.ALIGN_CENTRE|wx.ALL, 20 )
-
- panel.SetAutoLayout( True )
- panel.SetSizer( outer_box )
- outer_box.Fit( panel )
- panel.Move( (50,50) )
- self.panel = panel
-
- self.Bind(wx.EVT_CHECKBOX, self.OnSetMin, self.set_min)
- self.Bind(wx.EVT_CHECKBOX, self.OnSetMax, self.set_max)
- self.Bind(wx.EVT_CHECKBOX, self.SetTargetMinMax, self.limit_target)
- self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowNone, self.allow_none)
- self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowLong, self.allow_long)
-
- self.Bind(wx.lib.intctrl.EVT_INT, self.SetTargetMinMax, self.min)
- self.Bind(wx.lib.intctrl.EVT_INT, self.SetTargetMinMax, self.max)
- self.Bind(wx.lib.intctrl.EVT_INT, self.OnTargetChange, self.target_ctl)
-
-
- def OnSetMin( self, event ):
- self.min.Enable( self.set_min.GetValue() )
- self.SetTargetMinMax()
-
- def OnSetMax( self, event ):
- self.max.Enable( self.set_max.GetValue() )
- self.SetTargetMinMax()
-
-
- def SetTargetMinMax( self, event=None ):
- min = max = None
- self.target_ctl.SetLimited( self.limit_target.GetValue() )
-
- if self.set_min.GetValue():
- min = self.min.GetValue()
-
- if self.set_max.GetValue():
- max = self.max.GetValue()
-
- cur_min, cur_max = self.target_ctl.GetBounds()
-
- if min != cur_min and not self.target_ctl.SetMin( min ):
- self.log.write( "min (%d) > current max (%d) -- bound not set\n" % ( min, self.target_ctl.GetMax() ) )
- self.min.SetForegroundColour( wx.RED )
- else:
- self.min.SetForegroundColour( wx.BLACK )
-
- self.min.Refresh()
-
- if max != cur_max and not self.target_ctl.SetMax( max ):
- self.log.write( "max (%d) < current min (%d) -- bound not set\n" % ( max, self.target_ctl.GetMin() ) )
- self.max.SetForegroundColour( wx.RED )
- else:
- self.max.SetForegroundColour( wx.BLACK )
-
- self.max.Refresh()
-
- if min != cur_min or max != cur_max:
- new_min, new_max = self.target_ctl.GetBounds()
- self.log.write( "current min, max: (%s, %s)\n" % ( str(new_min), str(new_max) ) )
-
-
- def OnSetAllowNone( self, event ):
- self.target_ctl.SetNoneAllowed( self.allow_none.GetValue() )
-
-
- def OnSetAllowLong( self, event ):
- self.target_ctl.SetLongAllowed( self.allow_long.GetValue() )
-
-
- def OnTargetChange( self, event ):
- ctl = event.GetEventObject()
- value = ctl.GetValue()
- ib_str = [ " (out of bounds)", "" ]
- self.log.write( "integer value = %s%s\n" % ( str(value), ib_str[ ctl.IsInBounds(value) ] ) )
-
-
-#----------------------------------------------------------------------
-
-def runTest( frame, nb, log ):
- win = TestPanel( nb, log )
- return win
-
-#----------------------------------------------------------------------
-
-overview = """<html><body>
-<P>
-<B>IntCtrl</B> provides a control that takes and returns integers as
-value, and provides bounds support and optional value limiting.
-<P>
-<P>
-Here's the API for IntCtrl:
-<DL><PRE>
- <B>IntCtrl</B>(
- parent, id = -1,
- <B>value</B> = 0,
- <B>min</B> = None,
- <B>max</B> = None,
- <B>limited</B> = False,
- <B>allow_none</B> = False,
- <B>allow_long</B> = False,
- <B>default_color</B> = wxBLACK,
- <B>oob_color</B> = wxRED,
- pos = wxDefaultPosition,
- size = wxDefaultSize,
- style = 0,
- name = "integer")
-</PRE>
-<UL>
- <DT><B>value</B>
- <DD>If no initial value is set, the default will be zero, or
- the minimum value, if specified. If an illegal string is specified,
- a ValueError will result. (You can always later set the initial
- value with SetValue() after instantiation of the control.)
- <BR>
- <DL><B>min</B>
- <DD>The minimum value that the control should allow. This can be
- adjusted with SetMin(). If the control is not limited, any value
- below this bound will be colored with the current out-of-bounds color.
- <BR>
- <DT><B>max</B>
- <DD>The maximum value that the control should allow. This can be
- adjusted with SetMax(). If the control is not limited, any value
- above this bound will be colored with the current out-of-bounds color.
- <BR>
- <DT><B>limited</B>
- <DD>Boolean indicating whether the control prevents values from
- exceeding the currently set minimum and maximum values (bounds).
- If <I>False</I> and bounds are set, out-of-bounds values will
- be colored with the current out-of-bounds color.
- <BR>
- <DT><B>allow_none</B>
- <DD>Boolean indicating whether or not the control is allowed to be
- empty, representing a value of <I>None</I> for the control.
- <BR>
- <DT><B>allow_long</B>
- <DD>Boolean indicating whether or not the control is allowed to hold
- and return a value of type long as well as int. If False, the
- control will be implicitly limited to have a value such that
- -sys.maxint-1 <= n <= sys.maxint.
- <BR>
- <DT><B>default_color</B>
- <DD>Color value used for in-bounds values of the control.
- <BR>
- <DT><B>oob_color</B>
- <DD>Color value used for out-of-bounds values of the control
- when the bounds are set but the control is not limited.
-</UL>
-<BR>
-<BR>
-<DT><B>EVT_INT(win, id, func)</B>
-<DD>Respond to a wxEVT_COMMAND_INT_UPDATED event, generated when the
-value changes. Notice that this event will always be sent when the
-control's contents changes - whether this is due to user input or
-comes from the program itself (for example, if SetValue() is called.)
-<BR>
-<BR>
-<DT><B>SetValue(int)</B>
-<DD>Sets the value of the control to the integer value specified.
-The resulting actual value of the control may be altered to
-conform with the bounds set on the control if limited,
-or colored if not limited but the value is out-of-bounds.
-A ValueError exception will be raised if an invalid value
-is specified.
-<BR>
-<DT><B>GetValue()</B>
-<DD>Retrieves the integer value from the control. The value
-retrieved will be sized as an int if possible or a long,
-if necessary.
-<BR>
-<BR>
-<DT><B>SetMin(min=None)</B>
-<DD>Sets the expected minimum value, or lower bound, of the control.
-(The lower bound will only be enforced if the control is
-configured to limit its values to the set bounds.)
-If a value of <I>None</I> is provided, then the control will have
-no explicit lower bound. If the value specified is greater than
-the current lower bound, then the function returns 0 and the
-lower bound will not change from its current setting. On success,
-the function returns 1.
-<DT><DD>If successful and the current value is
-lower than the new lower bound, if the control is limited, the
-value will be automatically adjusted to the new minimum value;
-if not limited, the value in the control will be colored with
-the current out-of-bounds color.
-<BR>
-<DT><B>GetMin()</B>
-<DD>Gets the current lower bound value for the control.
-It will return None if no lower bound is currently specified.
-<BR>
-<BR>
-<DT><B>SetMax(max=None)</B>
-<DD>Sets the expected maximum value, or upper bound, of the control.
-(The upper bound will only be enforced if the control is
-configured to limit its values to the set bounds.)
-If a value of <I>None</I> is provided, then the control will
-have no explicit upper bound. If the value specified is less
-than the current lower bound, then the function returns 0 and
-the maximum will not change from its current setting. On success,
-the function returns 1.
-<DT><DD>If successful and the current value
-is greater than the new upper bound, if the control is limited
-the value will be automatically adjusted to the new maximum value;
-if not limited, the value in the control will be colored with the
-current out-of-bounds color.
-<BR>
-<DT><B>GetMax()</B>
-<DD>Gets the current upper bound value for the control.
-It will return None if no upper bound is currently specified.
-<BR>
-<BR>
-<DT><B>SetBounds(min=None,max=None)</B>
-<DD>This function is a convenience function for setting the min and max
-values at the same time. The function only applies the maximum bound
-if setting the minimum bound is successful, and returns True
-only if both operations succeed. <B><I>Note:</I></B> leaving out an argument
-will remove the corresponding bound.
-<DT><B>GetBounds()</B>
-<DD>This function returns a two-tuple (min,max), indicating the
-current bounds of the control. Each value can be None if
-that bound is not set.
-<BR>
-<BR>
-<DT><B>IsInBounds(value=None)</B>
-<DD>Returns <I>True</I> if no value is specified and the current value
-of the control falls within the current bounds. This function can also
-be called with a value to see if that value would fall within the current
-bounds of the given control.
-<BR>
-<BR>
-<DT><B>SetLimited(bool)</B>
-<DD>If called with a value of True, this function will cause the control
-to limit the value to fall within the bounds currently specified.
-If the control's value currently exceeds the bounds, it will then
-be limited accordingly.
-If called with a value of 0, this function will disable value
-limiting, but coloring of out-of-bounds values will still take
-place if bounds have been set for the control.
-<DT><B>IsLimited()</B>
-<DD>Returns <I>True</I> if the control is currently limiting the
-value to fall within the current bounds.
-<BR>
-<BR>
-<DT><B>SetNoneAllowed(bool)</B>
-<DD>If called with a value of True, this function will cause the control
-to allow the value to be empty, representing a value of None.
-If called with a value of false, this function will prevent the value
-from being None. If the value of the control is currently None,
-ie. the control is empty, then the value will be changed to that
-of the lower bound of the control, or 0 if no lower bound is set.
-<DT><B>IsNoneAllowed()</B>
-<DD>Returns <I>True</I> if the control currently allows its
-value to be None.
-<BR>
-<BR>
-<DT><B>SetLongAllowed(bool)</B>
-<DD>If called with a value of True, this function will cause the
-control to allow the value to be a long. If called with a value
-of False, and the value of the control is currently a long value,
-the value of the control will be adjusted to fall within the
-size of an integer type, at either the sys.maxint or -sys.maxint-1,
-for positive and negative values, respectively.
-<DT><B>IsLongAllowed()</B>
-<DD>Returns <I>True</I> if the control currently allows its
-value to be of type long.
-<BR>
-<BR>
-<DT><B>SetColors(default_color=wxBLACK, oob_color=wxRED)</B>
-<DD>Tells the control what colors to use for normal and out-of-bounds
-values. If the value currently exceeds the bounds, it will be
-recolored accordingly.
-<DT><B>GetColors()</B>
-<DD>Returns a tuple of <I>(default_color, oob_color)</I> indicating
-the current color settings for the control.
-<BR>
-<BR>
-<DT><B>Cut()</B>
-<DD>Will allow cuts to the clipboard of the text portion of the value,
-leaving the value of zero if the entire contents are "cut."
-<DT><B>Paste()</B>
-<DD>Will paste the contents of the clipboard to the selected portion
-of the value; if the resulting string does not represent a legal
-value, a ValueError will result. If the result is out-of bounds,
-it will either be adjusted or colored as appropriate.
-</DL>
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-
-#----------------------------------------------------------------------------
-
-from wxPython.wx import *
-from joystick_wdr import *
-
-
-class JoystickTestPanel(wxPanel):
- def __init__(self, parent, id,
- pos = wxDefaultPosition, size = wxDefaultSize,
- style = wxTAB_TRAVERSAL ):
- wxPanel.__init__(self, parent, id, pos, size, style)
-
- MakeJoystickTestPanel( self, True )
-
- try:
- self.stick = wxJoystick()
- self.stick.SetCapture(self)
- EVT_JOYSTICK_EVENTS(self, self.OnJoystick)
- self.UpdateFields()
- except NotImplementedError, v:
- wxMessageBox(str(v), "Exception Message")
-
-
- def UpdateFields(self):
- s = self.stick
- self.GetXPositionCtrl().SetValue(str(s.GetPosition().x))
- self.GetYPositionCtrl().SetValue(str(s.GetPosition().y))
- self.GetZPositionCtrl().SetValue(str(s.GetZPosition()))
- self.GetPovCtsPosCtrl().SetValue(str(s.GetPOVPosition()))
- self.GetRudderPosCtrl().SetValue(str(s.GetRudderPosition()))
- self.GetHasRudderCtrl().SetValue(str(s.HasRudder()))
- self.GetHasZCtrl().SetValue(str(s.HasZ()))
- self.GetHasPovCtrl().SetValue(str(s.HasPOV()))
- self.GetHasPov4dirCtrl().SetValue(str(s.HasPOV4Dir()))
- self.GetMfgIdCtrl().SetValue(str(s.GetManufacturerId()))
- self.GetProdNameCtrl().SetValue(str(s.GetProductName()))
- self.GetZMinCtrl().SetValue(str(s.GetZMin()))
- self.GetXMaxCtrl().SetValue(str(s.GetXMax()))
- self.GetNumButtonsCtrl().SetValue(str(s.GetNumberButtons()))
- self.GetNumAxesCtrl().SetValue(str(s.GetNumberAxes()))
- self.GetPollingMinCtrl().SetValue(str(s.GetPollingMin()))
- self.GetPollingMaxCtrl().SetValue(str(s.GetPollingMax()))
- self.GetUMinCtrl().SetValue(str(s.GetUMin()))
- self.GetUMaxCtrl().SetValue(str(s.GetUMax()))
- self.GetButtonStateCtrl().SetValue(str(s.GetButtonState()))
- self.GetPovPositionCtrl().SetValue(str(s.GetPOVPosition()))
- self.GetUPositionCtrl().SetValue(str(s.GetUPosition()))
- self.GetVPositionCtrl().SetValue(str(s.GetVPosition()))
- self.GetHasUCtrl().SetValue(str(s.HasU()))
- self.GetHasVCtrl().SetValue(str(s.HasV()))
- self.GetHasPovCtsCtrl().SetValue(str(s.HasPOVCTS()))
- self.GetNumSticksCtrl().SetValue(str(s.GetNumberJoysticks()))
- self.GetXMinCtrl().SetValue(str(s.GetXMin()))
- self.GetYMinCtrl().SetValue(str(s.GetYMin()))
- self.GetYMaxCtrl().SetValue(str(s.GetYMax()))
- self.GetZMaxCtrl().SetValue(str(s.GetZMax()))
- self.GetMaxButtonsCtrl().SetValue(str(s.GetMaxButtons()))
- self.GetMaxAxesCtrl().SetValue(str(s.GetMaxAxes()))
- self.GetRudderMinCtrl().SetValue(str(s.GetRudderMin()))
- self.GetRudderMaxCtrl().SetValue(str(s.GetRudderMax()))
- self.GetVMinCtrl().SetValue(str(s.GetVMin()))
- self.GetVMaxCtrl().SetValue(str(s.GetVMax()))
-
-
- def OnJoystick(self, evt):
- self.UpdateFields()
-
-
- # WDR: methods for JoystickTestPanel
-
- def GetYPositionCtrl(self):
- return self.FindWindowById(ID_Y_Position_Ctrl)
-
- def GetXPositionCtrl(self):
- return self.FindWindowById(ID_X_Position_Ctrl)
-
-
- def GetVMaxCtrl(self):
- return self.FindWindowById(ID_V_Max_Ctrl)
-
- def GetVMinCtrl(self):
- return self.FindWindowById(ID_V_Min_Ctrl)
-
- def GetRudderMaxCtrl(self):
- return self.FindWindowById(ID_Rudder_Max_Ctrl)
-
- def GetRudderMinCtrl(self):
- return self.FindWindowById(ID_Rudder_Min_Ctrl)
-
- def GetMaxAxesCtrl(self):
- return self.FindWindowById(ID_Max_Axes_Ctrl)
-
- def GetMaxButtonsCtrl(self):
- return self.FindWindowById(ID_Max_Buttons_Ctrl)
-
- def GetZMaxCtrl(self):
- return self.FindWindowById(ID_Z_Max_Ctrl)
-
- def GetYMaxCtrl(self):
- return self.FindWindowById(ID_Y_Max_Ctrl)
-
- def GetYMinCtrl(self):
- return self.FindWindowById(ID_Y_Min_Ctrl)
-
- def GetXMinCtrl(self):
- return self.FindWindowById(ID_X_Min_Ctrl)
-
- def GetNumSticksCtrl(self):
- return self.FindWindowById(ID_Num_Sticks_Ctrl)
-
- def GetHasPovCtsCtrl(self):
- return self.FindWindowById(ID_Has_POV_CTS_Ctrl)
-
- def GetHasVCtrl(self):
- return self.FindWindowById(ID_Has_V_Ctrl)
-
- def GetHasUCtrl(self):
- return self.FindWindowById(ID_Has_U_Ctrl)
-
- def GetVPositionCtrl(self):
- return self.FindWindowById(ID_V_Position_Ctrl)
-
- def GetUPositionCtrl(self):
- return self.FindWindowById(ID_U_Position_Ctrl)
-
- def GetPovPositionCtrl(self):
- return self.FindWindowById(ID_POV_Position_Ctrl)
-
- def GetButtonStateCtrl(self):
- return self.FindWindowById(ID_Button_State_Ctrl)
-
- def GetUMaxCtrl(self):
- return self.FindWindowById(ID_U_Max_Ctrl)
-
- def GetUMinCtrl(self):
- return self.FindWindowById(ID_U_Min_Ctrl)
-
- def GetPollingMaxCtrl(self):
- return self.FindWindowById(ID_Polling_Max_Ctrl)
-
- def GetPollingMinCtrl(self):
- return self.FindWindowById(ID_Polling_Min_Ctrl)
-
- def GetNumAxesCtrl(self):
- return self.FindWindowById(ID_Num_Axes_Ctrl)
-
- def GetNumButtonsCtrl(self):
- return self.FindWindowById(ID_Num_Buttons_Ctrl)
-
- def GetXMaxCtrl(self):
- return self.FindWindowById(ID_X_Max_Ctrl)
-
- def GetZMinCtrl(self):
- return self.FindWindowById(ID_Z_Min_Ctrl)
-
- def GetProdNameCtrl(self):
- return self.FindWindowById(ID_Prod_Name_Ctrl)
-
- def GetMfgIdCtrl(self):
- return self.FindWindowById(ID_Mfg_ID_Ctrl)
-
- def GetHasPov4dirCtrl(self):
- return self.FindWindowById(ID_Has_POV_4DIR_Ctrl)
-
- def GetHasPovCtrl(self):
- return self.FindWindowById(ID_Has_POV_Ctrl)
-
- def GetHasZCtrl(self):
- return self.FindWindowById(ID_Has_Z_Ctrl)
-
- def GetHasRudderCtrl(self):
- return self.FindWindowById(ID_Has_Rudder_Ctrl)
-
- def GetRudderPosCtrl(self):
- return self.FindWindowById(ID_Rudder_Pos_Ctrl)
-
- def GetPovCtsPosCtrl(self):
- return self.FindWindowById(ID_POV_CTS_Pos_Ctrl)
-
- def GetZPositionCtrl(self):
- return self.FindWindowById(ID_Z_Position_Ctrl)
-
- # WDR: handler implementations for JoysticktestPanel
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = JoystickTestPanel(nb, -1)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o lib.mixins.listctrl needs wx renamer applied.
-#
-# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxListCtrlAutoWidthMixin -> ListCtrlAutoWidthMixin
-#
-
-import wx
-import wx.lib.mixins.listctrl as listmix
-
-#----------------------------------------------------------------------
-
-keyMap = {
- wx.WXK_BACK : "wx.WXK_BACK",
- wx.WXK_TAB : "wx.WXK_TAB",
- wx.WXK_RETURN : "wx.WXK_RETURN",
- wx.WXK_ESCAPE : "wx.WXK_ESCAPE",
- wx.WXK_SPACE : "wx.WXK_SPACE",
- wx.WXK_DELETE : "wx.WXK_DELETE",
- wx.WXK_START : "wx.WXK_START",
- wx.WXK_LBUTTON : "wx.WXK_LBUTTON",
- wx.WXK_RBUTTON : "wx.WXK_RBUTTON",
- wx.WXK_CANCEL : "wx.WXK_CANCEL",
- wx.WXK_MBUTTON : "wx.WXK_MBUTTON",
- wx.WXK_CLEAR : "wx.WXK_CLEAR",
- wx.WXK_SHIFT : "wx.WXK_SHIFT",
- wx.WXK_ALT : "wx.WXK_ALT",
- wx.WXK_CONTROL : "wx.WXK_CONTROL",
- wx.WXK_MENU : "wx.WXK_MENU",
- wx.WXK_PAUSE : "wx.WXK_PAUSE",
- wx.WXK_CAPITAL : "wx.WXK_CAPITAL",
- wx.WXK_PRIOR : "wx.WXK_PRIOR",
- wx.WXK_NEXT : "wx.WXK_NEXT",
- wx.WXK_END : "wx.WXK_END",
- wx.WXK_HOME : "wx.WXK_HOME",
- wx.WXK_LEFT : "wx.WXK_LEFT",
- wx.WXK_UP : "wx.WXK_UP",
- wx.WXK_RIGHT : "wx.WXK_RIGHT",
- wx.WXK_DOWN : "wx.WXK_DOWN",
- wx.WXK_SELECT : "wx.WXK_SELECT",
- wx.WXK_PRINT : "wx.WXK_PRINT",
- wx.WXK_EXECUTE : "wx.WXK_EXECUTE",
- wx.WXK_SNAPSHOT : "wx.WXK_SNAPSHOT",
- wx.WXK_INSERT : "wx.WXK_INSERT",
- wx.WXK_HELP : "wx.WXK_HELP",
- wx.WXK_NUMPAD0 : "wx.WXK_NUMPAD0",
- wx.WXK_NUMPAD1 : "wx.WXK_NUMPAD1",
- wx.WXK_NUMPAD2 : "wx.WXK_NUMPAD2",
- wx.WXK_NUMPAD3 : "wx.WXK_NUMPAD3",
- wx.WXK_NUMPAD4 : "wx.WXK_NUMPAD4",
- wx.WXK_NUMPAD5 : "wx.WXK_NUMPAD5",
- wx.WXK_NUMPAD6 : "wx.WXK_NUMPAD6",
- wx.WXK_NUMPAD7 : "wx.WXK_NUMPAD7",
- wx.WXK_NUMPAD8 : "wx.WXK_NUMPAD8",
- wx.WXK_NUMPAD9 : "wx.WXK_NUMPAD9",
- wx.WXK_MULTIPLY : "wx.WXK_MULTIPLY",
- wx.WXK_ADD : "wx.WXK_ADD",
- wx.WXK_SEPARATOR : "wx.WXK_SEPARATOR",
- wx.WXK_SUBTRACT : "wx.WXK_SUBTRACT",
- wx.WXK_DECIMAL : "wx.WXK_DECIMAL",
- wx.WXK_DIVIDE : "wx.WXK_DIVIDE",
- wx.WXK_F1 : "wx.WXK_F1",
- wx.WXK_F2 : "wx.WXK_F2",
- wx.WXK_F3 : "wx.WXK_F3",
- wx.WXK_F4 : "wx.WXK_F4",
- wx.WXK_F5 : "wx.WXK_F5",
- wx.WXK_F6 : "wx.WXK_F6",
- wx.WXK_F7 : "wx.WXK_F7",
- wx.WXK_F8 : "wx.WXK_F8",
- wx.WXK_F9 : "wx.WXK_F9",
- wx.WXK_F10 : "wx.WXK_F10",
- wx.WXK_F11 : "wx.WXK_F11",
- wx.WXK_F12 : "wx.WXK_F12",
- wx.WXK_F13 : "wx.WXK_F13",
- wx.WXK_F14 : "wx.WXK_F14",
- wx.WXK_F15 : "wx.WXK_F15",
- wx.WXK_F16 : "wx.WXK_F16",
- wx.WXK_F17 : "wx.WXK_F17",
- wx.WXK_F18 : "wx.WXK_F18",
- wx.WXK_F19 : "wx.WXK_F19",
- wx.WXK_F20 : "wx.WXK_F20",
- wx.WXK_F21 : "wx.WXK_F21",
- wx.WXK_F22 : "wx.WXK_F22",
- wx.WXK_F23 : "wx.WXK_F23",
- wx.WXK_F24 : "wx.WXK_F24",
- wx.WXK_NUMLOCK : "wx.WXK_NUMLOCK",
- wx.WXK_SCROLL : "wx.WXK_SCROLL",
- wx.WXK_PAGEUP : "wx.WXK_PAGEUP",
- wx.WXK_PAGEDOWN : "wx.WXK_PAGEDOWN",
- wx.WXK_NUMPAD_SPACE : "wx.WXK_NUMPAD_SPACE",
- wx.WXK_NUMPAD_TAB : "wx.WXK_NUMPAD_TAB",
- wx.WXK_NUMPAD_ENTER : "wx.WXK_NUMPAD_ENTER",
- wx.WXK_NUMPAD_F1 : "wx.WXK_NUMPAD_F1",
- wx.WXK_NUMPAD_F2 : "wx.WXK_NUMPAD_F2",
- wx.WXK_NUMPAD_F3 : "wx.WXK_NUMPAD_F3",
- wx.WXK_NUMPAD_F4 : "wx.WXK_NUMPAD_F4",
- wx.WXK_NUMPAD_HOME : "wx.WXK_NUMPAD_HOME",
- wx.WXK_NUMPAD_LEFT : "wx.WXK_NUMPAD_LEFT",
- wx.WXK_NUMPAD_UP : "wx.WXK_NUMPAD_UP",
- wx.WXK_NUMPAD_RIGHT : "wx.WXK_NUMPAD_RIGHT",
- wx.WXK_NUMPAD_DOWN : "wx.WXK_NUMPAD_DOWN",
- wx.WXK_NUMPAD_PRIOR : "wx.WXK_NUMPAD_PRIOR",
- wx.WXK_NUMPAD_PAGEUP : "wx.WXK_NUMPAD_PAGEUP",
- wx.WXK_NUMPAD_NEXT : "wx.WXK_NUMPAD_NEXT",
- wx.WXK_NUMPAD_PAGEDOWN : "wx.WXK_NUMPAD_PAGEDOWN",
- wx.WXK_NUMPAD_END : "wx.WXK_NUMPAD_END",
- wx.WXK_NUMPAD_BEGIN : "wx.WXK_NUMPAD_BEGIN",
- wx.WXK_NUMPAD_INSERT : "wx.WXK_NUMPAD_INSERT",
- wx.WXK_NUMPAD_DELETE : "wx.WXK_NUMPAD_DELETE",
- wx.WXK_NUMPAD_EQUAL : "wx.WXK_NUMPAD_EQUAL",
- wx.WXK_NUMPAD_MULTIPLY : "wx.WXK_NUMPAD_MULTIPLY",
- wx.WXK_NUMPAD_ADD : "wx.WXK_NUMPAD_ADD",
- wx.WXK_NUMPAD_SEPARATOR : "wx.WXK_NUMPAD_SEPARATOR",
- wx.WXK_NUMPAD_SUBTRACT : "wx.WXK_NUMPAD_SUBTRACT",
- wx.WXK_NUMPAD_DECIMAL : "wx.WXK_NUMPAD_DECIMAL",
- wx.WXK_NUMPAD_DIVIDE : "wx.WXK_NUMPAD_DIVIDE",
-}
-
-
-#----------------------------------------------------------------------
-
-class KeySink(wx.Window):
- def __init__(self, parent):
- wx.Window.__init__(self, parent, -1, style=wx.WANTS_CHARS
- #| wx.RAISED_BORDER
- #| wx.SUNKEN_BORDER
- )
-
- self.SetBackgroundColour(wx.BLUE)
- self.haveFocus = False
- self.callSkip = False
- self.logKeyDn = True
- self.logKeyUp = True
- self.logChar = True
-
- self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
- self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
- self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
-
- self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
- self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
- self.Bind(wx.EVT_CHAR, self.OnChar)
-
-
- def SetCallSkip(self, skip):
- self.callSkip = skip
-
- def SetLogKeyUp(self, val):
- self.logKeyUp = val
-
- def SetLogKeyDn(self, val):
- self.logKeyDn = val
-
- def SetLogChar(self, val):
- self.logChar = val
-
-
- def OnPaint(self, evt):
- dc = wx.PaintDC(self)
- rect = self.GetClientRect()
- dc.SetTextForeground(wx.WHITE)
- dc.DrawLabel("Click here and then press some keys",
- rect, wx.ALIGN_CENTER | wx.ALIGN_TOP)
- if self.haveFocus:
- dc.SetTextForeground(wx.GREEN)
- dc.DrawLabel("Have Focus", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM)
- else:
- dc.SetTextForeground(wx.RED)
- dc.DrawLabel("Need Focus!", rect, wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM)
-
-
- def OnSetFocus(self, evt):
- self.haveFocus = True
- self.Refresh()
-
- def OnKillFocus(self, evt):
- self.haveFocus = False
- self.Refresh()
-
- def OnMouse(self, evt):
- if evt.ButtonDown():
- self.SetFocus()
-
-
- def OnKeyDown(self, evt):
- if self.logKeyDn:
- self.GetParent().keylog.LogKeyEvent("KeyDown", evt)
- if self.callSkip:
- evt.Skip()
-
- def OnKeyUp(self, evt):
- if self.logKeyUp:
- self.GetParent().keylog.LogKeyEvent("KeyUp", evt)
- if self.callSkip:
- evt.Skip()
-
- def OnChar(self, evt):
- if self.logChar:
- self.GetParent().keylog.LogKeyEvent("Char", evt)
-
-
-#----------------------------------------------------------------------
-
-class KeyLog(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
-
- def __init__(self, parent):
- wx.ListCtrl.__init__(self, parent, -1,
- style = wx.LC_REPORT|wx.LC_VRULES|wx.LC_HRULES)
- listmix.ListCtrlAutoWidthMixin.__init__(self)
-
- self.InsertColumn(0, "Event Type")
- self.InsertColumn(1, "Key Name")
- self.InsertColumn(2, "Key Code")
- self.InsertColumn(3, "Modifiers")
- self.InsertColumn(4, "RawKeyCode")
- self.InsertColumn(5, "RawKeyFlags")
- self.InsertColumn(6, "")
-
- for x in range(6):
- self.SetColumnWidth(x, wx.LIST_AUTOSIZE_USEHEADER)
-
- self.SetColumnWidth(1, 125)
-
-
- def LogKeyEvent(self, evType, evt):
- keycode = evt.GetKeyCode()
- keyname = keyMap.get(keycode, None)
- if keyname is None:
- if keycode < 256:
- if keycode == 0:
- keyname = "NUL"
- elif keycode < 27:
- keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
- else:
- keyname = "\"%s\"" % chr(keycode)
- else:
- keyname = "unknown (%s)" % keycode
-
- modifiers = ""
- for mod, ch in [(evt.ControlDown(), 'C'),
- (evt.AltDown(), 'A'),
- (evt.ShiftDown(), 'S'),
- (evt.MetaDown(), 'M')]:
- if mod:
- modifiers += ch
- else:
- modifiers += '-'
-
- id = self.InsertStringItem(self.GetItemCount(), evType)
- self.SetStringItem(id, 1, keyname)
- self.SetStringItem(id, 2, str(keycode))
- self.SetStringItem(id, 3, modifiers)
- self.SetStringItem(id, 4, str(evt.GetRawKeyCode()))
- self.SetStringItem(id, 5, str(evt.GetRawKeyFlags()))
-
- #print ( id, evType, keyname, str(keycode), modifiers, str(evt.GetRawKeyCode()), str(evt.GetRawKeyFlags()))
-
- self.EnsureVisible(id)
-
-
- def ClearLog(self):
- self.DeleteAllItems()
-
-
-#----------------------------------------------------------------------
-
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1, style=0)
- self.keysink = KeySink(self)
- self.keysink.SetSize((100, 65))
- self.keylog = KeyLog(self)
-
- btn = wx.Button(self, -1, "Clear Log")
- self.Bind(wx.EVT_BUTTON, self.OnClearBtn, btn)
-
- cb1 = wx.CheckBox(self, -1, "Call evt.Skip for Key Up/Dn events")
- self.Bind(wx.EVT_CHECKBOX, self.OnSkipCB, cb1)
-
- cb2 = wx.CheckBox(self, -1, "EVT_KEY_UP")
- self.Bind(wx.EVT_CHECKBOX, self.OnKeyUpCB, cb2)
- cb2.SetValue(True)
-
- cb3 = wx.CheckBox(self, -1, "EVT_KEY_DOWN")
- self.Bind(wx.EVT_CHECKBOX, self.OnKeyDnCB, cb3)
- cb3.SetValue(True)
-
- cb4 = wx.CheckBox(self, -1, "EVT_CHAR")
- self.Bind(wx.EVT_CHECKBOX, self.OnCharCB, cb4)
- cb4.SetValue(True)
-
- buttons = wx.BoxSizer(wx.HORIZONTAL)
- buttons.Add(btn, 0, wx.ALL, 4)
- buttons.Add(cb1, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 6)
- buttons.Add(cb2, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
- buttons.Add(cb3, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
- buttons.Add(cb4, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 6)
-
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(self.keysink, 0, wx.GROW)
- sizer.Add(buttons)
- sizer.Add(self.keylog, 1, wx.GROW)
-
- self.SetSizer(sizer)
-
-
- def OnClearBtn(self, evt):
- self.keylog.ClearLog()
-
- def OnSkipCB(self, evt):
- self.keysink.SetCallSkip(evt.GetInt())
-
- def OnKeyUpCB(self, evt):
- self.keysink.SetLogKeyUp(evt.GetInt())
-
- def OnKeyDnCB(self, evt):
- self.keysink.SetLogKeyDn(evt.GetInt())
-
- def OnCharCB(self, evt):
- self.keysink.SetLogChar(evt.GetInt())
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>wxKeyEvents</center></h2>
-
-This demo simply catches all key events and prints info about them.
-It is meant to be used as a compatibility test for cross platform work.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import time
-
-import wx
-import wx.gizmos as gizmos
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- led = gizmos.LEDNumberCtrl(self, -1, (25,25), (280, 50))
- led.SetValue("01234")
-
- led = gizmos.LEDNumberCtrl(self, -1, (25,100), (280, 50))
- led.SetValue("56789")
- led.SetAlignment(gizmos.LED_ALIGN_RIGHT)
- led.SetDrawFaded(False)
-
- led = gizmos.LEDNumberCtrl(self, -1, (25,175), (280, 50),
- gizmos.LED_ALIGN_CENTER)# | gizmos.LED_DRAW_FADED)
- self.clock = led
- self.OnTimer(None)
-
- self.timer = wx.Timer(self)
- self.timer.Start(1000)
- self.Bind(wx.EVT_TIMER, self.OnTimer)
-
-
- def OnTimer(self, evt):
- t = time.localtime(time.time())
- st = time.strftime("%I-%M-%S", t)
- self.clock.SetValue(st)
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-overview = """\
-<html>
-<body>
-<font size=-1>The following was gleaned as best I could from the wxWindows
-source, which was a bit reluctant to reveal its secrets. My appologies if
-I missed anything - jmg</font>
-<p>
-<code><b>wxLEDNumberCtrl</b>( parent, id=-1, pos=wx.DefaultPosition,
-size=wx.DefaultSize, style=LED_ALIGN_LEFT | LED_DRAW_FADED)</code>
-
-<p>This is a control that simulates an LED clock display. It only accepts
-numeric input.
-
-<p><b>Styles</b>
-
-<p><dl>
-<dt><b>LED_ALIGN_LEFT</b>
-<dd>Align to the left.
-
-<dt><b>LED_ALIGN_RIGHT</b>
-<dd>Align to the right.
-
-<dt><b>LED_ALIGN_CENTER</b>
-<dd>Center on display.
-
-<dt><b>LED_DRAW_FADED</b>
-<dd>Not implemented.
-
-</dl>
-
-<p><b>Methods</b> (and best guesses at what they do)
-
-<p><dl>
-<dt><b>GetAlignment()</b>
-<dd>Returns the alignment attribute for the control.
-
-<dt><b>GetDrawFaded()</b>
-<dd>Returns the DrawFaded attribute for the control.
-
-<dt><b>GetValue()</b>
-<dd>Returns the current value of the control.
-
-<dt><b>SetAlignment(alignment)</b>
-<dd>Set the alignment attribute for the control.
-
-<dt><b>SetDrawFaded(value)</b>
-<dd>Set the DrawFaded attribute for the control.
-
-<dt><b>SetValue(number)</b>
-<dd>Set the value for the control. Only numeric values are accepted.
-
-</dl>
-
-<p>Additionally, several methods of wx.Window are available as well.
-
-</body>
-</html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/19/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestLayoutConstraints(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent, -1)
- self.SetAutoLayout(True)
- self.Bind(wx.EVT_BUTTON, self.OnButton, id=100)
-
- self.SetBackgroundColour(wx.NamedColour("MEDIUM ORCHID"))
-
- self.panelA = wx.Window(self, -1, style=wx.SIMPLE_BORDER)
- self.panelA.SetBackgroundColour(wx.BLUE)
-
- txt = wx.StaticText(
- self.panelA, -1,
- "Resize the window and see\n"
- "what happens... Notice that\n"
- "there is no OnSize handler.",
- (5,5), (-1, 50)
- )
-
- txt.SetBackgroundColour(wx.BLUE)
- txt.SetForegroundColour(wx.WHITE)
-
- lc = wx.LayoutConstraints()
- lc.top.SameAs(self, wx.Top, 10)
- lc.left.SameAs(self, wx.Left, 10)
- lc.bottom.SameAs(self, wx.Bottom, 10)
- lc.right.PercentOf(self, wx.Right, 50)
- self.panelA.SetConstraints(lc)
-
- self.panelB = wx.Window(self, -1, style=wx.SIMPLE_BORDER)
- self.panelB.SetBackgroundColour(wx.RED)
- lc = wx.LayoutConstraints()
- lc.top.SameAs(self, wx.Top, 10)
- lc.right.SameAs(self, wx.Right, 10)
- lc.bottom.PercentOf(self, wx.Bottom, 30)
- lc.left.RightOf(self.panelA, 10)
- self.panelB.SetConstraints(lc)
-
- self.panelC = wx.Window(self, -1, style=wx.SIMPLE_BORDER)
- self.panelC.SetBackgroundColour(wx.WHITE)
- lc = wx.LayoutConstraints()
- lc.top.Below(self.panelB, 10)
- lc.right.SameAs(self, wx.Right, 10)
- lc.bottom.SameAs(self, wx.Bottom, 10)
- lc.left.RightOf(self.panelA, 10)
- self.panelC.SetConstraints(lc)
-
- b = wx.Button(self.panelA, 100, ' Panel A ')
- lc = wx.LayoutConstraints()
- lc.centreX.SameAs (self.panelA, wx.CentreX)
- lc.centreY.SameAs (self.panelA, wx.CentreY)
- lc.height.AsIs ()
- lc.width.PercentOf (self.panelA, wx.Width, 50)
- b.SetConstraints(lc);
-
- b = wx.Button(self.panelB, 100, ' Panel B ')
- lc = wx.LayoutConstraints()
- lc.top.SameAs (self.panelB, wx.Top, 2)
- lc.right.SameAs (self.panelB, wx.Right, 4)
- lc.height.AsIs ()
- lc.width.AsIs ()
- b.SetConstraints(lc);
-
- self.panelD = wx.Window(self.panelC, -1, style=wx.SIMPLE_BORDER)
- self.panelD.SetBackgroundColour(wx.GREEN)
- wx.StaticText(
- self.panelD, -1, "Panel D", (4, 4)
- ).SetBackgroundColour(wx.GREEN)
-
- b = wx.Button(self.panelC, 100, ' Panel C ')
- lc = wx.LayoutConstraints()
- lc.top.Below (self.panelD)
- lc.left.RightOf (self.panelD)
- lc.height.AsIs ()
- lc.width.AsIs ()
- b.SetConstraints(lc);
-
- lc = wx.LayoutConstraints()
- lc.bottom.PercentOf (self.panelC, wx.Height, 50)
- lc.right.PercentOf (self.panelC, wx.Width, 50)
- lc.height.SameAs (b, wx.Height)
- lc.width.SameAs (b, wx.Width)
- self.panelD.SetConstraints(lc);
-
-
- def OnButton(self, event):
- wx.Bell()
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestLayoutConstraints(nb)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-<html><body>
-Objects of this class can be associated with a window to define its
-layout constraints, with respect to siblings or its parent.
-
-<p>The class consists of the following eight constraints of class
-wxIndividualLayoutConstraint, some or all of which should be accessed
-directly to set the appropriate constraints.
-
-<p><ul>
-<li>left: represents the left hand edge of the window
-
-<li>right: represents the right hand edge of the window
-
-<li>top: represents the top edge of the window
-
-<li>bottom: represents the bottom edge of the window
-
-<li>width: represents the width of the window
-
-<li>height: represents the height of the window
-
-<li>centreX: represents the horizontal centre point of the window
-
-<li>centreY: represents the vertical centre point of the window
-</ul>
-<p>Most constraints are initially set to have the relationship
-wxUnconstrained, which means that their values should be calculated by
-looking at known constraints. The exceptions are width and height,
-which are set to wxAsIs to ensure that if the user does not specify a
-constraint, the existing width and height will be used, to be
-compatible with panel items which often have take a default size. If
-the constraint is wxAsIs, the dimension will not be changed.
-
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-# This listbox subclass lets you type the starting letters of what you want to
-# select, and scrolls the list to the match if it is found.
-class FindPrefixListBox(wx.ListBox):
- def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize,
- choices=[], style=0, validator=wx.DefaultValidator):
- wx.ListBox.__init__(self, parent, id, pos, size, choices, style, validator)
- self.typedText = ''
- self.log = parent.log
- self.Bind(wx.EVT_KEY_DOWN, self.OnKey)
-
-
- def FindPrefix(self, prefix):
- self.log.WriteText('Looking for prefix: %s\n' % prefix)
-
- if prefix:
- prefix = prefix.lower()
- length = len(prefix)
-
- # Changed in 2.5 because ListBox.Number() is no longer supported.
- # ListBox.GetCount() is now the appropriate way to go.
- for x in range(self.GetCount()):
- text = self.GetString(x)
- text = text.lower()
-
- if text[:length] == prefix:
- self.log.WriteText('Prefix %s is found.\n' % prefix)
- return x
-
- self.log.WriteText('Prefix %s is not found.\n' % prefix)
- return -1
-
-
- def OnKey(self, evt):
- key = evt.GetKeyCode()
-
- if key >= 32 and key <= 127:
- self.typedText = self.typedText + chr(key)
- item = self.FindPrefix(self.typedText)
-
- if item != -1:
- self.SetSelection(item)
-
- elif key == wx.WXK_BACK: # backspace removes one character and backs up
- self.typedText = self.typedText[:-1]
-
- if not self.typedText:
- self.SetSelection(0)
- else:
- item = self.FindPrefix(self.typedText)
-
- if item != -1:
- self.SetSelection(item)
- else:
- self.typedText = ''
- evt.Skip()
-
- def OnKeyDown(self, evt):
- pass
-
-
-#---------------------------------------------------------------------------
-
-class TestListBox(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
- 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
- 'twelve', 'thirteen', 'fourteen']
-
- wx.StaticText(self, -1, "This example uses the wxListBox control.", (45, 10))
- wx.StaticText(self, -1, "Select one:", (15, 50), (65, 18))
- self.lb1 = wx.ListBox(self, 60, (80, 50), (80, 120), sampleList, wx.LB_SINGLE)
- self.Bind(wx.EVT_LISTBOX, self.EvtListBox, self.lb1)
- self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, self.lb1)
- self.lb1.Bind(wx.EVT_RIGHT_UP, self.EvtRightButton)
- self.lb1.SetSelection(3)
- self.lb1.Append("with data", "This one has data");
- self.lb1.SetClientData(2, "This one has data");
-
-
- wx.StaticText(self, -1, "Select many:", (200, 50), (65, 18))
- self.lb2 = wx.ListBox(self, 70, (280, 50), (80, 120), sampleList, wx.LB_EXTENDED)
- self.Bind(wx.EVT_LISTBOX, self.EvtMultiListBox, self.lb2)
- self.lb2.Bind(wx.EVT_RIGHT_UP, self.EvtRightButton)
- self.lb2.SetSelection(0)
-
- sampleList = sampleList + ['test a', 'test aa', 'test aab',
- 'test ab', 'test abc', 'test abcc',
- 'test abcd' ]
- sampleList.sort()
- wx.StaticText(self, -1, "Find Prefix:", (15, 250))
- fp = FindPrefixListBox(self, -1, (80, 250), (80, 120), sampleList, wx.LB_SINGLE)
- fp.SetSelection(0)
-
-
- def EvtListBox(self, event):
- self.log.WriteText('EvtListBox: %s, %s, %s\n' %
- (event.GetString(), event.IsSelection(), event.GetSelection()))
-
- lb = event.GetEventObject()
- data = lb.GetClientData(lb.GetSelection())
-
- if data is not None:
- self.log.WriteText('\tdata: %s\n' % data)
-
-
- def EvtListBoxDClick(self, event):
- self.log.WriteText('EvtListBoxDClick: %s\n' % self.lb1.GetSelection())
- self.lb1.Delete(self.lb1.GetSelection())
-
- def EvtMultiListBox(self, event):
- self.log.WriteText('EvtMultiListBox: %s\n' % str(self.lb2.GetSelections()))
-
- def EvtRightButton(self, event):
- self.log.WriteText('EvtRightButton: %s\n' % event.GetPosition())
-
- if event.GetEventObject().GetId() == 70:
- selections = list(self.lb2.GetSelections())
- selections.reverse()
-
- for index in selections:
- self.lb2.Delete(index)
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestListBox(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-
-overview = """<html><body>
-A listbox is used to select one or more of a list of
-strings. The strings are displayed in a scrolling box, with the
-selected string(s) marked in reverse video. A listbox can be single
-selection (if an item is selected, the previous selection is removed)
-or multiple selection (clicking an item toggles the item on or off
-independently of other selections).
-</body></html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-#----------------------------------------------------------------------------
-# Name: ListCtrl.py
-# Purpose: Testing lots of stuff, controls, window types, etc.
-#
-# Author: Robin Dunn & Gary Dumer
-#
-# Created:
-# RCS-ID: $Id$
-# Copyright: (c) 1998 by Total Control Software
-# Licence: wxWindows license
-#----------------------------------------------------------------------------
-#
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o listctrl mixin needs wx renamer.
-# o wx.ListItem.GetText() returns a wxString pointer, not the text.
-#
-# 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o ColumnSorterMixin implementation was broke - added event.Skip()
-# to column click event to allow event to fall through to mixin.
-#
-# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxColumnSorterMixin -> ColumnSorterMixin
-# o wxListCtrlAutoWidthMixin -> ListCtrlAutoWidthMixin
-#
-
-import wx
-import wx.lib.mixins.listctrl as listmix
-
-import images
-
-#---------------------------------------------------------------------------
-
-musicdata = {
-1 : ("Bad English", "The Price Of Love", "Rock"),
-2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
-3 : ("George Michael", "Praying For Time", "Rock"),
-4 : ("Gloria Estefan", "Here We Are", "Rock"),
-5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
-6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
-7 : ("Paul Young", "Oh Girl", "Rock"),
-8 : ("Paula Abdul", "Opposites Attract", "Rock"),
-9 : ("Richard Marx", "Should've Known Better", "Rock"),
-10: ("Rod Stewart", "Forever Young", "Rock"),
-11: ("Roxette", "Dangerous", "Rock"),
-12: ("Sheena Easton", "The Lover In Me", "Rock"),
-13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
-14: ("Stevie B.", "Because I Love You", "Rock"),
-15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
-16: ("The Bangles", "Eternal Flame", "Rock"),
-17: ("Wilson Phillips", "Release Me", "Rock"),
-18: ("Billy Joel", "Blonde Over Blue", "Rock"),
-19: ("Billy Joel", "Famous Last Words", "Rock"),
-20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
-21: ("Billy Joel", "The River Of Dreams", "Rock"),
-22: ("Billy Joel", "Two Thousand Years", "Rock"),
-23: ("Janet Jackson", "Alright", "Rock"),
-24: ("Janet Jackson", "Black Cat", "Rock"),
-25: ("Janet Jackson", "Come Back To Me", "Rock"),
-26: ("Janet Jackson", "Escapade", "Rock"),
-27: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
-28: ("Janet Jackson", "Miss You Much", "Rock"),
-29: ("Janet Jackson", "Rhythm Nation", "Rock"),
-30: ("Janet Jackson", "State Of The World", "Rock"),
-31: ("Janet Jackson", "The Knowledge", "Rock"),
-32: ("Spyro Gyra", "End of Romanticism", "Jazz"),
-33: ("Spyro Gyra", "Heliopolis", "Jazz"),
-34: ("Spyro Gyra", "Jubilee", "Jazz"),
-35: ("Spyro Gyra", "Little Linda", "Jazz"),
-36: ("Spyro Gyra", "Morning Dance", "Jazz"),
-37: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
-38: ("Yes", "Owner Of A Lonely Heart", "Rock"),
-39: ("Yes", "Rhythm Of Love", "Rock"),
-40: ("Cusco", "Dream Catcher", "New Age"),
-41: ("Cusco", "Geronimos Laughter", "New Age"),
-42: ("Cusco", "Ghost Dance", "New Age"),
-43: ("Blue Man Group", "Drumbone", "New Age"),
-44: ("Blue Man Group", "Endless Column", "New Age"),
-45: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
-46: ("Kenny G", "Silhouette", "Jazz"),
-47: ("Sade", "Smooth Operator", "Jazz"),
-48: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)", "New Age"),
-49: ("David Arkenstone", "Stepping Stars", "New Age"),
-50: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
-51: ("David Lanz", "Behind The Waterfall", "New Age"),
-52: ("David Lanz", "Cristofori's Dream", "New Age"),
-53: ("David Lanz", "Heartsounds", "New Age"),
-54: ("David Lanz", "Leaves on the Seine", "New Age"),
-}
-
-#---------------------------------------------------------------------------
-
-class TestListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
- def __init__(self, parent, ID, pos=wx.DefaultPosition,
- size=wx.DefaultSize, style=0):
- wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
- listmix.ListCtrlAutoWidthMixin.__init__(self)
-
-
-class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
-
- self.log = log
- tID = wx.NewId()
-
- self.il = wx.ImageList(16, 16)
-
- self.idx1 = self.il.Add(images.getSmilesBitmap())
- self.sm_up = self.il.Add(images.getSmallUpArrowBitmap())
- self.sm_dn = self.il.Add(images.getSmallDnArrowBitmap())
-
- self.list = TestListCtrl(self, tID,
- style=wx.LC_REPORT
- | wx.SUNKEN_BORDER
- | wx.LC_EDIT_LABELS
- #| wxLC_NO_HEADER
- #| wxLC_VRULES | wxLC_HRULES
- )
-
- self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
-
- self.PopulateList()
-
- # Now that the list exists we can init the other base class,
- # see wxPython/lib/mixins/listctrl.py
- self.itemDataMap = musicdata
- listmix.ColumnSorterMixin.__init__(self, 3)
- #self.SortListItems(0, True)
-
- self.Bind(wx.EVT_SIZE, self.OnSize)
-
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
- self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.list)
- self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list)
- self.Bind(wx.EVT_LIST_DELETE_ITEM, self.OnItemDelete, self.list)
- self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
- self.Bind(wx.EVT_LIST_COL_RIGHT_CLICK, self.OnColRightClick, self.list)
- self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, self.OnColBeginDrag, self.list)
- self.Bind(wx.EVT_LIST_COL_DRAGGING, self.OnColDragging, self.list)
- self.Bind(wx.EVT_LIST_COL_END_DRAG, self.OnColEndDrag, self.list)
- self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list)
-
- self.list.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
- self.list.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
-
- # for wxMSW
- self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
-
- # for wxGTK
- self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
-
-
- def PopulateList(self):
- if 0:
- # for normal, simple columns, you can add them like this:
- self.list.InsertColumn(0, "Artist")
- self.list.InsertColumn(1, "Title", wx.LIST_FORMAT_RIGHT)
- self.list.InsertColumn(2, "Genre")
- else:
- # but since we want images on the column header we have to do it the hard way:
- info = wx.ListItem()
- info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
- info.m_image = -1
- info.m_format = 0
- info.m_text = "Artist"
- self.list.InsertColumnInfo(0, info)
-
- info.m_format = wx.LIST_FORMAT_RIGHT
- info.m_text = "Title"
- self.list.InsertColumnInfo(1, info)
-
- info.m_format = 0
- info.m_text = "Genre"
- self.list.InsertColumnInfo(2, info)
-
- items = musicdata.items()
- for x in range(len(items)):
- key, data = items[x]
- self.list.InsertImageStringItem(x, data[0], self.idx1)
- self.list.SetStringItem(x, 1, data[1])
- self.list.SetStringItem(x, 2, data[2])
- self.list.SetItemData(x, key)
-
- self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
- self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
- self.list.SetColumnWidth(2, 100)
-
- # show how to select an item
- self.list.SetItemState(5, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
-
- # show how to change the colour of a couple items
- item = self.list.GetItem(1)
- item.SetTextColour(wx.BLUE)
- self.list.SetItem(item)
- item = self.list.GetItem(4)
- item.SetTextColour(wx.RED)
- self.list.SetItem(item)
-
- self.currentItem = 0
-
-
- # Used by the ColumnSorterMixin, see wxPython/lib/mixins/listctrl.py
- def GetListCtrl(self):
- return self.list
-
- # Used by the ColumnSorterMixin, see wxPython/lib/mixins/listctrl.py
- def GetSortImages(self):
- return (self.sm_dn, self.sm_up)
-
-
- def OnRightDown(self, event):
- self.x = event.GetX()
- self.y = event.GetY()
- self.log.WriteText("x, y = %s\n" % str((self.x, self.y)))
- item, flags = self.list.HitTest((self.x, self.y))
-
- if flags & wx.LIST_HITTEST_ONITEM:
- self.list.Select(item)
-
- event.Skip()
-
-
- def getColumnText(self, index, col):
- item = self.list.GetItem(index, col)
- return item.GetText()
-
-
- def OnItemSelected(self, event):
- ##print event.GetItem().GetTextColour()
- self.currentItem = event.m_itemIndex
- self.log.WriteText("OnItemSelected: %s, %s, %s, %s\n" %
- (self.currentItem,
- self.list.GetItemText(self.currentItem),
- self.getColumnText(self.currentItem, 1),
- self.getColumnText(self.currentItem, 2)))
-
- if self.currentItem == 10:
- self.log.WriteText("OnItemSelected: Veto'd selection\n")
- #event.Veto() # doesn't work
- # this does
- self.list.SetItemState(10, 0, wx.LIST_STATE_SELECTED)
-
- event.Skip()
-
-
- def OnItemDeselected(self, evt):
- item = evt.GetItem()
- self.log.WriteText("OnItemDeselected: %d" % evt.m_itemIndex)
-
- # Show how to reselect something we don't want deselected
- if evt.m_itemIndex == 11:
- wx.CallAfter(self.list.SetItemState, 11, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
-
-
- def OnItemActivated(self, event):
- self.currentItem = event.m_itemIndex
- self.log.WriteText("OnItemActivated: %s\nTopItem: %s" %
- (self.list.GetItemText(self.currentItem), self.list.GetTopItem()))
-
- def OnBeginEdit(self, event):
- self.log.WriteText("OnBeginEdit")
- event.Allow()
-
- def OnItemDelete(self, event):
- self.log.WriteText("OnItemDelete\n")
-
- def OnColClick(self, event):
- self.log.WriteText("OnColClick: %d\n" % event.GetColumn())
- event.Skip()
-
- def OnColRightClick(self, event):
- item = self.list.GetColumn(event.GetColumn())
- self.log.WriteText("OnColRightClick: %d %s\n" %
- (event.GetColumn(), (item.GetText(), item.GetAlign(),
- item.GetWidth(), item.GetImage())))
-
- def OnColBeginDrag(self, event):
- self.log.WriteText("OnColBeginDrag\n")
- ## Show how to not allow a column to be resized
- #if event.GetColumn() == 0:
- # event.Veto()
-
-
- def OnColDragging(self, event):
- self.log.WriteText("OnColDragging\n")
-
- def OnColEndDrag(self, event):
- self.log.WriteText("OnColEndDrag\n")
-
- def OnDoubleClick(self, event):
- self.log.WriteText("OnDoubleClick item %s\n" % self.list.GetItemText(self.currentItem))
- event.Skip()
-
- def OnRightClick(self, event):
- self.log.WriteText("OnRightClick %s\n" % self.list.GetItemText(self.currentItem))
-
- # only do this part the first time so the events are only bound once
- if not hasattr(self, "popupID1"):
- self.popupID1 = wx.NewId()
- self.popupID2 = wx.NewId()
- self.popupID3 = wx.NewId()
- self.popupID4 = wx.NewId()
- self.popupID5 = wx.NewId()
- self.popupID6 = wx.NewId()
-
- self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
- self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
- self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
- self.Bind(wx.EVT_MENU, self.OnPopupFour, id=self.popupID4)
- self.Bind(wx.EVT_MENU, self.OnPopupFive, id=self.popupID5)
- self.Bind(wx.EVT_MENU, self.OnPopupSix, id=self.popupID6)
-
- # make a menu
- menu = wx.Menu()
- # add some items
- menu.Append(self.popupID1, "FindItem tests")
- menu.Append(self.popupID2, "Iterate Selected")
- menu.Append(self.popupID3, "ClearAll and repopulate")
- menu.Append(self.popupID4, "DeleteAllItems")
- menu.Append(self.popupID5, "GetItem")
- menu.Append(self.popupID6, "Edit")
-
- # Popup the menu. If an item is selected then its handler
- # will be called before PopupMenu returns.
- self.PopupMenu(menu, (self.x, self.y))
- menu.Destroy()
-
-
- def OnPopupOne(self, event):
- self.log.WriteText("Popup one\n")
- print "FindItem:", self.list.FindItem(-1, "Roxette")
- print "FindItemData:", self.list.FindItemData(-1, 11)
-
- def OnPopupTwo(self, event):
- self.log.WriteText("Selected items:\n")
- index = self.list.GetFirstSelected()
-
- while index != -1:
- self.log.WriteText(" %s: %s\n" % (self.list.GetItemText(index), self.getColumnText(index, 1)))
- index = self.list.GetNextSelected(index)
-
- def OnPopupThree(self, event):
- self.log.WriteText("Popup three\n")
- self.list.ClearAll()
- wx.CallAfter(self.PopulateList)
-
- def OnPopupFour(self, event):
- self.list.DeleteAllItems()
-
- def OnPopupFive(self, event):
- item = self.list.GetItem(self.currentItem)
- print item.m_text, item.m_itemId, self.list.GetItemData(self.currentItem)
-
- def OnPopupSix(self, event):
- self.list.EditLabel(self.currentItem)
-
-
- def OnSize(self, event):
- w,h = self.GetClientSizeTuple()
- self.list.SetDimensions(0, 0, w, h)
-
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestListCtrlPanel(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-<html>
-<body>
-A list control presents lists in a number of formats: list view, report view,
-icon view and small icon view. In any case, elements are numbered from zero.
-For all these modes (but not for virtual list controls), the items are stored
-in the control and must be added to it using InsertItem method.
-
-<p>To intercept events from a list control, use the event table macros described in
-<code>wxListEvent.</code>
-
-<h3>Mix-ins</h3>
-This example demonstrates how to use mixins. The following mixins are available.
-
-<h4>ColumnSorterMixin</h4>
-
-<code><b>ColumnSorterMixin(numColumns)</b></code>
-
-<p>A mixin class that handles sorting of a wxListCtrl in REPORT mode when the column
-header is clicked on.
-
-<p>There are a few requirments needed in order for this to work genericly:
-<p><ol>
- <li>The combined class must have a <code>GetListCtrl</code> method that returns
- the ListCtrl to be sorted, and the list control must exist at the time the
- <code>ColumnSorterMixin.__init__()</code>method is called because it uses
- <code>GetListCtrl</code>.
-
- <li>Items in the list control must have a unique data value set with
- <code>list.SetItemData</code>.
-
- <li>The combined class must have an attribute named <code>itemDataMap</code>
- that is a dictionary mapping the data values to a sequence of objects
- representing the values in each column. These valuesare compared in
- the column sorter to determine sort order.
-</ol>
-
-<p>Interesting methods to override are <code>GetColumnSorter</code>,
-<code>GetSecondarySortValues</code>, and <code>GetSortImages</code>.
-
-<h5>Methods</h5>
-<dl>
-<dt><code>SetColumnCount(newNumColumns)</code>
-<dd>Informs the mixin as to the number of columns in the control. When it is
-set, it also sets up an event handler for <code>EVT_LIST_COL_CLICK</code> events.
-
-<dt><code>SortListItems(col=-1, ascending=1)</code>
-<dd>Sort the list on demand. Can also be used to set the sort column and order.
-
-<dt><code>GetColumnWidths()</code>
-<dd>Returns a list of column widths. Can be used to help restore the current
-view later.
-
-<dt><code>GetSortImages()</code>
-<dd>Returns a tuple of image list indexes the indexes in the image list for an
-image to be put on the column header when sorting in descending order
-
-<dt><code>GetColumnSorter()</code>
-<dd>Returns a callable object to be used for comparing column values when sorting.
-
-<dt><code>GetSecondarySortValues(col, key1, key2)</code>
-<dd>Returns a tuple of 2 values to use for secondary sort values when the
-items in the selected column match equal. The default just returns the
-item data values.
-
-</dl>
-
-<h4>ListCtrlAutoWidthMixin</h4>
-
-<code><b>ListCtrlAutoWidthMixin()</b></code>
-
-<p>A mix-in class that automatically resizes the last column to take up the
-remaining width of the ListCtrl.
-
-<p>This causes the ListCtrl to automatically take up the full width of the list,
-without either a horizontal scroll bar (unless absolutely necessary) or empty
-space to the right of the last column.
-
-<p><b>NOTE:</b> This only works for report-style lists.
-
-<p><b>WARNING:</b> If you override the <code>EVT_SIZE</code> event in your ListCtrl,
-make sure you call event.Skip() to ensure that the mixin's _OnResize method is
-called.
-
-<p>This mix-in class was written by <a href='mailto:ewestra@wave.co.nz'>Erik Westra </a>
-
-<h5>Methods</h5>
-<dl>
-
-<dt><code>resizeLastColumn(minWidth)</code>
-<dd>Resize the last column appropriately. If the list's columns are too wide to
-fit within the window, we use a horizontal scrollbar. Otherwise, we expand the
-right-most column to take up the remaining free space in the list. This method is
-called automatically when the ListCtrl is resized; you can also call it yourself
-whenever you want the last column to be resized appropriately (eg, when adding,
-removing or resizing columns). 'minWidth' is the preferred minimum width for
-the last column.
-
-</dl>
-
-
-<h4>ListCtrlSelectionManagerMix</h4>
-
-<code><b>ListCtrlSelectionManagerMix()</b></code>
-
-<p>Mixin that defines a platform independent selection policy
-
-<p>As selection single and multi-select list return the item index or a
-list of item indexes respectively.
-
-<h5>Methods</h5>
-<dl>
-
-<dt><code>getPopupMenu()</code>
-<dd>Override to implement dynamic menus (create)
-
-<dt><code>setPopupMenu(menu)</code>
-<dd>Must be set for default behaviour.
-
-<dt><code>afterPopupMenu()</code>
-<dd>Override to implement dynamic menus (destroy).
-
-<dt><code>getSelection()</code>
-<dd>Returns the current selection (or selections as a Python list if extended
-selection is enabled)
-
-
-</body>
-</html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wx.ListItem.GetText() returns a wxString pointer, not the text.
-#
-
-import wx
-import images
-
-#----------------------------------------------------------------------
-
-class TestVirtualList(wx.ListCtrl):
- def __init__(self, parent, log):
- wx.ListCtrl.__init__(
- self, parent, -1,
- style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES
- )
-
- self.log = log
-
- self.il = wx.ImageList(16, 16)
- self.idx1 = self.il.Add(images.getSmilesBitmap())
- self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
-
-
- self.InsertColumn(0, "First")
- self.InsertColumn(1, "Second")
- self.InsertColumn(2, "Third")
- self.SetColumnWidth(0, 175)
- self.SetColumnWidth(1, 175)
- self.SetColumnWidth(2, 175)
-
- self.SetItemCount(1000000)
-
- self.attr1 = wx.ListItemAttr()
- self.attr1.SetBackgroundColour("yellow")
-
- self.attr2 = wx.ListItemAttr()
- self.attr2.SetBackgroundColour("light blue")
-
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
- self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
- self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected)
-
-
- def OnItemSelected(self, event):
- self.currentItem = event.m_itemIndex
- self.log.WriteText('OnItemSelected: "%s", "%s", "%s", "%s"\n' %
- (self.currentItem,
- self.GetItemText(self.currentItem),
- self.getColumnText(self.currentItem, 1),
- self.getColumnText(self.currentItem, 2)))
-
- def OnItemActivated(self, event):
- self.currentItem = event.m_itemIndex
- self.log.WriteText("OnItemActivated: %s\nTopItem: %s\n" %
- (self.GetItemText(self.currentItem), self.GetTopItem()))
-
- def getColumnText(self, index, col):
- item = self.GetItem(index, col)
- return item.GetText()
-
- def OnItemDeselected(self, evt):
- self.log.WriteText("OnItemDeselected: %s" % evt.m_itemIndex)
-
-
- #---------------------------------------------------
- # These methods are callbacks for implementing the
- # "virtualness" of the list... Normally you would
- # determine the text, attributes and/or image based
- # on values from some external data source, but for
- # this demo we'll just calculate them
- def OnGetItemText(self, item, col):
- return "Item %d, column %d" % (item, col)
-
- def OnGetItemImage(self, item):
- if item % 3 == 0:
- return self.idx1
- else:
- return -1
-
- def OnGetItemAttr(self, item):
- if item % 3 == 1:
- return self.attr1
- elif item % 3 == 2:
- return self.attr2
- else:
- return None
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestVirtualList(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-This example demonstrates the ListCtrl's Virtual List features. A Virtual list
-can contain any number of cells, but data is not loaded into the control itself.
-It is loaded on demand via virtual methods <code>OnGetItemText(), OnGetItemImage()</code>,
-and <code>OnGetItemAttr()</code>. This greatly reduces the amount of memory required
-without limiting what can be done with the list control itself.
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Bunches of imports that might need to go away for the final roll-out.
-#
-
-import sys
-
-import wx
-
-import images
-
-import ColorPanel
-
-colourList = [ "Aquamarine", "Black", "Blue", "Blue Violet", "Brown", "Cadet Blue",
- "Coral", "Cornflower Blue", "Cyan", "Dark Grey", "Dark Green",
- "Dark Olive Green", "Dark Orchid", "Dark Slate Blue",
- "Dark Slate Grey", "Dark Turquoise", "Dim Grey", "Firebrick",
- "Forest Green", "Gold", "Goldenrod", "Grey", "Green", "Green Yellow",
- "Indian Red", "Khaki", "Light Blue", "Light Grey", "Light Steel Blue",
- "Lime Green", "Magenta", "Maroon", "Medium Aquamarine", "Medium Blue",
- "Medium Forest Green", "Medium Goldenrod", "Medium Orchid",
- "Medium Sea Green", "Medium Slate Blue", "Medium Spring Green",
- "Medium Turquoise", "Medium Violet Red", "Midnight Blue", "Navy",
- "Orange", "Orange Red", "Orchid", "Pale Green", "Pink", "Plum",
- "Purple", "Red", "Salmon", "Sea Green", "Sienna", "Sky Blue",
- "Slate Blue", "Spring Green", "Steel Blue", "Tan", "Thistle",
- "Turquoise", "Violet", "Violet Red", "Wheat", "White", "Yellow",
- "Yellow Green"
- ]
-
-#----------------------------------------------------------------------------
-
-class TestLB(wx.Listbook):
- def __init__(self, parent, id, log):
- wx.Listbook.__init__(self, parent, id, style=
- wx.LB_DEFAULT
- #wxLB_TOP
- #wxLB_BOTTOM
- #wxLB_LEFT
- #wxLB_RIGHT
- )
- self.log = log
-
-
- # make an image list using the BlomXX images
- il = wx.ImageList(32, 32)
- for x in range(1, 15):
- f = getattr(images, 'getBlom%02dBitmap' % x)
- bmp = f()
- il.Add(bmp)
- self.AssignImageList(il)
-
- # Now make a bunch of panels for the list book
- first = True
- imID = 0
- for colour in colourList:
- win = self.makeColorPanel(colour)
- self.AddPage(win, colour, imageId=imID)
- imID += 1
- if imID == il.GetImageCount(): imID = 0
- if first:
- st = wx.StaticText(win.win, -1,
- "You can put nearly any type of window here,\n"
- "and the list can be on any side of the Listbook",
- wx.Point(10, 10))
- #st.SetForegroundColour(wxWHITE)
- #st.SetBackgroundColour(wxBLUE)
- first = False
-
-
-
- wx.EVT_LISTBOOK_PAGE_CHANGED(self, self.GetId(), self.OnPageChanged)
- wx.EVT_LISTBOOK_PAGE_CHANGING(self, self.GetId(), self.OnPageChanging)
-
-
- def makeColorPanel(self, color):
- p = wx.Panel(self, -1)
- win = ColorPanel.ColoredPanel(p, color)
- p.win = win
- def OnCPSize(evt, win=win):
- win.SetSize(evt.GetSize())
- p.Bind(wx.EVT_SIZE, OnCPSize)
- return p
-
-
- def OnPageChanged(self, event):
- old = event.GetOldSelection()
- new = event.GetSelection()
- sel = self.GetSelection()
- self.log.write('OnPageChanged, old:%d, new:%d, sel:%d\n' % (old, new, sel))
- event.Skip()
-
- def OnPageChanging(self, event):
- old = event.GetOldSelection()
- new = event.GetSelection()
- sel = self.GetSelection()
- self.log.write('OnPageChanging, old:%d, new:%d, sel:%d\n' % (old, new, sel))
- event.Skip()
-
-#----------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- testWin = TestLB(nb, -1, log)
- return testWin
-
-#----------------------------------------------------------------------------
-
-
-overview = """\
-<html><body>
-<h2>wxListbook</h2>
-<p>
-This class is a control similar to a notebook control, but with a
-wxListCtrl instead of a set of tabs.
-
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
-
+++ /dev/null
-# 11/12/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-import MDIDemo
-import MDISashDemo
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- b1 = wx.Button(self, -1, "MDI demo")
- self.Bind(wx.EVT_BUTTON, self.ShowMDIDemo, b1)
-
- b2 = wx.Button(self, -1, "MDI with SashWindows demo")
- self.Bind(wx.EVT_BUTTON, self.ShowMDISashDemo, b2)
-
- box = wx.BoxSizer(wx.VERTICAL)
- box.Add((20, 30))
- box.Add(b1, 0, wx.ALIGN_CENTER|wx.ALL, 15)
- box.Add(b2, 0, wx.ALIGN_CENTER|wx.ALL, 15)
- self.SetAutoLayout(True)
- self.SetSizer(box)
-
-
- def ShowMDIDemo(self, evt):
- frame = MDIDemo.MyParentFrame()
- frame.Show()
-
- def ShowMDISashDemo(self, evt):
- frame = MDISashDemo.MyParentFrame()
- frame.Show()
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>Multiple Document Interface</center></h2>
-
-Although Microsoft has deprecated the MDI model, wxWindows still supports
-it. Here are a couple samples of how to use it - one straightforward, the other
-showing how the MDI interface can be integrated into a SashWindow interface.
-
-</body></html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Library must be updated for this to run.
-#
-# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxMVCTree -> MVCTree
-#
-
-import os
-import sys
-
-import wx
-import wx.lib.mvctree as tree
-
-logger = None
-def selchanging(evt):
- logger.write("SelChanging!\n")
-
-def selchanged(evt):
- logger.write("SelChange!\n")
- logger.write(str(evt.node))
-def expanded(evt):
- logger.write("Expanded\n")
-def closed(evt):
- logger.write("Closed!\n")
-def key(evt):
- logger.write("Key\n")
-def add(evt):
- logger.write("Add\n")
-def delitem(evt):
- logger.write("Delete\n")
-
-def runTest(frame, nb, log):
- #f = wx.Frame(frame, -1, "MVCTree", (0,0), (200,500))
- global logger
- logger = log
- p = tree.MVCTree(nb, -1)
- #f = wx.Frame(frame, -1, "MVCTree")
- #p = tree.MVCTree(f, -1)
- p.SetAssumeChildren(True)
- p.SetModel(tree.LateFSTreeModel(os.path.normpath(os.getcwd() + os.sep +'..')))
-
- #Uncomment this to enable live filename editing!
-# p.AddEditor(FileEditor(p))
-
- p.SetMultiSelect(True)
- tree.EVT_MVCTREE_SEL_CHANGING(p, p.GetId(), selchanging)
- tree.EVT_MVCTREE_SEL_CHANGED(p, p.GetId(), selchanged)
- tree.EVT_MVCTREE_ITEM_EXPANDED(p, p.GetId(), expanded)
- tree.EVT_MVCTREE_ITEM_COLLAPSED(p, p.GetId(), closed)
- tree.EVT_MVCTREE_ADD_ITEM(p, p.GetId(), add)
- tree.EVT_MVCTREE_DELETE_ITEM(p, p.GetId(), delitem)
- tree.EVT_MVCTREE_KEY_DOWN(p, p.GetId(), key)
-
- return p
- #frame.otherWin = f
- #f.Show(True)
- #return None
-
-
-overview = """\
-
-MVCTree is a control which handles hierarchical data. It is
-constructed in model-view-controller architecture, so the display of
-that data, and the content of the data can be changed greatly without
-affecting the other parts.
-
-Multiple selections are possible by holding down the Ctrl key.
-
-This demo shows the wxPython directory structure. The interesting part
-is that the tree model is late-bound to the filesystem, so the
-filenames are not retrieved until the directory is expanded. In
-mvctree.py are models for generic data, and both the early and
-late-bound filesystem models.
-
-There is also support for editing, though it's not enabled in this
-demo, to avoid accidentally renaming files!
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-logicList = [
- ('wx.AND', wx.AND),
- ('wx.AND_INVERT', wx.AND_INVERT),
- ('wx.AND_REVERSE', wx.AND_REVERSE),
- ('wx.CLEAR', wx.CLEAR),
- ('wx.COPY', wx.COPY),
- ('wx.EQUIV', wx.EQUIV),
- ('wx.INVERT', wx.INVERT),
- ('wx.NAND', wx.NAND),
-
- # this one causes an assert on wxGTK, and doesn't seem to
- # do much on MSW anyway, so I'll just take it out....
- #('wxNOR', wxNOR),
-
- ('wx.NO_OP', wx.NO_OP),
- ('wx.OR', wx.OR),
- ('wx.OR_INVERT', wx.OR_INVERT),
- ('wx.OR_REVERSE', wx.OR_REVERSE),
- ('wx.SET', wx.SET),
- ('wx.SRC_INVERT', wx.SRC_INVERT),
- ('wx.XOR', wx.XOR),
-]
-
-import images
-
-class TestMaskWindow(wx.ScrolledWindow):
- def __init__(self, parent):
- wx.ScrolledWindow.__init__(self, parent, -1)
- self.SetBackgroundColour(wx.Colour(0,128,0))
-
- # A reference bitmap that we won't mask
- self.bmp_nomask = images.getTestStar2Bitmap()
-
- # One that we will
- self.bmp_withmask = images.getTestStar2Bitmap()
-
- # this mask comes from a monochrome bitmap
- self.bmp_themask = wx.BitmapFromImage(images.getTestMaskImage(), 1)
- mask = wx.Mask(self.bmp_themask)
-
- # set the mask on our bitmap
- self.bmp_withmask.SetMask(mask)
-
- # Now we'll create a mask in a bit of an easier way, by picking a
- # colour in the image that is to be the transparent colour.
- self.bmp_withcolourmask = images.getTestStar2Bitmap()
- mask = wx.MaskColour(self.bmp_withcolourmask, wx.WHITE)
- self.bmp_withcolourmask.SetMask(mask)
-
- self.SetScrollbars(20, 20, 700/20, 460/20)
-
- self.Bind(wx.EVT_PAINT, self.OnPaint)
-
-
- def OnPaint (self, e):
- dc = wx.PaintDC(self)
- self.PrepareDC(dc)
- dc.SetTextForeground(wx.WHITE)
-
- # make an interesting background...
- dc.SetPen(wx.MEDIUM_GREY_PEN)
- for i in range(100):
- dc.DrawLine((0,i*10), (i*10,0))
-
- # draw raw image, mask, and masked images
- dc.DrawText('original image', (0,0))
- dc.DrawBitmap(self.bmp_nomask, (0,20), 0)
- dc.DrawText('with colour mask', (0,100))
- dc.DrawBitmap(self.bmp_withcolourmask, (0,120), 1)
- dc.DrawText('the mask image', (0,200))
- dc.DrawBitmap(self.bmp_themask, (0,220), 0)
- dc.DrawText('masked image', (0,300))
- dc.DrawBitmap(self.bmp_withmask, (0,320), 1)
-
- cx,cy = self.bmp_themask.GetWidth(), self.bmp_themask.GetHeight()
-
- # draw array of assorted blit operations
- mdc = wx.MemoryDC()
- i = 0
-
- for text, code in logicList:
- x,y = 120+150*(i%4), 20+100*(i/4)
- dc.DrawText(text, (x, y-20))
- mdc.SelectObject(self.bmp_withcolourmask)
- dc.Blit((x,y), (cx,cy), mdc, (0,0), code, True)
- i = i + 1
-
-
-# On wxGTK there needs to be a panel under wxScrolledWindows if they are
-# going to be in a wxNotebook...
-class TestPanel(wx.Panel):
- def __init__(self, parent, ID):
- wx.Panel.__init__(self, parent, ID)
- self.win = TestMaskWindow(self)
- self.Bind(wx.EVT_SIZE, self.OnSize)
-
- def OnSize(self, evt):
- self.win.SetSize(evt.GetSize())
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, -1)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-This class encapsulates a monochrome mask bitmap, where the masked area is black
-and the unmasked area is white. When associated with a bitmap and drawn in a device
-context, the unmasked area of the bitmap will be drawn, and the masked area will
-not be drawn.
-
-This example shows not only how to create a Mask, but the effects of the Device
-Context (dc) <code>Blit()</code> method's logic codes.
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/29/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wx.lib.maskednumctrl needs hit up with the renamer and new binders
-#
-# 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Issues with lib corrected.
-#
-# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxMaskedNumCtrl -> MaskedNumCtrl
-#
-
-import string
-import sys
-import traceback
-
-import wx
-import wx.lib.maskednumctrl as mnum
-#----------------------------------------------------------------------
-
-class TestPanel( wx.Panel ):
- def __init__( self, parent, log ):
-
- wx.Panel.__init__( self, parent, -1 )
- self.log = log
- panel = wx.Panel( self, -1 )
-
- header = wx.StaticText(panel, -1, """\
-This shows the various options for MaskedNumCtrl.
-The controls at the top reconfigure the resulting control at the bottom.
-""")
- header.SetForegroundColour( "Blue" )
-
- intlabel = wx.StaticText( panel, -1, "Integer width:" )
- self.integerwidth = mnum.MaskedNumCtrl(
- panel, value=10, integerWidth=2, allowNegative=False
- )
-
- fraclabel = wx.StaticText( panel, -1, "Fraction width:" )
- self.fractionwidth = mnum.MaskedNumCtrl(
- panel, value=0, integerWidth=2, allowNegative=False
- )
-
- groupcharlabel = wx.StaticText( panel,-1, "Grouping char:" )
- self.groupchar = mnum.MaskedTextCtrl(
- panel, -1, value=',', mask='&', excludeChars = '-()',
- formatcodes='F', emptyInvalid=True, validRequired=True
- )
-
- decimalcharlabel = wx.StaticText( panel,-1, "Decimal char:" )
- self.decimalchar = mnum.MaskedTextCtrl(
- panel, -1, value='.', mask='&', excludeChars = '-()',
- formatcodes='F', emptyInvalid=True, validRequired=True
- )
-
- self.set_min = wx.CheckBox( panel, -1, "Set minimum value:" )
- # Create this MaskedNumCtrl using factory, to show how:
- self.min = mnum.MaskedNumCtrl( panel, integerWidth=5, fractionWidth=2 )
- self.min.Enable( False )
-
- self.set_max = wx.CheckBox( panel, -1, "Set maximum value:" )
- self.max = mnum.MaskedNumCtrl( panel, integerWidth=5, fractionWidth=2 )
- self.max.Enable( False )
-
-
- self.limit_target = wx.CheckBox( panel, -1, "Limit control" )
- self.allow_none = wx.CheckBox( panel, -1, "Allow empty control" )
- self.group_digits = wx.CheckBox( panel, -1, "Group digits" )
- self.group_digits.SetValue( True )
- self.allow_negative = wx.CheckBox( panel, -1, "Allow negative values" )
- self.allow_negative.SetValue( True )
- self.use_parens = wx.CheckBox( panel, -1, "Use parentheses" )
- self.select_on_entry = wx.CheckBox( panel, -1, "Select on entry" )
- self.select_on_entry.SetValue( True )
-
- label = wx.StaticText( panel, -1, "Resulting numeric control:" )
- font = label.GetFont()
- font.SetWeight(wx.BOLD)
- label.SetFont(font)
-
- self.target_ctl = mnum.MaskedNumCtrl( panel, -1, name="target control" )
-
- label_numselect = wx.StaticText( panel, -1, """\
-Programmatically set the above
-value entry ctrl:""")
- self.numselect = wx.ComboBox(panel, -1, choices = [ '0', '111', '222.22', '-3', '54321.666666666', '-1353.978',
- '1234567', '-1234567', '123456789', '-123456789.1',
- '1234567890.', '-9876543210.9' ])
-
- grid1 = wx.FlexGridSizer( 0, 4, 0, 0 )
- grid1.Add( intlabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
- grid1.Add( self.integerwidth, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid1.Add( groupcharlabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
- grid1.Add( self.groupchar, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid1.Add( fraclabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid1.Add( self.fractionwidth, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid1.Add( decimalcharlabel, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
- grid1.Add( self.decimalchar, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid1.Add( self.set_min, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid1.Add( self.min, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
-
- grid1.Add( self.set_max, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid1.Add( self.max, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
-
-
- grid1.Add( self.limit_target, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid1.Add( self.allow_none, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- hbox1 = wx.BoxSizer( wx.HORIZONTAL )
- hbox1.Add( (17,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- hbox1.Add( self.group_digits, 0, wx.ALIGN_LEFT|wx.LEFT, 5 )
- grid1.Add( hbox1, 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
-
- grid1.Add( self.allow_negative, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid1.Add( self.use_parens, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- hbox2 = wx.BoxSizer( wx.HORIZONTAL )
- hbox2.Add( (17,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- hbox2.Add( self.select_on_entry, 0, wx.ALIGN_LEFT|wx.LEFT, 5 )
- grid1.Add( hbox2, 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid1.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
-
-
- grid2 = wx.FlexGridSizer( 0, 2, 0, 0 )
- grid2.Add( label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid2.Add( self.target_ctl, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid2.Add( label_numselect, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid2.Add( self.numselect, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid2.Add( (5,5), 0, wx.ALIGN_LEFT|wx.ALL, 5)
- grid2.AddGrowableCol(1)
-
- self.outer_box = wx.BoxSizer( wx.VERTICAL )
- self.outer_box.Add(header, 0, wx.ALIGN_LEFT|wx.TOP|wx.LEFT, 20)
- self.outer_box.Add( grid1, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.BOTTOM|wx.RIGHT, 20 )
- self.outer_box.Add( grid2, 0, wx.ALIGN_LEFT|wx.ALL, 20 )
- self.grid2 = grid2
-
- panel.SetAutoLayout( True )
- panel.SetSizer( self.outer_box )
- self.outer_box.Fit( panel )
- panel.Move( (50,10) )
- self.panel = panel
-
- self.Bind(mnum.EVT_MASKEDNUM, self.OnSetIntWidth, self.integerwidth )
- self.Bind(mnum.EVT_MASKEDNUM, self.OnSetFractionWidth, self.fractionwidth )
- self.Bind(wx.EVT_TEXT, self.OnSetGroupChar, self.groupchar )
- self.Bind(wx.EVT_TEXT, self.OnSetDecimalChar, self.decimalchar )
-
- self.Bind(wx.EVT_CHECKBOX, self.OnSetMin, self.set_min )
- self.Bind(wx.EVT_CHECKBOX, self.OnSetMax, self.set_max )
- self.Bind(mnum.EVT_MASKEDNUM, self.SetTargetMinMax, self.min )
- self.Bind(mnum.EVT_MASKEDNUM, self.SetTargetMinMax, self.max )
-
- self.Bind(wx.EVT_CHECKBOX, self.SetTargetMinMax, self.limit_target )
- self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowNone, self.allow_none )
- self.Bind(wx.EVT_CHECKBOX, self.OnSetGroupDigits, self.group_digits )
- self.Bind(wx.EVT_CHECKBOX, self.OnSetAllowNegative, self.allow_negative )
- self.Bind(wx.EVT_CHECKBOX, self.OnSetUseParens, self.use_parens )
- self.Bind(wx.EVT_CHECKBOX, self.OnSetSelectOnEntry, self.select_on_entry )
-
- self.Bind(mnum.EVT_MASKEDNUM, self.OnTargetChange, self.target_ctl )
- self.Bind(wx.EVT_COMBOBOX, self.OnNumberSelect, self.numselect )
-
-
- def OnSetIntWidth(self, event ):
- width = self.integerwidth.GetValue()
-
- if width < 1:
- self.log.write("integer width must be positive\n")
- self.integerwidth.SetForegroundColour(wx.RED)
- else:
- self.integerwidth.SetForegroundColour(wx.BLACK)
- self.log.write("setting integer width to %d\n" % width)
- self.target_ctl.SetParameters( integerWidth = width)
- # Now resize and fit the dialog as appropriate:
- self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
- self.outer_box.Fit( self.panel )
- self.outer_box.SetSizeHints( self.panel )
-
-
- def OnSetFractionWidth(self, event ):
- width = self.fractionwidth.GetValue()
- self.log.write("setting fraction width to %d\n" % width)
- self.target_ctl.SetParameters( fractionWidth = width)
- # Now resize and fit the dialog as appropriate:
- self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
- self.outer_box.Fit( self.panel )
- self.outer_box.SetSizeHints( self.panel )
-
-
- def OnSetGroupChar( self, event ):
- char = self.groupchar.GetValue()
- if self.target_ctl.GetDecimalChar() == char:
- self.log.write("group and decimal chars must be different\n")
- self.groupchar.SetForegroundColour(wx.RED)
- else:
- self.groupchar.SetForegroundColour(wx.BLACK)
- self.log.write("setting group char to %s\n" % char)
- self.target_ctl.SetGroupChar( char )
-
- def OnSetDecimalChar( self, event ):
- char = self.decimalchar.GetValue()
- if self.target_ctl.GetGroupChar() == char:
- self.log.write("group and decimal chars must be different\n")
- self.decimalchar.SetForegroundColour(wx.RED)
- else:
- self.decimalchar.SetForegroundColour(wx.BLACK)
- self.log.write("setting decimal char to %s\n" % char)
- self.target_ctl.SetDecimalChar( char )
-
-
- def OnSetMin( self, event ):
- self.min.Enable( self.set_min.GetValue() )
- self.SetTargetMinMax()
-
- def OnSetMax( self, event ):
- self.max.Enable( self.set_max.GetValue() )
- self.SetTargetMinMax()
-
-
- def SetTargetMinMax( self, event=None ):
- min = max = None
- self.target_ctl.SetLimited( self.limit_target.GetValue() )
-
- if self.set_min.GetValue():
- min = self.min.GetValue()
- if self.set_max.GetValue():
- max = self.max.GetValue()
-
- cur_min, cur_max = self.target_ctl.GetBounds()
-
- if min != cur_min and not self.target_ctl.SetMin( min ):
- if self.target_ctl.GetMax() is None and cur_max > min:
- self.log.write( "min (%d) won't fit in control -- bound not set\n" % min )
- else:
- self.log.write( "min (%d) > current max (%d) -- bound not set\n" % ( min, self.target_ctl.GetMax() ) )
- self.min.SetParameters( signedForegroundColour=wx.RED, foregroundColour=wx.RED )
- else:
- self.min.SetParameters( signedForegroundColour=wx.BLACK, foregroundColour=wx.BLACK )
- self.min.Refresh()
-
- if max != cur_max and not self.target_ctl.SetMax( max ):
- if self.target_ctl.GetMax() is None and cur_min < max:
- self.log.write( "max (%d) won't fit in control -- bound not set\n" % max )
- else:
- self.log.write( "max (%d) < current min (%d) -- bound not set\n" % ( max, self.target_ctl.GetMin() ) )
- self.max.SetParameters( signedForegroundColour=wx.RED, foregroundColour=wx.RED )
- else:
- self.max.SetParameters( signedForegroundColour=wx.BLACK, foregroundColour=wx.BLACK )
- self.max.Refresh()
-
- if min != cur_min or max != cur_max:
- new_min, new_max = self.target_ctl.GetBounds()
- self.log.write( "current min, max: (%s, %s)\n" % ( str(new_min), str(new_max) ) )
-
-
- def OnSetAllowNone( self, event ):
- self.target_ctl.SetAllowNone( self.allow_none.GetValue() )
-
-
- def OnSetGroupDigits( self, event ):
- self.target_ctl.SetGroupDigits( self.group_digits.GetValue() )
- # Now resize and fit the dialog as appropriate:
- self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
- self.outer_box.Fit( self.panel )
- self.outer_box.SetSizeHints( self.panel )
-
-
- def OnSetAllowNegative( self, event ):
- if self.allow_negative.GetValue():
- self.use_parens.Enable(True)
- self.target_ctl.SetParameters(allowNegative=True,
- useParensForNegatives = self.use_parens.GetValue())
- else:
- self.target_ctl.SetAllowNegative(False)
- # Now resize and fit the dialog as appropriate:
- self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
- self.outer_box.Fit( self.panel )
- self.outer_box.SetSizeHints( self.panel )
-
-
- def OnSetUseParens( self, event ):
- self.target_ctl.SetUseParensForNegatives( self.use_parens.GetValue() )
- # Now resize and fit the dialog as appropriate:
- self.grid2.SetItemMinSize(self.target_ctl, self.target_ctl.GetSize())
- self.outer_box.Fit( self.panel )
- self.outer_box.SetSizeHints( self.panel )
-
-
- def OnSetSelectOnEntry( self, event ):
- self.target_ctl.SetSelectOnEntry( self.select_on_entry.GetValue() )
-
-
- def OnTargetChange( self, event ):
- ctl = event.GetEventObject()
- value = ctl.GetValue()
- ib_str = [ " (out of bounds)", "" ]
- self.log.write( "value = %s (%s)%s\n" % ( repr(value), repr(type(value)), ib_str[ ctl.IsInBounds(value) ] ) )
-
-
- def OnNumberSelect( self, event ):
- value = event.GetString()
- if value:
- if value.find('.') != -1:
- numvalue = float(value)
- else:
- numvalue = long(value)
- else:
- numvalue = value # try to clear the value again
-
- try:
- self.target_ctl.SetValue(numvalue)
- except:
- type, value, tb = sys.exc_info()
- for line in traceback.format_exception_only(type, value):
- self.log.write(line)
-
-
-#----------------------------------------------------------------------
-
-def runTest( frame, nb, log ):
- win = TestPanel( nb, log )
- return win
-
-#----------------------------------------------------------------------
-overview = mnum.__doc__
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-#-------------------------------------------------------------------
-# essaimenu.py
-#
-# menus in wxPython 2.3.3
-#
-#-------------------------------------------------------------------
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import time
-import wx
-import images
-
-#-------------------------------------------------------------------
-
-class MyFrame(wx.Frame):
-
- def __init__(self, parent, id, log):
- wx.Frame.__init__(self, parent, id, 'Playing with menus', size=(400, 200))
- self.log = log
- self.CenterOnScreen()
-
- self.CreateStatusBar()
- self.SetStatusText("This is the statusbar")
-
- tc = wx.TextCtrl(self, -1, """
-A bunch of bogus menus have been created for this frame. You
-can play around with them to see how they behave and then
-check the source for this sample to see how to implement them.
-""", style=wx.TE_READONLY|wx.TE_MULTILINE)
-
- # Prepare the menu bar
- menuBar = wx.MenuBar()
-
- # 1st menu from left
- menu1 = wx.Menu()
- menu1.Append(101, "&Mercury", "This the text in the Statusbar")
- menu1.Append(102, "&Venus", "")
- menu1.Append(103, "&Earth", "You may select Earth too")
- menu1.AppendSeparator()
- menu1.Append(104, "&Close", "Close this frame")
- # Add menu to the menu bar
- menuBar.Append(menu1, "&Planets")
-
- # 2nd menu from left
- menu2 = wx.Menu()
- menu2.Append(201, "Hydrogen")
- menu2.Append(202, "Helium")
- # a submenu in the 2nd menu
- submenu = wx.Menu()
- submenu.Append(2031,"Lanthanium")
- submenu.Append(2032,"Cerium")
- submenu.Append(2033,"Praseodymium")
- menu2.AppendMenu(203, "Lanthanides", submenu)
- # Append 2nd menu
- menuBar.Append(menu2, "&Elements")
-
- menu3 = wx.Menu()
- # Radio items
- menu3.Append(301, "IDLE", "a Python shell using tcl/tk as GUI", wx.ITEM_RADIO)
- menu3.Append(302, "PyCrust", "a Python shell using wxPython as GUI", wx.ITEM_RADIO)
- menu3.Append(303, "psi", "a simple Python shell using wxPython as GUI", wx.ITEM_RADIO)
- menu3.AppendSeparator()
- menu3.Append(304, "project1", "", wx.ITEM_NORMAL)
- menu3.Append(305, "project2", "", wx.ITEM_NORMAL)
- menuBar.Append(menu3, "&Shells")
-
- menu4 = wx.Menu()
- # Check menu items
- menu4.Append(401, "letters", "abcde...", wx.ITEM_CHECK)
- menu4.Append(402, "digits", "123...", wx.ITEM_CHECK)
- menu4.Append(403, "letters and digits", "abcd... + 123...", wx.ITEM_CHECK)
- menuBar.Append(menu4, "Chec&k")
-
- menu5 = wx.Menu()
- # Show how to put an icon in the menu
- item = wx.MenuItem(menu5, 500, "&Smile!\tCtrl+S", "This one has an icon")
- item.SetBitmap(images.getSmilesBitmap())
- menu5.AppendItem(item)
-
- # Shortcuts
- menu5.Append(501, "Interesting thing\tCtrl+A", "Note the shortcut!")
- menu5.AppendSeparator()
- menu5.Append(502, "Hello\tShift+H")
- menu5.AppendSeparator()
- menu5.Append(503, "remove the submenu")
- menu6 = wx.Menu()
- menu6.Append(601, "Submenu Item")
- menu5.AppendMenu(504, "submenu", menu6)
- menu5.Append(505, "remove this menu")
- menu5.Append(506, "this is updated")
- menu5.Append(507, "insert after this...")
- menu5.Append(508, "...and before this")
- menuBar.Append(menu5, "&Fun")
-
- self.SetMenuBar(menuBar)
-
- # Menu events
- self.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuHighlight)
-
- self.Bind(wx.EVT_MENU, self.Menu101, id=101)
- self.Bind(wx.EVT_MENU, self.Menu102, id=102)
- self.Bind(wx.EVT_MENU, self.Menu103, id=103)
- self.Bind(wx.EVT_MENU, self.CloseWindow, id=104)
-
- self.Bind(wx.EVT_MENU, self.Menu201, id=201)
- self.Bind(wx.EVT_MENU, self.Menu202, id=202)
- self.Bind(wx.EVT_MENU, self.Menu2031, id=2031)
- self.Bind(wx.EVT_MENU, self.Menu2032, id=2032)
- self.Bind(wx.EVT_MENU, self.Menu2033, id=2033)
-
- self.Bind(wx.EVT_MENU, self.Menu301To303, id=301)
- self.Bind(wx.EVT_MENU, self.Menu301To303, id=302)
- self.Bind(wx.EVT_MENU, self.Menu301To303, id=303)
- self.Bind(wx.EVT_MENU, self.Menu304, id=304)
- self.Bind(wx.EVT_MENU, self.Menu305, id=305)
-
- # Range of menu items
- self.Bind(wx.EVT_MENU_RANGE, self.Menu401To403, id=401, id2=403)
-
- self.Bind(wx.EVT_MENU, self.Menu500, id=500)
- self.Bind(wx.EVT_MENU, self.Menu501, id=501)
- self.Bind(wx.EVT_MENU, self.Menu502, id=502)
- self.Bind(wx.EVT_MENU, self.TestRemove, id=503)
- self.Bind(wx.EVT_MENU, self.TestRemove2, id=505)
- self.Bind(wx.EVT_MENU, self.TestInsert, id=507)
- self.Bind(wx.EVT_MENU, self.TestInsert, id=508)
-
- wx.GetApp().Bind(wx.EVT_UPDATE_UI, self.TestUpdateUI, id=506)
-
- # Methods
-
- def OnMenuHighlight(self, event):
- # Show how to get menu item imfo from this event handler
- id = event.GetMenuId()
- item = self.GetMenuBar().FindItemById(id)
- text = item.GetText()
- help = item.GetHelp()
-
- #print text, help
- # but in this case just call Skip so the default is done
- event.Skip()
-
-
- def Menu101(self, event):
- self.log.write('Welcome to Mercury\n')
-
- def Menu102(self, event):
- self.log.write('Welcome to Venus\n')
-
- def Menu103(self, event):
- self.log.write('Welcome to the Earth\n')
-
- def CloseWindow(self, event):
- self.Close()
-
- def Menu201(self, event):
- self.log.write('Chemical element number 1\n')
-
- def Menu202(self, event):
- self.log.write('Chemical element number 2\n')
-
- def Menu2031(self, event):
- self.log.write('Element number 57\n')
-
- def Menu2032(self, event):
- self.log.write('Element number 58\n')
-
- def Menu2033(self, event):
- self.log.write('Element number 59\n')
-
- def Menu301To303(self, event):
- id = event.GetId()
- self.log.write('Event id: %d\n' % id)
-
- def Menu304(self, event):
- self.log.write('Not yet available\n')
-
- def Menu305(self, event):
- self.log.write('Still vapour\n')
-
- def Menu401To403(self, event):
- self.log.write('From a EVT_MENU_RANGE event\n')
-
- def Menu500(self, event):
- self.log.write('Have a happy day!\n')
-
- def Menu501(self, event):
- self.log.write('Look in the code how the shortcut has been realized\n')
-
- def Menu502(self, event):
- self.log.write('Hello from Jean-Michel\n')
-
-
- def TestRemove(self, evt):
- mb = self.GetMenuBar()
- submenuItem = mb.FindItemById(601)
-
- if not submenuItem:
- return
-
- submenu = submenuItem.GetMenu()
- menu = submenu.GetParent()
-
- # This works
- #menu.Remove(504)
-
- # this also works
- menu.RemoveItem(mb.FindItemById(504))
-
- # This doesn't work, as expected since submenuItem is not on menu
- #menu.RemoveItem(submenuItem)
-
-
- def TestRemove2(self, evt):
- mb = self.GetMenuBar()
- mb.Remove(4)
-
-
- def TestUpdateUI(self, evt):
- text = time.ctime()
- evt.SetText(text)
-
-
- def TestInsert(self, evt):
- theID = 508
- # get the menu
- mb = self.GetMenuBar()
- menuItem = mb.FindItemById(theID)
- menu = menuItem.GetMenu()
-
- # figure out the position to insert at
- pos = 0
-
- for i in menu.GetMenuItems():
- if i.GetId() == theID:
- break
-
- pos += 1
-
- # now insert the new item
- ID = wx.NewId()
- ##menu.Insert(pos, ID, "NewItem " + str(ID))
- item = wx.MenuItem(menu)
- item.SetId(ID)
- item.SetText("NewItem " + str(ID))
- menu.InsertItem(pos, item)
-
-
-#-------------------------------------------------------------------
-
-wx.RegisterId(10000)
-
-def runTest(frame, nb, log):
- win = MyFrame(frame, -1, log)
- frame.otherWin = win
- win.Show(True)
-
-
-#-------------------------------------------------------------------
-
-
-overview = """\
-A demo of using wxMenuBar and wxMenu in various ways.
-
-A menu is a popup (or pull down) list of items, one of which may be selected
-before the menu goes away (clicking elsewhere dismisses the menu). Menus may be
-used to construct either menu bars or popup menus.
-
-A menu item has an integer ID associated with it which can be used to identify
-the selection, or to change the menu item in some way. A menu item with a special
-identifier -1 is a separator item and doesn't have an associated command but just
-makes a separator line appear in the menu.
-
-Menu items may be either normal items, check items or radio items. Normal items
-don't have any special properties while the check items have a boolean flag associated
-to them and they show a checkmark in the menu when the flag is set. wxWindows
-automatically toggles the flag value when the item is clicked and its value may
-be retrieved using either IsChecked method of wxMenu or wxMenuBar itself or by
-using wxEvent.IsChecked when you get the menu notification for the item in question.
-
-The radio items are similar to the check items except that all the other items
-in the same radio group are unchecked when a radio item is checked. The radio group
-is formed by a contiguous range of radio items, i.e. it starts at the first item of
-this kind and ends with the first item of a different kind (or the end of the menu).
-Notice that because the radio groups are defined in terms of the item positions
-inserting or removing the items in the menu containing the radio items risks to not
-work correctly. Finally note that the radio items are only supported under Windows
-and GTK+ currently.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- dlg = wx.MessageDialog(frame, 'Hello from Python and wxPython!',
- 'A Message Box', wx.OK | wx.ICON_INFORMATION)
- #wxYES_NO | wxNO_DEFAULT | wxCANCEL | wxICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-This class represents a dialog that shows a single or multi-line message, with a
-choice of OK, Yes, No and Cancel buttons.
-
-Additionally, various style flags can determine whether an icon is displayed,
-and, if so, what kind.
-
-The dialog can be modal or not; of modal, the user's response is in the return
-code of ShowModal(). If not, the response can be taken from GetReturnCode() (inherited
-from the wxDialog super class). If not modal and the return code is required, it
-must be retrieved before the dialog is destroyed.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-#----------------------------------------------------------------------
-# Name: wxMimeTypesManager
-# Purpose: Demonstrate use of wx.MimeTypesManager, wx.FileType
-#
-# Author: Jeff Grimmett (grimmtoo@softhome.net), adapted from original
-# .wdr-derived demo
-#
-# Created: 12/31/03
-# RCS-ID: $Id$
-# Copyright:
-# Licence: wxWindows license
-#----------------------------------------------------------------------
-#
-
-
-import pprint
-import wx
-import images
-
-#----------------------------------------------------------------------------
-
-# A convenient wrapper around wx.TextCtrl to give it a spiffy label.
-class ExtStr(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent, -1)
- sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, 'Extension'), wx.HORIZONTAL)
- self.ctl = wx.TextCtrl(self, -1, value="wav", style = wx.TE_PROCESS_ENTER )
- sizer.Add(self.ctl, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 3)
- self.Enable(True)
-
- self.SetSizer(sizer)
- sizer.Fit(self)
-
- def Enable(self, value):
- self.ctl.Enable(value)
-
- def SetValue(self, value):
- self.ctl.SetValue(value)
-
- def GetValue(self):
- return(self.ctl.GetValue())
-
-
-class MimeTypesDemoPanel(wx.Panel):
- def __init__(self, parent, log):
-
- self.log = log
-
- wx.Panel.__init__(self, parent, -1)
-
- # Contains everything
- tsizer = wx.BoxSizer(wx.VERTICAL)
-
- # Contains upper controls
- usizer = wx.BoxSizer(wx.HORIZONTAL)
-
- # A little fancy stuff to make things align right.
- self.ext = ExtStr(self)
- usizer.Add(self.ext, 0, wx.ALL | wx.ALIGN_TOP, 4)
- self.ext.Bind(wx.EVT_TEXT_ENTER, self.OnLookup)
-
- # Select how to look it up
- self.how = wx.RadioBox(
- self, -1, "Lookup method", choices=['By extension', 'By MIME type'],
- majorDimension=2, style=wx.RA_SPECIFY_COLS
- )
- usizer.Add(self.how, 0, wx.ALL | wx.ALIGN_TOP, 4)
- self.how.SetSelection(0)
-
- # Trigger a lookup (hitting ENTER in the text ctrl will do the same thing)
- self.go = wx.Button(self, -1, "Go get it!")
- usizer.Add(self.go, 0, wx.ALL | wx.ALIGN_CENTER, 4)
- self.Bind(wx.EVT_BUTTON, self.OnLookup, self.go)
-
- # StaticBox with larger label than usual
- lbox = wx.StaticBox(self, -1, 'wx.FileType')
- lbox.SetFont(
- wx.Font(
- self.GetFont().GetPointSize() * 2,
- self.GetFont().GetFamily(),
- self.GetFont().GetStyle(),
- wx.BOLD
- ))
-
- lsizer = wx.StaticBoxSizer(lbox, wx.HORIZONTAL)
-
- # Contains the wx.FileType info
- llsizer = wx.GridBagSizer(2, 2)
- llsizer.AddGrowableCol(2)
-
- # This will be used for all of the labels that follow (bold label)
- bfont = wx.Font(
- self.GetFont().GetPointSize(),
- self.GetFont().GetFamily(),
- self.GetFont().GetStyle(),
- wx.BOLD
- )
-
- #------- Icon info
-
- t = wx.StaticText(self, -1, 'GetIconInfo: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (0, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.icon = wx.StaticBitmap(self, -1, images.getNoIconBitmap())
- llsizer.Add(self.icon, (0, 1), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.iconsource = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
- llsizer.Add(self.iconsource, (0, 2), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.iconoffset = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
- llsizer.Add(self.iconoffset, (0, 3), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- #------- MIME Type
-
- t = wx.StaticText(self, -1, 'GetMimeType: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (1, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.mimetype = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
- llsizer.Add(self.mimetype, (1, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- #------- MIME Types
-
- t = wx.StaticText(self, -1, 'GetMimeTypes: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (2, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.mimetypes = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
- llsizer.Add(self.mimetypes, (2, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- #------- Extensions
-
- t = wx.StaticText(self, -1, 'GetExtensions: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (3, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.extensions = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
- llsizer.Add(self.extensions, (3, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- #------- Description
-
- t = wx.StaticText(self, -1, 'GetDescription: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (4, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.description = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY)
- llsizer.Add(self.description, (4, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- #------- Open command
-
- t = wx.StaticText(self, -1, 'GetOpenCommand: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (5, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.opencommand = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
- llsizer.Add(self.opencommand, (5, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- #------- Print command
-
- t = wx.StaticText(self, -1, 'GetPrintCommand: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (6, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.printcommand = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY )
- llsizer.Add(self.printcommand, (6, 1), (1, 3), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- #------- All commands
-
- t = wx.StaticText(self, -1, 'GetAllCommands: ', style = wx.ALIGN_RIGHT )
- t.SetFont(bfont)
- llsizer.Add(t, (7, 0), (1, 1), wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 2)
-
- self.allcommands = wx.TextCtrl(self, -1, value="", style = wx.TE_READONLY | wx.TE_DONTWRAP | wx.TE_MULTILINE )
-
- # Set the default height to be smaller than normal (for
- # multi-line) so the sizer can then expand it to whatever
- # space is available
- self.allcommands.SetSize((-1, 20))
-
- llsizer.Add(self.allcommands, (7, 1), (1, 3), wx.ALL | wx.GROW | wx.ALIGN_CENTER, 2)
-
- # Tell the sizer to expand this row as needed
- llsizer.AddGrowableRow(7)
-
- #----------------------------------------------------------------------------
-
- lrsizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, 'Known MIME types'), wx.HORIZONTAL)
-
- #------- List box with known MIME types
- self.mimelist = wx.ListBox(self, -1, choices=[], style = wx.LB_SINGLE | wx.LB_SORT)
- lrsizer.Add(self.mimelist, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
- self.Bind(wx.EVT_LISTBOX, self.OnListbox, self.mimelist)
-
- #----------------------------------------------------------------------------
-
- lsizer.Add(llsizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
- lsizer.Add(lrsizer, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
-
- #----------------------------------------------------------------------------
-
- tsizer.Add(usizer, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
- tsizer.Add(lsizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 4)
-
- #----------------------------------------------------------------------------
-
- self.SetSizer(tsizer)
- tsizer.Fit(self)
-
- # Populate the Known MIME types list with what is in the database
- mtypes = wx.TheMimeTypesManager.EnumAllFileTypes()
- for mt in mtypes:
- self.mimelist.Append(mt)
-
- # Do a lookup of *.wav for a starting position
- self.OnLookup()
-
- # Grab the selection from the listbox, push that into
- # the text box at top, select 'MIME', and then look it up.
- def OnListbox(self, event):
- mimetype = event.GetString()
- self.ext.SetValue(mimetype)
- self.how.SetSelection(1)
- self.OnLookup()
-
- # Look up a given file extension or MIME type.
- def OnLookup(self, event=None):
- txt = self.ext.GetValue()
-
- # For MIME lookups
- if self.how.GetSelection() == 1:
- fileType = wx.TheMimeTypesManager.GetFileTypeFromMimeType(txt)
- msg = "Mime type"
-
- # Select the entered value in the list
- if fileType:
- if self.mimelist.FindString(txt) != -1:
- self.mimelist.SetSelection(self.mimelist.FindString(txt))
-
- # Must be an extension lookup
- else:
- fileType = wx.TheMimeTypesManager.GetFileTypeFromExtension(txt)
- msg = "File extension"
-
- # Select the entered value in the list
- if fileType:
- if self.mimelist.FindString(str(fileType.GetMimeType())) != -1:
- # Using CallAfter to ensure that GUI is ready before trying to
- # select it (otherwise, it's selected but not visible)
- wx.CallAfter(self.mimelist.SetSelection, self.mimelist.FindString(str(fileType.GetMimeType())))
-
-
- if fileType is None:
- wx.MessageBox(msg + " not found.", "Oops!")
- else:
- self.Update(fileType)
-
- # Populate the wx.FileType fields with actual values.
- def Update(self, ft):
-
- #------- Icon info
- info = ft.GetIconInfo()
-
- if info is None:
- bmp = images.getNoIconBitmap()
- self.icon.SetBitmap(bmp)
- self.iconsource.SetValue("")
- self.iconoffset.SetValue("")
- else:
- icon, file, idx = info
- if icon.Ok():
- self.icon.SetIcon(icon)
- else:
- bmp = images.getNoIconBitmap()
- self.icon.SetBitmap(bmp)
- self.iconsource.SetValue(file)
- self.iconoffset.SetValue(str(idx))
-
- #------- MIME type
- self.mimetype.SetValue(str(ft.GetMimeType()))
- #------- MIME types
- self.mimetypes.SetValue(str(ft.GetMimeTypes()))
- #------- Associated extensions
- self.extensions.SetValue(str(ft.GetExtensions()))
- #------- Description of file type
- self.description.SetValue(str(ft.GetDescription()))
-
- #------- Prep a fake command line command
- extList = ft.GetExtensions()
-
- if extList:
- ext = extList[0]
- if ext[0] == ".": ext = ext[1:]
- else:
- ext = ""
-
- filename = "SPAM" + "." + ext
- mime = ft.GetMimeType() or ""
-
- #------- OPEN command
- cmd = ft.GetOpenCommand(filename, mime)
- self.opencommand.SetValue(str(cmd))
-
- #------- PRINT command
- cmd = ft.GetPrintCommand(filename, mime)
- self.printcommand.SetValue(str(cmd))
-
- #------- All commands
- all = ft.GetAllCommands(filename, mime)
-
- if all is None:
- self.allcommands.SetValue("")
- else:
- verbs, commands = all
- text = pprint.pformat(map(None, verbs, commands))
- self.allcommands.SetValue(text)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = MimeTypesDemoPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-overview = """\
-
-The <b>wx.MimeTypesManager</b> class allows the application to retrieve the
-information about all known MIME types from a system-specific location and the
-filename extensions to the MIME types and vice versa. After initialization the
-methods <b>GetFileTypeFromMimeType()</b> and <b>GetFileTypeFromExtension()</b>
-may be called: they will return a <b>wx.FileType</b> object which may be further
-queried for file description, icon and other attributes.
-
-A global instance of <b>wx.MimeTypesManager</b> is always available as
-<b>wx.TheMimeTypesManager</b>. It is recommended to use this instance instead
-of creating your own because gathering MIME information may take quite a long
-on Unix systems.
-
-This demo shows how to use wx.TheMimeTypesManager to list all known MIME types
-and retrieve that information as a wx.FileType from either an extension or
-MIME type.
-
-For further information please consult the wxWindows documentation for
-<b>wx.MimeTypesManager</b> and <b>wx.FileType</b>.
-
-"""
-
-#----------------------------------------------------------------------
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-class MyMiniFrame(wx.MiniFrame):
- def __init__(
- self, parent, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
- style=wx.DEFAULT_FRAME_STYLE
- ):
-
- wx.MiniFrame.__init__(self, parent, -1, title, pos, size, style)
- panel = wx.Panel(self, -1)
-
- button = wx.Button(panel, -1, "Close Me")
- button.SetPosition((15, 15))
- self.Bind(wx.EVT_BUTTON, self.OnCloseMe, button)
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
- def OnCloseMe(self, event):
- self.Close(True)
-
- def OnCloseWindow(self, event):
- print "OnCloseWindow"
- self.Destroy()
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = MyMiniFrame(frame, "This is a wxMiniFrame",
- #pos=(250,250), size=(200,200),
- style=wx.DEFAULT_FRAME_STYLE | wx.TINY_CAPTION_HORIZ)
- win.SetSize((200, 200))
- win.CenterOnParent(wx.BOTH)
- frame.otherWin = win
- win.Show(True)
-
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-A miniframe is a frame with a small title bar. It is suitable for floating
-toolbars that must not take up too much screen area. In other respects, it's the
-same as a wxFrame.
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wx renamer needs to be applied to multisash lib.
-# o There appears to be a problem with the image that
-# the library is trying to use for the alternate cursor
-#
-# 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o renamer issue shelved.
-#
-# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxMultiSash -> MultiSash
-#
-
-import wx
-import wx.lib.multisash as sash
-import wx.stc as stc
-
-#---------------------------------------------------------------------------
-
-sampleText="""\
-You can drag the little tab on the vertical sash left to create another view,
-or you can drag the tab on the horizontal sash to the top to create another
-horizontal view.
-
-The red blocks on the sashes will destroy the view (bottom,left) this block
-belongs to.
-
-A yellow rectangle also highlights the current selected view.
-
-By calling GetSaveData on the multiSash control the control will return its
-contents and the positions of each sash as a dictionary.
-Calling SetSaveData with such a dictionary will restore the control to the
-state it was in when it was saved.
-
-If the class, that is used as a view, has GetSaveData/SetSaveData implemented,
-these will also be called to save/restore their state. Any object can be
-returned by GetSaveData, as it is just another object in the dictionary.
-"""
-
-#---------------------------------------------------------------------------
-
-class TestWindow(stc.StyledTextCtrl):
-
- # shared document reference
- doc = None
-
- def __init__(self, parent):
- stc.StyledTextCtrl.__init__(self, parent, -1, style=wx.NO_BORDER)
- self.SetMarginWidth(1,0)
-
- if wx.Platform == '__WXMSW__':
- fSize = 10
- else:
- fSize = 12
-
- self.StyleSetFont(
- stc.STC_STYLE_DEFAULT,
- wx.Font(fSize, wx.MODERN, wx.NORMAL, wx.NORMAL)
- )
-
- if self.doc:
- self.SetDocPointer(self.doc)
- else:
- self.SetText(sampleText)
- TestWindow.doc = self.GetDocPointer()
-
-
- def SutdownDemo(self):
- # Reset doc reference in case this demo is run again
- TestWindow.doc = None
-
-
-#---------------------------------------------------------------------------
-
-
-def runTest(frame, nb, log):
- multi = sash.MultiSash(nb, -1, pos = (0,0), size = (640,480))
-
- # Use this method to set the default class that will be created when
- # a new sash is created. The class's constructor needs 1 parameter
- # which is the parent of the window
- multi.SetDefaultChildClass(TestWindow)
-
- return multi
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>MultiSash</center></h2>
-
-MultiSash allows the user to split a window any number of times
-either horizontally or vertically, and to close the split off windows
-when desired.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wx renamer not applied to lib.
-#
-# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxMultipleChoiceDialog -> MultipleChoiceDialog
-#
-
-import wx
-import wx.lib.dialogs
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- lst = [ 'apple', 'pear', 'banana', 'coconut', 'orange',
- 'etc', 'etc..', 'etc...' ]
-
- dlg = wx.lib.dialogs.MultipleChoiceDialog(
- frame,
- "Pick some from\n this list\nblah blah...",
- "m.s.d.", lst)
-
- if (dlg.ShowModal() == wx.ID_OK):
- print "Selection:", dlg.GetValue(), " -> ", dlg.GetValueString()
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-<html>
-<body>
-
-This is a Python implementation of a dialog that is not yet implemented in wxWindows
-proper, so don't let the wxWindows documentation mislead you.
-
-<p><code><b>MultipleChoiceDialog</b>(self, parent, msg, title, lst,
-pos = wx.wxDefaultPosition, size = (200,200), style = wx.wxDEFAULT_DIALOG_STYLE)
-</code>
-
-<dl>
-<dt><code>parent</code>
-<dd>The parent window
-
-<dt><code>msg</code>
-<dd>The message that will be displayed above the list
-
-<dt><code>title</code>
-<dd>The text that will appear on the title bar
-
-<dt><code>lst</code>
-<dd>A Python list of choices that will appear in the dialog.
-
-<dt><code>pos</code>
-<dd>The position of the dialog
-
-<dt><code>size</code>
-<dd>The size of the dialog
-
-<dt><code>style</code>
-<dd>The style for the dialog. Only styles normally available to wxDialog are
-available.
-
-</dl>
-
-<b><font size=+1><code>Methods</code></font></b>
-
-<dl>
-<dt><code>GetValue</code>
-<dd>Returns a tuple containing the indices of the selected items
-
-<dt><code>GetValueString</code>
-<dd>Returns a tuple containing the text of the selected items
-
-</dl>
-
-Additionally, MultipleChoiceDialog.lbox is a standard wx.ListBox which supports all
-methods applicable to that class.
-
-</body>
-</html>
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import sys
-
-import wx
-
-import ColorPanel
-import GridSimple
-import wxListCtrl
-import wxScrolledWindow
-import images
-
-#----------------------------------------------------------------------------
-
-class TestNB(wx.Notebook):
- def __init__(self, parent, id, log):
- wx.Notebook.__init__(self, parent, id, style=
- #wxNB_TOP
- wx.NB_BOTTOM
- #wxNB_LEFT
- #wxNB_RIGHT
- )
- self.log = log
-
- win = self.makeColorPanel(wx.BLUE)
- self.AddPage(win, "Blue")
- st = wx.StaticText(win.win, -1,
- "You can put nearly any type of window here,\n"
- "and if the platform supports it then the\n"
- "tabs can be on any side of the notebook.",
- (10, 10))
-
- st.SetForegroundColour(wx.WHITE)
- st.SetBackgroundColour(wx.BLUE)
-
- # Show how to put an image on one of the notebook tabs,
- # first make the image list:
- il = wx.ImageList(16, 16)
- idx1 = il.Add(images.getSmilesBitmap())
- self.AssignImageList(il)
-
- # now put an image on the first tab we just created:
- self.SetPageImage(0, idx1)
-
-
- win = self.makeColorPanel(wx.RED)
- self.AddPage(win, "Red")
-
- win = wxScrolledWindow.MyCanvas(self)
- self.AddPage(win, 'ScrolledWindow')
-
- win = self.makeColorPanel(wx.GREEN)
- self.AddPage(win, "Green")
-
- win = GridSimple.SimpleGrid(self, log)
- self.AddPage(win, "Grid")
-
- win = wxListCtrl.TestListCtrlPanel(self, log)
- self.AddPage(win, 'List')
-
- win = self.makeColorPanel(wx.CYAN)
- self.AddPage(win, "Cyan")
-
-# win = self.makeColorPanel(wxWHITE)
-# self.AddPage(win, "White")
-
-# win = self.makeColorPanel(wxBLACK)
-# self.AddPage(win, "Black")
-
- win = self.makeColorPanel(wx.NamedColour('MIDNIGHT BLUE'))
- self.AddPage(win, "MIDNIGHT BLUE")
-
- win = self.makeColorPanel(wx.NamedColour('INDIAN RED'))
- self.AddPage(win, "INDIAN RED")
-
- self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
- self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
-
-
- def makeColorPanel(self, color):
- p = wx.Panel(self, -1)
- win = ColorPanel.ColoredPanel(p, color)
- p.win = win
-
- def OnCPSize(evt, win=win):
- win.SetSize(evt.GetSize())
-
- p.Bind(wx.EVT_SIZE, OnCPSize)
- return p
-
- def OnPageChanged(self, event):
- old = event.GetOldSelection()
- new = event.GetSelection()
- sel = self.GetSelection()
- self.log.write('OnPageChanged, old:%d, new:%d, sel:%d\n' % (old, new, sel))
- event.Skip()
-
- def OnPageChanging(self, event):
- old = event.GetOldSelection()
- new = event.GetSelection()
- sel = self.GetSelection()
- self.log.write('OnPageChanging, old:%d, new:%d, sel:%d\n' % (old, new, sel))
- event.Skip()
-
-#----------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- testWin = TestNB(nb, -1, log)
- return testWin
-
-#----------------------------------------------------------------------------
-
-
-overview = """\
-<html><body>
-<h2>wxNotebook</h2>
-<p>
-This class represents a notebook control, which manages multiple
-windows with associated tabs.
-<p>
-To use the class, create a wxNotebook object and call AddPage or
-InsertPage, passing a window to be used as the page. Do not explicitly
-delete the window for a page that is currently managed by wxNotebook.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
-
-
-
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o OGL's busted bigtime. Can't even use OGLInitialize() without a
-# program error on w2k.
-#
-
-import wx
-import wx.ogl as ogl
-
-import images
-
-##wx.Trap()
-
-#----------------------------------------------------------------------
-# This creates some pens and brushes that the OGL library uses.
-
-ogl.OGLInitialize()
-
-#----------------------------------------------------------------------
-
-class DiamondShape(ogl.PolygonShape):
- def __init__(self, w=0.0, h=0.0):
- ogl.PolygonShape.__init__(self)
- if w == 0.0:
- w = 60.0
- if h == 0.0:
- h = 60.0
-
- # Either ogl.RealPoints or 2-tuples of floats works.
-
- #points = [ ogl.RealPoint(0.0, -h/2.0),
- # ogl.RealPoint(w/2.0, 0.0),
- # ogl.RealPoint(0.0, h/2.0),
- # ogl.RealPoint(-w/2.0, 0.0),
- # ]
- points = [ (0.0, -h/2.0),
- (w/2.0, 0.0),
- (0.0, h/2.0),
- (-w/2.0, 0.0),
- ]
-
- self.Create(points)
-
-
-#----------------------------------------------------------------------
-
-class RoundedRectangleShape(ogl.RectangleShape):
- def __init__(self, w=0.0, h=0.0):
- ogl.RectangleShape.__init__(self, w, h)
- self.SetCornerRadius(-0.3)
-
-
-#----------------------------------------------------------------------
-
-class DividedShape(ogl.DividedShape):
- def __init__(self, width, height, canvas):
- ogl.DividedShape.__init__(self, width, height)
-
- region1 = ogl.ShapeRegion()
- region1.SetText('DividedShape')
- region1.SetProportions(0.0, 0.2)
- region1.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ)
- self.AddRegion(region1)
-
- region2 = ogl.ShapeRegion()
- region2.SetText('This is Region number two.')
- region2.SetProportions(0.0, 0.3)
- region2.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ|ogl.FORMAT_CENTRE_VERT)
- self.AddRegion(region2)
-
- region3 = ogl.ShapeRegion()
- region3.SetText('Region 3\nwith embedded\nline breaks')
- region3.SetProportions(0.0, 0.5)
- region3.SetFormatMode(ogl.FORMAT_NONE)
- self.AddRegion(region3)
-
- self.SetRegionSizes()
- self.ReformatRegions(canvas)
-
-
- def ReformatRegions(self, canvas=None):
- rnum = 0
-
- if canvas is None:
- canvas = self.GetCanvas()
-
- dc = wx.ClientDC(canvas) # used for measuring
-
- for region in self.GetRegions():
- text = region.GetText()
- self.FormatText(dc, text, rnum)
- rnum += 1
-
-
- def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
- print "***", self
- self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
- self.SetRegionSizes()
- self.ReformatRegions()
- self.GetCanvas().Refresh()
-
-
-#----------------------------------------------------------------------
-
-class MyEvtHandler(ogl.ShapeEvtHandler):
- def __init__(self, log, frame):
- ogl.ShapeEvtHandler.__init__(self)
- self.log = log
- self.statbarFrame = frame
-
- def UpdateStatusBar(self, shape):
- x,y = shape.GetX(), shape.GetY()
- width, height = shape.GetBoundingBoxMax()
- self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" %
- (x, y, width, height))
-
-
- def OnLeftClick(self, x, y, keys = 0, attachment = 0):
- shape = self.GetShape()
- print shape.__class__, shape.GetClassName()
- canvas = shape.GetCanvas()
- dc = wx.ClientDC(canvas)
- canvas.PrepareDC(dc)
-
- if shape.Selected():
- shape.Select(False, dc)
- canvas.Redraw(dc)
- else:
- redraw = False
- shapeList = canvas.GetDiagram().GetShapeList()
- toUnselect = []
-
- for s in shapeList:
- if s.Selected():
- # If we unselect it now then some of the objects in
- # shapeList will become invalid (the control points are
- # shapes too!) and bad things will happen...
- toUnselect.append(s)
-
- shape.Select(True, dc)
-
- if toUnselect:
- for s in toUnselect:
- s.Select(False, dc)
-
- canvas.Redraw(dc)
-
- self.UpdateStatusBar(shape)
-
-
- def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
- shape = self.GetShape()
- self.base_OnEndDragLeft(x, y, keys, attachment)
-
- if not shape.Selected():
- self.OnLeftClick(x, y, keys, attachment)
-
- self.UpdateStatusBar(shape)
-
-
- def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
- self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
- self.UpdateStatusBar(self.GetShape())
-
-
- def OnMovePost(self, dc, x, y, oldX, oldY, display):
- self.base_OnMovePost(dc, x, y, oldX, oldY, display)
- self.UpdateStatusBar(self.GetShape())
-
-
- def OnRightClick(self, *dontcare):
- self.log.WriteText("%s\n" % self.GetShape())
-
-
-#----------------------------------------------------------------------
-
-class TestWindow(ogl.ShapeCanvas):
- def __init__(self, parent, log, frame):
- ogl.ShapeCanvas.__init__(self, parent)
-
- maxWidth = 1000
- maxHeight = 1000
- self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
-
- self.log = log
- self.frame = frame
- self.SetBackgroundColour("LIGHT BLUE") #wx.WHITE)
- self.diagram = ogl.Diagram()
- self.SetDiagram(self.diagram)
- self.diagram.SetCanvas(self)
- self.shapes = []
- self.save_gdi = []
-
- rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID)
- dsBrush = wx.Brush("WHEAT", wx.SOLID)
-
- self.MyAddShape(
- ogl.CircleShape(80),
- 100, 100, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle"
- )
-
- self.MyAddShape(
- ogl.RectangleShape(85, 50),
- 305, 60, wx.BLACK_PEN, wx.LIGHT_GREY_BRUSH, "Rectangle"
- )
-
- ds = self.MyAddShape(
- DividedShape(140, 150, self),
- 495, 145, wx.BLACK_PEN, dsBrush, ''
- )
-
- self.MyAddShape(
- DiamondShape(90, 90),
- 345, 235, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon"
- )
-
- self.MyAddShape(
- RoundedRectangleShape(95,70),
- 140, 255, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect"
- )
-
- bmp = images.getTest2Bitmap()
- mask = wx.MaskColour(bmp, wx.BLUE)
- bmp.SetMask(mask)
-
- s = ogl.BitmapShape()
- s.SetBitmap(bmp)
- self.MyAddShape(s, 225, 150, None, None, "Bitmap")
-
- dc = wx.ClientDC(self)
- self.PrepareDC(dc)
-
- for x in range(len(self.shapes)):
- fromShape = self.shapes[x]
- if x+1 == len(self.shapes):
- toShape = self.shapes[0]
- else:
- toShape = self.shapes[x+1]
-
- line = ogl.LineShape()
- line.SetCanvas(self)
- line.SetPen(wx.BLACK_PEN)
- line.SetBrush(wx.BLACK_BRUSH)
- line.AddArrow(ogl.ARROW_ARROW)
- line.MakeLineControlPoints(2)
- fromShape.AddLine(line, toShape)
- self.diagram.AddShape(line)
- line.Show(True)
-
- # for some reason, the shapes have to be moved for the line to show up...
- fromShape.Move(dc, fromShape.GetX(), fromShape.GetY())
-
- wx.EVT_WINDOW_DESTROY(self, self.OnDestroy)
-
-
- def MyAddShape(self, shape, x, y, pen, brush, text):
- shape.SetDraggable(True, True)
- shape.SetCanvas(self)
- shape.SetX(x)
- shape.SetY(y)
- if pen: shape.SetPen(pen)
- if brush: shape.SetBrush(brush)
- if text: shape.AddText(text)
- #shape.SetShadowMode(ogl.SHADOW_RIGHT)
- self.diagram.AddShape(shape)
- shape.Show(True)
-
- evthandler = MyEvtHandler(self.log, self.frame)
- evthandler.SetShape(shape)
- evthandler.SetPreviousHandler(shape.GetEventHandler())
- shape.SetEventHandler(evthandler)
-
- self.shapes.append(shape)
- return shape
-
-
- def OnDestroy(self, evt):
- # Do some cleanup
- for shape in self.diagram.GetShapeList():
- if shape.GetParent() == None:
- shape.SetCanvas(None)
- shape.Destroy()
-
- self.diagram.Destroy()
-
-
- def OnBeginDragLeft(self, x, y, keys):
- self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
-
- def OnEndDragLeft(self, x, y, keys):
- self.log.write("OnEndDragLeft: %s, %s, %s\n" % (x, y, keys))
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- # This creates some pens and brushes that the OGL library uses.
- # It should be called after the app object has been created, but
- # before OGL is used.
- ogl.OGLInitialize()
-
- win = TestWindow(nb, log, frame)
- return win
-
-#----------------------------------------------------------------------
-
-class __Cleanup:
- cleanup = ogl.OGLCleanUp
- def __del__(self):
- self.cleanup()
-
-# when this module gets cleaned up then wxOGLCleanUp() will get called
-__cu = __Cleanup()
-
-
-overview = """\
-The Object Graphics Library is a library supporting the creation and
-manipulation of simple and complex graphic images on a canvas.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- data = wx.PageSetupDialogData()
- data.SetMarginTopLeft( (15, 15) )
- data.SetMarginBottomRight( (15, 15) )
- #data.SetDefaultMinMargins(True)
- data.SetPaperId(wx.PAPER_LETTER)
-
- dlg = wx.PageSetupDialog(frame, data)
-
- if dlg.ShowModal() == wx.ID_OK:
- data = dlg.GetPageSetupData()
- tl = data.GetMarginTopLeft()
- br = data.GetMarginBottomRight()
- log.WriteText('Margins are: %s %s\n' % (str(tl), str(br)))
-
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class represents the page setup common dialog. The page setup dialog is standard
-from Windows 95 on, replacing the print setup dialog (which is retained in Windows
-and wxWindows for backward compatibility). On Windows 95 and NT 4.0 and above,
-the page setup dialog is native to the windowing system, otherwise it is emulated.
-
-The page setup dialog contains controls for paper size (A4, A5 etc.), orientation
-(landscape or portrait), and controls for setting left, top, right and bottom margin
-sizes in millimetres.
-
-When the dialog has been closed, you need to query the <code>wxPageSetupDialogData</code> object
-associated with the dialog.
-
-Note that the OK and Cancel buttons do not destroy the dialog; this must be done by
-the application. As with other dialogs, do not destroy the dialog until you are done
-with the data, and, conversely, do not use the wxPageSetupDialogData after the
-dialog is destroyed.
-
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxPlotCanvas must be updated with new draw mechanics (tuples) before
-# it can be used with 2.5.
-#
-
-import wx
-import wx.lib.wxPlotCanvas as plot
-
-import Numeric
-
-#---------------------------------------------------------------------------
-
-def _InitObjects():
- # 100 points sin function, plotted as green circles
- data1 = 2.*Numeric.pi*Numeric.arange(200)/200.
- data1.shape = (100, 2)
- data1[:,1] = Numeric.sin(data1[:,0])
- markers1 = plot.PolyMarker(data1, color='green', marker='circle',size=1)
-
- # 50 points cos function, plotted as red line
- data1 = 2.*Numeric.pi*Numeric.arange(100)/100.
- data1.shape = (50,2)
- data1[:,1] = Numeric.cos(data1[:,0])
- lines = plot.PolyLine(data1, color='red')
-
- # A few more points...
- pi = Numeric.pi
- markers2 = plot.PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.),
- (3.*pi/4., -1)], color='blue',
- fillcolor='green', marker='cross')
-
- return plot.PlotGraphics([markers1, lines, markers2])
-
-
-#---------------------------------------------------------------------------
-
-
-def runTest(frame, nb, log):
- win = plot.PlotCanvas(nb)
- win.draw(_InitObjects(),'automatic','automatic');
- return win
-
-overview = plot.__doc__
-
-#---------------------------------------------------------------------------
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Is it just me or are the graphics for the control not lining up right?
-#
-# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxPopupControl -> PopupControl
-#
-
-import wx
-import wx.lib.popupctl as pop
-import wx.calendar as cal
-
-class TestDateControl(pop.PopupControl):
- def __init__(self,*_args,**_kwargs):
- apply(pop.PopupControl.__init__,(self,) + _args,_kwargs)
-
- self.win = wx.Window(self,-1,pos = (0,0),style = 0)
- self.cal = cal.CalendarCtrl(self.win,-1,pos = (0,0))
-
- bz = self.cal.GetBestSize()
- self.win.SetSize(bz)
-
- # This method is needed to set the contents that will be displayed
- # in the popup
- self.SetPopupContent(self.win)
-
- # Event registration for date selection
- self.cal.Bind(cal.EVT_CALENDAR_DAY, self.OnCalSelected)
-
- # Method called when a day is selected in the calendar
- def OnCalSelected(self,evt):
- self.PopDown()
- date = self.cal.GetDate()
-
- # Format the date that was selected for the text part of the control
- self.SetValue('%02d/%02d/%04d' % (date.GetDay(),
- date.GetMonth()+1,
- date.GetYear()))
- evt.Skip()
-
- # Method overridden from PopupControl
- # This method is called just before the popup is displayed
- # Use this method to format any controls in the popup
- def FormatContent(self):
- # I parse the value in the text part to resemble the correct date in
- # the calendar control
- txtValue = self.GetValue()
- dmy = txtValue.split('/')
- didSet = False
-
- if len(dmy) == 3:
- date = self.cal.GetDate()
- d = int(dmy[0])
- m = int(dmy[1]) - 1
- y = int(dmy[2])
-
- if d > 0 and d < 31:
- if m >= 0 and m < 12:
- if y > 1000:
- self.cal.SetDate(wx.DateTimeFromDMY(d,m,y))
- didSet = True
-
- if not didSet:
- self.cal.SetDate(wx.DateTime_Today())
-
-
-#---------------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
- date = TestDateControl(self, -1, pos = (30,30), size = (100,22))
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-overview = """<html><body>
-<h2><center>PopupControl</center></h2>
-
-PopupControl is a class that can display a value and has a button
-that will popup another window similar to how a wxComboBox works. The
-popup window can contain whatever is needed to edit the value. This
-example uses a wxCalendarCtrl.
-
-<p>Currently a wxDialog is used for the popup. Eventually a
-wxPopupWindow should be used...
-
-</body></html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Some issues with the listbox example; I tried correcting
-# it but it's still not working the way it should. Commented
-# out for now but will be revisited.
-# o The math in determining the popup window's position is
-# a bit off.
-#
-
-import wx
-
-havePopupWindow = 1
-try:
- wx.PopupWindow
-except NameError:
- havePopupWindow = 0
- wx.PopupWindow = wx.PopupTransientWindow = wx.Window
-
-#---------------------------------------------------------------------------
-
-class TestPopup(wx.PopupWindow):
- """Adds a bit of text and mouse movement to the wxPopupWindow"""
- def __init__(self, parent, style):
- wx.PopupWindow.__init__(self, parent, style)
- self.SetBackgroundColour("CADET BLUE")
-
- st = wx.StaticText(self, -1,
- "This is a special kind of top level\n"
- "window that can be used for\n"
- "popup menus, combobox popups\n"
- "and such.\n\n"
- "Try positioning the demo near\n"
- "the bottom of the screen and \n"
- "hit the button again.\n\n"
- "In this demo this window can\n"
- "be dragged with the left button\n"
- "and closed with the right."
- ,
- pos=(10,10))
-
- sz = st.GetBestSize()
- self.SetSize( (sz.width+20, sz.height+20) )
-
- self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
- self.Bind(wx.EVT_MOTION, self.OnMouseMotion)
- self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
- self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
-
- st.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
- st.Bind(wx.EVT_MOTION, self.OnMouseMotion)
- st.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
- st.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
-
- def OnMouseLeftDown(self, evt):
- self.ldPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
- self.wPos = self.ClientToScreen((0,0))
- self.CaptureMouse()
-
- def OnMouseMotion(self, evt):
- if evt.Dragging() and evt.LeftIsDown():
- dPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
- nPos = (self.wPos.x + (dPos.x - self.ldPos.x),
- self.wPos.y + (dPos.y - self.ldPos.y))
- self.Move(nPos)
-
- def OnMouseLeftUp(self, evt):
- self.ReleaseMouse()
-
- def OnRightUp(self, evt):
- self.Show(False)
- self.Destroy()
-
-
-class TestTransientPopup(wx.PopupTransientWindow):
- """Adds a bit of text and mouse movement to the wxPopupWindow"""
- def __init__(self, parent, style, log):
- wx.PopupTransientWindow.__init__(self, parent, style)
- self.log = log
- panel = wx.Panel(self, -1)
- panel.SetBackgroundColour("#FFB6C1")
- st = wx.StaticText(panel, -1,
- "wxPopupTransientWindow is a\n"
- "wxPopupWindow which disappears\n"
- "automatically when the user\n"
- "clicks the mouse outside it or if it\n"
- "(or its first child) loses focus in \n"
- "any other way."
- ,
- pos=(10,10))
- sz = st.GetBestSize()
- panel.SetSize( (sz.width+20, sz.height+20) )
- self.SetSize(panel.GetSize())
-
- def ProcessLeftDown(self, evt):
- self.log.write("ProcessLeftDown\n")
- return False
-
- def OnDismiss(self):
- self.log.write("OnDismiss\n")
-
-
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- b = wx.Button(self, -1, "Show wxPopupWindow", (25, 50))
- self.Bind(wx.EVT_BUTTON, self.OnShowPopup, b)
-
- b = wx.Button(self, -1, "Show wxPopupTransientWindow", (25, 95))
- self.Bind(wx.EVT_BUTTON, self.OnShowPopupTransient, b)
-
- # This isn't working so well, not sure why. Commented out for
- # now.
-
-# b = wx.Button(self, -1, "Show wxPopupWindow with listbox", (25, 140))
-# self.Bind(wx.EVT_BUTTON, self.OnShowPopupListbox, b)
-
-
- def OnShowPopup(self, evt):
- win = TestPopup(self, wx.SIMPLE_BORDER)
-
- # Show the popup right below or above the button
- # depending on available screen space...
- btn = evt.GetEventObject()
- pos = btn.ClientToScreen( (0,0) )
- sz = btn.GetSize()
- win.Position(pos, (0, sz[1]))
-
- win.Show(True)
-
-
- def OnShowPopupTransient(self, evt):
- win = TestTransientPopup(self, wx.SIMPLE_BORDER, self.log)
-
- # Show the popup right below or above the button
- # depending on available screen space...
- btn = evt.GetEventObject()
- pos = btn.ClientToScreen( (0,0) )
- sz = btn.GetSize()
- win.Position(pos, (0, sz[1]))
-
- win.Popup()
-
-
- def OnShowPopupListbox(self, evt):
- win = TestPopupWithListbox(self, wx.NO_BORDER, self.log)
-
- # Show the popup right below or above the button
- # depending on available screen space...
- btn = evt.GetEventObject()
- pos = btn.ClientToScreen( (0,0) )
- sz = btn.GetSize()
- win.Position(pos, (0, sz[1]))
-
- win.Show(True)
-
-class TestPopupWithListbox(wx.PopupWindow):
- def __init__(self, parent, style, log):
- wx.PopupWindow.__init__(self, parent, style)
-
- import keyword
-
- self.lb = wx.ListBox(self, -1, choices = keyword.kwlist)
- #sz = self.lb.GetBestSize()
- self.SetSize((150, 75)) #sz)
- self.lb.SetSize(self.GetClientSize())
- self.lb.SetFocus()
- self.Bind(wx.EVT_LISTBOX, self.OnListBox)
- self.lb.Bind(wx.EVT_LEFT_DOWN, self.OnLeft)
-
- def OnLeft(self, evt):
- obj = evt.GetEventObject()
- print "OnLeft", obj
- print 'Selected: %s' % obj.GetStringSelection()
- obj.Show(False)
- evt.Skip()
-
- def OnListBox(self, evt):
- obj = evt.GetEventObject()
- print "OnListBox", obj
- print 'Selected: %s' % obj.GetString()
- evt.Skip()
-
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- if havePopupWindow:
- win = TestPanel(nb, log)
- return win
- else:
- dlg = wx.MessageDialog(
- frame, 'wxPopupWindow is not available on this platform.',
- 'Sorry', wx.OK | wx.ICON_INFORMATION
- )
-
- dlg.ShowModal()
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- data = wx.PrintDialogData()
-
- data.EnableSelection(True)
- data.EnablePrintToFile(True)
- data.EnablePageNumbers(True)
- data.SetMinPage(1)
- data.SetMaxPage(5)
- data.SetAllPages(True)
-
- dlg = wx.PrintDialog(frame, data)
-
- if dlg.ShowModal() == wx.ID_OK:
- data = dlg.GetPrintDialogData()
- log.WriteText('GetAllPages: %d\n' % data.GetAllPages())
-
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class represents the print and print setup common dialogs. You may obtain
-a wxPrinterDC device context from a successfully dismissed print dialog.
-
-User information is stored in a wxPrintDialogData object that is passed to the
-dialog at creation time, and it is filled in by the user. As with other dialogs,
-do not use this data once the dialog is dismissed, and do not destroy the dialog
-until you have everything you need from it.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, ID, log):
- wx.Panel.__init__(self, parent, ID)
- self.log = log
-
- self.process = None
- self.Bind(wx.EVT_IDLE, self.OnIdle)
-
- # We can either derive from wxProcess and override OnTerminate
- # or we can let wxProcess send this window an event that is
- # caught in the normal way...
- self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
-
-
- # Make the controls
- prompt = wx.StaticText(self, -1, 'Command line:')
- self.cmd = wx.TextCtrl(self, -1, 'python -u data/echo.py')
- self.exBtn = wx.Button(self, -1, 'Execute')
-
- self.out = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE|wx.TE_READONLY)
-
- self.inp = wx.TextCtrl(self, -1, '', style=wx.TE_PROCESS_ENTER)
- self.sndBtn = wx.Button(self, -1, 'Send')
- self.termBtn = wx.Button(self, -1, 'Close Stream')
- self.inp.Enable(False)
- self.sndBtn.Enable(False)
- self.termBtn.Enable(False)
-
- # Hook up the events
- self.Bind(wx.EVT_BUTTON, self.OnExecuteBtn, self.exBtn)
- self.Bind(wx.EVT_BUTTON, self.OnSendText, self.sndBtn)
- self.Bind(wx.EVT_BUTTON, self.OnCloseStream, self.termBtn)
- self.Bind(wx.EVT_TEXT_ENTER, self.OnSendText, self.inp)
-
-
- # Do the layout
- box1 = wx.BoxSizer(wx.HORIZONTAL)
- box1.Add(prompt, 0, wx.ALIGN_CENTER)
- box1.Add(self.cmd, 1, wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
- box1.Add(self.exBtn, 0)
-
- box2 = wx.BoxSizer(wx.HORIZONTAL)
- box2.Add(self.inp, 1, wx.ALIGN_CENTER)
- box2.Add(self.sndBtn, 0, wx.LEFT, 5)
- box2.Add(self.termBtn, 0, wx.LEFT, 5)
-
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(box1, 0, wx.EXPAND|wx.ALL, 10)
- sizer.Add(self.out, 1, wx.EXPAND|wx.ALL, 10)
- sizer.Add(box2, 0, wx.EXPAND|wx.ALL, 10)
-
- self.SetSizer(sizer)
- self.SetAutoLayout(True)
-
-
- def __del__(self):
- if self.process is not None:
- self.process.Detach()
- self.process.CloseOutput()
- self.process = None
-
-
- def OnExecuteBtn(self, evt):
- cmd = self.cmd.GetValue()
-
- self.process = wx.Process(self)
- self.process.Redirect();
- pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process)
- self.log.write('OnExecuteBtn: "%s" pid: %s\n' % (cmd, pid))
-
- self.inp.Enable(True)
- self.sndBtn.Enable(True)
- self.termBtn.Enable(True)
- self.cmd.Enable(False)
- self.exBtn.Enable(False)
- self.inp.SetFocus()
-
-
- def OnSendText(self, evt):
- text = self.inp.GetValue()
- self.inp.SetValue('')
- self.log.write('OnSendText: "%s"\n' % text)
- self.process.GetOutputStream().write(text + '\n')
- self.inp.SetFocus()
-
-
- def OnCloseStream(self, evt):
- self.log.write('OnCloseStream\n')
- #print "b4 CloseOutput"
- self.process.CloseOutput()
- #print "after CloseOutput"
-
- def OnIdle(self, evt):
- if self.process is not None:
- stream = self.process.GetInputStream()
-
- if stream.CanRead():
- text = stream.read()
- self.out.AppendText(text)
-
-
- def OnProcessEnded(self, evt):
- self.log.write('OnProcessEnded, pid:%s, exitCode: %s\n' %
- (evt.GetPid(), evt.GetExitCode()))
-
- stream = self.process.GetInputStream()
-
- if stream.CanRead():
- text = stream.read()
- self.out.AppendText(text)
-
- self.process.Destroy()
- self.process = None
- self.inp.Enable(False)
- self.sndBtn.Enable(False)
- self.termBtn.Enable(False)
- self.cmd.Enable(True)
- self.exBtn.Enable(True)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, -1, log)
- return win
-
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-<html><body>
-<h2>wxProcess</h2>
-
-wxProcess lets you get notified when an asyncronous child process
-started by wxExecute terminates, and also to get input/output streams
-for the child process's stdout, stderr and stdin.
-
-<p>
-This demo launches a simple python script that echos back on stdout
-lines that it reads from stdin. You can send text to the echo
-process' stdin by typing in the lower textctrl and clicking Send.
-
-<p>
-Clicking the Close Stream button will close the demo's end of the
-stdin pipe to the child process. In our case that will cause the
-child process to exit its main loop.
-
-</body><html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wx.ProgressDialog appears to be broken. No abort button
-# and it's not possible to dismiss it otherwise.
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- max = 20
-
- dlg = wx.ProgressDialog("Progress dialog example",
- "An informative message",
- maximum = max,
- parent=frame,
- style = wx.PD_CAN_ABORT | wx.PD_APP_MODAL)
-
- keepGoing = True
- count = 0
-
- while keepGoing and count < max:
- count = count + 1
- #print count
- wx.Sleep(1)
-
- if count == max / 2:
- keepGoing = dlg.Update(count, "Half-time!")
- else:
- keepGoing = dlg.Update(count)
-
- dlg.Destroy()
-
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class represents a dialog that shows a short message and a progress bar.
-Optionally, it can display an ABORT button
-
-This dialog indicates the progress of some event that takes a while to accomplish,
-usually, such as file copy progress, download progress, and so on. The display
-is <b>completely</b> under control of the program; you must update the dialog from
-within the program creating it.
-
-When the dialog closes, you must check to see if the user aborted the process or
-not, and act accordingly -- that is, if the PD_CAN_ABORT style flag is set.
-If not then you may progress blissfully onward.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 12/14/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated URL for SF link in overview.
-#
-# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxPyColorChooser -> PyColorChooser
-# o wxPyColourChooser -> PyColourChooser
-#
-
-import wx
-import wx.lib.colourchooser as cc
-
-#---------------------------------------------------------------
-
-class TestColourChooser(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- chooser = cc.PyColourChooser(self, -1)
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(chooser, 0, wx.ALL, 25)
-
- self.SetAutoLayout(True)
- self.SetSizer(sizer)
-
-#---------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestColourChooser(nb, log)
- return win
-
-#---------------------------------------------------------------
-
-overview = """
-The PyColourChooser component creates a colour chooser window
-that is similar to the Microsoft Windows colour chooser dialog.
-This dialog component is drawn in a panel, and thus can be
-embedded inside any widget (although it cannot be resized).
-This colour chooser may also be substituted for the colour
-chooser on any platform that might have an ugly one :)
-
-How to use it
-------------------------------
-
-The demo (demo/PyColourChooser.py code shows how to display
-a colour chooser and retrieve its options.
-
-Contact and Author Info
-------------------------------
-
-PyColourChooser was written and is maintained by:
-
- Michael Gilfix <mgilfix@eecs.tufts.edu>
-
-You can find the latest PyColourChooser code at
-http://sourceforge.net/projects/wxcolourchooser/. If you have
-any suggestions or want to submit a patch, please send
-it my way at: mgilfix@eecs.tufts.edu
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestRadioBox(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
- #self.SetBackgroundColour(wx.BLUE)
-
- sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
- 'six', 'seven', 'eight']
-
- sizer = wx.BoxSizer(wx.VERTICAL)
-
- rb = wx.RadioBox(
- self, -1, "wx.RadioBox", wx.DefaultPosition, wx.DefaultSize,
- sampleList, 2, wx.RA_SPECIFY_COLS
- )
-
- self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, rb)
- #rb.SetBackgroundColour(wx.BLUE)
- rb.SetToolTip(wx.ToolTip("This is a ToolTip!"))
- #rb.SetLabel("wxRadioBox")
-
- sizer.Add(rb, 0, wx.ALL, 20)
-
- rb = wx.RadioBox(
- self, -1, "", wx.DefaultPosition, wx.DefaultSize,
- sampleList, 3, wx.RA_SPECIFY_COLS | wx.NO_BORDER
- )
-
- self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, rb)
- rb.SetToolTip(wx.ToolTip("This box has no label"))
-
- sizer.Add(rb, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM, 20)
-
- self.SetSizer(sizer)
-
-
- def EvtRadioBox(self, event):
- self.log.WriteText('EvtRadioBox: %d\n' % event.GetInt())
-
-# Doesn't appear to be used for anything.
-# def EvtRadioButton(self, event):
-# self.log.write('EvtRadioButton:%d\n' % event.GetId())
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestRadioBox(nb, log)
- return win
-
-
-
-overview = """\
-A radio box item is used to select one of number of mutually exclusive
-choices. It is displayed as a vertical column or horizontal row of
-labelled buttons.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel( wx.Panel ):
- def __init__( self, parent, log ):
-
- wx.Panel.__init__( self, parent, -1 )
- self.log = log
- panel = wx.Panel( self, -1 )
-
- # 1st group of controls:
- self.group1_ctrls = []
- radio1 = wx.RadioButton( panel, -1, " Radio1 ", style = wx.RB_GROUP )
- text1 = wx.TextCtrl( panel, -1, "" )
- radio2 = wx.RadioButton( panel, -1, " Radio2 " )
- text2 = wx.TextCtrl( panel, -1, "" )
- radio3 = wx.RadioButton( panel, -1, " Radio3 " )
- text3 = wx.TextCtrl( panel, -1, "" )
- self.group1_ctrls.append((radio1, text1))
- self.group1_ctrls.append((radio2, text2))
- self.group1_ctrls.append((radio3, text3))
-
- # 2nd group of controls:
- self.group2_ctrls = []
- radio4 = wx.RadioButton( panel, -1, " Radio1 ", style = wx.RB_GROUP )
- text4 = wx.TextCtrl( panel, -1, "" )
- radio5 = wx.RadioButton( panel, -1, " Radio2 " )
- text5 = wx.TextCtrl( panel, -1, "" )
- radio6 = wx.RadioButton( panel, -1, " Radio3 " )
- text6 = wx.TextCtrl( panel, -1, "" )
- self.group2_ctrls.append((radio4, text4))
- self.group2_ctrls.append((radio5, text5))
- self.group2_ctrls.append((radio6, text6))
-
- # Layout controls on panel:
- vs = wx.BoxSizer( wx.VERTICAL )
-
- box1_title = wx.StaticBox( panel, -1, "Group 1" )
- box1 = wx.StaticBoxSizer( box1_title, wx.VERTICAL )
- grid1 = wx.FlexGridSizer( 0, 2, 0, 0 )
-
- for radio, text in self.group1_ctrls:
- grid1.AddWindow( radio, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
- grid1.AddWindow( text, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
-
- box1.AddSizer( grid1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
- vs.AddSizer( box1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
-
- box2_title = wx.StaticBox( panel, -1, "Group 2" )
- box2 = wx.StaticBoxSizer( box2_title, wx.VERTICAL )
- grid2 = wx.FlexGridSizer( 0, 2, 0, 0 )
-
- for radio, text in self.group2_ctrls:
- grid2.AddWindow( radio, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
- grid2.AddWindow( text, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 )
-
- box2.AddSizer( grid2, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
- vs.AddSizer( box2, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
-
- panel.SetSizer( vs )
- vs.Fit( panel )
- panel.Move( (50,50) )
- self.panel = panel
-
- # Setup event handling and initial state for controls:
- for radio, text in self.group1_ctrls:
- self.Bind(wx.EVT_RADIOBUTTON, self.OnGroup1Select, radio )
-
- for radio, text in self.group2_ctrls:
- self.Bind(wx.EVT_RADIOBUTTON, self.OnGroup2Select, radio )
-
- for radio, text in self.group1_ctrls + self.group2_ctrls:
- radio.SetValue(0)
- text.Enable(False)
-
- def OnGroup1Select( self, event ):
- radio_selected = event.GetEventObject()
- self.log.write('Group1 %s selected\n' % radio_selected.GetLabel() )
-
- for radio, text in self.group1_ctrls:
- if radio is radio_selected:
- text.Enable(True)
- else:
- text.Enable(False)
-
- def OnGroup2Select( self, event ):
- radio_selected = event.GetEventObject()
- self.log.write('Group2 %s selected\n' % radio_selected.GetLabel() )
-
- for radio, text in self.group2_ctrls:
- if radio is radio_selected:
- text.Enable(True)
- else:
- text.Enable(False)
-
-#----------------------------------------------------------------------
-
-def runTest( frame, nb, log ):
- win = TestPanel( nb, log )
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-<html><body>
-<P>
-This demo shows how individual radio buttons can be used to build
-more complicated selection mechanisms...
-<P>
-It uses 2 groups of wxRadioButtons, where the groups are defined by
-instantiation. When a wxRadioButton is created with the <I>wxRB_GROUP</I>
-style, all subsequent wxRadioButtons created without it are implicitly
-added to that group by the framework.
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o The rightalign library needs converted for this to work correctly.
-#
-# 12/11/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o All issues resolved.
-#
-# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxRightTextCtrl -> RightTextCtrl
-#
-
-############################################################################\
-# Note: this demo has been converted, but the control is deprecated because |
-# wx.TextCtrl now supports the wx.TE_RIGHT style flag, which makes this |
-# control completely superfluous. |
-############################################################################/
-
-import wx
-import wx.lib.rightalign as right
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent, -1)
-
- fgs = wx.FlexGridSizer(cols=2, vgap=5, hgap=5)
-
- txt = wx.StaticText(
- self, -1,
- "These text controls will align their contents to\n"
- "the right (on wxMSW) when they don't have focus.",
- style=wx.ALIGN_RIGHT
- )
-
- fgs.Add(txt)
- fgs.Add(right.RightTextCtrl(self, -1, "", size=(75, -1)))
-
- fgs.Add((10,10))
- fgs.Add(right.RightTextCtrl(self, -1, "123.45", size=(75, -1)))
-
- fgs.Add((10,10))
- fgs.Add(right.RightTextCtrl(self, -1, "234.56", size=(75, -1)))
-
- fgs.Add((10,10))
- fgs.Add(right.RightTextCtrl(self, -1, "345.67", size=(75, -1)))
-
- fgs.Add((10,10))
- fgs.Add(right.RightTextCtrl(self, -1, "456.78", size=(75, -1)))
-
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(fgs, 0, wx.ALL, 25)
-
- self.SetSizer(sizer)
- self.SetAutoLayout(True)
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb)
- return win
-
-#----------------------------------------------------------------------
-
-overview = right.__doc__
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o Should be renamed to wxSashLayoutWindow.py
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestSashWindow(wx.Panel):
- ID_WINDOW_TOP = 5100
- ID_WINDOW_LEFT1 = 5101
- ID_WINDOW_LEFT2 = 5102
- ID_WINDOW_BOTTOM = 5103
-
-
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
-
- self.log = log
-
- # will occupy the space not used by the Layout Algorithm
- self.remainingSpace = wx.Panel(self, -1, style=wx.SUNKEN_BORDER)
-
- self.Bind(
- wx.EVT_SASH_DRAGGED_RANGE, self.OnSashDrag,
- id=self.ID_WINDOW_TOP, id2=self.ID_WINDOW_BOTTOM,
- )
-
- self.Bind(wx.EVT_SIZE, self.OnSize)
-
-
- # Create some layout windows
- # A window like a toolbar
- win = wx.SashLayoutWindow(
- self, self.ID_WINDOW_TOP, wx.DefaultPosition, (200, 30),
- wx.NO_BORDER|wx.SW_3D
- )
-
- win.SetDefaultSize((1000, 30))
- win.SetOrientation(wx.LAYOUT_HORIZONTAL)
- win.SetAlignment(wx.LAYOUT_TOP)
- win.SetBackgroundColour(wx.Colour(255, 0, 0))
- win.SetSashVisible(wx.SASH_BOTTOM, True)
-
- self.topWindow = win
-
-
- # A window like a statusbar
- win = wx.SashLayoutWindow(
- self, self.ID_WINDOW_BOTTOM, wx.DefaultPosition, (200, 30),
- wx.NO_BORDER|wx.SW_3D
- )
-
- win.SetDefaultSize((1000, 30))
- win.SetOrientation(wx.LAYOUT_HORIZONTAL)
- win.SetAlignment(wx.LAYOUT_BOTTOM)
- win.SetBackgroundColour(wx.Colour(0, 0, 255))
- win.SetSashVisible(wx.SASH_TOP, True)
-
- self.bottomWindow = win
-
- # A window to the left of the client window
- win = wx.SashLayoutWindow(
- self, self.ID_WINDOW_LEFT1, wx.DefaultPosition, (200, 30),
- wx.NO_BORDER|wx.SW_3D
- )
-
- win.SetDefaultSize((120, 1000))
- win.SetOrientation(wx.LAYOUT_VERTICAL)
- win.SetAlignment(wx.LAYOUT_LEFT)
- win.SetBackgroundColour(wx.Colour(0, 255, 0))
- win.SetSashVisible(wx.SASH_RIGHT, True)
- win.SetExtraBorderSize(10)
- textWindow = wx.TextCtrl(
- win, -1, "", wx.DefaultPosition, wx.DefaultSize,
- wx.TE_MULTILINE|wx.SUNKEN_BORDER
- )
-
- textWindow.SetValue("A sub window")
-
- self.leftWindow1 = win
-
-
- # Another window to the left of the client window
- win = wx.SashLayoutWindow(
- self, self.ID_WINDOW_LEFT2, wx.DefaultPosition, (200, 30),
- wx.NO_BORDER|wx.SW_3D
- )
-
- win.SetDefaultSize((120, 1000))
- win.SetOrientation(wx.LAYOUT_VERTICAL)
- win.SetAlignment(wx.LAYOUT_LEFT)
- win.SetBackgroundColour(wx.Colour(0, 255, 255))
- win.SetSashVisible(wx.SASH_RIGHT, True)
-
- self.leftWindow2 = win
-
-
- def OnSashDrag(self, event):
- if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE:
- return
-
- eID = event.GetId()
-
- if eID == self.ID_WINDOW_TOP:
- self.topWindow.SetDefaultSize((1000, event.GetDragRect().height))
-
- elif eID == self.ID_WINDOW_LEFT1:
- self.leftWindow1.SetDefaultSize((event.GetDragRect().width, 1000))
-
-
- elif eID == self.ID_WINDOW_LEFT2:
- self.leftWindow2.SetDefaultSize((event.GetDragRect().width, 1000))
-
- elif eID == self.ID_WINDOW_BOTTOM:
- self.bottomWindow.SetDefaultSize((1000, event.GetDragRect().height))
-
- wx.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace)
- self.remainingSpace.Refresh()
-
- def OnSize(self, event):
- wx.LayoutAlgorithm().LayoutWindow(self, self.remainingSpace)
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestSashWindow(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-wxSashLayoutWindow responds to OnCalculateLayout events generated by
-wxLayoutAlgorithm. It allows the application to use simple accessors to
-specify how the window should be laid out, rather than having to respond
-to events. The fact that the class derives from wxSashWindow allows sashes
-to be used if required, to allow the windows to be user-resizable.
-
-The documentation for wxLayoutAlgorithm explains the purpose of this class
-in more detail.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o dialogs library needs updated to wx
-#
-# 12/01/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o dialogs library converted. All is well.
-#
-# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxScrolledMessageDialog -> ScrolledMessageDialog
-#
-
-import wx
-import wx.lib.dialogs
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- f = open("Main.py", "r")
- msg = f.read()
- f.close()
-
- dlg = wx.lib.dialogs.ScrolledMessageDialog(frame, msg, "message test")
- dlg.ShowModal()
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-
-<code><b>ScrolledMessageDialog</b>(parent, msg, caption, pos=wx.DefaultPosition, size=(500,300))</code>
-
-This class represents a message dialog that uses a wxTextCtrl to display the
-message. This allows more flexible information display without having to be
-as much concerned with layout requirements. A text file can simply be used
-
-This dialog offers no special attributes or methods beyond those supported
-by wxDialog.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o scrolledpanel lib needs wx update
-#
-# 12/11/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o lib updated, all is well.
-#
-# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxScrolledPanel -> ScrolledPanel
-#
-
-import wx
-import wx.lib.scrolledpanel as scrolled
-
-#----------------------------------------------------------------------
-
-text = "one two buckle my shoe three four shut the door five six pick up sticks seven eight lay them straight nine ten big fat hen"
-
-
-class TestPanel(scrolled.ScrolledPanel):
- def __init__(self, parent, log):
- self.log = log
- scrolled.ScrolledPanel.__init__(self, parent, -1)
-
- vbox = wx.BoxSizer(wx.VERTICAL)
- desc = wx.StaticText(self, -1,
- "ScrolledPanel extends wxScrolledWindow, adding all "
- "the necessary bits to set up scroll handling for you.\n\n"
- "Here are three fixed size examples of its use. The "
- "demo panel for this sample is also using it -- the \nwxStaticLine"
- "below is intentionally made too long so a scrollbar will be "
- "activated."
- )
- desc.SetForegroundColour("Blue")
- vbox.Add(desc, 0, wx.ALIGN_LEFT|wx.ALL, 5)
- vbox.Add(wx.StaticLine(self, -1, size=(1024,-1)), 0, wx.ALL, 5)
- vbox.Add((20,20))
-
- words = text.split()
-
- panel1 = scrolled.ScrolledPanel(self, -1, size=(120,300),
- style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER )
- fgs1 = wx.FlexGridSizer(cols=2, vgap=4, hgap=4)
-
- for word in words:
- label = wx.StaticText(panel1, -1, word+":")
- tc = wx.TextCtrl(panel1, -1, word, size=(50,-1))
- fgs1.Add(label, flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
- fgs1.Add(tc, flag=wx.EXPAND|wx.RIGHT, border=25)
-
- panel1.SetSizer( fgs1 )
- panel1.SetAutoLayout(1)
- panel1.SetupScrolling( scroll_x=False )
-
- panel2 = scrolled.ScrolledPanel(self, -1, size=(350, 40),
- style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
- panel3 = scrolled.ScrolledPanel(self, -1, size=(200,100),
- style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
-
- fgs2 = wx.FlexGridSizer(cols=25, vgap=4, hgap=4)
- fgs3 = wx.FlexGridSizer(cols=5, vgap=4, hgap=4)
-
- for i in range(len(words)):
- word = words[i]
- if i % 5 != 4:
- label2 = wx.StaticText(panel2, -1, word)
- fgs2.Add(label2, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
- label3 = wx.StaticText(panel3, -1, word)
- fgs3.Add(label3, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
- else:
- tc2 = wx.TextCtrl(panel2, -1, word, size=(50,-1))
- fgs2.Add(tc2, flag=wx.LEFT, border=5)
- tc3 = wx.TextCtrl(panel3, -1, word )
- fgs3.Add(tc3, flag=wx.LEFT, border=5)
-
- panel2.SetSizer( fgs2 )
- panel2.SetAutoLayout(1)
- panel2.SetupScrolling(scroll_y = False)
-
- panel3.SetSizer( fgs3 )
- panel3.SetAutoLayout(1)
- panel3.SetupScrolling()
-
- hbox = wx.BoxSizer(wx.HORIZONTAL)
- hbox.Add((20,20))
- hbox.Add(panel1, 0)
- hbox.Add((40, 10))
-
- vbox2 = wx.BoxSizer(wx.VERTICAL)
- vbox2.Add(panel2, 0)
- vbox2.Add((20, 50))
-
- vbox2.Add(panel3, 0)
- vbox2.Add((20, 10))
- hbox.Add(vbox2)
-
- vbox.AddSizer(hbox, 0)
- self.SetSizer(vbox)
- self.SetAutoLayout(1)
- self.SetupScrolling()
-
-
-#----------------------------------------------------------------------
-
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-ScrolledPanel fills a "hole" in the implementation of wxScrolledWindow,
-providing automatic scrollbar and scrolling behavior and the tab traversal
-mangement that wxScrolledWindow lacks.
-</body></html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/12/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o Rudimentary overview doc added.
-#
-
-import wx
-
-import images
-
-BUFFERED = 1
-
-#---------------------------------------------------------------------------
-
-class MyCanvas(wx.ScrolledWindow):
- def __init__(self, parent, id = -1, size = wx.DefaultSize):
- wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER)
-
- self.lines = []
- self.maxWidth = 1000
- self.maxHeight = 1000
- self.x = self.y = 0
- self.curLine = []
- self.drawing = False
-
- self.SetBackgroundColour("WHITE")
- self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))
- bmp = images.getTest2Bitmap()
- mask = wx.MaskColour(bmp, wx.BLUE)
- bmp.SetMask(mask)
- self.bmp = bmp
-
- self.SetScrollbars(20, 20, self.maxWidth/20, self.maxHeight/20)
-
- if BUFFERED:
- # Initialize the buffer bitmap. No real DC is needed at this point.
- self.buffer = wx.EmptyBitmap(self.maxWidth, self.maxHeight)
- dc = wx.BufferedDC(None, self.buffer)
- dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
- dc.Clear()
- self.DoDrawing(dc)
-
- self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftButtonEvent)
- self.Bind(wx.EVT_LEFT_UP, self.OnLeftButtonEvent)
- self.Bind(wx.EVT_MOTION, self.OnLeftButtonEvent)
- self.Bind(wx.EVT_PAINT, self.OnPaint)
-
-
- def getWidth(self):
- return self.maxWidth
-
- def getHeight(self):
- return self.maxHeight
-
-
- def OnPaint(self, event):
- if BUFFERED:
- # Create a buffered paint DC. It will create the real
- # wx.PaintDC and then blit the bitmap to it when dc is
- # deleted. Since we don't need to draw anything else
- # here that's all there is to it.
- dc = wx.BufferedPaintDC(self, self.buffer)
- else:
- dc = wx.PaintDC(self)
- self.PrepareDC(dc)
- # since we're not buffering in this case, we have to
- # paint the whole window, potentially very time consuming.
- self.DoDrawing(dc)
-
-
- def DoDrawing(self, dc, printing=False):
- dc.BeginDrawing()
- dc.SetPen(wx.Pen('RED'))
- dc.DrawRectangle((5, 5), (50, 50))
-
- dc.SetBrush(wx.LIGHT_GREY_BRUSH)
- dc.SetPen(wx.Pen('BLUE', 4))
- dc.DrawRectangle((15, 15), (50, 50))
-
- dc.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL))
- dc.SetTextForeground(wx.Colour(0xFF, 0x20, 0xFF))
- te = dc.GetTextExtent("Hello World")
- dc.DrawText("Hello World", (60, 65))
-
- dc.SetPen(wx.Pen('VIOLET', 4))
- dc.DrawLine((5, 65+te[1]), (60+te[0], 65+te[1]))
-
- lst = [(100,110), (150,110), (150,160), (100,160)]
- dc.DrawLines(lst, -60)
- dc.SetPen(wx.GREY_PEN)
- dc.DrawPolygon(lst, 75)
- dc.SetPen(wx.GREEN_PEN)
- dc.DrawSpline(lst+[(100,100)])
-
- dc.DrawBitmap(self.bmp, (200, 20), True)
- dc.SetTextForeground(wx.Colour(0, 0xFF, 0x80))
- dc.DrawText("a bitmap", (200, 85))
-
-## dc.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL))
-## dc.SetTextForeground("BLACK")
-## dc.DrawText("TEST this STRING", (10, 200))
-## print dc.GetFullTextExtent("TEST this STRING")
-
- font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
- dc.SetFont(font)
- dc.SetTextForeground(wx.BLACK)
-
- for a in range(0, 360, 45):
- dc.DrawRotatedText("Rotated text...", (300, 300), a)
-
- dc.SetPen(wx.TRANSPARENT_PEN)
- dc.SetBrush(wx.BLUE_BRUSH)
- dc.DrawRectangle((50,500),(50,50))
- dc.DrawRectangle((100,500),(50,50))
-
- dc.SetPen(wx.Pen('RED'))
- dc.DrawEllipticArc((200, 500), (50, 75), 0, 90)
-
- if not printing:
- # This has troubles when used on a print preview in wxGTK,
- # probably something to do with the pen styles and the scaling
- # it does...
- y = 20
-
- for style in [wx.DOT, wx.LONG_DASH, wx.SHORT_DASH, wx.DOT_DASH, wx.USER_DASH]:
- pen = wx.Pen("DARK ORCHID", 1, style)
- if style == wx.USER_DASH:
- pen.SetCap(wx.CAP_BUTT)
- pen.SetDashes([1,2])
- pen.SetColour("RED")
- dc.SetPen(pen)
- dc.DrawLine((300, y), (400, y))
- y = y + 10
-
- dc.SetBrush(wx.TRANSPARENT_BRUSH)
- dc.SetPen(wx.Pen(wx.Colour(0xFF, 0x20, 0xFF), 1, wx.SOLID))
- dc.DrawRectangle((450, 50), (100, 100))
- old_pen = dc.GetPen()
- new_pen = wx.Pen("BLACK", 5)
- dc.SetPen(new_pen)
- dc.DrawRectangle((470, 70), (60, 60))
- dc.SetPen(old_pen)
- dc.DrawRectangle((490, 90), (20, 20))
-
- self.DrawSavedLines(dc)
- dc.EndDrawing()
-
-
- def DrawSavedLines(self, dc):
- dc.SetPen(wx.Pen('MEDIUM FOREST GREEN', 4))
-
- for line in self.lines:
- for coords in line:
- apply(dc.DrawLine, coords)
-
-
- def SetXY(self, event):
- self.x, self.y = self.ConvertEventCoords(event)
-
- def ConvertEventCoords(self, event):
- xView, yView = self.GetViewStart()
- xDelta, yDelta = self.GetScrollPixelsPerUnit()
- return (event.GetX() + (xView * xDelta),
- event.GetY() + (yView * yDelta))
-
- def OnLeftButtonEvent(self, event):
- if event.LeftDown():
- self.SetFocus()
- self.SetXY(event)
- self.curLine = []
- self.CaptureMouse()
- self.drawing = True
-
- elif event.Dragging() and self.drawing:
- if BUFFERED:
- # If doing buffered drawing, create the buffered DC, giving it
- # it a real DC to blit to when done.
- cdc = wx.ClientDC(self)
- self.PrepareDC(cdc)
- dc = wx.BufferedDC(cdc, self.buffer)
- else:
- dc = wx.ClientDC(self)
- self.PrepareDC(dc)
-
- dc.BeginDrawing()
- dc.SetPen(wx.Pen('MEDIUM FOREST GREEN', 4))
- coords = [(self.x, self.y) , self.ConvertEventCoords(event)]
- self.curLine.append(coords)
- apply(dc.DrawLine, coords)
- self.SetXY(event)
- dc.EndDrawing()
-
-
- elif event.LeftUp() and self.drawing:
- self.lines.append(self.curLine)
- self.curLine = []
- self.ReleaseMouse()
- self.drawing = False
-
-
-## This is an example of what to do for the EVT_MOUSEWHEEL event,
-## but since wxScrolledWindow does this already it's not
-## necessary to do it ourselves. You would need to add an event table
-## entry to __init__() to direct wheelmouse events to this handler.
-
-## wheelScroll = 0
-## def OnWheel(self, evt):
-## delta = evt.GetWheelDelta()
-## rot = evt.GetWheelRotation()
-## linesPer = evt.GetLinesPerAction()
-## print delta, rot, linesPer
-## ws = self.wheelScroll
-## ws = ws + rot
-## lines = ws / delta
-## ws = ws - lines * delta
-## self.wheelScroll = ws
-## if lines != 0:
-## lines = lines * linesPer
-## vsx, vsy = self.GetViewStart()
-## scrollTo = vsy - lines
-## self.Scroll(-1, scrollTo)
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = MyCanvas(nb)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """
-<html>
-<body>
-The wx.ScrolledWindow class manages scrolling for its client area, transforming the
-coordinates according to the scrollbar positions, and setting the scroll positions,
-thumb sizes and ranges according to the area in view.
-</body>
-</html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- dlg = wx.SingleChoiceDialog(
- frame, 'Test Single Choice', 'The Caption',
- ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'],
- wx.CHOICEDLG_STYLE
- )
-
- if dlg.ShowModal() == wx.ID_OK:
- log.WriteText('You selected: %s\n' % dlg.GetStringSelection())
-
- dlg.Destroy()
-
-#---------------------------------------------------------------------------
-
-
-
-
-overview = """\
-This class represents a dialog that shows a list of strings, and allows the user
-to select one. Double-clicking on a list item is equivalent to single-clicking
-and then pressing OK.
-
-As with all dialogs, be sure to retrieve the information you need BEFORE you
-destroy the dialog.
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
- self.count = 0
-
- wx.StaticText(self, -1, "This is a wxSlider.", (45, 15))
-
- slider = wx.Slider(
- self, 100, 25, 1, 100, (30, 60), (250, -1),
- wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS
- )
-
- slider.SetTickFreq(5, 1)
-
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-
-overview = """\
-A slider is a control with a handle which can be pulled back and forth to
-change the value.
-
-In Windows versions below Windows 95, a scrollbar is used to simulate the slider.
-In Windows 95, the track bar control is used.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o EVT_SPIN events (or something about them) freezes up the app.
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
- self.count = 0
-
- wx.StaticText(self, -1, "This example uses the wxSpinButton control.", (45, 15))
-
- self.text = wx.TextCtrl(self, -1, "1", (30, 50), (60, -1))
- h = self.text.GetSize().height
-
- self.spin = wx.SpinButton(self, -1, (92, 50), (h, h), wx.SP_VERTICAL)
- self.spin.SetRange(1, 100)
- self.spin.SetValue(1)
-
- self.Bind(wx.EVT_SPIN, self.OnSpin, self.spin)
-
-
- def OnSpin(self, event):
- self.text.SetValue(str(event.GetPosition()))
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-A wxSpinButton has two small up and down (or left and right) arrow buttons.
-It is often used next to a text control for increment and decrementing a value.
-Portable programs should try to use wxSpinCtrl instead as wxSpinButton is not
-implemented for all platforms (Win32 and GTK only currently).
-
-NB: the range supported by this control (and wxSpinCtrl) depends on the platform
-but is at least -0x8000 to 0x7fff. Under GTK and Win32 with sufficiently new version
-of comctrl32.dll (at least 4.71 is required, 5.80 is recommended) the full 32 bit
-range is supported.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
- self.count = 0
-
- wx.StaticText(self, -1, "This example uses the wxSpinCtrl control.", (45, 15))
- sc = wx.SpinCtrl(self, -1, "", (30, 50), (80, -1))
- sc.SetRange(1,100)
- sc.SetValue(5)
- #sc.Enable(False)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-wxSpinCtrl combines wxTextCtrl and wxSpinButton in one control.
-
-Portable programs should try to use wxSpinCtrl instead as wxSpinButton is not
-implemented for all platforms (Win32 and GTK only currently).
-
-NB: the range supported by this control depends on the platform
-but is at least -0x8000 to 0x7fff. Under GTK and Win32 with sufficiently new version
-of comctrl32.dll (at least 4.71 is required, 5.80 is recommended) the full 32 bit
-range is supported.
-
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class MySplitter(wx.SplitterWindow):
- def __init__(self, parent, ID, log):
- wx.SplitterWindow.__init__(self, parent, ID)
- self.log = log
-
- self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnSashChanged)
- self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnSashChanging)
-
- def OnSashChanged(self, evt):
- self.log.WriteText("sash changed to %s\n" % str(evt.GetSashPosition()))
- # uncomment this to not allow the change
- #evt.SetSashPosition(-1)
-
- def OnSashChanging(self, evt):
- self.log.WriteText("sash changing to %s\n" % str(evt.GetSashPosition()))
- # uncomment this to not allow the change
- #evt.SetSashPosition(-1)
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- splitter = MySplitter(nb, -1, log)
-
- p1 = wx.Window(splitter, -1)
- p1.SetBackgroundColour(wx.RED)
- wx.StaticText(p1, -1, "Panel One", (5,5)).SetBackgroundColour(wx.RED)
-
- p2 = wx.Window(splitter, -1)
- p2.SetBackgroundColour(wx.BLUE)
- wx.StaticText(p2, -1, "Panel Two", (5,5)).SetBackgroundColour(wx.BLUE)
-
- splitter.SetMinimumPaneSize(20)
- splitter.SplitVertically(p1, p2, 100)
-
- return splitter
-
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-This class manages up to two subwindows. The current view can be split
-into two programmatically (perhaps from a menu command), and unsplit
-either programmatically or via the wxSplitterWindow user interface.
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import images
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
- self.count = 0
-
- wx.StaticText(self, -1, "This is a wxStaticBitmap.", (45, 15))
-
- bmp = images.getTest2Bitmap()
- mask = wx.MaskColour(bmp, wx.BLUE)
- bmp.SetMask(mask)
- wx.StaticBitmap(self, -1, bmp, (80, 50), (bmp.GetWidth(), bmp.GetHeight()))
-
- bmp = images.getRobinBitmap()
- wx.StaticBitmap(self, -1, bmp, (80, 150))
-
- wx.StaticText(self, -1, "Hey, if Ousterhout can do it, so can I.", (200, 175))
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-overview = """\
-A static bitmap control displays a bitmap.
-
-The bitmap to be displayed should have a small number of colours, such as 16,
-to avoid palette problems.
-
-A bitmap can be derived from most image formats using the wxImage class.
-
-"""
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o Removed the USE_GENERIC code because it doesn't work unless you use
-# the 'from wx import *' methodology.
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent, -1)
-
- wx.StaticText(self, -1, "This is an example of static text", (20, 10))
- wx.StaticText(self, -1, "using the wxStaticText Control.", (20, 30))
-
- wx.StaticText(
- self, -1, "Is this yellow?", (20, 70), (90, -1)
- ).SetBackgroundColour('Yellow')
-
- wx.StaticText(
- self, -1, "align center", (120, 70), (90, -1), wx.ALIGN_CENTER
- ).SetBackgroundColour('Yellow')
-
- wx.StaticText(
- self, -1, "align right", (220, 70), (90, -1), wx.ALIGN_RIGHT
- ).SetBackgroundColour('Yellow')
-
- str = "This is a different font."
- text = wx.StaticText(self, -1, str, (20, 100))
- font = wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)
- text.SetFont(font)
- #text.SetSize(text.GetBestSize())
-
- wx.StaticText(self, -1, "Multi-line wxStaticText\nline 2\nline 3\n\nafter empty line", (20,150))
- wx.StaticText(self, -1, "Align right multi-line\nline 2\nline 3\n\nafter empty line", (220,150), style=wx.ALIGN_RIGHT)
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- panel = TestPanel(nb)
- return panel
-
-
-#---------------------------------------------------------------------------
-
-
-overview = '''\
-A static text control displays one or more lines of read-only text.
-
-'''
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import time
-import wx
-
-#---------------------------------------------------------------------------
-
-class CustomStatusBar(wx.StatusBar):
- def __init__(self, parent, log):
- wx.StatusBar.__init__(self, parent, -1)
-
- # This status bar has three fields
- self.SetFieldsCount(3)
- self.log = log
- self.sizeChanged = False
- self.Bind(wx.EVT_SIZE, self.OnSize)
- self.Bind(wx.EVT_IDLE, self.OnIdle)
-
- # Field 0 ... just text
- self.SetStatusText("A Custom StatusBar...", 0)
-
- # This will fall into field 1 (the second field)
- self.cb = wx.CheckBox(self, 1001, "toggle clock")
- self.Bind(wx.EVT_CHECKBOX, self.OnToggleClock, self.cb)
- self.cb.SetValue(True)
-
- # set the initial position of the checkbox
- self.Reposition()
-
- # We're going to use a timer to drive a 'clock' in the last
- # field.
- self.timer = wx.PyTimer(self.Notify)
- self.timer.Start(1000)
- self.Notify()
-
-
- # Handles events from the timer we started in __init__().
- # We're using it to drive a 'clock' in field 2 (the third field).
- def Notify(self):
- t = time.localtime(time.time())
- st = time.strftime("%d-%b-%Y %I:%M:%S", t)
- self.SetStatusText(st, 2)
- self.log.WriteText("tick...\n")
-
-
- # the checkbox was clicked
- def OnToggleClock(self, event):
- if self.cb.GetValue():
- self.timer.Start(1000)
- self.Notify()
- else:
- self.timer.Stop()
-
-
- def OnSize(self, evt):
- self.Reposition() # for normal size events
-
- # Set a flag so the idle time handler will also do the repositioning.
- # It is done this way to get around a buglet where GetFieldRect is not
- # accurate during the EVT_SIZE resulting from a frame maximize.
- self.sizeChanged = True
-
-
- def OnIdle(self, evt):
- if self.sizeChanged:
- self.Reposition()
-
-
- # reposition the checkbox
- def Reposition(self):
- rect = self.GetFieldRect(1)
- self.cb.SetPosition((rect.x+2, rect.y+2))
- self.cb.SetSize((rect.width-4, rect.height-4))
- self.sizeChanged = False
-
-
-
-class TestCustomStatusBar(wx.Frame):
- def __init__(self, parent, log):
- wx.Frame.__init__(self, parent, -1, 'Test Custom StatusBar')
-
- self.sb = CustomStatusBar(self, log)
- self.SetStatusBar(self.sb)
- tc = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY|wx.TE_MULTILINE)
-
- self.SetSize((500, 300))
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
- def OnCloseWindow(self, event):
- self.sb.timer.Stop()
- del self.sb.timer
- self.Destroy()
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestCustomStatusBar(frame, log)
- frame.otherWin = win
- win.Show(True)
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-A status bar is a narrow window that can be placed along the bottom of
-a frame to give small amounts of status information. It can contain
-one or more fields, one or more of which can be variable length
-according to the size of the window.
-
-This example demonstrates how to create a custom status bar with actual
-gadgets embedded in it. In this case, the first field is just plain text,
-The second one has a checkbox that enables the timer, and the third
-field has a clock that shows the current time when it is enabled.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o EVT_STC_DRAG_OVER event GetdragResult() is not an int
-# o wx.TheClipboard.Flush() generates an error on program exit.
-#
-
-import wx
-import wx.stc as stc
-
-import images
-
-#----------------------------------------------------------------------
-
-debug = 1
-
-
-demoText = """\
-
-This editor is provided by a class named wxStyledTextCtrl. As
-the name suggests, you can define styles that can be applied to
-sections of text. This will typically be used for things like
-syntax highlighting code editors, but I'm sure that there are other
-applications as well. A style is a combination of font, point size,
-foreground and background colours. The editor can handle
-proportional fonts just as easily as monospaced fonts, and various
-styles can use different sized fonts.
-
-There are a few canned language lexers and colourizers included,
-(see the next demo) or you can handle the colourization yourself.
-If you do you can simply register an event handler and the editor
-will let you know when the visible portion of the text needs
-styling.
-
-wxStyledTextEditor also supports setting markers in the margin...
-
-
-
-
-...and indicators within the text. You can use these for whatever
-you want in your application. Cut, Copy, Paste, Drag and Drop of
-text works, as well as virtually unlimited Undo and Redo
-capabilities, (right click to try it out.)
-"""
-
-if wx.Platform == '__WXMSW__':
- face1 = 'Arial'
- face2 = 'Times New Roman'
- face3 = 'Courier New'
- pb = 10
-else:
- face1 = 'Helvetica'
- face2 = 'Times'
- face3 = 'Courier'
- pb = 10
-
-
-#----------------------------------------------------------------------
-# This shows how to catch the Modified event from the wxStyledTextCtrl
-
-class MySTC(stc.StyledTextCtrl):
- def __init__(self, parent, ID, log):
- stc.StyledTextCtrl.__init__(self, parent, ID)
- self.log = log
-
- self.Bind(stc.EVT_STC_DO_DROP, self.OnDoDrop)
- self.Bind(stc.EVT_STC_DRAG_OVER, self.OnDragOver)
- self.Bind(stc.EVT_STC_START_DRAG, self.OnStartDrag)
- self.Bind(stc.EVT_STC_MODIFIED, self.OnModified)
-
- self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
-
- def OnDestroy(self, evt):
- # This is how the clipboard contents can be preserved after
- # the app has exited.
- wx.TheClipboard.Flush()
- evt.Skip()
-
-
- def OnStartDrag(self, evt):
- self.log.write("OnStartDrag: %d, %s\n"
- % (evt.GetDragAllowMove(), evt.GetDragText()))
-
- if debug and evt.GetPosition() < 250:
- evt.SetDragAllowMove(False) # you can prevent moving of text (only copy)
- evt.SetDragText("DRAGGED TEXT") # you can change what is dragged
- #evt.SetDragText("") # or prevent the drag with empty text
-
-
- def OnDragOver(self, evt):
- #Todo: evt.GetdragResult() response is not an int
-
- self.log.write(
- "OnDragOver: x,y=(%d, %d) pos: %d DragResult: %d\n"
- % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult())
- )
-
- if debug and evt.GetPosition() < 250:
- evt.SetDragResult(wx.DragNone) # prevent dropping at the beginning of the buffer
-
-
- def OnDoDrop(self, evt):
- self.log.write("OnDoDrop: x,y=(%d, %d) pos: %d DragResult: %d\n"
- "\ttext: %s\n"
- % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult(),
- evt.GetDragText()))
-
- if debug and evt.GetPosition() < 500:
- evt.SetDragText("DROPPED TEXT") # Can change text if needed
- #evt.SetDragResult(wx.DragNone) # Can also change the drag operation, but it
- # is probably better to do it in OnDragOver so
- # there is visual feedback
-
- #evt.SetPosition(25) # Can also change position, but I'm not sure why
- # you would want to...
-
-
-
-
- def OnModified(self, evt):
- self.log.write("""OnModified
- Mod type: %s
- At position: %d
- Lines added: %d
- Text Length: %d
- Text: %s\n""" % ( self.transModType(evt.GetModificationType()),
- evt.GetPosition(),
- evt.GetLinesAdded(),
- evt.GetLength(),
- repr(evt.GetText()) ))
-
-
- def transModType(self, modType):
- st = ""
- table = [(stc.STC_MOD_INSERTTEXT, "InsertText"),
- (stc.STC_MOD_DELETETEXT, "DeleteText"),
- (stc.STC_MOD_CHANGESTYLE, "ChangeStyle"),
- (stc.STC_MOD_CHANGEFOLD, "ChangeFold"),
- (stc.STC_PERFORMED_USER, "UserFlag"),
- (stc.STC_PERFORMED_UNDO, "Undo"),
- (stc.STC_PERFORMED_REDO, "Redo"),
- (stc.STC_LASTSTEPINUNDOREDO, "Last-Undo/Redo"),
- (stc.STC_MOD_CHANGEMARKER, "ChangeMarker"),
- (stc.STC_MOD_BEFOREINSERT, "B4-Insert"),
- (stc.STC_MOD_BEFOREDELETE, "B4-Delete")
- ]
-
- for flag,text in table:
- if flag & modType:
- st = st + text + " "
-
- if not st:
- st = 'UNKNOWN'
-
- return st
-
-
-
-
-#----------------------------------------------------------------------
-
-_USE_PANEL = 1
-
-def runTest(frame, nb, log):
- if not _USE_PANEL:
- ed = p = MySTC(nb, -1, log)
-
- else:
- p = wx.Panel(nb, -1, style=wx.NO_FULL_REPAINT_ON_RESIZE)
- ed = MySTC(p, -1, log)
- s = wx.BoxSizer(wx.HORIZONTAL)
- s.Add(ed, 1, wx.EXPAND)
- p.SetSizer(s)
- p.SetAutoLayout(True)
-
-
- #ed.SetBufferedDraw(False)
- #ed.StyleClearAll()
- #ed.SetScrollWidth(800)
- #ed.SetWrapMode(True)
-
- ed.SetText(demoText)
-
- if wx.USE_UNICODE:
- import codecs
- decode = codecs.lookup("utf-8")[1]
-
- ed.GotoPos(ed.GetLength())
- ed.AddText("\n\nwxStyledTextCtrl can also do Unicode:\n")
- unitext, l = decode('\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd - '
- '\xd0\xbb\xd1\x83\xd1\x87\xd1\x88\xd0\xb8\xd0\xb9 '
- '\xd1\x8f\xd0\xb7\xd1\x8b\xd0\xba \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f!\n\n')
- ed.AddText('\tRussian: ')
- ed.AddText(unitext)
- ed.GotoPos(0)
-
- ed.EmptyUndoBuffer()
-
- # make some styles
- ed.StyleSetSpec(stc.STC_STYLE_DEFAULT, "size:%d,face:%s" % (pb, face3))
- ed.StyleSetSpec(1, "size:%d,bold,face:%s,fore:#0000FF" % (pb+2, face1))
- ed.StyleSetSpec(2, "face:%s,italic,fore:#FF0000,size:%d" % (face2, pb))
- ed.StyleSetSpec(3, "face:%s,bold,size:%d" % (face2, pb+2))
- ed.StyleSetSpec(4, "face:%s,size:%d" % (face1, pb-1))
-
- # Now set some text to those styles... Normally this would be
- # done in an event handler that happens when text needs displayed.
- ed.StartStyling(98, 0xff)
- ed.SetStyling(6, 1) # set style for 6 characters using style 1
-
- ed.StartStyling(190, 0xff)
- ed.SetStyling(20, 2)
-
- ed.StartStyling(310, 0xff)
- ed.SetStyling(4, 3)
- ed.SetStyling(2, 0)
- ed.SetStyling(10, 4)
-
-
- # line numbers in the margin
- ed.SetMarginType(0, stc.STC_MARGIN_NUMBER)
- ed.SetMarginWidth(0, 22)
- ed.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "size:%d,face:%s" % (pb, face1))
-
- # setup some markers
- ed.SetMarginType(1, stc.STC_MARGIN_SYMBOL)
- ed.MarkerDefine(0, stc.STC_MARK_ROUNDRECT, "#CCFF00", "RED")
- #ed.MarkerDefine(1, stc.STC_MARK_CIRCLE, "FOREST GREEN", "SIENNA")
- ed.MarkerDefineBitmap(1, images.getFolder1Bitmap())
- ed.MarkerDefine(2, stc.STC_MARK_SHORTARROW, "blue", "blue")
- ed.MarkerDefine(3, stc.STC_MARK_ARROW, "#00FF00", "#00FF00")
-
- # put some markers on some lines
- ed.MarkerAdd(17, 0)
- ed.MarkerAdd(18, 1)
- ed.MarkerAdd(19, 2)
- ed.MarkerAdd(20, 3)
- ed.MarkerAdd(20, 0)
-
-
- # and finally, an indicator or two
- ed.IndicatorSetStyle(0, stc.STC_INDIC_SQUIGGLE)
- ed.IndicatorSetForeground(0, wx.RED)
- ed.IndicatorSetStyle(1, stc.STC_INDIC_DIAGONAL)
- ed.IndicatorSetForeground(1, wx.BLUE)
- ed.IndicatorSetStyle(2, stc.STC_INDIC_STRIKE)
- ed.IndicatorSetForeground(2, wx.RED)
-
- ed.StartStyling(836, stc.STC_INDICS_MASK)
- ed.SetStyling(10, stc.STC_INDIC0_MASK)
- ed.SetStyling(10, stc.STC_INDIC1_MASK)
- ed.SetStyling(10, stc.STC_INDIC2_MASK | stc.STC_INDIC1_MASK)
-
-
- # some test stuff...
- if debug:
- print "GetTextLength(): ", ed.GetTextLength(), len(ed.GetText())
- print "GetText(): ", repr(ed.GetText())
- print
- print "GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104))
- print
- print "GetCurLine(): ", repr(ed.GetCurLine())
- ed.GotoPos(5)
- print "GetCurLine(): ", repr(ed.GetCurLine())
- print
- print "GetLine(1): ", repr(ed.GetLine(1))
- print
- ed.SetSelection(25, 35)
- print "GetSelectedText(): ", repr(ed.GetSelectedText())
- print "GetTextRange(25, 35): ", repr(ed.GetTextRange(25, 35))
- print "FindText(0, max, 'indicators'): ",
- print ed.FindText(0, ed.GetTextLength(), "indicators")
-
- ed.GotoPos(0)
-
-
- return p
-
-
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-<html><body>
-Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a>
-and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should
-be helpful.
-</body><html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import keyword
-
-import wx
-import wx.stc as stc
-
-import images
-
-#----------------------------------------------------------------------
-
-demoText = """\
-## This version of the editor has been set up to edit Python source
-## code. Here is a copy of wxPython/demo/Main.py to play with.
-
-
-"""
-
-#----------------------------------------------------------------------
-
-
-if wx.Platform == '__WXMSW__':
- faces = { 'times': 'Times New Roman',
- 'mono' : 'Courier New',
- 'helv' : 'Arial',
- 'other': 'Comic Sans MS',
- 'size' : 10,
- 'size2': 8,
- }
-else:
- faces = { 'times': 'Times',
- 'mono' : 'Courier',
- 'helv' : 'Helvetica',
- 'other': 'new century schoolbook',
- 'size' : 12,
- 'size2': 10,
- }
-
-
-#----------------------------------------------------------------------
-
-class PythonSTC(stc.StyledTextCtrl):
-
- fold_symbols = 2
-
- def __init__(self, parent, ID):
- stc.StyledTextCtrl.__init__(self, parent, ID,
- style = wx.NO_FULL_REPAINT_ON_RESIZE)
-
- self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
- self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
-
- self.SetLexer(stc.STC_LEX_PYTHON)
- self.SetKeyWords(0, " ".join(keyword.kwlist))
-
- self.SetProperty("fold", "1")
- self.SetProperty("tab.timmy.whinge.level", "1")
- self.SetMargins(0,0)
-
- self.SetViewWhiteSpace(False)
- #self.SetBufferedDraw(False)
- #self.SetViewEOL(True)
-
- self.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
- self.SetEdgeColumn(78)
-
- # Setup a margin to hold fold markers
- #self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
- self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
- self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
- self.SetMarginSensitive(2, True)
- self.SetMarginWidth(2, 12)
-
- if self.fold_symbols == 0:
- # Arrow pointing right for contracted folders, arrow pointing down for expanded
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_ARROWDOWN, "black", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_ARROW, "black", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "black", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "black", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black");
-
- elif self.fold_symbols == 1:
- # Plus for contracted folders, minus for expanded
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_MINUS, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_PLUS, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black");
-
- elif self.fold_symbols == 2:
- # Like a flattened tree control using circular headers and curved joins
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_CIRCLEMINUS, "white", "#404040");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_CIRCLEPLUS, "white", "#404040");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#404040");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNERCURVE, "white", "#404040");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040");
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE, "white", "#404040");
-
- elif self.fold_symbols == 3:
- # Like a flattened tree control using square headers
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "#808080")
- self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "#808080")
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#808080")
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "#808080")
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
- self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
- self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "#808080")
-
-
- self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
- self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
- self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
-
- # Make some styles, The lexer defines what each style is used for, we
- # just have to define what each style looks like. This set is adapted from
- # Scintilla sample property files.
-
- # Global default styles for all languages
- self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
- self.StyleClearAll() # Reset all to be like the default
-
- # Global default styles for all languages
- self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
- self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
- self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
- self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
- self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
-
- # Python styles
- # Default
- self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
- # Comments
- self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
- # Number
- self.StyleSetSpec(stc.STC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
- # String
- self.StyleSetSpec(stc.STC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
- # Single quoted string
- self.StyleSetSpec(stc.STC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
- # Keyword
- self.StyleSetSpec(stc.STC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
- # Triple quotes
- self.StyleSetSpec(stc.STC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
- # Triple double quotes
- self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
- # Class name definition
- self.StyleSetSpec(stc.STC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
- # Function or method name definition
- self.StyleSetSpec(stc.STC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
- # Operators
- self.StyleSetSpec(stc.STC_P_OPERATOR, "bold,size:%(size)d" % faces)
- # Identifiers
- self.StyleSetSpec(stc.STC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
- # Comment-blocks
- self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
- # End of line where string is not closed
- self.StyleSetSpec(stc.STC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
-
- self.SetCaretForeground("BLUE")
-
-
- # register some images for use in the AutoComplete box.
- self.RegisterImage(1, images.getSmilesBitmap())
- self.RegisterImage(2, images.getFile1Bitmap())
- self.RegisterImage(3, images.getCopy2Bitmap())
-
-
- def OnKeyPressed(self, event):
- if self.CallTipActive():
- self.CallTipCancel()
- key = event.KeyCode()
-
- if key == 32 and event.ControlDown():
- pos = self.GetCurrentPos()
-
- # Tips
- if event.ShiftDown():
- self.CallTipSetBackground("yellow")
- self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
- 'show some suff, maybe parameters..\n\n'
- 'fubar(param1, param2)')
- # Code completion
- else:
- #lst = []
- #for x in range(50000):
- # lst.append('%05d' % x)
- #st = " ".join(lst)
- #print len(st)
- #self.AutoCompShow(0, st)
-
- kw = keyword.kwlist[:]
- kw.append("zzzzzz?2")
- kw.append("aaaaa?2")
- kw.append("__init__?3")
- kw.append("zzaaaaa?2")
- kw.append("zzbaaaa?2")
- kw.append("this_is_a_longer_value")
- #kw.append("this_is_a_much_much_much_much_much_much_much_longer_value")
-
- kw.sort() # Python sorts are case sensitive
- self.AutoCompSetIgnoreCase(False) # so this needs to match
-
- # Images are specified with a appended "?type"
- for i in range(len(kw)):
- if kw[i] in keyword.kwlist:
- kw[i] = kw[i] + "?1"
-
- self.AutoCompShow(0, " ".join(kw))
- else:
- event.Skip()
-
-
- def OnUpdateUI(self, evt):
- # check for matching braces
- braceAtCaret = -1
- braceOpposite = -1
- charBefore = None
- caretPos = self.GetCurrentPos()
-
- if caretPos > 0:
- charBefore = self.GetCharAt(caretPos - 1)
- styleBefore = self.GetStyleAt(caretPos - 1)
-
- # check before
- if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
- braceAtCaret = caretPos - 1
-
- # check after
- if braceAtCaret < 0:
- charAfter = self.GetCharAt(caretPos)
- styleAfter = self.GetStyleAt(caretPos)
-
- if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
- braceAtCaret = caretPos
-
- if braceAtCaret >= 0:
- braceOpposite = self.BraceMatch(braceAtCaret)
-
- if braceAtCaret != -1 and braceOpposite == -1:
- self.BraceBadLight(braceAtCaret)
- else:
- self.BraceHighlight(braceAtCaret, braceOpposite)
- #pt = self.PointFromPosition(braceOpposite)
- #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
- #print pt
- #self.Refresh(False)
-
-
- def OnMarginClick(self, evt):
- # fold and unfold as needed
- if evt.GetMargin() == 2:
- if evt.GetShift() and evt.GetControl():
- self.FoldAll()
- else:
- lineClicked = self.LineFromPosition(evt.GetPosition())
-
- if self.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
- if evt.GetShift():
- self.SetFoldExpanded(lineClicked, True)
- self.Expand(lineClicked, True, True, 1)
- elif evt.GetControl():
- if self.GetFoldExpanded(lineClicked):
- self.SetFoldExpanded(lineClicked, False)
- self.Expand(lineClicked, False, True, 0)
- else:
- self.SetFoldExpanded(lineClicked, True)
- self.Expand(lineClicked, True, True, 100)
- else:
- self.ToggleFold(lineClicked)
-
-
- def FoldAll(self):
- lineCount = self.GetLineCount()
- expanding = True
-
- # find out if we are folding or unfolding
- for lineNum in range(lineCount):
- if self.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
- expanding = not self.GetFoldExpanded(lineNum)
- break;
-
- lineNum = 0
-
- while lineNum < lineCount:
- level = self.GetFoldLevel(lineNum)
- if level & stc.STC_FOLDLEVELHEADERFLAG and \
- (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
-
- if expanding:
- self.SetFoldExpanded(lineNum, True)
- lineNum = self.Expand(lineNum, True)
- lineNum = lineNum - 1
- else:
- lastChild = self.GetLastChild(lineNum, -1)
- self.SetFoldExpanded(lineNum, False)
-
- if lastChild > lineNum:
- self.HideLines(lineNum+1, lastChild)
-
- lineNum = lineNum + 1
-
-
-
- def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
- lastChild = self.GetLastChild(line, level)
- line = line + 1
-
- while line <= lastChild:
- if force:
- if visLevels > 0:
- self.ShowLines(line, line)
- else:
- self.HideLines(line, line)
- else:
- if doExpand:
- self.ShowLines(line, line)
-
- if level == -1:
- level = self.GetFoldLevel(line)
-
- if level & stc.STC_FOLDLEVELHEADERFLAG:
- if force:
- if visLevels > 1:
- self.SetFoldExpanded(line, True)
- else:
- self.SetFoldExpanded(line, False)
-
- line = self.Expand(line, doExpand, force, visLevels-1)
-
- else:
- if doExpand and self.GetFoldExpanded(line):
- line = self.Expand(line, True, force, visLevels-1)
- else:
- line = self.Expand(line, False, force, visLevels-1)
- else:
- line = line + 1;
-
- return line
-
-
-#----------------------------------------------------------------------
-
-_USE_PANEL = 1
-
-def runTest(frame, nb, log):
- if not _USE_PANEL:
- ed = p = PythonSTC(nb, -1)
- else:
- p = wx.Panel(nb, -1, style = wx.NO_FULL_REPAINT_ON_RESIZE)
- ed = PythonSTC(p, -1)
- s = wx.BoxSizer(wx.HORIZONTAL)
- s.Add(ed, 1, wx.EXPAND)
- p.SetSizer(s)
- p.SetAutoLayout(True)
-
-
- ed.SetText(demoText + open('Main.py').read())
- ed.EmptyUndoBuffer()
- ed.Colourise(0, -1)
-
- # line numbers in the margin
- ed.SetMarginType(1, stc.STC_MARGIN_NUMBER)
- ed.SetMarginWidth(1, 25)
-
- return p
-
-
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-<html><body>
-Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a>
-and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should
-be helpful.
-</body><html>
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
-
-
-
-
-#----------------------------------------------------------------------
-#----------------------------------------------------------------------
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import sys
-import wx
-
-#---------------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def OnSetFocus(self, evt):
- print "OnSetFocus"
- evt.Skip()
- def OnKillFocus(self, evt):
- print "OnKillFocus"
- evt.Skip()
- def OnWindowDestroy(self, evt):
- print "OnWindowDestroy"
- evt.Skip()
-
-
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- l1 = wx.StaticText(self, -1, "wx.TextCtrl")
- t1 = wx.TextCtrl(self, -1, "Test it out and see", size=(125, -1))
- t1.SetInsertionPoint(0)
- self.tc1 = t1
-
- self.Bind(wx.EVT_TEXT, self.EvtText, t1)
- t1.Bind(wx.EVT_CHAR, self.EvtChar)
- t1.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
- t1.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
- t1.Bind(wx.EVT_WINDOW_DESTROY, self.OnWindowDestroy)
-
- l2 = wx.StaticText(self, -1, "Password")
- t2 = wx.TextCtrl(self, -1, "", size=(125, -1), style=wx.TE_PASSWORD)
- self.Bind(wx.EVT_TEXT, self.EvtText, t2)
-
- l3 = wx.StaticText(self, -1, "Multi-line")
- t3 = wx.TextCtrl(self, -1,
- "Here is a looooooooooooooong line of text set in the control.\n\n"
- "The quick brown fox jumped over the lazy dog...",
- size=(200, 100), style=wx.TE_MULTILINE)
-
- t3.SetInsertionPoint(0)
- self.Bind(wx.EVT_TEXT, self.EvtText, t3)
- b = wx.Button(self, -1, "Test Replace")
- self.Bind(wx.EVT_BUTTON, self.OnTestReplace, b)
- b2 = wx.Button(self, -1, "Test GetSelection")
- self.Bind(wx.EVT_BUTTON, self.OnTestGetSelection, b2)
- b3 = wx.Button(self, -1, "Test WriteText")
- self.Bind(wx.EVT_BUTTON, self.OnTestWriteText, b3)
- self.tc = t3
-
-
- l4 = wx.StaticText(self, -1, "Rich Text")
- t4 = wx.TextCtrl(self, -1, "If supported by the native control, this is red, and this is a different font.",
- size=(200, 100), style=wx.TE_MULTILINE|wx.TE_RICH2)
- t4.SetInsertionPoint(0)
- t4.SetStyle(44, 47, wx.TextAttr("RED", "YELLOW"))
- points = t4.GetFont().GetPointSize() # get the current size
- f = wx.Font(points+3, wx.ROMAN, wx.ITALIC, wx.BOLD, True)
- t4.SetStyle(63, 77, wx.TextAttr("BLUE", wx.NullColour, f))
-
- l5 = wx.StaticText(self, -1, "Test Positions")
- t5 = wx.TextCtrl(self, -1, "0123456789\n" * 5, size=(200, 100),
- style = wx.TE_MULTILINE
- #| wx.TE_RICH
- | wx.TE_RICH2
- )
- t5.Bind(wx.EVT_LEFT_DOWN, self.OnT5LeftDown)
- self.t5 = t5
-
- bsizer = wx.BoxSizer(wx.VERTICAL)
- bsizer.Add(b, 0, wx.GROW|wx.ALL, 4)
- bsizer.Add(b2, 0, wx.GROW|wx.ALL, 4)
- bsizer.Add(b3, 0, wx.GROW|wx.ALL, 4)
-
- sizer = wx.FlexGridSizer(cols=3, hgap=6, vgap=6)
- sizer.AddMany([ l1, t1, (0,0),
- l2, t2, (0,0),
- l3, t3, bsizer,
- l4, t4, (0,0),
- l5, t5, (0,0),
- ])
- border = wx.BoxSizer(wx.VERTICAL)
- border.Add(sizer, 0, wx.ALL, 25)
- self.SetSizer(border)
- self.SetAutoLayout(True)
-
-
- def EvtText(self, event):
- self.log.WriteText('EvtText: %s\n' % event.GetString())
-
-
- def EvtChar(self, event):
- self.log.WriteText('EvtChar: %d\n' % event.GetKeyCode())
- event.Skip()
-
-
- def OnTestReplace(self, evt):
- self.tc.Replace(5, 9, "IS A")
- #self.tc.Remove(5, 9)
-
- def OnTestWriteText(self, evt):
- self.tc.WriteText("TEXT")
-
- def OnTestGetSelection(self, evt):
- start, end = self.tc.GetSelection()
- text = self.tc.GetValue()
- if wx.Platform == "__WXMSW__": # This is why GetStringSelection was added
- text = text.replace('\n', '\r\n')
-
- self.log.write("multi-line GetSelection(): (%d, %d)\n"
- "\tGetStringSelection(): %s\n"
- "\tSelectedText: %s\n" %
- (start, end,
- self.tc.GetStringSelection(),
- repr(text[start:end])))
-
- start, end = self.tc1.GetSelection()
- text = self.tc1.GetValue()
-
- if wx.Platform == "__WXMSW__": # This is why GetStringSelection was added
- text = text.replace('\n', '\r\n')
-
- self.log.write("single-line GetSelection(): (%d, %d)\n"
- "\tGetStringSelection(): %s\n"
- "\tSelectedText: %s\n" %
- (start, end,
- self.tc1.GetStringSelection(),
- repr(text[start:end])))
-
-
- def OnT5LeftDown(self, evt):
- evt.Skip()
- wx.CallAfter(self.LogT5Position, evt)
-
- def LogT5Position(self, evt):
- text = self.t5.GetValue()
- ip = self.t5.GetInsertionPoint()
- lp = self.t5.GetLastPosition()
- self.log.write("LogT5Position:\n"
- "\tGetInsertionPoint:\t%d\n"
- "\ttext[insertionpoint]:\t%s\n"
- "\tGetLastPosition:\t%d\n"
- "\tlen(text):\t\t%d\n"
- % (ip, text[ip], lp, len(text)))
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-overview = """\
-A text control allows text to be displayed and (possibly) edited. It may be single
-line or multi-line, support styles or not, be read-only or not, and even supports
-text masking for such things as passwords.
-
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- dlg = wx.TextEntryDialog(
- frame, 'What is your favorite programming language?',
- 'Duh??', 'Python')
-
- dlg.SetValue("Python is the best!")
-
- if dlg.ShowModal() == wx.ID_OK:
- log.WriteText('You entered: %s\n' % dlg.GetValue())
-
- dlg.Destroy()
-
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-This class represents a dialog that requests a one-line text string from the user.
-It is implemented as a generic wxWindows dialog. Along with the usual wxDialog
-style flags, all of the wxTextCtrl TE_* style flags are accepted, so, for example,
-wx.TE_PASSWORD could be used to create a password dialog.
-
-As with other dialogs of this type, the user input must be retrieved prior to
-destroying the dialog.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wx renamer needed for timectrl lib
-# o presense of spin control causing probs (see spin ctrl demo for details)
-#
-# 12/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o New binders applied. Issues still exist.
-#
-# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o wxTimeCtrl -> TimeCtrl
-# o wxScrolledPanel -> ScrolledPanel
-#
-
-import wx
-import wx.lib.timectrl as timectl
-import wx.lib.scrolledpanel as scrolled
-
-#----------------------------------------------------------------------
-
-class TestPanel( scrolled.ScrolledPanel ):
- def __init__( self, parent, log ):
-
- scrolled.ScrolledPanel.__init__( self, parent, -1 )
- self.log = log
-
-
- text1 = wx.StaticText( self, -1, "12-hour format:")
- self.time12 = timectl.TimeCtrl( self, -1, name="12 hour control" )
- spin1 = wx.SpinButton( self, -1, wx.DefaultPosition, (-1,20), 0 )
- self.time12.BindSpinButton( spin1 )
-
- text2 = wx.StaticText( self, -1, "24-hour format:")
- spin2 = wx.SpinButton( self, -1, wx.DefaultPosition, (-1,20), 0 )
- self.time24 = timectl.TimeCtrl(
- self, -1, name="24 hour control", fmt24hr=True,
- spinButton = spin2
- )
-
- text3 = wx.StaticText( self, -1, "No seconds\nor spin button:")
- self.spinless_ctrl = timectl.TimeCtrl(
- self, -1, name="spinless control",
- display_seconds = False
- )
-
- grid = wx.FlexGridSizer( 0, 2, 10, 5 )
- grid.Add( text1, 0, wx.ALIGN_RIGHT )
- hbox1 = wx.BoxSizer( wx.HORIZONTAL )
- hbox1.Add( self.time12, 0, wx.ALIGN_CENTRE )
- hbox1.Add( spin1, 0, wx.ALIGN_CENTRE )
- grid.Add( hbox1, 0, wx.LEFT )
-
- grid.Add( text2, 0, wx.ALIGN_RIGHT|wx.TOP|wx.BOTTOM )
- hbox2 = wx.BoxSizer( wx.HORIZONTAL )
- hbox2.Add( self.time24, 0, wx.ALIGN_CENTRE )
- hbox2.Add( spin2, 0, wx.ALIGN_CENTRE )
- grid.Add( hbox2, 0, wx.LEFT )
-
- grid.Add( text3, 0, wx.ALIGN_RIGHT|wx.TOP|wx.BOTTOM )
- grid.Add( self.spinless_ctrl, 0, wx.LEFT )
-
-
- buttonChange = wx.Button( self, -1, "Change Controls")
- self.radio12to24 = wx.RadioButton(
- self, -1, "Copy 12-hour time to 24-hour control",
- wx.DefaultPosition, wx.DefaultSize, wx.RB_GROUP
- )
-
- self.radio24to12 = wx.RadioButton(
- self, -1, "Copy 24-hour time to 12-hour control"
- )
-
- self.radioWx = wx.RadioButton( self, -1, "Set controls to 'now' using wxDateTime")
- self.radioMx = wx.RadioButton( self, -1, "Set controls to 'now' using mxDateTime")
-
- radio_vbox = wx.BoxSizer( wx.VERTICAL )
- radio_vbox.Add( self.radio12to24, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- radio_vbox.Add( self.radio24to12, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- radio_vbox.Add( self.radioWx, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- radio_vbox.Add( self.radioMx, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
-
- box_label = wx.StaticBox( self, -1, "Change Controls through API" )
- buttonbox = wx.StaticBoxSizer( box_label, wx.HORIZONTAL )
- buttonbox.Add( buttonChange, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
- buttonbox.Add( radio_vbox, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
-
- hbox = wx.BoxSizer( wx.HORIZONTAL )
- hbox.Add( grid, 0, wx.ALIGN_LEFT|wx.ALL, 15 )
- hbox.Add( buttonbox, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 20 )
-
-
- box_label = wx.StaticBox( self, -1, "Bounds Control" )
- boundsbox = wx.StaticBoxSizer( box_label, wx.HORIZONTAL )
- self.set_bounds = wx.CheckBox( self, -1, "Set time bounds:" )
-
- minlabel = wx.StaticText( self, -1, "minimum time:" )
- self.min = timectl.TimeCtrl( self, -1, name="min", display_seconds = False )
- self.min.Enable( False )
-
- maxlabel = wx.StaticText( self, -1, "maximum time:" )
- self.max = timectl.TimeCtrl( self, -1, name="max", display_seconds = False )
- self.max.Enable( False )
-
- self.limit_check = wx.CheckBox( self, -1, "Limit control" )
-
- label = wx.StaticText( self, -1, "Resulting time control:" )
- self.target_ctrl = timectl.TimeCtrl( self, -1, name="new" )
-
- grid2 = wx.FlexGridSizer( 0, 2, 0, 0 )
- grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid2.Add( self.set_bounds, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid3 = wx.FlexGridSizer( 0, 2, 5, 5 )
- grid3.Add(minlabel, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL )
- grid3.Add( self.min, 0, wx.ALIGN_LEFT )
- grid3.Add(maxlabel, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL )
- grid3.Add( self.max, 0, wx.ALIGN_LEFT )
- grid2.Add(grid3, 0, wx.ALIGN_LEFT )
-
- grid2.Add( self.limit_check, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
- grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid2.Add( (20, 0), 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- grid2.Add( label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
- grid2.Add( self.target_ctrl, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
- boundsbox.Add(grid2, 0, wx.ALIGN_CENTER|wx.EXPAND|wx.ALL, 5)
-
- vbox = wx.BoxSizer( wx.VERTICAL )
- vbox.Add( (20, 20) )
- vbox.Add( hbox, 0, wx.ALIGN_LEFT|wx.ALL, 5)
- vbox.Add( boundsbox, 0, wx.ALIGN_LEFT|wx.ALL, 5 )
-
-
- outer_box = wx.BoxSizer( wx.VERTICAL )
- outer_box.Add( vbox, 0, wx.ALIGN_LEFT|wx.ALL, 5)
-
-
- # Turn on mxDateTime option only if we can import the module:
- try:
- from mx import DateTime
- except ImportError:
- self.radioMx.Enable( False )
-
-
- self.SetAutoLayout( True )
- self.SetSizer( outer_box )
- outer_box.Fit( self )
- self.SetupScrolling()
-
- self.Bind(wx.EVT_BUTTON, self.OnButtonClick, buttonChange )
- self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.time12 )
- self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.time24 )
- self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.spinless_ctrl )
- self.Bind(wx.EVT_CHECKBOX, self.OnBoundsCheck, self.set_bounds )
- self.Bind(wx.EVT_CHECKBOX, self.SetTargetMinMax, self.limit_check )
- self.Bind(timectl.EVT_TIMEUPDATE, self.SetTargetMinMax, self.min )
- self.Bind(timectl.EVT_TIMEUPDATE, self.SetTargetMinMax, self.max )
- self.Bind(timectl.EVT_TIMEUPDATE, self.OnTimeChange, self.target_ctrl )
-
-
- def OnTimeChange( self, event ):
- timectrl = self.FindWindowById( event.GetId() )
- ib_str = [ " (out of bounds)", "" ]
-
- self.log.write('%s time = %s%s\n' % ( timectrl.GetName(), timectrl.GetValue(), ib_str[ timectrl.IsInBounds() ] ) )
-
-
- def OnButtonClick( self, event ):
- if self.radio12to24.GetValue():
- self.time24.SetValue( self.time12.GetValue() )
-
- elif self.radio24to12.GetValue():
- self.time12.SetValue( self.time24.GetValue() )
-
- elif self.radioWx.GetValue():
- now = wx.DateTime_Now()
- self.time12.SetValue( now )
- # (demonstrates that G/SetValue returns/takes a wxDateTime)
- self.time24.SetValue( self.time12.GetValue(as_wxDateTime=True) )
-
- # (demonstrates that G/SetValue returns/takes a wxTimeSpan)
- self.spinless_ctrl.SetValue( self.time12.GetValue(as_wxTimeSpan=True) )
-
- elif self.radioMx.GetValue():
- from mx import DateTime
- now = DateTime.now()
- self.time12.SetValue( now )
-
- # (demonstrates that G/SetValue returns/takes a DateTime)
- self.time24.SetValue( self.time12.GetValue(as_mxDateTime=True) )
-
- # (demonstrates that G/SetValue returns/takes a DateTimeDelta)
- self.spinless_ctrl.SetValue( self.time12.GetValue(as_mxDateTimeDelta=True) )
-
-
- def OnBoundsCheck( self, event ):
- self.min.Enable( self.set_bounds.GetValue() )
- self.max.Enable( self.set_bounds.GetValue() )
- self.SetTargetMinMax()
-
-
- def SetTargetMinMax( self, event=None ):
- min = None
- max = None
-
- if self.set_bounds.GetValue():
- min = self.min.GetWxDateTime()
- max = self.max.GetWxDateTime()
- else:
- min, max = None, None
-
- cur_min, cur_max = self.target_ctrl.GetBounds()
-
- # jmg - A little expirimental change to ensure that min
- # or max contain valid values before we use them
- if min and (min != cur_min): self.target_ctrl.SetMin( min )
- if max and (max != cur_max): self.target_ctrl.SetMax( max )
-
- self.target_ctrl.SetLimited( self.limit_check.GetValue() )
-
- if min != cur_min or max != cur_max:
- new_min, new_max = self.target_ctrl.GetBounds()
-
- if new_min and new_max:
- self.log.write( "current min, max: (%s, %s)\n" % ( new_min.FormatTime(), new_max.FormatTime() ) )
- else:
- self.log.write( "current min, max: (None, None)\n" )
-
-#----------------------------------------------------------------------
-
-def runTest( frame, nb, log ):
- win = TestPanel( nb, log )
- return win
-
-#----------------------------------------------------------------------
-
-overview = timectl.__doc__
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import time
-import wx
-
-#---------------------------------------------------------------------------
-
-## For your convenience; an example of creating your own timer class.
-##
-## class TestTimer(wxTimer):
-## def __init__(self, log = None):
-## wxTimer.__init__(self)
-## self.log = log
-## def Notify(self):
-## wxBell()
-## if self.log:
-## self.log.WriteText('beep!\n')
-
-#---------------------------------------------------------------------------
-
-ID_Start = wx.NewId()
-ID_Stop = wx.NewId()
-ID_Timer = wx.NewId()
-ID_Timer2 = wx.NewId()
-
-class TestTimerWin(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- wx.StaticText(self, -1, "This is a timer example", (15, 30))
- wx.Button(self, ID_Start, ' Start ', (15, 75), wx.DefaultSize)
- wx.Button(self, ID_Stop, ' Stop ', (115, 75), wx.DefaultSize)
-
- self.timer = wx.Timer(self, # object to send the event to
- ID_Timer) # event id to use
-
- self.timer2 = wx.Timer(self, # object to send the event to
- ID_Timer2) # event id to use
-
- self.Bind(wx.EVT_BUTTON, self.OnStart, id=ID_Start)
- self.Bind(wx.EVT_BUTTON, self.OnStop, id=ID_Stop)
- self.Bind(wx.EVT_TIMER, self.OnTimer, id=ID_Timer)
- self.Bind(wx.EVT_TIMER, self.OnTimer2, id=ID_Timer2)
-
- def OnStart(self, event):
- self.timer.Start(1000)
- self.timer2.Start(1500)
-
- def OnStop(self, event):
- self.timer.Stop()
- self.timer2.Stop()
-
- def OnTimer(self, event):
- wx.Bell()
- if self.log:
- self.log.WriteText('beep!\n')
-
- def OnTimer2(self, event):
- wx.Bell()
- if self.log:
- self.log.WriteText('beep 2!\n')
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestTimerWin(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-The wxTimer class allows you to execute code at specified intervals from
-within the wxPython event loop. Timers can be one-shot or repeating.
-
-"""
-
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-haveToggleBtn = 1
-
-try:
- wx.ToggleButton
-except NameError:
- haveToggleBtn = 0
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
- panel = wx.Panel(self, -1)
- buttons = wx.BoxSizer(wx.HORIZONTAL)
-
- for word in "These are toggle buttons".split():
- b = wx.ToggleButton(panel, -1, word)
- self.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggle, b)
- buttons.Add(b, flag=wx.ALL, border=5)
-
- panel.SetAutoLayout(True)
- panel.SetSizer(buttons)
- buttons.Fit(panel)
- panel.Move((50,50))
-
- def OnToggle(self, evt):
- self.log.write("Button %d toggled\n" % evt.GetId())
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- if haveToggleBtn:
- win = TestPanel(nb, log)
- return win
- else:
- dlg = wx.MessageDialog(frame, 'wxToggleButton is not available on this platform.',
- 'Sorry', wx.OK | wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-wxToggleButton is a button that stays pressed when clicked by the user.
-In other words, it is similar to wxCheckBox in functionality but looks like a
-wxButton.
-
-This class is only available under wxMSW and wxGTK currently.
-
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import images
-
-#---------------------------------------------------------------------------
-
-class TestToolBar(wx.Frame):
- def __init__(self, parent, log):
- wx.Frame.__init__(self, parent, -1, 'Test ToolBar', size=(500, 300))
- self.log = log
- self.timer = None
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
- wx.Window(self, -1).SetBackgroundColour(wx.NamedColour("WHITE"))
-
- # Use the wxFrame internals to create the toolbar and associate it all
- # in one tidy method call.
- tb = self.CreateToolBar( wx.TB_HORIZONTAL
- | wx.NO_BORDER
- | wx.TB_FLAT
- | wx.TB_TEXT
- )
-
- # Here's a 'simple' toolbar example, and how to bind it using SetToolBar()
- #tb = wx.ToolBarSimple(self, -1, wx.DefaultPosition, wx.DefaultSize,
- # wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
- #self.SetToolBar(tb)
- # But we're doing it a different way here.
-
- log.write("Default toolbar tool size: %s\n" % tb.GetToolBitmapSize())
-
- self.CreateStatusBar()
-
- tb.AddSimpleTool(10, images.getNewBitmap(), "New", "Long help for 'New'")
- #tb.AddLabelTool(10, "New", images.getNewBitmap(), shortHelp="New", longHelp="Long help for 'New'")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=10)
-
- tb.AddSimpleTool(20, images.getOpenBitmap(), "Open", "Long help for 'Open'")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=20)
-
- tb.AddSeparator()
- tb.AddSimpleTool(30, images.getCopyBitmap(), "Copy", "Long help for 'Copy'")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=30)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=30)
-
- tb.AddSimpleTool(40, images.getPasteBitmap(), "Paste", "Long help for 'Paste'")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=40)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick, id=40)
-
- tb.AddSeparator()
-
- tool = tb.AddCheckTool(50, images.getTog1Bitmap(),
- shortHelp="Toggle this")
- self.Bind(wx.EVT_TOOL, self.OnToolClick, id=50)
-
-## tb.AddCheckTool(60, images.getTog1Bitmap(), images.getTog2Bitmap(),
-## shortHelp="Toggle with 2 bitmaps")
-## self.Bind(EVT_TOOL, self.OnToolClick, id=60)
-
- self.Bind(wx.EVT_TOOL_ENTER, self.OnToolEnter)
- self.Bind(wx.EVT_TOOL_RCLICKED, self.OnToolRClick) # Match all
- self.Bind(wx.EVT_TIMER, self.OnClearSB)
-
- tb.AddSeparator()
- cbID = wx.NewId()
-
- tb.AddControl(
- wx.ComboBox(
- tb, cbID, "", choices=["", "This", "is a", "wxComboBox"],
- size=(150,-1), style=wx.CB_DROPDOWN
- ))
-
- self.Bind(wx.EVT_COMBOBOX, self.OnCombo, id=cbID)
- tb.AddControl(wx.TextCtrl(tb, -1, "Toolbar controls!!", size=(150, -1)))
-
- # Final thing to do for a toolbar is call the Realize() method. This
- # causes it to render (more or less, that is).
- tb.Realize()
-
-
- def OnToolClick(self, event):
- self.log.WriteText("tool %s clicked\n" % event.GetId())
- tb = self.GetToolBar()
- tb.EnableTool(10, not tb.GetToolEnabled(10))
-
- def OnToolRClick(self, event):
- self.log.WriteText("tool %s right-clicked\n" % event.GetId())
-
- def OnCombo(self, event):
- self.log.WriteText("combobox item selected: %s\n" % event.GetString())
-
- def OnToolEnter(self, event):
- self.log.WriteText('OnToolEnter: %s, %s\n' % (event.GetId(), event.GetInt()))
-
- if self.timer is None:
- self.timer = wx.Timer(self)
-
- if self.timer.IsRunning():
- self.timer.Stop()
-
- self.timer.Start(2000)
- event.Skip()
-
-
- def OnClearSB(self, event): # called for the timer event handler
- self.SetStatusText("")
- self.timer.Stop()
- self.timer = None
-
-
- def OnCloseWindow(self, event):
- if self.timer is not None:
- self.timer.Stop()
- self.timer = None
- self.Destroy()
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestToolBar(frame, log)
- frame.otherWin = win
- win.Show(True)
-
-#---------------------------------------------------------------------------
-
-
-
-overview = """\
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import string
-import wx
-import images
-
-#---------------------------------------------------------------------------
-
-class MyTreeCtrl(wx.TreeCtrl):
- def __init__(self, parent, id, pos, size, style, log):
- wx.TreeCtrl.__init__(self, parent, id, pos, size, style)
- self.log = log
-
- def OnCompareItems(self, item1, item2):
- t1 = self.GetItemText(item1)
- t2 = self.GetItemText(item2)
- self.log.WriteText('compare: ' + t1 + ' <> ' + t2 + '\n')
- if t1 < t2: return -1
- if t1 == t2: return 0
- return 1
-
-#---------------------------------------------------------------------------
-
-class TestTreeCtrlPanel(wx.Panel):
- def __init__(self, parent, log):
- # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
- wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
- self.Bind(wx.EVT_SIZE, self.OnSize)
-
- self.log = log
- tID = wx.NewId()
-
- self.tree = MyTreeCtrl(self, tID, wx.DefaultPosition, wx.DefaultSize,
- wx.TR_HAS_BUTTONS
- | wx.TR_EDIT_LABELS
- #| wx.TR_MULTIPLE
- #| wx.TR_HIDE_ROOT
- , self.log)
-
- isz = (16,16)
- il = wx.ImageList(isz[0], isz[1])
- fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
- fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
- fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_REPORT_VIEW, wx.ART_OTHER, isz))
- smileidx = il.Add(images.getSmilesBitmap())
-
- self.tree.SetImageList(il)
- self.il = il
-
- # NOTE: For some reason tree items have to have a data object in
- # order to be sorted. Since our compare just uses the labels
- # we don't need any real data, so we'll just use None below for
- # the item data.
-
- self.root = self.tree.AddRoot("The Root Item")
- self.tree.SetPyData(self.root, None)
- self.tree.SetItemImage(self.root, fldridx, wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(self.root, fldropenidx, wx.TreeItemIcon_Expanded)
-
-
- for x in range(15):
- child = self.tree.AppendItem(self.root, "Item %d" % x)
- self.tree.SetPyData(child, None)
- self.tree.SetItemImage(child, fldridx, wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(child, fldropenidx, wx.TreeItemIcon_Expanded)
-
- for y in range(5):
- last = self.tree.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y)))
- self.tree.SetPyData(last, None)
- self.tree.SetItemImage(last, fldridx, wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(last, fldropenidx, wx.TreeItemIcon_Expanded)
-
- for z in range(5):
- item = self.tree.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z))
- self.tree.SetPyData(item, None)
- self.tree.SetItemImage(item, fileidx, wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(item, smileidx, wx.TreeItemIcon_Selected)
-
- self.tree.Expand(self.root)
- self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, self.tree)
- self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.tree)
- self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree)
- self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.tree)
- self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndEdit, self.tree)
- self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate, self.tree)
-
- self.tree.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
- self.tree.Bind(wx.EVT_RIGHT_DOWN, self.OnRightClick)
- self.tree.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
-
-
-
- def OnRightClick(self, event):
- pt = event.GetPosition();
- item, flags = self.tree.HitTest(pt)
- self.log.WriteText("OnRightClick: %s, %s, %s\n" %
- (self.tree.GetItemText(item), type(item), item.__class__))
- self.tree.SelectItem(item)
-
-
- def OnRightUp(self, event):
- pt = event.GetPosition();
- item, flags = self.tree.HitTest(pt)
- self.log.WriteText("OnRightUp: %s (manually starting label edit)\n"
- % self.tree.GetItemText(item))
- self.tree.EditLabel(item)
-
-
-
- def OnBeginEdit(self, event):
- self.log.WriteText("OnBeginEdit\n")
- # show how to prevent edit...
- if self.tree.GetItemText(event.GetItem()) == "The Root Item":
- wx.Bell()
- self.log.WriteText("You can't edit this one...\n")
-
- # Lets just see what's visible of its children
- cookie = 0
- root = event.GetItem()
- (child, cookie) = self.tree.GetFirstChild(root, cookie)
-
- while child.IsOk():
- self.log.WriteText("Child [%s] visible = %d" %
- (self.tree.GetItemText(child),
- self.tree.IsVisible(child)))
- (child, cookie) = self.tree.GetNextChild(root, cookie)
-
- event.Veto()
-
-
- def OnEndEdit(self, event):
- self.log.WriteText("OnEndEdit\n")
- # show how to reject edit, we'll not allow any digits
- for x in event.GetLabel():
- if x in string.digits:
- self.log.WriteText("You can't enter digits...\n")
- event.Veto()
- return
-
-
- def OnLeftDClick(self, event):
- pt = event.GetPosition();
- item, flags = self.tree.HitTest(pt)
- self.log.WriteText("OnLeftDClick: %s\n" % self.tree.GetItemText(item))
- parent = self.tree.GetItemParent(item)
- self.tree.SortChildren(parent)
- event.Skip()
-
-
- def OnSize(self, event):
- w,h = self.GetClientSizeTuple()
- self.tree.SetDimensions(0, 0, w, h)
-
-
- def OnItemExpanded(self, event):
- item = event.GetItem()
- self.log.WriteText("OnItemExpanded: %s\n" % self.tree.GetItemText(item))
-
- def OnItemCollapsed(self, event):
- item = event.GetItem()
- self.log.WriteText("OnItemCollapsed: %s\n" % self.tree.GetItemText(item))
-
- def OnSelChanged(self, event):
- self.item = event.GetItem()
- self.log.WriteText("OnSelChanged: %s\n" % self.tree.GetItemText(self.item))
- if wx.Platform == '__WXMSW__':
- self.log.WriteText("BoundingRect: %s\n" %
- self.tree.GetBoundingRect(self.item, True))
- #items = self.tree.GetSelections()
- #print map(self.tree.GetItemText, items)
- event.Skip()
-
-
- def OnActivate(self, event):
- self.log.WriteText("OnActivate: %s\n" % self.tree.GetItemText(self.item))
-
-
-#---------------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestTreeCtrlPanel(nb, log)
- return win
-
-#---------------------------------------------------------------------------
-
-
-
-
-
-overview = """\
-A tree control presents information as a hierarchy, with items that may be
-expanded to show further items. Items in a tree control are referenced by
-wxTreeItemId handles.
-
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import wx.gizmos as gizmos
-
-import images
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
- self.Bind(wx.EVT_SIZE, self.OnSize)
-
- self.tree = gizmos.TreeListCtrl(self, -1, style = wx.TR_DEFAULT_STYLE
- #| wx.TR_ROW_LINES
- #| wx.TR_NO_LINES
- #| wx.TR_TWIST_BUTTONS
- )
- isz = (16,16)
- il = wx.ImageList(isz[0], isz[1])
- fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
- fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
- fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_REPORT_VIEW, wx.ART_OTHER, isz))
- smileidx = il.Add(images.getSmilesBitmap())
-
- self.tree.SetImageList(il)
- self.il = il
-
- # create some columns
- self.tree.AddColumn("Main column")
- self.tree.AddColumn("Column 1")
- self.tree.AddColumn("Column 2")
- self.tree.SetMainColumn(0) # the one with the tree in it...
- self.tree.SetColumnWidth(0, 175)
-
-
- self.root = self.tree.AddRoot("The Root Item")
- self.tree.SetItemText(self.root, "col 1 root", 1)
- self.tree.SetItemText(self.root, "col 2 root", 2)
- self.tree.SetItemImage(self.root, fldridx, which = wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(self.root, fldropenidx, which = wx.TreeItemIcon_Expanded)
-
-
- for x in range(15):
- txt = "Item %d" % x
- child = self.tree.AppendItem(self.root, txt)
- self.tree.SetItemText(child, txt + "(c1)", 1)
- self.tree.SetItemText(child, txt + "(c2)", 2)
- self.tree.SetItemImage(child, fldridx, which = wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(child, fldropenidx, which = wx.TreeItemIcon_Expanded)
-
- for y in range(5):
- txt = "item %d-%s" % (x, chr(ord("a")+y))
- last = self.tree.AppendItem(child, txt)
- self.tree.SetItemText(last, txt + "(c1)", 1)
- self.tree.SetItemText(last, txt + "(c2)", 2)
- self.tree.SetItemImage(last, fldridx, which = wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(last, fldropenidx, which = wx.TreeItemIcon_Expanded)
-
- for z in range(5):
- txt = "item %d-%s-%d" % (x, chr(ord("a")+y), z)
- item = self.tree.AppendItem(last, txt)
- self.tree.SetItemText(item, txt + "(c1)", 1)
- self.tree.SetItemText(item, txt + "(c2)", 2)
- self.tree.SetItemImage(item, fileidx, which = wx.TreeItemIcon_Normal)
- self.tree.SetItemImage(item, smileidx, which = wx.TreeItemIcon_Selected)
-
-
- self.tree.Expand(self.root)
-
- self.tree.GetMainWindow().Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
-
-
- def OnRightUp(self, evt):
- # Convert the position from being relative to the subwindow to
- # being relative to the outer treelist window so HitTest will
- # have the point it is expecting.
- pos = evt.GetPosition()
- pos = self.tree.GetMainWindow().ClientToScreen(pos)
- pos = self.tree.ScreenToClient(pos)
- item, flags, col = self.tree.HitTest(pos)
-
- if item:
- print flags, col, self.tree.GetItemText(item, col)
-
-
- def OnSize(self, evt):
- self.tree.SetSize(self.GetSize())
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>wxTreeListCtrl</center></h2>
-
-The wx.TreeListCtrl is essentially a wx.TreeCtrl with extra columns,
-such that the look is similar to a wx.ListCtrl.
-
-</body></html>
-"""
-
-
-if __name__ == '__main__':
- #raw_input("Press enter...")
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-#----------------------------------------------------------------------
-
-# The wxVListBox is much like a regular wxListBox except you draw the
-# items yourself and the items can vary in height.
-class MyVListBox(wx.VListBox):
-
- # This method must be overridden. When called it should draw the
- # n'th item on the dc within the rect. How it is drawn, and what
- # is drawn is entirely up to you.
- def OnDrawItem(self, dc, rect, n):
- if self.GetSelection() == n:
- c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
- else:
- c = self.GetForegroundColour()#wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
- dc.SetTextForeground(c)
- dc.DrawLabel(self._getItemText(n), rect,
- wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
-
- # This method must be overridden. It should return the height
- # required to draw the n'th item.
- def OnMeasureItem(self, n):
- height = 0
-
- for line in self._getItemText(n).split('\n'):
- w, h = self.GetTextExtent(line)
- height += h
-
- return height + 5
-
-
- # These are also overridable:
- #
- # OnDrawSeparator(dc, rect, n)
- # Draw a separator between items. Note that rect may be reduced
- # in size if desired so OnDrawItem gets a smaller rect.
- #
- # OnDrawBackground(dc, rect, n)
- # Draw the background and maybe a border if desired.
-
-
- def _getItemText(self, item):
- if item % 2 == 0:
- return "This is item# %d" % item
- else:
- return "This is item# %d\n with an extra line" % item
-
-#----------------------------------------------------------------------
-
-# The wx.HtmlListBox derives from wx.VListBox, but draws each item
-# itself as a wx.HtmlCell.
-class MyHtmlListBox(wx.HtmlListBox):
-
- def OnGetItem(self, n):
- if n % 2 == 0:
- return "This is item# <b>%d</b>" % n
- else:
- return "This is item# <b>%d</b> <br>Any <font color='RED'>HTML</font> is okay." % n
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
- spacer = 50
-
- vlb = MyVListBox(self, -1, size=(150, 250), style=wx.BORDER_SUNKEN)
- vlb.SetItemCount(50)
- vlb.SetSelection(0)
- vlb.SetFocus()
- vlbSizer = wx.BoxSizer(wx.VERTICAL)
- vlbSizer.Add((spacer, spacer))
- vlbSizer.Add(wx.StaticText(self, -1, "wx.VListBox"), 0, 5, wx.ALL)
- vlbSizer.Add(vlb)
-
- hlb = MyHtmlListBox(self, -1, size=(150, 250), style=wx.BORDER_SUNKEN)
- hlb.SetItemCount(50)
- hlb.SetSelection(0)
- hlbSizer = wx.BoxSizer(wx.VERTICAL)
- hlbSizer.Add((spacer, spacer))
- hlbSizer.Add(wx.StaticText(self, -1, "wx.HtmlListBox"), 0, 5, wx.ALL)
- hlbSizer.Add(hlb)
-
- sizer = wx.BoxSizer(wx.HORIZONTAL)
- sizer.Add((spacer, spacer))
- sizer.Add(vlbSizer)
- sizer.Add((spacer, spacer))
- sizer.Add((spacer, spacer))
- sizer.Add(hlbSizer)
-
- self.SetSizer(sizer)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>wxVListBox and wxHtmlListBox</center></h2>
-<hr>
-
-The "V" in wxVListBox stands for both "virtual" because it can have an
-unlimited number of items since it doesn't store them itself, and
-"variable" since items can vary in height. It has much the same
-interface as wxListBox and also emits the same events so you can use
-the same EVT_LISTBOX function to connect a handler.
-<p>
-
-The wxHtmlListBox derives from wxVListBox, but draws each item itself
-as a wxHtmlCell. This means that you just need to provide a snippet
-of HTML for each item when requested.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import string
-import wx
-
-
-#----------------------------------------------------------------------
-
-ALPHA_ONLY = 1
-DIGIT_ONLY = 2
-
-class MyValidator(wx.PyValidator):
- def __init__(self, flag=None, pyVar=None):
- wx.PyValidator.__init__(self)
- self.flag = flag
- self.Bind(wx.EVT_CHAR, self.OnChar)
-
- def Clone(self):
- return MyValidator(self.flag)
-
- def Validate(self, win):
- tc = self.GetWindow()
- val = tc.GetValue()
-
- if self.flag == ALPHA_ONLY:
- for x in val:
- if x not in string.letters:
- return False
-
- elif self.flag == DIGIT_ONLY:
- for x in val:
- if x not in string.digits:
- return False
-
- return True
-
-
- def OnChar(self, event):
- key = event.KeyCode()
-
- if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
- event.Skip()
- return
-
- if self.flag == ALPHA_ONLY and chr(key) in string.letters:
- event.Skip()
- return
-
- if self.flag == DIGIT_ONLY and chr(key) in string.digits:
- event.Skip()
- return
-
- if not wx.Validator_IsSilent():
- wx.Bell()
-
- # Returning without calling even.Skip eats the event before it
- # gets to the text control
- return
-
-#----------------------------------------------------------------------
-
-class TestValidatorPanel(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent, -1)
- self.SetAutoLayout(True)
- VSPACE = 10
-
- fgs = wx.FlexGridSizer(0, 2)
-
- fgs.Add((1,1))
- fgs.Add(wx.StaticText(self, -1, "These controls have validators that limit\n"
- "the type of characters that can be entered."))
-
- fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
-
- label = wx.StaticText(self, -1, "Alpha Only: ")
- fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
-
- fgs.Add(wx.TextCtrl(self, -1, "", validator = MyValidator(ALPHA_ONLY)))
-
- fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
-
- label = wx.StaticText(self, -1, "Digits Only: ")
- fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
- fgs.Add(wx.TextCtrl(self, -1, "", validator = MyValidator(DIGIT_ONLY)))
-
- fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
- fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
- fgs.Add((0,0))
- b = wx.Button(self, -1, "Test Dialog Validation")
- self.Bind(wx.EVT_BUTTON, self.OnDoDialog, b)
- fgs.Add(b)
-
- border = wx.BoxSizer()
- border.Add(fgs, 1, wx.GROW|wx.ALL, 25)
- self.SetSizer(border)
- self.Layout()
-
- def OnDoDialog(self, evt):
- dlg = TestValidateDialog(self)
- dlg.ShowModal()
- dlg.Destroy()
-
-
-#----------------------------------------------------------------------
-
-class TextObjectValidator(wx.PyValidator):
- """ This validator is used to ensure that the user has entered something
- into the text object editor dialog's text field.
- """
- def __init__(self):
- """ Standard constructor.
- """
- wx.PyValidator.__init__(self)
-
-
-
- def Clone(self):
- """ Standard cloner.
-
- Note that every validator must implement the Clone() method.
- """
- return TextObjectValidator()
-
-
- def Validate(self, win):
- """ Validate the contents of the given text control.
- """
- textCtrl = self.GetWindow()
- text = textCtrl.GetValue()
-
- if len(text) == 0:
- wx.MessageBox("A text object must contain some text!", "Error")
- textCtrl.SetBackgroundColour("pink")
- textCtrl.SetFocus()
- textCtrl.Refresh()
- return False
- else:
- textCtrl.SetBackgroundColour(
- wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
- textCtrl.Refresh()
- return True
-
-
- def TransferToWindow(self):
- """ Transfer data from validator to window.
-
- The default implementation returns False, indicating that an error
- occurred. We simply return True, as we don't do any data transfer.
- """
- return True # Prevent wxDialog from complaining.
-
-
- def TransferFromWindow(self):
- """ Transfer data from window to validator.
-
- The default implementation returns False, indicating that an error
- occurred. We simply return True, as we don't do any data transfer.
- """
- return True # Prevent wxDialog from complaining.
-
-#----------------------------------------------------------------------
-
-class TestValidateDialog(wx.Dialog):
- def __init__(self, parent):
- wx.Dialog.__init__(self, parent, -1, "Validated Dialog")
-
- self.SetAutoLayout(True)
- VSPACE = 10
-
- fgs = wx.FlexGridSizer(0, 2)
-
- fgs.Add((1,1));
- fgs.Add(wx.StaticText(self, -1,
- "These controls must have text entered into them. Each\n"
- "one has a validator that is checked when the Okay\n"
- "button is clicked."))
-
- fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
-
- label = wx.StaticText(self, -1, "First: ")
- fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
-
- fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator()))
-
- fgs.Add((1,VSPACE)); fgs.Add((1,VSPACE))
-
- label = wx.StaticText(self, -1, "Second: ")
- fgs.Add(label, 0, wx.ALIGN_RIGHT|wx.CENTER)
- fgs.Add(wx.TextCtrl(self, -1, "", validator = TextObjectValidator()))
-
-
- buttons = wx.BoxSizer(wx.HORIZONTAL)
- b = wx.Button(self, wx.ID_OK, "Okay")
- b.SetDefault()
- buttons.Add(b, 0, wx.ALL, 10)
- buttons.Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), 0, wx.ALL, 10)
-
- border = wx.BoxSizer(wx.VERTICAL)
- border.Add(fgs, 1, wx.GROW|wx.ALL, 25)
- border.Add(buttons)
- self.SetSizer(border)
- border.Fit(self)
- self.Layout()
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestValidatorPanel(nb)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """\
-<html>
-<body>
-wxValidator is the base class for a family of validator classes that mediate
-between a class of control, and application data.
-
-<p>A validator has three major roles:
-
-<p><ol>
-<li>to transfer data from a C++ variable or own storage to and from a control;
-<li>to validate data in a control, and show an appropriate error message;
-<li>to filter events (such as keystrokes), thereby changing the behaviour of the associated control.
-</ol>
-<p>Validators can be plugged into controls dynamically.
-</body>
-</html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-
-from Main import opj
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent, -1)
-
- b = wx.Button(self, -1, "Play Sound 1", (25, 25))
- self.Bind(wx.EVT_BUTTON, self.OnButton1, b)
-
- b = wx.Button(self, -1, "Play Sound 2", (25, 65))
- self.Bind(wx.EVT_BUTTON, self.OnButton2, b)
-
-
- def OnButton1(self, evt):
- try:
- wave = wx.Wave(opj('data/anykey.wav'))
- wave.Play()
- except NotImplementedError, v:
- wx.MessageBox(str(v), "Exception Message")
-
-
- def OnButton2(self, evt):
- try:
- wave = wx.Wave(opj('data/plan.wav'))
- wave.Play()
- except NotImplementedError, v:
- wx.MessageBox(str(v), "Exception Message")
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb)
- return win
-
-#----------------------------------------------------------------------
-
-
-overview = """\
-This class represents a short wave file, in Windows WAV format, that can
-be stored in memory and played. Currently this class is implemented on Windows
-and GTK (Linux) only.
-
-This demo offers two examples, both driven by buttons, but obviously the event
-that drives the playing of the sound can come from anywhere.
-
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-# 11/3-/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o WizardPage* doesn't support GetId()
-#
-
-import wx
-import wx.wizard as wiz
-import images
-
-#----------------------------------------------------------------------
-
-def makePageTitle(wizPg, title):
- sizer = wx.BoxSizer(wx.VERTICAL)
- wizPg.SetSizer(sizer)
- title = wx.StaticText(wizPg, -1, title)
- title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
- sizer.AddWindow(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- sizer.AddWindow(wx.StaticLine(wizPg, -1), 0, wx.EXPAND|wx.ALL, 5)
- return sizer
-
-#----------------------------------------------------------------------
-
-class TitledPage(wiz.WizardPageSimple):
- def __init__(self, parent, title):
- wiz.WizardPageSimple.__init__(self, parent)
- self.sizer = makePageTitle(self, title)
-
-
-#----------------------------------------------------------------------
-
-class SkipNextPage(wiz.PyWizardPage):
- def __init__(self, parent, title):
- wiz.PyWizardPage.__init__(self, parent)
- self.next = self.prev = None
- self.sizer = makePageTitle(self, title)
-
- self.cb = wx.CheckBox(self, -1, "Skip next page")
- self.sizer.Add(self.cb, 0, wx.ALL, 5)
-
- def SetNext(self, next):
- self.next = next
-
- def SetPrev(self, prev):
- self.prev = prev
-
-
- # Classes derived from wxPyWizardPanel must override
- # GetNext and GetPrev, and may also override GetBitmap
- # as well as all those methods overridable by
- # wx.PyWindow.
-
- def GetNext(self):
- """If the checkbox is set then return the next page's next page"""
- next = self.next
- if self.cb.GetValue():
- next = next.GetNext()
- return next
-
- def GetPrev(self):
- return self.prev
-
-#----------------------------------------------------------------------
-
-class UseAltBitmapPage(wiz.PyWizardPage):
- def __init__(self, parent, title):
- wiz.PyWizardPage.__init__(self, parent)
- self.next = self.prev = None
- self.sizer = makePageTitle(self, title)
-
- self.sizer.Add(wx.StaticText(self, -1, "This page uses a different bitmap"),
- 0, wx.ALL, 5)
-
- def SetNext(self, next):
- self.next = next
-
- def SetPrev(self, prev):
- self.prev = prev
-
- def GetNext(self):
- return self.next
-
- def GetPrev(self):
- return self.prev
-
- def GetBitmap(self):
- # You usually wouldn't need to override this method
- # since you can set a non-default bitmap in the
- # wxWizardPageSimple constructor, but if you need to
- # dynamically change the bitmap based on the
- # contents of the wizard, or need to also change the
- # next/prev order then it can be done by overriding
- # GetBitmap.
- return images.getWizTest2Bitmap()
-
-#----------------------------------------------------------------------
-
-class TestPanel(wx.Panel):
- ID_wiz = wx.NewId()
-
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- b = wx.Button(self, -1, "Run Simple Wizard", pos=(50, 50))
- self.Bind(wx.EVT_BUTTON, self.OnRunSimpleWizard, b)
-
- b = wx.Button(self, -1, "Run Dynamic Wizard", pos=(50, 100))
- self.Bind(wx.EVT_BUTTON, self.OnRunDynamicWizard, b)
-
- wiz.EVT_WIZARD_PAGE_CHANGED(self, self.ID_wiz, self.OnWizPageChanged)
- wiz.EVT_WIZARD_PAGE_CHANGING(self, self.ID_wiz, self.OnWizPageChanging)
- wiz.EVT_WIZARD_CANCEL(self, self.ID_wiz, self.OnWizCancel)
-
-
- def OnWizPageChanged(self, evt):
- if evt.GetDirection():
- dir = "forward"
- else:
- dir = "backward"
-
- page = evt.GetPage()
- self.log.write("OnWizPageChanged: %s, %s\n" % (dir, page.__class__))
-
-
- def OnWizPageChanging(self, evt):
- if evt.GetDirection():
- dir = "forward"
- else:
- dir = "backward"
-
- page = evt.GetPage()
- self.log.write("OnWizPageChanging: %s, %s\n" % (dir, page.__class__))
-
-
- def OnWizCancel(self, evt):
- page = evt.GetPage()
- self.log.write("OnWizCancel: %s\n" % page.__class__)
-
- # Show how to prevent cancelling of the wizard. The
- # other events can be Veto'd too.
- if page is self.page1:
- wx.MessageBox("Cancelling on the first page has been prevented.", "Sorry")
- evt.Veto()
-
- def OnWizFinished(self, evt):
- self.log.write("OnWizFinished\n")
-
-
- def OnRunSimpleWizard(self, evt):
- # Create the wizard and the pages
- wizard = wiz.Wizard(self, self.ID_wiz, "Simple Wizard",
- images.getWizTest1Bitmap())
- page1 = TitledPage(wizard, "Page 1")
- page2 = TitledPage(wizard, "Page 2")
- page3 = TitledPage(wizard, "Page 3")
- page4 = TitledPage(wizard, "Page 4")
- self.page1 = page1
-
- page1.sizer.Add(wx.StaticText(page1, -1, """
-This wizard is totally useless, but is meant to show how to
-chain simple wizard pages together in a non-dynamic manner.
-IOW, the order of the pages never changes, and so the
-wxWizardPageSimple class can easily be used for the pages."""))
- wizard.FitToPage(page1)
- page4.sizer.Add(wx.StaticText(page4, -1, "\nThis is the last page."))
-
- # Use the convenience Chain function to connect the pages
- wiz.WizardPageSimple_Chain(page1, page2)
- wiz.WizardPageSimple_Chain(page2, page3)
- wiz.WizardPageSimple_Chain(page3, page4)
-
- if wizard.RunWizard(page1):
- wx.MessageBox("Wizard completed successfully", "That's all folks!")
- else:
- wx.MessageBox("Wizard was cancelled", "That's all folks!")
-
-
-
- def OnRunDynamicWizard(self, evt):
- # Create the wizard and the pages
- #wizard = wx.PreWizard()
- #wizard.SetExtraStyle(wx.WIZARD_EX_HELPBUTTON)
- #wizard.Create(self, self.ID_wiz, "Simple Wizard",
- # images.getWizTest1Bitmap())
- wizard = wiz.Wizard(self, self.ID_wiz, "Simple Wizard",
- images.getWizTest1Bitmap())
-
- page1 = TitledPage(wizard, "Page 1")
- page2 = SkipNextPage(wizard, "Page 2")
- page3 = TitledPage(wizard, "Page 3")
- page4 = UseAltBitmapPage(wizard, "Page 4")
- page5 = TitledPage(wizard, "Page 5")
- self.page1 = page1
-
- page1.sizer.Add(wx.StaticText(page1, -1, """
-This wizard shows the ability to choose at runtime the order
-of the pages and also which bitmap is shown.
-"""))
- wizard.FitToPage(page1)
- page5.sizer.Add(wx.StaticText(page5, -1, "\nThis is the last page."))
-
- # Set the initial order of the pages
- page1.SetNext(page2)
- page2.SetPrev(page1)
- page2.SetNext(page3)
- page3.SetPrev(page2)
- page3.SetNext(page4)
- page4.SetPrev(page3)
- page4.SetNext(page5)
- page5.SetPrev(page4)
-
-
- if wizard.RunWizard(page1):
- wx.MessageBox("Wizard completed successfully", "That's all folks!")
- else:
- wx.MessageBox("Wizard was cancelled", "That's all folks!")
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>wxWizard</center></h2>
-
-wxWizard is the central class for implementing 'wizard-like'
-dialogs. These dialogs are mostly familiar to Windows users and are
-nothing else but a sequence of 'pages' each of them displayed inside a
-dialog which has the buttons to pass to the next (and previous) pages.
-<p>
-The wizards are typically used to decompose a complex dialog into
-several simple steps and are mainly useful to the novice users, hence
-it is important to keep them as simple as possible.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import wx.xrc as xrc
-
-from Main import opj
-
-#----------------------------------------------------------------------
-
-RESFILE = opj("data/resource_wdr.xrc")
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- wx.Panel.__init__(self, parent, -1)
- self.log = log
-
- # make the components
- label = wx.StaticText(self, -1, "The lower panel was built from this XML:")
- label.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
-
- resourceText = open(RESFILE).read()
- text = wx.TextCtrl(self, -1, resourceText,
- style=wx.TE_READONLY|wx.TE_MULTILINE)
- text.SetInsertionPoint(0)
-
- line = wx.StaticLine(self, -1)
-
- # This shows a few different ways to load XML Resources
- if 0:
- # XML Resources can be loaded from a file like this:
- res = xrc.XmlResource(RESFILE)
-
- elif 1:
- # or from a Virtual FileSystem:
- wx.FileSystem_AddHandler(wx.MemoryFSHandler())
- wx.MemoryFSHandler_AddFile("XRC_Resources/data_file", resourceText)
- res = xrc.XmlResource("memory:XRC_Resources/data_file")
-
- else:
- # or from a string, like this:
- res = xrc.EmptyXmlResource()
- res.LoadFromString(resourceText)
-
-
- # Now create a panel from the resource data
- panel = res.LoadPanel(self, "MyPanel")
-
- # and do the layout
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.LEFT, 5)
- sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)
- sizer.Add(line, 0, wx.EXPAND)
- sizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
-
- self.SetSizer(sizer)
- self.SetAutoLayout(True)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """
-"""
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-# o There are issues using the wx namespace within the xrc code.
-#
-# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Error report: "Error: No handler found for XML node 'object',
-# class 'wx.StaticText'!"; no text shows on panel.
-#
-
-import wx
-import wx.xrc as xrc
-
-#----------------------------------------------------------------------
-
-resourceText = r'''<?xml version="1.0"?>
-<resource>
-
-<!-- Notice that the class is NOT a standard wx class -->
-
-<object class="MyBluePanel" name="MyPanel">
- <size>200,100</size>
- <object class="wx.StaticText" name="label1">
- <label>This blue panel is a class derived from wx.Panel,\nand is loaded by a custom XmlResourceHandler.</label>
- <pos>10,10</pos>
- </object>
-</object>
-</resource>
-'''
-
-#----------------------------------------------------------------------
-
-class MyBluePanel(wx.Panel):
- def __init__(self, parent, id, pos, size, style, name):
- wx.Panel.__init__(self, parent, id, pos, size, style, name)
-
- # This is the little bit of customization that we do for this
- # silly example. It could just as easily have been done in
- # the resource.
- self.SetBackgroundColour("BLUE")
- self.SetForegroundColour("WHITE")
-
-
-# To do it the more complex way, (see below) we need to write the
-# class a little differently... This could obviously be done with a
-# single class, but I wanted to make separate ones to make clear what
-# the different requirements are.
-class PreMyBluePanel(wx.Panel):
- def __init__(self):
- p = wx.PrePanel()
- self.PostCreate(p)
-
- def Create(self, parent, id, pos, size, style, name):
- wx.Panel.Create(self, parent, id, pos, size, style, name)
- self.SetBackgroundColour("BLUE")
- self.SetForegroundColour("WHITE")
-
-
-#----------------------------------------------------------------------
-
-class MyBluePanelXmlHandler(xrc.XmlResourceHandler):
- def __init__(self):
- xrc.XmlResourceHandler.__init__(self)
- # Specify the styles recognized by objects of this type
- self.AddStyle("wx.NO_3D", wx.NO_3D);
- self.AddStyle("wx.TAB_TRAVERSAL", wx.TAB_TRAVERSAL);
- self.AddStyle("wx.WS_EX_VALIDATE_RECURSIVELY", wx.WS_EX_VALIDATE_RECURSIVELY);
- self.AddStyle("wx.CLIP_CHILDREN", wx.CLIP_CHILDREN);
- self.AddWindowStyles();
-
- # This method and the next one are required for XmlResourceHandlers
- def CanHandle(self, node):
- return self.IsOfClass(node, "MyBluePanel")
-
- def DoCreateResource(self):
- # NOTE: wxWindows can be created in either a single-phase or
- # in a two-phase way. Single phase is what you normally do,
- # and two-phase creates the instnace first, and then later
- # creates the actual window when the Create method is called.
- # (In wxPython the first phase is done using the wxPre*
- # function, for example, wxPreFrame, wxPrePanel, etc.)
- #
- # wxXmlResource supports either method, a premade instance can
- # be created and populated by xrc using the appropriate
- # LoadOn* method (such as LoadOnPanel) or xrc can create the
- # instance too, using the Load* method. However this makes
- # the handlers a bit more complex. If you can be sure that a
- # particular class will never be loaded using a pre-existing
- # instance, then you can make the handle much simpler. I'll
- # show both methods below.
-
- if 1:
- # The simple method assumes that there is no existing
- # instance. Be sure of that with an assert.
- assert self.GetInstance() is None
-
- # Now create the object
- panel = MyBluePanel(self.GetParentAsWindow(),
- self.GetID(),
- self.GetPosition(),
- self.GetSize(),
- self.GetStyle("style", wx.TAB_TRAVERSAL),
- self.GetName()
- )
- else:
- # When using the more complex (but more flexible) method
- # the instance may already have been created, check for it
- panel = self.GetInstance()
- if panel is None:
- # if not, then create the instance (but not the window)
- panel = PreMyBluePanel()
-
- # Now call the panel's Create method to actually create the window
- panel.Create(self.GetParentAsWindow(),
- self.GetID(),
- self.GetPosition(),
- self.GetSize(),
- self.GetStyle("style", wx.TAB_TRAVERSAL),
- self.GetName()
- )
-
- # These two things should be done in either case:
- # Set standard window attributes
- self.SetupWindow(panel)
- # Create any child windows of this node
- self.CreateChildren(panel)
-
- return panel
-
-
-#----------------------------------------------------------------------
-
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- # make the components
- label = wx.StaticText(self, -1, "The lower panel was built from this XML:")
- label.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
-
- text = wx.TextCtrl(self, -1, resourceText,
- style=wx.TE_READONLY|wx.TE_MULTILINE)
- text.SetInsertionPoint(0)
-
- line = wx.StaticLine(self, -1)
-
- # Load the resource
- res = xrc.EmptyXmlResource()
- res.InsertHandler(MyBluePanelXmlHandler())
- res.LoadFromString(resourceText)
-
- # Now create a panel from the resource data
- panel = res.LoadObject(self, "MyPanel", "MyBluePanel")
-
- # and do the layout
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.LEFT, 5)
- sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)
- sizer.Add(line, 0, wx.EXPAND)
- sizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
-
- self.SetSizer(sizer)
- self.SetAutoLayout(True)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>wxXmlResourceHandler</center></h2>
-
-Deriving a class from wxXmlResourceHandler allows you to specify your
-own classes in XRC resources, and your handler class will then be used
-to create instances of that class when the resource is loaded.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-
+++ /dev/null
-# 11/22/2003 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o Updated for wx namespace
-#
-
-import wx
-import wx.xrc as xrc
-
-#----------------------------------------------------------------------
-
-resourceText = r'''<?xml version="1.0"?>
-<resource>
-
-<!-- Notice that the class IS a standard wx class, and a custom
- subclass is specified as "moduleName.ClassName" Try changing
- the classname to one that does not exist and see what happens -->
-
-<object class="wxPanel" subclass="wxXmlResourceSubclass.MyBluePanel" name="MyPanel">
- <size>200,100</size>
- <object class="wxStaticText" name="label1">
- <label>This blue panel is a class derived from wxPanel
-and is loaded by a using a subclass attribute of the object tag.</label>
- <pos>10,10</pos>
- </object>
-</object>
-</resource>
-'''
-
-#----------------------------------------------------------------------
-
-class MyBluePanel(wx.Panel):
- def __init__(self):
- p = wx.PrePanel()
- self.PostCreate(p)
-
- self.Bind(wx.EVT_WINDOW_CREATE, self.OnCreate)
-
- def OnCreate(self, evt):
- # This is the little bit of customization that we do for this
- # silly example. It could just as easily have been done in
- # the resource. We do it in the EVT_WINDOW_CREATE handler
- # because the window doesn't really exist yet in the __init__.
- self.SetBackgroundColour("BLUE")
- self.SetForegroundColour("WHITE")
-
-#----------------------------------------------------------------------
-
-
-class TestPanel(wx.Panel):
- def __init__(self, parent, log):
- self.log = log
- wx.Panel.__init__(self, parent, -1)
-
- # make the components
- label = wx.StaticText(self, -1, "The lower panel was built from this XML:")
- label.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
-
- text = wx.TextCtrl(self, -1, resourceText,
- style=wx.TE_READONLY|wx.TE_MULTILINE)
- text.SetInsertionPoint(0)
-
- line = wx.StaticLine(self, -1)
-
- # Load the resource
- res = xrc.EmptyXmlResource()
- res.LoadFromString(resourceText)
-
- # Now create a panel from the resource data
- panel = res.LoadPanel(self, "MyPanel")
-
- # and do the layout
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.LEFT, 5)
- sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)
- sizer.Add(line, 0, wx.EXPAND)
- sizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
-
- self.SetSizer(sizer)
- self.SetAutoLayout(True)
-
-
-#----------------------------------------------------------------------
-
-def runTest(frame, nb, log):
- win = TestPanel(nb, log)
- return win
-
-#----------------------------------------------------------------------
-
-
-
-overview = """<html><body>
-<h2><center>wxXmlResourceSubclass</center></h2>
-
-Sometimes it is necessary to use custom classes, but you still want
-them to be created from XRC. The subclass XRC attribute allows you to
-do that.
-
-</body></html>
-"""
-
-
-
-if __name__ == '__main__':
- import sys,os
- import run
- run.main(['', os.path.basename(sys.argv[0])])
-