diff python/other/diagramitems.py @ 390:b77f3290ac79

Added diagram editor tests
author Windel Bouwman
date Fri, 16 May 2014 10:12:16 +0200
parents 534b94b40aa8
children bb4289c84907
line wrap: on
line diff
--- a/python/other/diagramitems.py	Fri May 02 14:51:46 2014 +0200
+++ b/python/other/diagramitems.py	Fri May 16 10:12:16 2014 +0200
@@ -2,43 +2,55 @@
  Contains all blocks that can be used to build models.
 """
 
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+import sys
+import json
+import base64
+import os
+
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'ide'))
+
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon
+from qtwrapper import abspath, Qt
+
 
 def uniqify(name, names):
-   newname, i = name, 1
-   while newname in names: newname, i = name + str(i), i + 1
-   return newname
+    newname, i = name, 1
+    while newname in names: newname, i = name + str(i), i + 1
+    return newname
+
 
 def enum(**enums):
-   return type('Enum', (), enums)
+    return type('Enum', (), enums)
+
 
 Position = enum(TOP=0, TOP_RIGHT=1, RIGHT=2, BOTTOM_RIGHT=3, BOTTOM=4, BOTTOM_LEFT=5, LEFT=6, TOP_LEFT=7)
 
+
 def buildPath(pts):
-   path = QPainterPath(pts[0])
-   for pt in pts[1:]: path.lineTo(pt)
-   return path
+    path = QtGui.QPainterPath(pts[0])
+    for pt in pts[1:]: path.lineTo(pt)
+    return path
 
 def equalSpace(n, l, offset=15):
-   if n == 1:
-      return [l / 2]
-   elif n > 1:
-      return [offset + (l - offset*2)/(n - 1)*i for i in range(n)]
-   return []
+    if n == 1:
+        return [l / 2]
+    elif n > 1:
+        return [offset + (l - offset*2)/(n - 1)*i for i in range(n)]
+    return []
 
-class Connection(QGraphicsPathItem):
+
+class Connection(QtWidgets.QGraphicsPathItem):
    """ A connection between blocks """
    def __init__(self, fromPort=None, toPort=None):
       super(Connection, self).__init__()
       self.pos2 = self.fromPort = self.toPort = None
       self.setFlags(self.ItemIsSelectable | self.ItemClipsToShape)
-      pen = QPen(Qt.blue, 2, cap=Qt.RoundCap)
+      pen = QtGui.QPen(Qt.blue, 2, cap=Qt.RoundCap)
       self.setPen(pen)
-      self.arrowhead = QGraphicsPathItem(self)
+      self.arrowhead = QtGui.QGraphicsPathItem(self)
       self.arrowhead.setPath(buildPath([QPointF(0.0, 0.0), QPointF(-6.0, 10.0), QPointF(6.0, 10.0), QPointF(0.0, 0.0)]))
       self.arrowhead.setPen(pen)
-      self.arrowhead.setBrush(QBrush(pen.color()))
+      self.arrowhead.setBrush(QtGui.QBrush(pen.color()))
       self.vias = []
       self.setFromPort(fromPort)
       self.setToPort(toPort)
@@ -99,7 +111,7 @@
       scene = self.scene()
       vias = [pos1 + QPointF(20, 0)] + self.vias + [pos2 + QPointF(-20, 0)]
       if scene:
-         litem = QGraphicsLineItem()
+         litem = QtGui.QGraphicsLineItem()
          litem.setFlags(self.ItemIsSelectable)
          scene.addItem(litem)
          for p1, p2 in zip(vias[:-1], vias[1:]):
@@ -115,19 +127,19 @@
       self.setPath(p)
       """ Create a shape outline using the path stroker """
       s = super(Connection, self).shape()
-      pps = QPainterPathStroker()
+      pps = QtGui.QPainterPathStroker()
       pps.setWidth(10)
       self.myshape = pps.createStroke(s).simplified()
 
-class PortItem(QGraphicsPathItem):
+class PortItem(QtWidgets.QGraphicsPathItem):
    """ Represents a port to a subsystem """
    def __init__(self, name, block):
       super(PortItem, self).__init__(block)
-      self.textItem = QGraphicsTextItem(self)
+      self.textItem = QtGui.QGraphicsTextItem(self)
       self.connection = None
       self.block = block
-      self.setCursor(QCursor(Qt.CrossCursor))
-      self.setPen(QPen(Qt.blue, 2, cap=Qt.RoundCap))
+      self.setCursor(QtGui.QCursor(Qt.CrossCursor))
+      self.setPen(QtGui.QPen(Qt.blue, 2, cap=Qt.RoundCap))
       self.name = name
       self.posCallbacks = []
       self.setFlag(self.ItemSendsScenePositionChanges, True)
@@ -160,15 +172,15 @@
       super(InputPort, self).__init__(name, block)
       self.setPath(buildPath([QPointF(-d, -d), QPointF(0, 0), QPointF(-d, d)]))
 
-class Handle(QGraphicsEllipseItem):
+class Handle(QtWidgets.QGraphicsEllipseItem):
    """ A handle that can be moved by the mouse """
    def __init__(self, dx=10.0, parent=None):
-      super(Handle, self).__init__(QRectF(-0.5*dx,-0.5*dx,dx,dx), parent)
-      self.setBrush(QBrush(Qt.white))
+      super(Handle, self).__init__(QtCore.QRectF(-0.5*dx,-0.5*dx,dx,dx), parent)
+      self.setBrush(QtGui.QBrush(Qt.white))
       self.setFlags(self.ItemIsMovable)
       self.setZValue(1)
       self.setVisible(False)
-      self.setCursor(QCursor(Qt.SizeFDiagCursor))
+      self.setCursor(QtGui.QCursor(Qt.SizeFDiagCursor))
    def mouseMoveEvent(self, event):
       """ Move function without moving the other selected elements """
       p = self.mapToParent(event.pos())
@@ -180,38 +192,38 @@
       self.position = position
       self.block = block
       if position in [Position.TOP_LEFT, Position.BOTTOM_RIGHT]:
-         self.setCursor(QCursor(Qt.SizeFDiagCursor))
+         self.setCursor(QtGui.QCursor(Qt.SizeFDiagCursor))
       elif position in [Position.TOP_RIGHT, Position.BOTTOM_LEFT]:
          self.setCursor(QCursor(Qt.SizeBDiagCursor))
       elif position in [Position.TOP, Position.BOTTOM]:
          self.setCursor(QCursor(Qt.SizeVerCursor))
       elif position in [Position.LEFT, Position.RIGHT]:
-         self.setCursor(QCursor(Qt.SizeHorCursor))
+         self.setCursor(QtGui.QCursor(Qt.SizeHorCursor))
    def mouseMoveEvent(self, event):
       self.block.sizerMoveEvent(self, event.scenePos())
 
-class Block(QGraphicsRectItem):
+class Block(QtWidgets.QGraphicsRectItem):
    """ Represents a block in the diagram. """
    def __init__(self, name='Untitled', parent=None):
       super(Block, self).__init__(parent)
       self.selectionHandles = [ResizeSelectionHandle(i, self) for i in range(8)]
       # Properties of the rectangle:
-      self.setPen(QPen(Qt.blue, 2))
-      self.setBrush(QBrush(Qt.lightGray))
+      self.setPen(QtGui.QPen(Qt.blue, 2))
+      self.setBrush(QtGui.QBrush(Qt.lightGray))
       self.setFlags(self.ItemIsSelectable | self.ItemIsMovable | self.ItemSendsScenePositionChanges)
-      self.setCursor(QCursor(Qt.PointingHandCursor))
+      self.setCursor(QtGui.QCursor(Qt.PointingHandCursor))
       self.setAcceptHoverEvents(True)
-      self.label = QGraphicsTextItem(name, self)
+      self.label = QtWidgets.QGraphicsTextItem(name, self)
       self.name = name
       # Create corner for resize:
-      button = QPushButton('+in')
+      button = QtWidgets.QPushButton('+in')
       button.clicked.connect(self.newInputPort)
-      self.buttonItemAddInput = QGraphicsProxyWidget(self)
+      self.buttonItemAddInput = QtWidgets.QGraphicsProxyWidget(self)
       self.buttonItemAddInput.setWidget(button)
       self.buttonItemAddInput.setVisible(False)
-      button = QPushButton('+out')
+      button = QtWidgets.QPushButton('+out')
       button.clicked.connect(self.newOutputPort)
-      self.buttonItemAddOutput = QGraphicsProxyWidget(self)
+      self.buttonItemAddOutput = QtWidgets.QGraphicsProxyWidget(self)
       self.buttonItemAddOutput.setWidget(button)
       self.buttonItemAddOutput.setVisible(False)
       # Inputs and outputs of the block:
@@ -329,18 +341,22 @@
       self.label.setPos((w - rect.width()) / 2, (h - rect.height()) / 2)
       self.updateSize()
 
+
 class CodeBlock(Block):
-   def __init__(self, name='Untitled', parent=None):
-      super(CodeBlock, self).__init__(name, parent)
-      self.code = ''
-   def setDict(self, d):
-      super(CodeBlock, self).setDict(d)
-      self.code = d['code']
-   def getDict(self):
-      d = super(CodeBlock, self).getDict()
-      d['code'] = self.code
-      return d
-   def gencode(self):
+    def __init__(self, name='Untitled', parent=None):
+        super(CodeBlock, self).__init__(name, parent)
+        self.code = ''
+
+    def setDict(self, d):
+        super(CodeBlock, self).setDict(d)
+        self.code = d['code']
+
+    def getDict(self):
+        d = super(CodeBlock, self).getDict()
+        d['code'] = self.code
+        return d
+
+    def gencode(self):
       c = ['def {0}():'.format(self.name)]
       if self.code:
          c += indent(self.code.split('\n'))
@@ -348,14 +364,17 @@
          c += indent(['pass'])
       return c
 
+
 class DiagramBlock(Block):
-   def __init__(self, name='Untitled', parent=None):
+    def __init__(self, name='Untitled', parent=None):
       super(DiagramBlock, self).__init__(name, parent)
       self.subModel = DiagramScene()
       self.subModel.containingBlock = self
-   def setDict(self, d):
-      self.subModel.Dict = d['submodel']
-   def mouseDoubleClickEvent(self, event):
+
+    def setDict(self, d):
+        self.subModel.Dict = d['submodel']
+
+    def mouseDoubleClickEvent(self, event):
       # descent into child diagram
       #self.editParameters()
       print('descent')
@@ -365,7 +384,8 @@
             view.diagram = self.subModel
             view.zoomAll()
 
-class DiagramScene(QGraphicsScene):
+
+class DiagramScene(QtWidgets.QGraphicsScene):
    """ A diagram scene consisting of blocks and connections """
    structureChanged = pyqtSignal()
    def __init__(self):