diff options
Diffstat (limited to 'Lib')
| -rw-r--r-- | Lib/defconQt/glyphView.py | 97 | ||||
| -rw-r--r-- | Lib/defconQt/objects/sizeGripItem.py | 205 | 
2 files changed, 226 insertions, 76 deletions
| diff --git a/Lib/defconQt/glyphView.py b/Lib/defconQt/glyphView.py index 6eb9eee..850a216 100644 --- a/Lib/defconQt/glyphView.py +++ b/Lib/defconQt/glyphView.py @@ -6,6 +6,7 @@ import pickle  from defcon import Anchor, Component  from defconQt import icons_db  # noqa  from defconQt.objects.defcon import TContour, TGlyph +from defconQt.objects.sizeGripItem import ResizeHandleItem, SizeGripItem  from defconQt.pens.copySelectionPen import CopySelectionPen  from defconQt.util import platformSpecific  from fontTools.misc import bezierTools @@ -16,7 +17,7 @@ from PyQt5.QtGui import (  from PyQt5.QtWidgets import (      QAction, QActionGroup, QApplication, QColorDialog, QComboBox, QDialog,      QDialogButtonBox, QGraphicsEllipseItem, QGraphicsItem, QGraphicsLineItem, -    QGraphicsPathItem, QGraphicsPixmapItem, QGraphicsRectItem, QGraphicsScene, +    QGraphicsPathItem, QGraphicsPixmapItem, QGraphicsScene,      QGraphicsSimpleTextItem, QGraphicsView, QGridLayout, QLabel, QLineEdit,      QListWidget, QMainWindow, QMenu, QRadioButton, QSizePolicy, QStyle,      QStyleOptionGraphicsItem, QToolBar, QWidget) @@ -1186,86 +1187,32 @@ class VGuidelinesTextItem(QGraphicsSimpleTextItem):          self.setFont(font) -class ResizeHandleItem(QGraphicsRectItem): - -    def __init__(self, parent=None): -        super(QGraphicsRectItem, self).__init__(parent) -        self.setPointPath() -        self.setBrush(QBrush(QColor(60, 60, 60))) -        self.setPen(QPen(Qt.NoPen)) -        self.setFlag(QGraphicsItem.ItemIgnoresParentOpacity) -        self.setFlag(QGraphicsItem.ItemIsMovable) -        # self.setFlag(QGraphicsItem.ItemIsSelectable) -        self.setCursor(Qt.SizeFDiagCursor) - -        rect = self.parentItem().boundingRect() -        self.setPos(rect.width(), rect.height()) - -    def itemChange(self, change, value): -        if change == QGraphicsItem.ItemSelectedChange: -            if not value: -                self.setVisible(value) -        return value - -    def mouseMoveEvent(self, event): -        self.parentItem()._pixmapGeometryChanged(event) - -    def setPointPath(self, scale=None): -        if scale is None: -            scene = self.scene() -            if scene is not None: -                scale = scene.getViewScale() -            else: -                scale = 1 -        if scale > 4: -            scale = 4 -        self.prepareGeometryChange() -        self.setRect(-onHalf / scale, -onHalf / scale, -                     onWidth / scale, onHeight / scale) - -  class PixmapItem(QGraphicsPixmapItem): -    def __init__(self, x, y, pixmap, parent=None): +    def __init__(self, x, y, pixmap, scale, parent=None):          super(QGraphicsPixmapItem, self).__init__(pixmap, parent) -        self.setPos(x, y) -        self.setFlag(QGraphicsItem.ItemIsMovable) +        self._pixmap = pixmap +        self.setOffset(x, -y)          self.setFlag(QGraphicsItem.ItemIsSelectable) +        self.setShapeMode(QGraphicsPixmapItem.BoundingRectShape)          self.setTransform(QTransform().fromScale(1, -1)) -        self.setOpacity(.5) +        self.setOpacity(.6)          self.setZValue(-1) - -        rect = self.boundingRect() -        self._rWidth = rect.width() -        self._rHeight = rect.height() -        handle = ResizeHandleItem(self) -        handle.setVisible(False) - -    def _pixmapGeometryChanged(self, event): -        modifiers = event.modifiers() -        pos = event.scenePos() -        if modifiers & Qt.ControlModifier: -            # rotate -            refLine = QLineF(self.x(), self.y(), self.x() + -                             self._rWidth, self.y() - self._rHeight) -            curLine = QLineF(self.x(), self.y(), pos.x(), pos.y()) -            self.setRotation(refLine.angleTo(curLine)) -        else: -            # scale -            dy = (pos.y() - self.y()) / self._rHeight -            if modifiers & Qt.ShiftModifier: -                # keep original aspect ratio -                dx = -dy -            else: -                dx = (pos.x() - self.x()) / self._rWidth -            self.setTransform(QTransform().fromScale(dx, dy)) -        event.accept() +        sizeGripItem = SizeGripItem(scale, self) +        sizeGripItem.setVisible(False) + +    def setRect(self, rect): +        dTopLeft = rect.topLeft() - self.pos() +        if not dTopLeft.isNull(): +            self.setOffset(dTopLeft) +        self.setPixmap(self._pixmap.scaled( +            rect.size().toSize() +        ))      def itemChange(self, change, value):          if change == QGraphicsItem.ItemSelectedChange: -            children = self.childItems() -            if not children[0].isUnderMouse(): -                children[0].setVisible(value) +            sizeGripItem = self.childItems()[0] +            sizeGripItem.setVisible(value)          return value @@ -1329,8 +1276,8 @@ class GlyphScene(QGraphicsScene):          else:              return          pos = event.scenePos() -        newPix = PixmapItem(pos.x(), pos.y(), dragPix) -        self._addRegisterItem(newPix) +        pixmapItem = PixmapItem(pos.x(), pos.y(), dragPix, self.getViewScale()) +        self._addRegisterItem(pixmapItem)          event.acceptProposedAction()      def getItemForPoint(self, point): @@ -1371,8 +1318,6 @@ class GlyphScene(QGraphicsScene):                  elif isinstance(item, (AnchorItem, ComponentItem,                                         OffCurvePointItem)):                      item.delete() -                elif isinstance(item, PixmapItem): -                    self.removeItem(item)              self._blocked = False              self._glyphObject.dirty = True              event.accept() diff --git a/Lib/defconQt/objects/sizeGripItem.py b/Lib/defconQt/objects/sizeGripItem.py new file mode 100644 index 0000000..94e07ba --- /dev/null +++ b/Lib/defconQt/objects/sizeGripItem.py @@ -0,0 +1,205 @@ +# SizeGripItem - A size grip QGraphicsItem for interactive resizing. +# +# Python port by Felipe Correa da Silva Sanches +# based on the original C++ code by Cesar L. B. Silveira +# +# Copyright 2011, Cesar L. B. Silveira. +# Copyright 2015, Felipe Correa da Silva Sanches <juca@members.fsf.org>. +# Copyright 2015, Adrien Tétar. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QBrush, QPen +from PyQt5.QtWidgets import QGraphicsItem, QGraphicsRectItem + +Top = 1 << 0 +Bottom = 1 << 1 +Left = 1 << 2 +Right = 1 << 3 +Center = 1 << 4 +TopLeft = Top | Left +BottomLeft = Bottom | Left +TopRight = Top | Right +BottomRight = Bottom | Right + +possibleFlags = (Top, Bottom, Left, TopLeft, BottomLeft, Right, TopRight, +                 BottomRight, Center) + + +class ResizeHandleItem(QGraphicsRectItem): +    def __init__(self, positionFlags, scale, parent): +        super(ResizeHandleItem, self).__init__(parent) +        self.setPointPath(scale) +        self.positionFlags = positionFlags +        self.setBrush(QBrush(Qt.lightGray)) +        self.setFlag(QGraphicsItem.ItemIsMovable) +        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) +        if self.positionFlags in (Top, Bottom): +            cursor = Qt.SizeVerCursor +        elif self.positionFlags in (Left, Right): +            cursor = Qt.SizeHorCursor +        elif self.positionFlags in (BottomLeft, TopRight): +            cursor = Qt.SizeBDiagCursor +        elif self.positionFlags in (TopLeft, BottomRight): +            cursor = Qt.SizeFDiagCursor +        elif self.positionFlags == Center: +            cursor = Qt.SizeAllCursor +        self.setCursor(cursor) + +    def itemChange(self, change, value): +        if change == QGraphicsItem.ItemPositionChange: +            return self.restrictPosition(value) +        return value + +    def mouseMoveEvent(self, event): +        pos = self.mapToParent(event.pos()) +        parent = self.parentItem() +        if self.positionFlags == TopLeft: +            parent.setTopLeft(pos) +        elif self.positionFlags == Top: +            parent.setTop(pos.y()) +        elif self.positionFlags == TopRight: +            parent.setTopRight(pos) +        elif self.positionFlags == Right: +            parent.setRight(pos.x()) +        elif self.positionFlags == BottomRight: +            parent.setBottomRight(pos) +        elif self.positionFlags == Bottom: +            parent.setBottom(pos.y()) +        elif self.positionFlags == BottomLeft: +            parent.setBottomLeft(pos) +        elif self.positionFlags == Left: +            parent.setLeft(pos.x()) +        elif self.positionFlags == Center: +            parent.setCenter(pos) +        parent.doResize() + +    def restrictPosition(self, newPos): +        parent = self.parentItem() +        retVal = newPos + +        if self.positionFlags & Top or self.positionFlags & Bottom: +            retVal.setY(newPos.y()) +        if self.positionFlags & Left or self.positionFlags & Right: +            retVal.setX(newPos.x()) + +        if self.positionFlags & Top and retVal.y() > parent.rect.bottom(): +            retVal.setY(parent.rect.bottom()) +        elif self.positionFlags & Bottom and retVal.y() < parent.rect.top(): +            retVal.setY(parent.rect.top()) + +        if self.positionFlags & Left and retVal.x() > parent.rect.right(): +            retVal.setX(parent.rect.right()) +        elif self.positionFlags & Right and retVal.x() < parent.rect.left(): +            retVal.setX(parent.rect.left()) + +        return retVal + +    def setPointPath(self, scale=None): +        if scale is None: +            scene = self.scene() +            if scene is not None: +                scale = scene.getViewScale() +            else: +                scale = 1 +        if scale > 4: +            scale = 4 +        self.prepareGeometryChange() +        self.setPen(QPen(Qt.black, 1.0 / scale)) +        self.setRect(-4 / scale, -4 / scale, 8 / scale, 8 / scale) + + +class SizeGripItem(QGraphicsItem): +    def __init__(self, scale, parent): +        super(SizeGripItem, self).__init__(parent) +        self.setFlag(QGraphicsItem.ItemIgnoresParentOpacity) + +        for flag in possibleFlags: +            ResizeHandleItem(flag, scale, self) +        self.updateBoundingRect() + +    def boundingRect(self): +        return self.rect + +    def paint(self, painter, option, widget): +        pass + +    def setTopLeft(self, pos): +        self.rect.setTopLeft(pos) + +    def setTop(self, y): +        self.rect.setTop(y) + +    def setTopRight(self, pos): +        self.rect.setTopRight(pos) + +    def setRight(self, x): +        self.rect.setRight(x) + +    def setBottomRight(self, pos): +        self.rect.setBottomRight(pos) + +    def setBottom(self, y): +        self.rect.setBottom(y) + +    def setBottomLeft(self, pos): +        self.rect.setBottomLeft(pos) + +    def setLeft(self, x): +        self.rect.setLeft(x) + +    def setCenter(self, pos): +        self.rect.moveCenter(pos) + +    def doResize(self): +        self.parentItem().setRect(self.rect) +        self.updateHandleItemPositions() + +    def updateBoundingRect(self): +        self.rect = self.parentItem().boundingRect() +        self.updateHandleItemPositions() + +    def updateHandleItemPositions(self): +        for item in self.childItems(): +            item.setFlag(QGraphicsItem.ItemSendsGeometryChanges, False) +            flags = item.positionFlags +            if flags == TopLeft: +                item.setPos(self.rect.topLeft()) +            elif flags == Top: +                item.setPos(self.rect.left() + self.rect.width() / 2 - 1, +                            self.rect.top()) +            elif flags == TopRight: +                item.setPos(self.rect.topRight()) +            elif flags == Right: +                item.setPos(self.rect.right(), +                            self.rect.top() + self.rect.height() / 2 - 1) +            elif flags == BottomRight: +                item.setPos(self.rect.bottomRight()) +            elif flags == Bottom: +                item.setPos(self.rect.left() + self.rect.width() / 2 - 1, +                            self.rect.bottom()) +            elif flags == BottomLeft: +                item.setPos(self.rect.bottomLeft()) +            elif flags == Left: +                item.setPos(self.rect.left(), +                            self.rect.top() + self.rect.height() / 2 - 1) +            elif flags == Center: +                item.setPos(self.rect.center()) +            item.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) | 
