Mercurial > lcfOS
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):