diff options
Diffstat (limited to 'Lib')
| -rw-r--r-- | Lib/defconQt/featureTextEditor.py | 3 | ||||
| -rw-r--r-- | Lib/defconQt/fontView.py | 30 | ||||
| -rw-r--r-- | Lib/defconQt/glyphView.py | 151 | ||||
| -rw-r--r-- | Lib/defconQt/layerSetList.py | 25 | ||||
| -rw-r--r-- | Lib/defconQt/representationFactories/__init__.py | 3 | ||||
| -rw-r--r-- | Lib/defconQt/representationFactories/glyphViewFactory.py | 125 | ||||
| -rw-r--r-- | Lib/defconQt/scriptingWindow.py | 1 |
7 files changed, 187 insertions, 151 deletions
diff --git a/Lib/defconQt/featureTextEditor.py b/Lib/defconQt/featureTextEditor.py index 5c5de76..b11947a 100644 --- a/Lib/defconQt/featureTextEditor.py +++ b/Lib/defconQt/featureTextEditor.py @@ -33,7 +33,8 @@ class MainEditWindow(QMainWindow): def closeEvent(self, event): if self.editor.document().isModified(): - closeDialog = QMessageBox(QMessageBox.Question, "Me", "Save your changes?", + name = QApplication.applicationName() + closeDialog = QMessageBox(QMessageBox.Question, name, "Save your changes?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel, self) closeDialog.setInformativeText("Your changes will be lost if you don’t save them.") closeDialog.setModal(True) diff --git a/Lib/defconQt/fontView.py b/Lib/defconQt/fontView.py index 001d2ea..15f4489 100644 --- a/Lib/defconQt/fontView.py +++ b/Lib/defconQt/fontView.py @@ -48,11 +48,13 @@ latinDefault = GlyphSet( "uni0327","quoteleft","quoteright","minus"],"Latin-default") class Application(QApplication): + currentFontChanged = pyqtSignal() currentGlyphChanged = pyqtSignal() def __init__(self, *args, **kwargs): super(Application, self).__init__(*args, **kwargs) self._currentGlyph = None + self._currentMainWindow = None def allFonts(self): fonts = [] @@ -62,7 +64,7 @@ class Application(QApplication): return fonts def currentFont(self): - return self.currentMainWindow._font + return self._currentMainWindow._font def currentGlyph(self): return self._currentGlyph @@ -72,6 +74,27 @@ class Application(QApplication): return self._currentGlyph = glyph self.currentGlyphChanged.emit() + # update currentMainWindow if we need to. + # XXX: find a way to update currentMainWindow when we switch to any + # child of a MainWindow instead of the MainWindow itself. + # Currently, what's below serves for the glyphView but should probably + # be expanded. + font = glyph.getParent() + if font != self.currentFont(): + for window in QApplication.topLevelWidgets(): + if isinstance(window, MainWindow): + if window._font == font: + self.setCurrentMainWindow(window) + break + + def currentMainWindow(self): + return self._currentMainWindow + + def setCurrentMainWindow(self, mainWindow): + if mainWindow == self._currentMainWindow: + return + self._currentMainWindow = mainWindow + self.currentFontChanged.emit() MAX_RECENT_FILES = 6 @@ -630,6 +653,7 @@ class MainWindow(QMainWindow): windowMenu = QMenu("&Windows", self) action = windowMenu.addAction("&Inspector", self.inspector, "Ctrl+I") + # XXX: we're getting duplicate shortcut when we spawn a new window... action.setShortcutContext(Qt.ApplicationShortcut) windowMenu.addAction("&Space center", self.spaceCenter, "Ctrl+Alt+S") windowMenu.addAction("&Groups window", self.fontGroups, "Ctrl+Alt+G") @@ -972,7 +996,7 @@ class MainWindow(QMainWindow): def event(self, event): if event.type() == QEvent.WindowActivate: app = QApplication.instance() - app.currentMainWindow = self + app.setCurrentMainWindow(self) lastSelectedGlyph = self.collectionWidget.lastSelectedGlyph() if lastSelectedGlyph is not None: app.setCurrentGlyph(lastSelectedGlyph) @@ -1051,6 +1075,8 @@ class MainWindow(QMainWindow): app.inspectorWindow = InspectorWindow() app.inspectorWindow.show() elif app.inspectorWindow.isVisible(): + # TODO: do this only if the widget is user-visible, otherwise the + # key press feels as if it did nothing # toggle app.inspectorWindow.close() else: diff --git a/Lib/defconQt/glyphView.py b/Lib/defconQt/glyphView.py index bd5779f..adebab3 100644 --- a/Lib/defconQt/glyphView.py +++ b/Lib/defconQt/glyphView.py @@ -543,6 +543,7 @@ smoothWidth = smoothHeight = roundPosition(onCurveSmoothPointSize)# * self._inve smoothHalf = smoothWidth / 2.0 onCurvePenWidth = 1.5 offCurvePenWidth = 1.0 +startItemDist = 10 anchorSize = 11 anchorWidth = anchorHeight = roundPosition(anchorSize) @@ -878,6 +879,44 @@ class OnCurvePointItem(QGraphicsPathItem): self.setPen(pen) super(OnCurvePointItem, self).paint(painter, newOption, widget) +class StartPointItem(QGraphicsPathItem): + def __init__(self, x, y, angle, scale=1, parent=None): + super(StartPointItem, self).__init__(parent) + self._angle = 360 - angle + + self.setPointPath(scale) + self.setPos(x, y) + self.setZValue(-996) + + 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 > 1.30: scale = 1.30 + elif scale < .6: scale = .6 + self.prepareGeometryChange() + dist = startItemDist / scale + path = QPainterPath() + line = QLineF(0, 0, 0+dist, 0) + line2 = QLineF(line) + line.setAngle(self._angle-90) + path.lineTo(line.x2(), line.y2()) + line2.setAngle(self._angle) + line2.translate(line.p2()-line.p1()) + path.lineTo(line2.x2(), line2.y2()) + line.setP1(line2.p2()) + line.setAngle(line.angle() - 27.5) + line.setLength(2*dist/5) + line2.setLength(line2.length() + .5) + path.moveTo(line.x2(), line.y2()) + path.lineTo(line2.x2(), line2.y2()) + line.setAngle(line.angle() + 55) + path.lineTo(line.x2(), line.y2()) + self.setPath(path) + class AnchorItem(QGraphicsPathItem): def __init__(self, anchor, scale=1, parent=None): super(AnchorItem, self).__init__(parent) @@ -1643,14 +1682,6 @@ class GlyphView(QGraphicsView): # will change during lifetime self._layer = glyph.layer - self._impliedPointSize = 1000 - self._pointSize = None - - # apparently unused code - self._inverseScale = 0.1 - self._scale = 10 - - self._noPointSizePadding = 200 self._drawStroke = True self._showOffCurvePoints = True self._showOnCurvePoints = True @@ -1766,7 +1797,7 @@ class GlyphView(QGraphicsView): item.setPos(self._glyph.width, item.y()) def activeGlyphChanged(self): - # For now, we'll assume not scene._blocked == moving UI points + # For now, we'll assume that scene._blocked == moving UI points # this will not be the case anymore when drag sidebearings pops up scene = self.scene() if scene._blocked: @@ -1963,6 +1994,7 @@ class GlyphView(QGraphicsView): # FIXME: don't like this scene._outlineItem = item self.addComponents() + self.addStartPoints() return item def updateActiveLayerPath(self): @@ -1973,6 +2005,7 @@ class GlyphView(QGraphicsView): scene = self.scene() path = glyph.getRepresentation(representationKey) self._sceneItems[layer].setPath(path) + self.addStartPoints() def _getSceneItems(self, key, clear=False): items = self._sceneItems.get(key, None) @@ -2015,79 +2048,45 @@ class GlyphView(QGraphicsView): anchors.append(item) scene.addItem(item) - def addPoints(self): + def addStartPoints(self): scene = self.scene() + startPointItems = self._getSceneItems('startPoints', clear=True) + startPointsData = self._glyph.getRepresentation("defconQt.StartPointsInformation") + path = QPainterPath() + for point, angle in startPointsData: + x, y = point + if angle is not None: + item = StartPointItem(x, y, angle, self.transform().m11()) + startPointItems.append(item) + scene.addItem(item) + def addPoints(self): + scene = self.scene() pointItems = self._getSceneItems('points', clear=True) - - # work out appropriate sizes and - # skip if the glyph is too small - pointSize = self._impliedPointSize - if pointSize > 550: - startPointSize = 21 - offCurvePointSize = 5 - onCurvePointSize = 6 - onCurveSmoothPointSize = 7 - elif pointSize > 250: - startPointSize = 15 - offCurvePointSize = 3 - onCurvePointSize = 4 - onCurveSmoothPointSize = 5 - elif pointSize > 175: - startPointSize = 9 - offCurvePointSize = 1 - onCurvePointSize = 2 - onCurveSmoothPointSize = 3 - else: - return # use the data from the outline representation outlineData = self._glyph.getRepresentation("defconQt.OutlineInformation") - points = [] # TODO: remove this unless we need it # useful for text drawing, add it - startObjects = [] scale = self.transform().m11() - if outlineData["onCurvePoints"]: - for onCurve in outlineData["onCurvePoints"]: - # on curve - x, y = onCurve.x, onCurve.y - points.append((x, y)) - item = OnCurvePointItem(x, y, onCurve.isSmooth, self._glyph[onCurve.contourIndex], - self._glyph[onCurve.contourIndex][onCurve.pointIndex], scale) - pointItems.append(item) - scene.addItem(item) - # off curve - for CP in [onCurve.prevCP, onCurve.nextCP]: - if CP: - cx, cy = CP - # line - lineObj = HandleLineItem(0, 0, cx-x, cy-y, item) - # point - points.append((cx, cy)) - CPObject = OffCurvePointItem(cx-x, cy-y, item) - else: - lineObj = HandleLineItem(0, 0, 0, 0, item) - #lineObj.setVisible(False) - CPObject = OffCurvePointItem(0, 0, item) - CPObject.setVisible(False) - ''' - # start point - if self._showOnCurvePoints and outlineData["startPoints"]: - startWidth = startHeight = roundPosition(startPointSize)# * self._inverseScale) - startHalf = startWidth / 2.0 - for point, angle in outlineData["startPoints"]: - x, y = point - # TODO: do we really need to special-case with Qt? - if angle is not None: - path = QPainterPath() - path.moveTo(x, y) - path.arcTo(x-startHalf, y-startHalf, 2*startHalf, 2*startHalf, angle-90, -180) - item = scene.addPath(path, QPen(Qt.NoPen), QBrush(self._startPointColor)) - startObjects.append(item) - #path.closeSubpath() + for onCurve in outlineData: + # on curve + x, y = onCurve.x, onCurve.y + item = OnCurvePointItem(x, y, onCurve.isSmooth, self._glyph[onCurve.contourIndex], + self._glyph[onCurve.contourIndex][onCurve.pointIndex], scale) + pointItems.append(item) + scene.addItem(item) + # off curve + for CP in [onCurve.prevCP, onCurve.nextCP]: + if CP: + cx, cy = CP + # line + lineObj = HandleLineItem(0, 0, cx-x, cy-y, item) + # point + CPObject = OffCurvePointItem(cx-x, cy-y, item) else: - item = scene.addEllipse(x-startHalf, y-startHalf, startWidth, startHeight, - QPen(Qt.NoPen), QBrush(self._startPointColor)) - startObjects.append(item) - #s.addPath(path, QPen(Qt.NoPen), brush=QBrush(self._startPointColor)) + lineObj = HandleLineItem(0, 0, 0, 0, item) + #lineObj.setVisible(False) + CPObject = OffCurvePointItem(0, 0, item) + CPObject.setVisible(False) + ''' # text if self._showPointCoordinates and coordinateSize: fontSize = 9 * self._inverseScale @@ -2215,5 +2214,5 @@ class GlyphView(QGraphicsView): if scale < 4: for item in self.scene().items(): if isinstance(item, (OnCurvePointItem, OffCurvePointItem, \ - ResizeHandleItem, AnchorItem)): + ResizeHandleItem, AnchorItem, StartPointItem)): item.setPointPath(scale) diff --git a/Lib/defconQt/layerSetList.py b/Lib/defconQt/layerSetList.py index b2d3c9f..485477b 100644 --- a/Lib/defconQt/layerSetList.py +++ b/Lib/defconQt/layerSetList.py @@ -1,15 +1,16 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QKeySequence, QColor, QPixmap, QIcon -from PyQt5.QtWidgets import QWidget, QMenu, QListWidget, QListWidgetItem, \ - QAbstractItemView, QVBoxLayout, QAction, QColorDialog +from PyQt5.QtWidgets import (QApplication, QWidget, QMenu, QListWidget, + QListWidgetItem, QAbstractItemView, QVBoxLayout, QAction, QColorDialog) from defconQt import icons_db from defconQt.glyphView import AddLayerDialog class LayerSetList(QListWidget): - def __init__(self, font, parent=None, *args, **kwds): - super().__init__(parent, *args, **kwds) + def __init__(self, parent=None, *args, **kwargs): + super().__init__(parent, *args, **kwargs) - self._layerSet = font.layers + app = QApplication.instance() + self._layerSet = app.currentFont().layers self.setDragDropMode(QAbstractItemView.InternalMove) @@ -45,13 +46,13 @@ class LayerSetList(QListWidget): self.addAction(action) self._layerSet.addObserver(self, '_update', 'LayerSet.Changed') - self._update() + app.currentFontChanged.connect(self.updateFont) + def _update(self, *args): index = self.currentRow() - while self.count(): - self.takeItem(self.count()-1) + self.clear() for i, layer in enumerate(self._layerSet): item = self._makeItem(layer) self.addItem(item) @@ -133,3 +134,11 @@ class LayerSetList(QListWidget): if not layer: return layer.color = None + + def updateFont(self): + if self._layerSet is not None: + self._layerSet.removeObserver(self, 'LayerSet.Changed') + currentFont = QApplication.instance().currentFont() + self._layerSet = currentFont.layers + self._layerSet.addObserver(self, '_update', 'LayerSet.Changed') + self._update() diff --git a/Lib/defconQt/representationFactories/__init__.py b/Lib/defconQt/representationFactories/__init__.py index 657b2c2..df13068 100644 --- a/Lib/defconQt/representationFactories/__init__.py +++ b/Lib/defconQt/representationFactories/__init__.py @@ -1,12 +1,13 @@ from defcon.objects.glyph import addRepresentationFactory
from defconQt.representationFactories.qPainterPathFactory import QPainterPathFactory
-from defconQt.representationFactories.glyphViewFactory import NoComponentsQPainterPathFactory, OnlyComponentsQPainterPathFactory, OutlineInformationFactory
+from defconQt.representationFactories.glyphViewFactory import NoComponentsQPainterPathFactory, OnlyComponentsQPainterPathFactory, OutlineInformationFactory, StartPointsInformationFactory
_factories = {
"defconQt.QPainterPath" : QPainterPathFactory,
"defconQt.OnlyComponentsQPainterPath" : OnlyComponentsQPainterPathFactory,
"defconQt.NoComponentsQPainterPath" : NoComponentsQPainterPathFactory,
"defconQt.OutlineInformation" : OutlineInformationFactory,
+ "defconQt.StartPointsInformation" : StartPointsInformationFactory,
}
def registerAllFactories():
diff --git a/Lib/defconQt/representationFactories/glyphViewFactory.py b/Lib/defconQt/representationFactories/glyphViewFactory.py index 8aeeadd..3edfe3b 100644 --- a/Lib/defconQt/representationFactories/glyphViewFactory.py +++ b/Lib/defconQt/representationFactories/glyphViewFactory.py @@ -59,6 +59,64 @@ class OnlyComponentsQtPen(BasePen): tPen = TransformPen(self.pen, transformation)
glyph.draw(tPen)
+# ------------
+# start points
+# ------------
+
+def StartPointsInformationFactory(glyph):
+ pen = StartPointsInformationPen()
+ glyph.drawPoints(pen)
+ return pen.getData()
+
+class StartPointsInformationPen(AbstractPointPen):
+ def __init__(self):
+ self._rawPointData = []
+
+ def getData(self):
+ data = []
+ for contour in self._rawPointData:
+ # TODO: UFO3 special-case anchors so presumably we don't need to do
+ # this anymore
+ # anchor
+ if len(contour) == 1 and contour[0]["name"] is not None:
+ pass
+ # points
+ else:
+ haveFirst = False
+ for pointIndex, point in enumerate(contour):
+ if not haveFirst:
+ haveFirst = True
+ nextOn = None
+ for nextPoint in contour[pointIndex:] + contour[:pointIndex]:
+ #if nextPoint["segmentType"] is None:
+ # continue
+ if nextPoint["point"] == point["point"]:
+ continue
+ nextOn = nextPoint
+ break
+ angle = None
+ if nextOn:
+ x1, y1 = point["point"]
+ x2, y2 = nextOn["point"]
+ xDiff = x2 - x1
+ yDiff = y2 - y1
+ angle = round(math.atan2(yDiff, xDiff) * 180 / math.pi, 3)
+ data.append((point["point"], angle))
+ return data
+
+ def beginPath(self):
+ self._rawPointData.append([])
+
+ def endPath(self):
+ pass
+
+ def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
+ d = dict(point=pt, segmentType=segmentType, smooth=smooth, name=name)
+ self._rawPointData[-1].append(d)
+
+ def addComponent(self, baseGlyphName, transformation):
+ pass
+
# ----------
# point data
# ----------
@@ -67,20 +125,17 @@ class OutlineInformationPen(AbstractPointPen): def __init__(self):
self._rawPointData = []
- self._rawComponentData = []
- self._bezierHandleData = []
self.cIndex = 0
self.index = 0
def getData(self):
- data = dict(startPoints=[], onCurvePoints=[], offCurvePoints=[], bezierHandles=[], anchors=[], components=self._rawComponentData)
+ data = []
CPoint = namedtuple('Point', ['x', 'y', 'contourIndex', 'pointIndex', 'isSmooth', 'isFirst', 'prevCP', 'nextCP'])
for contour in self._rawPointData:
# anchor
if len(contour) == 1 and contour[0]["name"] is not None:
- anchor = contour[0]
- data["anchors"].append(anchor)
+ pass
# points
else:
haveFirst = False
@@ -98,68 +153,13 @@ class OutlineInformationPen(AbstractPointPen): nextCP = forward["point"]
x, y = point["point"]
pt = CPoint(x, y, self.cIndex, self.index, point["smooth"], not haveFirst, prevCP, nextCP)
- data["onCurvePoints"].append(pt)
+ data.append(pt)
# catch first point
if not haveFirst:
haveFirst = True
- '''
- nextOn = None
- for nextPoint in contour[pointIndex:] + contour[:pointIndex]:
- #if nextPoint["segmentType"] is None:
- # continue
- if nextPoint["point"] == point["point"]:
- continue
- nextOn = nextPoint
- break
- angle = None
- if nextOn:
- x1, y1 = point["point"]
- x2, y2 = nextOn["point"]
- xDiff = x2 - x1
- yDiff = y2 - y1
- angle = round(math.atan2(yDiff, xDiff) * 180 / math.pi, 3)
- data["startPoints"].append((point["point"], angle))
- '''
- self.index += 1
- else:
- '''
- if back["segmentType"] is not None:
- onCurveNeighbor = back
- elif forward["segmentType"] is not None:
- onCurveNeighbor = forward
- else:
- print("Whoops")
- continue
- # QPainterPath elides no-op moveTo's, so do the same when indexing here
- if onCurveNeighbor["point"] == point["point"]:
- print("Skipped: {}".format(self.index))
- continue
- '''
self.index += 1
-
-
- '''
else:
- onCurveParent = self.index+1
- print("OffCurve")
- # look for handles
- # TODO: calculate this when drawing
- back = contour[pointIndex - 1]
- forward = contour[(pointIndex + 1) % len(contour)]
- if back["segmentType"] in ("curve", "line"):
- onCurveParent = self.index-1
- p1 = back["point"]
- p2 = point["point"]
- if p1 != p2:
- data["bezierHandles"].append((p1, p2, self.index, onCurveParent))
- elif forward["segmentType"] in ("curve", "line"):
- p1 = forward["point"]
- p2 = point["point"]
- if p1 != p2:
- data["bezierHandles"].append((p1, p2, self.index, onCurveParent))
- data["offCurvePoints"].append((point, self.index, onCurveParent))
self.index += 1
- '''
self.index = 0
self.cIndex += 1
return data
@@ -175,8 +175,7 @@ class OutlineInformationPen(AbstractPointPen): self._rawPointData[-1].append(d)
def addComponent(self, baseGlyphName, transformation):
- d = dict(baseGlyphName=baseGlyphName, transformation=transformation)
- self._rawComponentData.append((baseGlyphName, transformation))
+ pass
def OutlineInformationFactory(glyph):
diff --git a/Lib/defconQt/scriptingWindow.py b/Lib/defconQt/scriptingWindow.py index f48fd0a..38f70ab 100644 --- a/Lib/defconQt/scriptingWindow.py +++ b/Lib/defconQt/scriptingWindow.py @@ -31,6 +31,7 @@ class MainScriptingWindow(QMainWindow): "AllFonts": app.allFonts, "CurrentFont": app.currentFont, "CurrentGlyph": app.currentGlyph, + "rootHandle": self, } try: code = compile(script, "<string>", "exec") |
