diff --git a/wx/lib/floatcanvas/FCObjects.py b/wx/lib/floatcanvas/FCObjects.py index f1095309..d0a3affa 100644 --- a/wx/lib/floatcanvas/FCObjects.py +++ b/wx/lib/floatcanvas/FCObjects.py @@ -650,7 +650,8 @@ class PointsObjectMixin: class Polygon(PointsObjectMixin, LineAndFillMixin, DrawObject): - """Draws a polygon + """ + Draws a polygon Points is a list of 2-tuples, or a NX2 NumPy array of point coordinates. so that Points[N][0] is the x-coordinate of @@ -667,7 +668,8 @@ class Polygon(PointsObjectMixin, LineAndFillMixin, DrawObject): FillColor = None, FillStyle = "Solid", InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `Points`: start point, takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -705,7 +707,8 @@ class Polygon(PointsObjectMixin, LineAndFillMixin, DrawObject): HTdc.DrawPolygon(Points) class Line(PointsObjectMixin, LineOnlyMixin, DrawObject): - """Draws a line + """ + Draws a line It will draw a straight line if there are two points, and a polyline if there are more than two. @@ -716,7 +719,8 @@ class Line(PointsObjectMixin, LineOnlyMixin, DrawObject): LineStyle = "Solid", LineWidth = 1, InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `Points`: takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -752,7 +756,8 @@ class Line(PointsObjectMixin, LineOnlyMixin, DrawObject): class Spline(Line): """Draws a spline""" def __init__(self, *args, **kwargs): - """Default class constructor. + """ + Default class constructor. see :class:`~lib.floatcanvas.FloatCanvas.Line` @@ -769,7 +774,8 @@ class Spline(Line): class Arrow(XYObjectMixin, LineOnlyMixin, DrawObject): - """Draws an arrow + """ + Draws an arrow It will draw an arrow , starting at the point ``XY`` points at an angle defined by ``Direction``. @@ -785,7 +791,8 @@ class Arrow(XYObjectMixin, LineOnlyMixin, DrawObject): ArrowHeadSize = 8, ArrowHeadAngle = 30, InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `XY`: the (x, y) coordinate of the starting point, or a 2-tuple, or a (2,) `NumPy `_ array @@ -823,7 +830,8 @@ class Arrow(XYObjectMixin, LineOnlyMixin, DrawObject): self.HitLineWidth = max(LineWidth,self.MinHitLineWidth) def SetDirection(self, Direction): - """Set the direction + """ + Set the direction :param integer `Direction`: angle of arrow in degrees, zero is straight up `+` angle is to the right @@ -833,7 +841,8 @@ class Arrow(XYObjectMixin, LineOnlyMixin, DrawObject): self.CalcArrowPoints() def SetLength(self, Length): - """Set the length + """ + Set the length :param integer `Length`: length of arrow in pixels @@ -842,7 +851,8 @@ class Arrow(XYObjectMixin, LineOnlyMixin, DrawObject): self.CalcArrowPoints() def SetLengthDirection(self, Length, Direction): - """Set the lenght and direction + """ + Set the lenght and direction :param integer `Length`: length of arrow in pixels :param integer `Direction`: angle of arrow in degrees, zero is straight @@ -896,7 +906,8 @@ class Arrow(XYObjectMixin, LineOnlyMixin, DrawObject): class ArrowLine(PointsObjectMixin, LineOnlyMixin, DrawObject): - """Draws an arrow line. + """ + Draws an arrow line. It will draw a set of arrows from point to point. @@ -912,7 +923,8 @@ class ArrowLine(PointsObjectMixin, LineOnlyMixin, DrawObject): ArrowHeadSize = 8, ArrowHeadAngle = 30, InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `Points`: takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -977,7 +989,8 @@ class ArrowLine(PointsObjectMixin, LineOnlyMixin, DrawObject): class PointSet(PointsObjectMixin, ColorOnlyMixin, DrawObject): - """Draws a set of points + """ + Draws a set of points If Points is a sequence of tuples: Points[N][0] is the x-coordinate of point N and Points[N][1] is the y-coordinate. @@ -996,7 +1009,8 @@ class PointSet(PointsObjectMixin, ColorOnlyMixin, DrawObject): """ def __init__(self, Points, Color="Black", Diameter=1, InForeground=False): - """Default class constructor. + """ + Default class constructor. :param `Points`: takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -1016,7 +1030,8 @@ class PointSet(PointsObjectMixin, ColorOnlyMixin, DrawObject): self.SetColor(Color) def SetDiameter(self, Diameter): - """Sets the diameter + """ + Sets the diameter :param integer `Diameter`: the points diameter @@ -1025,7 +1040,6 @@ class PointSet(PointsObjectMixin, ColorOnlyMixin, DrawObject): def FindClosestPoint(self, XY): """ - Returns the index of the closest point to the point, XY, given in World coordinates. It's essentially random which you get if there are more than one that are the same. @@ -1084,7 +1098,8 @@ class PointSet(PointsObjectMixin, ColorOnlyMixin, DrawObject): HTdc.DrawCircle(xy[0],xy[1], radius) class Point(XYObjectMixin, ColorOnlyMixin, DrawObject): - """A point DrawObject + """ + A point DrawObject .. note:: @@ -1094,7 +1109,8 @@ class Point(XYObjectMixin, ColorOnlyMixin, DrawObject): """ def __init__(self, XY, Color="Black", Diameter=1, InForeground=False): - """Default class constructor. + """ + Default class constructor. :param `XY`: the (x, y) coordinate of the center of the point, or a 2-tuple, or a (2,) `NumPy `_ array @@ -1115,7 +1131,8 @@ class Point(XYObjectMixin, ColorOnlyMixin, DrawObject): self.HitLineWidth = self.MinHitLineWidth def SetDiameter(self, Diameter): - """Set the diameter of the object. + """ + Set the diameter of the object. :param integer `Diameter`: in screen points @@ -1140,7 +1157,8 @@ class Point(XYObjectMixin, ColorOnlyMixin, DrawObject): HTdc.DrawCircle(xy[0],xy[1], radius) class SquarePoint(XYObjectMixin, ColorOnlyMixin, DrawObject): - """Draws a square point + """ + Draws a square point The Size is in screen points, not world coordinates, so the Bounding box is just the point, and doesn't include the Size. @@ -1149,7 +1167,8 @@ class SquarePoint(XYObjectMixin, ColorOnlyMixin, DrawObject): """ def __init__(self, Point, Color="Black", Size=4, InForeground=False): - """Default class constructor. + """ + Default class constructor. :param `Point`: takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -1169,7 +1188,8 @@ class SquarePoint(XYObjectMixin, ColorOnlyMixin, DrawObject): self.HitLineWidth = self.MinHitLineWidth def SetSize(self, Size): - """Sets the size + """ + Sets the size :param integer `Size`: the size of the square point @@ -1205,7 +1225,8 @@ class RectEllipse(XYObjectMixin, LineAndFillMixin, DrawObject): FillColor = None, FillStyle = "Solid", InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `XY`: the (x, y) coordinate of the corner of RectEllipse, or a 2-tuple, or a (2,) `NumPy `_ array @@ -1238,7 +1259,8 @@ class RectEllipse(XYObjectMixin, LineAndFillMixin, DrawObject): self.SetBrush(FillColor,FillStyle) def SetShape(self, XY, WH): - """Set the shape of the object. + """ + Set the shape of the object. :param `XY`: takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -1296,7 +1318,8 @@ class Circle(XYObjectMixin, LineAndFillMixin, DrawObject): FillColor = None, FillStyle = "Solid", InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `XY`: the (x, y) coordinate of the center of the circle, or a 2-tuple, or a (2,) `NumPy `_ array @@ -1331,7 +1354,8 @@ class Circle(XYObjectMixin, LineAndFillMixin, DrawObject): self.SetBrush(FillColor,FillStyle) def SetDiameter(self, Diameter): - """Set the diameter of the object + """ + Set the diameter of the object :param integer `Diameter`: the diameter for the object @@ -1360,7 +1384,6 @@ class Circle(XYObjectMixin, LineAndFillMixin, DrawObject): class TextObjectMixin(XYObjectMixin): """ - A mix in class that holds attributes and methods that are needed by the Text objects @@ -1433,7 +1456,8 @@ class TextObjectMixin(XYObjectMixin): 'br': lambda x, y, w, h, world=0, pad=0: (x - w - pad, y - h + 2*world*h - pad + world*2*pad)} class Text(TextObjectMixin, DrawObject): - """Draws a text object + """ + Draws a text object The size is fixed, and does not scale with the drawing. @@ -1452,7 +1476,8 @@ class Text(TextObjectMixin, DrawObject): Position = 'tl', InForeground = False, Font = None): - """Default class constructor. + """ + Default class constructor. :param string `string`: the text to draw :param `XY`: the (x, y) coordinate of the corner of the text, or a 2-tuple, @@ -1702,7 +1727,8 @@ class ScaledText(TextObjectMixin, DrawObject): HTdc.DrawRectangle(xy, (w, h)) class ScaledTextBox(TextObjectMixin, DrawObject): - """Draws a text object + """ + Draws a text object The object is scaled when zoomed. @@ -1743,7 +1769,8 @@ class ScaledTextBox(TextObjectMixin, DrawObject): Font = None, LineSpacing = 1.0, InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `Point`: takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -1879,7 +1906,6 @@ class ScaledTextBox(TextObjectMixin, DrawObject): def LayoutText(self): """ - Calculates the positions of the words of text. This isn't exact, as fonts don't scale exactly. @@ -1952,13 +1978,7 @@ class ScaledTextBox(TextObjectMixin, DrawObject): self.CalcBoundingBox() def CalcBoundingBox(self): - - """ - - Calculates the Bounding Box - - """ - + """Calculates the Bounding Box""" w, h = self.BoxWidth, self.BoxHeight x, y = self.ShiftFun(self.XY[0], self.XY[1], w, h, world=1) self.BoundingBox = BBox.asBBox(((x, y-h ),(x + w, y))) @@ -2007,7 +2027,8 @@ class ScaledTextBox(TextObjectMixin, DrawObject): HTdc.DrawRectangle(xy, wh) class Bitmap(TextObjectMixin, DrawObject): - """Draws a bitmap + """ + Draws a bitmap The size is fixed, and does not scale with the drawing. @@ -2016,7 +2037,8 @@ class Bitmap(TextObjectMixin, DrawObject): def __init__(self, Bitmap, XY, Position='tl', InForeground=False): - """Default class constructor. + """ + Default class constructor. :param Bitmap `Bitmap`: the bitmap to be drawn :param `XY`: the (x, y) coordinate of the corner of the bitmap, or a 2-tuple, @@ -2069,7 +2091,8 @@ class Bitmap(TextObjectMixin, DrawObject): HTdc.DrawRectangle(XY, (self.Width, self.Height) ) class ScaledBitmap(TextObjectMixin, DrawObject): - """Draws a scaled bitmap + """ + Draws a scaled bitmap The size scales with the drawing @@ -2081,7 +2104,8 @@ class ScaledBitmap(TextObjectMixin, DrawObject): Height, Position = 'tl', InForeground = False): - """Default class constructor. + """ + Default class constructor. :param wx.Bitmap `Bitmap`: the bitmap to be drawn :param `XY`: the (x, y) coordinate of the corner of the scaled bitmap, @@ -2151,7 +2175,8 @@ class ScaledBitmap(TextObjectMixin, DrawObject): HTdc.DrawRectangle(XY, (W, H) ) class ScaledBitmap2(TextObjectMixin, DrawObject, ): - """Draws a scaled bitmap + """ + Draws a scaled bitmap An alternative scaled bitmap that only scaled the required amount of the main bitmap when zoomed in: EXPERIMENTAL! @@ -2165,7 +2190,8 @@ class ScaledBitmap2(TextObjectMixin, DrawObject, ): Width=None, Position = 'tl', InForeground = False): - """Default class constructor. + """ + Default class constructor. :param wx.Bitmap `Bitmap`: the bitmap to be drawn :param `XY`: the (x, y) coordinate of the corner of the scaled bitmap, @@ -2317,7 +2343,7 @@ class ScaledBitmap2(TextObjectMixin, DrawObject, ): Hs = int(scale * Hb + 0.5) if (self.ScaledBitmap is None) or (self.ScaledBitmap[0] != (Xb, Yb, Wb, Hb, Ws, Ws) ): Img = self.Image.GetSubImage(wx.Rect(Xb, Yb, Wb, Hb)) - print("rescaling with High quality") + #print("rescaling with High quality") Img.Rescale(Ws, Hs, quality=wx.IMAGE_QUALITY_HIGH) bmp = wx.Bitmap(Img) self.ScaledBitmap = ((Xb, Yb, Wb, Hb, Ws, Ws), bmp)# this defines the cached bitmap @@ -2352,7 +2378,7 @@ class ScaledBitmap2(TextObjectMixin, DrawObject, ): class DotGrid: """ - An example of a Grid Object -- it is set on the FloatCanvas with one of: + An example of a Grid Object -- it is set on the FloatCanvas with one of:: FloatCanvas.GridUnder = Grid FloatCanvas.GridOver = Grid @@ -2429,7 +2455,8 @@ class DotGrid: dc.DrawCircle(xy[0],xy[1], radius) class Arc(XYObjectMixin, LineAndFillMixin, DrawObject): - """Draws an arc of a circle, centered on point ``CenterXY``, from + """ + Draws an arc of a circle, centered on point ``CenterXY``, from the first point ``StartXY`` to the second ``EndXY``. The arc is drawn in an anticlockwise direction from the start point to @@ -2446,7 +2473,8 @@ class Arc(XYObjectMixin, LineAndFillMixin, DrawObject): FillColor = None, FillStyle = "Solid", InForeground = False): - """Default class constructor. + """ + Default class constructor. :param `StartXY`: start point, takes a 2-tuple, or a (2,) `NumPy `_ array of point coordinates @@ -2499,7 +2527,8 @@ class Arc(XYObjectMixin, LineAndFillMixin, DrawObject): self.SetBrush(FillColor, FillStyle) #Why isn't this working ??? def Move(self, Delta): - """Move the object by delta + """ + Move the object by delta :param `Delta`: delta is a (dx, dy) pair. Ideally a `NumPy `_ array of shape (2,) @@ -2541,26 +2570,8 @@ class PieChart(XYObjectMixin, LineOnlyMixin, DrawObject): You can pass in a bunch of values, and it will draw a pie chart for you, and it will make the chart, scaling the size of each "slice" to match your values. - - The parameters are: - - XY : The (x,y) coords of the center of the chart - Diameter : The diamter of the chart in worls coords, unless you set - "Scaled" to False, in which case it's in pixel coords. - Values : sequence of values you want to make the chart of. - FillColors=None : sequence of colors you want the slices. If - None, it will choose (no guarantee youll like them!) - FillStyles=None : Fill style you want ("Solid", "Hash", etc) - LineColor = None : Color of lines separating the slices - LineStyle = "Solid" : style of lines separating the slices - LineWidth = 1 : With of lines separating the slices - Scaled = True : Do you want the pie to scale when zooming? or stay the same size in pixels? - InForeground = False: Should it be on the foreground? - - """ - ##fixme: this should be a longer and better designed set. ## Maybe one from: http://geography.uoregon.edu/datagraphics/color_scales.htm DefaultColorList = Colors.CategoricalColor1 @@ -2577,6 +2588,23 @@ class PieChart(XYObjectMixin, LineOnlyMixin, DrawObject): LineWidth = 1, Scaled = True, InForeground = False): + """ + Default class constructor. + + :param `XY`: The (x,y) coords of the center of the chart + :param `Diameter`: The diamter of the chart in worls coords, unless you + set "Scaled" to False, in which case it's in pixel coords. + :param `Values`: sequence of values you want to make the chart of. + :param `FillColors`: sequence of colors you want the slices. If + None, it will choose (no guarantee you'll like them!) + :param `FillStyles`: Fill style you want ("Solid", "Hash", etc) + :param `LineColor`: Color of lines separating the slices + :param `LineStyle`: style of lines separating the slices + :param `LineWidth`: With of lines separating the slices + :param `Scaled`: Do you want the pie to scale when zooming? + or stay the same size in pixels? + :param `InForeground`: Should it be on the foreground? + """ DrawObject.__init__(self, InForeground) self.XY = N.asarray(XY, N.float).reshape( (2,) ) @@ -2599,25 +2627,42 @@ class PieChart(XYObjectMixin, LineOnlyMixin, DrawObject): self.CalculatePoints() def SetFillColors(self, FillColors): + """ + Set the FillColors and update the Brushes. + + :param `FillColors`: sequence of colors + """ self.FillColors = FillColors self.SetBrushes() def SetFillStyles(self, FillStyles): + """ + Set te FillStyles and update the Brushes. + + :param `FillStyles`: Fill style you want ("Solid", "Hash", etc) + """ self.FillStyles = FillStyles self.SetBrushed() def SetValues(self, Values): + """ + Set the values and calculate the points. + + :param `Values`: sequence of values you want to use for the chart + """ Values = N.asarray(Values, dtype=N.float).reshape((-1,1)) self.Values = Values self.CalculatePoints() def CalculatePoints(self): + """Calculate the points.""" # add the zero point to start Values = N.vstack( ( (0,), self.Values) ) self.Angles = 360. * Values.cumsum()/Values.sum() self.CalcBoundingBox() def SetBrushes(self): + """Set the Brushes.""" self.Brushes = [] for FillColor, FillStyle in zip(self.FillColors, self.FillStyles): if FillColor is None or FillStyle is None: @@ -2628,6 +2673,7 @@ class PieChart(XYObjectMixin, LineOnlyMixin, DrawObject): ) ) def CalcBoundingBox(self): + """Calculate the bounding box.""" if self.Scaled: self.BoundingBox = BBox.asBBox( ((self.XY-self.Diameter),(self.XY+self.Diameter)) ) else: diff --git a/wx/lib/floatcanvas/FloatCanvas.py b/wx/lib/floatcanvas/FloatCanvas.py index a698df66..66c87129 100644 --- a/wx/lib/floatcanvas/FloatCanvas.py +++ b/wx/lib/floatcanvas/FloatCanvas.py @@ -80,7 +80,7 @@ class _MouseEvent(wx.PyCommandEvent): It adds the method: - GetCoords() , which returns and (x,y) tuple in world coordinates. + GetCoords() , which returns an (x,y) tuple in world coordinates. Another difference is that it is a CommandEvent, which propagates up the window hierarchy until it is handled. @@ -988,7 +988,8 @@ class FloatCanvas(wx.Panel): self.Draw() def RemoveObjects(self, Objects): - """"Remove objects from canvas + """" + Remove objects from canvas :param list `Objects`: a list of :class:`DrawObjects` to remove @@ -998,7 +999,8 @@ class FloatCanvas(wx.Panel): self.BoundingBoxDirty = True def RemoveObject(self, Object, ResetBB=True): - """"Remove object from canvas + """" + Remove object from canvas :param DrawObject `Object`: a :class:`DrawObjects` to remove :param boolean `ResetBB`: reset the bounding box diff --git a/wx/lib/floatcanvas/Utilities/BBox.py b/wx/lib/floatcanvas/Utilities/BBox.py index ea953a92..ec6a06fa 100755 --- a/wx/lib/floatcanvas/Utilities/BBox.py +++ b/wx/lib/floatcanvas/Utilities/BBox.py @@ -23,10 +23,12 @@ 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: + 2x2 numpy array of floats:: - [[MinX, MinY ], - [MaxX, MaxY ]] + [ + [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. @@ -42,13 +44,16 @@ class BBox(N.ndarray): """ 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: + 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 ]] + [ + [MinX, MinY ], + [MaxX, MaxY ] + ] - You don't usually call this directly. BBox objects are created with the factory functions: + You don't usually call this directly. BBox objects are created with + the factory functions: asBBox @@ -197,10 +202,12 @@ def asBBox(data): If object is a numpy array, a BBox object is returned that shares a view of the data with that array. The numpy array should be of the correct - format: a 2x2 numpy array of floats: + format: a 2x2 numpy array of floats:: - [[MinX, MinY ], - [MaxX, MaxY ]] + [ + [MinX, MinY ], + [MaxX, MaxY ] + ] """ @@ -225,22 +232,22 @@ def fromPoints(Points): 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 + """ + 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 def NullBBox(): """ @@ -290,9 +297,6 @@ class RectBBox(BBox): BBox.BBox(data) self.edges = np.asarray(edges) - print("new rectbbox created") - - def ac_leftOf_ab(self, a, b, c): ab = np.array(b) - np.array(a) ac = np.array(c) - np.array(a) @@ -300,8 +304,6 @@ class RectBBox(BBox): return (ac[0]*ab[1] - ac[1]*ab[0]) <= 0 def PointInside(self, point): - print("point inside called") - for edge in xrange(4): if self.ac_leftOf_ab(self.edges[edge], self.edges[(edge+1)%4], @@ -310,4 +312,3 @@ class RectBBox(BBox): else: return False return True - diff --git a/wx/lib/floatcanvas/Utilities/GUI.py b/wx/lib/floatcanvas/Utilities/GUI.py index 44df6c4d..263458b0 100644 --- a/wx/lib/floatcanvas/Utilities/GUI.py +++ b/wx/lib/floatcanvas/Utilities/GUI.py @@ -38,23 +38,14 @@ class RubberBandBox(GUIMode.GUIBase): def __init__(self, CallBack, Tol=5): """ - To initialize: - - RubberBandBox(CallBack, Tol=5) + Default class constructor. - CallBack: is the method you want called when the mouse is + :param `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 - - - Attributes: - - CallBack: The callback function. - + :param `Tol`: The tolerance for the smallest rectangle allowed. defaults + to 5. In pixels """ self.Canvas = None # this will be set when the mode is set on a Canvas