diff options
| author | Adrien Tétar | 2015-11-07 18:37:13 +0100 |
|---|---|---|
| committer | Adrien Tétar | 2015-11-07 18:50:42 +0100 |
| commit | 06b9cdcf0e873c9233d070874d84ceca58d379f7 (patch) | |
| tree | a016e6dcf07746dc134ee4529c55d9d4e2b6c4c4 | |
| parent | 6609eead1d2a5e0f173bb2a79536cc6b11c8483c (diff) | |
| download | trufont-06b9cdcf0e873c9233d070874d84ceca58d379f7.tar.bz2 | |
SizeGripItem: finish and fix implementation, use with pixmap
| -rw-r--r-- | Lib/defconQt/glyphView.py | 97 | ||||
| -rw-r--r-- | Lib/defconQt/objects/sizeGripItem.py | 151 |
2 files changed, 114 insertions, 134 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 index dfccf76..94e07ba 100644 --- a/Lib/defconQt/objects/sizeGripItem.py +++ b/Lib/defconQt/objects/sizeGripItem.py @@ -3,8 +3,9 @@ # Python port by Felipe Correa da Silva Sanches # based on the original C++ code by Cesar L. B. Silveira # -# Copyright (c) 2015 Felipe Correa da Silva Sanches <juca@members.fsf.org> -# Copyright (c) 2011 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"), @@ -25,79 +26,114 @@ # IN THE SOFTWARE. from PyQt5.QtCore import Qt -from PyQt5.QtGui import QBrush +from PyQt5.QtGui import QBrush, QPen from PyQt5.QtWidgets import QGraphicsItem, QGraphicsRectItem -Top = 1 << 0 -Bottom = 1 << 1 -Left = 1 << 2 -Right = 1 << 3 -TopLeft = Top | Left -BottomLeft = Bottom | Left -TopRight = Top | Right +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 -class HandleItem(QGraphicsRectItem): - def __init__(self, positionFlags, parent): - super(HandleItem, self).__init__(-4, -4, 8, 8, parent) +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.parent = parent 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) - elif change == QGraphicsItem.ItemPositionHasChanged: - if self.positionFlags == TopLeft: - self.parent.setTopLeft(value) - elif self.positionFlags == Top: - self.parent.setTop(value.y()) - elif self.positionFlags == TopRight: - self.parent.setTopRight(value) - elif self.positionFlags == Right: - self.parent.setRight(value.x()) - elif self.positionFlags == BottomRight: - self.parent.setBottomRight(value) - elif self.positionFlags == Bottom: - self.parent.setBottom(value.y()) - elif self.positionFlags == BottomLeft: - self.parent.setBottomLeft(value) - elif self.positionFlags == Left: - self.parent.setLeft(value.x()) 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() > self.parent.rect.bottom(): - retVal.setY(self.parent.rect.bottom()) - elif self.positionFlags & Bottom and retVal.y() < self.parent.rect.top(): - retVal.setY(self.parent.rect.top()) + 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() > self.parent.rect.right(): - retVal.setX(self.parent.rect.right()) - elif self.positionFlags & Right and retVal.x() < self.parent.rect.left(): - retVal.setX(self.parent.rect.left()) + 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, resizer, parent): + def __init__(self, scale, parent): super(SizeGripItem, self).__init__(parent) - self.resizer = resizer - self.parent = parent - self.rect = self.parent.boundingRect() + self.setFlag(QGraphicsItem.ItemIgnoresParentOpacity) - self.handleItems = [HandleItem(d, self) for d in [Top, Bottom, Left, TopLeft, BottomLeft, Right, TopRight, BottomRight]] - self.updateHandleItemPositions() + for flag in possibleFlags: + ResizeHandleItem(flag, scale, self) + self.updateBoundingRect() def boundingRect(self): return self.rect @@ -107,45 +143,42 @@ class SizeGripItem(QGraphicsItem): def setTopLeft(self, pos): self.rect.setTopLeft(pos) - self.doResize() def setTop(self, y): self.rect.setTop(y) - self.doResize() def setTopRight(self, pos): self.rect.setTopRight(pos) - self.doResize() def setRight(self, x): self.rect.setRight(x) - self.doResize() def setBottomRight(self, pos): self.rect.setBottomRight(pos) - self.doResize() def setBottom(self, y): self.rect.setBottom(y) - self.doResize() def setBottomLeft(self, pos): self.rect.setBottomLeft(pos) - self.doResize() def setLeft(self, x): self.rect.setLeft(x) - self.doResize() + + def setCenter(self, pos): + self.rect.moveCenter(pos) def doResize(self): - if self.resizer: - self.resizer.resize(self.rect) + self.parentItem().setRect(self.rect) + self.updateHandleItemPositions() + + def updateBoundingRect(self): + self.rect = self.parentItem().boundingRect() self.updateHandleItemPositions() def updateHandleItemPositions(self): - for item in self.handleItems: + for item in self.childItems(): item.setFlag(QGraphicsItem.ItemSendsGeometryChanges, False) - flags = item.positionFlags if flags == TopLeft: item.setPos(self.rect.topLeft()) @@ -167,4 +200,6 @@ class SizeGripItem(QGraphicsItem): 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) |
