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

📄 _lines.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 4 页
字号:
# -*- coding: iso-8859-1 -*-
#----------------------------------------------------------------------------
# Name:         lines.py
# Purpose:      LineShape class
#
# Author:       Pierre Hj鋖m (from C++ original by Julian Smart)
#
# Created:      2004-05-08
# RCS-ID:       $Id: _lines.py,v 1.17 2006/02/03 06:51:34 RD Exp $
# Copyright:    (c) 2004 Pierre Hj鋖m - 1998 Julian Smart
# Licence:      wxWindows license
#----------------------------------------------------------------------------

import sys
import math

from _basic import Shape, ShapeRegion, ShapeTextLine, ControlPoint, RectangleShape
from _oglmisc import *

# Line alignment flags
# Vertical by default
LINE_ALIGNMENT_HORIZ =              1
LINE_ALIGNMENT_VERT =               0
LINE_ALIGNMENT_TO_NEXT_HANDLE =     2
LINE_ALIGNMENT_NONE =               0



class LineControlPoint(ControlPoint):
    def __init__(self, theCanvas = None, object = None, size = 0.0, x = 0.0, y = 0.0, the_type = 0):
        ControlPoint.__init__(self, theCanvas, object, size, x, y, the_type)
        self._xpos = x
        self._ypos = y
        self._type = the_type
        self._point = None
        self._originalPos = None

    def OnDraw(self, dc):
        RectangleShape.OnDraw(self, dc)

    # Implement movement of Line point
    def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
        self._shape.GetEventHandler().OnSizingDragLeft(self, draw, x, y, keys, attachment)

    def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
        self._shape.GetEventHandler().OnSizingBeginDragLeft(self, x, y, keys, attachment)

    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
        self._shape.GetEventHandler().OnSizingEndDragLeft(self, x, y, keys, attachment)



class ArrowHead(object):
    def __init__(self, type = 0, end = 0, size = 0.0, dist = 0.0, name = "", mf = None, arrowId = -1):
        if isinstance(type, ArrowHead):
            pass
        else:
            self._arrowType = type
            self._arrowEnd = end
            self._arrowSize = size
            self._xOffset = dist
            self._yOffset = 0.0
            self._spacing = 5.0

            self._arrowName = name
            self._metaFile = mf
            self._id = arrowId
            if self._id == -1:
                self._id = wx.NewId()
            
    def _GetType(self):
        return self._arrowType

    def GetPosition(self):
        return self._arrowEnd

    def SetPosition(self, pos):
        self._arrowEnd = pos

    def GetXOffset(self):
        return self._xOffset

    def GetYOffset(self):
        return self._yOffset
    
    def GetSpacing(self):
        return self._spacing

    def GetSize(self):
        return self._arrowSize

    def SetSize(self, size):
        self._arrowSize = size
        if self._arrowType == ARROW_METAFILE and self._metaFile:
            oldWidth = self._metaFile._width
            if oldWidth == 0:
                return

            scale = float(size) / oldWidth
            if scale != 1:
                self._metaFile.Scale(scale, scale)
                
    def GetName(self):
        return self._arrowName

    def SetXOffset(self, x):
        self._xOffset = x

    def SetYOffset(self, y):
        self._yOffset = y

    def GetMetaFile(self):
        return self._metaFile

    def GetId(self):
        return self._id

    def GetArrowEnd(self):
        return self._arrowEnd

    def GetArrowSize(self):
        return self._arrowSize

    def SetSpacing(self, sp):
        self._spacing = sp



class LabelShape(RectangleShape):
    def __init__(self, parent, region, w, h):
        RectangleShape.__init__(self, w, h)
        self._lineShape = parent
        self._shapeRegion = region
        self.SetPen(wx.Pen(wx.Colour(0, 0, 0), 1, wx.DOT))

    def OnDraw(self, dc):
        if self._lineShape and not self._lineShape.GetDrawHandles():
            return

        x1 = self._xpos - self._width / 2.0
        y1 = self._ypos - self._height / 2.0

        if self._pen:
            if self._pen.GetWidth() == 0:
                dc.SetPen(wx.Pen(wx.WHITE, 1, wx.TRANSPARENT))
            else:
                dc.SetPen(self._pen)
        dc.SetBrush(wx.TRANSPARENT_BRUSH)

        if self._cornerRadius > 0:
            dc.DrawRoundedRectangle(x1, y1, self._width, self._height, self._cornerRadius)
        else:
            dc.DrawRectangle(x1, y1, self._width, self._height)

    def OnDrawContents(self, dc):
        pass

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

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

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

    def OnMovePre(self, dc, x, y, old_x, old_y, display):
        return self._lineShape.OnLabelMovePre(dc, self, x, y, old_x, old_y, display)

    # Divert left and right clicks to line object
    def OnLeftClick(self, x, y, keys = 0, attachment = 0):
        self._lineShape.GetEventHandler().OnLeftClick(x, y, keys, attachment)

    def OnRightClick(self, x, y, keys = 0, attachment = 0):
        self._lineShape.GetEventHandler().OnRightClick(x, y, keys, attachment)
        


