""" 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