Exemplo n.º 1
0
    def setLine(self, line):
        """
        Set the arrow base line (a `QLineF` in object coordinates).
        """
        if self.__line != line:
            self.__line = line

            # local item coordinate system
            geom = self.geometry().translated(-self.pos())

            if geom.isNull() and not line.isNull():
                geom = QRectF(0, 0, 1, 1)

            arrow_shape = arrow_path_concave(line, self.lineWidth())
            arrow_rect = arrow_shape.boundingRect()

            if not (geom.contains(arrow_rect)):
                geom = geom.united(arrow_rect)

            if self.__autoAdjustGeometry:
                # Shrink the geometry if required.
                geom = geom.intersected(arrow_rect)

            # topLeft can move changing the local coordinates.
            diff = geom.topLeft()
            line = QLineF(line.p1() - diff, line.p2() - diff)
            self.__arrowItem.setLine(line)
            self.__line = line

            # parent item coordinate system
            geom.translate(self.pos())
            self.setGeometry(geom)
Exemplo n.º 2
0
    def setLine(self, line):
        """
        Set the arrow base line (a `QLineF` in object coordinates).
        """
        if self.__line != line:
            self.__line = line

            # local item coordinate system
            geom = self.geometry().translated(-self.pos())

            if geom.isNull() and not line.isNull():
                geom = QRectF(0, 0, 1, 1)

            arrow_shape = arrow_path_concave(line, self.lineWidth())
            arrow_rect = arrow_shape.boundingRect()

            if not (geom.contains(arrow_rect)):
                geom = geom.united(arrow_rect)

            if self.__autoAdjustGeometry:
                # Shrink the geometry if required.
                geom = geom.intersected(arrow_rect)

            # topLeft can move changing the local coordinates.
            diff = geom.topLeft()
            line = QLineF(line.p1() - diff, line.p2() - diff)
            self.__arrowItem.setLine(line)
            self.__line = line

            # parent item coordinate system
            geom.translate(self.pos())
            self.setGeometry(geom)
Exemplo n.º 3
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.º 4
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)
Exemplo n.º 5
0
class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()

        # na pozici [0, 0] se šířkou 50px  a výškou 50px
        # musíme ho vykreslit my, protože je to pouze abstraktní objekt (abstrakní ve smyslu, že nám pouze uchovává data a poskytuje potřebné výpočty)
        self.__drag_and_drop_rect = QRectF(QPointF(), QSizeF(50, 50))
        self.__rect_color = QColor("red")
        self.__mouse_pressed = False

    def paintEvent(self, _):
        """
        :type _: QPaintEvent
        """

        painter = QPainter(self)
        painter.setBrush(QBrush(self.__rect_color))
        painter.setPen(QPen(self.__rect_color))
        painter.drawRect(self.__drag_and_drop_rect)

    def mousePressEvent(self, mouse_event):
        """
        :type mouse_event: QMouseEvent
        """

        # je v bod kliknutí v obdelníku?
        self.__mouse_pressed = self.__drag_and_drop_rect.contains(mouse_event.pos())

    def mouseReleaseEvent(self, _):
        """
        :type _: QMouseEvent
        """

        self.__mouse_pressed = False

    def mouseMoveEvent(self, mouse_event):
        """
        :type mouse_event: QMouseEvent
        """

        if not self.__mouse_pressed:
            return

        # přesuň obdelník na pozici kurzoru
        self.__drag_and_drop_rect.moveTo(mouse_event.pos())
        # obnov okno(zavolá se metoda paintEvent)
        self.update()
