2 from wxPython
.wx
import *
5 ## Stuff to integrate FloatCanvas into wxPython Demo
15 The FloatCanvas requires the Numeric module:
17 http://sourceforge.net/projects/numpy
19 def runTest(frame
, nb
, log
):
20 dlg
= wxMessageDialog(frame
, errorText
,
21 'Sorry', wxOK | wxICON_INFORMATION
)
28 def runTest(frame
, nb
, log
):
30 This method is used by the wxPython Demo Framework for integrating
31 this demo with the rest.
33 win
= DrawFrame(NULL
, -1, "FloatCanvas Drawing Window",wxDefaultPosition
,wxSize(500,500))
39 from wxPython
.lib
import floatcanvas
40 import wxPython
.lib
.colourdb
42 ID_ABOUT_MENU
= wxNewId()
43 ID_EXIT_MENU
= wxNewId()
44 ID_ZOOM_TO_FIT_MENU
= wxNewId()
45 ID_DRAWTEST_MENU
= wxNewId()
46 ID_LINETEST_MENU
= wxNewId()
47 ID_DRAWMAP_MENU
= wxNewId()
48 ID_DRAWMAP2_MENU
= wxNewId()
49 ID_CLEAR_MENU
= wxNewId()
51 wxPython
.lib
.colourdb
.updateColourDB()
52 colors
= wxPython
.lib
.colourdb
.getColourList()
54 LineStyles
= floatcanvas
.draw_object
.LineStyleList
.keys()
56 class DrawFrame(wxFrame
):
60 A frame used for the FloatCanvas Demo
64 def __init__(self
,parent
, id,title
,position
,size
):
65 wxFrame
.__init
__(self
,parent
, id,title
,position
, size
)
72 file_menu
.Append(ID_EXIT_MENU
, "&Close","Close this frame")
73 EVT_MENU(self
, ID_EXIT_MENU
, self
.OnQuit
)
74 MenuBar
.Append(file_menu
, "&File")
77 draw_menu
.Append(ID_DRAWTEST_MENU
, "&Draw Test","Run a test of drawing random components")
78 EVT_MENU(self
, ID_DRAWTEST_MENU
,self
.DrawTest
)
79 draw_menu
.Append(ID_LINETEST_MENU
, "&Line Test","Run a test of drawing random lines")
80 EVT_MENU(self
, ID_LINETEST_MENU
,self
.LineTest
)
81 draw_menu
.Append(ID_DRAWMAP_MENU
, "Draw &Map","Run a test of drawing a map")
82 EVT_MENU(self
, ID_DRAWMAP_MENU
,self
.DrawMap
)
83 draw_menu
.Append(ID_CLEAR_MENU
, "&Clear","Clear the Canvas")
84 EVT_MENU(self
, ID_CLEAR_MENU
,self
.Clear
)
85 MenuBar
.Append(draw_menu
, "&Draw")
89 view_menu
.Append(ID_ZOOM_TO_FIT_MENU
, "Zoom to &Fit","Zoom to fit the window")
90 EVT_MENU(self
, ID_ZOOM_TO_FIT_MENU
,self
.ZoomToFit
)
91 MenuBar
.Append(view_menu
, "&View")
94 help_menu
.Append(ID_ABOUT_MENU
, "&About",
95 "More information About this program")
96 EVT_MENU(self
, ID_ABOUT_MENU
, self
.OnAbout
)
97 MenuBar
.Append(help_menu
, "&Help")
99 self
.SetMenuBar(MenuBar
)
101 self
.CreateStatusBar()
102 self
.SetStatusText("")
104 EVT_CLOSE(self
, self
.OnCloseWindow
)
106 # Other event handlers:
107 EVT_RIGHT_DOWN(self
, self
.RightButtonEvent
)
110 self
.Canvas
= floatcanvas
.FloatCanvas(self
,-1,(500,500),
111 ProjectionFun
= 'FlatEarth',
113 EnclosingFrame
= self
,
114 BackgroundColor
= "DARK SLATE BLUE",
119 self
.object_list
= []
123 def RightButtonEvent(self
,event
):
124 print "Right Button has been clicked in DrawFrame"
125 print "coords are: %i, %i"%(event
.GetX(),event
.GetY())
128 def OnAbout(self
, event
):
129 dlg
= wxMessageDialog(self
, "This is a small program to demonstrate\n"
130 "the use of the FloatCanvas\n",
131 "About Me", wxOK | wxICON_INFORMATION
)
135 def SetMode(self
,event
):
136 for id in [ID_ZOOM_IN_BUTTON
,ID_ZOOM_OUT_BUTTON
,ID_MOVE_MODE_BUTTON
]:
137 self
.ToolBar
.ToggleTool(id,0)
138 self
.ToolBar
.ToggleTool(event
.GetId(),1)
139 if event
.GetId() == ID_ZOOM_IN_BUTTON
:
140 self
.Canvas
.SetGUIMode("ZoomIn")
141 elif event
.GetId() == ID_ZOOM_OUT_BUTTON
:
142 self
.Canvas
.SetGUIMode("ZoomOut")
143 elif event
.GetId() == ID_MOVE_MODE_BUTTON
:
144 self
.Canvas
.SetGUIMode("Move")
146 def ZoomToFit(self
,event
):
147 self
.Canvas
.ZoomToBB()
149 def Clear(self
,event
= None):
150 self
.Canvas
.RemoveObjects(self
.object_list
)
151 self
.object_list
= []
154 def OnQuit(self
,event
):
157 def OnCloseWindow(self
, event
):
160 def DrawTest(self
,event
):
167 object_list
= self
.object_list
169 ## Random tests of everything:
173 x
,y
= (random
.uniform(Range
[0],Range
[1]),random
.uniform(Range
[0],Range
[1]))
174 lw
= random
.randint(1,5)
175 cf
= random
.randint(0,len(colors
)-1)
176 h
= random
.randint(1,5)
177 w
= random
.randint(1,5)
178 object_list
.append(Canvas
.AddRectangle(x
,y
,h
,w
,LineWidth
= lw
,FillColor
= colors
[cf
]))
182 x
,y
= (random
.uniform(Range
[0],Range
[1]),random
.uniform(Range
[0],Range
[1]))
183 lw
= random
.randint(1,5)
184 cf
= random
.randint(0,len(colors
)-1)
185 h
= random
.randint(1,5)
186 w
= random
.randint(1,5)
187 object_list
.append(Canvas
.AddEllipse(x
,y
,h
,w
,LineWidth
= lw
,FillColor
= colors
[cf
]))
191 x
,y
= (random
.uniform(Range
[0],Range
[1]),random
.uniform(Range
[0],Range
[1]))
192 D
= random
.randint(1,50)
193 lw
= random
.randint(1,5)
194 cf
= random
.randint(0,len(colors
)-1)
195 cl
= random
.randint(0,len(colors
)-1)
196 object_list
.append(Canvas
.AddDot(x
,y
,D
,LineWidth
= lw
,LineColor
= colors
[cl
],FillColor
= colors
[cf
]))
200 x
,y
= (random
.uniform(Range
[0],Range
[1]),random
.uniform(Range
[0],Range
[1]))
201 D
= random
.randint(1,5)
202 lw
= random
.randint(1,5)
203 cf
= random
.randint(0,len(colors
)-1)
204 cl
= random
.randint(0,len(colors
)-1)
205 object_list
.append(Canvas
.AddCircle(x
,y
,D
,LineWidth
= lw
,LineColor
= colors
[cl
],FillColor
= colors
[cf
]))
206 self
.object_list
.append(self
.Canvas
.AddText("Circle # %i"%(i),x
,y
,Size
= 12,BackGround
= None,Position
= "cc"))
211 for j
in range(random
.randint(2,10)):
212 point
= (random
.randint(Range
[0],Range
[1]),random
.randint(Range
[0],Range
[1]))
214 lw
= random
.randint(1,10)
215 cf
= random
.randint(0,len(colors
)-1)
216 cl
= random
.randint(0,len(colors
)-1)
217 self
.object_list
.append(self
.Canvas
.AddLine(points
, LineWidth
= lw
, LineColor
= colors
[cl
]))
222 for j
in range(random
.randint(2,6)):
223 point
= (random
.uniform(Range
[0],Range
[1]),random
.uniform(Range
[0],Range
[1]))
225 lw
= random
.randint(1,6)
226 cf
= random
.randint(0,len(colors
)-1)
227 cl
= random
.randint(0,len(colors
)-1)
228 self
.object_list
.append(self
.Canvas
.AddPolygon(points
,
230 LineColor
= colors
[cl
],
231 FillColor
= colors
[cf
],
232 FillStyle
= 'Solid'))
238 points
= RandomArray
.uniform(Range
[0],Range
[1],(100,2))
239 cf
= random
.randint(0,len(colors
)-1)
240 D
= random
.randint(1,4)
241 self
.object_list
.append(self
.Canvas
.AddPointSet(points
, Color
= colors
[cf
], Diameter
= D
))
246 ts
= random
.randint(10,40)
247 cf
= random
.randint(0,len(colors
)-1)
248 x
,y
= (random
.uniform(Range
[0],Range
[1]),random
.uniform(Range
[0],Range
[1]))
249 self
.object_list
.append(self
.Canvas
.AddText(String
,x
,y
,Size
= ts
,ForeGround
= colors
[cf
],Position
= "cc"))
251 self
.Canvas
.ZoomToBB()
253 def DrawMap(self
,event
= None):
256 ## Test of Actual Map Data
259 Shorelines
= Read_MapGen(os
.path
.join("data",'world.dat'),stats
= 0)
260 print "It took %f seconds to load %i shorelines"%(time
.clock() - start
,len(Shorelines
) )
262 for segment
in Shorelines
:
263 self
.object_list
.append(self
.Canvas
.AddLine(segment
))
264 print "It took %f seconds to add %i shorelines"%(time
.clock() - start
,len(Shorelines
) )
266 self
.Canvas
.ZoomToBB()
267 print "It took %f seconds to draw %i shorelines"%(time
.clock() - start
,len(Shorelines
) )
269 ## def LineTest(self,event = None):
270 ## wxGetApp().Yield()
274 ## ## Test of drawing lots of lines
276 ## start = time.clock()
281 ## for i in range(500):
282 ## points = (random.randint(Range[0],Range[1]),
283 ## random.randint(Range[0],Range[1]))
284 ## linepoints.append(points)
285 ## points = (random.randint(Range[0],Range[1]),
286 ## random.randint(Range[0],Range[1]))
287 ## linepoints.append(points)
288 ## linewidths.append(random.randint(1,10) )
289 ## linecolors.append(colors[random.randint(0,len(colors)-1) ])
290 ## linestyles.append(LineStyles[random.randint(0, len(LineStyles)-1)])
292 ## self.object_list.append(self.Canvas.AddLineSet(linepoints, LineWidths = linewidths, LineColors = linecolors, LineStyles = linestyles))
293 ## print "It took %f seconds to add %i lines"%(time.clock() - start,len(linepoints) )
294 ## start = time.clock()
295 ## self.Canvas.ZoomToBB()
296 ## print "It took %f seconds to draw %i lines"%(time.clock() - start,len(linepoints) )
298 def LineTest(self
,event
= None):
303 ## Test of drawing lots of lines
309 for i
in range(2000):
310 points
= (random
.randint(Range
[0],Range
[1]),
311 random
.randint(Range
[0],Range
[1]),
312 random
.randint(Range
[0],Range
[1]),
313 random
.randint(Range
[0],Range
[1]))
314 linepoints
.append(points
)
315 linewidths
.append(random
.randint(1,10) )
316 linecolors
.append(random
.randint(0,len(colors
)-1) )
317 for (points
,color
,width
) in zip(linepoints
,linecolors
,linewidths
):
318 self
.object_list
.append(self
.Canvas
.AddLine((points
[0:2],points
[2:4]), LineWidth
= width
, LineColor
= colors
[color
]))
319 print "It took %f seconds to add %i lines"%(time
.clock() - start
,len(linepoints
) )
321 self
.Canvas
.ZoomToBB()
322 print "It took %f seconds to draw %i lines"%(time
.clock() - start
,len(linepoints
) )
324 class DemoApp(wxApp
):
328 Under the Draw menu, there are three options:
330 *Draw Test: will put up a picture of a bunch of randomly generated
331 objects, of each kind supported.
333 *Draw Map: will draw a map of the world. Be patient, it is a big map,
334 with a lot of data, and will take a while to load and draw (about 10 sec
335 on my 450Mhz PIII). Redraws take about 2 sec. This demonstrates how the
336 performance is not very good for large drawings.
338 *Clear: Clears the Canvas.
340 Once you have a picture drawn, you can zoom in and out and move about
341 the picture. There is a tool bar with three tools that can be
344 The magnifying glass with the plus is the zoom in tool. Once selected,
345 if you click the image, it will zoom in, centered on where you
346 clicked. If you click and drag the mouse, you will get a rubber band
347 box, and the image will zoom to fit that box when you release it.
349 The magnifying glass with the minus is the zoom out tool. Once selected,
350 if you click the image, it will zoom out, centered on where you
351 clicked. (note that this takes a while when you are looking at the map,
352 as it has a LOT of lines to be drawn. The image is double buffered, so
353 you don't see the drawing in progress)
355 The hand is the move tool. Once selected, if you click and drag on the
356 image, it will move so that the part you clicked on ends up where you
357 release the mouse. Nothing is changed while you are dragging. The
358 drawing is too slow for that.
360 I'd like the cursor to change as you change tools, but the stock
361 wxCursors didn't include anything I liked, so I stuck with the
362 pointer. Please let me know if you have any nice cursor images for me to
366 Any bugs, comments, feedback, questions, and especially code are welcome:
370 Chris.Barker@noaa.gov
375 frame
= DrawFrame(NULL
, -1, "FloatCanvas Demo App",wxDefaultPosition
,wxSize(700,700))
377 self
.SetTopWindow(frame
)
381 def Read_MapGen(filename
,stats
= 0,AllLines
=0):
383 This function reads a MapGen Format file, and
384 returns a list of NumPy arrays with the line segments in them.
386 Each NumPy array in the list is an NX2 array of Python Floats.
388 The demo should have come with a file, "world.dat" that is the
389 shorelines of the whole world, in MapGen format.
393 from Numeric
import array
394 file = open(filename
,'rt')
395 data
= file.readlines()
396 data
= map(string
.strip
,data
)
402 if line
== "# -b": #New segment beginning
403 if segment
: Shorelines
.append(array(segment
))
406 segment
.append(map(float,string
.split(line
)))
407 if segment
: Shorelines
.append(array(segment
))
410 NumSegments
= len(Shorelines
)
412 for segment
in Shorelines
:
413 NumPoints
= NumPoints
+ len(segment
)
414 AvgPoints
= NumPoints
/ NumSegments
415 print "Number of Segments: ", NumSegments
416 print "Average Number of Points per segment: ",AvgPoints
419 for segment
in Shorelines
:
420 Lines
.append(segment
[0])
421 for point
in segment
[1:-1]:
424 Lines
.append(segment
[-1])
426 #for point in Lines: print point
431 ## for the wxPython demo:
432 overview
= floatcanvas
.FloatCanvas
.__doc
__
434 if __name__
== "__main__":