Exemplo n.º 1
0
 def __init__(self,*args):
     super(ViewingWindow,self).__init__(*args)
     self.graph = BridgeConceptGraph()
     self.nodeSelected = SignalSlotObject()
     self.nodeUnselected = SignalSlotObject()
     self.cursor = Cursor()
     self.cursor.leftClick.connect(self.onLeftClick)
     self.cursor.leftHover.connect(self.onHover)
     self.cursor.leftDrag.connect(self.onLeftDrag)
     self.cursor.leftPress.connect(self.onLeftPress)
     self.cursor.leftRelease.connect(self.onLeftRelease)
     self.cursor.rightClick.connect(self.onRightClick)
     self.cursor.rightDrag.connect(self.onRightDrag)
     self.cursor.rightPress.connect(self.onRightPress)
     self.cursor.rightRelease.connect(self.onRightRelease)
     self.cursor.rightPull.connect(self.onRightPull)
     self.cursor.rightHover.connect(self.onHover)
     self.worldCursor = QPointF(0,0)
     self.leftClickB = False
     self.leftDragB = False
     self.HoverB = False
     self.leftPressB = False
     self.leftReleaseB = False
     self.rightClickB = False
     self.rightDragB = False
     self.rightPressB = False
     self.rightReleaseB = False
     self.rightPullB = False
     self.selectedNode = None
     self.heldNode = None
     self.hoverNode = None
     self.edgeDragNode = None
     self.fps = 30
     self.translation = QPointF(0.0,0.0)
     self.scale = 1.0
     self.minScale = 0.1
     self.maxScale = 10.0
     self.initUI()
Exemplo n.º 2
0
class Cursor():
    def __init__(self):
        self.x = 0
        self.y = 0
        self._px = 0
        self._py = 0
        self.resetPrevious = False
        self.leftDown = False
        self.rightDown = False
        self.middleDown = False
        self.leftClickOnRelease = False
        self.rightClickOnRelease = False
        self.middleClickOnRelease = False
        self.leftPullOnDrag = False
        self.rightPullOnDrag = False
        self.middlePullOnDrag = False
        self.leftPress = SignalSlotObject()
        self.rightPress = SignalSlotObject()
        self.middlePress = SignalSlotObject()
        self.leftClick = SignalSlotObject()
        self.rightClick = SignalSlotObject()
        self.middleClick = SignalSlotObject()
        self.leftRelease = SignalSlotObject()
        self.rightRelease = SignalSlotObject()
        self.middleRelease = SignalSlotObject()
        self.click = SignalSlotObject()
        self.leftHover = SignalSlotObject()
        self.rightHover = SignalSlotObject()
        self.middleHover = SignalSlotObject()
        self.hover = SignalSlotObject()
        self.leftDrag = SignalSlotObject()
        self.rightDrag = SignalSlotObject()
        self.middleDrag = SignalSlotObject()
        self.leftPull = SignalSlotObject()
        self.rightPull = SignalSlotObject()
        self.middlePull = SignalSlotObject()
        self.drag = SignalSlotObject()
        
    def setX(self,a):
        if (self.resetPrevious): self._px = self.x
        self.x = a

    def setY(self,a):
        if (self.resetPrevious): self._py = self.y
        self.y = a

    def setButtons(self,b):
        b = int(b)
        a = b % 2
        self.leftDown = (a == 1)
        b = (b - a) / 2
        a = b % 2
        self.rightDown = (a == 1)
        b = (b - a) / 2
        a = b % 2
        self.middleDown = (a == 1)

    def update(self,e,prm='o'):
        self.setX(e.x())
        self.setY(e.y())
        self.resetPrevious = False
        self.setButtons(e.buttons())
        
        if prm == 'p':
            if e.button() == Qt.LeftButton:
                self.leftClickOnRelease = True
                self.leftPullOnDrag = True
                self.leftPress.emit()
            elif e.button() == Qt.RightButton:
                self.rightClickOnRelease = True
                self.rightPullOnDrag = True
                self.rightPress.emit()
            elif e.button() == Qt.MiddleButton:
                self.middleClickOnRelease = True
                self.middlePullOnDrag = True
                self.middlePress.emit()
        elif prm == 'r':
            if e.button() == Qt.LeftButton:
                self.leftRelease.emit()
                self.leftPullOnDrag = False
                if self.leftClickOnRelease:
                    self.leftClick.emit()
                    self.click.emit()
            elif e.button() == Qt.RightButton:
                self.rightRelease.emit()
                self.rightPullOnDrag = False
                if self.rightClickOnRelease:
                    self.rightClick.emit()
                    self.click.emit()
            elif e.button() == Qt.MiddleButton:
                self.middleRelease.emit()
                self.middlePullOnDrag = False
                if self.middleClickOnRelease:
                    self.middleClick.emit()
                    self.click.emit()
        elif prm == 'm':
            buttonDown = False
            if self.leftDown:
                self.leftClickOnRelease = False
                if self.leftPullOnDrag:
                    self.leftPull.emit()
                    self.leftPullOnDrag = False
                self.leftDrag.emit()
                self.drag.emit()
                buttonDown = True
            else:
                self.leftHover.emit()
            if self.rightDown:
                self.rightClickOnRelease = False
                if self.rightPullOnDrag:
                    self.rightPull.emit()
                    self.rightPullOnDrag = False
                self.rightDrag.emit()
                self.drag.emit()
                buttonDown = True
            else:
                self.rightHover.emit()
            if self.middleDown:
                self.middleClickOnRelease = False
                if self.middlePullOnDrag:
                    self.middlePull.emit()
                    self.middlePullOnDrag = False
                self.middleDrag.emit()
                self.drag.emit()
                buttonDown = True
            else:
                self.middleHover.emit()
            if not buttonDown:
                self.hover.emit()
        else:
            pass
