Example #1
0
    def paintEvent(self, event):
        QFrame.paintEvent(self, event)
        text = QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate)
        logicalRect = QRectF(QPointF(0, 0), QSizeF(QFontMetrics(self.font()).size(Qt.TextSingleLine, text)))
        physicalRect, frameWidth = QRectF(self.rect()), self.frameWidth()
        physicalRect.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth)
        scaleForWidth = physicalRect.width() / logicalRect.width()
        scaleForHeight = physicalRect.height() / logicalRect.height()
        logicalRect.moveTo(frameWidth / scaleForWidth , frameWidth / scaleForHeight)

        painter = QStylePainter(self)
        painter.scale(scaleForWidth, scaleForHeight)
        painter.drawText(logicalRect, Qt.AlignCenter, text)
Example #2
0
    def exportAsImage(self):
        filename = unicode(QFileDialog.getSaveFileName(self,
                                                       self.tr('Save Model As Image'), '',
                                                       self.tr('PNG files (*.png *.PNG)')))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = QRectF(0, 0, 1, 1)
        for item in self.scene.items():
            totalRect = totalRect.united(item.sceneBoundingRect())
        totalRect.adjust(-10, -10, 10, 10)

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, totalRect, totalRect)
        painter.end()

        img.save(filename)
Example #3
0
    def exportAsImage(self):
        filename = unicode(
            QFileDialog.getSaveFileName(self,
                                        self.tr('Save Model As Image'), '',
                                        self.tr('PNG files (*.png *.PNG)')))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = QRectF(0, 0, 1, 1)
        for item in self.scene.items():
            totalRect = totalRect.united(item.sceneBoundingRect())
        totalRect.adjust(-10, -10, 10, 10)

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, totalRect, totalRect)
        painter.end()

        img.save(filename)
Example #4
0
    def paintEvent(self, event):
        QFrame.paintEvent(self, event)
        text = QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate)
        logicalRect = QRectF(
            QPointF(0, 0),
            QSizeF(QFontMetrics(self.font()).size(Qt.TextSingleLine, text)))
        physicalRect, frameWidth = QRectF(self.rect()), self.frameWidth()
        physicalRect.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth)
        scaleForWidth = physicalRect.width() / logicalRect.width()
        scaleForHeight = physicalRect.height() / logicalRect.height()
        logicalRect.moveTo(frameWidth / scaleForWidth,
                           frameWidth / scaleForHeight)

        painter = QStylePainter(self)
        painter.scale(scaleForWidth, scaleForHeight)
        painter.drawText(logicalRect, Qt.AlignCenter, text)
Example #5
0
    def ensureZoomFit(self):
        if self._data:
            prev_rect = self._previousScene.sceneRect()
            cur_rect = self._currentScene.sceneRect()
            prev_wnd = QRectF(self.ui.previousData.childrenRect())
            cur_wnd = QRectF(self.ui.currentData.childrenRect())
            prev_matrix = self.ui.previousData.matrix()
            cur_matrix = self.ui.currentData.matrix()

            prev_mapped_rect = prev_matrix.mapRect(prev_rect)
            cur_mapped_rect = cur_matrix.mapRect(cur_rect)

            if (prev_mapped_rect.width() < prev_wnd.width()
                    or prev_mapped_rect.height() < prev_wnd.height()
                    or cur_mapped_rect.width() < cur_wnd.width()
                    or cur_mapped_rect.height() < cur_wnd.height()):
                self.on_action_Fit_triggered()
    def ensureZoomFit(self):
        if self._data:
            prev_rect = self._previousScene.sceneRect()
            cur_rect = self._currentScene.sceneRect()
            prev_wnd = QRectF(self.ui.previousData.childrenRect())
            cur_wnd = QRectF(self.ui.currentData.childrenRect())
            prev_matrix = self.ui.previousData.matrix()
            cur_matrix = self.ui.currentData.matrix()

            prev_mapped_rect = prev_matrix.mapRect(prev_rect)
            cur_mapped_rect = cur_matrix.mapRect(cur_rect)

            if (prev_mapped_rect.width() < prev_wnd.width() or
                    prev_mapped_rect.height() < prev_wnd.height() or
                    cur_mapped_rect.width() < cur_wnd.width() or
                    cur_mapped_rect.height() < cur_wnd.height()):
                self.on_action_Fit_triggered()
Example #7
0
    def paintEvent(self, event):
        QWidget.paintEvent(self, event)
        rect = QRectF(self.rect())

        painter = QPainter(self)
        painter.setBrush(self._corFundo)

        pen = QPen()
        pen.setColor(Qt.gray)
        painter.setPen(pen)

        painter.drawRoundedRect(QRectF(2, 1, rect.width()-6, rect.height()-4), 8, 2)
        if self.getPorcentagem() > 0:
            painter.setBrush(self._corBarra)
            larguraBarra = self.getPorcentagem()*((rect.width()-6)/100.)
            painter.drawRoundedRect(QRectF(2, 1, larguraBarra, rect.height()-4), 8, 2)
            
        painter.end()
Example #8
0
    def data2scene(self, data2scene):
        self._data2scene = data2scene
        self.scene2data, isInvertible = data2scene.inverted()
        assert isInvertible

        for patchNr in range(self._patchAccessor.patchCount):
            # the patch accessor uses the data coordinate system.
            # because the patch is drawn on the screen, its holds coordinates
            # corresponding to Qt's QGraphicsScene's system, which need to be
            # converted to scene coordinates

            # the image rectangle includes an overlap margin
            imageRectF = data2scene.mapRect(
                self._patchAccessor.patchRectF(patchNr, self.overlap))

            # the patch rectangle has per default no overlap
            patchRectF = data2scene.mapRect(
                self._patchAccessor.patchRectF(patchNr, 0))

            # add a little overlap when the overlap_draw setting is
            # activated
            if self._overlap_draw != 0:
                patchRectF = QRectF(
                    patchRectF.x() - self._overlap_draw,
                    patchRectF.y() - self._overlap_draw,
                    patchRectF.width() + 2 * self._overlap_draw,
                    patchRectF.height() + 2 * self._overlap_draw)

            patchRect = QRect(round(patchRectF.x()), round(patchRectF.y()),
                              round(patchRectF.width()),
                              round(patchRectF.height()))

            # the image rectangles of neighboring patches can overlap
            # slightly, to account for inaccuracies in sub-pixel
            # rendering of many ImagePatch objects
            imageRect = QRect(round(imageRectF.x()), round(imageRectF.y()),
                              round(imageRectF.width()),
                              round(imageRectF.height()))

            self.imageRectFs[patchNr] = imageRectF
            self.dataRectFs[patchNr] = imageRectF
            self.tileRectFs[patchNr] = patchRectF
            self.imageRects[patchNr] = imageRect
            self.tileRects[patchNr] = patchRect
Example #9
0
    def data2scene(self, data2scene):
        self._data2scene = data2scene
        self.scene2data, isInvertible = data2scene.inverted()
        assert isInvertible

        for patchNr in range(self._patchAccessor.patchCount):
            # the patch accessor uses the data coordinate system.
            # because the patch is drawn on the screen, its holds coordinates
            # corresponding to Qt's QGraphicsScene's system, which need to be
            # converted to scene coordinates

            # the image rectangle includes an overlap margin
            imageRectF = data2scene.mapRect(self._patchAccessor.patchRectF(patchNr, self.overlap))

            # the patch rectangle has per default no overlap
            patchRectF = data2scene.mapRect(self._patchAccessor.patchRectF(patchNr, 0))

            # add a little overlap when the overlap_draw setting is
            # activated
            if self._overlap_draw != 0:
                patchRectF = QRectF(patchRectF.x() - self._overlap_draw,
                                    patchRectF.y() - self._overlap_draw,
                                    patchRectF.width() + 2 * self._overlap_draw,
                                    patchRectF.height() + 2 * self._overlap_draw)

            patchRect = QRect(round(patchRectF.x()),
                              round(patchRectF.y()),
                              round(patchRectF.width()),
                              round(patchRectF.height()))

            # the image rectangles of neighboring patches can overlap
            # slightly, to account for inaccuracies in sub-pixel
            # rendering of many ImagePatch objects
            imageRect = QRect(round(imageRectF.x()),
                              round(imageRectF.y()),
                              round(imageRectF.width()),
                              round(imageRectF.height()))

            self.imageRectFs[patchNr] = imageRectF
            self.dataRectFs[ patchNr] = imageRectF
            self.tileRectFs[ patchNr] = patchRectF
            self.imageRects[ patchNr] = imageRect
            self.tileRects[  patchNr] = patchRect
Example #10
0
 def wait(self):
     array_data = self._arrayreq.wait()
     rectf = self.rectf
     if array_data.handedness_switched: # array_data should be of type slicingtools.ProjectedArray
         rectf = QRectF(rectf.height(), rectf.width())
     
     from PyQt4.QtGui import QPainter
     img = QImage( QSize( self.rectf.width(), self.rectf.height() ), QImage.Format_ARGB32_Premultiplied)
     img.fill(0xffffffff)
     p = QPainter(img)
     p.drawImage(0,0, img)
     DummyItem(self.rectf).paint(p, None)
     return img
Example #11
0
 def wait(self):
     array_data = self._arrayreq.wait()
     rectf = self.rectf
     if array_data.handedness_switched: # array_data should be of type slicingtools.ProjectedArray
         rectf = QRectF(rectf.height(), rectf.width())
     
     from PyQt4.QtGui import QPainter
     img = QImage( QSize( self.rectf.width(), self.rectf.height() ), QImage.Format_ARGB32_Premultiplied)
     img.fill(0xffffffff)
     p = QPainter(img)
     p.drawImage(0,0, img)
     DummyItem(self.rectf).paint(p, None)
     return img
Example #12
0
def grab_svg(scene):
    """
    Return a SVG rendering of the scene contents.

    Parameters
    ----------
    scene : :class:`CanvasScene`

    """
    from PyQt4.QtSvg import QSvgGenerator
    svg_buffer = QBuffer()
    gen = QSvgGenerator()
    gen.setOutputDevice(svg_buffer)

    items_rect = scene.itemsBoundingRect().adjusted(-10, -10, 10, 10)

    if items_rect.isNull():
        items_rect = QRectF(0, 0, 10, 10)

    width, height = items_rect.width(), items_rect.height()
    rect_ratio = float(width) / height

    # Keep a fixed aspect ratio.
    aspect_ratio = 1.618
    if rect_ratio > aspect_ratio:
        height = int(height * rect_ratio / aspect_ratio)
    else:
        width = int(width * aspect_ratio / rect_ratio)

    target_rect = QRectF(0, 0, width, height)
    source_rect = QRectF(0, 0, width, height)
    source_rect.moveCenter(items_rect.center())

    gen.setSize(target_rect.size().toSize())
    gen.setViewBox(target_rect)

    painter = QPainter(gen)

    # Draw background.
    painter.setBrush(QBrush(Qt.white))
    painter.drawRect(target_rect)

    # Render the scene
    scene.render(painter, target_rect, source_rect)
    painter.end()

    buffer_str = str(svg_buffer.buffer())
    return unicode(buffer_str.decode("utf-8"))
    def relayout(self):
        """Approximate Fruchterman-Reingold spring layout"""
        nodes = list(self.nodes.values())
        pos = np.array([(np.cos(i / len(nodes) * 2 * np.pi + np.pi / 4),
                         np.sin(i / len(nodes) * 2 * np.pi + np.pi / 4))
                        for i in range(1, 1 + len(nodes))])
        K = 1 / np.sqrt(pos.shape[0])
        GRAVITY, ITERATIONS = 10, 20
        TEMPERATURES = np.linspace(.3, .01, ITERATIONS)
        for temp in chain([.8, .5], TEMPERATURES):
            # Repulsive forces
            delta = pos[:, np.newaxis, :] - pos
            delta /= np.abs(delta).sum(
                2)[:, :, np.newaxis]**2  # NOTE: This warning was expected
            delta = np.nan_to_num(delta)  # Reverse the effect of zero-division
            disp = -delta.sum(0) * K * K
            # Attractive forces
            for edge in self.edges:
                n1, n2 = nodes.index(edge.source), nodes.index(edge.dest)
                delta = pos[n1] - pos[n2]
                magnitude = np.abs(delta).sum()
                disp[n1] -= delta * magnitude / K
                disp[n2] += delta * magnitude / K
            # Gravity; tend toward center
            magnitude = np.sqrt(np.sum(np.abs(pos)**2, 1))
            disp -= (pos.T * K * GRAVITY * magnitude).T
            # Limit max displacement and reposition
            magnitude = np.sqrt(np.sum(np.abs(disp)**2, 1))
            pos += (disp.T / magnitude).T * np.clip(np.abs(disp), 0, temp)

        for node, position in zip(nodes, 500 * pos):
            node.setPos(*position)
        for edge in self.edges:
            edge.adjust()

        MARGIN, rect = 10, self.scene().itemsBoundingRect()
        rect = QRectF(rect.x() - MARGIN,
                      rect.y() - MARGIN,
                      rect.width() + 2 * MARGIN,
                      rect.height() + 2 * MARGIN)
        self.scene().setSceneRect(rect)
        self.scene().invalidate()
    def relayout(self):
        """Approximate Fruchterman-Reingold spring layout"""
        nodes = list(self.nodes.values())
        pos = np.array([(np.cos(i/len(nodes)*2*np.pi + np.pi/4),
                         np.sin(i/len(nodes)*2*np.pi + np.pi/4))
                        for i in range(1, 1 + len(nodes))])
        K = 1 / np.sqrt(pos.shape[0])
        GRAVITY, ITERATIONS = 10, 20
        TEMPERATURES = np.linspace(.3, .01, ITERATIONS)
        for temp in chain([.8, .5], TEMPERATURES):
            # Repulsive forces
            delta = pos[:, np.newaxis, :] - pos
            delta /= np.abs(delta).sum(2)[:, :, np.newaxis]**2  # NOTE: This warning was expected
            delta = np.nan_to_num(delta)  # Reverse the effect of zero-division
            disp = -delta.sum(0)*K*K
            # Attractive forces
            for edge in self.edges:
                n1, n2 = nodes.index(edge.source), nodes.index(edge.dest)
                delta = pos[n1] - pos[n2]
                magnitude = np.abs(delta).sum()
                disp[n1] -= delta*magnitude/K
                disp[n2] += delta*magnitude/K
            # Gravity; tend toward center
            magnitude = np.sqrt(np.sum(np.abs(pos)**2, 1))
            disp -= (pos.T*K*GRAVITY*magnitude).T
            # Limit max displacement and reposition
            magnitude = np.sqrt(np.sum(np.abs(disp)**2, 1))
            pos += (disp.T / magnitude).T * np.clip(np.abs(disp), 0, temp)

        for node, position in zip(nodes, 500*pos):
            node.setPos(*position)
        for edge in self.edges:
            edge.adjust()

        MARGIN, rect = 10, self.scene().itemsBoundingRect()
        rect = QRectF(rect.x() - MARGIN, rect.y() - MARGIN,
                      rect.width() + 2*MARGIN, rect.height() + 2*MARGIN)
        self.scene().setSceneRect(rect)
        self.scene().invalidate()
