Updated FloatCanvas code from Chris
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@45725 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1,26 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
|
||||
#print "running:", wx.__version__
|
||||
##First, make sure Numeric or numarray can be imported.
|
||||
try:
|
||||
import Numeric
|
||||
import RandomArray
|
||||
haveNumeric = True
|
||||
import numpy as N
|
||||
import numpy.random as RandomArray
|
||||
haveNumpy = True
|
||||
#print "Using numpy, version:", N.__version__
|
||||
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
|
||||
# numpy isn't there
|
||||
haveNumpy = False
|
||||
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"
|
||||
"The FloatCanvas requires the numpy module, version 1.* \n\n"
|
||||
"You can get info about it at:\n"
|
||||
"http://numpy.scipy.org/\n\n"
|
||||
)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -100,7 +91,10 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
item = draw_menu.Append(-1, "&Arrows","Run a test of Arrows")
|
||||
self.Bind(wx.EVT_MENU, self.ArrowTest, item)
|
||||
|
||||
item = draw_menu.Append(-1, "&Hide","Run a test of the Show() Hide() Show() and methods")
|
||||
item = draw_menu.Append(-1, "&ArrowLine Test","Run a test of drawing Arrow Lines")
|
||||
self.Bind(wx.EVT_MENU, self.ArrowLineTest, item)
|
||||
|
||||
item = draw_menu.Append(-1, "&Hide","Run a test of hiding and showing objects")
|
||||
self.Bind(wx.EVT_MENU, self.HideTest, item)
|
||||
|
||||
MenuBar.Append(draw_menu, "&Tests")
|
||||
@@ -122,10 +116,12 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
|
||||
# Add the Canvas
|
||||
self.Canvas = NavCanvas.NavCanvas(self,
|
||||
NC = NavCanvas.NavCanvas(self,
|
||||
Debug = 0,
|
||||
BackgroundColor = "DARK SLATE BLUE")
|
||||
|
||||
self.Canvas = NC.Canvas # reference the contained FloatCanvas
|
||||
|
||||
self.MsgWindow = wx.TextCtrl(self, wx.ID_ANY,
|
||||
"Look Here for output from events\n",
|
||||
style = (wx.TE_MULTILINE |
|
||||
@@ -135,13 +131,14 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
##Create a sizer to manage the Canvas and message window
|
||||
MainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
MainSizer.Add(self.Canvas, 4, wx.EXPAND)
|
||||
MainSizer.Add(NC, 4, wx.EXPAND)
|
||||
MainSizer.Add(self.MsgWindow, 1, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
self.SetSizer(MainSizer)
|
||||
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
|
||||
|
||||
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||
self.Canvas.Bind(FloatCanvas.EVT_MOTION, self.OnMove)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_MOUSEWHEEL, self.OnWheel)
|
||||
|
||||
self.EventsAreBound = False
|
||||
|
||||
@@ -161,56 +158,39 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
def BindAllMouseEvents(self):
|
||||
if not self.EventsAreBound:
|
||||
## Here is how you catch FloatCanvas mouse events
|
||||
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, self.OnLeftDown )
|
||||
FloatCanvas.EVT_LEFT_UP(self.Canvas, self.OnLeftUp )
|
||||
FloatCanvas.EVT_LEFT_DCLICK(self.Canvas, self.OnLeftDouble )
|
||||
self.Canvas.Bind(FloatCanvas.EVT_LEFT_DOWN, self.OnLeftDown)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_LEFT_UP, self.OnLeftUp)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_LEFT_DCLICK, self.OnLeftDouble)
|
||||
|
||||
FloatCanvas.EVT_MIDDLE_DOWN(self.Canvas, self.OnMiddleDown )
|
||||
FloatCanvas.EVT_MIDDLE_UP(self.Canvas, self.OnMiddleUp )
|
||||
FloatCanvas.EVT_MIDDLE_DCLICK(self.Canvas, self.OnMiddleDouble )
|
||||
self.Canvas.Bind(FloatCanvas.EVT_MIDDLE_DOWN, self.OnMiddleDown)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_MIDDLE_UP, self.OnMiddleUp)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_MIDDLE_DCLICK, self.OnMiddleDouble)
|
||||
|
||||
FloatCanvas.EVT_RIGHT_DOWN(self.Canvas, self.OnRightDown )
|
||||
FloatCanvas.EVT_RIGHT_UP(self.Canvas, self.OnRightUp )
|
||||
FloatCanvas.EVT_RIGHT_DCLICK(self.Canvas, self.OnRightDouble )
|
||||
self.Canvas.Bind(FloatCanvas.EVT_RIGHT_DOWN, self.OnRightDown)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_RIGHT_UP, self.OnRightUp)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_RIGHT_DCLICK, self.OnRightDouble)
|
||||
|
||||
FloatCanvas.EVT_MOUSEWHEEL(self.Canvas, self.OnWheel )
|
||||
self.EventsAreBound = True
|
||||
|
||||
|
||||
def UnBindAllMouseEvents(self):
|
||||
## 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)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_LEFT_DOWN)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_LEFT_UP)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_LEFT_DCLICK)
|
||||
|
||||
FloatCanvas.EVT_MIDDLE_DOWN(self.Canvas, None )
|
||||
FloatCanvas.EVT_MIDDLE_UP(self.Canvas, None )
|
||||
FloatCanvas.EVT_MIDDLE_DCLICK(self.Canvas, None )
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_MIDDLE_DOWN)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_MIDDLE_UP)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_MIDDLE_DCLICK)
|
||||
|
||||
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)
|
||||
|
||||
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 )
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_RIGHT_DOWN)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_RIGHT_UP)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_RIGHT_DCLICK)
|
||||
|
||||
self.EventsAreBound = False
|
||||
|
||||
|
||||
def PrintCoords(self,event):
|
||||
#print "coords are: %s"%(event.Coords,)
|
||||
#print "pixel coords are: %s\n"%(event.GetPosition(),)
|
||||
self.Log("coords are: %s"%(event.Coords,))
|
||||
self.Log("pixel coords are: %s\n"%(event.GetPosition(),))
|
||||
|
||||
@@ -256,7 +236,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.PrintCoords(event)
|
||||
|
||||
def OnRightUp(self, event):
|
||||
self.Log("RightDown")
|
||||
self.Log("RightUp")
|
||||
self.PrintCoords(event)
|
||||
|
||||
def OnRightDouble(self, event):
|
||||
@@ -278,6 +258,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Updates the status bar with the world coordinates
|
||||
"""
|
||||
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||
event.Skip()
|
||||
|
||||
def OnAbout(self, event):
|
||||
dlg = wx.MessageDialog(self,
|
||||
@@ -293,8 +274,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
def Clear(self,event = None):
|
||||
self.UnBindAllMouseEvents()
|
||||
self.Canvas.ClearAll()
|
||||
self.Canvas.SetProjectionFun(None)
|
||||
self.Canvas.InitAll()
|
||||
self.Canvas.Draw()
|
||||
|
||||
def OnQuit(self,event):
|
||||
@@ -304,7 +284,12 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.Destroy()
|
||||
|
||||
def DrawTest(self,event=None):
|
||||
wx.GetApp().Yield()
|
||||
"""
|
||||
This demo draws a few of everything
|
||||
|
||||
"""
|
||||
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
Range = (-10,10)
|
||||
colors = self.colors
|
||||
@@ -312,8 +297,12 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.BindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
#
|
||||
## these set the limits for how much you can zoom in and out
|
||||
Canvas.MinScale = 14
|
||||
Canvas.MaxScale = 500
|
||||
|
||||
|
||||
############# Random tests of everything ##############
|
||||
|
||||
@@ -417,6 +406,18 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
LineColor = colors[random.randint(0,len(colors)-1)],
|
||||
ArrowHeadAngle = random.uniform(20,90))
|
||||
|
||||
# ArrowLines
|
||||
for i in range(5):
|
||||
points = []
|
||||
for j in range(random.randint(2,10)):
|
||||
point = (random.randint(Range[0],Range[1]),random.randint(Range[0],Range[1]))
|
||||
points.append(point)
|
||||
lw = random.randint(1,10)
|
||||
cf = random.randint(0,len(colors)-1)
|
||||
cl = random.randint(0,len(colors)-1)
|
||||
Canvas.AddArrowLine(points, LineWidth = lw, LineColor = colors[cl], ArrowHeadSize= 16)
|
||||
|
||||
|
||||
Canvas.ZoomToBB()
|
||||
|
||||
def TestAnimation(self,event=None):
|
||||
@@ -429,15 +430,13 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
having to re-draw the whole background.
|
||||
|
||||
"""
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
Range = (-10,10)
|
||||
self.Range = Range
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
## Random tests of everything:
|
||||
colors = self.colors
|
||||
@@ -544,13 +543,12 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
#print "Did %i frames in %f seconds"%(N, (time.time() - start) )
|
||||
|
||||
def TestHitTest(self, event=None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
#Add a Hit-able rectangle
|
||||
w, h = 60, 20
|
||||
@@ -558,7 +556,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
dx = 80
|
||||
dy = 40
|
||||
x, y = 20, 20
|
||||
FontSize = 8
|
||||
FontSize = 10
|
||||
|
||||
#Add one that is not HitAble
|
||||
Canvas.AddRectangle((x,y), (w, h), LineWidth = 2)
|
||||
@@ -709,7 +707,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
R.Name = color
|
||||
R.Bind(FloatCanvas.EVT_FC_ENTER_OBJECT, self.RectMouseOver)
|
||||
R.Bind(FloatCanvas.EVT_FC_LEAVE_OBJECT, self.RectMouseLeave)
|
||||
Canvas.AddText("Mouse ENter&Leave", (x, y), Size = FontSize, Position = "bl")
|
||||
Canvas.AddText("Mouse Enter&Leave", (x, y), Size = FontSize, Position = "bl")
|
||||
Canvas.AddText(R.Name, (x, y+h), Size = FontSize, Position = "tl")
|
||||
|
||||
x = 20
|
||||
@@ -722,7 +720,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
x += dx
|
||||
color = "SEA GREEN"
|
||||
Points = Numeric.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), Numeric.Float)
|
||||
Points = N.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), N.float_)
|
||||
R = Canvas.AddPolygon(Points, LineWidth = 2, FillColor = color)
|
||||
R.Name = color + " Polygon"
|
||||
R.Bind(FloatCanvas.EVT_FC_RIGHT_DOWN, self.RectGotHitRight)
|
||||
@@ -731,7 +729,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
x += dx
|
||||
color = "Red"
|
||||
Points = Numeric.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), Numeric.Float)
|
||||
Points = N.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), N.float_)
|
||||
R = Canvas.AddPointSet(Points, Diameter = 4, Color = color)
|
||||
R.Name = "PointSet"
|
||||
R.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.PointSetGotHit)
|
||||
@@ -755,7 +753,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
x += dx
|
||||
color = "Cyan"
|
||||
Point = (x + w/2, y)
|
||||
#Points = Numeric.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), Numeric.Float)
|
||||
#Points = N.array(( (x, y), (x, y+2.*h/3), (x+w, y+h), (x+w, y+h/2.), (x + 2.*w/3, y+h/2.), (x + 2.*w/3,y) ), N.float_)
|
||||
R = Canvas.AddSquarePoint(Point, Size = 8, Color = color)
|
||||
R.Name = "SquarePoint"
|
||||
R.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.RectGotHit)
|
||||
@@ -766,13 +764,12 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.Canvas.ZoomToBB()
|
||||
|
||||
def TestHitTestForeground(self,event=None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
#Add a Hitable rectangle
|
||||
w, h = 60, 20
|
||||
@@ -871,13 +868,14 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
|
||||
def TestText(self, event= None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.BindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
|
||||
DefaultSize = 12
|
||||
Point = (3, 0)
|
||||
|
||||
## Add a non-visible rectangle, just to get a Bounding Box
|
||||
@@ -889,29 +887,29 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
# Text
|
||||
String = "Some text"
|
||||
self.Canvas.AddText("Top Left",Point,Size = 14,Color = "Yellow",BackgroundColor = "Blue", Position = "tl")
|
||||
self.Canvas.AddText("Bottom Left",Point,Size = 14,Color = "Cyan",BackgroundColor = "Black",Position = "bl")
|
||||
self.Canvas.AddText("Top Right",Point,Size = 14,Color = "Black",BackgroundColor = "Cyan",Position = "tr")
|
||||
self.Canvas.AddText("Bottom Right",Point,Size = 14,Color = "Blue",BackgroundColor = "Yellow",Position = "br")
|
||||
self.Canvas.AddText("Top Left",Point,Size = DefaultSize,Color = "Yellow",BackgroundColor = "Blue", Position = "tl")
|
||||
self.Canvas.AddText("Bottom Left",Point,Size = DefaultSize,Color = "Cyan",BackgroundColor = "Black",Position = "bl")
|
||||
self.Canvas.AddText("Top Right",Point,Size = DefaultSize,Color = "Black",BackgroundColor = "Cyan",Position = "tr")
|
||||
self.Canvas.AddText("Bottom Right",Point,Size = DefaultSize,Color = "Blue",BackgroundColor = "Yellow",Position = "br")
|
||||
Canvas.AddPointSet((Point), Color = "White", Diameter = 2)
|
||||
|
||||
Point = (3, 2)
|
||||
|
||||
Canvas.AddPointSet((Point), Color = "White", Diameter = 2)
|
||||
self.Canvas.AddText("Top Center",Point,Size = 14,Color = "Black",Position = "tc")
|
||||
self.Canvas.AddText("Bottom Center",Point,Size = 14,Color = "White",Position = "bc")
|
||||
self.Canvas.AddText("Top Center",Point,Size = DefaultSize,Color = "Black",Position = "tc")
|
||||
self.Canvas.AddText("Bottom Center",Point,Size = DefaultSize,Color = "White",Position = "bc")
|
||||
|
||||
Point = (3, 4)
|
||||
|
||||
Canvas.AddPointSet((Point), Color = "White", Diameter = 2)
|
||||
self.Canvas.AddText("Center Right",Point,Size = 14,Color = "Black",Position = "cr")
|
||||
self.Canvas.AddText("Center Left",Point,Size = 14,Color = "Black",Position = "cl")
|
||||
self.Canvas.AddText("Center Right",Point,Size = DefaultSize,Color = "Black",Position = "cr")
|
||||
self.Canvas.AddText("Center Left",Point,Size = DefaultSize,Color = "Black",Position = "cl")
|
||||
|
||||
Point = (3, -2)
|
||||
|
||||
Canvas.AddPointSet((Point), Color = "White", Diameter = 2)
|
||||
self.Canvas.AddText("Center Center",
|
||||
Point, Size = 14,
|
||||
Point, Size = DefaultSize,
|
||||
Color = "Black",
|
||||
Position = "cc")
|
||||
|
||||
@@ -927,18 +925,17 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.Canvas.AddText("ROMAN ITALIC BOLD Font", (-10, -5), Family = wx.ROMAN, Weight=wx.BOLD, Style=wx.ITALIC)
|
||||
|
||||
# NOTE: this font exists on my Linux box..who knows were else you'll find it!
|
||||
Font = wx.Font(20, wx.DEFAULT, wx.ITALIC, wx.NORMAL, False, "zapf chancery")
|
||||
self.Canvas.AddText("zapf chancery Font", (-10, -6), Font = Font)
|
||||
Font = wx.Font(20, wx.DEFAULT, wx.ITALIC, wx.NORMAL, False, "helvetica")
|
||||
self.Canvas.AddText("Helvetica Italic", (-10, -6), Font = Font)
|
||||
|
||||
self.Canvas.ZoomToBB()
|
||||
|
||||
def TestScaledText(self, event= None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.BindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
Point = (0, 0)
|
||||
|
||||
@@ -977,24 +974,23 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Canvas.AddPointSet((x,0), Color = "White", Diameter = 4)
|
||||
|
||||
|
||||
# NOTE: this font exists on my Linux box..who knows were else you'll find it!
|
||||
# NOTE: this font exists on my OS-X.who knows were else you'll find it!
|
||||
Point = (-100, 50)
|
||||
Font = wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.NORMAL, False, "zapf chancery")
|
||||
T = self.Canvas.AddScaledText("zapf chancery Font", Point, Size = 20, Font = Font, Position = 'bc')
|
||||
Font = wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.NORMAL, False, "helvetica")
|
||||
T = self.Canvas.AddScaledText("Helvetica Italic", Point, Size = 20, Font = Font, Position = 'bc')
|
||||
|
||||
Point = (-50, -50)
|
||||
Font = wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.NORMAL, False, "bookman")
|
||||
T = self.Canvas.AddScaledText("Bookman Font", Point, Size = 8, Font = Font)
|
||||
Font = wx.Font(12, wx.DEFAULT, wx.ITALIC, wx.NORMAL, False, "times")
|
||||
T = self.Canvas.AddScaledText("Times Font", Point, Size = 8, Font = Font)
|
||||
|
||||
self.Canvas.ZoomToBB()
|
||||
|
||||
def TestScaledTextBox(self, event= None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
Point = (45,40)
|
||||
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||
@@ -1010,7 +1006,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Family = wx.ROMAN,
|
||||
Style = wx.NORMAL,
|
||||
Weight = wx.NORMAL,
|
||||
Underline = False,
|
||||
Underlined = False,
|
||||
Position = 'br',
|
||||
Alignment = "left",
|
||||
InForeground = False)
|
||||
@@ -1058,7 +1054,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Family = wx.TELETYPE,
|
||||
Style = wx.NORMAL,
|
||||
Weight = wx.NORMAL,
|
||||
Underline = False,
|
||||
Underlined = False,
|
||||
Position = 'cr',
|
||||
Alignment = "left",
|
||||
InForeground = False)
|
||||
@@ -1076,7 +1072,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Family = wx.TELETYPE,
|
||||
Style = wx.NORMAL,
|
||||
Weight = wx.NORMAL,
|
||||
Underline = False,
|
||||
Underlined = False,
|
||||
Position = 'cl',
|
||||
Alignment = "left",
|
||||
InForeground = False)
|
||||
@@ -1097,7 +1093,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Family = wx.TELETYPE,
|
||||
Style = wx.NORMAL,
|
||||
Weight = wx.NORMAL,
|
||||
Underline = False,
|
||||
Underlined = False,
|
||||
Position = 'tc',
|
||||
Alignment = "left",
|
||||
InForeground = False)
|
||||
@@ -1115,7 +1111,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Family = wx.TELETYPE,
|
||||
Style = wx.NORMAL,
|
||||
Weight = wx.NORMAL,
|
||||
Underline = False,
|
||||
Underlined = False,
|
||||
Position = 'bc',
|
||||
Alignment = "left",
|
||||
InForeground = False)
|
||||
@@ -1143,7 +1139,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Family = wx.ROMAN,
|
||||
Alignment = "right"
|
||||
)
|
||||
Point = Numeric.array((100, -20), Numeric.Float)
|
||||
Point = N.array((100, -20), N.float_)
|
||||
Box = Canvas.AddScaledTextBox("Here is even more auto wrapped text. This time the line spacing is set to 0.8. \n\nThe Padding is set to 0.",
|
||||
Point,
|
||||
Size = 3,
|
||||
@@ -1157,8 +1153,8 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
)
|
||||
Canvas.AddPoint(Point, "Red", 2)
|
||||
|
||||
Point = Numeric.array((0, -40), Numeric.Float)
|
||||
# Point = Numeric.array((0, 0), Numeric.Float)
|
||||
Point = N.array((0, -40), N.float_)
|
||||
# Point = N.array((0, 0), N.float_)
|
||||
for Position in ["tl", "bl", "tr", "br"]:
|
||||
# for Position in ["br"]:
|
||||
Box = Canvas.AddScaledTextBox("Here is a\nfour liner\nanother line\nPosition=%s"%Position,
|
||||
@@ -1176,7 +1172,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
)
|
||||
Canvas.AddPoint(Point, "Red", 4)
|
||||
|
||||
Point = Numeric.array((-20, 60), Numeric.Float)
|
||||
Point = N.array((-20, 60), N.float_)
|
||||
Box = Canvas.AddScaledTextBox("Here is some\ncentered\ntext",
|
||||
Point,
|
||||
Size = 4,
|
||||
@@ -1192,7 +1188,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
LineSpacing = 0.8
|
||||
)
|
||||
|
||||
Point = Numeric.array((-20, 20), Numeric.Float)
|
||||
Point = N.array((-20, 20), N.float_)
|
||||
Box = Canvas.AddScaledTextBox("Here is some\nright aligned\ntext",
|
||||
Point,
|
||||
Size = 4,
|
||||
@@ -1207,7 +1203,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
LineSpacing = 0.8
|
||||
)
|
||||
|
||||
Point = Numeric.array((100, -60), Numeric.Float)
|
||||
Point = N.array((100, -60), N.float_)
|
||||
Box = Canvas.AddScaledTextBox("Here is some auto wrapped text. This time it is centered, rather than right aligned.\n\nThe Padding is set to 2.",
|
||||
Point,
|
||||
Size = 3,
|
||||
@@ -1230,12 +1226,11 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.Log("I'm the TextBox")
|
||||
|
||||
def TestBitmap(self, event= None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
Canvas.AddRectangle((10, 20),
|
||||
(400, 100),
|
||||
@@ -1295,16 +1290,17 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.Canvas.ZoomToBB()
|
||||
|
||||
def DrawMap(self,event = None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
import os, time
|
||||
|
||||
self.Canvas.InitAll()
|
||||
self.Canvas.SetProjectionFun("FlatEarth")
|
||||
self.BindAllMouseEvents()
|
||||
|
||||
## Test of Actual Map Data
|
||||
self.Canvas.ClearAll()
|
||||
self.Canvas.SetProjectionFun("FlatEarth")
|
||||
#start = time.clock()
|
||||
self.Log("Loading Map from a File")
|
||||
wx.GetApp().Yield() # so log text will get displayed now.
|
||||
wx.GetApp().Yield(True) # so log text will get displayed now.
|
||||
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()
|
||||
@@ -1316,16 +1312,16 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
#print "It took %f seconds to draw %i shorelines"%(time.clock() - start,len(Shorelines) )
|
||||
|
||||
|
||||
|
||||
def LineTest(self,event = None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
import os, time
|
||||
# import random
|
||||
colors = self.colors
|
||||
Range = (-10,10)
|
||||
## Test of drawing lots of lines
|
||||
Canvas = self.Canvas
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
#start = time.clock()
|
||||
linepoints = []
|
||||
linecolors = []
|
||||
@@ -1345,16 +1341,43 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Canvas.ZoomToBB()
|
||||
#print "It took %f seconds to draw %i lines"%(time.clock() - start,len(linepoints) )
|
||||
|
||||
def ArrowLineTest(self,event = None):
|
||||
wx.GetApp().Yield(True)
|
||||
Canvas = self.Canvas
|
||||
Canvas.InitAll()
|
||||
# import os, time
|
||||
## import random
|
||||
Range = (-100,100)
|
||||
colors = self.colors
|
||||
|
||||
# Lines
|
||||
for i in range(5):
|
||||
points = []
|
||||
for j in range(random.randint(2,10)):
|
||||
point = (random.randint(Range[0],Range[1]),random.randint(Range[0],Range[1]))
|
||||
points.append(point)
|
||||
lw = random.randint(1,4)
|
||||
cf = random.randint(0,len(colors)-1)
|
||||
cl = random.randint(0,len(colors)-1)
|
||||
al = random.randint(8,20)
|
||||
aa = random.randint(20,90)
|
||||
Canvas.AddArrowLine(points,
|
||||
LineWidth = lw,
|
||||
LineColor = colors[cl],
|
||||
ArrowHeadSize = al,
|
||||
ArrowHeadAngle = aa)
|
||||
|
||||
Canvas.ZoomToBB()
|
||||
|
||||
def SpeedTest(self,event=None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
BigRange = (-1000,1000)
|
||||
colors = self.colors
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
# Pointset
|
||||
coords = []
|
||||
@@ -1369,7 +1392,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Canvas.ZoomToBB()
|
||||
|
||||
def PropertiesChangeTest(self,event=None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
Range = (-10,10)
|
||||
colors = self.colors
|
||||
@@ -1377,8 +1400,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
self.ColorObjectsAll = []
|
||||
self.ColorObjectsLine = []
|
||||
@@ -1512,12 +1534,13 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.Canvas.Draw(Force = True)
|
||||
|
||||
def ArrowTest(self,event=None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
Canvas.MinScale = 15
|
||||
Canvas.MaxScale = 30
|
||||
|
||||
# put in a rectangle to get a bounding box
|
||||
Canvas.AddRectangle((0,0), (20,20), LineColor = None)
|
||||
@@ -1534,16 +1557,18 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
Canvas.AddText("Clickable Arrow", (4,18), Position = "bc")
|
||||
Arrow = Canvas.AddArrow((4,18), 80, Direction = 90 ,LineWidth = 3, LineColor = "Red", ArrowHeadAngle = 30)
|
||||
Arrow.HitLineWidth = 6
|
||||
Arrow.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.ArrowClicked)
|
||||
|
||||
Canvas.AddText("Changable Arrow", (16,4), Position = "cc")
|
||||
Canvas.AddText("Changable Arrow: try clicking it", (16,4), Position = "tc")
|
||||
self.RotArrow = Canvas.AddArrow((16,4), 80, Direction = 0 ,LineWidth = 3, LineColor = "Green", ArrowHeadAngle = 30)
|
||||
self.RotArrow.HitLineWidth = 6
|
||||
self.RotArrow.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.RotateArrow)
|
||||
|
||||
Canvas.ZoomToBB()
|
||||
|
||||
def ArrowClicked(self,event):
|
||||
print "The Arrow was Clicked"
|
||||
self.Log("The Arrow was Clicked")
|
||||
|
||||
def RotateArrow(self,event):
|
||||
##print "The Changeable Arrow was Clicked"
|
||||
@@ -1557,12 +1582,11 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
self.Canvas.Draw(Force = True)
|
||||
|
||||
def HideTest(self, event=None):
|
||||
wx.GetApp().Yield()
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
Range = (-10,10)
|
||||
|
||||
@@ -1616,21 +1640,31 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
def HidePoly(self, Button):
|
||||
Poly = Button.HidePoly
|
||||
|
||||
if Poly.Visible:
|
||||
Poly.Hide()
|
||||
Poly.Visible = False
|
||||
Button.SetText(Button.String.replace("Hide","Show"))
|
||||
else:
|
||||
Poly.Show()
|
||||
Poly.Visible = True
|
||||
Button.SetText(Button.String.replace("Show", "Hide"))
|
||||
self.Canvas.Draw(True)
|
||||
|
||||
|
||||
def TempTest(self, event= None):
|
||||
wx.GetApp().Yield()
|
||||
"""
|
||||
|
||||
This is the start of a poly editor test, but it's not complete
|
||||
so you can only run it through a command line flag:
|
||||
|
||||
python FloatCanvasDemo.py --temp
|
||||
|
||||
"""
|
||||
|
||||
wx.GetApp().Yield(True)
|
||||
|
||||
self.UnBindAllMouseEvents()
|
||||
Canvas = self.Canvas
|
||||
Canvas.ClearAll()
|
||||
Canvas.SetProjectionFun(None)
|
||||
Canvas.InitAll()
|
||||
|
||||
Range = (-10,10)
|
||||
|
||||
@@ -1654,7 +1688,6 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Canvas.ZoomToBB()
|
||||
|
||||
def SelectPoly(self, Object):
|
||||
print "In SelectPoly"
|
||||
Canvas = self.Canvas
|
||||
if Object is self.SelectedPoly:
|
||||
pass
|
||||
@@ -1673,7 +1706,7 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
Canvas.Draw()
|
||||
|
||||
def SelectPointHit(self, Point):
|
||||
print "Point Num: %i Hit"%Point.VerticeNum
|
||||
self.Log("Point Num: %i Hit"%Point.VerticeNum)
|
||||
self.SelectedPoint = Point
|
||||
|
||||
def Read_MapGen(self, filename, stats = 0,AllLines=0):
|
||||
@@ -1697,11 +1730,11 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
for line in data:
|
||||
if line:
|
||||
if line == "# -b": #New segment beginning
|
||||
if segment: Shorelines.append(Numeric.array(segment))
|
||||
if segment: Shorelines.append(N.array(segment))
|
||||
segment = []
|
||||
else:
|
||||
segment.append(map(float,string.split(line)))
|
||||
if segment: Shorelines.append(Numeric.array(segment))
|
||||
if segment: Shorelines.append(N.array(segment))
|
||||
|
||||
if stats:
|
||||
NumSegments = len(Shorelines)
|
||||
@@ -1728,13 +1761,16 @@ def BuildDrawFrame(): # this gets called when needed, rather than on import
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# running stand alone, Use wxversion:
|
||||
# import wxversion
|
||||
# wxversion.select("2.6")
|
||||
# wxversion.select("2.8")
|
||||
import wx
|
||||
|
||||
|
||||
# check options:
|
||||
import sys, getopt
|
||||
optlist, args = getopt.getopt(sys.argv[1:],'l',["local",
|
||||
"all",
|
||||
optlist, args = getopt.getopt(sys.argv[1:],'l',["all",
|
||||
"text",
|
||||
"map",
|
||||
"stext",
|
||||
@@ -1747,40 +1783,15 @@ if __name__ == "__main__":
|
||||
"temp",
|
||||
"props",
|
||||
"arrow",
|
||||
"arrowline",
|
||||
"hide"])
|
||||
|
||||
if not haveNumeric:
|
||||
if not haveNumpy:
|
||||
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] == "--stextbox":
|
||||
StartUpDemo = "stextbox"
|
||||
elif opt[0] == "--bitmap":
|
||||
StartUpDemo = "bitmap"
|
||||
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"
|
||||
elif opt[0] == "--hide":
|
||||
StartUpDemo = "hide"
|
||||
if optlist:
|
||||
StartUpDemo = optlist[0][0][2:]
|
||||
|
||||
|
||||
class DemoApp(wx.App):
|
||||
"""
|
||||
@@ -1844,6 +1855,7 @@ if __name__ == "__main__":
|
||||
frame.Show()
|
||||
|
||||
## check to see if the demo is set to start in a particular mode.
|
||||
## fixme: should this be in a dict instead?
|
||||
if StartUpDemo == "text":
|
||||
frame.TestText()
|
||||
elif StartUpDemo == "stext":
|
||||
@@ -1859,25 +1871,20 @@ if __name__ == "__main__":
|
||||
elif StartUpDemo == "hit":
|
||||
frame.TestHitTest()
|
||||
elif StartUpDemo == "hitf":
|
||||
"starting TestHitTestForeground"
|
||||
frame.TestHitTestForeground()
|
||||
elif StartUpDemo == "animate":
|
||||
"starting TestAnimation"
|
||||
frame.TestAnimation()
|
||||
elif StartUpDemo == "speed":
|
||||
"starting SpeedTest"
|
||||
frame.SpeedTest()
|
||||
elif StartUpDemo == "temp":
|
||||
"starting temp Test"
|
||||
frame.TempTest()
|
||||
elif StartUpDemo == "props":
|
||||
"starting PropertiesChange Test"
|
||||
frame.PropertiesChangeTest()
|
||||
elif StartUpDemo == "arrow":
|
||||
"starting arrow Test"
|
||||
frame.ArrowTest()
|
||||
elif StartUpDemo == "arrowline":
|
||||
frame.ArrowLineTest()
|
||||
elif StartUpDemo == "hide":
|
||||
"starting Hide Test"
|
||||
frame.HideTest()
|
||||
|
||||
return True
|
||||
@@ -1889,14 +1896,14 @@ else:
|
||||
# It's not running stand-alone, set up for wxPython demo.
|
||||
# don't neeed wxversion here.
|
||||
import wx
|
||||
if not haveNumeric:
|
||||
if not haveNumpy:
|
||||
## 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
|
||||
from wx.lib.floatcanvas.ScreenShot import getScreenShotBitmap
|
||||
|
||||
note1 = wx.StaticText(self, -1, errorText)
|
||||
note2 = wx.StaticText(self, -1, "This is what the FloatCanvas can look like:")
|
||||
@@ -1904,7 +1911,7 @@ else:
|
||||
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(wx.StaticBitmap(self,-1,getScreenShotBitmap()),0,wx.ALIGN_CENTER)
|
||||
S.Add((10, 10), 1)
|
||||
self.SetSizer(S)
|
||||
self.Layout()
|
||||
|
File diff suppressed because it is too large
Load Diff
347
wxPython/wx/lib/floatcanvas/GUIMode.py
Normal file
347
wxPython/wx/lib/floatcanvas/GUIMode.py
Normal file
@@ -0,0 +1,347 @@
|
||||
"""
|
||||
|
||||
Module that holds the GUI modes used by FloatCanvas
|
||||
|
||||
|
||||
Note that this can only be imported after a wx.App() has been created.
|
||||
|
||||
This approach was inpired by Christian Blouin, who also wrote the initial
|
||||
version of the code.
|
||||
|
||||
"""
|
||||
|
||||
import wx
|
||||
## fixme: events should live in their own module, so all of FloatCanvas
|
||||
## wouldn't have to be imported here.
|
||||
import FloatCanvas, Resources
|
||||
import numpy as N
|
||||
|
||||
## create all the Cursors, so they don't need to be created each time.
|
||||
if "wxMac" in wx.PlatformInfo: # use 16X16 cursors for wxMac
|
||||
HandCursor = wx.CursorFromImage(Resources.getHand16Image())
|
||||
GrabHandCursor = wx.CursorFromImage(Resources.getGrabHand16Image())
|
||||
|
||||
img = Resources.getMagPlus16Image()
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 6)
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 6)
|
||||
MagPlusCursor = wx.CursorFromImage(img)
|
||||
|
||||
img = Resources.getMagMinus16Image()
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 6)
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 6)
|
||||
MagMinusCursor = wx.CursorFromImage(img)
|
||||
else: # use 24X24 cursors for GTK and Windows
|
||||
HandCursor = wx.CursorFromImage(Resources.getHandImage())
|
||||
GrabHandCursor = wx.CursorFromImage(Resources.getGrabHandImage())
|
||||
|
||||
img = Resources.getMagPlusImage()
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 9)
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 9)
|
||||
MagPlusCursor = wx.CursorFromImage(img)
|
||||
|
||||
img = Resources.getMagMinusImage()
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 9)
|
||||
img.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 9)
|
||||
MagMinusCursor = wx.CursorFromImage(img)
|
||||
|
||||
|
||||
class GUIBase:
|
||||
"""
|
||||
Basic Mouse mode and baseclass for other GUImode.
|
||||
|
||||
This one does nothing with any event
|
||||
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
|
||||
Cursor = wx.NullCursor
|
||||
|
||||
# Handlers
|
||||
def OnLeftDown(self, event):
|
||||
pass
|
||||
def OnLeftUp(self, event):
|
||||
pass
|
||||
def OnLeftDouble(self, event):
|
||||
pass
|
||||
def OnRightDown(self, event):
|
||||
pass
|
||||
def OnRightUp(self, event):
|
||||
pass
|
||||
def OnRightDouble(self, event):
|
||||
pass
|
||||
def OnMiddleDown(self, event):
|
||||
pass
|
||||
def OnMiddleUp(self, event):
|
||||
pass
|
||||
def OnMiddleDouble(self, event):
|
||||
pass
|
||||
def OnWheel(self, event):
|
||||
pass
|
||||
def OnMove(self, event):
|
||||
pass
|
||||
|
||||
def UpdateScreen(self):
|
||||
"""
|
||||
Update gets called if the screen has been repainted in the middle of a zoom in
|
||||
so the Rubber Band Box can get updated
|
||||
"""
|
||||
pass
|
||||
|
||||
class GUIMouse(GUIBase):
|
||||
"""
|
||||
|
||||
Mouse mode checks for a hit test, and if nothing is hit,
|
||||
raises a FloatCanvas mouse event for each event.
|
||||
|
||||
"""
|
||||
|
||||
Cursor = wx.NullCursor
|
||||
|
||||
# Handlers
|
||||
def OnLeftDown(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_LEFT_DOWN
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnLeftUp(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_LEFT_UP
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnLeftDouble(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_LEFT_DCLICK
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnMiddleDown(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_MIDDLE_DOWN
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnMiddleUp(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_MIDDLE_UP
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnMiddleDouble(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_MIDDLE_DCLICK
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnRightDown(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_RIGHT_DOWN
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnRightUp(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_RIGHT_UP
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnRightDouble(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_RIGHT_DCLICK
|
||||
if not self.parent.HitTest(event, EventType):
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnWheel(self, event):
|
||||
EventType = FloatCanvas.EVT_FC_MOUSEWHEEL
|
||||
self.parent._RaiseMouseEvent(event, EventType)
|
||||
|
||||
def OnMove(self, event):
|
||||
## The Move event always gets raised, even if there is a hit-test
|
||||
self.parent.MouseOverTest(event)
|
||||
self.parent._RaiseMouseEvent(event,FloatCanvas.EVT_FC_MOTION)
|
||||
|
||||
|
||||
class GUIMove(GUIBase):
|
||||
|
||||
Cursor = HandCursor
|
||||
GrabCursor = GrabHandCursor
|
||||
def __init__(self, parent):
|
||||
GUIBase.__init__(self, parent)
|
||||
self.StartMove = None
|
||||
self.PrevMoveXY = None
|
||||
|
||||
def OnLeftDown(self, event):
|
||||
self.parent.SetCursor(self.GrabCursor)
|
||||
self.parent.CaptureMouse()
|
||||
self.StartMove = N.array( event.GetPosition() )
|
||||
self.PrevMoveXY = (0,0)
|
||||
|
||||
def OnLeftUp(self, event):
|
||||
if self.StartMove is not None:
|
||||
StartMove = self.StartMove
|
||||
EndMove = N.array(event.GetPosition())
|
||||
DiffMove = StartMove-EndMove
|
||||
if N.sum(DiffMove**2) > 16:
|
||||
self.parent.MoveImage(DiffMove, 'Pixel')
|
||||
self.StartMove = None
|
||||
self.parent.SetCursor(self.Cursor)
|
||||
|
||||
def OnMove(self, event):
|
||||
# Allways raise the Move event.
|
||||
self.parent._RaiseMouseEvent(event,FloatCanvas.EVT_FC_MOTION)
|
||||
if event.Dragging() and event.LeftIsDown() and not self.StartMove is None:
|
||||
xy1 = N.array( event.GetPosition() )
|
||||
wh = self.parent.PanelSize
|
||||
xy_tl = xy1 - self.StartMove
|
||||
dc = wx.ClientDC(self.parent)
|
||||
dc.BeginDrawing()
|
||||
x1,y1 = self.PrevMoveXY
|
||||
x2,y2 = xy_tl
|
||||
w,h = self.parent.PanelSize
|
||||
##fixme: This sure could be cleaner!
|
||||
if x2 > x1 and y2 > y1:
|
||||
xa = xb = x1
|
||||
ya = yb = y1
|
||||
wa = w
|
||||
ha = y2 - y1
|
||||
wb = x2- x1
|
||||
hb = h
|
||||
elif x2 > x1 and y2 <= y1:
|
||||
xa = x1
|
||||
ya = y1
|
||||
wa = x2 - x1
|
||||
ha = h
|
||||
xb = x1
|
||||
yb = y2 + h
|
||||
wb = w
|
||||
hb = y1 - y2
|
||||
elif x2 <= x1 and y2 > y1:
|
||||
xa = x1
|
||||
ya = y1
|
||||
wa = w
|
||||
ha = y2 - y1
|
||||
xb = x2 + w
|
||||
yb = y1
|
||||
wb = x1 - x2
|
||||
hb = h - y2 + y1
|
||||
elif x2 <= x1 and y2 <= y1:
|
||||
xa = x2 + w
|
||||
ya = y1
|
||||
wa = x1 - x2
|
||||
ha = h
|
||||
xb = x1
|
||||
yb = y2 + h
|
||||
wb = w
|
||||
hb = y1 - y2
|
||||
|
||||
dc.SetPen(wx.TRANSPARENT_PEN)
|
||||
dc.SetBrush(self.parent.BackgroundBrush)
|
||||
dc.DrawRectangle(xa, ya, wa, ha)
|
||||
dc.DrawRectangle(xb, yb, wb, hb)
|
||||
self.PrevMoveXY = xy_tl
|
||||
if self.parent._ForeDrawList:
|
||||
dc.DrawBitmapPoint(self.parent._ForegroundBuffer,xy_tl)
|
||||
else:
|
||||
dc.DrawBitmapPoint(self.parent._Buffer,xy_tl)
|
||||
dc.EndDrawing()
|
||||
|
||||
def OnWheel(self, event):
|
||||
"""
|
||||
By default, zoom in/out by a 0.1 factor per Wheel event.
|
||||
"""
|
||||
if event.GetWheelRotation() < 0:
|
||||
self.parent.Zoom(0.9)
|
||||
else:
|
||||
self.parent.Zoom(1.1)
|
||||
|
||||
class GUIZoomIn(GUIBase):
|
||||
|
||||
Cursor = MagPlusCursor
|
||||
|
||||
def __init__(self, parent):
|
||||
GUIBase.__init__(self, parent)
|
||||
self.StartRBBox = None
|
||||
self.PrevRBBox = None
|
||||
|
||||
def OnLeftDown(self, event):
|
||||
self.StartRBBox = N.array( event.GetPosition() )
|
||||
self.PrevRBBox = None
|
||||
self.parent.CaptureMouse()
|
||||
|
||||
def OnLeftUp(self, event):
|
||||
#if self.parent.HasCapture():
|
||||
# self.parent.ReleaseMouse()
|
||||
if event.LeftUp() and not self.StartRBBox is None:
|
||||
self.PrevRBBox = None
|
||||
EndRBBox = event.GetPosition()
|
||||
StartRBBox = self.StartRBBox
|
||||
# if mouse has moved less that ten pixels, don't use the box.
|
||||
if ( abs(StartRBBox[0] - EndRBBox[0]) > 10
|
||||
and abs(StartRBBox[1] - EndRBBox[1]) > 10 ):
|
||||
EndRBBox = self.parent.PixelToWorld(EndRBBox)
|
||||
StartRBBox = self.parent.PixelToWorld(StartRBBox)
|
||||
BB = N.array(((min(EndRBBox[0],StartRBBox[0]),
|
||||
min(EndRBBox[1],StartRBBox[1])),
|
||||
(max(EndRBBox[0],StartRBBox[0]),
|
||||
max(EndRBBox[1],StartRBBox[1]))),N.float_)
|
||||
self.parent.ZoomToBB(BB)
|
||||
else:
|
||||
Center = self.parent.PixelToWorld(StartRBBox)
|
||||
self.parent.Zoom(1.5,Center)
|
||||
self.StartRBBox = None
|
||||
|
||||
def OnMove(self, event):
|
||||
# Allways raise the Move event.
|
||||
self.parent._RaiseMouseEvent(event,FloatCanvas.EVT_FC_MOTION)
|
||||
if event.Dragging() and event.LeftIsDown() and not (self.StartRBBox is None):
|
||||
xy0 = self.StartRBBox
|
||||
xy1 = N.array( event.GetPosition() )
|
||||
wh = abs(xy1 - xy0)
|
||||
wh[0] = max(wh[0], int(wh[1]*self.parent.AspectRatio))
|
||||
wh[1] = int(wh[0] / self.parent.AspectRatio)
|
||||
xy_c = (xy0 + xy1) / 2
|
||||
dc = wx.ClientDC(self.parent)
|
||||
dc.BeginDrawing()
|
||||
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||
dc.SetLogicalFunction(wx.XOR)
|
||||
if self.PrevRBBox:
|
||||
dc.DrawRectanglePointSize(*self.PrevRBBox)
|
||||
self.PrevRBBox = ( xy_c - wh/2, wh )
|
||||
dc.DrawRectanglePointSize( *self.PrevRBBox )
|
||||
dc.EndDrawing()
|
||||
|
||||
def UpdateScreen(self):
|
||||
"""
|
||||
Update gets called if the screen has been repainted in the middle of a zoom in
|
||||
so the Rubber Band Box can get updated
|
||||
"""
|
||||
if self.PrevRBBox is not None:
|
||||
dc = wx.ClientDC(self.parent)
|
||||
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||
dc.SetLogicalFunction(wx.XOR)
|
||||
dc.DrawRectanglePointSize(*self.PrevRBBox)
|
||||
|
||||
def OnRightDown(self, event):
|
||||
self.parent.Zoom(1/1.5, event.GetPosition(), centerCoords="pixel")
|
||||
|
||||
def OnWheel(self, event):
|
||||
if event.GetWheelRotation() < 0:
|
||||
self.parent.Zoom(0.9)
|
||||
else:
|
||||
self.parent.Zoom(1.1)
|
||||
|
||||
class GUIZoomOut(GUIBase):
|
||||
|
||||
Cursor = MagMinusCursor
|
||||
|
||||
def OnLeftDown(self, event):
|
||||
self.parent.Zoom(1/1.5, event.GetPosition(), centerCoords="pixel")
|
||||
|
||||
def OnRightDown(self, event):
|
||||
self.parent.Zoom(1.5, event.GetPosition(), centerCoords="pixel")
|
||||
|
||||
def OnWheel(self, event):
|
||||
if event.GetWheelRotation() < 0:
|
||||
self.parent.Zoom(0.9)
|
||||
else:
|
||||
self.parent.Zoom(1.1)
|
||||
|
||||
def OnMove(self, event):
|
||||
# Allways raise the Move event.
|
||||
self.parent._RaiseMouseEvent(event,FloatCanvas.EVT_FC_MOTION)
|
||||
|
@@ -4,17 +4,8 @@ A Panel that includes the FloatCanvas and Navigation controls
|
||||
"""
|
||||
|
||||
import wx
|
||||
|
||||
import FloatCanvas, Resources
|
||||
|
||||
ID_ZOOM_IN_BUTTON = wx.NewId()
|
||||
ID_ZOOM_OUT_BUTTON = wx.NewId()
|
||||
ID_ZOOM_TO_FIT_BUTTON = wx.NewId()
|
||||
ID_MOVE_MODE_BUTTON = wx.NewId()
|
||||
ID_POINTER_BUTTON = wx.NewId()
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class NavCanvas(wx.Panel):
|
||||
"""
|
||||
@@ -23,96 +14,80 @@ class NavCanvas(wx.Panel):
|
||||
This is a high level window that encloses the FloatCanvas in a panel
|
||||
and adds a Navigation toolbar.
|
||||
|
||||
Copyright: Christopher Barker)
|
||||
|
||||
License: Same as the version of wxPython you are using it with
|
||||
|
||||
Please let me know if you're using this!!!
|
||||
|
||||
Contact me at:
|
||||
|
||||
Chris.Barker@noaa.gov
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, parent, id = -1,
|
||||
def __init__(self,
|
||||
parent,
|
||||
id = wx.ID_ANY,
|
||||
size = wx.DefaultSize,
|
||||
**kwargs): # The rest just get passed into FloatCanvas
|
||||
wx.Panel.__init__(self, parent, id, size=size)
|
||||
|
||||
wx.Panel.__init__( self, parent, id, wx.DefaultPosition, size)
|
||||
|
||||
self.BuildToolbar()
|
||||
## Create the vertical sizer for the toolbar and Panel
|
||||
box = wx.BoxSizer(wx.VERTICAL)
|
||||
box.Add(self.BuildToolbar(), 0, wx.ALL | wx.ALIGN_LEFT | wx.GROW, 4)
|
||||
box.Add(self.ToolBar, 0, wx.ALL | wx.ALIGN_LEFT | wx.GROW, 4)
|
||||
|
||||
self.Canvas = FloatCanvas.FloatCanvas( self, wx.NewId(),
|
||||
size = wx.DefaultSize,
|
||||
**kwargs)
|
||||
self.Canvas = FloatCanvas.FloatCanvas(self, **kwargs)
|
||||
box.Add(self.Canvas, 1, wx.GROW)
|
||||
|
||||
box.Fit(self)
|
||||
self.SetSizer(box)
|
||||
self.SetSizerAndFit(box)
|
||||
|
||||
|
||||
import GUIMode # here so that it doesn't get imported before wx.App()
|
||||
self.GUIZoomIn = GUIMode.GUIZoomIn(self.Canvas)
|
||||
self.GUIZoomOut = GUIMode.GUIZoomOut(self.Canvas)
|
||||
self.GUIMove = GUIMode.GUIMove(self.Canvas)
|
||||
self.GUIMouse = GUIMode.GUIMouse(self.Canvas)
|
||||
|
||||
# default to Mouse mode
|
||||
self.ToolBar.ToggleTool(ID_POINTER_BUTTON,1)
|
||||
self.Canvas.SetMode("Mouse")
|
||||
self.ToolBar.ToggleTool(self.PointerTool.GetId(), True)
|
||||
self.Canvas.SetMode(self.GUIMouse)
|
||||
|
||||
return None
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""
|
||||
Delegate all extra methods to the Canvas
|
||||
"""
|
||||
attrib = getattr(self.Canvas, name)
|
||||
## add the attribute to this module's dict for future calls
|
||||
self.__dict__[name] = attrib
|
||||
return attrib
|
||||
|
||||
def BuildToolbar(self):
|
||||
tb = wx.ToolBar(self,-1)
|
||||
tb = wx.ToolBar(self)
|
||||
self.ToolBar = tb
|
||||
|
||||
tb.SetToolBitmapSize((24,24))
|
||||
|
||||
tb.AddTool(ID_POINTER_BUTTON, Resources.getPointerBitmap(), isToggle=True, shortHelpString = "Pointer")
|
||||
wx.EVT_TOOL(self, ID_POINTER_BUTTON, self.SetToolMode)
|
||||
self.PointerTool = tb.AddRadioTool(wx.ID_ANY, bitmap=Resources.getPointerBitmap(), shortHelp = "Pointer")
|
||||
self.Bind(wx.EVT_TOOL, lambda evt : self.SetMode(Mode=self.GUIMouse), self.PointerTool)
|
||||
|
||||
tb.AddTool(ID_ZOOM_IN_BUTTON, Resources.getMagPlusBitmap(), isToggle=True, shortHelpString = "Zoom In")
|
||||
wx.EVT_TOOL(self, ID_ZOOM_IN_BUTTON, self.SetToolMode)
|
||||
self.ZoomInTool = tb.AddRadioTool(wx.ID_ANY, bitmap=Resources.getMagPlusBitmap(), shortHelp = "Zoom In")
|
||||
self.Bind(wx.EVT_TOOL, lambda evt : self.SetMode(Mode=self.GUIZoomIn), self.ZoomInTool)
|
||||
|
||||
tb.AddTool(ID_ZOOM_OUT_BUTTON, Resources.getMagMinusBitmap(), isToggle=True, shortHelpString = "Zoom Out")
|
||||
wx.EVT_TOOL(self, ID_ZOOM_OUT_BUTTON, self.SetToolMode)
|
||||
self.ZoomOutTool = tb.AddRadioTool(wx.ID_ANY, bitmap=Resources.getMagMinusBitmap(), shortHelp = "Zoom Out")
|
||||
self.Bind(wx.EVT_TOOL, lambda evt : self.SetMode(Mode=self.GUIZoomOut), self.ZoomOutTool)
|
||||
|
||||
tb.AddTool(ID_MOVE_MODE_BUTTON, Resources.getHandBitmap(), isToggle=True, shortHelpString = "Move")
|
||||
wx.EVT_TOOL(self, ID_MOVE_MODE_BUTTON, self.SetToolMode)
|
||||
self.MoveTool = tb.AddRadioTool(wx.ID_ANY, bitmap=Resources.getHandBitmap(), shortHelp = "Move")
|
||||
self.Bind(wx.EVT_TOOL, lambda evt : self.SetMode(Mode=self.GUIMove), self.MoveTool)
|
||||
|
||||
tb.AddSeparator()
|
||||
|
||||
tb.AddControl(wx.Button(tb, ID_ZOOM_TO_FIT_BUTTON, "Zoom To Fit",wx.DefaultPosition, wx.DefaultSize))
|
||||
wx.EVT_BUTTON(self, ID_ZOOM_TO_FIT_BUTTON, self.ZoomToFit)
|
||||
self.ZoomButton = wx.Button(tb, label="Zoom To Fit")
|
||||
tb.AddControl(self.ZoomButton)
|
||||
self.ZoomButton.Bind(wx.EVT_BUTTON, self.ZoomToFit)
|
||||
|
||||
tb.Realize()
|
||||
S = tb.GetSize()
|
||||
tb.SetSizeHints(S[0],S[1])
|
||||
## fixme: remove this when the bug is fixed!
|
||||
wx.CallAfter(self.HideShowHack) # this required on wxPython 2.8.3 on OS-X
|
||||
|
||||
return tb
|
||||
|
||||
def SetToolMode(self,event):
|
||||
for id in [ID_ZOOM_IN_BUTTON,
|
||||
ID_ZOOM_OUT_BUTTON,
|
||||
ID_MOVE_MODE_BUTTON,
|
||||
ID_POINTER_BUTTON]:
|
||||
self.ToolBar.ToggleTool(id,0)
|
||||
self.ToolBar.ToggleTool(event.GetId(),1)
|
||||
if event.GetId() == ID_ZOOM_IN_BUTTON:
|
||||
self.Canvas.SetMode("ZoomIn")
|
||||
elif event.GetId() == ID_ZOOM_OUT_BUTTON:
|
||||
self.Canvas.SetMode("ZoomOut")
|
||||
elif event.GetId() == ID_MOVE_MODE_BUTTON:
|
||||
self.Canvas.SetMode("Move")
|
||||
elif event.GetId() == ID_POINTER_BUTTON:
|
||||
self.Canvas.SetMode("Mouse")
|
||||
def HideShowHack(self):
|
||||
##fixme: remove this when the bug is fixed!
|
||||
"""
|
||||
Hack to hide and show button on toolbar to get around OS-X bug on
|
||||
wxPython2.8 on OS-X
|
||||
"""
|
||||
self.ZoomButton.Hide()
|
||||
self.ZoomButton.Show()
|
||||
|
||||
def SetMode(self, Mode):
|
||||
self.Canvas.SetMode(Mode)
|
||||
|
||||
def ZoomToFit(self,Event):
|
||||
self.Canvas.ZoomToBB()
|
||||
self.Canvas.SetFocus() # Otherwise the focus stays on the Button, and wheel events are lost.
|
||||
|
||||
|
170
wxPython/wx/lib/floatcanvas/Utilities/BBox.py
Normal file
170
wxPython/wx/lib/floatcanvas/Utilities/BBox.py
Normal file
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
A Bounding Box object and assorted utilities , subclassed from a numpy array
|
||||
|
||||
"""
|
||||
|
||||
import numpy as N
|
||||
|
||||
class BBox(N.ndarray):
|
||||
"""
|
||||
A Bounding Box object:
|
||||
|
||||
Takes Data as an array. Data is any python sequence that can be turned into a
|
||||
2x2 numpy array of floats:
|
||||
|
||||
[[MinX, MinY ],
|
||||
[MaxX, MaxY ]]
|
||||
|
||||
It is a subclass of numpy.ndarray, so for the most part it can be used as
|
||||
an array, and arrays that fit the above description can be used in its place.
|
||||
|
||||
Usually created by the factory functions:
|
||||
|
||||
asBBox
|
||||
|
||||
and
|
||||
|
||||
fromPoints
|
||||
|
||||
"""
|
||||
def __new__(subtype, data):
|
||||
"""
|
||||
Takes Data as an array. Data is any python sequence that can be turned into a
|
||||
2x2 numpy array of floats:
|
||||
|
||||
[[MinX, MinY ],
|
||||
[MaxX, MaxY ]]
|
||||
|
||||
You don't usually call this directly. BBox objects are created with the factory functions:
|
||||
|
||||
asBBox
|
||||
|
||||
and
|
||||
|
||||
fromPoints
|
||||
|
||||
"""
|
||||
arr = N.array(data, N.float)
|
||||
arr.shape = (2,2)
|
||||
if arr[0,0] > arr[1,0] or arr[0,1] > arr[1,1]:
|
||||
# note: zero sized BB OK.
|
||||
raise ValueError("BBox values not aligned: \n minimum values must be less that maximum values")
|
||||
return N.ndarray.__new__(BBox, shape=arr.shape, dtype=arr.dtype, buffer=arr)
|
||||
|
||||
def Overlaps(self, BB):
|
||||
"""
|
||||
Overlap(BB):
|
||||
|
||||
Tests if the given Bounding Box overlaps with this one.
|
||||
Returns True is the Bounding boxes overlap, False otherwise
|
||||
If they are just touching, returns True
|
||||
"""
|
||||
|
||||
if ( (self[1,0] >= BB[0,0]) and (self[0,0] <= BB[1,0]) and
|
||||
(self[1,1] >= BB[0,1]) and (self[0,1] <= BB[1,1]) ):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Inside(self, BB):
|
||||
"""
|
||||
Inside(BB):
|
||||
|
||||
Tests if the given Bounding Box is entirely inside this one.
|
||||
|
||||
Returns True if it is entirely inside, or touching the
|
||||
border.
|
||||
|
||||
Returns False otherwise
|
||||
"""
|
||||
if ( (BB[0,0] >= self[0,0]) and (BB[1,0] <= self[1,0]) and
|
||||
(BB[0,1] >= self[0,1]) and (BB[1,1] <= self[1,1]) ):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Merge(self, BB):
|
||||
"""
|
||||
Joins this bounding box with the one passed in, maybe making this one bigger
|
||||
|
||||
"""
|
||||
|
||||
if BB[0,0] < self[0,0]: self[0,0] = BB[0,0]
|
||||
if BB[0,1] < self[0,1]: self[0,1] = BB[0,1]
|
||||
if BB[1,0] > self[1,0]: self[1,0] = BB[1,0]
|
||||
if BB[1,1] > self[1,1]: self[1,1] = BB[1,1]
|
||||
|
||||
### This could be used for a make BB from a bunch of BBs
|
||||
|
||||
#~ def _getboundingbox(bboxarray): # lrk: added this
|
||||
#~ # returns the bounding box of a bunch of bounding boxes
|
||||
#~ upperleft = N.minimum.reduce(bboxarray[:,0])
|
||||
#~ lowerright = N.maximum.reduce(bboxarray[:,1])
|
||||
#~ return N.array((upperleft, lowerright), N.float)
|
||||
#~ _getboundingbox = staticmethod(_getboundingbox)
|
||||
|
||||
|
||||
## Save the ndarray __eq__ for internal use.
|
||||
Array__eq__ = N.ndarray.__eq__
|
||||
def __eq__(self, BB):
|
||||
"""
|
||||
__eq__(BB) The equality operator
|
||||
|
||||
A == B if and only if all the entries are the same
|
||||
|
||||
"""
|
||||
return N.all(self.Array__eq__(BB))
|
||||
|
||||
|
||||
def asBBox(data):
|
||||
"""
|
||||
returns a BBox object.
|
||||
|
||||
If object is a BBox, it is returned unaltered
|
||||
|
||||
If object is a numpy array, a BBox object is returned that shares a
|
||||
view of the data with that array
|
||||
|
||||
"""
|
||||
|
||||
if isinstance(data, BBox):
|
||||
return data
|
||||
arr = N.asarray(data, N.float)
|
||||
return N.ndarray.__new__(BBox, shape=arr.shape, dtype=arr.dtype, buffer=arr)
|
||||
|
||||
def fromPoints(Points):
|
||||
"""
|
||||
fromPoints (Points).
|
||||
|
||||
reruns the bounding box of the set of points in Points. Points can
|
||||
be any python object that can be turned into a numpy NX2 array of Floats.
|
||||
|
||||
If a single point is passed in, a zero-size Bounding Box is returned.
|
||||
|
||||
"""
|
||||
Points = N.asarray(Points, N.float).reshape(-1,2)
|
||||
|
||||
arr = N.vstack( (Points.min(0), Points.max(0)) )
|
||||
return N.ndarray.__new__(BBox, shape=arr.shape, dtype=arr.dtype, buffer=arr)
|
||||
|
||||
def fromBBArray(BBarray):
|
||||
"""
|
||||
Builds a BBox object from an array of Bounding Boxes.
|
||||
The resulting Bounding Box encompases all the included BBs.
|
||||
|
||||
The BBarray is in the shape: (Nx2x2) where BBarray[n] is a 2x2 array that represents a BBox
|
||||
"""
|
||||
|
||||
#upperleft = N.minimum.reduce(BBarray[:,0])
|
||||
#lowerright = N.maximum.reduce(BBarray[:,1])
|
||||
|
||||
# BBarray = N.asarray(BBarray, N.float).reshape(-1,2)
|
||||
# arr = N.vstack( (BBarray.min(0), BBarray.max(0)) )
|
||||
BBarray = N.asarray(BBarray, N.float).reshape(-1,2,2)
|
||||
arr = N.vstack( (BBarray[:,0,:].min(0), BBarray[:,1,:].max(0)) )
|
||||
return asBBox(arr)
|
||||
#return asBBox( (upperleft, lowerright) ) * 2
|
||||
|
||||
|
||||
|
||||
|
354
wxPython/wx/lib/floatcanvas/Utilities/BBoxTest.py
Normal file
354
wxPython/wx/lib/floatcanvas/Utilities/BBoxTest.py
Normal file
@@ -0,0 +1,354 @@
|
||||
|
||||
"""
|
||||
Test code for the BBox Object
|
||||
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from BBox import *
|
||||
|
||||
class testCreator(unittest.TestCase):
|
||||
def testCreates(self):
|
||||
B = BBox(((0,0),(5,5)))
|
||||
self.failUnless(isinstance(B, BBox))
|
||||
|
||||
def testType(self):
|
||||
B = N.array(((0,0),(5,5)))
|
||||
self.failIf(isinstance(B, BBox))
|
||||
|
||||
def testDataType(self):
|
||||
B = BBox(((0,0),(5,5)))
|
||||
self.failUnless(B.dtype == N.float)
|
||||
|
||||
def testShape(self):
|
||||
B = BBox((0,0,5,5))
|
||||
self.failUnless(B.shape == (2,2))
|
||||
|
||||
def testShape2(self):
|
||||
self.failUnlessRaises(ValueError, BBox, (0,0,5) )
|
||||
|
||||
def testShape3(self):
|
||||
self.failUnlessRaises(ValueError, BBox, (0,0,5,6,7) )
|
||||
|
||||
def testArrayConstruction(self):
|
||||
A = N.array(((4,5),(10,12)), N.float_)
|
||||
B = BBox(A)
|
||||
self.failUnless(isinstance(B, BBox))
|
||||
|
||||
def testMinMax(self):
|
||||
self.failUnlessRaises(ValueError, BBox, (0,0,-1,6) )
|
||||
|
||||
def testMinMax2(self):
|
||||
self.failUnlessRaises(ValueError, BBox, (0,0,1,-6) )
|
||||
|
||||
def testMinMax(self):
|
||||
# OK to have a zero-sized BB
|
||||
B = BBox(((0,0),(0,5)))
|
||||
self.failUnless(isinstance(B, BBox))
|
||||
|
||||
def testMinMax2(self):
|
||||
# OK to have a zero-sized BB
|
||||
B = BBox(((10.0,-34),(10.0,-34.0)))
|
||||
self.failUnless(isinstance(B, BBox))
|
||||
|
||||
def testMinMax3(self):
|
||||
# OK to have a tiny BB
|
||||
B = BBox(((0,0),(1e-20,5)))
|
||||
self.failUnless(isinstance(B, BBox))
|
||||
|
||||
def testMinMax4(self):
|
||||
# Should catch tiny difference
|
||||
self.failUnlessRaises(ValueError, BBox, ((0,0), (-1e-20,5)) )
|
||||
|
||||
class testAsBBox(unittest.TestCase):
|
||||
|
||||
def testPassThrough(self):
|
||||
B = BBox(((0,0),(5,5)))
|
||||
C = asBBox(B)
|
||||
self.failUnless(B is C)
|
||||
|
||||
def testPassThrough2(self):
|
||||
B = (((0,0),(5,5)))
|
||||
C = asBBox(B)
|
||||
self.failIf(B is C)
|
||||
|
||||
def testPassArray(self):
|
||||
# Different data type
|
||||
A = N.array( (((0,0),(5,5))) )
|
||||
C = asBBox(A)
|
||||
self.failIf(A is C)
|
||||
|
||||
def testPassArray2(self):
|
||||
# same data type -- should be a view
|
||||
A = N.array( (((0,0),(5,5))), N.float_ )
|
||||
C = asBBox(A)
|
||||
A[0,0] = -10
|
||||
self.failUnless(C[0,0] == A[0,0])
|
||||
|
||||
class testIntersect(unittest.TestCase):
|
||||
|
||||
def testSame(self):
|
||||
B = BBox(((-23.5, 456),(56, 532.0)))
|
||||
C = BBox(((-23.5, 456),(56, 532.0)))
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testUpperLeft(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (0, 12),(10, 32.0) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testUpperRight(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (12, 12),(25, 32.0) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testLowerRight(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (12, 5),(25, 15) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testLowerLeft(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (-10, 5),(8.5, 15) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testBelow(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (-10, 5),(8.5, 9.2) ) )
|
||||
self.failIf(B.Overlaps(C) )
|
||||
|
||||
def testAbove(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (-10, 25.001),(8.5, 32) ) )
|
||||
self.failIf(B.Overlaps(C) )
|
||||
|
||||
def testLeft(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (4, 8),(4.95, 32) ) )
|
||||
self.failIf(B.Overlaps(C) )
|
||||
|
||||
def testRight(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (17.1, 8),(17.95, 32) ) )
|
||||
self.failIf(B.Overlaps(C) )
|
||||
|
||||
def testInside(self):
|
||||
B = BBox( ( (-15, -25),(-5, -10) ) )
|
||||
C = BBox( ( (-12, -22), (-6, -8) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testOutside(self):
|
||||
B = BBox( ( (-15, -25),(-5, -10) ) )
|
||||
C = BBox( ( (-17, -26), (3, 0) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testTouch(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (15, 8),(17.95, 32) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testCorner(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (15, 25),(17.95, 32) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testZeroSize(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (15, 25),(15, 25) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testZeroSize2(self):
|
||||
B = BBox( ( (5, 10),(5, 10) ) )
|
||||
C = BBox( ( (15, 25),(15, 25) ) )
|
||||
self.failIf(B.Overlaps(C) )
|
||||
|
||||
def testZeroSize3(self):
|
||||
B = BBox( ( (5, 10),(5, 10) ) )
|
||||
C = BBox( ( (0, 8),(10, 12) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
def testZeroSize4(self):
|
||||
B = BBox( ( (5, 1),(10, 25) ) )
|
||||
C = BBox( ( (8, 8),(8, 8) ) )
|
||||
self.failUnless(B.Overlaps(C) )
|
||||
|
||||
|
||||
|
||||
class testEquality(unittest.TestCase):
|
||||
def testSame(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
self.failUnless(B == C)
|
||||
|
||||
def testIdentical(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
self.failUnless(B == B)
|
||||
|
||||
def testNotSame(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = BBox( ( (1.0, 2.0), (5.0, 10.1) ) )
|
||||
self.failIf(B == C)
|
||||
|
||||
def testWithArray(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = N.array( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
self.failUnless(B == C)
|
||||
|
||||
def testWithArray2(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = N.array( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
self.failUnless(C == B)
|
||||
|
||||
def testWithArray2(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = N.array( ( (1.01, 2.0), (5.0, 10.0) ) )
|
||||
self.failIf(C == B)
|
||||
|
||||
class testInside(unittest.TestCase):
|
||||
def testSame(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
self.failUnless(B.Inside(C))
|
||||
|
||||
def testPoint(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = BBox( ( (3.0, 4.0), (3.0, 4.0) ) )
|
||||
self.failUnless(B.Inside(C))
|
||||
|
||||
def testPointOutside(self):
|
||||
B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
C = BBox( ( (-3.0, 4.0), (0.10, 4.0) ) )
|
||||
self.failIf(B.Inside(C))
|
||||
|
||||
def testUpperLeft(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (0, 12),(10, 32.0) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
def testUpperRight(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (12, 12),(25, 32.0) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
def testLowerRight(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (12, 5),(25, 15) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
def testLowerLeft(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (-10, 5),(8.5, 15) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
def testBelow(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (-10, 5),(8.5, 9.2) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
def testAbove(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (-10, 25.001),(8.5, 32) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
def testLeft(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (4, 8),(4.95, 32) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
def testRight(self):
|
||||
B = BBox( ( (5, 10),(15, 25) ) )
|
||||
C = BBox( ( (17.1, 8),(17.95, 32) ) )
|
||||
self.failIf(B.Inside(C) )
|
||||
|
||||
class testFromPoints(unittest.TestCase):
|
||||
|
||||
def testCreate(self):
|
||||
Pts = N.array( ((5,2),
|
||||
(3,4),
|
||||
(1,6),
|
||||
), N.float_ )
|
||||
B = fromPoints(Pts)
|
||||
#B = BBox( ( (1.0, 2.0), (5.0, 10.0) ) )
|
||||
self.failUnless(B[0,0] == 1.0 and
|
||||
B[0,1] == 2.0 and
|
||||
B[1,0] == 5.0 and
|
||||
B[1,1] == 6.0
|
||||
)
|
||||
def testCreateInts(self):
|
||||
Pts = N.array( ((5,2),
|
||||
(3,4),
|
||||
(1,6),
|
||||
) )
|
||||
B = fromPoints(Pts)
|
||||
self.failUnless(B[0,0] == 1.0 and
|
||||
B[0,1] == 2.0 and
|
||||
B[1,0] == 5.0 and
|
||||
B[1,1] == 6.0
|
||||
)
|
||||
|
||||
def testSinglePoint(self):
|
||||
Pts = N.array( (5,2), N.float_ )
|
||||
B = fromPoints(Pts)
|
||||
self.failUnless(B[0,0] == 5.0 and
|
||||
B[0,1] == 2.0 and
|
||||
B[1,0] == 5.0 and
|
||||
B[1,1] == 2.0
|
||||
)
|
||||
|
||||
def testListTuples(self):
|
||||
Pts = [ (3, 6.5),
|
||||
(13, 43.2),
|
||||
(-4.32, -4),
|
||||
(65, -23),
|
||||
(-0.0001, 23.432),
|
||||
]
|
||||
B = fromPoints(Pts)
|
||||
self.failUnless(B[0,0] == -4.32 and
|
||||
B[0,1] == -23.0 and
|
||||
B[1,0] == 65.0 and
|
||||
B[1,1] == 43.2
|
||||
)
|
||||
class testMerge(unittest.TestCase):
|
||||
A = BBox( ((-23.5, 456), (56, 532.0)) )
|
||||
B = BBox( ((-20.3, 460), (54, 465 )) )# B should be completely inside A
|
||||
C = BBox( ((-23.5, 456), (58, 540.0)) )# up and to the right or A
|
||||
D = BBox( ((-26.5, 12), (56, 532.0)) )
|
||||
|
||||
def testInside(self):
|
||||
C = self.A.copy()
|
||||
C.Merge(self.B)
|
||||
self.failUnless(C == self.A)
|
||||
|
||||
def testFullOutside(self):
|
||||
C = self.B.copy()
|
||||
C.Merge(self.A)
|
||||
self.failUnless(C == self.A)
|
||||
|
||||
def testUpRight(self):
|
||||
A = self.A.copy()
|
||||
A.Merge(self.C)
|
||||
self.failUnless(A[0] == self.A[0] and A[1] == self.C[1])
|
||||
|
||||
def testDownLeft(self):
|
||||
A = self.A.copy()
|
||||
A.Merge(self.D)
|
||||
self.failUnless(A[0] == self.D[0] and A[1] == self.A[1])
|
||||
|
||||
class testBBarray(unittest.TestCase):
|
||||
BBarray = N.array( ( ((-23.5, 456), (56, 532.0)),
|
||||
((-20.3, 460), (54, 465 )),
|
||||
((-23.5, 456), (58, 540.0)),
|
||||
((-26.5, 12), (56, 532.0)),
|
||||
),
|
||||
dtype=N.float)
|
||||
print BBarray
|
||||
BB = asBBox( ((-26.5, 12.), ( 58. , 540.)) )
|
||||
|
||||
def testJoin(self):
|
||||
BB = fromBBArray(self.BBarray)
|
||||
self.failUnless(BB == self.BB, "Wrong BB was created. It was:\n%s \nit should have been:\n%s"%(BB, self.BB))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
115
wxPython/wx/lib/floatcanvas/Utilities/GUI.py
Normal file
115
wxPython/wx/lib/floatcanvas/Utilities/GUI.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
|
||||
Part of the floatcanvas.Utilities package.
|
||||
|
||||
This module contains assorted GUI-related utilities that can be used
|
||||
with FloatCanvas
|
||||
|
||||
So far, they are:
|
||||
|
||||
RubberBandBox: used to draw a RubberBand Box on the screen
|
||||
|
||||
"""
|
||||
import wx
|
||||
from floatcanvas import FloatCanvas
|
||||
|
||||
class RubberBandBox:
|
||||
"""
|
||||
Class to provide a rubber band box that can be drawn on a Window
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, Canvas, CallBack, Tol=5):
|
||||
|
||||
"""
|
||||
To initialize:
|
||||
|
||||
RubberBandBox(Canvas, CallBack)
|
||||
|
||||
Canvas: the FloatCanvas you want the Rubber band box to be used on
|
||||
|
||||
CallBack: is the method you want called when the mouse is
|
||||
released. That method will be called, passing in a rect
|
||||
parameter, where rect is: (Point, WH) of the rect in
|
||||
world coords.
|
||||
|
||||
Tol: The tolerance for the smallest rectangle allowed. defaults
|
||||
to 5. In pixels
|
||||
|
||||
Methods:
|
||||
|
||||
Enable() : Enables the Rubber Band Box (Binds the events)
|
||||
|
||||
Disable() : Enables the Rubber Band Box (Unbinds the events)
|
||||
|
||||
Attributes:
|
||||
|
||||
CallBack: The callback function, if it's replaced you need to
|
||||
call Enable() again.
|
||||
|
||||
"""
|
||||
|
||||
self.Canvas = Canvas
|
||||
self.CallBack = CallBack
|
||||
self.Tol = Tol
|
||||
|
||||
self.Drawing = False
|
||||
self.RBRect = None
|
||||
self.StartPointWorld = None
|
||||
|
||||
return None
|
||||
|
||||
def Enable(self):
|
||||
"""
|
||||
Called when you want the rubber band box to be enabled
|
||||
|
||||
"""
|
||||
|
||||
# bind events:
|
||||
self.Canvas.Bind(FloatCanvas.EVT_MOTION, self.OnMove )
|
||||
self.Canvas.Bind(FloatCanvas.EVT_LEFT_DOWN, self.OnLeftDown)
|
||||
self.Canvas.Bind(FloatCanvas.EVT_LEFT_UP, self.OnLeftUp )
|
||||
|
||||
def Disable(self):
|
||||
"""
|
||||
Called when you don't want the rubber band box to be enabled
|
||||
|
||||
"""
|
||||
|
||||
# unbind events:
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_MOTION)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_LEFT_DOWN)
|
||||
self.Canvas.Unbind(FloatCanvas.EVT_LEFT_UP)
|
||||
|
||||
def OnMove(self, event):
|
||||
if self.Drawing:
|
||||
x, y = self.StartPoint
|
||||
Cornerx, Cornery = event.GetPosition()
|
||||
w, h = ( Cornerx - x, Cornery - y)
|
||||
if abs(w) > self.Tol and abs(h) > self.Tol:
|
||||
# draw the RB box
|
||||
dc = wx.ClientDC(self.Canvas)
|
||||
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||
dc.SetLogicalFunction(wx.XOR)
|
||||
if self.RBRect:
|
||||
dc.DrawRectangle(*self.RBRect)
|
||||
self.RBRect = (x, y, w, h )
|
||||
dc.DrawRectangle(*self.RBRect)
|
||||
event.Skip() # skip so that other events can catch these
|
||||
|
||||
def OnLeftDown(self, event):
|
||||
# Start drawing
|
||||
self.Drawing = True
|
||||
self.StartPoint = event.GetPosition()
|
||||
self.StartPointWorld = event.Coords
|
||||
|
||||
def OnLeftUp(self, event):
|
||||
# Stop Drawing
|
||||
if self.Drawing:
|
||||
self.Drawing = False
|
||||
if self.RBRect:
|
||||
WH = event.Coords - self.StartPointWorld
|
||||
wx.CallAfter(self.CallBack, (self.StartPointWorld, WH))
|
||||
self.RBRect = None
|
||||
self.StartPointWorld = None
|
7
wxPython/wx/lib/floatcanvas/Utilities/__init__.py
Normal file
7
wxPython/wx/lib/floatcanvas/Utilities/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""
|
||||
__init__ for the floatcanvas Utilities package
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@@ -29,8 +29,7 @@ It is double buffered, so re-draws after the window is uncovered by
|
||||
something else are very quick.
|
||||
|
||||
It relies on NumPy, which is needed for speed (maybe, I haven't profiled
|
||||
it). It will also use numarray, if you don't have Numeric, but it is
|
||||
slower.
|
||||
properly) and convenience.
|
||||
|
||||
Bugs and Limitations: Lots: patches, fixes welcome
|
||||
|
||||
@@ -93,6 +92,6 @@ Chris.Barker@noaa.gov
|
||||
|
||||
"""
|
||||
|
||||
__version__ = "0.9.10"
|
||||
__version__ = "0.9.18a"
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user