summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/asymptote/GUI/InplaceAddObj.py')
-rwxr-xr-xMaster/texmf-dist/asymptote/GUI/InplaceAddObj.py179
1 files changed, 147 insertions, 32 deletions
diff --git a/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py b/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py
index 132969dad19..9bacd5f51fe 100755
--- a/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py
+++ b/Master/texmf-dist/asymptote/GUI/InplaceAddObj.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-import PyQt5.QtCore as Qc
-import PyQt5.QtGui as Qg
-import xasy2asy as x2a
+import PyQt5.QtCore as QtCore
+import PyQt5.QtGui as QtGui
+import xasy2asy as xasy2asy
import PrimitiveShape
import math
@@ -11,9 +11,9 @@ import Widg_addPolyOpt
import Widg_addLabel
-class InplaceObjProcess(Qc.QObject):
- objectCreated = Qc.pyqtSignal(Qc.QObject)
- objectUpdated = Qc.pyqtSignal()
+class InplaceObjProcess(QtCore.QObject):
+ objectCreated = QtCore.pyqtSignal(QtCore.QObject)
+ objectUpdated = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
@@ -24,10 +24,10 @@ class InplaceObjProcess(Qc.QObject):
def active(self):
return self._active
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
raise NotImplementedError
- def mouseMove(self, pos, event: Qg.QMouseEvent):
+ def mouseMove(self, pos, event: QtGui.QMouseEvent):
raise NotImplementedError
def mouseRelease(self):
@@ -45,7 +45,7 @@ class InplaceObjProcess(Qc.QObject):
def getXasyObject(self):
raise NotImplementedError
- def postDrawPreview(self, canvas: Qg.QPainter):
+ def postDrawPreview(self, canvas: QtGui.QPainter):
pass
def createOptWidget(self, info):
@@ -55,10 +55,10 @@ class InplaceObjProcess(Qc.QObject):
class AddCircle(InplaceObjProcess):
def __init__(self, parent=None):
super().__init__(parent)
- self.center = Qc.QPointF(0, 0)
+ self.center = QtCore.QPointF(0, 0)
self.radius = 0
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
self.radius = 0
self.center.setX(x)
@@ -75,9 +75,9 @@ class AddCircle(InplaceObjProcess):
def getPreview(self):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.center)
- boundRect = Qc.QRectF(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius)
+ boundRect = QtCore.QRectF(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius)
# because the internal image is flipped...
- newPath = Qg.QPainterPath()
+ newPath = QtGui.QPainterPath()
newPath.addEllipse(boundRect)
# newPath.addRect(boundRect)
return newPath
@@ -87,9 +87,9 @@ class AddCircle(InplaceObjProcess):
def getXasyObject(self):
if self.fill:
- newObj = x2a.xasyFilledShape(self.getObject(), None)
+ newObj = xasy2asy.xasyFilledShape(self.getObject(), None)
else:
- newObj = x2a.xasyShape(self.getObject(), None)
+ newObj = xasy2asy.xasyShape(self.getObject(), None)
return newObj
def forceFinalize(self):
@@ -102,8 +102,9 @@ class AddLabel(InplaceObjProcess):
self.alignMode = None
self.opt = None
self.text = None
- self.anchor = Qc.QPointF(0, 0)
+ self.anchor = QtCore.QPointF(0, 0)
self._active = False
+ self.fontSize = 12
def createOptWidget(self, info):
self.opt = Widg_addLabel.Widg_addLabel(info)
@@ -121,7 +122,7 @@ class AddLabel(InplaceObjProcess):
self.anchor.setX(x)
self.anchor.setY(y)
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
if self.opt is not None:
self.text = self.opt.labelText
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
@@ -140,7 +141,7 @@ class AddLabel(InplaceObjProcess):
text = self.text
align = str(self.alignMode)
anchor = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.anchor)
- newLabel = x2a.xasyText(text=text, location=anchor, pen=None,
+ newLabel = xasy2asy.xasyText(text=text, location=anchor, pen=None,
align=align, asyengine=None, fontsize=self.fontSize)
newLabel.asyfied = False
return newLabel
@@ -164,11 +165,11 @@ class AddBezierShape(InplaceObjProcess):
# Linkmode should be to the last point.
# (x, y, linkmode), (u, v, lm2) <==> (x, y) <=lm2=> (u, v)
self.pointsList = []
- self.currentPoint = Qc.QPointF(0, 0)
+ self.currentPoint = QtCore.QPointF(0, 0)
self.pendingPoint = None
self.useLegacy = False
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
self.currentPoint.setX(x)
self.currentPoint.setY(y)
@@ -222,7 +223,7 @@ class AddBezierShape(InplaceObjProcess):
# self.updateBasePath()
def updateBasePath(self):
- self.basePath = x2a.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ self.basePath = xasy2asy.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase)
newNode = [(x, y) for x, y, _ in self.pointsList]
newLink = [lnk for *args, lnk in self.pointsList[1:]]
if self.useLegacy:
@@ -237,7 +238,7 @@ class AddBezierShape(InplaceObjProcess):
self.basePath.computeControls()
def updateBasePathPreview(self):
- self.basePathPreview = x2a.asyPath(
+ self.basePathPreview = xasy2asy.asyPath(
asyengine=self.asyengine, forceCurve=self.useBezierBase)
newNode = [(x, y) for x, y, _ in self.pointsList] + [(self.currentPoint.x(), self.currentPoint.y())]
newLink = [lnk for *args, lnk in self.pointsList[1:]] + [self._getLinkType()]
@@ -271,16 +272,16 @@ class AddBezierShape(InplaceObjProcess):
def getXasyObject(self):
if self.fill:
- return x2a.xasyFilledShape(self.getObject(), None)
+ return xasy2asy.xasyFilledShape(self.getObject(), None)
else:
- return x2a.xasyShape(self.getObject(), None)
+ return xasy2asy.xasyShape(self.getObject(), None)
class AddPoly(InplaceObjProcess):
def __init__(self, parent=None):
super().__init__(parent)
- self.center = Qc.QPointF(0, 0)
- self.currPos = Qc.QPointF(0, 0)
+ self.center = QtCore.QPointF(0, 0)
+ self.currPos = QtCore.QPointF(0, 0)
self.sides = None
self.inscribed = None
self.centermode = None
@@ -288,18 +289,18 @@ class AddPoly(InplaceObjProcess):
self.fill = None
self.opt = None
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
self._active = True
self.sides = info['sides']
self.inscribed = info['inscribed']
self.centermode = info['centermode']
self.fill = info['fill']
-
+
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
self.center.setX(x)
self.center.setY(y)
- self.currPos = Qc.QPointF(self.center)
+ self.currPos = QtCore.QPointF(self.center)
def mouseMove(self, pos, event):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
@@ -329,7 +330,7 @@ class AddPoly(InplaceObjProcess):
else:
poly = PrimitiveShape.PrimitiveShape.exscribedRegPolygon(self.sides, self.center, self._rad(),
self._angle(), qpoly=True)
- newPath = Qg.QPainterPath()
+ newPath = QtGui.QPainterPath()
newPath.addPolygon(poly)
return newPath
@@ -350,7 +351,121 @@ class AddPoly(InplaceObjProcess):
def getXasyObject(self):
if self.fill:
- newObj = x2a.xasyFilledShape(self.getObject(), None)
+ newObj = xasy2asy.xasyFilledShape(self.getObject(), None)
else:
- newObj = x2a.xasyShape(self.getObject(), None)
+ newObj = xasy2asy.xasyShape(self.getObject(), None)
return newObj
+
+class AddFreehand(InplaceObjProcess):
+ # TODO: At the moment this is just a copy-paste of the AddBezierObj.
+ # Must find a better algorithm for constructing the obj rather than
+ # a node for every pixel the mouse moves.
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.asyengine = None
+ self.basePath = None
+ self.basePathPreview = None
+ self.closedPath = None
+ self.info = None
+ self.fill = False
+ self.opt = None
+
+ # list of "committed" points with Linkage information.
+ # Linkmode should be to the last point.
+ # (x, y, linkmode), (u, v, lm2) <==> (x, y) <=lm2=> (u, v)
+ self.pointsList = []
+ self.currentPoint = QtCore.QPointF(0, 0)
+ self.pendingPoint = None
+ self.useLegacy = False
+
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.currentPoint.setX(x)
+ self.currentPoint.setY(y)
+ self.info = info
+
+ if not self._active:
+ self._active = True
+ self.fill = info['fill']
+ self.asyengine = info['asyengine']
+ self.closedPath = info['closedPath']
+ self.useBezierBase = info['useBezier']
+ self.useLegacy = self.info['options']['useLegacyDrawMode']
+ self.pointsList.clear()
+ self.pointsList.append((x, y, None))
+ else:
+ # see http://doc.qt.io/archives/qt-4.8/qt.html#MouseButton-enum
+ if (int(mouseEvent.buttons()) if mouseEvent is not None else 0) & 0x2 and self.useLegacy:
+ self.forceFinalize()
+
+ def _getLinkType(self):
+ if self.info['useBezier']:
+ return '..'
+ else:
+ return '--'
+
+ def mouseMove(self, pos, event):
+ # in postscript coords.
+ if self._active:
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+
+ if self.useLegacy or int(event.buttons()) != 0:
+ self.currentPoint.setX(x)
+ self.currentPoint.setY(y)
+ self.pointsList.append((x, y, self._getLinkType()))
+
+
+ def createOptWidget(self, info):
+ return None
+
+ def mouseRelease(self):
+ self.updateBasePath()
+ self._active = False
+ self.pointsList.clear()
+ self.objectCreated.emit(self.getXasyObject())
+ self.basePath = None
+
+ def updateBasePath(self):
+ self.basePath = xasy2asy.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ newNode = [(x, y) for x, y, _ in self.pointsList]
+ newLink = [lnk for *args, lnk in self.pointsList[1:]]
+ if self.useLegacy:
+ newNode += [(self.currentPoint.x(), self.currentPoint.y())]
+ newLink += [self._getLinkType()]
+ if self.closedPath:
+ newNode.append('cycle')
+ newLink.append(self._getLinkType())
+ self.basePath.initFromNodeList(newNode, newLink)
+
+ if self.useBezierBase:
+ self.basePath.computeControls()
+
+ def updateBasePathPreview(self):
+ self.basePathPreview = xasy2asy.asyPath(
+ asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ newNode = [(x, y) for x, y, _ in self.pointsList] + [(self.currentPoint.x(), self.currentPoint.y())]
+ newLink = [lnk for *args, lnk in self.pointsList[1:]] + [self._getLinkType()]
+ if self.closedPath:
+ newNode.append('cycle')
+ newLink.append(self._getLinkType())
+ self.basePathPreview.initFromNodeList(newNode, newLink)
+
+ if self.useBezierBase:
+ self.basePathPreview.computeControls()
+
+ def getObject(self):
+ if self.basePath is None:
+ raise RuntimeError('BasePath is None')
+ self.basePath.asyengine = self.asyengine
+ return self.basePath
+
+ def getPreview(self):
+ if self._active:
+ if self.pointsList:
+ self.updateBasePathPreview()
+ newPath = self.basePathPreview.toQPainterPath()
+ return newPath
+
+ def getXasyObject(self):
+ self.fill = False
+ return xasy2asy.xasyShape(self.getObject(), None)