Exemplo n.º 3
0
class ViewingWindow(QWidget):
    def __init__(self,*args):
        super(ViewingWindow,self).__init__(*args)
        self.graph = BridgeConceptGraph()
        self.nodeSelected = SignalSlotObject()
        self.nodeUnselected = SignalSlotObject()
        self.cursor = Cursor()
        self.cursor.leftClick.connect(self.onLeftClick)
        self.cursor.leftHover.connect(self.onHover)
        self.cursor.leftDrag.connect(self.onLeftDrag)
        self.cursor.leftPress.connect(self.onLeftPress)
        self.cursor.leftRelease.connect(self.onLeftRelease)
        self.cursor.rightClick.connect(self.onRightClick)
        self.cursor.rightDrag.connect(self.onRightDrag)
        self.cursor.rightPress.connect(self.onRightPress)
        self.cursor.rightRelease.connect(self.onRightRelease)
        self.cursor.rightPull.connect(self.onRightPull)
        self.cursor.rightHover.connect(self.onHover)
        self.worldCursor = QPointF(0,0)
        self.leftClickB = False
        self.leftDragB = False
        self.HoverB = False
        self.leftPressB = False
        self.leftReleaseB = False
        self.rightClickB = False
        self.rightDragB = False
        self.rightPressB = False
        self.rightReleaseB = False
        self.rightPullB = False
        self.selectedNode = None
        self.heldNode = None
        self.hoverNode = None
        self.edgeDragNode = None
        self.fps = 30
        self.translation = QPointF(0.0,0.0)
        self.scale = 1.0
        self.minScale = 0.1
        self.maxScale = 10.0
        self.initUI()

    def initUI(self):
        self.setAutoFillBackground(True)
        self.setMouseTracking(True)
        palette = QPalette()
        palette.setColor(QPalette.Window,QColor(0,100,0))
        self.setPalette(palette)

    def sizeHint(self):
        return QSize(800,500)

    def minimumSizeHint(self):
        return QSize(300,300)

    def paintEvent(self,event):
        qp = QPainter()
        qp.begin(self)
        qp.scale(self.scale,self.scale)
        qp.translate(self.translation)
        qp.setRenderHint(QPainter.Antialiasing)
        self.drawGraph(qp)
        self.drawUI(qp)
        qp.end()

    def wheelEvent(self,event):
        self.cursor.update(event,'o')
        d = float(event.delta())
        self.updateWorldCursor()
        p = self.worldCursor
        oldScale = self.scale
        oldTranslation = self.translation
        self.scale += d/360
        self.scale = min(self.maxScale,self.scale)
        self.scale = max(self.minScale,self.scale)
        self.translation=((self.translation+p)*(oldScale/self.scale))-p

    def drawUI(self,qp):
        pen = QPen()
        brush = QBrush(QColor(0,100,0,200))
        qp.setPen(pen)
        qp.setBrush(brush)
        p = self.worldCursor
        if self.edgeDragNode != None:
            qp.drawPath(
                getArrowPath(self.edgeDragNode.position,
                             p,
                             4,
                             40,
                             20,
                             pi/3,
                             0,
                             0
                         )
            )
        #qp.drawText(0,20,str(self.translation))
        #qp.drawText(0,50,str(self.cursor.x)+','+str(self.cursor.y))
        #qp.drawText(0,110,str(self.scale))
        #qp.drawEllipse(QPointF(0,0),10,10)
        #qp.drawEllipse(QPointF(0,100),10,10)
        #qp.drawEllipse(QPointF(100,100),10,10)
        #qp.drawEllipse(QPointF(100,0),10,10)
        #print self.scale

    def drawGraph(self, qp):
        for index, concept in self.graph.concepts.items():
            self.drawConceptToBridgeEdges(qp,
                                          concept,
                                          self.graph.ForwardEdges[index])
        for index, bridge in self.graph.bridges.items():
            self.drawBridgeToConceptEdges(qp,
                                          bridge,
                                          self.graph.ForwardEdges[index])
        for index in self.graph.concepts:
            self.drawConcept(qp,self.graph.concepts[index])
        for index in self.graph.bridges:
            self.drawBridge(qp,self.graph.bridges[index])

    def drawBridgeToConceptEdges(self,qp,bridge,edges):
        pen = QPen()
        brush = QBrush(QColor(100,0,0,200))
        qp.setPen(pen)
        qp.setBrush(brush)
        for e in edges:
            qp.drawPath(
                getArrowPath(bridge.position,
                             self.graph.concepts[e].position,10,65,30, pi/3,0,self.graph.concepts[e].radius))
            
    def drawConceptToBridgeEdges(self,qp,concept,edges):
        pen = QPen()
        brush = QBrush(QColor(0,0,100,200))
        qp.setPen(pen)
        qp.setBrush(brush)
        for e in edges:
            qp.drawPath(
                getArrowPath(concept.position,
                             self.graph.bridges[e].position,6,40,20, pi/3,0,self.graph.bridges[e].radius))
            
    def drawBridge(self,qp,bridge):
        self.drawNode(qp,bridge)
        pen = QPen(QColor(0,0,0))
        font = QFont()
        font.setPointSizeF(12.0/(self.scale**(3.0/4)))
        font.setItalic(True)
        font.setBold(True)
        qp.setPen(pen)
        qp.setFont(font)
        bTitle = bridge.title
        pos = bridge.position + QPointF(1,-1)*bridge.radius
        qp.drawText(pos,bTitle)
        
    def drawConcept(self,qp,concept):
        self.drawNode(qp,concept)
        pen = QPen(QColor(0,0,0))
        bgBrush = QBrush(QColor(255,255,255,20))
        font = QFont()
        font.setPointSizeF(12.0/(self.scale**(3.0/4)))
        font.setBold(True)
        qp.setPen(pen)
        qp.setFont(font)
        qp.setBackgroundMode(Qt.OpaqueMode)
        qp.setBackground(bgBrush)
        cTitle = concept.title
        pos = concept.position + QPointF(1,-1)*concept.radius
        qp.drawText(pos,cTitle)

    def drawNode(self,qp,node):
        ring = False
        ringRadius = 5
        if node.selected:
            pen = QPen(node.palette[2])
            brush = QBrush(node.palette[2])
        elif node.held:
            pen = QPen(node.palette[0])
            brush = QBrush(node.palette[0])
        elif node.hovered:
            pen = QPen(node.palette[1])
            brush = QBrush(node.palette[1])
        elif node.highlighted:
            ring = True
            pen = QPen(node.palette[3])
            brush = QBrush(node.palette[3])
        else:
            pen = QPen(node.palette[3])
            brush = QBrush(node.palette[3])
        qp.setPen(pen)
        qp.setBrush(brush)
        qp.drawEllipse(node.position,node.radius,node.radius)
        if ring:
            pen = QPen(node.palette[2])
            brush = QBrush()
            qp.setPen(pen)
            qp.setBrush(brush)
            qp.drawEllipse(node.position,\
                           node.radius + ringRadius,\
                           node.radius + ringRadius)
        

    def setGraph(self,graph):
        self.graph = graph
        
    def mousePressEvent(self,event):
        self.cursor.update(event,'p')
        
    def mouseReleaseEvent(self,event):
        self.cursor.update(event,'r')
        
    def mouseMoveEvent(self,event):
        self.cursor.update(event,'m')

    def onLeftClick(self):
        self.leftClickB = True

    def onLeftDrag(self):
        self.leftDragB = True
        
    def onHover(self):
        self.HoverB = True

    def onLeftPress(self):
        self.leftPressB = True

    def onLeftRelease(self):
        self.leftReleaseB = True

    def onRightClick(self):
        self.rightClickB = True

    def onRightDrag(self):
        self.rightDragB = True

    def onRightPress(self):
        self.rightPressB = True

    def onRightRelease(self):
        self.rightReleaseB = True

    def onRightPull(self):
        self.rightPullB = True

    def getClosestNode(self,pos):
        try:
            G = self.graph
            distances=[(node,norm(pos - node.position)) for node in G.Nodes()]
            r = reduce(ltIndex(1),distances)
            return r
        except:
            return (None,None)

    def updateWorldCursor(self):
        c = self.cursor
        s = QPointF(self.scale,self.scale)
        t = self.translation
        self.worldCursor = QPointF((c.x/s.x())-t.x(),(c.y/s.y())-t.y())
            
    def readCursorEvents(self):
        c = self.cursor
        self.cursor.resetPrevious = True
        s = QPointF(self.scale,self.scale)
        t = self.translation
        self.updateWorldCursor()
        pos = self.worldCursor
        prevPos = QPointF((c._px/s.x())-t.x(),(c._py/s.y())-t.y())
        (node,dist) = self.getClosestNode(pos)
        #Due to the ascynchronous design, it's necessary to order these
        #properly
        if (self.leftDragB):
            try:
                self.heldNode.position = pos
            except:
                self.translation += pos - prevPos
            self.leftDragB = False
            
        if (self.HoverB):
            if node == None: pass
            elif (dist < node.radius):
                self.unhover()
                self.hover(node)
            else:
                self.unhover()
            self.leftHoverB = False
            
        if (self.leftPressB):
            if node == None: pass
            elif (dist < node.radius):
                self.unhold()
                self.unhover()
                self.hold(node)
            self.leftPressB = False
            
        if (self.leftReleaseB):
            self.unhold()
            self.leftReleaseB = False
            
        if (self.leftClickB):
            if node == None: pass
            elif (dist < node.radius):
                self.unhover()
                self.unhold()
                if not self.selectedNode == node:
                    self.unselect()
                    self.select(node)
                else:
                    self.unselect()
            else:
                self.unselect()
            self.leftClickB = False

        if (self.rightClickB):
            if node == None: self.addConcept(pos)
            elif (dist < node.radius):
                self.deleteNode(node)
            else:
                self.addConcept(pos)
            self.rightClickB = False

        if (self.rightPullB):
            if node == None:
                pass
            elif dist < node.radius:
                self.edgeDragNode = node
            elif self.selectedNode != None:
                self.edgeDragNode = self.selectedNode
            else:
                pass
            self.rightPullB = False
                
        if (self.rightDragB):
            pass
            
        if (self.rightPressB):
            pass

        if (self.rightReleaseB):
            if self.edgeDragNode != None and self.edgeDragNode != node:
                if dist < node.radius:
                    if isinstance(self.edgeDragNode,Bridge):
                        if isinstance(node,Concept):
                            self.graph.ConnectBridgeToConcept(
                                self.edgeDragNode.key,
                                node.key)
                    elif isinstance(self.edgeDragNode,Concept):
                        if isinstance(node,Bridge):
                            self.graph.ConnectConceptToBridge(
                                self.edgeDragNode.key,
                                node.key)
                        elif isinstance(node,Concept):
                            k =self.addBridge((pos + self.edgeDragNode.position)/2)
                            self.graph.ConnectConceptToBridge(self.edgeDragNode.key,k)
                            self.graph.ConnectBridgeToConcept(k,node.key)
            self.edgeDragNode = None
            self.rightReleaseB = False

    def update(self):
        self.readCursorEvents()
        #print "Held Node: ",self.heldNode
        #print "Selected Node: ",self.selectedNode
        #print "Hovered Node: ",self.hoverNode
        self.repaint()

    def animate(self):
        t1 = clock()
        self.update()
        QTimer.singleShot(max(0,1000/self.fps-(clock()-t1)),self.animate)
            
    def select(self,node):
        self.selectedNode = node
        self.selectedNode.selected = True
        for pn in self.graph.ReverseEdges[node.key]:
            try:
                self.graph.bridges[pn].highlighted = True
            except:
                self.graph.concepts[pn].highlighted = True
        self.nodeSelected.emit()

    def unselect(self,node=None):
        if self.selectedNode == node or node == None:
            try:
                self.selectedNode.selected = False
                for pn in self.graph.ReverseEdges[self.selectedNode.key]:
                    try:
                        self.graph.bridges[pn].highlighted = False
                    except:
                        self.graph.concepts[pn].highlighted = False
                self.selectedNode = None
                self.nodeUnselected.emit()
            except:
                pass

    def hold(self, node):
        self.heldNode = node
        self.heldNode.held = True

    def unhold(self, node=None):
        if self.heldNode == node or node == None:
            try:
                self.heldNode.held = False
                self.heldNode = None
            except:
                pass
            
    def hover(self,node):
        self.hoverNode = node
        self.hoverNode.hovered = True

    def unhover(self, node=None):
        if self.hoverNode == node or node == None:
            try:
                self.hoverNode.hovered = False
                self.hoverNode = None
            except:
                pass

    def deleteNode(self,node):
        self.unselect(node)
        self.unhold(node)
        self.unhover(node)
        try:
            self.graph.RemoveBridge(node.key)
        except:
            self.graph.RemoveConcept(node.key)

    def addConcept(self,pos):
        C = Concept()
        C.position = pos
        k = self.graph.AddConcept(C)
        C.key = k
        return k

    def addBridge(self,pos):
        B = Bridge()
        B.position = pos
        k = self.graph.AddBridge(B)
        B.key = k
        return k

    def writeTo(self, filename):
        f = open(filename,'w')
        dump(self.graph,f)
        f.close()

    def readFrom(self,filename):
        f = open(str(filename),'r')
        self.graph = load(f)
        f.close()