Example #15
0
class DummyRasterRequest(object):
    """
    For stupid tests.
    Uses DummyItem, but rasterizes it to turn it into a QImage.
    """
    def __init__(self, arrayreq, rect):
        self.rectf = QRectF(rect)
        self._arrayreq = arrayreq
    
    def wait(self):
        array_data = self._arrayreq.wait()
        rectf = self.rectf
        if array_data.handedness_switched: # array_data should be of type slicingtools.ProjectedArray
            rectf = QRectF(rectf.height(), rectf.width())
        
        from PyQt4.QtGui import QPainter
        img = QImage( QSize( self.rectf.width(), self.rectf.height() ), QImage.Format_ARGB32_Premultiplied)
        img.fill(0xffffffff)
        p = QPainter(img)
        p.drawImage(0,0, img)
        DummyItem(self.rectf).paint(p, None)
        return img
Example #16
0
class DummyRasterRequest(object):
    """
    For stupid tests.
    Uses DummyItem, but rasterizes it to turn it into a QImage.
    """
    def __init__(self, arrayreq, rect):
        self.rectf = QRectF(rect)
        self._arrayreq = arrayreq
    
    def wait(self):
        array_data = self._arrayreq.wait()
        rectf = self.rectf
        if array_data.handedness_switched: # array_data should be of type slicingtools.ProjectedArray
            rectf = QRectF(rectf.height(), rectf.width())
        
        from PyQt4.QtGui import QPainter
        img = QImage( QSize( self.rectf.width(), self.rectf.height() ), QImage.Format_ARGB32_Premultiplied)
        img.fill(0xffffffff)
        p = QPainter(img)
        p.drawImage(0,0, img)
        DummyItem(self.rectf).paint(p, None)
        return img
Example #17
0
    def run_loader(self):
        filename = self.result
        try:
            self.retryObject = None
# First, prepare the data by getting the images and computing how big they
# should be
            f = open(filename)
            first_line = f.readline()
            f.close()
            if first_line.startswith("TRKR_VERSION"):
                result = Result(None)
                result.load(self.result, **self._loading_arguments)
                result_type = "Growth"
            else:
                result = TrackingData()
                result.load(self.result, **self._loading_arguments)
                result_type = "Data"
            self.result = result
            self.result_type = result_type
            if result_type == "Data":
                data = result
                images = data.images_name
                if data.cells:
                    self.has_cells = True
                    self.has_walls = True
                else:
                    self.has_cells = False
                    self.has_walls = False
                self.has_points = bool(data.cell_points)
            else:
                data = result.data
                images = result.images
                self.has_cells = False
                self.has_walls = False
                self.has_points = False
            self.images = images
            cache = image_cache.cache
            self.update_nb_images(len(result))
            bbox = QRectF()
            ms = data.minScale()
            for i in range(len(result)):
                img_name = images[i]
                img_data = data[img_name]
                img = cache.image(data.image_path(img_name))
                matrix = QTransform()
                matrix = img_data.matrix()
                sc = QTransform()
                sc.scale(1.0/ms, 1.0/ms)
                matrix *= sc
                r = QRectF(img.rect())
                rbox = matrix.map(QPolygonF(r)).boundingRect()
                bbox |= rbox
                log_debug("Image '%s':\n\tSize = %gx%g\n\tTransformed = %gx%g %+g %+g\n\tGlobal bbox = %gx%g %+g %+g\n" %
                             (img_name, r.width(), r.height(), rbox.width(), rbox.height(), rbox.left(), rbox.top(),
                              bbox.width(), bbox.height(), bbox.left(), bbox.top()))
                log_debug("Matrix:\n%g\t%g\t%g\n%g\t%g\t%g\n" %
                            (matrix.m11(), matrix.m12(), matrix.dx(), matrix.m21(), matrix.m22(), matrix.dy()))
                if result_type == "Growth":
                    if result.cells[i]:
                        self.has_cells = True
                    if result.walls[i]:
                        self.has_walls = True
                    self.has_points = bool(result.data.cell_points)
                self.nextImage()
            translate = bbox.topLeft()
            translate *= -1
            self.translate = translate
            size = bbox.size().toSize()
            self.img_size = size
            self._crop = QRect(QPoint(0,0), size)
            self.finished()
            self._loading_arguments = {} # All done, we don't need that anymore
        except RetryTrackingDataException as ex:
            ex.filename = filename
            self.retryObject = ex
            self.finished()
            return
        except Exception as ex:
            _, _, exceptionTraceback = sys.exc_info()
            self.abort(ex, traceback=exceptionTraceback)
            raise
Example #18
0
    def setAxisIntersect(self, intersect):
        self._axisIntersect = intersect
        #print "SkeletonsLayer(axis=%d) is updating intersect=%d" % (self._axis, self._axisIntersect)
        
        nodes, eIntersected, ePlane = self._3d._skeletons.intersect(self._axis, self._axisIntersect)
       
        #update existing items 
        toRemove = []
        for node, item in self._node2view.iteritems():
            if node.pos[self._axis] != self._axisIntersect:
                self._scene.removeItem(item)
                toRemove.append(node)
            elif node.pointF(self._axis) != item.pos():
                item.setPos( self._scene.data2scene.map( node.pointF(self._axis) ) )
            if node.isSelected() != item.isSelected():
                item.setSelected(node.isSelected())
                assert item.isSelected() == node.isSelected()
            i = 0 
            newSize = [0,0]
            for j in range(3):
                if j == self._axis:
                    continue
                newSize[i] = node.shape[j] 
                i += 1
            newRectF = QRectF(0,0,*newSize)
            newRectF = self._scene.data2scene.mapRect(newRectF)
            
            item.setRect(QRectF(-newRectF.width()/2.0, -newRectF.height()/2.0, newRectF.width(), newRectF.height()))
            
        for r in toRemove:
            del self._node2view[r]
               
        #add new views for nodes 
        for n in nodes:
            if n in self._node2view:
                continue
            
            pos2D = list(n.pos)
            del pos2D[self._axis]

            shape2D = n.shape2D(self._axis)
            itm = QGraphicsSkeletonNode(shape2D, skeletons=self._3d._skeletons, node = n)
            itm.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            itm.setSelected(n.isSelected())
            
            self._scene.addItem(itm)
            self._node2view[n] = itm

        for itm in self._edge2view.values():
            self._scene.removeItem(itm) 
        self._edge2view = dict()
        
        for e in ePlane:
            l = QLineF(e[0].pointF(), e[1].pointF())

            c1 = e[0].color()
            c2 = e[1].color()
            mixColor = QColor( (c1.red()+c2.red())/2,
                               (c1.green()+c2.green())/2,
                               (c1.blue()+c2.blue())/2 )

            line = QGraphicsLineItem(self._scene.data2scene.map(l))
            line.setPen(QPen(mixColor))
            self._scene.addItem(line)
            self._edge2view[e] = line
            
        for theEdge, e in eIntersected:
            c1 = theEdge[0].color()
            c2 = theEdge[1].color()
            mixColor = QColor( (c1.red()+c2.red())/2,
                               (c1.green()+c2.green())/2,
                               (c1.blue()+c2.blue())/2 )

            nodeSize = 6
            p = QGraphicsRectItem(-nodeSize/2, -nodeSize/2, nodeSize, nodeSize)
            pos2D = list(e)
            del pos2D[self._axis]
            p.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            p.setPen(QPen(mixColor))
            self._scene.addItem(p)
            self._edge2view[e] = p
Example #19
0
class ENode(QGraphicsObject):

    onMove = pyqtSignal()
    onPress = pyqtSignal()

    kGuiAttributeId = EObject()
    kGuiAttributeType = EObject()
    kGuiAttributePlug = EObject()
    kGuiAttributeParent = EObject()
    kGuiAttributeParentName = EObject()
    kGuiAttributeLongName = EObject()
    kGuiAttributeShortName = EObject()

    def __init__(self, eNodeHandle):
        QGraphicsObject.__init__(self)

        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setAcceptsHoverEvents(True)

        self.__isDefaultPen = False

        self.__pen = None
        self.__pens = {
            0: EDraw.EColor.DefaultLeaveHoverPen,
            1: EDraw.EColor.DefaultEnterHoverPen
        }
        self.setPen(self.__pens[self.__isDefaultPen])

        self.Name = eNodeHandle.Name

        self.__font = QFont('Helvetica', 8, False)
        self.__nodeHandle = eNodeHandle
        self.__nodeHandle.Message.connect(self.__messageFilter)

        self.__attrRect = QRectF(0, 0, 15, 15)

        self.__titleRect = QRectF(0, 0, 125, 20)
        self.__textSpace = QRectF(
            self.__attrRect.width() + self.pen().width(), 0.0,
            (self.__titleRect.width() - self.__attrRect.width() * 2 -
             self.pen().width() * 2) / 2, self.__attrRect.height())

        self.__attributes = {}

        self.__out_attr_step = self.__titleRect.height() + self.pen().width()
        self.__in_attr_step = self.__titleRect.height() + self.pen().width()

        self.__buildAttributes()

        self.__height = max([self.__in_attr_step, self.__out_attr_step])

    def __messageFilter(self, message):
        if message.match(self.__nodeHandle.kMessageAttributeAdded):
            self.__buildAttribute(message.getData())

    def __getAttrShortName(self, attributeName):
        fm = QFontMetrics(self.__font)

        shortName = ''

        if fm.width(attributeName) > self.__textSpace.width():

            for x in range(len(attributeName) + 1):
                if fm.width(shortName) > int(self.__textSpace.width()) - 10:
                    return shortName

                shortName = attributeName[:x] + '...'

        return attributeName

    def __getAttributePosition(self, attrType):

        attr_x_pos = 0

        if attrType.match(EAttribute.kTypeOutput):

            attr_x_pos = self.__titleRect.width() - self.__attrRect.width()
            rect = self.__attrRect.translated(
                QPointF(attr_x_pos, self.__out_attr_step))

            point = QPointF((rect.topRight() + rect.bottomRight()) / 2)
            point.setX(point.x() + self.pen().width() * 2)

            self.__out_attr_step += self.__attrRect.width() + self.pen().width(
            )

            return [rect, point]

        rect = self.__attrRect.translated(
            QPointF(attr_x_pos, self.__in_attr_step))
        point = QPointF((rect.topLeft() + rect.bottomLeft()) / 2)
        point.setX(point.x() - self.pen().width() * 2)

        self.__in_attr_step += self.__attrRect.width() + self.pen().width()

        return [rect, point]

    def __buildAttribute(self, attribute):
        data = self.__getAttributePosition(attribute.Type)

        self.__attributes[data[0]] = dict({
            self.kGuiAttributeId:
            attribute.Id,
            self.kGuiAttributeType:
            attribute.Type,
            self.kGuiAttributeParent:
            self,
            self.kGuiAttributeParentName:
            self.__nodeHandle.Name,
            self.kGuiAttributePlug:
            data[1],
            self.kGuiAttributeLongName:
            attribute.Name,
            self.kGuiAttributeShortName:
            self.__getAttrShortName(attribute.Name)
        })

        self.__height = max([self.__in_attr_step, self.__out_attr_step])

        self.update()
        self.onMove.emit()

    def __buildAttributes(self):

        for eddAttr in self.__nodeHandle.ls():
            self.__buildAttribute(eddAttr)

    def __toggleHighlight(self):
        if self.__isDefaultPen:
            self.__isDefaultPen = False
            self.setPen(self.__pens[self.__isDefaultPen])
            #self.setZValue(0.0)
            return

        self.__isDefaultPen = True
        self.setPen(self.__pens[self.__isDefaultPen])
        #self.setZValue(-2.0)

    @property
    def Id(self):
        return self.__nodeHandle.Id

    def pen(self):
        return self.__pen

    def setPen(self, pen):
        if not isinstance(pen, QPen):
            raise AttributeError

        self.__pen = pen

    @property
    def Handle(self):
        return self.__nodeHandle

    def mapFromPoint(self, QPoint):

        for attrRect, attrValues in self.__attributes.iteritems():
            if attrRect.contains(self.mapFromScene(QPoint)):
                return attrValues[self.kGuiAttributeId]

        return self.__nodeHandle.Id

    def mapFromId(self, attrId):

        for attrValue in self.__attributes.itervalues():
            if attrValue[self.kGuiAttributeId] == attrId:
                return attrValue

        return None

    def hoverEnterEvent(self, mouseEvent):
        QGraphicsObject.hoverEnterEvent(self, mouseEvent)
        self.__toggleHighlight()

    def hoverMoveEvent(self, mouseEvent):
        QGraphicsObject.hoverMoveEvent(self, mouseEvent)

    def hoverLeaveEvent(self, mouseEvent):
        QGraphicsObject.hoverLeaveEvent(self, mouseEvent)
        self.__toggleHighlight()

    def mousePressEvent(self, mouseEvent):
        QGraphicsObject.mousePressEvent(self, mouseEvent)

        #if mouseEvent.button() == Qt.RightButton:
        #print self.mapFromPoint(mouseEvent.scenePos())
        self.onPress.emit()

    def mouseDoubleClickEvent(self, mouseEvent):
        QGraphicsObject.mouseDoubleClickEvent(self, mouseEvent)

        #self.__nodeHandle.compute()

    def mouseMoveEvent(self, mouseEvent):
        QGraphicsObject.mouseMoveEvent(self, mouseEvent)
        self.onMove.emit()

    def boundingRect(self):
        extra = self.pen().width()
        return self.__titleRect.normalized().adjusted(
            -extra, -extra, extra,
            (self.__height - self.__titleRect.height()) + extra)

    def shape(self):
        return QGraphicsItem.shape(self)

    def paint(self, painter, option, widget=None):

        painter.setBrush(Qt.darkGray)

        painter.setPen(self.pen())
        painter.drawRect(self.boundingRect())

        painter.setPen(Qt.NoPen)

        painter.setBrush(QColor(43, 43, 43))
        painter.drawRect(self.__titleRect)

        painter.setPen(Qt.darkGray)
        painter.drawText(self.__titleRect, Qt.AlignCenter, self.Name)

        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(60, 63, 65))

        for rect in self.__attributes.iterkeys():
            painter.drawRect(rect)

        painter.setBrush(Qt.darkGray)
        for rect in self.__attributes.iterkeys():
            painter.drawPolygon(
                EDraw.Circle(rect.height() / 3, 3).translated(rect.center()))

        painter.setPen(QPen(QColor(43, 43, 43), 1.0, Qt.SolidLine))
        painter.setBrush(Qt.NoBrush)

        painter.setFont(self.__font)
        for attrRect, attrValues in self.__attributes.iteritems():

            attrNameRect = self.__textSpace.translated(attrRect.topLeft())
            align = Qt.AlignLeft

            if attrRect.topLeft().x() > 0:
                attrNameRect = self.__textSpace.translated(
                    QPointF((self.__titleRect.width() / 2) -
                            (attrRect.width() + self.pen().width()),
                            attrRect.topLeft().y()))

                align = Qt.AlignRight

            painter.drawText(attrNameRect, align,
                             attrValues[self.kGuiAttributeShortName])