class LineShape(Shape):
    """LineShape may be attached to two nodes;
    it may be segmented, in which case a control point is drawn for each joint.

    A wxLineShape may have arrows at the beginning, end and centre.

    Derived from:
      Shape
    """
    def __init__(self):
        Shape.__init__(self)

        self._sensitivity = OP_CLICK_LEFT | OP_CLICK_RIGHT
        self._draggable = False
        self._attachmentTo = 0
        self._attachmentFrom = 0
        self._from = None
        self._to = None
        self._erasing = False
        self._arrowSpacing = 5.0
        self._ignoreArrowOffsets = False
        self._isSpline = False
        self._maintainStraightLines = False
        self._alignmentStart = 0
        self._alignmentEnd = 0

        self._lineControlPoints = None

        # Clear any existing regions (created in an earlier constructor)
        # and make the three line regions.
        self.ClearRegions()
        for name in ["Middle","Start","End"]:
            newRegion = ShapeRegion()
            newRegion.SetName(name)
            newRegion.SetSize(150, 50)
            self._regions.append(newRegion)

        self._labelObjects = [None, None, None]
        self._lineOrientations = []
        self._lineControlPoints = []
        self._arcArrows = []

    def __del__(self):
        if self._lineControlPoints:
            self._lineControlPoints = []
        for i in range(3):
            if self._labelObjects[i]:
                self._labelObjects[i].Select(False)
                self._labelObjects[i].RemoveFromCanvas(self._canvas)
        self._labelObjects = []
        self.ClearArrowsAtPosition(-1)

    def GetFrom(self):
        """Return the 'from' object."""
        return self._from
    
    def GetTo(self):
        """Return the 'to' object."""
        return self._to

    def GetAttachmentFrom(self):
        """Return the attachment point on the 'from' node."""
        return self._attachmentFrom

    def GetAttachmentTo(self):
        """Return the attachment point on the 'to' node."""
        return self._attachmentTo

    def GetLineControlPoints(self):
        return self._lineControlPoints

    def SetSpline(self, spline):
        """Specifies whether a spline is to be drawn through the control points."""
        self._isSpline = spline

    def IsSpline(self):
        """TRUE if a spline is drawn through the control points."""
        return self._isSpline

    def SetAttachmentFrom(self, attach):
        """Set the 'from' shape attachment."""
        self._attachmentFrom = attach

    def SetAttachmentTo(self, attach):
        """Set the 'to' shape attachment."""
        self._attachmentTo = attach

    # This is really to distinguish between lines and other images.
    # For lines, want to pass drag to canvas, since lines tend to prevent
    # dragging on a canvas (they get in the way.)
    def Draggable(self):
        return False

    def SetIgnoreOffsets(self, ignore):
        """Set whether to ignore offsets from the end of the line when drawing."""
        self._ignoreArrowOffsets = ignore

    def GetArrows(self):
        return self._arcArrows

    def GetAlignmentStart(self):
        return self._alignmentStart

    def GetAlignmentEnd(self):
        return self._alignmentEnd

    def IsEnd(self, nodeObject):
        """TRUE if shape is at the end of the line."""
        return self._to == nodeObject

    def MakeLineControlPoints(self, n):
        """Make a given number of control points (minimum of two)."""
        self._lineControlPoints = []
        
        for _ in range(n):
            point = wx.RealPoint(-999, -999)
            self._lineControlPoints.append(point)

        # pi: added _initialised to keep track of when we have set
        # the middle points to something other than (-999, -999)
        self._initialised = False
        
    def InsertLineControlPoint(self, dc = None, point = None):
        """Insert a control point at an optional given position."""
        if dc:
            self.Erase(dc)

        if point:
            line_x, line_y = point
        else:
            last_point = self._lineControlPoints[-1]
            second_last_point = self._lineControlPoints[-2]

            line_x = (last_point[0] + second_last_point[0]) / 2.0
            line_y = (last_point[1] + second_last_point[1]) / 2.0

        point = wx.RealPoint(line_x, line_y)
        self._lineControlPoints.insert(len(self._lineControlPoints)-1, point)

    def DeleteLineControlPoint(self):
        """Delete an arbitary point on the line."""
        if len(self._lineControlPoints) < 3:
            return False

        del self._lineControlPoints[-2]
        return True

    def Initialise(self):
        """Initialise the line object."""
        if self._lineControlPoints:
            # Just move the first and last control points
            first_point = self._lineControlPoints[0]
            last_point = self._lineControlPoints[-1]

            # If any of the line points are at -999, we must
            # initialize them by placing them half way between the first
            # and the last.

            for i in range(1,len(self._lineControlPoints)):
                point = self._lineControlPoints[i]
                if point[0] == -999:
                    if first_point[0] < last_point[0]:
                        x1 = first_point[0]
                        x2 = last_point[0]
                    else:
                        x2 = first_point[0]
                        x1 = last_point[0]
                    if first_point[1] < last_point[1]:
                        y1 = first_point[1]
                        y2 = last_point[1]
                    else:
                        y2 = first_point[1]
                        y1 = last_point[1]
                    self._lineControlPoints[i] = wx.RealPoint((x2 - x1) / 2.0 + x1, (y2 - y1) / 2.0 + y1)
                    self._initialised = True
                    
    def FormatText(self, dc, s, i):
        """Format a text string according to the region size, adding
        strings with positions to region text list.
        """
        self.ClearText(i)

        if len(self._regions) == 0 or i >= len(self._regions):
            return

        region = self._regions[i]
        region.SetText(s)
        dc.SetFont(region.GetFont())

        w, h = region.GetSize()
        # Initialize the size if zero
        if (w == 0 or h == 0) and s:
            w, h = 100, 50
            region.SetSize(w, h)

        string_list = FormatText(dc, s, w - 5, h - 5, region.GetFormatMode())
        for s in string_list:
            line = ShapeTextLine(0.0, 0.0, s)
            region.GetFormattedText().append(line)

        actualW = w
        actualH = h
        if region.GetFormatMode() & FORMAT_SIZE_TO_CONTENTS:
            actualW, actualH = GetCentredTextExtent(dc, region.GetFormattedText(), self._xpos, self._ypos, w, h)
            if actualW != w or actualH != h:
                xx, yy = self.GetLabelPosition(i)

⌨️ 快捷键说明

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