diff applications/lab/diagrameditor.py @ 56:7a82f0d52e85

Cleanup of line selection
author windel
date Sun, 22 Apr 2012 13:32:09 +0200
parents 9414bad225a8
children 143ab220aa27
line wrap: on
line diff
--- a/applications/lab/diagrameditor.py	Thu Apr 19 18:16:34 2012 +0200
+++ b/applications/lab/diagrameditor.py	Sun Apr 22 13:32:09 2012 +0200
@@ -5,7 +5,7 @@
 import sys
 import xml.dom.minidom as md
 
-""" 
+"""
  Author: Windel Bouwman
  Year: 2012
  Description: This script implements a diagram editor.
@@ -25,16 +25,6 @@
       self.setPen(pen)
       self.setBrush(QBrush(pen.color()))
 
-class LinePart(QGraphicsLineItem):
-   def __init__(self, x1, y1, x2, y2):
-      super(LinePart, self).__init__(x1, y1, x2, y2)
-      self.setFlags(self.ItemIsSelectable)
-   def boundingRect(self):
-      rect = super(LinePart, self).boundingRect()
-      rect.adjust(-2, -2, 2, 2)
-      return rect
-
-#class Connection(QGraphicsItemGroup):
 class Connection(QGraphicsPathItem):
    """ Implementation of a connection between blocks """
    def __init__(self, fromPort, toPort):
@@ -43,18 +33,12 @@
       self.pos2 = None
       self.fromPort = None
       self.toPort = None
-      #self.setFlags(self.ItemIsSelectable | self.ItemIsMovable)
       self.setFlag(self.ItemIsSelectable, True)
       self.setFlag(self.ItemClipsToShape, True)
       self.pen = QPen(Qt.blue, 2)
       self.pen.setCapStyle(Qt.RoundCap)
       self.setPen(self.pen)
       self.arrowhead = ArrowHead(self)
-      #self.addToGroup(self.arrowhead)
-      #self.body = QGraphicsPathItem(self)
-      #self.body.setPen(self.pen)
-      #self.addToGroup(self.body)
-      self.lineItems = []
       self.setFromPort(fromPort)
       self.setToPort(toPort)
    def setFromPort(self, fromPort):
@@ -88,6 +72,12 @@
       if change == self.ItemSelectedHasChanged:
          pass # TODO, do something useful here.
       return super(Connection, self).itemChange(change, value)
