diff python/apps/diagramitems.py @ 90:499183b99c71

Fixed handles to block
author windel
date Wed, 28 Nov 2012 08:41:56 +0100
parents 4b1892054744
children 7ad4c66dd092
line wrap: on
line diff
--- a/python/apps/diagramitems.py	Tue Nov 27 18:11:39 2012 +0100
+++ b/python/apps/diagramitems.py	Wed Nov 28 08:41:56 2012 +0100
@@ -154,27 +154,21 @@
    """ 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.posChangeCallbacks = []
       self.setBrush(QBrush(Qt.white))
-      self.setFlags(self.ItemSendsScenePositionChanges | self.ItemIsMovable)
+      self.setFlags(self.ItemIsMovable)
+      self.setZValue(1)
       self.setVisible(False)
       self.setCursor(QCursor(Qt.SizeFDiagCursor))
    def mouseMoveEvent(self, event):
       """ Move function without moving the other selected elements """
       p = self.mapToParent(event.pos())
       self.setPos(p)
-   def itemChange(self, change, value):
-      if change == self.ItemPositionChange:
-         for cb in self.posChangeCallbacks:
-            res = cb(value)
-            if res: value = res
-         return value
-      return super(Handle, self).itemChange(change, value)
 
 class ResizeSelectionHandle(Handle):
-   def __init__(self, position):
-      super(ResizeSelectionHandle, self).__init__()
+   def __init__(self, position, block):
+      super(ResizeSelectionHandle, self).__init__(dx=6, parent=block)
       self.position = position
+      self.block = block
       if position in [Position.TOP_LEFT, Position.BOTTOM_RIGHT]:
          self.setCursor(QCursor(Qt.SizeFDiagCursor))
       elif position in [Position.TOP_RIGHT, Position.BOTTOM_LEFT]:
@@ -184,14 +178,13 @@
       elif position in [Position.LEFT, Position.RIGHT]:
          self.setCursor(QCursor(Qt.SizeHorCursor))
    def mouseMoveEvent(self, event):
-      self.scene().sizerMoveEvent(self, event.scenePos())
+      self.block.sizerMoveEvent(self, event.scenePos())
 
 class Block(QGraphicsRectItem):
    """ Represents a block in the diagram """
    def __init__(self, name='Untitled', parent=None):
       super(Block, self).__init__(parent)
-      self.subModel = DiagramScene()
-      self.subModel.containingBlock = self
+      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))
@@ -199,7 +192,6 @@
       self.setCursor(QCursor(Qt.PointingHandCursor))
       self.label = QGraphicsTextItem(name, self)
       self.name = name
-      self.code = ''
       # Create corner for resize:
       button = QPushButton('+in')
       button.clicked.connect(self.newInputPort)
@@ -244,20 +236,11 @@
       return d
    def setDict(self, d):
       self.name = d['name']
-      self.code = d['code']
       self.setPos(d['x'], d['y'])
       self.changeSize(d['width'], d['height'])
       for inp in d['inputs']: self.addInput(InputPort(inp['name'], self))
       for outp in d['outputs']: self.addOutput(OutputPort(outp['name'], self))
-      self.subModel.Dict = d['submodel']
    Dict = property(getDict, setDict)
-   def gencode(self):
-      c = ['def {0}():'.format(self.name)]
-      if self.code:
-         c += indent(self.code.split('\n'))
-      else:
-         c += indent(['pass'])
-      return c
    def addInput(self, i):
       self.inputs.append(i)
       self.updateSize()
@@ -273,11 +256,42 @@
       if change == self.ItemSelectedHasChanged:
          for child in [self.buttonItemAddInput, self.buttonItemAddOutput]:
             child.setVisible(value)
+         if value:
+            self.repositionAndShowHandles()
+         else:
+            [h.setVisible(False) for h in self.selectionHandles]
+
       return super(Block, self).itemChange(change, value)
    def myDelete(self):
       for p in self.inputs + self.outputs:
          if p.connection: p.connection.myDelete()
       self.scene().removeItem(self)
+   def repositionAndShowHandles(self):
+         r = self.rect()
+         self.selectionHandles[Position.TOP_LEFT].setPos(r.topLeft())
+         self.selectionHandles[Position.TOP].setPos(r.center().x(), r.top())
+         self.selectionHandles[Position.TOP_RIGHT].setPos(r.topRight())
+         self.selectionHandles[Position.RIGHT].setPos(r.right(), r.center().y())
+         self.selectionHandles[Position.BOTTOM_RIGHT].setPos(r.bottomRight())
+         self.selectionHandles[Position.BOTTOM].setPos(r.center().x(), r.bottom())
+         self.selectionHandles[Position.BOTTOM_LEFT].setPos(r.bottomLeft())
+         self.selectionHandles[Position.LEFT].setPos(r.left(), r.center().y())
+         for h in self.selectionHandles:
+            h.setVisible(True)
+   def sizerMoveEvent(self, handle, pos):
+      r = self.rect().translated(self.pos())
+      if handle.position == Position.TOP_LEFT: r.setTopLeft(pos)
+      elif handle.position == Position.TOP: r.setTop(pos.y())
+      elif handle.position == Position.TOP_RIGHT: r.setTopRight(pos)
+      elif handle.position == Position.RIGHT: r.setRight(pos.x())
+      elif handle.position == Position.BOTTOM_RIGHT: r.setBottomRight(pos)
+      elif handle.position == Position.BOTTOM: r.setBottom(pos.y())
+      elif handle.position == Position.BOTTOM_LEFT: r.setBottomLeft(pos)
+      elif handle.position == Position.LEFT: r.setLeft(pos.x())
+      else:
+         print('invalid position')
+      self.setCenterAndSize(r.center(), r.size())
+      self.repositionAndShowHandles()
    def updateSize(self):
       rect = self.rect()
       h, w = rect.height(), rect.width()
@@ -299,55 +313,32 @@
       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):
+      self.code = d['code']
+   def gencode(self):
+      c = ['def {0}():'.format(self.name)]
+      if self.code:
+         c += indent(self.code.split('\n'))
+      else:
+         c += indent(['pass'])
+      return c
+
+class DiagramBlock(Block):
+   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']
+
 class DiagramScene(QGraphicsScene):
    def __init__(self):
       super(DiagramScene, self).__init__()
       self.startedConnection = None
-      self.selectionHandles = [ResizeSelectionHandle(i) for i in range(8)]
-      for h in self.selectionHandles:
-         self.addItem(h)
-         h.setVisible(False)
-      self.selectionChanged.connect(self.handleSelectionChanged)
-   def repositionAndShowHandles(self):
-         r = self.selectionRect
-         self.selectionHandles[Position.TOP_LEFT].setPos(r.topLeft())
-         self.selectionHandles[Position.TOP].setPos(r.center().x(), r.top())
-         self.selectionHandles[Position.TOP_RIGHT].setPos(r.topRight())
-         self.selectionHandles[Position.RIGHT].setPos(r.right(), r.center().y())
-         self.selectionHandles[Position.BOTTOM_RIGHT].setPos(r.bottomRight())
-         self.selectionHandles[Position.BOTTOM].setPos(r.center().x(), r.bottom())
-         self.selectionHandles[Position.BOTTOM_LEFT].setPos(r.bottomLeft())
-         self.selectionHandles[Position.LEFT].setPos(r.left(), r.center().y())
-         for h in self.selectionHandles:
-            h.setVisible(True)
-   def handleSelectionChanged(self):
-      [h.setVisible(False) for h in self.selectionHandles]
-      items = self.selectedItems()
-      items = [i for i in items if type(i) is Block]
-      if items:
-         r = QRectF()
-         for i in items:
-            r = r.united(i.boundingRect().translated(i.scenePos()))
-         self.selectionRect = r
-         self.repositionAndShowHandles()
-   def sizerMoveEvent(self, handle, pos):
-      if handle.position == Position.TOP_LEFT: self.selectionRect.setTopLeft(pos)
-      elif handle.position == Position.TOP: self.selectionRect.setTop(pos.y())
-      elif handle.position == Position.TOP_RIGHT: self.selectionRect.setTopRight(pos)
-      elif handle.position == Position.RIGHT: self.selectionRect.setRight(pos.x())
-      elif handle.position == Position.BOTTOM_RIGHT: self.selectionRect.setBottomRight(pos)
-      elif handle.position == Position.BOTTOM: self.selectionRect.setBottom(pos.y())
-      elif handle.position == Position.BOTTOM_LEFT: self.selectionRect.setBottomLeft(pos)
-      elif handle.position == Position.LEFT: self.selectionRect.setLeft(pos.x())
-      else:
-         print('invalid position')
-      self.repositionAndShowHandles()
-      items = self.selectedItems()
-      items = [i for i in items if type(i) is Block]
-      if items:
-         item = items[0]
-         # TODO resize more items!
-         item.setCenterAndSize(self.selectionRect.center(), self.selectionRect.size())
 
    blocks = property(lambda sel: [i for i in sel.items() if type(i) is Block])
    connections = property(lambda sel: [i for i in sel.items() if type(i) is Connection])