diff options
| author | Adrien Tétar | 2015-11-05 22:03:11 +0100 |
|---|---|---|
| committer | Adrien Tétar | 2015-11-05 22:03:11 +0100 |
| commit | 2229c660a3375281a61e6adab834c4b33139159f (patch) | |
| tree | c049d2b7e82c9ca3181ceae2c7ee2cf3693764ce | |
| parent | 9551e20b7c92c79906815a66b99757c322db518b (diff) | |
| parent | 2931c81497ce9840940b2842233ef0b7e2eac8d7 (diff) | |
| download | trufont-2229c660a3375281a61e6adab834c4b33139159f.tar.bz2 | |
Merge pull request #116 from trufont/patch-16
glyphView: stability improvements + LayerActionsDialog
| -rw-r--r-- | Lib/defconQt/glyphView.py | 167 | ||||
| -rw-r--r-- | Lib/defconQt/objects/defcon.py | 3 |
2 files changed, 141 insertions, 29 deletions
diff --git a/Lib/defconQt/glyphView.py b/Lib/defconQt/glyphView.py index da933c2..74af3b3 100644 --- a/Lib/defconQt/glyphView.py +++ b/Lib/defconQt/glyphView.py @@ -197,6 +197,65 @@ class AddLayerDialog(QDialog): return (name, result) +class LayerActionsDialog(QDialog): + + def __init__(self, currentGlyph, parent=None): + super().__init__(parent) + self.setWindowModality(Qt.WindowModal) + self.setWindowTitle("Layer actions…") + self._workableLayers = [] + for layer in currentGlyph.layerSet: + if layer != currentGlyph.layer: + self._workableLayers.append(layer) + + layout = QGridLayout(self) + + copyBox = QRadioButton("Copy", self) + moveBox = QRadioButton("Move", self) + swapBox = QRadioButton("Swap", self) + self.otherCheckBoxes = (moveBox, swapBox) + copyBox.setChecked(True) + + self.layersList = QListWidget(self) + self.layersList.addItems( + layer.name for layer in self._workableLayers) + if self.layersList.count(): + self.layersList.setCurrentRow(0) + self.layersList.itemDoubleClicked.connect(self.accept) + + buttonBox = QDialogButtonBox( + QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + buttonBox.accepted.connect(self.accept) + buttonBox.rejected.connect(self.reject) + + l = 0 + layout.addWidget(copyBox, l, 0, 1, 2) + layout.addWidget(moveBox, l, 2, 1, 2) + layout.addWidget(swapBox, l, 4, 1, 2) + l += 1 + layout.addWidget(self.layersList, l, 0, 1, 6) + l += 1 + layout.addWidget(buttonBox, l, 0, 1, 6) + self.setLayout(layout) + + @classmethod + def getLayerAndAction(cls, parent, currentGlyph): + dialog = cls(currentGlyph, parent) + result = dialog.exec_() + currentItem = dialog.layersList.currentItem() + newLayer = None + if currentItem is not None: + newLayerName = currentItem.text() + for layer in dialog._workableLayers: + if layer.name == newLayerName: + newLayer = layer + action = "Copy" + for checkBox in dialog.otherCheckBoxes: + if checkBox.isChecked(): + action = checkBox.text() + return (newLayer, action, result) + + class GenericSettings(object): def __init__(self, title, parent, callback): @@ -307,7 +366,8 @@ class MainGfxWindow(QMainWindow): menuBar.addMenu(fileMenu) glyphMenu = QMenu("&Glyph", self) - glyphMenu.addAction("&Go to…", self.changeGlyph, "G") + glyphMenu.addAction("&Go To…", self.changeGlyph, "G") + glyphMenu.addAction("&Layer Actions…", self.layerActions, "L") menuBar.addMenu(glyphMenu) self._displaySettings = DisplayStyleSettings( @@ -364,6 +424,10 @@ class MainGfxWindow(QMainWindow): self.setWindowTitle(glyph.name, glyph.getParent()) self.adjustSize() + def layerActions(self): + if self.view is not None: + self.view.layerActions() + def _changeGlyph(self, glyph): oldView = self.view # Preserve the selected layer (by setting the glyph from that layer) @@ -626,7 +690,7 @@ class OffCurvePointItem(QGraphicsEllipseItem): self._needsUngrab = False def delete(self): - self.parentItem()._CPDeleted() + self.parentItem()._CPDeleted(self) def itemChange(self, change, value): if change == QGraphicsItem.ItemPositionChange: @@ -646,10 +710,9 @@ class OffCurvePointItem(QGraphicsEllipseItem): else: value.setY(0) elif change == QGraphicsItem.ItemPositionHasChanged: - self.parentItem()._CPMoved(value) - # TODO: consider what to do w offCurves - # elif change == QGraphicsItem.ItemSelectedHasChanged: - # pass#self.parentItem()._CPSelChanged(value) + self.parentItem()._CPMoved(self, value) + elif change == QGraphicsItem.ItemSelectedHasChanged: + self.parentItem()._CPSelected(self, value) return value def mousePressEvent(self, event): @@ -775,26 +838,33 @@ class OnCurvePointItem(QGraphicsPathItem): index += 1 return index % len(self._contour.segments) - def _CPDeleted(self): + def _CPDeleted(self, item): + # XXX: is this sufficient guard? + if self.isSelected(): + return pointIndex = self.getPointIndex() children = self.childItems() - selected = 1 - if not (children[1].isVisible() and children[1].isSelected()): - selected = 3 + if item == children[1]: + delta = -1 + segmentOn = 0 + else: + delta = 1 + segmentOn = 3 - firstSibling = self._contour[pointIndex + selected - 2] - secondSibling = self._contour[pointIndex + (selected - 2) * 2] + firstSibling = self._contour.getPoint(pointIndex + delta) + secondSibling = self._contour.getPoint(pointIndex + delta * 2) if (firstSibling.segmentType is None and secondSibling.segmentType is None): # we have two offCurves, wipe them + self._contour.getPoint(pointIndex + segmentOn).segmentType = "line" self._contour.removePoint(firstSibling) self._contour.removePoint(secondSibling) - def _CPMoved(self, newValue): + def _CPMoved(self, item, newValue): pointIndex = self.getPointIndex() children = self.childItems() # nodes are stored after lines (for stacking order) - if children[1].isSelected(): + if item == children[1]: selected = 1 propagate = 3 else: @@ -806,8 +876,8 @@ class OnCurvePointItem(QGraphicsPathItem): if not len(children) > 4: elemIndex = pointIndex - 2 + selected - self._contour[elemIndex].x = self.pos().x() + newValue.x() - self._contour[elemIndex].y = self.pos().y() + newValue.y() + self._contour.getPoint(elemIndex).x = self.pos().x() + newValue.x() + self._contour.getPoint(elemIndex).y = self.pos().y() + newValue.y() if not (self._isSmooth and children[propagate].isVisible()): self.setShallowDirty() return @@ -829,11 +899,21 @@ class OnCurvePointItem(QGraphicsPathItem): children[propagate].setFlag(QGraphicsItem.ItemSendsGeometryChanges) children[propagate - 1].setLine(line.x1(), line.y1(), tmpLine.x2(), tmpLine.y2()) - propagateInContour = pointIndex - 2 + propagate - self._contour[propagateInContour].x = self.pos().x() + tmpLine.x2() - self._contour[propagateInContour].y = self.pos().y() + tmpLine.y2() + propagateIn = pointIndex - 2 + propagate + self._contour.getPoint(propagateIn).x = self.pos().x() + tmpLine.x2() + self._contour.getPoint(propagateIn).y = self.pos().y() + tmpLine.y2() self.setShallowDirty() + def _CPSelected(self, item, value): + pointIndex = self.getPointIndex() + children = self.childItems() + if item == children[1]: + delta = -1 + else: + delta = 1 + + self._contour[pointIndex + delta].selected = value + def itemChange(self, change, value): if change == QGraphicsItem.ItemPositionChange: if self.scene()._integerPlane: @@ -848,12 +928,14 @@ class OnCurvePointItem(QGraphicsPathItem): children = self.childItems() if children[1].isVisible(): prevPos = children[1].pos() - self._contour[pointIndex - 1].x = self.pos().x() + prevPos.x() - self._contour[pointIndex - 1].y = self.pos().y() + prevPos.y() + point = self._contour.getPoint(pointIndex - 1) + point.x = self.pos().x() + prevPos.x() + point.y = self.pos().y() + prevPos.y() if children[3].isVisible(): nextPos = children[3].pos() - self._contour[pointIndex + 1].x = self.pos().x() + nextPos.x() - self._contour[pointIndex + 1].y = self.pos().y() + nextPos.y() + point = self._contour.getPoint(pointIndex + 1) + point.x = self.pos().x() + nextPos.x() + point.y = self.pos().y() + nextPos.y() self.setShallowDirty() elif change == QGraphicsItem.ItemSelectedHasChanged: self._point.selected = value @@ -886,11 +968,11 @@ class OnCurvePointItem(QGraphicsPathItem): scene = self.scene() scene._blocked = True # if we have line segment, insert offCurve points - insertIndex = (ptIndex + (i - 1) // 2) % len(self._contour) - if self._contour[insertIndex].segmentType == "line": - nextToCP = self._contour[(ptIndex - 2 + i) % len(self._contour)] + insertIndex = ptIndex + (i - 1) // 2 + if self._contour.getPoint(insertIndex).segmentType == "line": + nextToCP = self._contour.getPoint(ptIndex - 2 + i) assert(nextToCP.segmentType is not None) - self._contour[insertIndex].segmentType = "curve" + self._contour.getPoint(insertIndex).segmentType = "curve" if i == 1: first, second = ( self._point.x, self._point.y), (nextToCP.x, nextToCP.y) @@ -2179,14 +2261,13 @@ class GlyphView(QGraphicsView): def updateActiveLayerPath(self): self.updateLayerPath( self._layer, representationKey="defconQt.NoComponentsQPainterPath") + self.addStartPoints() def updateLayerPath(self, layer, representationKey="defconQt.QPainterPath"): glyph = layer[self._name] - # scene = self.scene() # unused path = glyph.getRepresentation(representationKey) self._sceneItems[layer].setPath(path) - self.addStartPoints() def _getSceneItems(self, key, clear=False): items = self._sceneItems.get(key, None) @@ -2315,6 +2396,34 @@ class GlyphView(QGraphicsView): component.baseGlyph = newGlyph.name self._glyph.appendComponent(component) + def layerActions(self): + newLayer, action, ok = LayerActionsDialog.getLayerAndAction( + self, self._glyph) + if ok and newLayer is not None: + # TODO: whole glyph for now, but consider selection too + if not self._glyph.name in newLayer: + newLayer.newGlyph(self._glyph.name) + otherGlyph = newLayer[self._glyph.name] + otherGlyph.disableNotifications() + if action == "Swap": + tempGlyph = TGlyph() + otherGlyph.drawPoints(tempGlyph.getPointPen()) + tempGlyph.width = otherGlyph.width + otherGlyph.clearContours() + self._glyph.drawPoints(otherGlyph.getPointPen()) + otherGlyph.width = self._glyph.width + if action != "Copy": + self._glyph.disableNotifications() + self._glyph.clearContours() + # XXX: we shouldn't have to do this manually but it seems there + # is a timing problem + self._glyph.destroyAllRepresentations() + if action == "Swap": + tempGlyph.drawPoints(self._glyph.getPointPen()) + self._glyph.width = tempGlyph.width + self._glyph.enableNotifications() + otherGlyph.enableNotifications() + def _makeLayerGlyph(self, layer): name = self._name glyph = layer.newGlyph(name) diff --git a/Lib/defconQt/objects/defcon.py b/Lib/defconQt/objects/defcon.py index 496f1c6..bb1336b 100644 --- a/Lib/defconQt/objects/defcon.py +++ b/Lib/defconQt/objects/defcon.py @@ -93,6 +93,9 @@ class TContour(Contour): selected=point.selected) pointPen.endPath() + def getPoint(self, index): + return self[index % len(self)] + class TPoint(Point): __slots__ = ["_selected"] |