+   def shape(self):
+      """ Create a shape outline using the path stroker """
+      s = super(Connection, self).shape()
+      pps = QPainterPathStroker()
+      pps.setWidth(10)
+      return pps.createStroke(s).simplified()
    def updateLineStukken(self):
       """
          This algorithm determines the optimal routing of all signals.
@@ -97,7 +87,6 @@
          return
 
       # TODO: do not get the scene here?
-      # TODO: create pieces of lines.
 
       # Determine the begin and end positions:
       pts = editor.diagramScene.vias(self.pos1, self.pos2)
@@ -108,31 +97,10 @@
       else:
          self.arrowhead.setRotation(90)
 
-      usePath = True
-      if usePath:
-         path = QPainterPath(pts[0])
-         # Now move from p2 to p3 without hitting blocks:
-         for pt in pts[1:]:
-            path.lineTo(pt)
-         for pt in reversed(pts[0:-1]):
-            path.lineTo(pt)
-         path.closeSubpath()
-
-         #self.body.setPath(path)
-         self.setPath(path)
-         #outline = QGraphicsPathItem(self.shape())
-         #editor.diagramScene.addItem(outline)
-      else:
-         # Delete old line items:
-         for li in self.lineItems:
-            editor.diagramScene.removeItem(li)
-            #self.removeFromGroup(li)
-         self.lineItems = []
-         for a, b in zip(pts[0:-1], pts[1:]):
-            li = LinePart(a.x(),a.y(),b.x(),b.y())
-            #self.addToGroup(li)
-            editor.diagramScene.addItem(li)
-            self.lineItems.append(li)
+      path = QPainterPath(pts[0])
+      for pt in pts[1:]:
+         path.lineTo(pt)
+      self.setPath(path)
 
 class ParameterDialog(QDialog):
    def __init__(self, block, parent = None):
@@ -148,6 +116,7 @@
    def OK(self):
       self.block.setName(self.nameEdit.text())
       self.close()
+
 # TODO: merge dialogs?
 
 class AddPortDialog(QDialog):
@@ -171,16 +140,14 @@
    """ Represents a port to a subsystem """
    def __init__(self, name, block, direction):
       super(PortItem, self).__init__(block)
-      #QRectF(-6,-6,12.0,12.0)
       self.connection = None
       path = QPainterPath()
+      d = 10.0
       if direction == 'input':
-         d = 5.0
          path.moveTo(-d, -d)
          path.lineTo(0.0, 0.0)
          path.lineTo(-d, d)
       else:
-         d = 5.0
          path.moveTo(0.0, -d)
          path.lineTo(d, 0.0)
          path.lineTo(0.0, d)
@@ -188,8 +155,9 @@
       self.direction = direction
       self.block = block
       self.setCursor(QCursor(Qt.CrossCursor))
-      #self.setBrush(QBrush(Qt.red))
-      self.setPen(QPen(Qt.blue, 2))
+      pen = QPen(Qt.blue, 2)
+      pen.setCapStyle(Qt.RoundCap)
+      self.setPen(pen)
       self.name = name
       self.textItem = QGraphicsTextItem(name, self)
       self.setName(name)
@@ -218,7 +186,7 @@
       return super(PortItem, self).itemChange(change, value)
    def mousePressEvent(self, event):
       if self.direction == 'output':
-         editor.startConnection(self)
+         editor.diagramScene.startConnection(self)
 
 class OutputPort(PortItem):
    # TODO: create a subclass OR make a member porttype
@@ -228,7 +196,7 @@
 class HandleItem(QGraphicsEllipseItem):
    """ A handle that can be moved by the mouse """
    def __init__(self, parent=None):
-      dx = 12.0
+      dx = 9.0
       super(HandleItem, self).__init__(QRectF(-0.5*dx,-0.5*dx,dx,dx), parent)
       self.posChangeCallbacks = []
       self.setBrush(QBrush(Qt.white))
@@ -392,8 +360,7 @@
    """ Save and load and deletion of item"""
    def __init__(self, parent=None):
       super(DiagramScene, self).__init__(parent)
-      #circle = QGraphicsEllipseItem(-10,-10,20,20)
-      #self.addItem(circle)
+      self.startedConnection = None
 
    def saveDiagram(self, filename):
       items = self.items()
@@ -484,12 +451,33 @@
          for port in block.inputs + block.outputs:
             if port.name == portname:
                return port
-   def mouseMoveEvent(self, mouseEvent):
-      editor.sceneMouseMoveEvent(mouseEvent)
-      super(DiagramScene, self).mouseMoveEvent(mouseEvent)
-   def mouseReleaseEvent(self, mouseEvent):
-      editor.sceneMouseReleaseEvent(mouseEvent)
-      super(DiagramScene, self).mouseReleaseEvent(mouseEvent)
+   def mouseMoveEvent(self, event):
+      if self.startedConnection:
+         pos = event.scenePos()
+         items = self.items(pos)
+         for item in items:
+            if type(item) is PortItem:
+               pen = item.pen()
+               pen.setColor(Qt.red)
+               item.setPen(pen)
+         self.startedConnection.setEndPos(pos)
+      super(DiagramScene, self).mouseMoveEvent(event)
+   def mouseReleaseEvent(self, event):
+      if self.startedConnection:
+         items = self.items(event.scenePos())
+         for item in items:
+            if type(item) is PortItem:
+               self.startedConnection.setToPort(item)
+               self.startedConnection = None
+               return
+         self.deleteItem(self.startedConnection)
+         self.startedConnection = None
+      super(DiagramScene, self).mouseReleaseEvent(event)
+   def startConnection(self, port):
+      self.startedConnection = Connection(port, None)
+      pos = port.scenePos()
+      self.startedConnection.setEndPos(pos)
+      self.addItem(self.startedConnection)
    def vias(self, P1, P2):
       """ Constructs a list of points that must be connected
           to go from P1 to P2 """
@@ -585,7 +573,6 @@
       self.horizontalLayout.addWidget(self.libraryBrowserView)
       self.horizontalLayout.addWidget(self.diagramView)
 
-      self.startedConnection = None
       fullScreenShortcut = QShortcut(QKeySequence("F11"), self)
       fullScreenShortcut.activated.connect(self.toggleFullScreen)
       saveShortcut = QShortcut(QKeySequence(QKeySequence.Save), self)
@@ -604,30 +591,10 @@
       self.diagramScene.saveDiagram('diagram2.usd')
    def toggleFullScreen(self):
       self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
-   def startConnection(self, port):
-      self.startedConnection = Connection(port, None)
-      pos = port.scenePos()
-      self.startedConnection.setEndPos(pos)
-      self.diagramScene.addItem(self.startedConnection)
    def zoomAll(self):
       """ zoom to fit all items """
       rect = self.diagramScene.itemsBoundingRect()
       self.diagramView.fitInView(rect, Qt.KeepAspectRatio)
-   def sceneMouseMoveEvent(self, event):
-      if self.startedConnection:
-         pos = event.scenePos()
-         self.startedConnection.setEndPos(pos)
-   def sceneMouseReleaseEvent(self, event):
-      # Clear the actual connection:
-      if self.startedConnection:
-         items = self.diagramScene.items(event.scenePos())
-         for item in items:
-            if type(item) is PortItem:
-               self.startedConnection.setToPort(item)
-               self.startedConnection = None
-               return
-         self.diagramScene.deleteItem(self.startedConnection)
-         self.startedConnection = None
 
 if __name__ == '__main__':
    if sys.version_info.major != 3: