/
BB_HitTest.py
133 lines (96 loc) · 4.24 KB
/
BB_HitTest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python
"""
Test of an alternative hit test methoid that used the bounding boxes of the objects instead.
Poorly tested!
Edited from code contributed by Benjamin Jessup on the mailing list
"""
import wx
## import the installed version
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
## import a local version
#import sys
#sys.path.append("../")
#from floatcanvas import NavCanvas, FloatCanvas
FC = FloatCanvas
def BB_HitTest(self, event, HitEvent):
""" Hit Test Function for BoundingBox Based HitMap System"""
if self.HitDict and self.HitDict[HitEvent]:
# loop though the objects associated with this event
objects = [] #Create object list for holding multiple objects
object_index_list = [] #Create list for holding the indexes
xy_p = event.GetPosition()
xy = self.PixelToWorld( xy_p ) #Convert to the correct coords
for key2 in self.HitDict[HitEvent]:
#Get Mouse Event Position
bb = self.HitDict[HitEvent][key2].BoundingBox
if bb.PointInside(xy):
Object = self.HitDict[HitEvent][key2]
objects.append(Object)
try:
#First try the foreground index and add the length of the background index
#to account for the two 'layers' that already exist in the code
index = self._ForeDrawList.index(Object) + len(self._DrawList)
except ValueError:
index = self._DrawList.index(Object) #Now check background if not found in foreground
object_index_list.append(index) #append the index found
else:
Object = self.HitDict[HitEvent][key2]
if len(objects) > 0: #If no objects then do nothing
#Get the highest index object
highest_object = objects[object_index_list.index(max(object_index_list))]
highest_object.HitCoords = xy
highest_object.HitCoordsPixel = xy_p
highest_object.CallBackFuncs[HitEvent](highest_object)
return True
else:
return False
return False
FC.FloatCanvas.HitTest = BB_HitTest
class DrawFrame(wx.Frame):
"""
A frame used for the FloatCanvas Demo
"""
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.CreateStatusBar()
# Add the Canvas
Canvas = NavCanvas.NavCanvas(self,-1,
size = (500,500),
ProjectionFun = None,
Debug = 0,
BackgroundColor = "DARK SLATE BLUE",
).Canvas
self.Canvas = Canvas
self.Canvas.Bind(FloatCanvas.EVT_MOTION, self.OnMove)
Point = (45,40)
Text = Canvas.AddScaledText("A String",
Point,
20,
Color = "Black",
BackgroundColor = None,
Family = wx.ROMAN,
Style = wx.NORMAL,
Weight = wx.NORMAL,
Underlined = False,
Position = 'bl',
InForeground = False)
Text.MinFontSize = 4 # the default is 1
Text.DisappearWhenSmall = False #the default is True
Rect1 = Canvas.AddRectangle((50, 20), (40,15), FillColor="Red", LineStyle = None)
Rect1.Bind(FC.EVT_FC_LEFT_DOWN, self.OnLeft)
Rect1.Name = "red"
Rect2 = Canvas.AddRectangle((70, 30), (40,15), FillColor="Blue", LineStyle = None)
Rect2.Bind(FC.EVT_FC_LEFT_DOWN, self.OnLeft)
Rect2.Name = 'blue'
self.Show()
Canvas.ZoomToBB()
def OnLeft(self, object):
print("Rect %s got hit"%object.Name)
def OnMove(self, event):
"""
Updates the status bar with the world coordinates
"""
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
app = wx.App(False)
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
app.MainLoop()