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

📄 _lines.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 4 页
字号:
                    arrow.GetMetaFile().Draw(dc, x + deltaX, y + deltaY)

    def OnErase(self, dc):
        old_pen = self._pen
        old_brush = self._brush

        bg_pen = self.GetBackgroundPen()
        bg_brush = self.GetBackgroundBrush()
        self.SetPen(bg_pen)
        self.SetBrush(bg_brush)

        bound_x, bound_y = self.GetBoundingBoxMax()
        if self._font:
            dc.SetFont(self._font)

        # Undraw text regions
        for i in range(3):
            if self._regions[i]:
                x, y = self.GetLabelPosition(i)
                self.EraseRegion(dc, self._regions[i], x, y)

        # Undraw line
        dc.SetPen(self.GetBackgroundPen())
        dc.SetBrush(self.GetBackgroundBrush())

        # Drawing over the line only seems to work if the line has a thickness
        # of 1.
        if old_pen and old_pen.GetWidth() > 1:
            dc.DrawRectangle(self._xpos - bound_x / 2.0 - 2, self._ypos - bound_y / 2.0 - 2,
                             bound_x + 4, bound_y + 4)
        else:
            self._erasing = True
            self.GetEventHandler().OnDraw(dc)
            self.GetEventHandler().OnEraseControlPoints(dc)
            self._erasing = False

        if old_pen:
            self.SetPen(old_pen)
        if old_brush:
            self.SetBrush(old_brush)

    def GetBoundingBoxMin(self):
        x1, y1 = 10000, 10000
        x2, y2 = -10000, -10000

        for point in self._lineControlPoints:
            if point[0] < x1:
                x1 = point[0]
            if point[1] < y1:
                y1 = point[1]
            if point[0] > x2:
                x2 = point[0]
            if point[1] > y2:
                y2 = point[1]

        return x2 - x1, y2 - y1
        
    # For a node image of interest, finds the position of this arc
    # amongst all the arcs which are attached to THIS SIDE of the node image,
    # and the number of same.
    def FindNth(self, image, incoming):
        """Find the position of the line on the given object.

        Specify whether incoming or outgoing lines are being considered
        with incoming.
        """
        n = -1
        num = 0
        
        if image == self._to:
            this_attachment = self._attachmentTo
        else:
            this_attachment = self._attachmentFrom

        # Find number of lines going into / out of this particular attachment point
        for line in image.GetLines():
            if line._from == image:
                # This is the nth line attached to 'image'
                if line == self and not incoming:
                    n = num

                # Increment num count if this is the same side (attachment number)
                if line._attachmentFrom == this_attachment:
                    num += 1

            if line._to == image:
                # This is the nth line attached to 'image'
                if line == self and incoming:
                    n = num

                # Increment num count if this is the same side (attachment number)
                if line._attachmentTo == this_attachment:
                    num += 1

        return n, num

    def OnDrawOutline(self, dc, x, y, w, h):
        old_pen = self._pen
        old_brush = self._brush

        dottedPen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.DOT)
        self.SetPen(dottedPen)
        self.SetBrush(wx.TRANSPARENT_BRUSH)

        self.GetEventHandler().OnDraw(dc)

        if old_pen:
            self.SetPen(old_pen)
        else:
            self.SetPen(None)
        if old_brush:
            self.SetBrush(old_brush)
        else:
            self.SetBrush(None)

    def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
        x_offset = x - old_x
        y_offset = y - old_y

        if self._lineControlPoints and not (x_offset == 0 and y_offset == 0):
            for point in self._lineControlPoints:
                point[0] += x_offset
                point[1] += y_offset

        # Move temporary label rectangles if necessary
        for i in range(3):
            if self._labelObjects[i]:
                self._labelObjects[i].Erase(dc)
                xp, yp = self.GetLabelPosition(i)
                if i < len(self._regions):
                    xr, yr = self._regions[i].GetPosition()
                else:
                    xr, yr = 0, 0
                self._labelObjects[i].Move(dc, xp + xr, yp + yr)
        return True

    def OnMoveLink(self, dc, moveControlPoints = True):
        """Called when a connected object has moved, to move the link to
        correct position
        """
        if not self._from or not self._to:
            return

        # Do each end - nothing in the middle. User has to move other points
        # manually if necessary
        end_x, end_y, other_end_x, other_end_y = self.FindLineEndPoints()

        oldX, oldY = self._xpos, self._ypos

        # pi: The first time we go through FindLineEndPoints we can't
        # use the middle points (since they don't have sane values),
        # so we just do what we do for a normal line. Then we call
        # Initialise to set the middle points, and then FindLineEndPoints
        # again, but this time (and from now on) we use the middle
        # points to calculate the end points.
        # This was buggy in the C++ version too.
        
        self.SetEnds(end_x, end_y, other_end_x, other_end_y)

        if len(self._lineControlPoints) > 2:
            self.Initialise()

        # Do a second time, because one may depend on the other
        end_x, end_y, other_end_x, other_end_y = self.FindLineEndPoints()
        self.SetEnds(end_x, end_y, other_end_x, other_end_y)

        # Try to move control points with the arc
        x_offset = self._xpos - oldX
        y_offset = self._ypos - oldY

        # Only move control points if it's a self link. And only works
        # if attachment mode is ON
        if self._from == self._to and self._from.GetAttachmentMode() != ATTACHMENT_MODE_NONE and moveControlPoints and self._lineControlPoints and not (x_offset == 0 and y_offset == 0):
            for point in self._lineControlPoints[1:-1]:
                point[0] += x_offset
                point[1] += y_offset

        self.Move(dc, self._xpos, self._ypos)

    def FindLineEndPoints(self):
        """Finds the x, y points at the two ends of the line.

        This function can be used by e.g. line-routing routines to
        get the actual points on the two node images where the lines will be
        drawn to / from.
        """
        if not self._from or not self._to:
            return

        # Do each end - nothing in the middle. User has to move other points
        # manually if necessary.
        second_point = self._lineControlPoints[1]
        second_last_point = self._lineControlPoints[-2]

        # pi: If we have a segmented line and this is the first time,
        # do this as a straight line.
        if len(self._lineControlPoints) > 2 and self._initialised:
            if self._from.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
                nth, no_arcs = self.FindNth(self._from, False) # Not incoming
                end_x, end_y = self._from.GetAttachmentPosition(self._attachmentFrom, nth, no_arcs, self)
            else:
                end_x, end_y = self._from.GetPerimeterPoint(self._from.GetX(), self._from.GetY(), second_point[0], second_point[1])

            if self._to.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
                nth, no_arch = self.FindNth(self._to, True) # Incoming
                other_end_x, other_end_y = self._to.GetAttachmentPosition(self._attachmentTo, nth, no_arch, self)
            else:
                other_end_x, other_end_y = self._to.GetPerimeterPoint(self._to.GetX(), self._to.GetY(), second_last_point[0], second_last_point[1])
        else:
            fromX = self._from.GetX()
            fromY = self._from.GetY()
            toX = self._to.GetX()
            toY = self._to.GetY()

            if self._from.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
                nth, no_arcs = self.FindNth(self._from, False)
                end_x, end_y = self._from.GetAttachmentPosition(self._attachmentFrom, nth, no_arcs, self)
                fromX = end_x
                fromY = end_y

            if self._to.GetAttachmentMode() != ATTACHMENT_MODE_NONE:
                nth, no_arcs = self.FindNth(self._to, True)
                other_end_x, other_end_y = self._to.GetAttachmentPosition(self._attachmentTo, nth, no_arcs, self)
                toX = other_end_x
                toY = other_end_y

            if self._from.GetAttachmentMode() == ATTACHMENT_MODE_NONE:
                end_x, end_y = self._from.GetPerimeterPoint(self._from.GetX(), self._from.GetY(), toX, toY)

            if self._to.GetAttachmentMode() == ATTACHMENT_MODE_NONE:
                other_end_x, other_end_y = self._to.GetPerimeterPoint(self._to.GetX(), self._to.GetY(), fromX, fromY)

        return end_x, end_y, other_end_x, other_end_y


    def OnDraw(self, dc):
        if not self._lineControlPoints:
            return

        if self._pen:
            dc.SetPen(self._pen)
        if self._brush:
            dc.SetBrush(self._brush)

        points = []
        for point in self._lineControlPoints:
            points.append(wx.Point(point[0], point[1]))

        if self._isSpline:
            dc.DrawSpline(points)
        else:
            dc.DrawLines(points)

        if sys.platform[:3] == "win":
            # For some reason, last point isn't drawn under Windows
            pt = points[-1]
            dc.DrawPoint(pt[0], pt[1])

        # Problem with pen - if not a solid pen, does strange things
        # to the arrowhead. So make (get) a new pen that's solid.
        if self._pen and self._pen.GetStyle() != wx.SOLID:
            solid_pen = wx.Pen(self._pen.GetColour(), 1, wx.SOLID)
            if solid_pen:
                dc.SetPen(solid_pen)

        self.DrawArrows(dc)

    def OnDrawControlPoints(self, dc):
        if not self._drawHandles:
            return

        # Draw temporary label rectangles if necessary
        for i in range(3):
            if self._labelObjects[i]:
                self._labelObjects[i].Draw(dc)

        Shape.OnDrawControlPoints(self, dc)

    def OnEraseControlPoints(self, dc):
        # Erase temporary label rectangles if necessary
        
        for i in range(3):
            if self._labelObjects[i]:
                self._labelObjects[i].Erase(dc)

        Shape.OnEraseControlPoints(self, dc)

    def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
        pass

    def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
        pass

    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
        pass

    def OnDrawContents(self, dc):
        if self.GetDisableLabel():
            return

        for i in range(3):
            if self._regions[i]:
                x, y = self.GetLabelPosition(i)
                self.DrawRegion(dc, self._regions[i], x, y)

    def SetTo(self, object):
        """Set the 'to' object for the line."""
        self._to = object

    def SetFrom(self, object):
        """Set the 'from' object for the line."""
        self._from = object

    def MakeControlPoints(self):
        """Make handle control points."""
        if self._canvas and self._lineControlPoints:
            first = self._lineControlPoints[0]
            last = self._lineControlPoints[-1]

            control = LineControlPoint(self._canvas, self, CONTROL_POINT_SIZE, first[0], first[1], CONTROL_POINT_ENDPOINT_FROM)
            control._point = first
            self._canvas.AddShape(control)
            self._controlPoints.append(control)

            for point in self._lineControlPoints[1:-1]:
                control = LineControlPoint(self._canvas, self, CONTROL_POINT_SIZE, point[0], point[1], CONTROL_POINT_LINE)
                control._point = point
                self._canvas.AddShape(control)
                self._controlPoints.append(control)

            control = LineControlPoint(self._canvas, self, CONTROL_POINT_SIZE, last[0], last[1], CONTROL_POINT_ENDPOINT_TO)
            control._point = last
            self._canvas.AddShape(control)
            self._controlPoints.append(control)

    def ResetControlPoints(self):
        if self._canvas and self._lineControlPoints and self._controlPoints:
            for i in range(min(len(self._controlPoints), len(self._lineControlPoints))):
                point = self._lineControlPoints[i]
                control = self._controlPoints[i]
                control.SetX(point[0])
                control.SetY(point[1])

    # Override select, to create / delete temporary label-moving objects
    def Select(self, select, dc = None):
        Shape.Select(self, select, dc)
        if select:
            for i in range(3):
                if self._regions[i]:
                    region = self._regions[i]
                    if region._formattedText:
                        w, h = region.GetSize()
                        x, y = region.GetPosition()
                        xx, yy = self.GetLabelPosition(i)

                        if self._labelObjects[i]:
                            self._labelObjects[i].Select(False)
                            self._labelObjects[i].RemoveFromCanvas(self._canvas)

                        self._labelObjects[i] = self.OnCreateLabelShape(self, region, w, h)
                        self._labelObjects[i].AddToCanvas(self._canvas)
                        self._labelObjects[i].Show(True)
                        if dc:
                            self._labelObjects[i].Move(dc, x + xx, y + yy)
                        self._labelObjects[i].Select(True, dc)
        else:
            for i in range(3):
                if self._labelObjects[i]:
                    self._labelObjects[i].Select(False, dc)
                    self._labelObjects[i].Erase(dc)
                    self._labelObjects[i].RemoveFromCanvas(self._canvas)
                    self._labelObjects[i] = None

    # Control points ('handles') redirect control to the actual shape, to
    # make it easier to override sizing behaviour.
    def OnSizingDragLeft(self, pt, draw, x, y, keys = 0, attachment = 0):
        dc = wx.ClientDC(self.GetCanvas())
        self.GetCanvas().PrepareDC(dc)

        dc.SetLogicalFunction(OGLRBLF)

        dottedPen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.DOT)
        dc.SetPen(dottedPen)
        dc.SetBrush(wx.TRANSPARENT_BRUSH)

⌨️ 快捷键说明

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