Example #20
0
class EFrameLayout(QGraphicsPolygonItem):

    def __init__(self, parent=None, scene=None):
        super(EFrameLayout, self).__init__(parent, scene)

        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setAcceptsHoverEvents(True)

        self.__name = QGraphicsTextItem()
        self.__name.setPlainText('Frame Layout')

        self.__handleWidth = 500
        self.__handleHeight = 20
        self.__separator = 5
        self.__boundExtra = 3 + self.pen().width()
        self.__handleRect = QRectF( 0.0 , 0.0 , self.__handleWidth, self.__handleHeight  )

        self.__controlsBound = 0.0
        self.__controls = []

        self.__isDefaultPen = False
        self.__isCollapsed = True

        self.__pens = { 0: EDraw.EColor.DefaultLeaveHoverPen, 1: EDraw.EColor.DefaultEnterHoverPen }
        self.setPen(self.__pens[self.__isDefaultPen])

    @property
    def Label(self): return self.__name.toPlainText()

    @Label.setter
    def Label(self, label): self.__name.setPlainText( str( label ) )

    @property
    def Width(self): return self.__handleWidth

    @Width.setter
    def Width(self, width):
        self.__handleWidth = width
        self.updateGeometry()

    def toggleContentVisibility(self):
        if not len(self.__controls): return

        if self.__controls[0].isVisible():
            [ control.hide() for control in self.__controls ]
            self.__isCollapsed = True
            return

        [ control.show() for control in self.__controls ]
        self.__isCollapsed = False

    def updateGeometry(self):

        self.__handleRect = QRectF( 0.0 , 0.0 , self.__handleWidth, self.__handleHeight  )

        if not len(self.__controls) or self.__isCollapsed:
            self.__controlsBound = 0.0
            return

        self.__controlsBound = 0.0
        self.__controlsBound = self.__separator
        self.__controlsBound += sum( [ control.boundingRect().height() + self.__separator for control in self.__controls ] )

        step = self.__handleHeight + self.__separator * 2

        for control in self.__controls:

            control.Name.setTextWidth( self.__controlNameWidth )
            control.Width = self.__handleRect.normalized().adjusted( 5.0, 0.0, -5.0, 0.0 ).width()

            control.setPos( 5.0 , step )
            step += control.boundingRect().height() + self.__separator

    def addControl(self, control):
        if not isinstance(control, EControlsGroup): raise AttributeError

        self.__controls.append(control)
        control.setParentItem(self)
        control.setFlag(QGraphicsItem.ItemIsMovable, False)

        self.__controlNameWidth = max([ control.Name.boundingRect().width() for control in self.__controls ]) + 5

        self.__isCollapsed = False
        self.updateGeometry()

    def clear(self):
        [ control.setParentItem(None) for control in self.__controls ]
        self.__controls = []

        self.updateGeometry()

    def mouseDoubleClickEvent(self, mouseEvent):
        QGraphicsPolygonItem.mouseDoubleClickEvent(self, mouseEvent)

        self.toggleContentVisibility()
        self.updateGeometry()

    def shape(self): return QGraphicsItem.shape(self)

    def boundingRect(self):
        return self.__handleRect.normalized().adjusted( 0.0, 0.0, 0.0, self.__controlsBound )

    def paint(self, painter, option, widget=None):

        if not self.__isCollapsed:
            painter.setPen( QPen( QColor( 0, 0, 0, 50 ), 2 , Qt.SolidLine ) )
            painter.setBrush( QColor( 0, 0, 0, 50 ) )
            painter.drawRect( self.boundingRect().adjusted( self.pen().width(), self.__handleHeight , -self.pen().width(), 0.0 ) )

        painter.setPen(self.pen())
        painter.setBrush( EDraw.EColor.LinearGradient( self.__handleRect, Qt.darkGray ) )
        #painter.drawPolygon( QPolygonF( self.__handleRect.normalized().adjusted(-self.__boundExtra, 0.0, self.__boundExtra, 0.0 ) ) )
        painter.drawPolygon( QPolygonF( self.__handleRect ) )

        painter.setPen(Qt.lightGray)
        r = QRectF( 0.0, 0.0, self.__name.boundingRect().width(), self.__handleRect.height() )
        painter.drawText( r, Qt.AlignCenter, self.__name.toPlainText() )
Example #21
0
class DrawableNote(DrawableNode, QGraphicsItem):
    def __init__(self, uml_object):
        super(DrawableNote, self).__init__(uml_object)
        QGraphicsItem.__init__(self)
        self.__bounding_rect = QRectF(0, 0, 100, 100)
        self.__font = Drawable.get_font()
        self.__text_margin = 3
        self.__note_margin = 10

        self.setFlag(QGraphicsItem.ItemIsMovable, 1)
        self.setFlag(QGraphicsItem.ItemIsSelectable, 1)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, 1)

    def boundingRect(self):
        return self.__bounding_rect

    def paint(self, painter, style, widget):
        metrics = QFontMetrics(self.__font)
        
        painter.setFont(self.__font)
        painter.setPen(QColor(0, 0, 0))
        painter.fillRect(QRectF(self.__bounding_rect), QBrush(QColor(255, 255, 255), Qt.SolidPattern))
        
        # Draw folded corner first
        painter.drawLine(self.__bounding_rect.width() - self.__note_margin, 0, self.__bounding_rect.width(), self.__note_margin)
        painter.drawLine(self.__bounding_rect.width() - self.__note_margin, 0, self.__bounding_rect.width() - self.__note_margin, self.__note_margin)
        painter.drawLine(self.__bounding_rect.width() - self.__note_margin, self.__note_margin, self.__bounding_rect.width(), self.__note_margin)
        
        text_rect = QRect(self.__text_margin, self.__text_margin, self.__bounding_rect.width() - self.__note_margin, self.__bounding_rect.height())
        
        if('text' in self.uml_object):
            painter.drawText(text_rect, Qt.TextWordWrap, self.uml_object['text'])
        
        painter.drawLine(0, 0, self.__bounding_rect.width() - self.__note_margin, 0)
        painter.drawLine(0, 0, 0, self.__bounding_rect.height())
        painter.drawLine(0, self.__bounding_rect.height(), self.__bounding_rect.width(), self.__bounding_rect.height())
        painter.drawLine(self.__bounding_rect.width(), self.__note_margin, self.__bounding_rect.width(), self.__bounding_rect.height())
        
    def update(self):
        metrics = QFontMetrics(self.__font)
        
        if('text' in self.uml_object):
            text = self.uml_object['text']
            width = metrics.width(text)
            height = metrics.height()
            
            rect_ratio = (width / height) * 0.337 # LOL MAGIC NUMBER
            rect_ratio = min(10, rect_ratio)
            
            note_width = height * rect_ratio
            note_height = 2 * note_width / height # no higher than that
            
            self.__bounding_rect = QRectF(metrics.boundingRect(QRect(0,0, note_width, note_height), Qt.TextWordWrap | Qt.TextDontClip, text)
                                    .adjusted(0, 0, 2 * self.__text_margin + self.__note_margin, 2 * self.__text_margin))
        else:
            self.__bounding_rect = QRectF(0,0,50,50)
            
    def itemChange(self, change, value):        
        if(change == QGraphicsItem.ItemPositionChange):
            for anchor in self.anchors:
                anchor.connector.update()
                
            self.resize_scene_rect()
                
        return QGraphicsItem.itemChange(self, change, value)
    
    def crop_line(self, line, line_point):
        global_rect = self.globalBoundingRect()
        
        vertexes = [global_rect.topLeft(), global_rect.topRight(),
                  global_rect.bottomRight(), global_rect.bottomLeft(),
                  
                  # Folded corner
                  QPointF(global_rect.topRight().x() - self.__note_margin, global_rect.topRight().y()), 
                  QPointF(global_rect.topRight().x(), global_rect.topRight().y() + self.__note_margin)
                  ]
                
        intersection_point = QPointF()
        
        # Iterate over pairs of vertices that make rectangle edges
        # Check folded corner first and we don't have to crop
        # rest of the edges. 
        for (a, b) in [(4, 5), (0, 1), (1, 2), (2, 3), (3, 0)]:
            bok = QLineF(vertexes[a], vertexes[b])
            itype = line.intersect(bok, intersection_point)
            if(itype == QLineF.BoundedIntersection):
                if(line_point == 0):
                    return QLineF(intersection_point, line.p2())
                else:
                    return QLineF(line.p1(), intersection_point)
        
        return line
        
    def find_anchor(self):
        return self.globalBoundingRect().center()
class TreeNode(object):
	"""store data for a class and manage hierarchy"""
	def __init__(self, classid,name,rect=None,color=None,pos=None,accu = 1.0,parent=None):
		super(TreeNode, self).__init__()
		self.classid = classid
		self.name = name
		self.parent = parent
		self.accu = accu
		self.rect = QRectF(*rect) if rect else rect
		self.color = QColor(color) if color else color
		self.pos = QPointF(*pos) if pos else pos 
		self.children = []
		if parent:
			parent.children.append(self)

	# def __init__(self,jsonobj):
	# 	self.__init__(jsonobj['id'],jsonobj['name'],jsonobj['rect'],jsonobj['color'],jsonobj['pos'])
	# 	for child in jsonobj['children']:
	# 		childItem = TreeNode(child)
	# 		self.children.append(childItem)
	# 		childItem.parent = self

	def isLeaf(self):
		if self.children:
			return False
		else:
			return True

	def isRoot(self):
		if self.parent:
			return False
		else:
			return True

	def toJSON(self):
		jsonObj = {}
		jsonObj['id']= self.classid
		jsonObj['name'] = self.name
		jsonObj['rect'] = [self.rect.left(),self.rect.top(),self.rect.width(),self.rect.height()] if self.rect else self.rect
		jsonObj['color'] = str(self.color.name()) if self.color else self.color
		jsonObj['pos'] = [self.pos.x(),self.pos.y()] if isinstance(self.pos,QPointF) else self.pos
		jsonObj['accu'] = self.accu
		jsonObj['children'] = []
		for child in self.children:
			jsonObj['children'].append(child.toJSON())
		return jsonObj

	def __str__(self):
		tempstr = "%s   %s\n" % (self.classid,self.name)
		for child in self.children:
			tempstr+= '   '+str(child)
		return tempstr 

	def findNode(self,id):
		if self.classid == id:
			return self
		for child in self.children:
			result = child.findNode(id)
			if result:
				return result
		return None

	def toplogicalDistance(self,id1,id2):
		if id1==id2:
			return 0
		else:
			node1 = self.findNode(id1)
			node2 = self.findNode(id2)
			if node1 and node2:
				if node1.parent == node2.parent:
					return 1
				else:
					return 2
		return 0

	def matrixDistance(self,id1,id2):
		if id1==id2:
			return 0
		else:
			node1 = self.findNode(id1)
			node2 = self.findNode(id2)
			if node1 and node2:
					pos1 = node1.pos + node1.parent.pos
					pos2 = node2.pos + node2.parent.pos
					return QLineF(pos1,pos2).length()
		return 2000.0

	def transactionPossibility(self,id1,id2):
		node1 = self.findNode(id1)
		node2 = self.findNode(id2)
		if node1 and node2:
			return node1.accu * node2.accu
		else:
			return 1.0
Example #23
0
class SlideshowFrame(object):
    def __init__(self, win, rect, filename, metadata):
        self.win = win
        self.rect = rect
        self.filename = filename
        self.metadata = metadata

        if self.metadata:
            self.line1 = self.metadata['Name']
            self.line2 = "%s Mission" % (self.metadata['Mission'])
            self.line3 = "%s" % (self.metadata['Time'])
        else:
            self.line1 = ""
            self.line2 = ""
            self.line3 = ""

        self.image = QGraphicsPixmapItem()
        self.win.scene.addItem(self.image)
        self.image.setTransformationMode(Qt.SmoothTransformation)

        self.use_two_lines = True

        self.fontsize1 = 32
        self.fontsize2 = 26
        self.fontsize3 = 24

        self.font1 = QFont('Times New Roman', self.fontsize1)
        self.font2 = QFont('Times New Roman', self.fontsize2)
        self.font3 = QFont('Times New Roman', self.fontsize3)

        self.title1 = self.win.scene.addText(self.line1, self.font1)
        self.title1.setDefaultTextColor(Qt.white)
        self.title1.setVisible(False)

        self.title2 = self.win.scene.addText(self.line2, self.font2)
        self.title2.setDefaultTextColor(Qt.white)
        self.title2.setVisible(False)

        self.title3 = self.win.scene.addText(self.line3, self.font3)
        self.title3.setDefaultTextColor(Qt.white)
        self.title3.setVisible(False)

        self.reservedHeight = 128
        self.padding = 20

        self.hide()

    def move(self, x, y):
        self.rect = QRectF(x, y, self.rect.width(), self.rect.height())

    def __rotate(self, metadata, origImgSize):
        # Qt only handles orientation properly from v5.5
        try:
            # try directly to get the tag, because sometimes get_tags() returns
            # tags that don't actually are in the file
            rot = metadata['Exif.Image.Orientation']
        except KeyError:
            # guess :-/
            rot = '1'

        # see http://www.daveperrett.com/images/articles/2012-07-28-exif-orientation-handling-is-a-ghetto/EXIF_Orientations.jpg
        # we have to 'undo' the rotations, so the numbers are negative
        if rot == '1':
            rotate = 0
            imgSize = origImgSize
        if rot == '8':
            rotate = -90
            imgSize = QSize(origImgSize.height(), origImgSize.width())
        if rot == '3':
            rotate = -180
            imgSize = origImgSize
        if rot == '6':
            rotate = -270
            imgSize = QSize(origImgSize.height(), origImgSize.width())

        # undo the last rotation and apply the new one
        self.image.setRotation(rotate)

        return imgSize

    def __zoomFit(self, imgSize):

        reservedHeight = self.reservedHeight + self.padding * 2

        hZoom = self.rect.width() / imgSize.width()
        vZoom = (self.rect.height() - reservedHeight) / imgSize.height()
        scale = min(hZoom, vZoom)

        self.image.setScale(scale)

        width = imgSize.width() * scale
        height = imgSize.height() * scale
        self.image.setPos(
            (self.rect.width() - width) / 2 + self.rect.x(),
            (self.rect.height() - reservedHeight - height) / 2 + self.rect.y())

    def layoutText(self):
        reservedHeight = self.reservedHeight + self.padding
        vertical_spacing = (self.reservedHeight -
                            self.title1.boundingRect().height() -
                            self.title2.boundingRect().height() -
                            self.title3.boundingRect().height()) / 3

        x = (self.rect.width() - self.title1.boundingRect().width()) / 2
        y = self.rect.height() - reservedHeight + vertical_spacing
        self.title1.setPos(x + self.rect.x(), y + self.rect.y())

        x = (self.rect.width() - self.title2.boundingRect().width()) / 2
        y = self.rect.height(
        ) - reservedHeight + vertical_spacing * 2 + self.title1.boundingRect(
        ).height()
        self.title2.setPos(x + self.rect.x(), y + self.rect.y())

        x = (self.rect.width() - self.title3.boundingRect().width()) / 2
        y = self.rect.height(
        ) - reservedHeight + vertical_spacing * 3 + self.title1.boundingRect(
        ).height() + self.title2.boundingRect().height()
        self.title3.setPos(x + self.rect.x(), y + self.rect.y())

    def show(self):
        img = QPixmap(self.filename)

        try:
            metadata = GExiv2.Metadata(self.filename)
        except GLib.Error as e:
            print(repr(e))
            return

        self.image.setPixmap(img)
        self.image.setScale(1.0)
        self.image.setRotation(0)

        imgSize = self.__rotate(metadata, img.size())
        self.__zoomFit(imgSize)
        self.layoutText()

        self.title1.setVisible(True)
        self.title2.setVisible(True)
        self.title3.setVisible(True)
        self.image.setVisible(True)

    def hide(self):
        self.title1.setVisible(False)
        self.title2.setVisible(False)
        self.title3.setVisible(False)
        self.image.setVisible(False)
        self.image.setPixmap(QPixmap())

    def showImage(self, file, md):
        self.metadata = md

        try:
            metadata = GExiv2.Metadata(file)
        except GLib.Error as e:
            print(repr(e))
            return

        img = QPixmap(file)

        self.image.setPixmap(img)
        self.image.setScale(1.0)
        self.image.setRotation(0)

        imgSize = self.__rotate(metadata, img.size())

        self.__zoomFit(imgSize)
        self.layoutMetadata()