Exemplo n.º 6
0
    def betweenTwoPoints(self, point, first, second):
        """ Checks whether 'point' lies between 'first' and 'second'.
        
        This function can currently (08-11-15) only deal with horizontal and vertical distances.
        """

        halfthick = 0.5 * self.CONNECTION_THICKNESS * self.zoomFactor()
        direction = self.getPointToPointDirection(first, second)

        topLeft = QPointF()
        bottomRight = QPointF()
        if direction == self.ConnectionDirection.LEFT:
            # horizontal, negative
            topLeft.setX(second.x())
            topLeft.setY(second.y() - halfthick)
            bottomRight.setX(first.x())
            bottomRight.setY(first.y() + halfthick)
        elif direction == self.ConnectionDirection.RIGHT:
            # horizontal, positive
            topLeft.setX(first.x())
            topLeft.setY(first.y() - halfthick)
            bottomRight.setX(second.x())
            bottomRight.setY(second.y() + halfthick)
        elif direction == self.ConnectionDirection.UP:
            # vertical, negative
            topLeft.setX(second.x() - halfthick)
            topLeft.setY(second.y())
            bottomRight.setX(first.x() + halfthick)
            bottomRight.setY(first.y())
        elif direction == self.ConnectionDirection.UP:
            # vertical, positive
            topLeft.setX(first.x() - halfthick)
            topLeft.setY(first.y())
            bottomRight.setX(second.x() + halfthick)
            bottomRight.setY(second.y())
        else:
            return False

        rect = QRectF(topLeft, bottomRight)
        return rect.contains(QPointF(point))
Exemplo n.º 7
0
 def betweenTwoPoints(self, point, first, second):
     """ Checks whether 'point' lies between 'first' and 'second'.
     
     This function can currently (08-11-15) only deal with horizontal and vertical distances.
     """
     
     halfthick = 0.5 * self.CONNECTION_THICKNESS * self.zoomFactor() 
     direction = self.getPointToPointDirection(first, second)
     
     topLeft = QPointF()
     bottomRight = QPointF()
     if direction == self.ConnectionDirection.LEFT:
         # horizontal, negative
         topLeft.setX(second.x())
         topLeft.setY(second.y() - halfthick)
         bottomRight.setX(first.x())
         bottomRight.setY(first.y() + halfthick)
     elif direction == self.ConnectionDirection.RIGHT:
         # horizontal, positive
         topLeft.setX(first.x())
         topLeft.setY(first.y() - halfthick)
         bottomRight.setX(second.x())
         bottomRight.setY(second.y() + halfthick)
     elif direction == self.ConnectionDirection.UP:
         # vertical, negative
         topLeft.setX(second.x() - halfthick)
         topLeft.setY(second.y())
         bottomRight.setX(first.x() + halfthick)
         bottomRight.setY(first.y())
     elif direction == self.ConnectionDirection.UP:
         # vertical, positive
         topLeft.setX(first.x() - halfthick)
         topLeft.setY(first.y())
         bottomRight.setX(second.x() + halfthick)
         bottomRight.setY(second.y())
     else:
         return False
     
     rect = QRectF(topLeft, bottomRight)
     return rect.contains(QPointF(point))
Exemplo n.º 8
0
    def adjustGeometry(self):
        """
        Adjust the widget geometry to exactly fit the arrow inside
        while preserving the arrow path scene geometry.

        """
        # local system coordinate
        geom = self.geometry().translated(-self.pos())
        line = self.__line

        arrow_rect = self.__arrowItem.shape().boundingRect()

        if geom.isNull() and not line.isNull():
            geom = QRectF(0, 0, 1, 1)

        if not (geom.contains(arrow_rect)):
            geom = geom.united(arrow_rect)

        geom = geom.intersected(arrow_rect)
        diff = geom.topLeft()
        line = QLineF(line.p1() - diff, line.p2() - diff)
        geom.translate(self.pos())
        self.setGeometry(geom)
        self.setLine(line)