Exemplo n.º 4
0
 def __init__(self):
     self.x = 0
     self.y = 0
     self._px = 0
     self._py = 0
     self.resetPrevious = False
     self.leftDown = False
     self.rightDown = False
     self.middleDown = False
     self.leftClickOnRelease = False
     self.rightClickOnRelease = False
     self.middleClickOnRelease = False
     self.leftPullOnDrag = False
     self.rightPullOnDrag = False
     self.middlePullOnDrag = False
     self.leftPress = SignalSlotObject()
     self.rightPress = SignalSlotObject()
     self.middlePress = SignalSlotObject()
     self.leftClick = SignalSlotObject()
     self.rightClick = SignalSlotObject()
     self.middleClick = SignalSlotObject()
     self.leftRelease = SignalSlotObject()
     self.rightRelease = SignalSlotObject()
     self.middleRelease = SignalSlotObject()
     self.click = SignalSlotObject()
     self.leftHover = SignalSlotObject()
     self.rightHover = SignalSlotObject()
     self.middleHover = SignalSlotObject()
     self.hover = SignalSlotObject()
     self.leftDrag = SignalSlotObject()
     self.rightDrag = SignalSlotObject()
     self.middleDrag = SignalSlotObject()
     self.leftPull = SignalSlotObject()
     self.rightPull = SignalSlotObject()
     self.middlePull = SignalSlotObject()
     self.drag = SignalSlotObject()