aboutsummaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/defconQt/featureTextEditor.py3
-rw-r--r--Lib/defconQt/fontView.py30
-rw-r--r--Lib/defconQt/glyphView.py151
-rw-r--r--Lib/defconQt/layerSetList.py25
-rw-r--r--Lib/defconQt/representationFactories/__init__.py3
-rw-r--r--Lib/defconQt/representationFactories/glyphViewFactory.py125
-rw-r--r--Lib/defconQt/scriptingWindow.py1
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")