Exemplo n.º 9
0
    def adjustGeometry(self):
        """
        Adjust the widget geometry to exactly fit the arrow inside
        while preserving the arrow path scene geometry.

        """
        # local system coordinate
        geom = self.geometry().translated(-self.pos())
        line = self.__line

        arrow_rect = self.__arrowItem.shape().boundingRect()

        if geom.isNull() and not line.isNull():
            geom = QRectF(0, 0, 1, 1)

        if not (geom.contains(arrow_rect)):
            geom = geom.united(arrow_rect)

        geom = geom.intersected(arrow_rect)
        diff = geom.topLeft()
        line = QLineF(line.p1() - diff, line.p2() - diff)
        geom.translate(self.pos())
        self.setGeometry(geom)
        self.setLine(line)
Exemplo n.º 10
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)
Exemplo n.º 11
0
    def update(self, zoom_only=False):
        self.update_ticks()
        line_color = self.plot.color(OWPalette.Axis)
        text_color = self.plot.color(OWPalette.Text)
        if not self.graph_line or not self.scene():
            return
        self.line_item.setLine(self.graph_line)
        self.line_item.setPen(line_color)
        if self.title:
            self.title_item.setHtml('<b>' + self.title + '</b>')
            self.title_item.setDefaultTextColor(text_color)
        if self.title_location == AxisMiddle:
            title_p = 0.5
        elif self.title_location == AxisEnd:
            title_p = 0.95
        else:
            title_p = 0.05
        title_pos = self.graph_line.pointAt(title_p)
        v = self.graph_line.normalVector().unitVector()

        dense_text = False
        if hasattr(self, 'title_margin'):
            offset = self.title_margin
        elif self._ticks:
            if self.should_be_expanded():
                offset = 55
                dense_text = True
            else:
                offset = 35
        else:
            offset = 10

        if self.title_above:
            title_pos = title_pos + (v.p2() - v.p1()) * (
                offset + QFontMetrics(self.title_item.font()).height())
        else:
            title_pos = title_pos - (v.p2() - v.p1()) * offset
        ## TODO: Move it according to self.label_pos
        self.title_item.setVisible(self.show_title)
        self.title_item.setRotation(-self.graph_line.angle())
        c = self.title_item.mapToParent(
            self.title_item.boundingRect().center())
        tl = self.title_item.mapToParent(
            self.title_item.boundingRect().topLeft())
        self.title_item.setPos(title_pos - c + tl)

        ## Arrows
        if not zoom_only:
            if self.start_arrow_item:
                self.scene().removeItem(self.start_arrow_item)
                self.start_arrow_item = None
            if self.end_arrow_item:
                self.scene().removeItem(self.end_arrow_item)
                self.end_arrow_item = None

        if self.arrows & AxisStart:
            if not zoom_only or not self.start_arrow_item:
                self.start_arrow_item = QGraphicsPathItem(
                    self.arrow_path, self)
            self.start_arrow_item.setPos(self.graph_line.p1())
            self.start_arrow_item.setRotation(-self.graph_line.angle() + 180)
            self.start_arrow_item.setBrush(line_color)
            self.start_arrow_item.setPen(line_color)
        if self.arrows & AxisEnd:
            if not zoom_only or not self.end_arrow_item:
                self.end_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.end_arrow_item.setPos(self.graph_line.p2())
            self.end_arrow_item.setRotation(-self.graph_line.angle())
            self.end_arrow_item.setBrush(line_color)
            self.end_arrow_item.setPen(line_color)

        ## Labels

        n = len(self._ticks)
        resize_plot_item_list(self.label_items, n, QGraphicsTextItem, self)
        resize_plot_item_list(self.label_bg_items, n, QGraphicsRectItem, self)
        resize_plot_item_list(self.tick_items, n, QGraphicsLineItem, self)

        test_rect = QRectF(self.graph_line.p1(),
                           self.graph_line.p2()).normalized()
        test_rect.adjust(-1, -1, 1, 1)

        n_v = self.graph_line.normalVector().unitVector()
        if self.title_above:
            n_p = n_v.p2() - n_v.p1()
        else:
            n_p = n_v.p1() - n_v.p2()
        l_v = self.graph_line.unitVector()
        l_p = l_v.p2() - l_v.p1()
        for i in range(n):
            pos, text, size, step = self._ticks[i]
            hs = 0.5 * step
            tick_pos = self.map_to_graph(pos)
            if not test_rect.contains(tick_pos):
                self.tick_items[i].setVisible(False)
                self.label_items[i].setVisible(False)
                continue
            item = self.label_items[i]
            item.setVisible(True)
            if not zoom_only:
                if self.id in XAxes or getattr(self, 'is_horizontal', False):
                    item.setHtml('<center>' + Qt.escape(text.strip()) +
                                 '</center>')
                else:
                    item.setHtml(Qt.escape(text.strip()))

            item.setTextWidth(-1)
            text_angle = 0
            if dense_text:
                w = min(item.boundingRect().width(), self.max_text_width)
                item.setTextWidth(w)
                if self.title_above:
                    label_pos = tick_pos + n_p * (
                        w + self.text_margin
                    ) + l_p * item.boundingRect().height() / 2
                else:
                    label_pos = tick_pos + n_p * self.text_margin + l_p * item.boundingRect(
                    ).height() / 2
                text_angle = -90 if self.title_above else 90
            else:
                w = min(
                    item.boundingRect().width(),
                    QLineF(self.map_to_graph(pos - hs),
                           self.map_to_graph(pos + hs)).length())
                label_pos = tick_pos + n_p * self.text_margin - l_p * w / 2
                item.setTextWidth(w)

            if not self.always_horizontal_text:
                if self.title_above:
                    item.setRotation(-self.graph_line.angle() - text_angle)
                else:
                    item.setRotation(self.graph_line.angle() - text_angle)

            item.setPos(label_pos)
            item.setDefaultTextColor(text_color)

            self.label_bg_items[i].setRect(item.boundingRect())
            self.label_bg_items[i].setPen(QPen(Qt.NoPen))
            self.label_bg_items[i].setBrush(self.plot.color(OWPalette.Canvas))

            item = self.tick_items[i]
            item.setVisible(True)
            tick_line = QLineF(v)
            tick_line.translate(-tick_line.p1())
            tick_line.setLength(size)
            if self.title_above:
                tick_line.setAngle(tick_line.angle() + 180)
            item.setLine(tick_line)
            item.setPen(line_color)
            item.setPos(self.map_to_graph(pos))
