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

📄 _drawn.py

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

import os.path

from _basic import RectangleShape
from _oglmisc import *

METAFLAGS_OUTLINE         = 1
METAFLAGS_ATTACHMENTS     = 2

DRAWN_ANGLE_0        = 0
DRAWN_ANGLE_90       = 1
DRAWN_ANGLE_180      = 2
DRAWN_ANGLE_270      = 3

# Drawing operations
DRAWOP_SET_PEN               = 1
DRAWOP_SET_BRUSH             = 2
DRAWOP_SET_FONT              = 3
DRAWOP_SET_TEXT_COLOUR       = 4
DRAWOP_SET_BK_COLOUR         = 5
DRAWOP_SET_BK_MODE           = 6
DRAWOP_SET_CLIPPING_RECT     = 7
DRAWOP_DESTROY_CLIPPING_RECT = 8

DRAWOP_DRAW_LINE             = 20
DRAWOP_DRAW_POLYLINE         = 21
DRAWOP_DRAW_POLYGON          = 22
DRAWOP_DRAW_RECT             = 23
DRAWOP_DRAW_ROUNDED_RECT     = 24
DRAWOP_DRAW_ELLIPSE          = 25
DRAWOP_DRAW_POINT            = 26
DRAWOP_DRAW_ARC              = 27
DRAWOP_DRAW_TEXT             = 28
DRAWOP_DRAW_SPLINE           = 29
DRAWOP_DRAW_ELLIPTIC_ARC     = 30

class DrawOp(object):
    def __init__(self, theOp):
        self._op = theOp

    def GetOp(self):
        return self._op

    def GetPerimeterPoint(self, x1, y1, x2, y2, xOffset, yOffset, attachmentMode):
        return False

    def Scale(self,scaleX, scaleY):
        pass

    def Translate(self, x, y):
        pass

    def Rotate(self, x, y, theta, sinTheta, cosTheta):
        pass
    
class OpSetGDI(DrawOp):
    """Set font, brush, text colour."""
    def __init__(self, theOp, theImage, theGdiIndex, theMode = 0):
        DrawOp.__init__(self, theOp)

        self._gdiIndex = theGdiIndex
        self._image = theImage
        self._mode = theMode

    def Do(self, dc, xoffset = 0, yoffset = 0):
        if self._op == DRAWOP_SET_PEN:
            # Check for overriding this operation for outline colour
            if self._gdiIndex in self._image._outlineColours:
                if self._image._outlinePen:
                    dc.SetPen(self._image._outlinePen)
            else:
                try:
                    dc.SetPen(self._image._gdiObjects[self._gdiIndex])
                except IndexError:
                    pass
        elif self._op == DRAWOP_SET_BRUSH:
            # Check for overriding this operation for outline or fill colour
            if self._gdiIndex in self._image._outlineColours:
                # Need to construct a brush to match the outline pen's colour
                if self._image._outlinePen:
                    br = wx.Brush(self._image._outlinePen, wx.SOLID)
                    if br:
                        dc.SetBrush(br)
            elif self._gdiIndex in self._image._fillColours:
                if self._image._fillBrush:
                    dc.SetBrush(self._image._fillBrush)
            else:
                brush = self._image._gdiObjects[self._gdiIndex]
                if brush:
                    dc.SetBrush(brush)
        elif self._op == DRAWOP_SET_FONT:
            try:
                dc.SetFont(self._image._gdiObjects[self._gdiIndex])
            except IndexError:
                pass
        elif self._op == DRAWOP_SET_TEXT_COLOUR:
            dc.SetTextForeground(wx.Colour(self._r, self._g, self._b))
        elif self._op == DRAWOP_SET_BK_COLOUR:
            dc.SetTextBackground(wx.Colour(self._r, self._g, self._b))
        elif self._op == DRAWOP_SET_BK_MODE:
            dc.SetBackgroundMode(self._mode)

    