Example #24
0
class QGraphicsListData(QGraphicsItem):  # IGNORE:abstract-class-not-used
    _editName = ""

    def __init__(self, qScore, parent = None):
        super(QGraphicsListData, self).__init__(parent = parent, scene = qScore)
        self._qScore = qScore
        self._props = qScore.displayProperties
        self._rect = QRectF(0, 0, 0, 0)
        self.setRect()
        self.setCursor(Qt.PointingHandCursor)
        self.setAcceptsHoverEvents(True)

    def _iterData(self):
        raise NotImplementedError()

    def _dataLen(self):
        raise NotImplementedError()

    def font(self):
        raise NotImplementedError()

    def setRect(self, fm = None):
        if fm is None:
            font = self.font()
            if font is None:
                return
            fm = QFontMetrics(font)
        lineHeight = fm.height()
        height = lineHeight * self._dataLen() * 1.1
        width = max(fm.width(data) for data in self._iterData()) + 10
        if height != self._rect.height() or width != self._rect.width():
            self.prepareGeometryChange()
            self._rect.setBottomRight(QPointF(width, height))

    def boundingRect(self):
        return self._rect

    def paint(self, painter, dummyOption, dummyWidget = None):
        painter.save()
        try:
            scheme = self._qScore.parent().colourScheme
            painter.setPen(QPen(scheme.text.borderColour))
            font = self.font()
            if font is None:
                font = painter.font()
            else:
                painter.setFont(font)
            fm = QFontMetrics(painter.font())
            self.setRect(fm)
            lineHeight = fm.height()
            for index, data in enumerate(self._iterData()):
                painter.drawText(QPoint(5, (index + 1) * lineHeight), data)
        finally:
            painter.restore()

    def fontChanged(self):
        self.update()

    def update(self):
        self.setRect()
        super(QGraphicsListData, self).update()

    def hoverEnterEvent(self, event):
        self._qScore.setStatusMessage("Double click to edit %s."
                                      % self._editName)
        event.accept()

    def hoverLeaveEvent(self, event):
        self._qScore.setStatusMessage()
        event.accept()
Example #25
0
    def layout(self,
               scene,
               nodes,
               center=None,
               padX=None,
               padY=None,
               direction=None,
               animationGroup=None):
        """
        Lays out the nodes for this scene based on a block layering algorithm.
        
        :param      scene          | <XNodeScene>
                    nodes          | [<XNode>, ..]
                    center         | <QPointF> || None
                    padX           | <int> || None
                    padY           | <int> || None
                    direction      | <Qt.Direction>
                    animationGroup | <QAnimationGroup> || None
        
        :return     {<XNode>: <QRectF>, ..} | new rects per affected node
        """
        nodes = filter(lambda x: x is not None and x.isVisible(), nodes)

        # make sure we have at least 1 node, otherwise, it is already laid out
        if not nodes or len(nodes) == 1:
            return {}

        # calculate the default padding based on the scene
        if padX == None:
            if direction == Qt.Vertical:
                padX = 2 * scene.cellWidth()
            else:
                padX = 4 * scene.cellWidth()

        if padY == None:
            if direction == Qt.Vertical:
                padY = 4 * scene.cellHeight()
            else:
                padY = 2 * scene.cellWidth()

        # step 1: create a mapping of the connections
        connection_map = self.connectionMap(scene, nodes)

        # step 2: organize the nodes into layers based on their connection chain
        layers = self.generateLayers(scene, nodes, connection_map)
        layers = list(reversed(layers))

        # step 3: calculate the total dimensions for the layout
        bounds = QRectF()

        # step 3.1: compare the nodes together that have common connections
        layer_widths = []
        layer_heights = []
        node_heights = {}
        node_widths = {}

        for layer_index, layer in enumerate(layers):
            layer_w = 0
            layer_h = 0

            layer_node_w = []
            layer_node_h = []

            self.organizeLayer(layer, connection_map)

            for node in layer:
                rect = node.rect()

                layer_node_w.append(rect.width())
                layer_node_h.append(rect.height())

                if direction == Qt.Vertical:
                    layer_w += rect.width()
                    layer_h = max(rect.height(), layer_h)
                else:
                    layer_w = max(rect.width(), layer_w)
                    layer_h += rect.height()

            # update the bounding area
            if direction == Qt.Vertical:
                layer_w += padX * 1 - len(layer)
                bounds.setWidth(max(layer_w, bounds.width()))
                bounds.setHeight(bounds.height() + layer_h)
            else:
                layer_h += padY * 1 - len(layer)
                bounds.setWidth(bounds.width() + layer_w)
                bounds.setHeight(max(layer_h, bounds.height()))

            node_widths[layer_index] = layer_node_w
            node_heights[layer_index] = layer_node_h

            layer_widths.append(layer_w)
            layer_heights.append(layer_h)

        if not center:
            center = scene.sceneRect().center()

        w = bounds.width()
        h = bounds.height()
        bounds.setX(center.x() - bounds.width() / 2.0)
        bounds.setY(center.y() - bounds.height() / 2.0)
        bounds.setWidth(w)
        bounds.setHeight(h)

        # step 4: assign positions for each node by layer
        processed_nodes = {}
        layer_grps = [(i, layer) for i, layer in enumerate(layers)]
        layer_grps.sort(key=lambda x: len(x[1]))

        for layer_index, layer in reversed(layer_grps):
            layer_width = layer_widths[layer_index]
            layer_height = layer_heights[layer_index]

            # determine the starting point for this layer
            if direction == Qt.Vertical:
                offset = layer_index * padY + sum(layer_heights[:layer_index])
                point = QPointF(bounds.x(), offset + bounds.y())
            else:
                offset = layer_index * padX + sum(layer_widths[:layer_index])
                point = QPointF(offset + bounds.x(), bounds.y())

            # assign node positions based on existing connections
            for node_index, node in enumerate(layer):
                max_, min_ = (None, None)
                inputs, outputs = connection_map[node]
                for connected_node in inputs + outputs:
                    if not connected_node in processed_nodes:
                        continue

                    npos = processed_nodes[connected_node]
                    nrect = connected_node.rect()
                    rect = QRectF(npos.x(), npos.y(), nrect.width(),
                                  nrect.height())

                    if direction == Qt.Vertical:
                        if min_ is None:
                            min_ = rect.left()
                        min_ = min(rect.left(), min_)
                        max_ = max(rect.right(), max_)
                    else:
                        if min_ is None:
                            min_ = rect.top()
                        min_ = min(rect.top(), min_)
                        max_ = max(rect.bottom(), max_)

                if direction == Qt.Vertical:
                    off_x = 0
                    off_y = (layer_height - node.rect().height()) / 2.0
                    start_x = (bounds.width() - layer_width)
                    start_y = 0
                else:
                    off_x = (layer_width - node.rect().width()) / 2.0
                    off_y = 0
                    start_x = 0
                    start_y = (bounds.height() - layer_height)

                # align against existing nodes
                if not None in (min_, max):
                    if direction == Qt.Vertical:
                        off_x = (max_ - min_) / 2.0 - node.rect().width() / 2.0
                        point_x = min_ + off_x
                        point_y = point.y() + off_y
                    else:
                        off_y = (max_ -
                                 min_) / 2.0 - node.rect().height() / 2.0
                        point_x = point.x() + off_x
                        point_y = min_ + off_y

                # otherwise, align based on its position in the layer
                else:
                    if direction == Qt.Vertical:
                        off_x = sum(node_widths[layer_index][:node_index])
                        off_x += node_index * padX
                        off_x += start_x

                        point_x = point.x() + off_x
                        point_y = point.y() + off_y
                    else:
                        off_y = sum(node_heights[layer_index][:node_index])
                        off_y += node_index * padY
                        off_y += start_y

                        point_x = point.x() + off_x
                        point_y = point.y() + off_y

                if not animationGroup:
                    node.setPos(point_x, point_y)
                else:
                    anim = XNodeAnimation(node, 'setPos')
                    anim.setStartValue(node.pos())
                    anim.setEndValue(QPointF(point_x, point_y))
                    animationGroup.addAnimation(anim)

                processed_nodes[node] = QPointF(point_x, point_y)

                if self._testing:
                    QApplication.processEvents()
                    time.sleep(1)

        return processed_nodes
def paintBoundaries(tgslicesFile, zSlice, d, boundaryData, mask, filename, swapCoordinates=False, colortable=None, penWidth=4.0):
    print "* making boundary img '%s'" % filename
    
    #b = BoundariesLayerPy(tgslicesFile=tgslicesFile, normalAxis=2, data2scene=QTransform(), swapCoordinates=True)
    b = BoundariesLayer(None, 2, QTransform(), True)
    
    n  = b.normalAxis()
    axis = None
    if swapCoordinates:
        if   n == 0: axis = "z"
        elif n == 1: axis = "y"
        else:        axis = "x"
    else:
        if   n == 0: axis = "x"
        elif n == 1: axis = "y"
        else:        axis = "z"
    
    f = h5py.File(tgslicesFile, 'r')
    group = "%s/%d" % (axis, zSlice)
    serializedBoundaries = f[group].value
    f.close()
    
    assert d.ndim == 2
    
    scene = QGraphicsScene()
    
    b.setSliceNumber( zSlice )
    b.setBoundaries(serializedBoundaries)
    b.setColormap("tyr")
    assert boundaryData.dtype == numpy.float32
    assert mask.dtype == numpy.float32
    b.setBoundaryData(boundaryData, boundaryData.size, boundaryData)
    b.setBoundaryMask(mask, mask.size)
    if colortable is not None:
        b.setColormap(colortable)
    print "setting pen width to be %f" % penWidth
    b.setPenWidth(float(penWidth))
    print "...done"
   
    mag = 4
    shape = d.shape
    
    dBig = vigra.sampling.resizeImageNoInterpolation(d.astype(numpy.float32), (mag*shape[0], mag*shape[1]))
    #dBig = dBig.swapaxes(0,1)
    qimg = qimage2ndarray.gray2qimage(dBig)
    #qimg = qimg.mirrored(True, False)
    imgItm = QGraphicsPixmapItem(QPixmap(qimg))
    imgItm.setScale(1.0/mag)
    scene.addItem(imgItm)
    
    sourceRect = QRectF(0,0,shape[1], shape[0])
    targetRect = QRectF(0,0,mag*shape[1], mag*shape[0])
    scene.setSceneRect(sourceRect)
    scene.addItem(b)
    
    img = QImage(targetRect.width(), targetRect.height(), QImage.Format_ARGB32);
    painter = QPainter(img);
    painter.setRenderHint(QPainter.Antialiasing);
    scene.render(painter, targetRect, sourceRect );
    img.save(filename)
    painter.end()
    #print "img has size ", img.width(), img.height()
    img = None
    painter = None
    scene = None