Exemplo n.º 12
0
    def update(self, zoom_only = False):
        self.update_ticks()
        line_color = self.plot.color(OWPalette.Axis)
        text_color = self.plot.color(OWPalette.Text)
        if not self.graph_line or not self.scene():
            return
        self.line_item.setLine(self.graph_line)
        self.line_item.setPen(line_color)
        if self.title:
            self.title_item.setHtml('<b>' + self.title + '</b>')
            self.title_item.setDefaultTextColor(text_color)
        if self.title_location == AxisMiddle:
            title_p = 0.5
        elif self.title_location == AxisEnd:
            title_p = 0.95
        else:
            title_p = 0.05
        title_pos = self.graph_line.pointAt(title_p)
        v = self.graph_line.normalVector().unitVector()

        dense_text = False
        if hasattr(self, 'title_margin'):
            offset = self.title_margin
        elif self._ticks:
            if self.should_be_expanded():
                offset = 55
                dense_text = True
            else:
                offset = 35
        else:
            offset = 10

        if self.title_above:
            title_pos = title_pos + (v.p2() - v.p1())*(offset + QFontMetrics(self.title_item.font()).height())
        else:
            title_pos = title_pos - (v.p2() - v.p1())*offset
        ## TODO: Move it according to self.label_pos
        self.title_item.setVisible(self.show_title)
        self.title_item.setRotation(-self.graph_line.angle())
        c = self.title_item.mapToParent(self.title_item.boundingRect().center())
        tl = self.title_item.mapToParent(self.title_item.boundingRect().topLeft())
        self.title_item.setPos(title_pos - c + tl)

        ## Arrows
        if not zoom_only:
            if self.start_arrow_item:
                self.scene().removeItem(self.start_arrow_item)
                self.start_arrow_item = None
            if self.end_arrow_item:
                self.scene().removeItem(self.end_arrow_item)
                self.end_arrow_item = None

        if self.arrows & AxisStart:
            if not zoom_only or not self.start_arrow_item:
                self.start_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.start_arrow_item.setPos(self.graph_line.p1())
            self.start_arrow_item.setRotation(-self.graph_line.angle() + 180)
            self.start_arrow_item.setBrush(line_color)
            self.start_arrow_item.setPen(line_color)
        if self.arrows & AxisEnd:
            if not zoom_only or not self.end_arrow_item:
                self.end_arrow_item = QGraphicsPathItem(self.arrow_path, self)
            self.end_arrow_item.setPos(self.graph_line.p2())
            self.end_arrow_item.setRotation(-self.graph_line.angle())
            self.end_arrow_item.setBrush(line_color)
            self.end_arrow_item.setPen(line_color)

        ## Labels

        n = len(self._ticks)
        resize_plot_item_list(self.label_items, n, QGraphicsTextItem, self)
        resize_plot_item_list(self.label_bg_items, n, QGraphicsRectItem, self)
        resize_plot_item_list(self.tick_items, n, QGraphicsLineItem, self)

        test_rect = QRectF(self.graph_line.p1(),  self.graph_line.p2()).normalized()
        test_rect.adjust(-1, -1, 1, 1)

        n_v = self.graph_line.normalVector().unitVector()
        if self.title_above:
            n_p = n_v.p2() - n_v.p1()
        else:
            n_p = n_v.p1() - n_v.p2()
        l_v = self.graph_line.unitVector()
        l_p = l_v.p2() - l_v.p1()
        for i in range(n):
            pos, text, size, step = self._ticks[i]
            hs = 0.5 * step
            tick_pos = self.map_to_graph( pos )
            if not test_rect.contains(tick_pos):
                self.tick_items[i].setVisible(False)
                self.label_items[i].setVisible(False)
                continue
            item = self.label_items[i]
            item.setVisible(True)
            if not zoom_only:
                if self.id in XAxes or getattr(self, 'is_horizontal', False):
                    item.setHtml( '<center>' + Qt.escape(text.strip()) + '</center>')
                else:
                    item.setHtml(Qt.escape(text.strip()))

            item.setTextWidth(-1)
            text_angle = 0
            if dense_text:
                w = min(item.boundingRect().width(), self.max_text_width)
                item.setTextWidth(w)
                if self.title_above:
                    label_pos = tick_pos + n_p * (w + self.text_margin) + l_p * item.boundingRect().height()/2
                else:
                    label_pos = tick_pos + n_p * self.text_margin + l_p * item.boundingRect().height()/2
                text_angle = -90 if self.title_above else 90
            else:
                w = min(item.boundingRect().width(), QLineF(self.map_to_graph(pos - hs), self.map_to_graph(pos + hs) ).length())
                label_pos = tick_pos + n_p * self.text_margin - l_p * w/2
                item.setTextWidth(w)

            if not self.always_horizontal_text:
                if self.title_above:
                    item.setRotation(-self.graph_line.angle() - text_angle)
                else:
                    item.setRotation(self.graph_line.angle() - text_angle)

            item.setPos(label_pos)
            item.setDefaultTextColor(text_color)

            self.label_bg_items[i].setRect(item.boundingRect())
            self.label_bg_items[i].setPen(QPen(Qt.NoPen))
            self.label_bg_items[i].setBrush(self.plot.color(OWPalette.Canvas))

            item = self.tick_items[i]
            item.setVisible(True)
            tick_line = QLineF(v)
            tick_line.translate(-tick_line.p1())
            tick_line.setLength(size)
            if self.title_above:
                tick_line.setAngle(tick_line.angle() + 180)
            item.setLine( tick_line )
            item.setPen(line_color)
            item.setPos(self.map_to_graph(pos))