⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floatcanvas.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 5 页
字号:
        if self._Canvas and (not self.InForeground):
            self._Canvas._ForeDrawList.append(self)
            self._Canvas._DrawList.remove(self)
            self._Canvas._BackgroundDirty = True
            self.InForeground = True

    def Hide(self):
        self.Visible = False

    def Show(self):
        self.Visible = True

class ColorOnlyMixin:
    """

    Mixin class for objects that have just one color, rather than a fill
    color and line color

    """

    def SetColor(self, Color):
        self.SetPen(Color,"Solid",1)
        self.SetBrush(Color,"Solid")

    SetFillColor = SetColor # Just to provide a consistant interface 

class LineOnlyMixin:
    """

    Mixin class for objects that have just one color, rather than a fill
    color and line color

    """

    def SetLineColor(self, LineColor):
        self.LineColor = LineColor
        self.SetPen(LineColor,self.LineStyle,self.LineWidth)

    def SetLineStyle(self, LineStyle):
        self.LineStyle = LineStyle
        self.SetPen(self.LineColor,LineStyle,self.LineWidth)

    def SetLineWidth(self, LineWidth):
        self.LineWidth = LineWidth
        self.SetPen(self.LineColor,self.LineStyle,LineWidth)

class LineAndFillMixin(LineOnlyMixin):
    """

    Mixin class for objects that have both a line and a fill color and
    style.

    """
    def SetFillColor(self, FillColor):
        self.FillColor = FillColor
        self.SetBrush(FillColor, self.FillStyle)

    def SetFillStyle(self, FillStyle):
        self.FillStyle = FillStyle
        self.SetBrush(self.FillColor,FillStyle)
    
class XYObjectMixin:
    """

    This is a mixin class that provides some methods suitable for use
    with objects that have a single (x,y) coordinate pair.

    """

    def Move(self, Delta ):
        """

        Move(Delta): moves the object by delta, where delta is a
        (dx,dy) pair. Ideally a Numpy array of shape (2,)

        """
        
        Delta = asarray(Delta, Float)
        self.XY += Delta
        self.BoundingBox = self.BoundingBox + Delta
        
        if self._Canvas:
            self._Canvas.BoundingBoxDirty = True      

    def CalcBoundingBox(self):
        ## This may get overwritten in some subclasses
        self.BoundingBox = array( (self.XY, self.XY), Float )

    def SetPoint(self, xy):
        xy = array( xy, Float)
        xy.shape = (2,)
        Delta = xy - self.XY
        
        self.XY = xy
        self.BoundingBox = self.BoundingBox + Delta

        #self.CalcBoundingBox()
        if self._Canvas:
            self._Canvas.BoundingBoxDirty = True     

class PointsObjectMixin:
    """

    This is a mixin class that provides some methods suitable for use
    with objects that have a set of (x,y) coordinate pairs.

    """


## This is code for the PointsObjectMixin object, it needs to be adapted and tested.
## Is the neccesary at all: you can always do:
##    Object.SetPoints( Object.Points + delta, copy = False)    
##    def Move(self, Delta ):
##        """

##        Move(Delta): moves the object by delta, where delta is an (dx,
##        dy) pair. Ideally a Numpy array of shape (2,)

##        """
        
##        Delta = array(Delta, Float)
##        self.XY += Delta
##        self.BoundingBox = self.BoundingBox + Delta##array((self.XY, (self.XY + self.WH)), Float)
##        if self._Canvas:
##            self._Canvas.BoundingBoxDirty = True      

    def CalcBoundingBox(self):
        self.BoundingBox = array(((min(self.Points[:,0]),
                                   min(self.Points[:,1]) ),
                                  (max(self.Points[:,0]),
                                   max(self.Points[:,1]) ) ), Float )
        if self._Canvas:
            self._Canvas.BoundingBoxDirty = True

    def SetPoints(self, Points, copy = True):
        """
        Sets the coordinates of the points of the object to Points (NX2 array).

        By default, a copy is made, if copy is set to False, a reference
        is used, iff Points is a NumPy array of Floats. This allows you
        to change some or all of the points without making any copies.

        For example:

        Points = Object.Points
        Points += (5,10) # shifts the points 5 in the x dir, and 10 in the y dir.
        Object.SetPoints(Points, False) # Sets the points to the same array as it was
        
        """
        if copy:
            self.Points = array(Points, Float)
            self.Points.shape = (-1,2) # Make sure it is a NX2 array, even if there is only one point
        else:
            self.Points = asarray(Points, Float)
        self.CalcBoundingBox()

     
class Polygon(DrawObject,PointsObjectMixin,LineAndFillMixin):

    """

    The Polygon class takes a list of 2-tuples, or a NX2 NumPy array of
    point coordinates.  so that Points[N][0] is the x-coordinate of
    point N and Points[N][1] is the y-coordinate or Points[N,0] is the
    x-coordinate of point N and Points[N,1] is the y-coordinate for
    arrays.

    The other parameters specify various properties of the Polygon, and
    should be self explanatory.

    """
    def __init__(self,
                 Points,
                 LineColor = "Black",
                 LineStyle = "Solid",
                 LineWidth    = 1,
                 FillColor    = None,
                 FillStyle    = "Solid",
                 InForeground = False):
        DrawObject.__init__(self,InForeground)
        self.Points = array(Points,Float) # this DOES need to make a copy
        self.CalcBoundingBox()

        self.LineColor = LineColor
        self.LineStyle = LineStyle
        self.LineWidth = LineWidth
        self.FillColor = FillColor
        self.FillStyle = FillStyle

        self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)

        self.SetPen(LineColor,LineStyle,LineWidth)
        self.SetBrush(FillColor,FillStyle)

    def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel = None, HTdc=None):
        Points = WorldToPixel(self.Points)#.tolist()
        dc.SetPen(self.Pen)
        dc.SetBrush(self.Brush)
        dc.DrawPolygon(Points)
        if HTdc and self.HitAble:
            HTdc.SetPen(self.HitPen)
            HTdc.SetBrush(self.HitBrush)
            HTdc.DrawPolygon(Points)
            