class OpSetClipping(DrawOp):
    """Set/destroy clipping."""
    def __init__(self, theOp, theX1, theY1, theX2, theY2):
        DrawOp.__init__(self, theOp)

        self._x1 = theX1
        self._y1 = theY1
        self._x2 = theX2
        self._y2 = theY2

    def Do(self, dc, xoffset, yoffset):
        if self._op == DRAWOP_SET_CLIPPING_RECT:
            dc.SetClippingRegion(self._x1 + xoffset, self._y1 + yoffset, self._x2 + xoffset, self._y2 + yoffset)
        elif self._op == DRAWOP_DESTROY_CLIPPING_RECT:
            dc.DestroyClippingRegion()

    def Scale(self, scaleX, scaleY):
        self._x1 *= scaleX
        self._y1 *= scaleY
        self._x2 *= scaleX
        self._y2 *= scaleY

    def Translate(self, x, y):
        self._x1 += x
        self._y1 += y


class OpDraw(DrawOp):
    """Draw line, rectangle, rounded rectangle, ellipse, point, arc, text."""
    def __init__(self, theOp, theX1, theY1, theX2, theY2, theRadius = 0.0, s = ""):
        DrawOp.__init__(self, theOp)

        self._x1 = theX1
        self._y1 = theY1
        self._x2 = theX2
        self._y2 = theY2
        self._x3 = 0.0
        self._y3 = 0.0
        self._radius = theRadius
        self._textString = s

    def Do(self, dc, xoffset, yoffset):
        if self._op == DRAWOP_DRAW_LINE:
            dc.DrawLine(self._x1 + xoffset, self._y1 + yoffset, self._x2 + xoffset, self._y2 + yoffset)
        elif self._op == DRAWOP_DRAW_RECT:
            dc.DrawRectangle(self._x1 + xoffset, self._y1 + yoffset, self._x2, self._y2)
        elif self._op == DRAWOP_DRAW_ROUNDED_RECT:
            dc.DrawRoundedRectangle(self._x1 + xoffset, self._y1 + yoffset, self._x2, self._y2, self._radius)
        elif self._op == DRAWOP_DRAW_ELLIPSE:
            dc.DrawEllipse(self._x1 + xoffset, self._y1 + yoffset, self._x2, self._y2)
        elif self._op == DRAWOP_DRAW_ARC:
            dc.DrawArc(self._x2 + xoffset, self._y2 + yoffset, self._x3 + xoffset, self._y3 + yoffset, self._x1 + xoffset, self._y1 + yoffset)
        elif self._op == DRAWOP_DRAW_ELLIPTIC_ARC:
            dc.DrawEllipticArc(self._x1 + xoffset, self._y1 + yoffset, self._x2, self._y2, self._x3 * 360 / (2 * math.pi), self._y3 * 360 / (2 * math.pi))
        elif self._op == DRAWOP_DRAW_POINT:
            dc.DrawPoint(self._x1 + xoffset, self._y1 + yoffset)
        elif self._op == DRAWOP_DRAW_TEXT:
            dc.DrawText(self._textString, self._x1 + xoffset, self._y1 + yoffset)
    def Scale(self, scaleX, scaleY):
        self._x1 *= scaleX
        self._y1 *= scaleY
        self._x2 *= scaleX
        self._y2 *= scaleY

        if self._op != DRAWOP_DRAW_ELLIPTIC_ARC:
            self._x3 *= scaleX
            self._y3 *= scaleY

        self._radius *= scaleX
        
    def Translate(self, x, y):
        self._x1 += x
        self._y1 += y

        if self._op == DRAWOP_DRAW_LINE:
            self._x2 += x
            self._y2 += y
        elif self._op == DRAWOP_DRAW_ARC:
            self._x2 += x
            self._y2 += y
            self._x3 += x
            self._y3 += y

    def Rotate(self, x, y, theta, sinTheta, cosTheta):
        newX1 = self._x1 * cosTheta + self._y1 * sinTheta + x * (1 - cosTheta) + y * sinTheta
        newY1 = self._x1 * sinTheta + self._y1 * cosTheta + y * (1 - cosTheta) + x * sinTheta

        if self._op == DRAWOP_DRAW_LINE:
            newX2 = self._x2 * cosTheta - self._y2 * sinTheta + x * (1 - cosTheta) + y * sinTheta
            newY2 = self._x2 * sinTheta + self._y2 * cosTheta + y * (1 - cosTheta) + x * sinTheta;

            self._x1 = newX1
            self._y1 = newY1
            self._x2 = newX2
            self._y2 = newY2

        elif self._op in [DRAWOP_DRAW_RECT, DRAWOP_DRAW_ROUNDED_RECT, DRAWOP_DRAW_ELLIPTIC_ARC]:
            # Assume only 0, 90, 180, 270 degree rotations.
            # oldX1, oldY1 represents the top left corner. Find the
            # bottom right, and rotate that. Then the width/height is
            # the difference between x/y values.
            oldBottomRightX = self._x1 + self._x2
            oldBottomRightY = self._y1 + self._y2
            newBottomRightX = oldBottomRightX * cosTheta - oldBottomRightY * sinTheta + x * (1 - cosTheta) + y * sinTheta
            newBottomRightY = oldBottomRightX * sinTheta + oldBottomRightY * cosTheta + y * (1 - cosTheta) + x * sinTheta

            # Now find the new top-left, bottom-right coordinates.
            minX = min(newX1, newBottomRightX)
            minY = min(newY1, newBottomRightY)
            maxX = max(newX1, newBottomRightX)
            maxY = max(newY1, newBottomRightY)

            self._x1 = minX
            self._y1 = minY
            self._x2 = maxX - minX # width
            self._y2 = maxY - minY # height

            if self._op == DRAWOP_DRAW_ELLIPTIC_ARC:
                # Add rotation to angles
                self._x3 += theta
                self._y3 += theta
        elif self._op == DRAWOP_DRAW_ARC:
            newX2 = self._x2 * cosTheta - self._y2 * sinTheta + x * (1 - cosTheta) + y * sinTheta
            newY2 = self._x2 * sinTheta + self._y2 * cosTheta + y * (1 - cosTheta) + x * sinTheta
            newX3 = self._x3 * cosTheta - self._y3 * sinTheta + x * (1 - cosTheta) + y * sinTheta
            newY3 = self._x3 * sinTheta + self._y3 * cosTheta + y * (1 - cosTheta) + x * sinTheta

            self._x1 = newX1
            self._y1 = newY1
            self._x2 = newX2
            self._y2 = newY2
            self._x3 = newX3
            self._y3 = newY3