Example #27
0
class ZoomSlider(QFrame):
    """
    Two way slider representing narrowing of a view.
    The sliders coorespond to factors: a min value and a max value in the range [0, 1]
    Emits zoomValueChanged(float, float) whenever the markers are adjusted. (float, float) -> (min, max)
    """
    def __init__(self, parent=None, horizontal=True):
        QFrame.__init__(self, parent)

        self.horizontal = horizontal
        if horizontal:
            self.setFrameShape(QFrame.HLine)
            self.setMinimumHeight(21)
            self.tilt = 90
        else:
            self.setFrameShape(QFrame.VLine)
            self.setMinimumWidth(21)
            self.tilt = 180

        self.setFrameShadow(QFrame.Sunken)
        self.setMidLineWidth(3)

        self.setMouseTracking(True)

        self.size = 12

        self.min_value = 0.0
        self.max_value = 1.0

        self.setDefaultColors()
        self.button = Qt.NoButton
        self.selected_marker = 'none'


    def paintEvent(self, paint_event):
        QFrame.paintEvent(self, paint_event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        w = self.width()
        h = self.height()

        if self.horizontal:
            self.min_marker = QRectF(w * self.min_value, 4, self.size, self.size)
            self.max_marker = QRectF(w * self.max_value - self.size - 1, 4, self.size, self.size)
        else:
            self.min_marker = QRectF(4, h - h * self.min_value - self.size - 1, self.size, self.size)
            self.max_marker = QRectF(4, h - h * self.max_value, self.size, self.size)

        pen = painter.pen()
        pen.setWidth(0)
        pen.setColor(QApplication.palette().background().color().dark())
        painter.setPen(pen)

        painter.setBrush(self.min_marker_brush)
        painter.drawPie(self.min_marker, self.tilt * 16, 180 * 16)

        painter.setBrush(self.max_marker_brush)
        painter.drawPie(self.max_marker, self.tilt * 16, -180 * 16)

    def resizeEvent (self, resize_event):
        QFrame.resizeEvent(self, resize_event)


    def _getMinTestMarker(self):
        """Returns the "real" marker bounds. Adjusted for the missing part of an arc."""
        if self.horizontal:
            return QRectF(self.min_marker.left(),
                          self.min_marker.top(),
                          self.min_marker.width() / 2.0,
                          self.min_marker.height())
        else:
            return QRectF(self.min_marker.left(),
                          self.min_marker.top() + self.min_marker.height() / 2.0,
                          self.min_marker.width(),
                          self.min_marker.height() / 2.0)

    def _getMaxTestMarker(self):
        """Returns the "real" marker bounds. Adjusted for the missing part of an arc."""
        if self.horizontal:
            return QRectF(self.max_marker.left() + self.max_marker.width() / 2.0,
                          self.max_marker.top(),
                          self.max_marker.width() / 2.0,
                          self.max_marker.height())

        else:
            return QRectF(self.max_marker.left(),
                          self.max_marker.top(),
                          self.max_marker.width(),
                          self.max_marker.height() / 2.0)

    def mouseMoveEvent (self, mouse_event):
        """Dragging or highlighting the markers."""
        self.setDefaultColors()

        min_test_marker = self._getMinTestMarker()

        if min_test_marker.contains(mouse_event.x(), mouse_event.y()) or self.selected_marker == 'min':
            self.min_marker_brush = self.getDefaultHighlightColor()

        if self.selected_marker == 'min':
            if self.horizontal:
                value = mouse_event.x() / float(self.width())
            else:
                value = (self.height() - mouse_event.y()) / float(self.height())

            self.setMinValue(value, False)

        max_test_marker = self._getMaxTestMarker()

        if max_test_marker.contains(mouse_event.x(), mouse_event.y()) or self.selected_marker == 'max':
            self.max_marker_brush = self.getDefaultHighlightColor()

        if self.selected_marker == 'max':
            if self.horizontal:
                value = mouse_event.x() / float(self.width())
            else:
                value = (self.height() - mouse_event.y()) / float(self.height())
                
            self.setMaxValue(value, False)

        self.update()


    def mousePressEvent (self, mouse_event):
        """Selecting a marker."""
        if mouse_event.button() == Qt.LeftButton:
            min_test_marker = self._getMinTestMarker()

            if min_test_marker.contains(mouse_event.x(), mouse_event.y()):
                self.selected_marker = 'min'

            max_test_marker = self._getMaxTestMarker()

            if max_test_marker.contains(mouse_event.x(), mouse_event.y()):
                self.selected_marker = 'max'


    def mouseReleaseEvent (self, mouse_event):
        self.selected_marker = 'none'

    def leaveEvent (self, event):
        self.setDefaultColors()

    def getDefaultMarkerColor(self):
        return QApplication.palette().background().color().light(175)

    def getDefaultHighlightColor(self):
        return QApplication.palette().highlight().color()

    def setDefaultColors(self):
        self.min_marker_brush = self.getDefaultMarkerColor()
        self.max_marker_brush = self.getDefaultMarkerColor()
        self.update()

    def setMaxValue(self, max_value, update=True):
        """The the position of the max marker."""
        if self.horizontal:
            m = float(self.width())
        else:
            m = float(self.height())

        marker_offset = (self.size + 1) / m

        if not self.max_value == max_value:
            self.max_value = max_value
            if self.max_value - marker_offset <= self.min_value:
                self.max_value = self.min_value + marker_offset
            if self.max_value > 1.0:
                self.max_value = 1


            self.emit(SIGNAL('zoomValueChanged(float, float)'), self.min_value, self.max_value)

            if update:
                self.update()

    def setMinValue(self, min_value, update=True):
        """The the position of the min marker."""
        if self.horizontal:
            m = float(self.width())
        else:
            m = float(self.height())

        marker_offset = (self.size + 1) / m

        if not self.min_value == min_value:
            self.min_value = min_value
            if self.min_value + marker_offset >= self.max_value:
                self.min_value = self.max_value - marker_offset
            if self.min_value < 0.0:
                self.min_value = 0.0


            self.emit(SIGNAL('zoomValueChanged(float, float)'), self.min_value, self.max_value)

            if update:
                self.update()
Example #28
0
class XYGraphicsScene(QGraphicsScene):
    def __init__(self, parent):
        QGraphicsScene.__init__(self, parent)

        self.cc_x = 1
        self.cc_y = 2
        self.m_channels = []
        self.m_mouseLock = False
        self.m_smooth = False
        self.m_smooth_x = 0
        self.m_smooth_y = 0

        self.setBackgroundBrush(Qt.black)

        cursorPen   = QPen(QColor(255, 255, 255), 2)
        cursorBrush = QColor(255, 255, 255, 50)
        self.m_cursor = self.addEllipse(QRectF(-10, -10, 20, 20), cursorPen, cursorBrush)

        linePen = QPen(QColor(200, 200, 200, 100), 1, Qt.DashLine)
        self.m_lineH = self.addLine(-9999, 0, 9999, 0, linePen)
        self.m_lineV = self.addLine(0, -9999, 0, 9999, linePen)

        self.p_size = QRectF(-100, -100, 100, 100)

    def setControlX(self, x):
        self.cc_x = x

    def setControlY(self, y):
        self.cc_y = y

    def setChannels(self, channels):
        self.m_channels = channels

    def setPosX(self, x, forward=True):
        if not self.m_mouseLock:
            pos_x = x * (self.p_size.x() + self.p_size.width())
            self.m_cursor.setPos(pos_x, self.m_cursor.y())
            self.m_lineV.setX(pos_x)

            if forward:
                self.sendMIDI(pos_x / (self.p_size.x() + self.p_size.width()), None)
            else:
                self.m_smooth_x = pos_x

    def setPosY(self, y, forward=True):
        if not self.m_mouseLock:
            pos_y = y * (self.p_size.y() + self.p_size.height())
            self.m_cursor.setPos(self.m_cursor.x(), pos_y)
            self.m_lineH.setY(pos_y)

            if forward:
                self.sendMIDI(None, pos_y / (self.p_size.y() + self.p_size.height()))
            else:
                self.m_smooth_y = pos_y

    def setSmooth(self, smooth):
        self.m_smooth = smooth

    def setSmoothValues(self, x, y):
        self.m_smooth_x = x * (self.p_size.x() + self.p_size.width())
        self.m_smooth_y = y * (self.p_size.y() + self.p_size.height())

    def handleCC(self, param, value):
        sendUpdate = False
        xp = yp = 0.0

        if param == self.cc_x:
            sendUpdate = True
            xp = (float(value) / 63) - 1.0
            yp = self.m_cursor.y() / (self.p_size.y() + self.p_size.height())

            if xp < -1.0:
                xp = -1.0
            elif xp > 1.0:
                xp = 1.0

            self.setPosX(xp, False)

        if param == self.cc_y:
            sendUpdate = True
            xp = self.m_cursor.x() / (self.p_size.x() + self.p_size.width())
            yp = (float(value) / 63) - 1.0

            if yp < -1.0:
                yp = -1.0
            elif yp > 1.0:
                yp = 1.0

            self.setPosY(yp, False)

        if sendUpdate:
            self.emit(SIGNAL("cursorMoved(double, double)"), xp, yp)

    def handleMousePos(self, pos):
        if not self.p_size.contains(pos):
            if pos.x() < self.p_size.x():
                pos.setX(self.p_size.x())
            elif pos.x() > self.p_size.x() + self.p_size.width():
                pos.setX(self.p_size.x() + self.p_size.width())

            if pos.y() < self.p_size.y():
                pos.setY(self.p_size.y())
            elif pos.y() > self.p_size.y() + self.p_size.height():
                pos.setY(self.p_size.y() + self.p_size.height())

        self.m_smooth_x = pos.x()
        self.m_smooth_y = pos.y()

        if not self.m_smooth:
            self.m_cursor.setPos(pos)
            self.m_lineH.setY(pos.y())
            self.m_lineV.setX(pos.x())

            xp = pos.x() / (self.p_size.x() + self.p_size.width())
            yp = pos.y() / (self.p_size.y() + self.p_size.height())

            self.sendMIDI(xp, yp)
            self.emit(SIGNAL("cursorMoved(double, double)"), xp, yp)

    def sendMIDI(self, xp=None, yp=None):
        global jack_midi_out_data
        rate = float(0xff) / 4

        if xp != None:
            value = int((xp * rate) + rate)
            for channel in self.m_channels:
                jack_midi_out_data.put_nowait((0xB0 + channel - 1, self.cc_x, value))

        if yp != None:
            value = int((yp * rate) + rate)
            for channel in self.m_channels:
                jack_midi_out_data.put_nowait((0xB0 + channel - 1, self.cc_y, value))

    def updateSize(self, size):
        self.p_size.setRect(-(size.width() / 2), -(size.height() / 2), size.width(), size.height())

    def updateSmooth(self):
        if self.m_smooth:
            if self.m_cursor.x() != self.m_smooth_x or self.m_cursor.y() != self.m_smooth_y:
                if abs(self.m_cursor.x() - self.m_smooth_x) <= 0.001:
                    self.m_smooth_x = self.m_cursor.x()
                    return
                elif abs(self.m_cursor.y() - self.m_smooth_y) <= 0.001:
                    self.m_smooth_y = self.m_cursor.y()
                    return

                new_x = (self.m_smooth_x + self.m_cursor.x() * 3) / 4
                new_y = (self.m_smooth_y + self.m_cursor.y() * 3) / 4
                pos = QPointF(new_x, new_y)

                self.m_cursor.setPos(pos)
                self.m_lineH.setY(pos.y())
                self.m_lineV.setX(pos.x())

                xp = pos.x() / (self.p_size.x() + self.p_size.width())
                yp = pos.y() / (self.p_size.y() + self.p_size.height())

                self.sendMIDI(xp, yp)
                self.emit(SIGNAL("cursorMoved(double, double)"), xp, yp)

    def keyPressEvent(self, event):
        event.accept()

    def wheelEvent(self, event):
        event.accept()

    def mousePressEvent(self, event):
        self.m_mouseLock = True
        self.handleMousePos(event.scenePos())
        QGraphicsScene.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        self.handleMousePos(event.scenePos())
        QGraphicsScene.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        self.m_mouseLock = False
        QGraphicsScene.mouseReleaseEvent(self, event)
Example #29
0
class EFrameLayout(QGraphicsPolygonItem):
    def __init__(self, parent=None, scene=None):
        super(EFrameLayout, self).__init__(parent, scene)

        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setAcceptsHoverEvents(True)

        self.__name = QGraphicsTextItem()
        self.__name.setPlainText('Frame Layout')

        self.__handleWidth = 500
        self.__handleHeight = 20
        self.__separator = 5
        self.__boundExtra = 3 + self.pen().width()
        self.__handleRect = QRectF(0.0, 0.0, self.__handleWidth,
                                   self.__handleHeight)

        self.__controlsBound = 0.0
        self.__controls = []

        self.__isDefaultPen = False
        self.__isCollapsed = True

        self.__pens = {
            0: EDraw.EColor.DefaultLeaveHoverPen,
            1: EDraw.EColor.DefaultEnterHoverPen
        }
        self.setPen(self.__pens[self.__isDefaultPen])

    @property
    def Label(self):
        return self.__name.toPlainText()

    @Label.setter
    def Label(self, label):
        self.__name.setPlainText(str(label))

    @property
    def Width(self):
        return self.__handleWidth

    @Width.setter
    def Width(self, width):
        self.__handleWidth = width
        self.updateGeometry()

    def toggleContentVisibility(self):
        if not len(self.__controls): return

        if self.__controls[0].isVisible():
            [control.hide() for control in self.__controls]
            self.__isCollapsed = True
            return

        [control.show() for control in self.__controls]
        self.__isCollapsed = False

    def updateGeometry(self):

        self.__handleRect = QRectF(0.0, 0.0, self.__handleWidth,
                                   self.__handleHeight)

        if not len(self.__controls) or self.__isCollapsed:
            self.__controlsBound = 0.0
            return

        self.__controlsBound = 0.0
        self.__controlsBound = self.__separator
        self.__controlsBound += sum([
            control.boundingRect().height() + self.__separator
            for control in self.__controls
        ])

        step = self.__handleHeight + self.__separator * 2

        for control in self.__controls:

            control.Name.setTextWidth(self.__controlNameWidth)
            control.Width = self.__handleRect.normalized().adjusted(
                5.0, 0.0, -5.0, 0.0).width()

            control.setPos(5.0, step)
            step += control.boundingRect().height() + self.__separator

    def addControl(self, control):
        if not isinstance(control, EControlsGroup): raise AttributeError

        self.__controls.append(control)
        control.setParentItem(self)
        control.setFlag(QGraphicsItem.ItemIsMovable, False)

        self.__controlNameWidth = max([
            control.Name.boundingRect().width() for control in self.__controls
        ]) + 5

        self.__isCollapsed = False
        self.updateGeometry()

    def clear(self):
        [control.setParentItem(None) for control in self.__controls]
        self.__controls = []

        self.updateGeometry()

    def mouseDoubleClickEvent(self, mouseEvent):
        QGraphicsPolygonItem.mouseDoubleClickEvent(self, mouseEvent)

        self.toggleContentVisibility()
        self.updateGeometry()

    def shape(self):
        return QGraphicsItem.shape(self)

    def boundingRect(self):
        return self.__handleRect.normalized().adjusted(0.0, 0.0, 0.0,
                                                       self.__controlsBound)

    def paint(self, painter, option, widget=None):

        if not self.__isCollapsed:
            painter.setPen(QPen(QColor(0, 0, 0, 50), 2, Qt.SolidLine))
            painter.setBrush(QColor(0, 0, 0, 50))
            painter.drawRect(self.boundingRect().adjusted(
                self.pen().width(), self.__handleHeight, -self.pen().width(),
                0.0))

        painter.setPen(self.pen())
        painter.setBrush(
            EDraw.EColor.LinearGradient(self.__handleRect, Qt.darkGray))
        #painter.drawPolygon( QPolygonF( self.__handleRect.normalized().adjusted(-self.__boundExtra, 0.0, self.__boundExtra, 0.0 ) ) )
        painter.drawPolygon(QPolygonF(self.__handleRect))

        painter.setPen(Qt.lightGray)
        r = QRectF(0.0, 0.0,
                   self.__name.boundingRect().width(),
                   self.__handleRect.height())
        painter.drawText(r, Qt.AlignCenter, self.__name.toPlainText())
Example #30
0
    def draw(self, painter, size=None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport()  # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError(
                    "Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w / 5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i / nb_values))
            gr.setColorAt(i / nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [str(i) * 5 for i in range(10)]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width = max(lim_width, rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1 - length) / 2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1] - value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length * w, shift_width * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1 - shift_width - width) * w,
                                shift_length * h, width * w, length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length * w,
                                (1 - shift_width - width) * h, length * w,
                                width * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width * w, shift_length * h, width * w,
                                length * h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos - start_pos) / delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
        # Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar - max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar - max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
        #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts, t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos + shift_pos * (t - value_range[0])
            if shift_left is None:
                pos.setX(pos.x() - r.width() / 2)
            else:
                pos.setX(pos.x() + shift_left)
            if shift_top is None:
                pos.setY(pos.y() - r.height() / 2)
            else:
                pos.setY(pos.y() + shift_top)
            r.moveTo(pos)
            real_rect = painter.drawText(
                r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size * exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size * exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width() + exp_r.width() + unit_r.width()
            total_height = max(r.height(),
                               unit_r.height()) + exp_r.height() / 2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w, h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else:  # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width) / 2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x() + total_width + dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(
                    r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    exp_txt)
                bounding_rect |= real_rect
                pos.setX(pos.x() + r.width())
                pos.setY(pos.y() - metric.ascent() / 2)
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(
                    exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter,
                    ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent() / 2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(
                    unit_r,
                    Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width() * tick_size
        else:
            width = scale_rect.height() * tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos * (t - value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width,
                                               pen_width, pen_width)
        return bounding_rect
Example #31
0
class ItemMovel(QGraphicsWidget):
    rectChanged = pyqtSignal()

    def __init__(self, moveX=True, moveY=True, rect=QRectF(0, 0, 30, 30), parent=None):
        super().__init__(parent)

        self._movel = Movel(moveX, moveY, self)
        self.installEventFilter(self._movel)

        self._newPos = QPointF()
        self._oldPos = QPointF()

        self._rect = QRectF()
        self._newRect = QRectF()
        self._oldRect = QRectF()

        self._timePos = QTimeLine(1000)
        self._timePos.setCurveShape(QTimeLine.EaseInOutCurve)
        self._timePos.valueChanged.connect(self._atualizaPos)

        self._timeRect = QTimeLine(1000)
        self._timeRect.valueChanged.connect(self._atualizaRect)

        self.setTamanho(rect)

    def setMoveXY(self, x, y):
        self._movel.setMoveXY(x, y)

    def getRect(self):
        return self._rect

    def setRect(self, rect):
        self._rect = rect
        self._atualizaGeometria()

    def boundingRect(self):
        return self._rect.adjusted(-1, -1, 1, 1)

    def altura(self):
        return self._newRect.height()

    def _atualizaPos(self, t):
        # Funcao da curva que parametriza um segmento AB
        # C(t) = A + (B - A)*t
        pos = self._oldPos + (self._newPos - self._oldPos) * t

        self.setPos(pos)
        self._atualizaGeometria()

    def _atualizaRect(self, t):
        oldP1 = self._oldRect.topLeft()
        oldP2 = self._oldRect.bottomRight()

        newP1 = self._newRect.topLeft()
        newP2 = self._newRect.bottomRight()

        p1 = oldP1 + (newP1 - oldP1) * t
        p2 = oldP2 + (newP2 - oldP2) * t

        self.setRect(QRectF(p1, p2))

    def _atualizaGeometria(self):
        self.setGeometry(QRectF(self.pos(), self.pos() + self._rect.bottomRight()))

    def goto(self, pos):
        if self.pos() == pos:
            return

        if self._timePos.state() == QTimeLine.Running:
            self._timePos.stop()

        self._oldPos = self.pos()
        self._newPos = pos
        self._timePos.start()

    def setTamanho(self, tam):
        if self._rect == tam:
            return

        if self._timeRect.state() == QTimeLine.Running:
            self._timeRect.stop()

        self._oldRect = self._rect
        self._newRect = tam
        self._timeRect.start()
        self.rectChanged.emit()

    def resize(self, size):
        if isinstance(size, QRect):
            size = size.size()

        self.setTamanho(QRectF(0, 0, size.width() - 3, self._newRect.height()))

    def paint(self, painter, widget, option):
        if self._timePos.state() == QTimeLine.Running:
            currentValue = self._timePos.currentValue()
            nextValue = self._timePos.valueForTime(self._timePos.currentTime() + 100)
            painter.setBrush(QColor(255, 0, 0, (nextValue - currentValue) * 150))

        painter.drawRoundedRect(self._rect, 7, 5)
Example #32
0
 def run_loader(self):
     filename = self.result
     try:
         self.retryObject = None
         # First, prepare the data by getting the images and computing how big they
         # should be
         f = open(filename)
         first_line = f.readline()
         f.close()
         if first_line.startswith("TRKR_VERSION"):
             result = Result(None)
             result.load(self.result, **self._loading_arguments)
             result_type = "Growth"
         else:
             result = TrackingData()
             result.load(self.result, **self._loading_arguments)
             result_type = "Data"
         self.result = result
         self.result_type = result_type
         if result_type == "Data":
             data = result
             images = data.images_name
             if data.cells:
                 self.has_cells = True
                 self.has_walls = True
             else:
                 self.has_cells = False
                 self.has_walls = False
             self.has_points = bool(data.cell_points)
         else:
             data = result.data
             images = result.images
             self.has_cells = False
             self.has_walls = False
             self.has_points = False
         self.images = images
         cache = image_cache.cache
         self.update_nb_images(len(result))
         bbox = QRectF()
         ms = data.minScale()
         for i in range(len(result)):
             img_name = images[i]
             img_data = data[img_name]
             img = cache.image(data.image_path(img_name))
             matrix = QTransform()
             matrix = img_data.matrix()
             sc = QTransform()
             sc.scale(1.0 / ms, 1.0 / ms)
             matrix *= sc
             r = QRectF(img.rect())
             rbox = matrix.map(QPolygonF(r)).boundingRect()
             bbox |= rbox
             log_debug(
                 "Image '%s':\n\tSize = %gx%g\n\tTransformed = %gx%g %+g %+g\n\tGlobal bbox = %gx%g %+g %+g\n"
                 % (img_name, r.width(), r.height(), rbox.width(),
                    rbox.height(), rbox.left(), rbox.top(), bbox.width(),
                    bbox.height(), bbox.left(), bbox.top()))
             log_debug("Matrix:\n%g\t%g\t%g\n%g\t%g\t%g\n" %
                       (matrix.m11(), matrix.m12(), matrix.dx(),
                        matrix.m21(), matrix.m22(), matrix.dy()))
             if result_type == "Growth":
                 if result.cells[i]:
                     self.has_cells = True
                 if result.walls[i]:
                     self.has_walls = True
                 self.has_points = bool(result.data.cell_points)
             self.nextImage()
         translate = bbox.topLeft()
         translate *= -1
         self.translate = translate
         size = bbox.size().toSize()
         self.img_size = size
         self._crop = QRect(QPoint(0, 0), size)
         self.finished()
         self._loading_arguments = {
         }  # All done, we don't need that anymore
     except RetryTrackingDataException as ex:
         ex.filename = filename
         self.retryObject = ex
         self.finished()
         return
     except Exception as ex:
         _, _, exceptionTraceback = sys.exc_info()
         self.abort(ex, traceback=exceptionTraceback)
         raise
Example #33
0
class ENode(QGraphicsObject):

    onMove = pyqtSignal()
    onPress = pyqtSignal()

    kGuiPropertyId = EObject()
    kGuiPropertyName = EObject()

    kGuiAttribute = EObject()
    kGuiAttributeId = EObject()
    kGuiAttributeType = EObject()
    kGuiAttributePlug = EObject()
    kGuiAttributeParent = EObject()
    kGuiAttributeParentName = EObject()
    kGuiAttributeLongName = EObject()
    kGuiAttributeShortName = EObject()

    def __init__(self, eNodeHandle):
        QGraphicsObject.__init__(self)

        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setAcceptsHoverEvents(True)

        self.__isDefaultPen = False

        self.__pen = None
        self.__pens = {0: EDraw.EColor.DefaultLeaveHoverPen, 1: EDraw.EColor.DefaultEnterHoverPen}
        self.setPen(self.__pens[self.__isDefaultPen])

        self.__font = EDraw.DefaultNodeFont
        self.__nodeHandle = eNodeHandle
        self.__nodeHandle.Message.connect(self.__messageFilter)

        self.__name = self.__nodeHandle.__class__.__name__

        self.__attrRect = QRectF(0, 0, 15, 15)

        self.__titleRect = QRectF(0, 0, 135, 20)
        self.__textSpace = QRectF(self.__attrRect.width() + self.pen().width(), 0.0,
                                  (self.__titleRect.width() - self.__attrRect.width() * 2 - self.pen().width() * 2) / 2,
                                  self.__attrRect.height())

        self.buildAttributes()

        self.__height = max([self.__in_attr_step, self.__out_attr_step])

    def __messageFilter(self, message):
        if message.matches(self.__nodeHandle.kMessageAttributeAdded):
            self.__buildAttribute(message.getData())

        if message.matches(self.__nodeHandle.kMessageAttributeRemoved):

            print message.getData()

            self.__attributes = {}
            self.__properties = {}
            self.buildAttributes()

    def __getAttrShortName(self, attributeName):
        fm = QFontMetrics(self.__font)

        shortName = ''

        if fm.width(attributeName) > self.__textSpace.width():

            for x in range(len(attributeName) + 1):
                if fm.width(shortName) > int(self.__textSpace.width()) - 10:
                    return shortName

                shortName = attributeName[:x] + '...'

        return attributeName

    def __getAttributePosition(self, opposite=False):

        attr_x_pos = 0

        if opposite:

            attr_x_pos = self.__titleRect.width() - self.__attrRect.width()
            rect = self.__attrRect.translated(QPointF(attr_x_pos, self.__out_attr_step))

            point = QPointF((rect.topRight() + rect.bottomRight()) / 2)
            point.setX(point.x() + self.pen().width() * 2)

            self.__out_attr_step += self.__attrRect.width() + self.pen().width()

            return [rect, point]

        rect = self.__attrRect.translated(QPointF(attr_x_pos, self.__in_attr_step))
        point = QPointF((rect.topLeft() + rect.bottomLeft()) / 2)
        point.setX(point.x() - self.pen().width() * 2)

        self.__in_attr_step += self.__attrRect.width() + self.pen().width()

        return [rect, point]

    def __buildAttribute(self, attribute, opposite=False):

        """
        if not attribute.Type.matches(EAttribute.kTypeGenericInput) and not attribute.Type.matches(EAttribute.kTypeGenericOutput):

            self.__properties[attribute.Id] = dict({self.kGuiPropertyId: attribute.Id,
                                                    self.kGuiPropertyName: attribute.Name})
            return
        """

        data = self.__getAttributePosition(opposite)

        self.__attributes[data[0]] = dict({self.kGuiAttributeId: attribute.Id,
                                           self.kGuiAttributeType: attribute.Type,
                                           self.kGuiAttributeParent: self,
                                           self.kGuiAttributePlug: data[1],
                                           self.kGuiAttributeLongName: attribute.Name,
                                           self.kGuiAttributeShortName: self.__getAttrShortName(attribute.Name)})

        self.__height = max([self.__in_attr_step, self.__out_attr_step])

        self.update()
        self.onMove.emit()

    def buildAttributes(self):

        self.__attributes = {}
        self.__properties = {}

        self.__out_attr_step = self.__titleRect.height() + self.pen().width()
        self.__in_attr_step = self.__titleRect.height() + self.pen().width()

        for eddAttr in self.__nodeHandle.lsInputAttributes():
            self.__buildAttribute(eddAttr)

        for eddAttr in self.__nodeHandle.lsOutputAttributes():
            self.__buildAttribute(eddAttr, True)

        self.update()

    def __toggleHighlight(self):
        if self.__isDefaultPen:
            self.__isDefaultPen = False
            self.setPen(self.__pens[self.__isDefaultPen])
            #self.setZValue(0.0)
            return

        self.__isDefaultPen = True
        self.setPen(self.__pens[self.__isDefaultPen])
        #self.setZValue(-2.0)

    def mute(self, uuid):
        pass

    @property
    def Id(self):
        return self.__nodeHandle.Id

    @property
    def Name(self):
        return self.__name

    @Name.setter
    def Name(self, newName):
        self.__name = newName

    def pen(self):
        return self.__pen

    def setPen(self, pen):
        if not isinstance(pen, QPen):
            raise AttributeError

        self.__pen = pen

    @property
    def Font(self):
        return self.__font

    @Font.setter
    def Font(self, QFont):
        self.__font = QFont

    @property
    def Handle(self):
        return self.__nodeHandle

    @property
    def Properties(self):
        return self.__properties

    def mapFromPoint(self, QPoint):

        for attrRect, attrValues in self.__attributes.iteritems():
            if attrRect.contains(self.mapFromScene(QPoint)):
                return attrValues[self.kGuiAttributeId], QPoint

        return self.__nodeHandle.Id, None

    def mapFromId(self, attrId):

        for attrValue in self.__attributes.itervalues():
            if attrValue[self.kGuiAttributeId] == attrId:
                return attrValue

        return None

    def hoverEnterEvent(self, mouseEvent):
        QGraphicsObject.hoverEnterEvent(self, mouseEvent)
        self.__toggleHighlight()

    def hoverMoveEvent(self, mouseEvent):
        QGraphicsObject.hoverMoveEvent(self, mouseEvent)

    def hoverLeaveEvent(self, mouseEvent):
        QGraphicsObject.hoverLeaveEvent(self, mouseEvent)
        self.__toggleHighlight()

    def mousePressEvent(self, mouseEvent):
        QGraphicsObject.mousePressEvent(self, mouseEvent)

        #if mouseEvent.button() == Qt.RightButton:
        #print self.mapFromPoint(mouseEvent.scenePos())
        self.onPress.emit()

    def mouseDoubleClickEvent(self, mouseEvent):
        QGraphicsObject.mouseDoubleClickEvent(self, mouseEvent)

        #self.__nodeHandle.compute()

    def mouseMoveEvent(self, mouseEvent):
        QGraphicsObject.mouseMoveEvent(self, mouseEvent)
        self.onMove.emit()

    def boundingRect(self):
        extra = self.pen().width()
        return self.__titleRect.normalized().adjusted(-extra, -extra, extra,
                                                      (self.__height - self.__titleRect.height()) + extra)

    def shape(self):
        return QGraphicsItem.shape(self)

    def paint(self, painter, option, widget=None):

        painter.setBrush(EDraw.EColor.DefaultNodeFillColor)

        painter.setPen(self.pen())
        painter.drawRect(self.boundingRect())

        painter.setPen(Qt.NoPen)

        painter.setBrush(EDraw.EColor.DefaultTitleColor)
        painter.drawRect(self.__titleRect)

        painter.setPen(EDraw.EColor.DefaultTitleTextColor)
        painter.drawText(self.__titleRect, Qt.AlignCenter, self.__name)

        painter.setPen(Qt.NoPen)
        painter.setBrush(EDraw.EColor.DefaultAttributeFillColor)

        for rect in self.__attributes.iterkeys():
            painter.drawRect(rect)

        painter.setBrush(Qt.darkGray)
        for rect in self.__attributes.iterkeys():
            painter.drawPolygon(EDraw.Circle(rect.height() / 3, 3).translated(rect.center()))

        painter.setPen(QPen(QColor(43, 43, 43), 1.0, Qt.SolidLine))
        painter.setBrush(Qt.NoBrush)

        for attrRect, attrValues in self.__attributes.iteritems():

            attrNameRect = self.__textSpace.translated(attrRect.topLeft())
            align = Qt.AlignLeft

            if attrRect.topLeft().x() > 0:
                attrNameRect = self.__textSpace.translated(
                    QPointF((self.__titleRect.width() / 2) - (attrRect.width() + self.pen().width()),
                            attrRect.topLeft().y()))

                align = Qt.AlignRight

            painter.drawText(attrNameRect, align,  attrValues[self.kGuiAttributeShortName])
Example #34
0
class GradientLegendItem(QGraphicsObject, GraphicsWidgetAnchor):
    gradient_width = 20

    def __init__(self, title, palette, values, parent):
        QGraphicsObject.__init__(self, parent)
        GraphicsWidgetAnchor.__init__(self)
        self.parent = self.legend = parent
        self.palette = palette
        self.values = values

        self.title = QGraphicsTextItem('%s:' % title, self)
        f = self.title.font()
        f.setBold(True)
        self.title.setFont(f)
        self.title_item = QGraphicsRectItem(self.title.boundingRect(), self)
        self.title_item.setPen(QPen(Qt.NoPen))
        self.title_item.stackBefore(self.title)

        self.label_items = [QGraphicsTextItem(text, self) for text in values]
        for i in self.label_items:
            i.setTextWidth(50)

        self.rect = QRectF()

        self.gradient_item = QGraphicsRectItem(self)
        self.gradient = QLinearGradient()
        self.gradient.setStops([(v * 0.1, self.palette[v * 0.1])
                                for v in range(11)])
        self.orientation = Qt.Horizontal
        self.set_orientation(Qt.Vertical)

        self.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)
        self.setFlag(QGraphicsItem.ItemIsMovable, True)

    def set_orientation(self, orientation):
        return
        if self.orientation == orientation:
            return

        self.orientation = orientation

        if self.orientation == Qt.Vertical:
            height = max(item.boundingRect().height()
                         for item in self.label_items)
            total_height = height * max(5, len(self.label_items))
            interval = (total_height -
                        self.label_items[-1].boundingRect().height()
                        ) / (len(self.label_items) - 1)
            self.gradient_item.setRect(10, 0, self.gradient_width, total_height)
            self.gradient.setStart(10, 0)
            self.gradient.setFinalStop(10, total_height)
            self.gradient_item.setBrush(QBrush(self.gradient))
            self.gradient_item.setPen(QPen(Qt.NoPen))
            y = -20   # hja, no; dela --> pri boundingRect() zato pristejem +20
            x = 0
            move_item_xy(self.title, x, y, False)
            y = 10
            x = 30
            for item in self.label_items:
                move_item_xy(item, x, y, False)
                                       # self.parent.graph.animate_plot)
                y += interval
            self.rect = QRectF(10, 0,
                               self.gradient_width +
                               max(item.boundingRect().width()
                                   for item in self.label_items),
                               self.label_items[0].boundingRect().height() *
                               max(5, len(self.label_items)))
        else:
            # za horizontalno orientacijo nisem dodajal title-a
            width = 50
            height = max(item.boundingRect().height()
                         for item in self.label_items)
            total_width = width * max(5, len(self.label_items))
            interval = (total_width -
                        self.label_items[-1].boundingRect().width()
                        ) / (len(self.label_items) - 1)

            self.gradient_item.setRect(0, 0, total_width, self.gradient_width)
            self.gradient.setStart(0, 0)
            self.gradient.setFinalStop(total_width, 0)
            self.gradient_item.setBrush(QBrush(self.gradient))
            self.gradient_item.setPen(QPen(Qt.NoPen))
            x = 0
            y = 30
            for item in self.label_items:
                move_item_xy(item, x, y, False)
                                       # self.parent.graph.animate_plot)
                x += interval
            self.rect = QRectF(0, 0, total_width, self.gradient_width + height)

    # noinspection PyPep8Naming
    def boundingRect(self):
        width = max(self.rect.width(), self.title_item.boundingRect().width())
        height = self.rect.height() + self.title_item.boundingRect().height()
        return QRectF(self.rect.left(), self.rect.top(), width, height)

    def paint(self, painter, option, widget):
        pass
Example #35
0
class QGraphicsListData(QGraphicsItem):
    '''
    classdocs
    '''

    _editName = ""

    def __init__(self, qScore, parent=None):
        '''
        Constructor
        '''
        super(QGraphicsListData, self).__init__(parent=parent, scene=qScore)
        self._qScore = qScore
        self._props = qScore.displayProperties
        self._rect = QRectF(0, 0, 0, 0)
        self.setRect()
        self.setCursor(Qt.PointingHandCursor)
        self.setAcceptsHoverEvents(True)

    def _iterData(self):
        raise NotImplementedError()

    def _dataLen(self):
        raise NotImplementedError()

    def font(self):
        raise NotImplementedError()

    def setRect(self, fm=None):
        if fm is None:
            font = self.font()
            if font is None:
                return
            fm = QFontMetrics(font)
        lineHeight = fm.height()
        height = lineHeight * self._dataLen() * 1.1
        width = max(fm.width(data) for data in self._iterData()) + 10
        if height != self._rect.height() or width != self._rect.width():
            self.prepareGeometryChange()
            self._rect.setBottomRight(QPointF(width, height))

    def boundingRect(self):
        return self._rect

    def paint(self, painter, dummyOption, dummyWidget=None):
        painter.save()
        try:
            font = self.font()
            if font is None:
                font = painter.font()
            else:
                painter.setFont(font)
            fm = QFontMetrics(painter.font())
            self.setRect(fm)
            lineHeight = fm.height()
            for index, data in enumerate(self._iterData()):
                painter.drawText(QPoint(5, (index + 1) * lineHeight), data)
        finally:
            painter.restore()

    def fontChanged(self):
        self.update()

    def update(self):
        self.setRect()
        super(QGraphicsListData, self).update()

    def hoverEnterEvent(self, *args, **kwargs):
        self._qScore.setStatusMessage("Double click to edit %s." %
                                      self._editName)
        return super(QGraphicsListData, self).hoverEnterEvent(*args, **kwargs)

    def hoverLeaveEvent(self, *args, **kwargs):
        self._qScore.setStatusMessage()
        return super(QGraphicsListData, self).hoverLeaveEvent(*args, **kwargs)
Example #36
0
class DrawManager(QObject):
    """
    DEPRECATED.
    Will be replaced with BrushingModel, BrushingControler, BrushStroke.
    """
     
    brushSizeChanged  = pyqtSignal(int)
    brushColorChanged = pyqtSignal(QColor)
    
    minBrushSize       = 1
    maxBrushSize       = 61
    defaultBrushSize   = 3
    defaultDrawnNumber = 1
    defaultColor       = Qt.white
    erasingColor       = Qt.black
    
    def __init__(self):
        QObject.__init__(self)
        self.shape = None
        self.bb    = QRect() #bounding box enclosing the drawing
        self.brushSize = self.defaultBrushSize
        self.drawColor = self.defaultColor
        self.drawnNumber = self.defaultDrawnNumber

        self.penVis  = QPen(self.drawColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        self.penDraw = QPen(self.drawColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        self.pos = None
        self.erasing = False
        
        #on which layer do we want to draw when self.drawingEnabled?
        self.drawOnto = None
        
        #an empty scene, where we add all drawn line segments
        #a QGraphicsLineItem, and which we can use to then
        #render to an image
        self.scene = QGraphicsScene()

    def growBoundingBox(self):
        self.bb.setLeft(  max(0, self.bb.left()-self.brushSize-1))
        self.bb.setTop(   max(0, self.bb.top()-self.brushSize-1 ))
        self.bb.setRight( min(self.shape[0], self.bb.right()+self.brushSize+1))
        self.bb.setBottom(min(self.shape[1], self.bb.bottom()+self.brushSize+1))

    def toggleErase(self):
        self.erasing = not(self.erasing)

    def setErasing(self):
        self.erasing = True
        self.brushColorChanged.emit(self.erasingColor)
    
    def disableErasing(self):
        self.erasing = False
        self.brushColorChanged.emit(self.drawColor)

    def setBrushSize(self, size):
        self.brushSize = size
        self.penVis.setWidth(size)
        self.penDraw.setWidth(size)
        self.brushSizeChanged.emit(self.brushSize)
    
    def setDrawnNumber(self, num):
        self.drawnNumber = num
        self.drawnNumberChanged.emit(num)
        
    def getBrushSize(self):
        return self.brushSize
    
    def brushSmaller(self):
        b = self.brushSize
        if b > self.minBrushSize:
            self.setBrushSize(b-1)
        
    def brushBigger(self):
        b = self.brushSize
        if self.brushSize < self.maxBrushSize:
            self.setBrushSize(b+1)
        
    def setBrushColor(self, color):
        self.drawColor = color
        self.penVis.setColor(color)
        self.emit.brushColorChanged(self.drawColor)
        
    def beginDrawing(self, pos, shape):
        self.shape = shape
        self.bb = QRectF(0, 0, self.shape[0], self.shape[1])
        self.scene.clear()
        if self.erasing:
            self.penVis.setColor(self.erasingColor)
        else:
            self.penVis.setColor(self.drawColor)
        self.pos = QPointF(pos.x()+0.0001, pos.y()+0.0001)
        line = self.moveTo(pos)
        return line

    def endDrawing(self, pos):
        self.moveTo(pos)
        self.growBoundingBox()

        tempi = QImage(QSize(self.bb.width(), self.bb.height()), QImage.Format_ARGB32_Premultiplied) #TODO: format
        tempi.fill(0)
        painter = QPainter(tempi)
        
        self.scene.render(painter, QRectF(QPointF(0,0), self.bb.size()), self.bb)
        
        return (self.bb.left(), self.bb.top(), tempi) #TODO: hackish, probably return a class ??

    def dumpDraw(self, pos):
        res = self.endDrawing(pos)
        self.beginDrawing(pos, self.shape)
        return res

    def moveTo(self, pos):    
        lineVis = QGraphicsLineItem(self.pos.x(), self.pos.y(), pos.x(), pos.y())
        lineVis.setPen(self.penVis)
        
        line = QGraphicsLineItem(self.pos.x(), self.pos.y(), pos.x(), pos.y())
        line.setPen(self.penDraw)
        self.scene.addItem(line)

        self.pos = pos
        x = pos.x()
        y = pos.y()
        #update bounding Box :
        if x > self.bb.right():
            self.bb.setRight(x)
        if x < self.bb.left():
            self.bb.setLeft(x)
        if y > self.bb.bottom():
            self.bb.setBottom(y)
        if y < self.bb.top():
            self.bb.setTop(y)
        return lineVis
Example #37
0
class DrawableActor(DrawableNode, QGraphicsItem):
    def __init__(self, uml_object):
        super(DrawableActor, self).__init__(uml_object)
        QGraphicsItem.__init__(self)
        self.__bounding_rect = QRectF(0, 0, 100, 100)
        self.__font = Drawable.get_font()
        self.__sectionMargin = 5
        self.__text_margin = 3

        self.setFlag(QGraphicsItem.ItemIsMovable, 1)
        self.setFlag(QGraphicsItem.ItemIsSelectable, 1)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, 1)
        
        self.__actor_rectangle = QRectF(0, 0, 40, 80)
        
        self.__actor_name_text = DrawableText.create_drawable_text(self)

    def boundingRect(self):
        return self.__bounding_rect

    def paint(self, painter, style, widget):
        metrics = QFontMetrics(self.__font)
        painter.setFont(self.__font)
        painter.setPen(QColor(0, 0, 0))
        painter.fillRect(QRectF(self.__bounding_rect), QBrush(QColor(255, 255, 255), Qt.SolidPattern))

        painter.setRenderHint(QPainter.Antialiasing, True)
        
        head_rad = math.ceil(self.__actor_rectangle.height() / 3)
        center = self.__actor_rectangle.width() / 2
        head_start = center - head_rad / 2
        
        painter.drawEllipse(head_start,0,head_rad,head_rad)
        
        painter.drawLine(0, head_rad * 1.3, self.__actor_rectangle.width(), head_rad * 1.3)
        painter.drawLine(center, head_rad, center, head_rad*2)
        
        painter.drawLine(center, head_rad * 2, 0, self.__actor_rectangle.height())
        painter.drawLine(center, head_rad * 2, self.__actor_rectangle.width(), self.__actor_rectangle.height())
        
        painter.setRenderHint(QPainter.Antialiasing, False)

    def update(self):
        metrics = QFontMetrics(self.__font)
        
        self.__bounding_rect = QRectF(self.__actor_rectangle)
        globalRect = self.globalBoundingRect()
        
        # TODO: This again
        if "name" not in self.uml_object.properties:
            self.uml_object["name"] = self.uml_object.name
            
        self.__actor_name_text.text = self.uml_object["name"]
        self.__actor_name_text.origin_pos = QPointF(globalRect.x() + globalRect.width() / 2, 
                                                    globalRect.y() + globalRect.height())
        self.__actor_name_text.reset_vector = QPointF(- metrics.width(self.uml_object["name"]) / 2, 0)
        if(not self.__actor_name_text.isVisible()):
            self.__actor_name_text.reset_pos()
            self.__actor_name_text.setVisible(True)            

    def crop_line(self, line, line_point):
        global_rect = self.globalBoundingRect()
        
        vertexes = [global_rect.topLeft(), global_rect.topRight(),
                  global_rect.bottomRight(), global_rect.bottomLeft()]
        
        intersection_point = QPointF()
        
        # Iterate over pairs of vertexes that make rectangle edges
        for (a, b) in [(0, 1), (1, 2), (2, 3), (3, 0)]:
            bok = QLineF(vertexes[a], vertexes[b])
            itype = line.intersect(bok, intersection_point)
            if(itype == QLineF.BoundedIntersection):
                if(line_point == 0):
                    return QLineF(intersection_point, line.p2())
                else:
                    return QLineF(line.p1(), intersection_point)
        
        return line
        
    def find_anchor(self):
        return self.globalBoundingRect().center()

    def itemChange(self, change, value):
        if(change == QGraphicsItem.ItemPositionChange):
            for anchor in self.anchors:
                anchor.connector.update()
                self.resize_scene_rect()
                
        return QGraphicsItem.itemChange(self, change, value)
Example #38
0
    def draw(self, painter, size = None):
        """
        :Arguments:
            painter : QPainter
                Opened painter on which to draw
        """
        bounding_rect = QRectF()
        position = self.position
        transfer_function = self.transfer_function
        font = QFont(self.font)
        text_color = self.text_color
        line_color = self.line_color
        line_thickness = self.line_thickness
        value_range = self.value_range
        if size is None:
            viewport = painter.viewport() # viewport rectangle
            mat, ok = painter.worldMatrix().inverted()
            if not ok:
                raise ValueError("Transformation matrix of painter is singular.")
            viewport = mat.mapRect(viewport)
        else:
            viewport = size
# First, prepare the gradient
        w = viewport.width()
        h = viewport.height()
        #print("Size of viewport: {0}x{1}".format(w, h))
        gr = QLinearGradient()
        nb_values = ceil(w/5.0)
        brush_color = QColor()
        for i in range(int(nb_values)):
            brush_color.setRgbF(*transfer_function.rgba(i/nb_values))
            gr.setColorAt(i/nb_values, brush_color)
# Second, find its position
        metric = QFontMetricsF(font, painter.device())
        font_test = [ str(i)*5 for i in range(10) ]
        lim_width = 0
        lim_height = 0
        for t in font_test:
            rect = metric.boundingRect(t)
            lim_width  = max(lim_width,  rect.width())
            lim_height = max(lim_height, rect.height())
        lim_height *= 3
        length = self.scale_length
        shift_length = (1-length)/2
        width = self.scale_width
        shift_width = self.scale_shift_width
        delta_value = value_range[1]-value_range[0]
        if position == "Top":
            scale_rect = QRectF(shift_length*w, shift_width*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.bottomRight()
        elif position == "Right":
            scale_rect = QRectF((1-shift_width-width)*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomLeft()
            end_pos = scale_rect.topLeft()
        elif position == "Bottom":
            scale_rect = QRectF(shift_length*w, (1-shift_width-width)*h, length*w, width*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.left(), scale_rect.center().y())
            gr.setFinalStop(scale_rect.right(), scale_rect.center().y())
            start_pos = scale_rect.topLeft()
            end_pos = scale_rect.topRight()
        elif position == "Left":
            scale_rect = QRectF(shift_width*w, shift_length*h, width*w, length*h)
            limit_rect(scale_rect, viewport, lim_width, lim_height)
            gr.setStart(scale_rect.center().x(), scale_rect.bottom())
            gr.setFinalStop(scale_rect.center().x(), scale_rect.top())
            start_pos = scale_rect.bottomRight()
            end_pos = scale_rect.topRight()
        else:
            raise ValueError("Invalid scale position: %s" % position)
        shift_pos = (end_pos-start_pos)/delta_value
        if position in ["Left", "Right"]:
            is_vertical = True
            length = scale_rect.height()
        else:
            is_vertical = False
            length = scale_rect.width()
# Get the ticks
        ticks = self.selectValues(length, is_vertical, painter)
        if len(ticks) == 0:
            return
        ticks_str, ticks_extra = self._tick2str(ticks)
# Figure the shifts
        dist_to_bar = self.text_to_bar
        max_width = 0
        max_height = 0
        for t in ticks_str:
            rect = metric.boundingRect(t)
            max_width = max(rect.width(), max_width)
            max_height = max(rect.height(), max_height)
        if position == "Left":
            shift_left = dist_to_bar
            shift_top = None
        elif position == "Right":
            shift_left = -dist_to_bar-max_width
            shift_top = None
        elif position == "Top":
            shift_left = None
            shift_top = dist_to_bar
        else:
            shift_left = None
            shift_top = -dist_to_bar-max_height
        painter.save()
        painter.translate(viewport.topLeft())
        #print("viewport.topLeft() = {0}x{1}".format(viewport.left(), viewport.top()))
        painter.setBrush(gr)
        line_pen = QPen(line_color)
        line_pen.setWidth(line_thickness)
        painter.setPen(line_pen)
        painter.drawRect(scale_rect)
        bounding_rect |= scale_rect
        #print("Scale rect: +{0}+{1}x{2}x{3}".format(scale_rect.left(),
            #scale_rect.top(), scale_rect.width(), scale_rect.height()))
        painter.setFont(font)
        painter.setPen(text_color)
        for ts,t in zip(ticks_str, ticks):
            r = metric.boundingRect(ts)
            pos = start_pos+shift_pos*(t-value_range[0])
            if shift_left is None:
                pos.setX( pos.x() - r.width()/2 )
            else:
                pos.setX( pos.x() + shift_left )
            if shift_top is None:
                pos.setY( pos.y() - r.height()/2)
            else:
                pos.setY( pos.y() + shift_top )
            r.moveTo(pos)
            real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ts)
            bounding_rect |= real_rect
        if ticks_extra is not None or self.unit:
            unit = self.unit
            exp_width = width = space_width = 0
            exp_txt = ""
            r = exp_r = unit_r = QRectF()
            exp_font = None
            if ticks_extra is not None:
                exp_txt = u"×10"
                r = metric.boundingRect(exp_txt)
                exp_font = QFont(font)
                exp_size = self.exp_size
                if exp_font.pixelSize() != -1:
                    exp_font.setPixelSize(exp_size*exp_font.pixelSize())
                else:
                    exp_font.setPointSizeF(exp_size*exp_font.pointSizeF())
                exp_metric = QFontMetricsF(exp_font, painter.device())
                exp_r = exp_metric.boundingRect(ticks_extra)
            if unit:
                unit_r = metric.boundingRect(unit)
            total_width = r.width()+exp_r.width()+unit_r.width()
            total_height = max(r.height(),unit_r.height())+exp_r.height()/2
            pos = scale_rect.topRight()
            log_debug("top right of scale bar = (%g,%g)" % (pos.x(), pos.y()))
            log_debug("Size of image = (%d,%d)" % (w,h))
            log_debug("Size of text = (%g,%g)" % (total_width, total_height))
            if position == "Bottom":
                pos.setY(pos.y() + scale_rect.height() + dist_to_bar)
                pos.setX(pos.x() - total_width)
            elif position == "Top":
                pos.setY(pos.y() - dist_to_bar - total_height)
                pos.setX(pos.x() - total_width)
            else: # position == "left" or "right"
                pos.setX(pos.x() - (scale_rect.width() + total_width)/2)
                if pos.x() < 0:
                    pos.setX(dist_to_bar)
                elif pos.x()+total_width+dist_to_bar > w:
                    pos.setX(w - total_width - dist_to_bar)
                pos.setY(pos.y() - dist_to_bar - total_height)
            log_debug("Display unit at position: (%g,%g)" % (pos.x(), pos.y()))

            if ticks_extra is not None:
                r.moveTo(pos)
                real_rect = painter.drawText(r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, exp_txt)
                bounding_rect |= real_rect
                pos.setX( pos.x() + r.width() )
                pos.setY( pos.y() - metric.ascent()/2 )
                exp_r.moveTo(pos)
                painter.setFont(exp_font)
                real_rect = painter.drawText(exp_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, ticks_extra)
                bounding_rect |= real_rect
                pos.setY(pos.y() + metric.ascent()/2)
            if unit:
                pos.setX(pos.x() + space_width + exp_r.width())
                unit_r.moveTo(pos)
                painter.setFont(font)
                real_rect = painter.drawText(unit_r, Qt.TextDontClip | Qt.AlignVCenter | Qt.AlignHCenter, unit)
                bounding_rect |= real_rect
        # Draw the ticks now
        painter.setPen(line_pen)
        tick_size = self.tick_size
        if is_vertical:
            width = scale_rect.width()*tick_size
        else:
            width = scale_rect.height()*tick_size
        pen_width = painter.pen().widthF()
        if pen_width == 0:
            pen_width = 1.0
        for t in ticks:
            pos1 = start_pos + shift_pos*(t-value_range[0])
            pos2 = QPointF(pos1)
            if is_vertical:
                pos1.setX(scale_rect.left() + pen_width)
                pos2.setX(pos1.x() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setX(scale_rect.right() - pen_width)
                pos2.setX(pos1.x() - width + pen_width)
                painter.drawLine(pos1, pos2)
            else:
                pos1.setY(scale_rect.top() + pen_width)
                pos2.setY(pos1.y() + width - pen_width)
                painter.drawLine(pos1, pos2)
                pos1.setY(scale_rect.bottom() - pen_width)
                pos2.setY(pos1.y() - width + pen_width)
                painter.drawLine(pos1, pos2)
        painter.restore()
        bounding_rect = bounding_rect.adjusted(-pen_width, -pen_width, pen_width, pen_width)
        return bounding_rect
Example #39
0
class ZoomSlider(QFrame):
    """
    Two way slider representing narrowing of a view.
    The sliders coorespond to factors: a min value and a max value in the range [0, 1]
    Emits zoomValueChanged(float, float) whenever the markers are adjusted. (float, float) -> (min, max)
    """
    def __init__(self, parent=None, horizontal=True):
        QFrame.__init__(self, parent)

        self.horizontal = horizontal
        if horizontal:
            self.setFrameShape(QFrame.HLine)
            self.setMinimumHeight(21)
            self.tilt = 90
        else:
            self.setFrameShape(QFrame.VLine)
            self.setMinimumWidth(21)
            self.tilt = 180

        self.setFrameShadow(QFrame.Sunken)
        self.setMidLineWidth(3)

        self.setMouseTracking(True)

        self.size = 12

        self.min_value = 0.0
        self.max_value = 1.0

        self.setDefaultColors()
        self.button = Qt.NoButton
        self.selected_marker = 'none'

    def paintEvent(self, paint_event):
        QFrame.paintEvent(self, paint_event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        w = self.width()
        h = self.height()

        if self.horizontal:
            self.min_marker = QRectF(w * self.min_value, 4, self.size,
                                     self.size)
            self.max_marker = QRectF(w * self.max_value - self.size - 1, 4,
                                     self.size, self.size)
        else:
            self.min_marker = QRectF(4, h - h * self.min_value - self.size - 1,
                                     self.size, self.size)
            self.max_marker = QRectF(4, h - h * self.max_value, self.size,
                                     self.size)

        pen = painter.pen()
        pen.setWidth(0)
        pen.setColor(QApplication.palette().background().color().dark())
        painter.setPen(pen)

        painter.setBrush(self.min_marker_brush)
        painter.drawPie(self.min_marker, self.tilt * 16, 180 * 16)

        painter.setBrush(self.max_marker_brush)
        painter.drawPie(self.max_marker, self.tilt * 16, -180 * 16)

    def resizeEvent(self, resize_event):
        QFrame.resizeEvent(self, resize_event)

    def _getMinTestMarker(self):
        """Returns the "real" marker bounds. Adjusted for the missing part of an arc."""
        if self.horizontal:
            return QRectF(self.min_marker.left(), self.min_marker.top(),
                          self.min_marker.width() / 2.0,
                          self.min_marker.height())
        else:
            return QRectF(
                self.min_marker.left(),
                self.min_marker.top() + self.min_marker.height() / 2.0,
                self.min_marker.width(),
                self.min_marker.height() / 2.0)

    def _getMaxTestMarker(self):
        """Returns the "real" marker bounds. Adjusted for the missing part of an arc."""
        if self.horizontal:
            return QRectF(
                self.max_marker.left() + self.max_marker.width() / 2.0,
                self.max_marker.top(),
                self.max_marker.width() / 2.0, self.max_marker.height())

        else:
            return QRectF(self.max_marker.left(), self.max_marker.top(),
                          self.max_marker.width(),
                          self.max_marker.height() / 2.0)

    def mouseMoveEvent(self, mouse_event):
        """Dragging or highlighting the markers."""
        self.setDefaultColors()

        min_test_marker = self._getMinTestMarker()

        if min_test_marker.contains(
                mouse_event.x(),
                mouse_event.y()) or self.selected_marker == 'min':
            self.min_marker_brush = self.getDefaultHighlightColor()

        if self.selected_marker == 'min':
            if self.horizontal:
                value = mouse_event.x() / float(self.width())
            else:
                value = (self.height() - mouse_event.y()) / float(
                    self.height())

            self.setMinValue(value, False)

        max_test_marker = self._getMaxTestMarker()

        if max_test_marker.contains(
                mouse_event.x(),
                mouse_event.y()) or self.selected_marker == 'max':
            self.max_marker_brush = self.getDefaultHighlightColor()

        if self.selected_marker == 'max':
            if self.horizontal:
                value = mouse_event.x() / float(self.width())
            else:
                value = (self.height() - mouse_event.y()) / float(
                    self.height())

            self.setMaxValue(value, False)

        self.update()

    def mousePressEvent(self, mouse_event):
        """Selecting a marker."""
        if mouse_event.button() == Qt.LeftButton:
            min_test_marker = self._getMinTestMarker()

            if min_test_marker.contains(mouse_event.x(), mouse_event.y()):
                self.selected_marker = 'min'

            max_test_marker = self._getMaxTestMarker()

            if max_test_marker.contains(mouse_event.x(), mouse_event.y()):
                self.selected_marker = 'max'

    def mouseReleaseEvent(self, mouse_event):
        self.selected_marker = 'none'

    def leaveEvent(self, event):
        self.setDefaultColors()

    def getDefaultMarkerColor(self):
        return QApplication.palette().background().color().light(175)

    def getDefaultHighlightColor(self):
        return QApplication.palette().highlight().color()

    def setDefaultColors(self):
        self.min_marker_brush = self.getDefaultMarkerColor()
        self.max_marker_brush = self.getDefaultMarkerColor()
        self.update()

    def setMaxValue(self, max_value, update=True):
        """The the position of the max marker."""
        if self.horizontal:
            m = float(self.width())
        else:
            m = float(self.height())

        marker_offset = (self.size + 1) / m

        if not self.max_value == max_value:
            self.max_value = max_value
            if self.max_value - marker_offset <= self.min_value:
                self.max_value = self.min_value + marker_offset
            if self.max_value > 1.0:
                self.max_value = 1

            #print "max:", self.min_value, self.max_value

            self.emit(SIGNAL('zoomValueChanged(float, float)'), self.min_value,
                      self.max_value)

            if update:
                self.update()

    def setMinValue(self, min_value, update=True):
        """The the position of the min marker."""
        if self.horizontal:
            m = float(self.width())
        else:
            m = float(self.height())

        marker_offset = (self.size + 1) / m

        if not self.min_value == min_value:
            self.min_value = min_value
            if self.min_value + marker_offset >= self.max_value:
                self.min_value = self.max_value - marker_offset
            if self.min_value < 0.0:
                self.min_value = 0.0

            #print "min:", self.min_value, self.max_value

            self.emit(SIGNAL('zoomValueChanged(float, float)'), self.min_value,
                      self.max_value)

            if update:
                self.update()
Example #40
0
    def setAxisIntersect(self, intersect):
        self._axisIntersect = intersect
        #print "SkeletonsLayer(axis=%d) is updating intersect=%d" % (self._axis, self._axisIntersect)

        nodes, eIntersected, ePlane = self._3d._skeletons.intersect(
            self._axis, self._axisIntersect)

        #update existing items
        toRemove = []
        for node, item in self._node2view.iteritems():
            if node.pos[self._axis] != self._axisIntersect:
                self._scene.removeItem(item)
                toRemove.append(node)
            elif node.pointF(self._axis) != item.pos():
                item.setPos(self._scene.data2scene.map(node.pointF(
                    self._axis)))
            if node.isSelected() != item.isSelected():
                item.setSelected(node.isSelected())
                assert item.isSelected() == node.isSelected()
            i = 0
            newSize = [0, 0]
            for j in range(3):
                if j == self._axis:
                    continue
                newSize[i] = node.shape[j]
                i += 1
            newRectF = QRectF(0, 0, *newSize)
            newRectF = self._scene.data2scene.mapRect(newRectF)

            item.setRect(
                QRectF(-newRectF.width() / 2.0, -newRectF.height() / 2.0,
                       newRectF.width(), newRectF.height()))

        for r in toRemove:
            del self._node2view[r]

        #add new views for nodes
        for n in nodes:
            if n in self._node2view:
                continue

            pos2D = list(n.pos)
            del pos2D[self._axis]

            shape2D = n.shape2D(self._axis)
            itm = QGraphicsSkeletonNode(shape2D,
                                        skeletons=self._3d._skeletons,
                                        node=n)
            itm.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            itm.setSelected(n.isSelected())

            self._scene.addItem(itm)
            self._node2view[n] = itm

        for itm in self._edge2view.values():
            self._scene.removeItem(itm)
        self._edge2view = dict()

        for e in ePlane:
            l = QLineF(e[0].pointF(), e[1].pointF())

            c1 = e[0].color()
            c2 = e[1].color()
            mixColor = QColor((c1.red() + c2.red()) / 2,
                              (c1.green() + c2.green()) / 2,
                              (c1.blue() + c2.blue()) / 2)

            line = QGraphicsLineItem(self._scene.data2scene.map(l))
            line.setPen(QPen(mixColor))
            self._scene.addItem(line)
            self._edge2view[e] = line

        for theEdge, e in eIntersected:
            c1 = theEdge[0].color()
            c2 = theEdge[1].color()
            mixColor = QColor((c1.red() + c2.red()) / 2,
                              (c1.green() + c2.green()) / 2,
                              (c1.blue() + c2.blue()) / 2)

            nodeSize = 6
            p = QGraphicsRectItem(-nodeSize / 2, -nodeSize / 2, nodeSize,
                                  nodeSize)
            pos2D = list(e)
            del pos2D[self._axis]
            p.setPos(self._scene.data2scene.map(QPointF(*pos2D)))
            p.setPen(QPen(mixColor))
            self._scene.addItem(p)
            self._edge2view[e] = p