Exemple #1
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)