FloatCanvas patch from Chris Barker.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29711 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2004-10-07 19:28:57 +00:00
parent c82be69b51
commit 2a0495c9f7
7 changed files with 2176 additions and 208 deletions

View File

@@ -1,92 +1,39 @@
#!/usr/bin/env python2.3
import wx
##First, make sure Numeric or numarray can be imported.
try:
import Numeric
import RandomArray
haveNumeric = True
except ImportError:
# Numeric isn't there, let's try numarray
try:
import numarray as Numeric
import numarray.random_array as RandomArray
haveNumeric = True
except ImportError:
# numarray isn't there either
haveNumeric = False
if not haveNumeric:
errorText = """
The FloatCanvas requires either the Numeric or Numarray module:
You can get them at:
http://sourceforge.net/projects/numpy
NOTE: The Numeric module is substantially faster than numarray for this
purpose, if you have lot's of objects
"""
StartUpDemo = "all"
if __name__ == "__main__": # parse options if run stand-alone
# check options:
import sys, getopt
optlist, args = getopt.getopt(sys.argv[1:],'l',["local","all","text","map","stext","hit","hitf","animate","speed","temp","props"])
for opt in optlist:
if opt[0] == "--all":
StartUpDemo = "all"
elif opt[0] == "--text":
StartUpDemo = "text"
elif opt[0] == "--map":
StartUpDemo = "map"
elif opt[0] == "--stext":
StartUpDemo = "stext"
elif opt[0] == "--hit":
StartUpDemo = "hit"
elif opt[0] == "--hitf":
StartUpDemo = "hitf"
elif opt[0] == "--animate":
StartUpDemo = "animate"
elif opt[0] == "--speed":
StartUpDemo = "speed"
elif opt[0] == "--temp":
StartUpDemo = "temp"
elif opt[0] == "--props":
StartUpDemo = "props"
import wx
import time, random
errorText = (
"The FloatCanvas requires either the Numeric or numarray module\n\n"
"You can get them at:\n"
"http://sourceforge.net/projects/numpy\n\n"
"NOTE: The Numeric module is substantially faster than numarray for this\n"
"purpose, if you have lots of objects\n"
)
#---------------------------------------------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
b = wx.Button(self, -1, "Show the FloatCanvas sample", (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
def OnButton(self, evt):
if not haveNumeric:
dlg = wx.MessageDialog(self, errorText, 'Sorry', wx.OK |
wx.ICON_INFORMATION)
dlg.ShowModal()
dlg.Destroy()
else:
win = DrawFrame(None, -1, "FloatCanvas Drawing Window",wx.DefaultPosition,(500,500))
win.Show(True)
win.DrawTest()
#---------------------------------------------------------------------------
if haveNumeric:
def BuildDrawFrame(): # this gets called when needed, rather than on import
try:
from floatcanvas import NavCanvas, FloatCanvas
except ImportError: # if it's not there locally, try the wxPython lib.
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
import wxPython.lib.colourdb
import wx.lib.colourdb
import time, random
class DrawFrame(wx.Frame):
@@ -133,6 +80,9 @@ if haveNumeric:
self.Bind(wx.EVT_MENU, self.SpeedTest, item)
item = draw_menu.Append(-1, "Change &Properties","Run a test of Changing Object Properties")
self.Bind(wx.EVT_MENU, self.PropertiesChangeTest, item)
item = draw_menu.Append(-1, "&Arrows","Run a test of Arrows")
self.Bind(wx.EVT_MENU, self.ArrowTest, item)
MenuBar.Append(draw_menu, "&Tests")
view_menu = wx.Menu()
@@ -164,8 +114,8 @@ if haveNumeric:
self.EventsAreBound = False
## getting all the colors and linestyles for random objects
wxPython.lib.colourdb.updateColourDB()
self.colors = wxPython.lib.colourdb.getColourList()
wx.lib.colourdb.updateColourDB()
self.colors = wx.lib.colourdb.getColourList()
#self.LineStyles = FloatCanvas.DrawObject.LineStyleList.keys()
@@ -190,7 +140,20 @@ if haveNumeric:
self.EventsAreBound = True
def UnBindAllMouseEvents(self):
## Here is how you catch FloatCanvas mouse events
## Here is how you unbind FloatCanvas mouse events
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, None )
FloatCanvas.EVT_LEFT_UP(self.Canvas, None )
FloatCanvas.EVT_LEFT_DCLICK(self.Canvas, None)
FloatCanvas.EVT_MIDDLE_DOWN(self.Canvas, None )
FloatCanvas.EVT_MIDDLE_UP(self.Canvas, None )
FloatCanvas.EVT_MIDDLE_DCLICK(self.Canvas, None )
FloatCanvas.EVT_RIGHT_DOWN(self.Canvas, None )
FloatCanvas.EVT_RIGHT_UP(self.Canvas, None )
FloatCanvas.EVT_RIGHT_DCLICK(self.Canvas, None )
FloatCanvas.EVT_MOUSEWHEEL(self.Canvas, None )
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, None )
FloatCanvas.EVT_LEFT_UP(self.Canvas, None )
FloatCanvas.EVT_LEFT_DCLICK(self.Canvas, None)
@@ -250,10 +213,18 @@ if haveNumeric:
def OnWheel(self, event):
print "Mouse Wheel Moved in DrawFrame"
self.PrintCoords(event)
Rot = event.GetWheelRotation()
print "Wheel Rotation is:", Rot
print "Wheel Delta is:", event.GetWheelDelta()
Rot = Rot / abs(Rot) * 0.1
if event.ControlDown(): # move left-right
self.Canvas.MoveImage( (Rot, 0), "Panel" )
else: # move up-down
self.Canvas.MoveImage( (0, Rot), "Panel" )
def OnMove(self, event):
"""
Updates the staus bar with the world coordinates
Updates the status bar with the world coordinates
"""
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
@@ -283,8 +254,7 @@ if haveNumeric:
def DrawTest(self,event=None):
wx.GetApp().Yield()
# import random
# import RandomArray
Range = (-10,10)
colors = self.colors
@@ -320,7 +290,6 @@ if haveNumeric:
D = random.randint(1,50)
cf = random.randint(0,len(colors)-1)
Canvas.AddPoint((x,y), Color = colors[cf], Diameter = D)
# Circles
for i in range(5):
x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
@@ -330,7 +299,6 @@ if haveNumeric:
cl = random.randint(0,len(colors)-1)
Canvas.AddCircle(x,y,D,LineWidth = lw,LineColor = colors[cl],FillColor = colors[cf])
Canvas.AddText("Circle # %i"%(i),x,y,Size = 12,BackgroundColor = None,Position = "cc")
# Lines
for i in range(5):
points = []
@@ -341,7 +309,6 @@ if haveNumeric:
cf = random.randint(0,len(colors)-1)
cl = random.randint(0,len(colors)-1)
Canvas.AddLine(points, LineWidth = lw, LineColor = colors[cl])
# Polygons
for i in range(3):
points = []
@@ -381,6 +348,17 @@ if haveNumeric:
x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
Canvas.AddScaledText(String, x, y, Size = ts, Color = colors[cf], Position = "cc")
# Arrows
N = 5
Points = RandomArray.uniform(Range[0], Range[1], (N,2) )
for i in range(N):
Canvas.AddArrow(Points[i],
random.uniform(20,100),
Direction = random.uniform(0,360),
LineWidth = random.uniform(1,5),
LineColor = colors[random.randint(0,len(colors)-1)],
ArrowHeadAngle = random.uniform(20,90))
Canvas.ZoomToBB()
def TestAnimation(self,event=None):
@@ -518,7 +496,7 @@ if haveNumeric:
Canvas.ClearAll()
Canvas.SetProjectionFun(None)
#Add a HitAble rectangle
#Add a Hit-able rectangle
w, h = 60, 20
dx = 80
@@ -941,7 +919,7 @@ if haveNumeric:
self.Canvas.ClearAll()
self.Canvas.SetProjectionFun("FlatEarth")
#start = time.clock()
Shorelines = Read_MapGen(os.path.join("data",'world.dat'),stats = 0)
Shorelines = self.Read_MapGen(os.path.join("data",'world.dat'),stats = 0)
#print "It took %f seconds to load %i shorelines"%(time.clock() - start,len(Shorelines) )
#start = time.clock()
for segment in Shorelines:
@@ -1147,6 +1125,52 @@ if haveNumeric:
x,y = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
w,h = random.randint(1,5), random.randint(1,5)
Object.SetShape(x,y,w,h)
self.Canvas.Draw(Force = True)
def ArrowTest(self,event=None):
wx.GetApp().Yield()
self.UnBindAllMouseEvents()
Canvas = self.Canvas
Canvas.ClearAll()
Canvas.SetProjectionFun(None)
# put in a rectangle to get a bounding box
Canvas.AddRectangle(0,0,20,20,LineColor = None)
# Draw some Arrows
Canvas.AddArrow((10,10),Length = 40, Direction = 0)
Canvas.AddArrow((10,10),Length = 50, Direction = 45 ,LineWidth = 2, LineColor = "Black", ArrowHeadAngle = 20)
Canvas.AddArrow((10,10),Length = 60, Direction = 90 ,LineWidth = 3, LineColor = "Red", ArrowHeadAngle = 30)
Canvas.AddArrow((10,10),Length = 70, Direction = 135,LineWidth = 4, LineColor = "Red", ArrowHeadAngle = 40)
Canvas.AddArrow((10,10),Length = 80, Direction = 180,LineWidth = 5, LineColor = "Blue", ArrowHeadAngle = 50)
Canvas.AddArrow((10,10),Length = 90, Direction = 225,LineWidth = 4, LineColor = "Blue", ArrowHeadAngle = 60)
Canvas.AddArrow((10,10),Length = 100,Direction = 270,LineWidth = 3, LineColor = "Green", ArrowHeadAngle = 70)
Canvas.AddArrow((10,10),Length = 110,Direction = 315,LineWidth = 2, LineColor = "Green", ArrowHeadAngle = 90 )
Canvas.AddText("Clickable Arrow",4,18,Position = "bc")
Arrow = Canvas.AddArrow((4,18), 80, Direction = 90 ,LineWidth = 3, LineColor = "Red", ArrowHeadAngle = 30)
Arrow.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.ArrowClicked)
Canvas.AddText("Changable Arrow",16,4,Position = "cc")
self.RotArrow = Canvas.AddArrow((16,4), 80, Direction = 0 ,LineWidth = 3, LineColor = "Green", ArrowHeadAngle = 30)
self.RotArrow.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.RotateArrow)
Canvas.ZoomToBB()
def ArrowClicked(self,event):
print "The Arrow was Clicked"
def RotateArrow(self,event):
print "The Changeable Arrow was Clicked"
## You can do them either one at a time, or both at once
## Doing them both at once prevents the arrow points from being calculated twice
#self.RotArrow.SetDirection(self.RotArrow.Direction + random.uniform(-90,90))
#self.RotArrow.SetLength(self.RotArrow.Length + random.randint(-20,20))
self.RotArrow.SetLengthDirection(self.RotArrow.Length + random.randint(-20,20),
self.RotArrow.Direction + random.uniform(-90,90) )
self.Canvas.Draw(Force = True)
@@ -1202,7 +1226,95 @@ if haveNumeric:
print "Point Num: %i Hit"%Point.VerticeNum
self.SelectedPoint = Point
def Read_MapGen(self, filename, stats = 0,AllLines=0):
"""
This function reads a MapGen Format file, and
returns a list of NumPy arrays with the line segments in them.
Each NumPy array in the list is an NX2 array of Python Floats.
The demo should have come with a file, "world.dat" that is the
shorelines of the whole world, in MapGen format.
"""
import string
file = open(filename,'rt')
data = file.readlines()
data = map(string.strip,data)
Shorelines = []
segment = []
for line in data:
if line:
if line == "# -b": #New segment beginning
if segment: Shorelines.append(Numeric.array(segment))
segment = []
else:
segment.append(map(float,string.split(line)))
if segment: Shorelines.append(Numeric.array(segment))
if stats:
NumSegments = len(Shorelines)
NumPoints = 0
for segment in Shorelines:
NumPoints = NumPoints + len(segment)
AvgPoints = NumPoints / NumSegments
print "Number of Segments: ", NumSegments
print "Average Number of Points per segment: ",AvgPoints
if AllLines:
Lines = []
for segment in Shorelines:
Lines.append(segment[0])
for point in segment[1:-1]:
Lines.append(point)
Lines.append(point)
Lines.append(segment[-1])
return Lines
else:
return Shorelines
return DrawFrame
#---------------------------------------------------------------------------
if __name__ == "__main__":
# check options:
import sys, getopt
optlist, args = getopt.getopt(sys.argv[1:],'l',["local","all","text","map","stext","hit","hitf","animate","speed","temp","props","arrow"])
if not haveNumeric:
raise ImportError(errorText)
StartUpDemo = "all" # the default
for opt in optlist:
if opt[0] == "--all":
StartUpDemo = "all"
elif opt[0] == "--text":
StartUpDemo = "text"
elif opt[0] == "--map":
StartUpDemo = "map"
elif opt[0] == "--stext":
StartUpDemo = "stext"
elif opt[0] == "--hit":
StartUpDemo = "hit"
elif opt[0] == "--hitf":
StartUpDemo = "hitf"
elif opt[0] == "--animate":
StartUpDemo = "animate"
elif opt[0] == "--speed":
StartUpDemo = "speed"
elif opt[0] == "--temp":
StartUpDemo = "temp"
elif opt[0] == "--props":
StartUpDemo = "props"
elif opt[0] == "--arrow":
StartUpDemo = "arrow"
try:
import fixdc
except ImportError:
print ("\n *************Notice*************\n"
"The fixdc module fixes the DC API for wxPython2.5.1.6 You can get the module from:\n"
"http://prdownloads.sourceforge.net/wxpython/fixdc.py?download\n"
" It will set up the DC methods to match both older and upcoming versions\n")
raise
class DemoApp(wx.App):
"""
@@ -1259,6 +1371,7 @@ if haveNumeric:
def OnInit(self):
wx.InitAllImageHandlers()
DrawFrame = BuildDrawFrame()
frame = DrawFrame(None, -1, "FloatCanvas Demo App",wx.DefaultPosition,(700,700))
self.SetTopWindow(frame)
@@ -1290,99 +1403,73 @@ if haveNumeric:
elif StartUpDemo == "props":
"starting PropertiesChange Test"
frame.PropertiesChangeTest()
elif StartUpDemo == "arrow":
"starting arrow Test"
frame.ArrowTest()
return True
def Read_MapGen(filename,stats = 0,AllLines=0):
"""
This function reads a MapGen Format file, and
returns a list of NumPy arrays with the line segments in them.
app = DemoApp(False)# put in True if you want output to go to it's own window.
app.MainLoop()
Each NumPy array in the list is an NX2 array of Python Floats.
The demo should have come with a file, "world.dat" that is the
shorelines of the whole world, in MapGen format.
"""
import string
file = open(filename,'rt')
data = file.readlines()
data = map(string.strip,data)
Shorelines = []
segment = []
for line in data:
if line:
if line == "# -b": #New segment beginning
if segment: Shorelines.append(Numeric.array(segment))
segment = []
else:
segment.append(map(float,string.split(line)))
if segment: Shorelines.append(Numeric.array(segment))
# It's not running stand-alone, set up for wxPython demo.
if not haveNumeric:
## TestPanel and runTest used for integration into wxPython Demo
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
import images
note1 = wx.StaticText(self, -1, errorText)
note2 = wx.StaticText(self, -1, "This is what the FloatCanvas can look like:")
S = wx.BoxSizer(wx.VERTICAL)
S.Add((10, 10), 1)
S.Add(note1, 0, wx.ALIGN_CENTER)
S.Add(note2, 0, wx.ALIGN_CENTER | wx.BOTTOM, 4)
S.Add(wx.StaticBitmap(self,-1,images.getFloatCanvasBitmap()),0,wx.ALIGN_CENTER)
S.Add((10, 10), 1)
self.SetSizer(S)
self.Layout()
if stats:
NumSegments = len(Shorelines)
NumPoints = 0
for segment in Shorelines:
NumPoints = NumPoints + len(segment)
AvgPoints = NumPoints / NumSegments
print "Number of Segments: ", NumSegments
print "Average Number of Points per segment: ",AvgPoints
if AllLines:
Lines = []
for segment in Shorelines:
Lines.append(segment[0])
for point in segment[1:-1]:
Lines.append(point)
Lines.append(point)
Lines.append(segment[-1])
return Lines
else:
return Shorelines
## TestPanel and runTest used for integration into wxPython Demo
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
note1 = wx.StaticText(self, -1, "The FloatCanvas Demo needs")
note2 = wx.StaticText(self, -1, "a separate frame")
b = wx.Button(self, -1, "Open Demo Frame Now")
b.Bind(wx.EVT_BUTTON, self.OnButton)
#---------------------------------------------------------------------------
## for the wxPython demo:
S = wx.BoxSizer(wx.VERTICAL)
S.Add((10, 10), 1)
S.Add(note1, 0, wx.ALIGN_CENTER)
S.Add(note2, 0, wx.ALIGN_CENTER | wx.BOTTOM, 5)
S.Add(b, 0, wx.ALIGN_CENTER | wx.ALL, 5)
S.Add((10, 10), 1)
self.SetSizer(S)
self.Layout()
def OnButton(self, evt):
DrawFrame = BuildDrawFrame()
frame = DrawFrame(None, -1, "FloatCanvas Drawing Window",wx.DefaultPosition,(500,500))
#win = wx.lib.plot.TestFrame(self, -1, "PlotCanvas Demo")
frame.Show()
frame.DrawTest()
def runTest(frame, nb, log):
win = TestPanel(nb, log)
return win
if haveNumeric:
try:
import floatcanvas
except ImportError: # if it's not there locally, try the wxPython lib.
# import to get the doc
from wx.lib import floatcanvas
overview = floatcanvas.__doc__
else:
overview = ""
if __name__ == "__main__":
if not haveNumeric:
print errorText
else:
app = DemoApp(False)# put in True if you want output to go to it's own window.
app.MainLoop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -78,9 +78,9 @@ command_lines = [
"-a -u -n Blom13 bmp_source/toblom13.png images.py",
"-a -u -n Blom14 bmp_source/toblom14.png images.py",
"-a -u -n Blom15 bmp_source/toblom15.png images.py",
"-a -u -n Blom10Masked -m #FFFFFF bmp_source/toblom10.png images.py",
"-a -u -n FloatCanvas bmp_source/floatcanvas.png images.py",
" -u -c bmp_source/001.png throbImages.py",
"-a -u -c bmp_source/002.png throbImages.py",

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,10 @@
try:
from Numeric import array,asarray,Float,cos,pi,sum,minimum,maximum,Int32,zeros, ones, concatenate, sqrt, argmin, power, absolute
from Numeric import array,asarray,Float,cos, sin, pi,sum,minimum,maximum,Int32,zeros, ones, concatenate, sqrt, argmin, power, absolute, matrixmultiply, transpose, sometrue
except ImportError:
from numarray import array, asarray, Float, cos, pi, sum, minimum, maximum, Int32, zeros, concatenate
try:
from numarray import array, asarray, Float, cos, sin, pi, sum, minimum, maximum, Int32, zeros, concatenate, matrixmultiply, transpose, sometrue
except ImportError:
raise ImportError("I could not import either Numeric or numarray")
from time import clock, sleep
@@ -17,10 +20,11 @@ global ScreenPPI
## a custom Exceptions:
class FloatCanvasException(Exception):
class FloatCanvasError(Exception):
pass
## Create all the mouse events
# I don't see a need for these two, but maybe some day!
#EVT_FC_ENTER_WINDOW = wx.NewEventType()
#EVT_FC_LEAVE_WINDOW = wx.NewEventType()
EVT_FC_LEFT_DOWN = wx.NewEventType()
@@ -92,8 +96,9 @@ class _MouseEvent(wx.PyCommandEvent):
self._NativeEvent = NativeEvent
self.Coords = Coords
def SetCoords(self,Coords):
self.Coords = Coords
# I don't think this is used.
# def SetCoords(self,Coords):
# self.Coords = Coords
def GetCoords(self):
return self.Coords
@@ -294,7 +299,6 @@ class DrawObject:
self._Canvas.MakeHitDict()
self._Canvas.HitDict[Event][self.HitColor] = (self) # put the object in the hit dict, indexed by it's color
def UnBindAll(self):
## fixme: this only removes one from each list, there could be more.
if self._Canvas.HitDict:
@@ -421,6 +425,10 @@ class XYObjectMixin:
self.XY = array( (x, y), Float)
self.CalcBoundingBox()
def CalcBoundingBox(self):
## This may get overwritten in some subclasses
self.BoundingBox = array( (self.XY, self.XY), Float )
def SetPoint(self, xy):
self.XY = array( xy, Float)
self.XY.shape = (2,)
@@ -601,6 +609,98 @@ class Line(DrawObject,PointsObjectMixin,LineOnlyMixin):
HTdc.SetPen(self.HitPen)
HTdc.DrawLines(Points)
class Arrow(DrawObject,XYObjectMixin,LineOnlyMixin):
"""
Arrow(XY, # coords of origin of arrow (x,y)
Length, # length of arrow in pixels
theta, # angle of arrow in degrees: zero is straight up
# angle is to the right
LineColor = "Black",
LineStyle = "Solid",
LineWidth = 1,
ArrowHeadSize = 4,
ArrowHeadAngle = 45,
InForeground = False):
It will draw an arrow , starting at the point, (X,Y) pointing in
direction, theta.
"""
def __init__(self,
XY,
Length,
Direction,
LineColor = "Black",
LineStyle = "Solid",
LineWidth = 2, # pixels
ArrowHeadSize = 8, # pixels
ArrowHeadAngle = 30, # degrees
InForeground = False):
DrawObject.__init__(self, InForeground)
self.XY = array(XY, Float)
self.XY.shape = (2,) # Make sure it is a 1X2 array, even if there is only one point
self.Length = Length
self.Direction = float(Direction)
self.ArrowHeadSize = ArrowHeadSize
self.ArrowHeadAngle = float(ArrowHeadAngle)
self.CalcArrowPoints()
self.CalcBoundingBox()
self.LineColor = LineColor
self.LineStyle = LineStyle
self.LineWidth = LineWidth
self.SetPen(LineColor,LineStyle,LineWidth)
##fixme: How should the HitTest be drawn?
self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
def SetDirection(self, Direction):
self.Direction = float(Direction)
self.CalcArrowPoints()
def SetLength(self, Length):
self.Length = Length
self.CalcArrowPoints()
def SetLengthDirection(self, Length, Direction):
self.Direction = float(Direction)
self.Length = Length
self.CalcArrowPoints()
def SetLength(self, Length):
self.Length = Length
self.CalcArrowPoints()
def CalcArrowPoints(self):
L = self.Length
S = self.ArrowHeadSize
phi = self.ArrowHeadAngle * pi / 360
theta = (self.Direction-90.0) * pi / 180
ArrowPoints = array( ( (0, L, L - S*cos(phi),L, L - S*cos(phi) ),
(0, 0, S*sin(phi), 0, -S*sin(phi) ) ),
Float )
RotationMatrix = array( ( ( cos(theta), -sin(theta) ),
( sin(theta), cos(theta) ) ),
Float
)
ArrowPoints = matrixmultiply(RotationMatrix, ArrowPoints)
self.ArrowPoints = transpose(ArrowPoints)
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
dc.SetPen(self.Pen)
xy = WorldToPixel(self.XY)
ArrowPoints = xy + self.ArrowPoints
dc.DrawLines(ArrowPoints)
if HTdc and self.HitAble:
HTdc.SetPen(self.HitPen)
HTdc.DrawLines(ArrowPoints)
##class LineSet(DrawObject, ObjectSetMixin):
## """
## The LineSet class takes a list of 2-tuples, or a NX2 NumPy array of point coordinates.
@@ -755,8 +855,6 @@ class Point(DrawObject,XYObjectMixin,ColorOnlyMixin):
def SetDiameter(self,Diameter):
self.Diameter = Diameter
def CalcBoundingBox(self):
self.BoundingBox = array( (self.XY, self.XY), Float )
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
dc.SetPen(self.Pen)
@@ -821,9 +919,6 @@ class RectEllipse(DrawObject, XYObjectMixin,LineAndFillMixin):
class Rectangle(RectEllipse):
# def __init__(*args, **kwargs):
# RectEllipse.__init__(*args, **kwargs)
# raise "an error"
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
( XY, WH ) = self.SetUpDraw(dc,
@@ -993,10 +1088,6 @@ class Text(DrawObject, TextObjectMixin):
(self.TextWidth, self.TextHeight) = (None, None)
self.ShiftFun = self.ShiftFunDict[Position]
def CalcBoundingBox(self):
self.BoundingBox = array((self.XY, self.XY),Float)
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
XY = WorldToPixel(self.XY)
dc.SetFont(self.Font)
@@ -1321,7 +1412,7 @@ class FloatCanvas(wx.Panel):
elif ProjectionFun is None:
self.ProjectionFun = lambda x=None: array( (1,1), Float)
else:
raise FloatCanvasException('Projectionfun must be either: "FlatEarth", None, or a function that takes the ViewPortCenter and returns a MapProjectionVector')
raise FloatCanvasError('Projectionfun must be either: "FlatEarth", None, or a function that takes the ViewPortCenter and returns a MapProjectionVector')
def FlatEarthProjection(self,CenterPoint):
return array((cos(pi*CenterPoint[1]/180),1),Float)
@@ -1330,7 +1421,7 @@ class FloatCanvas(wx.Panel):
if Mode in ["ZoomIn","ZoomOut","Move","Mouse",None]:
self.GUIMode = Mode
else:
raise FloatCanvasException('"%s" is Not a valid Mode'%Mode)
raise FloatCanvasError('"%s" is Not a valid Mode'%Mode)
def MakeHitDict(self):
##fixme: Should this just be None if nothing has been bound?
@@ -1465,7 +1556,8 @@ class FloatCanvas(wx.Panel):
self._RaiseMouseEvent(event, EventType)
def WheelEvent(self,event):
if self.GUIMode == "Mouse":
##if self.GUIMode == "Mouse":
## Why not always raise this?
self._RaiseMouseEvent(event, EVT_FC_MOUSEWHEEL)
@@ -1516,7 +1608,7 @@ class FloatCanvas(wx.Panel):
StartMove = self.StartMove
EndMove = array((event.GetX(),event.GetY()))
if sum((StartMove-EndMove)**2) > 16:
self.Move(StartMove-EndMove,'Pixel')
self.MoveImage(StartMove-EndMove,'Pixel')
self.StartMove = None
elif self.GUIMode == "Mouse":
EventType = EVT_FC_LEFT_UP
@@ -1694,8 +1786,9 @@ class FloatCanvas(wx.Panel):
animation, for instance.
"""
#print "In Draw"
if self.PanelSize < (1,1): # it's possible for this to get called before being properly initialized.
# print "in Draw", self.PanelSize
if sometrue(self.PanelSize < 1 ): # it's possible for this to get called before being properly initialized.
# if self.PanelSize < (1,1): # it's possible for this to get called before being properly initialized.
return
if self.Debug: start = clock()
ScreenDC = wx.ClientDC(self)
@@ -1779,7 +1872,7 @@ class FloatCanvas(wx.Panel):
## else:
## return False
def Move(self,shift,CoordType):
def MoveImage(self,shift,CoordType):
"""
move the image in the window.
@@ -1798,7 +1891,8 @@ class FloatCanvas(wx.Panel):
"""
shift = array(shift,Float)
shift = asarray(shift,Float)
#print "shifting by:", shift
if CoordType == 'Panel':# convert from panel coordinates
shift = shift * array((-1,1),Float) *self.PanelSize/self.TransformVector
elif CoordType == 'Pixel': # convert from pixel coordinates
@@ -1806,7 +1900,9 @@ class FloatCanvas(wx.Panel):
elif CoordType == 'World': # No conversion
pass
else:
raise FloatCanvasException('CoordType must be either "Panel", "Pixel", or "World"')
raise FloatCanvasError('CoordType must be either "Panel", "Pixel", or "World"')
#print "shifting by:", shift
self.ViewPortCenter = self.ViewPortCenter + shift
self.MapProjectionVector = self.ProjectionFun(self.ViewPortCenter)
@@ -2010,7 +2106,7 @@ class FloatCanvas(wx.Panel):
NumBetweenBlits = self.NumBetweenBlits # for speed
for i, Object in enumerate(self._ShouldRedraw(DrawList, ViewPortBB)):
Object._Draw(dc, WorldToPixel, ScaleWorldToPixel, HTdc)
if i % NumBetweenBlits == 0:
if i+1 % NumBetweenBlits == 0:
Blit(0, 0, PanelSize0, PanelSize1, dc, 0, 0)
dc.EndDrawing()
@@ -2035,7 +2131,7 @@ class FloatCanvas(wx.Panel):
def _makeFloatCanvasAddMethods(): ## lrk's code for doing this in module __init__
classnames = ["Circle", "Ellipse", "Rectangle", "ScaledText", "Polygon",
"Line", "Text", "PointSet","Point"]
"Line", "Text", "PointSet","Point", "Arrow"]
for classname in classnames:
klass = globals()[classname]
def getaddshapemethod(klass=klass):

View File

@@ -3,18 +3,10 @@ A Panel that includes the FloatCanvas and Navigation controls
"""
#from Numeric import array,Float,cos,pi,sum,minimum,maximum,Int32
#from time import clock, sleep
import wx
#import types
#import os
import FloatCanvas, Resources
ID_ZOOM_IN_BUTTON = wx.NewId()
ID_ZOOM_OUT_BUTTON = wx.NewId()
ID_ZOOM_TO_FIT_BUTTON = wx.NewId()

View File

@@ -2,7 +2,7 @@
This is the floatcanvas package. It provides two primary modules, and a
support module.
FloatCanvas.py contains the main FloatCanvas class, and it's supporting
FloatCanvas.py contains the main FloatCanvas class, and its supporting
classes. NavCanvas.py contains a wrapper for the FloatCanvas that
provides the canvas and a toolbar with tools that allow you to navigate
the canvas (zooming, panning, etc.) Resources.py is a module that
@@ -73,6 +73,10 @@ just like the regular mouse events, but include an extra attribute:
Event.GetCoords(), that returns the (x,y) position in world coordinates,
as a length-2 NumPy vector of Floats.
There are also a full set of bindings to mouse events on objects, so
that you can specify a given function be called when an objects is
clicked, mouse-over'd, etc.
See the Demo for what it can do, and how to use it.
Copyright: Christopher Barker
@@ -90,6 +94,6 @@ Chris.Barker@noaa.gov
"""
__version__ = "0.8.5"
__version__ = "0.8.7"