##class PolygonSet(DrawObject):
##    """
##    The PolygonSet class takes a Geometry.Polygon object.
##    so that Points[N] = (x1,y1) and Points[N+1] = (x2,y2). N must be an even number!
    
##    it creates a set of line segments, from (x1,y1) to (x2,y2)
    
##    """
    
##    def __init__(self,PolySet,LineColors,LineStyles,LineWidths,FillColors,FillStyles,InForeground = False):
##        DrawObject.__init__(self, InForeground)

##        ##fixme: there should be some error checking for everything being the right length.

        
##        self.Points = array(Points,Float)
##        self.BoundingBox = array(((min(self.Points[:,0]),min(self.Points[:,1])),(max(self.Points[:,0]),max(self.Points[:,1]))),Float)

##        self.LineColors = LineColors
##        self.LineStyles = LineStyles
##        self.LineWidths = LineWidths
##        self.FillColors = FillColors
##        self.FillStyles = FillStyles

##        self.SetPens(LineColors,LineStyles,LineWidths)

##    #def _Draw(self,dc,WorldToPixel,ScaleWorldToPixel):
##    def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
##        Points = WorldToPixel(self.Points)
##        Points.shape = (-1,4)
##        dc.DrawLineList(Points,self.Pens)
 

class Line(DrawObject,PointsObjectMixin,LineOnlyMixin):
    """

    The Line class takes a list of 2-tuples, or a NX2 NumPy Float array
    of point coordinates.

    It will draw a straight line if there are two points, and a polyline
    if there are more than two.

    """
    def __init__(self,Points,
                 LineColor = "Black",
                 LineStyle = "Solid",
                 LineWidth    = 1,
                 InForeground = False):
        DrawObject.__init__(self, InForeground)


        self.Points = array(Points,Float)
        self.CalcBoundingBox()

        self.LineColor = LineColor
        self.LineStyle = LineStyle
        self.LineWidth = LineWidth

        self.SetPen(LineColor,LineStyle,LineWidth)

        self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)

            
    def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
        Points = WorldToPixel(self.Points)
        dc.SetPen(self.Pen)
        dc.DrawLines(Points)
        if HTdc and self.HitAble:
            HTdc.SetPen(self.HitPen)
            HTdc.DrawLines(Points)

class Arrow(DrawObject,XYObjectMixin,LineOnlyMixin):
    """

    Arrow(XY, # coords of origin of arrow (x,y)
          Length, # length of arrow in pixels
          theta, # angle of arrow in degrees: zero is straight up
                 # angle is to the right
          LineColor = "Black",
          LineStyle = "Solid",
          LineWidth    = 1, 
          ArrowHeadSize = 4,
          ArrowHeadAngle = 45,
          InForeground = False):

    It will draw an arrow , starting at the point, (X,Y) pointing in
    direction, theta.


    """
    def __init__(self,
                 XY,
                 Length,
                 Direction,
                 LineColor = "Black",
                 LineStyle = "Solid",
                 LineWidth    = 2, # pixels
                 ArrowHeadSize = 8, # pixels
                 ArrowHeadAngle = 30, # degrees
                 InForeground = False):

        DrawObject.__init__(self, InForeground)

        self.XY = array(XY, Float)
        self.XY.shape = (2,) # Make sure it is a 1X2 array, even if there is only one point
        self.Length = Length
        self.Direction = float(Direction)
        self.ArrowHeadSize = ArrowHeadSize 
        self.ArrowHeadAngle = float(ArrowHeadAngle)        

        self.CalcArrowPoints()
        self.CalcBoundingBox()

        self.LineColor = LineColor
        self.LineStyle = LineStyle
        self.LineWidth = LineWidth

        self.SetPen(LineColor,LineStyle,LineWidth)

        ##fixme: How should the HitTest be drawn?
        self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)

    def SetDirection(self, Direction):
        self.Direction = float(Direction)
        self.CalcArrowPoints()
        
    def SetLength(self, Length):
        self.Length = Length
        self.CalcArrowPoints()

    def SetLengthDirection(self, Length, Direction):
        self.Direction = float(Direction)
        self.Length = Length
        self.CalcArrowPoints()
        
    def SetLength(self, Length):
        self.Length = Length
        self.CalcArrowPoints()

    ## fixme: cache this?
    def CalcArrowPoints(self):
        L = self.Length
        S = self.ArrowHeadSize
        phi = self.ArrowHeadAngle * pi / 360
        theta = (self.Direction-90.0) * pi / 180
        ArrowPoints = array( ( (0, L, L - S*cos(phi),L, L - S*cos(phi) ),
                               (0, 0, S*sin(phi),    0, -S*sin(phi)    ) ),
                             Float )
        RotationMatrix = array( ( ( cos(theta), -sin(theta) ),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -