Beispiel #1
0
 def save(self):
     """
     Saves the snapshot based on the current region.
     """
     # close down the snapshot widget
     if self.hideWindow():
         self.hideWindow().hide()
     
     self.hide()
     QApplication.processEvents()
     time.sleep(1)
     
     # create the pixmap to save
     wid = QApplication.desktop().winId()
     
     if not self._region.isNull():
         x = self._region.x()
         y = self._region.y()
         w = self._region.width()
         h = self._region.height()
     else:
         x = self.x()
         y = self.y()
         w = self.width()
         h = self.height()
     
     pixmap = QPixmap.grabWindow(wid, x, y, w, h)
     pixmap.save(self.filepath())
     
     self.close()
     self.deleteLater()
     if self.hideWindow():
         self.hideWindow().show()
Beispiel #2
0
    def exec_(self, pos=None):
        self._result = 0
        self.setWindowModality(Qt.ApplicationModal)
        self.popup(pos)
        while self.isVisible():
            QApplication.processEvents()

        return self.result()
Beispiel #3
0
 def exec_(self, pos=None):
     self._result = 0
     self.setWindowModality(Qt.ApplicationModal)
     self.popup(pos)
     while self.isVisible():
         QApplication.processEvents()
     
     return self.result()
Beispiel #4
0
 def show(self):
     """
     Shows this widget and hides the specified window if necessary.
     """
     super(XSnapshotWidget, self).show()
     
     if self.hideWindow():
         self.hideWindow().hide()
         QApplication.processEvents()
Beispiel #5
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)

        # 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 = []

            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]))

        used_rects = [n.sceneRect() for n in scene.nodes() if not n in nodes]

        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
                point_x = -1
                point_y = -1
                offset = 0
                before = True
                found_point = True
                new_rect = QRectF()

                while found_point:
                    if not None in (min_, max_):
                        if direction == Qt.Vertical:
                            off_x = (max_ -
                                     min_) / 2.0 - node.rect().width() / 2.0

                            if before:
                                off_x -= offset
                                offset += node.rect().width() + padX
                            else:
                                off_x += offset

                            point_x = min_ + off_x
                            point_y = point.y() + off_y
                        else:
                            off_y = (max_ -
                                     min_) / 2.0 - node.rect().height() / 2.0

                            if before:
                                off_y -= offset
                                offset += node.rect().height() + padY
                            else:
                                off_y += offset

                            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

                            if before:
                                off_x -= offset
                                offset += node.rect().width() + padX
                            else:
                                off_x += offset

                            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

                            if before:
                                off_y -= offset
                                offset += node.rect().height() + padY
                            else:
                                off_y += offset

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

                    # determine if we've already used this point before
                    before = not before
                    found_point = False
                    orect = node.rect()
                    new_rect = QRectF(point_x, point_y, orect.width(),
                                      orect.height())
                    for used_rect in used_rects:
                        if used_rect.intersects(new_rect):
                            found_point = True
                            break

                used_rects.append(new_rect)

                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(0.5)

        return processed_nodes
Beispiel #6
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)
     
     # 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 = []
         
         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]))
     
     used_rects = [n.sceneRect() for n in scene.nodes() if not n in nodes]
     
     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
             point_x = -1
             point_y = -1
             offset = 0
             before = True
             found_point = True
             new_rect = QRectF()
             
             while found_point:
                 if not None in (min_, max_):
                     if direction == Qt.Vertical:
                         off_x = (max_ - min_)/2.0 - node.rect().width()/2.0
                         
                         if before:
                             off_x -= offset
                             offset += node.rect().width() + padX
                         else:
                             off_x += offset
                         
                         point_x = min_ + off_x
                         point_y = point.y() + off_y
                     else:
                         off_y = (max_ - min_)/2.0 - node.rect().height()/2.0
                         
                         if before:
                             off_y -= offset
                             offset += node.rect().height() + padY
                         else:
                             off_y += offset
                         
                         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
                         
                         if before:
                             off_x -= offset
                             offset += node.rect().width() + padX
                         else:
                             off_x += offset
                         
                         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
                         
                         if before:
                             off_y -= offset
                             offset += node.rect().height() + padY
                         else:
                             off_y += offset
                         
                         point_x = point.x() + off_x
                         point_y = point.y() + off_y
                 
                 # determine if we've already used this point before
                 before = not before
                 found_point = False
                 orect = node.rect()
                 new_rect = QRectF(point_x, point_y,
                                   orect.width(), orect.height())
                 for used_rect in used_rects:
                     if used_rect.intersects(new_rect):
                         found_point = True
                         break
             
             used_rects.append(new_rect)
             
             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(0.5)
     
     return processed_nodes