Exemplo n.º 1
0
    def draw_text(self, txt, txtlen, window):
        if ((txtlen>0) and not ((txt == self.cursor_char) and (self._cursor_visible == False))): # If there IS something to print
            if (self.pbuffer_painter[window.id] == None):
                self.brush.setColor(self.ztoq_color[self.cur_bg])
                self.pbuffer_painter[window.id] = QPainter(self.pbuffer[window.id])
                self.pbuffer_painter[window.id].setPen(self.ztoq_color[self.cur_fg])
                self.pbuffer_painter[window.id].setBackground(self.brush)

            painter = self.pbuffer_painter[window.id]

            # @type window ZWindow
            if (window.cursor == None):
                if (window.id == 0): # Main window
                    window.set_cursor_position(1, self.height)
                    window.set_cursor_real_position(2, self.height*(self.linesize-1))
                else:
                    window.set_cursor_position(1, 1)
                    window.set_cursor_real_position(2, self.linesize-1)

            if (txt=='\n'):
                if (window.cursor[1]==self.height):
                    if (window.scrolling):
                        self.scroll(painter)
                    window.set_cursor_position(1, window.cursor[1])
                    window.set_cursor_real_position(2, window.cursor_real_pos[1])
                else:
                    window.set_cursor_position(1, window.cursor[1]+1)
                    window.set_cursor_real_position(2, window.cursor_real_pos[1]+self.linesize)
            else:
                rect = QRectF(window.cursor_real_pos[0], window.cursor_real_pos[1], self.pbuffer[window.id].width()-window.cursor_real_pos[0], self.linesize)

                painter.setFont(self.font())
                #painter.setRenderHint(QPainter.TextAntialiasing)
                if (self._input_buffer_printing == False):
                    painter.setBackgroundMode(Qt.OpaqueMode)
                else:
                    painter.setBackgroundMode(Qt.TransparentMode)
                bounding_rect = painter.boundingRect(rect,txt)
                if (rect.contains(bounding_rect)):
                    #print rect.x(), rect.y(), rect.width(),rect.height(), txt, bounding_rect
                    painter.drawText(bounding_rect, txt)
                    if txt != self.cursor_char:
                        window.set_cursor_position(window.cursor[0]+txtlen, window.cursor[1])
                        window.set_cursor_real_position(rect.x()+bounding_rect.width(), rect.y())
                else: # There is not enough space
                    #print "Not enough space to print:", txt
                    self.scroll(painter)
                    window.set_cursor_position(1, self.height)
                    window.set_cursor_real_position(2, self.height*(self.linesize-1))
                    rect.setX(2)
                    rect.setY(window.cursor_real_pos[1])
                    rect.setWidth(self.pbuffer[window.id].width()-window.cursor_real_pos[0])
                    rect.setHeight(self.linesize)
                    bounding_rect = painter.boundingRect(rect,txt)
                    painter.drawText(bounding_rect, txt)
                    if txt != self.cursor_char:
                        window.set_cursor_position(window.cursor[0]+txtlen, window.cursor[1])
                        window.set_cursor_real_position(rect.x()+bounding_rect.width(), rect.y())
Exemplo n.º 2
0
 def clean_input_buffer_from_screen(self):
     rect = QRectF()
     rect.setX(self.lastwindow.cursor_real_pos[0])
     rect.setY(self.lastwindow.cursor_real_pos[1])
     rect.setWidth(self.pbuffer[0].width()-self.lastwindow.cursor_real_pos[0]+1)
     rect.setHeight(self.linesize)
     txtbuffer = ''
     for w in self.input_buf:
         txtbuffer += w
     bounding_rect = self.pbuffer_painter[0].boundingRect(rect, txtbuffer)
     if (rect.contains(bounding_rect)): # string fits in this line
         self.pbuffer_painter[0].eraseRect(bounding_rect)
         #self.pbuffer_painter.drawRect(bounding_rect)
         #print 'Erasing rect', bounding_rect
     else:
         self.pbuffer_painter[0].eraseRect(rect)
 def setY(self,y):
     QRectF.setY(self,y)
Exemplo n.º 4
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