#!/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()