]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/FloatCanvas.py
Give BitmapButton its own demo, get rid of ErrorDialogs
[wxWidgets.git] / wxPython / demo / FloatCanvas.py
CommitLineData
8b9a4190 1
8fa876ca 2import wx
8b9a4190 3
8fa876ca 4# Stuff to integrate FloatCanvas into wxPython Demo
8b9a4190
RD
5try:
6 import Numeric
7 haveNumeric = True
8except ImportError:
9 haveNumeric = False
10
11
12if not haveNumeric:
13 errorText = """\
14The FloatCanvas requires the Numeric module:
15You can get it at:
16 http://sourceforge.net/projects/numpy
17"""
18 def runTest(frame, nb, log):
8fa876ca
RD
19 dlg = wx.MessageDialog(
20 frame, errorText, 'Sorry', wx.OK | wx.ICON_INFORMATION
21 )
22
8b9a4190
RD
23 dlg.ShowModal()
24 dlg.Destroy()
25
26 overview = ""
27
28else:
8b9a4190
RD
29 from wxPython.lib import floatcanvas
30 import wxPython.lib.colourdb
31
8fa876ca
RD
32 ID_ABOUT_MENU = wx.NewId()
33 ID_EXIT_MENU = wx.NewId()
34 ID_ZOOM_TO_FIT_MENU = wx.NewId()
35 ID_DRAWTEST_MENU = wx.NewId()
36 ID_LINETEST_MENU = wx.NewId()
37 ID_DRAWMAP_MENU = wx.NewId()
38 ID_DRAWMAP2_MENU = wx.NewId()
39 ID_CLEAR_MENU = wx.NewId()
40
8b9a4190 41
fbd5dd1d 42 colors = []
8b9a4190 43 LineStyles = floatcanvas.draw_object.LineStyleList.keys()
fbd5dd1d
RD
44
45
8b9a4190 46
8fa876ca 47 class DrawFrame(wx.Frame):
8b9a4190
RD
48
49 """
50
51 A frame used for the FloatCanvas Demo
52
53 """
54
8fa876ca
RD
55 def __init__(self, parent, id, title, position, size):
56 wx.Frame.__init__(self,parent, id,title,position, size)
8b9a4190 57
8fa876ca 58 # Set up the MenuBar
8b9a4190 59
8fa876ca 60 MenuBar = wx.MenuBar()
8b9a4190 61
8fa876ca 62 file_menu = wx.Menu()
8b9a4190 63 file_menu.Append(ID_EXIT_MENU, "&Close","Close this frame")
8fa876ca 64 self.Bind(wx.EVT_MENU, self.OnQuit, id=ID_EXIT_MENU)
8b9a4190
RD
65 MenuBar.Append(file_menu, "&File")
66
8fa876ca 67 draw_menu = wx.Menu()
8b9a4190 68 draw_menu.Append(ID_DRAWTEST_MENU, "&Draw Test","Run a test of drawing random components")
8fa876ca 69 self.Bind(wx.EVT_MENU, self.DrawTest, id=ID_DRAWTEST_MENU)
8b9a4190 70 draw_menu.Append(ID_LINETEST_MENU, "&Line Test","Run a test of drawing random lines")
8fa876ca 71 self.Bind(wx.EVT_MENU, self.LineTest, id=ID_LINETEST_MENU)
8b9a4190 72 draw_menu.Append(ID_DRAWMAP_MENU, "Draw &Map","Run a test of drawing a map")
8fa876ca 73 self.Bind(wx.EVT_MENU, self.DrawMap, id=ID_DRAWMAP_MENU)
8b9a4190 74 draw_menu.Append(ID_CLEAR_MENU, "&Clear","Clear the Canvas")
8fa876ca 75 self.Bind(wx.EVT_MENU, self.Clear, id=ID_CLEAR_MENU)
8b9a4190 76 MenuBar.Append(draw_menu, "&Draw")
8fa876ca
RD
77
78 view_menu = wx.Menu()
8b9a4190 79 view_menu.Append(ID_ZOOM_TO_FIT_MENU, "Zoom to &Fit","Zoom to fit the window")
8fa876ca 80 self.Bind(wx.EVT_MENU, self.ZoomToFit, id=ID_ZOOM_TO_FIT_MENU)
8b9a4190
RD
81 MenuBar.Append(view_menu, "&View")
82
8fa876ca 83 help_menu = wx.Menu()
8b9a4190
RD
84 help_menu.Append(ID_ABOUT_MENU, "&About",
85 "More information About this program")
8fa876ca 86 self.Bind(wx.EVT_MENU, self.OnAbout, id=ID_ABOUT_MENU)
8b9a4190
RD
87 MenuBar.Append(help_menu, "&Help")
88
89 self.SetMenuBar(MenuBar)
90
91 self.CreateStatusBar()
92 self.SetStatusText("")
93
8fa876ca 94 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
8b9a4190
RD
95
96 # Other event handlers:
8fa876ca 97 self.Bind(wx.EVT_RIGHT_DOWN, self.RightButtonEvent)
8b9a4190
RD
98
99 # Add the Canvas
100 self.Canvas = floatcanvas.FloatCanvas(self,-1,(500,500),
101 ProjectionFun = 'FlatEarth',
118f4724 102 Debug = 0,
8b9a4190
RD
103 EnclosingFrame = self,
104 BackgroundColor = "DARK SLATE BLUE",
105 UseBackground = 0,
106 UseToolbar = 1)
107 self.Show(True)
108
109 self.object_list = []
110
111 return None
112
113 def RightButtonEvent(self,event):
114 print "Right Button has been clicked in DrawFrame"
115 print "coords are: %i, %i"%(event.GetX(),event.GetY())
116 event.Skip()
117
118 def OnAbout(self, event):
8fa876ca 119 dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
8b9a4190 120 "the use of the FloatCanvas\n",
8fa876ca 121 "About Me", wx.OK | wx.ICON_INFORMATION)
8b9a4190
RD
122 dlg.ShowModal()
123 dlg.Destroy()
124
125 def SetMode(self,event):
126 for id in [ID_ZOOM_IN_BUTTON,ID_ZOOM_OUT_BUTTON,ID_MOVE_MODE_BUTTON]:
127 self.ToolBar.ToggleTool(id,0)
8fa876ca 128
8b9a4190 129 self.ToolBar.ToggleTool(event.GetId(),1)
8fa876ca 130
8b9a4190
RD
131 if event.GetId() == ID_ZOOM_IN_BUTTON:
132 self.Canvas.SetGUIMode("ZoomIn")
8fa876ca 133
8b9a4190
RD
134 elif event.GetId() == ID_ZOOM_OUT_BUTTON:
135 self.Canvas.SetGUIMode("ZoomOut")
8fa876ca 136
8b9a4190
RD
137 elif event.GetId() == ID_MOVE_MODE_BUTTON:
138 self.Canvas.SetGUIMode("Move")
139
140 def ZoomToFit(self,event):
141 self.Canvas.ZoomToBB()
142
143 def Clear(self,event = None):
144 self.Canvas.RemoveObjects(self.object_list)
145 self.object_list = []
146 self.Canvas.Draw()
147
148 def OnQuit(self,event):
149 self.Close(True)
150
151 def OnCloseWindow(self, event):
152 self.Destroy()
153
154 def DrawTest(self,event):
8fa876ca
RD
155 wx.GetApp().Yield()
156
8b9a4190
RD
157 import random
158 import RandomArray
8fa876ca 159
8b9a4190
RD
160 Range = (-10,10)
161
162 Canvas = self.Canvas
163 object_list = self.object_list
164
8fa876ca 165 # Random tests of everything:
8b9a4190
RD
166
167 # Rectangles
168 for i in range(5):
169 x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
170 lw = random.randint(1,5)
171 cf = random.randint(0,len(colors)-1)
172 h = random.randint(1,5)
173 w = random.randint(1,5)
174 object_list.append(Canvas.AddRectangle(x,y,h,w,LineWidth = lw,FillColor = colors[cf]))
175
176 # Ellipses
177 for i in range(5):
178 x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
179 lw = random.randint(1,5)
180 cf = random.randint(0,len(colors)-1)
181 h = random.randint(1,5)
182 w = random.randint(1,5)
183 object_list.append(Canvas.AddEllipse(x,y,h,w,LineWidth = lw,FillColor = colors[cf]))
184
185 # Dots
186 for i in range(5):
187 x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
188 D = random.randint(1,50)
189 lw = random.randint(1,5)
190 cf = random.randint(0,len(colors)-1)
191 cl = random.randint(0,len(colors)-1)
192 object_list.append(Canvas.AddDot(x,y,D,LineWidth = lw,LineColor = colors[cl],FillColor = colors[cf]))
193
194 # Circles
195 for i in range(5):
196 x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
197 D = random.randint(1,5)
198 lw = random.randint(1,5)
199 cf = random.randint(0,len(colors)-1)
200 cl = random.randint(0,len(colors)-1)
201 object_list.append(Canvas.AddCircle(x,y,D,LineWidth = lw,LineColor = colors[cl],FillColor = colors[cf]))
202 self.object_list.append(self.Canvas.AddText("Circle # %i"%(i),x,y,Size = 12,BackGround = None,Position = "cc"))
203
204 # Lines
205 for i in range(5):
206 points = []
207 for j in range(random.randint(2,10)):
208 point = (random.randint(Range[0],Range[1]),random.randint(Range[0],Range[1]))
209 points.append(point)
210 lw = random.randint(1,10)
211 cf = random.randint(0,len(colors)-1)
212 cl = random.randint(0,len(colors)-1)
213 self.object_list.append(self.Canvas.AddLine(points, LineWidth = lw, LineColor = colors[cl]))
214
215 # Polygons
216 for i in range(3):
217 points = []
218 for j in range(random.randint(2,6)):
219 point = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
220 points.append(point)
221 lw = random.randint(1,6)
222 cf = random.randint(0,len(colors)-1)
223 cl = random.randint(0,len(colors)-1)
224 self.object_list.append(self.Canvas.AddPolygon(points,
225 LineWidth = lw,
226 LineColor = colors[cl],
227 FillColor = colors[cf],
228 FillStyle = 'Solid'))
229
230
231 ## Pointset
232 for i in range(4):
233 points = []
234 points = RandomArray.uniform(Range[0],Range[1],(100,2))
235 cf = random.randint(0,len(colors)-1)
236 D = random.randint(1,4)
237 self.object_list.append(self.Canvas.AddPointSet(points, Color = colors[cf], Diameter = D))
238
239 # Text
240 String = "Some text"
241 for i in range(10):
242 ts = random.randint(10,40)
243 cf = random.randint(0,len(colors)-1)
244 x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
245 self.object_list.append(self.Canvas.AddText(String,x,y,Size = ts,ForeGround = colors[cf],Position = "cc"))
246
247 self.Canvas.ZoomToBB()
248
249 def DrawMap(self,event = None):
8fa876ca 250 wx.GetApp().Yield()
8b9a4190
RD
251 import os, time
252 ## Test of Actual Map Data
253 self.Clear()
254 start = time.clock()
255 Shorelines = Read_MapGen(os.path.join("data",'world.dat'),stats = 0)
256 print "It took %f seconds to load %i shorelines"%(time.clock() - start,len(Shorelines) )
257 start = time.clock()
258 for segment in Shorelines:
259 self.object_list.append(self.Canvas.AddLine(segment))
260 print "It took %f seconds to add %i shorelines"%(time.clock() - start,len(Shorelines) )
261 start = time.clock()
262 self.Canvas.ZoomToBB()
263 print "It took %f seconds to draw %i shorelines"%(time.clock() - start,len(Shorelines) )
264
265 ## def LineTest(self,event = None):
266 ## wxGetApp().Yield()
267 ## import os, time
268 ## import random
269 ## Range = (-10,10)
270 ## ## Test of drawing lots of lines
271 ## self.Clear()
272 ## start = time.clock()
273 ## linepoints = []
274 ## linecolors = []
275 ## linewidths = []
276 ## linestyles = []
277 ## for i in range(500):
278 ## points = (random.randint(Range[0],Range[1]),
279 ## random.randint(Range[0],Range[1]))
280 ## linepoints.append(points)
281 ## points = (random.randint(Range[0],Range[1]),
282 ## random.randint(Range[0],Range[1]))
283 ## linepoints.append(points)
284 ## linewidths.append(random.randint(1,10) )
285 ## linecolors.append(colors[random.randint(0,len(colors)-1) ])
286 ## linestyles.append(LineStyles[random.randint(0, len(LineStyles)-1)])
287
288 ## self.object_list.append(self.Canvas.AddLineSet(linepoints, LineWidths = linewidths, LineColors = linecolors, LineStyles = linestyles))
289 ## print "It took %f seconds to add %i lines"%(time.clock() - start,len(linepoints) )
290 ## start = time.clock()
291 ## self.Canvas.ZoomToBB()
292 ## print "It took %f seconds to draw %i lines"%(time.clock() - start,len(linepoints) )
293
294 def LineTest(self,event = None):
8fa876ca 295 wx.GetApp().Yield()
8b9a4190
RD
296 import os, time
297 import random
298 Range = (-10,10)
299 ## Test of drawing lots of lines
300 self.Clear()
301 start = time.clock()
302 linepoints = []
303 linecolors = []
304 linewidths = []
305 for i in range(2000):
306 points = (random.randint(Range[0],Range[1]),
307 random.randint(Range[0],Range[1]),
308 random.randint(Range[0],Range[1]),
309 random.randint(Range[0],Range[1]))
310 linepoints.append(points)
311 linewidths.append(random.randint(1,10) )
312 linecolors.append(random.randint(0,len(colors)-1) )
313 for (points,color,width) in zip(linepoints,linecolors,linewidths):
314 self.object_list.append(self.Canvas.AddLine((points[0:2],points[2:4]), LineWidth = width, LineColor = colors[color]))
315 print "It took %f seconds to add %i lines"%(time.clock() - start,len(linepoints) )
316 start = time.clock()
317 self.Canvas.ZoomToBB()
318 print "It took %f seconds to draw %i lines"%(time.clock() - start,len(linepoints) )
319
8fa876ca 320 class DemoApp(wx.App):
8b9a4190
RD
321 """
322 How the demo works:
323
324 Under the Draw menu, there are three options:
325
326 *Draw Test: will put up a picture of a bunch of randomly generated
327 objects, of each kind supported.
328
329 *Draw Map: will draw a map of the world. Be patient, it is a big map,
330 with a lot of data, and will take a while to load and draw (about 10 sec
331 on my 450Mhz PIII). Redraws take about 2 sec. This demonstrates how the
332 performance is not very good for large drawings.
333
334 *Clear: Clears the Canvas.
335
336 Once you have a picture drawn, you can zoom in and out and move about
337 the picture. There is a tool bar with three tools that can be
338 selected.
339
340 The magnifying glass with the plus is the zoom in tool. Once selected,
341 if you click the image, it will zoom in, centered on where you
342 clicked. If you click and drag the mouse, you will get a rubber band
343 box, and the image will zoom to fit that box when you release it.
344
345 The magnifying glass with the minus is the zoom out tool. Once selected,
346 if you click the image, it will zoom out, centered on where you
347 clicked. (note that this takes a while when you are looking at the map,
348 as it has a LOT of lines to be drawn. The image is double buffered, so
349 you don't see the drawing in progress)
350
351 The hand is the move tool. Once selected, if you click and drag on the
352 image, it will move so that the part you clicked on ends up where you
353 release the mouse. Nothing is changed while you are dragging. The
354 drawing is too slow for that.
355
356 I'd like the cursor to change as you change tools, but the stock
357 wxCursors didn't include anything I liked, so I stuck with the
358 pointer. Please let me know if you have any nice cursor images for me to
359 use.
360
361
362 Any bugs, comments, feedback, questions, and especially code are welcome:
363
364 -Chris Barker
365
366 Chris.Barker@noaa.gov
367
368 """
369
370 def OnInit(self):
fbd5dd1d
RD
371 global colors
372 wxPython.lib.colourdb.updateColourDB()
373 colors = wxPython.lib.colourdb.getColourList()
374
e7325293
RD
375 frame = DrawFrame(None, -1, "FloatCanvas Demo App",
376 wx.DefaultPosition, (700,700))
8b9a4190
RD
377
378 self.SetTopWindow(frame)
379
380 return True
381
382 def Read_MapGen(filename,stats = 0,AllLines=0):
383 """
384 This function reads a MapGen Format file, and
385 returns a list of NumPy arrays with the line segments in them.
386
387 Each NumPy array in the list is an NX2 array of Python Floats.
388
389 The demo should have come with a file, "world.dat" that is the
390 shorelines of the whole world, in MapGen format.
391
392 """
393 import string
394 from Numeric import array
395 file = open(filename,'rt')
396 data = file.readlines()
397 data = map(string.strip,data)
398
399 Shorelines = []
400 segment = []
401 for line in data:
402 if line:
403 if line == "# -b": #New segment beginning
404 if segment: Shorelines.append(array(segment))
405 segment = []
406 else:
407 segment.append(map(float,string.split(line)))
408 if segment: Shorelines.append(array(segment))
409
410 if stats:
411 NumSegments = len(Shorelines)
412 NumPoints = 0
413 for segment in Shorelines:
414 NumPoints = NumPoints + len(segment)
415 AvgPoints = NumPoints / NumSegments
416 print "Number of Segments: ", NumSegments
417 print "Average Number of Points per segment: ",AvgPoints
418 if AllLines:
419 Lines = []
420 for segment in Shorelines:
421 Lines.append(segment[0])
422 for point in segment[1:-1]:
423 Lines.append(point)
424 Lines.append(point)
425 Lines.append(segment[-1])
426 #print Shorelines
427 #for point in Lines: print point
428 return Lines
429 else:
430 return Shorelines
fbd5dd1d
RD
431
432
433 #----------------------------------------------------------------------
434
435 def runTest(frame, nb, log):
436 """
437 This method is used by the wxPython Demo Framework for integrating
438 this demo with the rest.
439 """
440 global colors
441 wxPython.lib.colourdb.updateColourDB()
442 colors = wxPython.lib.colourdb.getColourList()
443
707fbe5d
RD
444 win = DrawFrame(None, -1, "FloatCanvas Drawing Window",
445 wx.DefaultPosition, (500,500))
fbd5dd1d
RD
446 frame.otherWin = win
447 win.Show(True)
448
449
450
8b9a4190
RD
451
452 ## for the wxPython demo:
453 overview = floatcanvas.FloatCanvas.__doc__
fbd5dd1d
RD
454
455
8b9a4190
RD
456
457if __name__ == "__main__":
458 if not haveNumeric:
459 print errorText
460 else:
461 app = DemoApp(0)
8fa876ca
RD
462
463 import wx.lib.colourdb
464 wx.lib.colourdb.updateColourDB()
465 colors = wx.lib.colourdb.getColourList()
466
8b9a4190
RD
467 app.MainLoop()
468
469
470
471