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)