class OpPolyDraw(DrawOp):
    """Draw polygon, polyline, spline."""
    def __init__(self, theOp, thePoints):
        DrawOp.__init__(self, theOp)

        self._noPoints = len(thePoints)
        self._points = thePoints

    def Do(self, dc, xoffset, yoffset):
        if self._op == DRAWOP_DRAW_POLYLINE:
            dc.DrawLines(self._points, xoffset, yoffset)
        elif self._op == DRAWOP_DRAW_POLYGON:
            dc.DrawPolygon(self._points, xoffset, yoffset)
        elif self._op == DRAWOP_DRAW_SPLINE:
            dc.DrawSpline(self._points) # no offsets in DrawSpline

    def Scale(self, scaleX, scaleY):
        for i in range(self._noPoints):
            self._points[i] = wx.Point(self._points[i][0] * scaleX, self._points[i][1] * scaleY)

    def Translate(self, x, y):
        for i in range(self._noPoints):
            self._points[i][0] += x
            self._points[i][1] += y

    def Rotate(self, x, y, theta, sinTheta, cosTheta):
        for i in range(self._noPoints):
            x1 = self._points[i][0]
            y1 = self._points[i][1]

            self._points[i] = x1 * cosTheta - y1 * sinTheta + x * (1 - cosTheta) + y * sinTheta, x1 * sinTheta + y1 * cosTheta + y * (1 - cosTheta) + x * sinTheta

    def OnDrawOutline(self, dc, x, y, w, h, oldW, oldH):
        dc.SetBrush(wx.TRANSPARENT_BRUSH)

        # Multiply all points by proportion of new size to old size
        x_proportion = abs(w / oldW)
        y_proportion = abs(h / oldH)

        dc.DrawPolygon([(x_proportion * x, y_proportion * y) for x, y in self._points], x, y)

    def GetPerimeterPoint(self, x1, y1, x2, y2, xOffset, yOffset, attachmentMode):
        # First check for situation where the line is vertical,
        # and we would want to connect to a point on that vertical --
        # oglFindEndForPolyline can't cope with this (the arrow
        # gets drawn to the wrong place).
        if attachmentMode == ATTACHMENT_MODE_NONE and x1 == x2:

⌨️ 快捷键说明

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