]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/FloatCanvas.py
Send an extra size event after creation to work around an apparent bug
[wxWidgets.git] / wxPython / demo / FloatCanvas.py
1
2 import wx
3
4 # Stuff to integrate FloatCanvas into wxPython Demo
5 try:
6 import Numeric
7 haveNumeric = True
8 except ImportError:
9 haveNumeric = False
10
11
12 if not haveNumeric:
13 errorText = """\
14 The FloatCanvas requires the Numeric module:
15 You can get it at:
16 http://sourceforge.net/projects/numpy
17 """
18 def runTest(frame, nb, log):
19 dlg = wx.MessageDialog(
20 frame, errorText, 'Sorry', wx.OK | wx.ICON_INFORMATION
21 )
22
23 dlg.ShowModal()
24 dlg.Destroy()
25
26 overview = ""
27
28 else:
29 from wxPython.lib import floatcanvas
30 import wxPython.lib.colourdb
31
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
41
42 colors = []
43 LineStyles = floatcanvas.draw_object.LineStyleList.keys()
44
45
46
47 class DrawFrame(wx.Frame):
48
49 """
50
51 A frame used for the FloatCanvas Demo
52
53 """
54
55 def __init__(self, parent, id, title, position, size):
56 wx.Frame.__init__(self,parent, id,title,position, size)
57
58 # Set up the MenuBar
59
60 MenuBar = wx.MenuBar()
61
62 file_menu = wx.Menu()
63 file_menu.Append(ID_EXIT_MENU, "&Close","Close this frame")
64 self.Bind(wx.EVT_MENU, self.OnQuit, id=ID_EXIT_MENU)
65 MenuBar.Append(file_menu, "&File")
66
67 draw_menu = wx.Menu()
68 draw_menu.Append(ID_DRAWTEST_MENU, "&Draw Test","Run a test of drawing random components")
69 self.Bind(wx.EVT_MENU, self.DrawTest, id=ID_DRAWTEST_MENU)
70 draw_menu.Append(ID_LINETEST_MENU, "&Line Test","Run a test of drawing random lines")
71 self.Bind(wx.EVT_MENU, self.LineTest, id=ID_LINETEST_MENU)
72 draw_menu.Append(ID_DRAWMAP_MENU, "Draw &Map","Run a test of drawing a map")
73 self.Bind(wx.EVT_MENU, self.DrawMap, id=ID_DRAWMAP_MENU)
74 draw_menu.Append(ID_CLEAR_MENU, "&Clear","Clear the Canvas")
75 self.Bind(wx.EVT_MENU, self.Clear, id=ID_CLEAR_MENU)
76 MenuBar.Append(draw_menu, "&Draw")
77
78 view_menu = wx.Menu()
79 view_menu.Append(ID_ZOOM_TO_FIT_MENU, "Zoom to &Fit","Zoom to fit the window")
80 self.Bind(wx.EVT_MENU, self.ZoomToFit, id=ID_ZOOM_TO_FIT_MENU)
81 MenuBar.Append(view_menu, "&View")
82
83 help_menu = wx.Menu()
84 help_menu.Append(ID_ABOUT_MENU, "&About",
85 "More information About this program")
86 self.Bind(wx.EVT_MENU, self.OnAbout, id=ID_ABOUT_MENU)
87 MenuBar.Append(help_menu, "&Help")
88
89 self.SetMenuBar(MenuBar)
90
91 self.CreateStatusBar()
92 self.SetStatusText("")
93
94 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
95
96 # Other event handlers:
97 self.Bind(wx.EVT_RIGHT_DOWN, self.RightButtonEvent)
98
99 # Add the Canvas
100 self.Canvas = floatcanvas.FloatCanvas(self,-1,(500,500),
101 ProjectionFun = 'FlatEarth',
102 Debug = 0,
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):
119 dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
120 "the use of the FloatCanvas\n",
121 "About Me", wx.OK | wx.ICON_INFORMATION)
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)
128
129 self.ToolBar.ToggleTool(event.GetId(),1)
130
131 if event.GetId() == ID_ZOOM_IN_BUTTON:
132 self.Canvas.SetGUIMode("ZoomIn")
133
134 elif event.GetId() == ID_ZOOM_OUT_BUTTON:
135 self.Canvas.SetGUIMode("ZoomOut")
136
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):
155 wx.GetApp().Yield()
156
157 import random
158 import RandomArray
159
160 Range = (-10,10)
161
162 Canvas = self.Canvas
163 object_list = self.object_list
164
165 # Random tests of everything:
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):
250 wx.GetApp().Yield()
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):
295 wx.GetApp().Yield()
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
320 class DemoApp(wx.App):
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):
371 global colors
372 wxPython.lib.colourdb.updateColourDB()
373 colors = wxPython.lib.colourdb.getColourList()
374
375 frame = DrawFrame(None, -1, "FloatCanvas Demo App",
376 wx.DefaultPosition, (700,700))
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
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
444 win = DrawFrame(None, -1, "FloatCanvas Drawing Window",
445 wx.DefaultPosition, (500,500))
446 frame.otherWin = win
447 win.Show(True)
448
449
450
451
452 ## for the wxPython demo:
453 overview = floatcanvas.FloatCanvas.__doc__
454
455
456
457 if __name__ == "__main__":
458 if not haveNumeric:
459 print errorText
460 else:
461 app = DemoApp(0)
462
463 import wx.lib.colourdb
464 wx.lib.colourdb.updateColourDB()
465 colors = wx.lib.colourdb.getColourList()
466
467 app.MainLoop()
468
469
470
471