| @@ -62,7 +62,7 @@ HAVE_FFMPEG = $(shell pkg-config --exists libavcodec libavformat libavutil | |||
| HAVE_OPENGL = $(shell pkg-config --exists gl && echo true) | |||
| HAVE_GTK2 = $(shell pkg-config --exists gtk+-2.0 && echo true) | |||
| HAVE_GTK3 = $(shell pkg-config --exists gtk+-3.0 && echo true) | |||
| # HAVE_QT4 = $(shell pkg-config --exists QtCore && echo true) | |||
| HAVE_QT4 = $(shell pkg-config --exists QtCore && echo true) | |||
| HAVE_QT5 = $(shell pkg-config --exists Qt5Core && echo true) | |||
| HAVE_AF_DEPS = $(shell pkg-config --exists sndfile && echo true) | |||
| @@ -682,8 +682,6 @@ struct ParameterData { | |||
| hints(0x0), | |||
| midiChannel(0), | |||
| midiCC(-1) {} | |||
| CARLA_LEAK_DETECTOR(ParameterData) | |||
| #endif | |||
| }; | |||
| @@ -706,8 +704,6 @@ struct ParameterRanges { | |||
| step(0.01f), | |||
| stepSmall(0.0001f), | |||
| stepLarge(0.1f) {} | |||
| CARLA_LEAK_DETECTOR(ParameterRanges) | |||
| #endif | |||
| void fixDefault() | |||
| @@ -763,8 +759,6 @@ struct MidiProgramData { | |||
| : bank(0), | |||
| program(0), | |||
| name(nullptr) {} | |||
| CARLA_LEAK_DETECTOR(MidiProgramData) | |||
| #endif | |||
| }; | |||
| @@ -784,8 +778,6 @@ struct CustomData { | |||
| : type(nullptr), | |||
| key(nullptr), | |||
| value(nullptr) {} | |||
| CARLA_LEAK_DETECTOR(CustomData) | |||
| #endif | |||
| }; | |||
| @@ -100,8 +100,8 @@ LIBS = ../libcarla_engine.a | |||
| LIBS += ../libcarla_plugin.a | |||
| LIBS += ../libcarla_native.a | |||
| LIBS += ../../libs/rtmempool.a | |||
| LIBS += ../../libs/widgets.a | |||
| LIBS += ../../libs/theme.a | |||
| LIBS += ../../libs/widgets.a | |||
| ifeq ($(CARLA_PLUGIN_SUPPORT),true) | |||
| LIBS += ../../libs/lilv.a | |||
| @@ -150,10 +150,35 @@ debug: | |||
| # -------------------------------------------------------------- | |||
| ../libcarla_engine.a: | |||
| $(MAKE) -C ../engine | |||
| ../libcarla_plugin.a: | |||
| $(MAKE) -C ../plugin | |||
| ../libcarla_native.a: | |||
| $(MAKE) -C ../native | |||
| ../../libs/dgl.a: | |||
| $(MAKE) -C ../../libs dgl | |||
| ../../libs/lilv.a: | |||
| $(MAKE) -C ../../libs lilv | |||
| ../../libs/rtmempool.a: | |||
| $(MAKE) -C ../../libs rtmempool | |||
| ../../libs/theme.a: | |||
| $(MAKE) -C ../../libs theme | |||
| ../../libs/widgets.a: | |||
| $(MAKE) -C ../../libs widgets | |||
| .PHONY: ../libcarla_native.a ../../libs/widgets.a | |||
| .PHONY: ../libcarla_engine.a \ | |||
| ../libcarla_plugin.a \ | |||
| ../libcarla_native.a \ | |||
| ../../libs/dgl.a \ | |||
| ../../libs/lilv.a \ | |||
| ../../libs/rtmempool.a \ | |||
| ../../libs/theme.a \ | |||
| ../../libs/widgets.a | |||
| @@ -337,6 +337,8 @@ const char* CallbackType2Str(const CallbackType& type) | |||
| return "CALLBACK_BUFFER_SIZE_CHANGED"; | |||
| case CALLBACK_SAMPLE_RATE_CHANGED: | |||
| return "CALLBACK_SAMPLE_RATE_CHANGED"; | |||
| case CALLBACK_PROCESS_MODE_CHANGED: | |||
| return "CALLBACK_PROCESS_MODE_CHANGED"; | |||
| case CALLBACK_NSM_ANNOUNCE: | |||
| return "CALLBACK_NSM_ANNOUNCE"; | |||
| case CALLBACK_NSM_OPEN: | |||
| @@ -0,0 +1,43 @@ | |||
| #!/usr/bin/env python3 | |||
| # -*- coding: utf-8 -*- | |||
| # Clickable Label, a custom Qt4 widget | |||
| # Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||
| # | |||
| # This program is free software; you can redistribute it and/or modify | |||
| # it under the terms of the GNU General Public License as published by | |||
| # the Free Software Foundation; either version 2 of the License, or | |||
| # any later version. | |||
| # | |||
| # This program is distributed in the hope that it will be useful, | |||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| # GNU General Public License for more details. | |||
| # | |||
| # For a full copy of the GNU General Public License see the GPL.txt file | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Imports (Global) | |||
| from PyQt4.QtCore import pyqtSlot, Qt, QTimer, SIGNAL, SLOT | |||
| from PyQt4.QtGui import QLabel | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Widget Class | |||
| class ClickableLabel(QLabel): | |||
| def __init__(self, parent): | |||
| QLabel.__init__(self, parent) | |||
| self.setCursor(Qt.PointingHandCursor) | |||
| def mousePressEvent(self, event): | |||
| self.emit(SIGNAL("clicked()")) | |||
| # Use busy cursor for 2 secs | |||
| self.setCursor(Qt.WaitCursor) | |||
| QTimer.singleShot(2000, self, SLOT("slot_setNormalCursor()")) | |||
| QLabel.mousePressEvent(self, event) | |||
| @pyqtSlot() | |||
| def slot_setNormalCursor(self): | |||
| self.setCursor(Qt.PointingHandCursor) | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Pixmap Button, a custom Qt4 widget | |||
| * LED Button, a custom Qt4 widget | |||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| @@ -21,18 +21,18 @@ | |||
| #include <QtGui/QPaintEvent> | |||
| LEDButton::LEDButton(QWidget* parent): | |||
| QPushButton(parent) | |||
| QPushButton(parent), | |||
| fColor(OFF), | |||
| fLastColor(OFF), | |||
| fPixmapRect(0, 0, 0, 0) | |||
| { | |||
| fPixmapRect = QRectF(0, 0, 0, 0); | |||
| setCheckable(true); | |||
| setText(""); | |||
| setColor(BLUE); | |||
| } | |||
| LEDButton::~LEDButton() | |||
| { | |||
| // matching fLastColor | |||
| fPixmap.load(":/bitmaps/led_off.png"); | |||
| } | |||
| void LEDButton::setColor(Color color) | |||
| @@ -42,10 +42,8 @@ void LEDButton::setColor(Color color) | |||
| fPixmapRect = QRectF(0, 0, size, size); | |||
| setMinimumWidth(size); | |||
| setMaximumWidth(size); | |||
| setMinimumHeight(size); | |||
| setMaximumHeight(size); | |||
| setMinimumSize(size, size); | |||
| setMaximumSize(size, size); | |||
| } | |||
| void LEDButton::paintEvent(QPaintEvent* event) | |||
| @@ -55,23 +53,36 @@ void LEDButton::paintEvent(QPaintEvent* event) | |||
| if (isChecked()) | |||
| { | |||
| switch (fColor) | |||
| if (fLastColor != fColor) | |||
| { | |||
| case BLUE: | |||
| fPixmap.load(":/bitmaps/led_blue.png"); | |||
| case GREEN: | |||
| fPixmap.load(":/bitmaps/led_green.png"); | |||
| case RED: | |||
| fPixmap.load(":/bitmaps/led_red.png"); | |||
| case YELLOW: | |||
| fPixmap.load(":/bitmaps/led_yellow.png"); | |||
| default: | |||
| return; | |||
| switch (fColor) | |||
| { | |||
| case OFF: | |||
| fPixmap.load(":/bitmaps/led_off.png"); | |||
| break; | |||
| case BLUE: | |||
| fPixmap.load(":/bitmaps/led_blue.png"); | |||
| break; | |||
| case GREEN: | |||
| fPixmap.load(":/bitmaps/led_green.png"); | |||
| break; | |||
| case RED: | |||
| fPixmap.load(":/bitmaps/led_red.png"); | |||
| break; | |||
| case YELLOW: | |||
| fPixmap.load(":/bitmaps/led_yellow.png"); | |||
| break; | |||
| default: | |||
| return; | |||
| } | |||
| fLastColor = fColor; | |||
| } | |||
| } | |||
| else | |||
| else if (fLastColor != OFF) | |||
| { | |||
| fPixmap.load(":/bitmaps/led_off.png"); | |||
| fLastColor = OFF; | |||
| } | |||
| painter.drawPixmap(fPixmapRect, fPixmap, fPixmapRect); | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Pixmap Button, a custom Qt4 widget | |||
| * LED Button, a custom Qt4 widget | |||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| @@ -34,22 +34,23 @@ class LEDButton : public QPushButton | |||
| public: | |||
| enum Color { | |||
| BLUE = 1, | |||
| GREEN = 2, | |||
| RED = 3, | |||
| YELLOW = 4 | |||
| OFF = 0, | |||
| BLUE = 1, | |||
| GREEN = 2, | |||
| RED = 3, | |||
| YELLOW = 4 | |||
| }; | |||
| LEDButton(QWidget* parent); | |||
| ~LEDButton(); | |||
| void setColor(Color color); | |||
| protected: | |||
| void paintEvent(QPaintEvent* event); | |||
| void paintEvent(QPaintEvent* event) override; | |||
| private: | |||
| Color fColor; | |||
| Color fLastColor; | |||
| QPixmap fPixmap; | |||
| QRectF fPixmapRect; | |||
| @@ -26,10 +26,11 @@ from PyQt4.QtGui import QPainter, QPixmap, QPushButton | |||
| # Widget Class | |||
| class LEDButton(QPushButton): | |||
| BLUE = 1 | |||
| GREEN = 2 | |||
| RED = 3 | |||
| YELLOW = 4 | |||
| OFF = 0 | |||
| BLUE = 1 | |||
| GREEN = 2 | |||
| RED = 3 | |||
| YELLOW = 4 | |||
| def __init__(self, parent): | |||
| QPushButton.__init__(self, parent) | |||
| @@ -42,6 +43,9 @@ class LEDButton(QPushButton): | |||
| self.setColor(self.BLUE) | |||
| self.fLastColor = self.OFF | |||
| self.fPixmap.load(":/bitmaps/led_off.png") | |||
| def setColor(self, color): | |||
| self.fColor = color | |||
| size = 14 | |||
| @@ -56,17 +60,24 @@ class LEDButton(QPushButton): | |||
| event.accept() | |||
| if self.isChecked(): | |||
| if self.fColor == self.BLUE: | |||
| self.fPixmap.load(":/bitmaps/led_blue.png") | |||
| elif self.fColor == self.GREEN: | |||
| self.fPixmap.load(":/bitmaps/led_green.png") | |||
| elif self.fColor == self.RED: | |||
| self.fPixmap.load(":/bitmaps/led_red.png") | |||
| elif self.fColor == self.YELLOW: | |||
| self.fPixmap.load(":/bitmaps/led_yellow.png") | |||
| else: | |||
| return | |||
| else: | |||
| if self.fLastColor != self.fColor: | |||
| if self.fColor == self.OFF: | |||
| self.fPixmap.load(":/bitmaps/led_off.png") | |||
| elif self.fColor == self.BLUE: | |||
| self.fPixmap.load(":/bitmaps/led_blue.png") | |||
| elif self.fColor == self.GREEN: | |||
| self.fPixmap.load(":/bitmaps/led_green.png") | |||
| elif self.fColor == self.RED: | |||
| self.fPixmap.load(":/bitmaps/led_red.png") | |||
| elif self.fColor == self.YELLOW: | |||
| self.fPixmap.load(":/bitmaps/led_yellow.png") | |||
| else: | |||
| return | |||
| self.fLastColor = self.fColor | |||
| elif self.fLastColor != self.OFF: | |||
| self.fPixmap.load(":/bitmaps/led_off.png") | |||
| self.fLastColor = self.OFF | |||
| painter.drawPixmap(self.fPixmapRect, self.fPixmap, self.fPixmapRect) | |||
| @@ -12,7 +12,7 @@ | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #include "paramspinbox.hpp" | |||
| @@ -12,7 +12,7 @@ | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #ifndef __PARAMSPINBOX_HPP__ | |||
| @@ -53,10 +53,10 @@ signals: | |||
| protected: | |||
| void handleMouseEventPos(const QPoint& pos); | |||
| void mousePressEvent(QMouseEvent* event); | |||
| void mouseMoveEvent(QMouseEvent* event); | |||
| void mouseReleaseEvent(QMouseEvent* event); | |||
| void paintEvent(QPaintEvent* event); | |||
| void mousePressEvent(QMouseEvent* event) override; | |||
| void mouseMoveEvent(QMouseEvent* event) override; | |||
| void mouseReleaseEvent(QMouseEvent* event) override; | |||
| void paintEvent(QPaintEvent* event) override; | |||
| private: | |||
| bool m_leftClickDown; | |||
| @@ -64,11 +64,16 @@ class PixmapButton(QPushButton): | |||
| event.accept() | |||
| if not self.isEnabled(): | |||
| painter.save() | |||
| painter.setOpacity(0.2) | |||
| painter.drawPixmap(self.fPixmapRect, self.fPixmapNormal, self.fPixmapRect) | |||
| painter.restore() | |||
| elif self.isChecked() or self.isDown(): | |||
| painter.drawPixmap(self.fPixmapRect, self.fPixmapDown, self.fPixmapRect) | |||
| elif self.fIsHovered: | |||
| painter.drawPixmap(self.fPixmapRect, self.fPixmapHover, self.fPixmapRect) | |||
| else: | |||
| painter.drawPixmap(self.fPixmapRect, self.fPixmapNormal, self.fPixmapRect) | |||
| @@ -53,10 +53,10 @@ public: | |||
| protected: | |||
| void updateSizes(); | |||
| void enterEvent(QEvent* event); | |||
| void leaveEvent(QEvent* event); | |||
| void paintEvent(QPaintEvent* event); | |||
| void resizeEvent(QResizeEvent* event); | |||
| void enterEvent(QEvent* event) override; | |||
| void leaveEvent(QEvent* event) override; | |||
| void paintEvent(QPaintEvent* event) override; | |||
| void resizeEvent(QResizeEvent* event) override; | |||
| private: | |||
| enum Orientation { | |||
| @@ -25,9 +25,9 @@ | |||
| #ifndef HAVE_CPP11_SUPPORT | |||
| static std::map<int, QRectF> kMidiKey2RectMapHorizontal; | |||
| #else | |||
| static const std::map<int, QRectF> kMidiKey2RectMapHorizontal = { | |||
| static std::map<int, QRectF> kMidiKey2RectMapHorizontal = { | |||
| {0, QRectF(0, 0, 18, 64)}, // C | |||
| {1, QRectF(13, 0, 11, 42)}, // C# | |||
| {1, QRectF(13, 0, 11, 42)}, // C# | |||
| {2, QRectF(18, 0, 25, 64)}, // D | |||
| {3, QRectF(37, 0, 11, 42)}, // D# | |||
| {4, QRectF(42, 0, 18, 64)}, // E | |||
| @@ -44,7 +44,7 @@ static const std::map<int, QRectF> kMidiKey2RectMapHorizontal = { | |||
| #ifndef HAVE_CPP11_SUPPORT | |||
| static std::map<int, QRectF> kMidiKey2RectMapVertical; | |||
| #else | |||
| static const std::map<int, QRectF> kMidiKey2RectMapVertical = { | |||
| static std::map<int, QRectF> kMidiKey2RectMapVertical = { | |||
| {11, QRectF(0, 0, 64, 18)}, // B | |||
| {10, QRectF(0, 14, 42, 7)}, // A# | |||
| {9, QRectF(0, 18, 64, 24)}, // A | |||
| @@ -99,42 +99,96 @@ static QVector<int> kBlackNotes; | |||
| static const QVector<int> kBlackNotes = {1, 3, 6, 8, 10}; | |||
| #endif | |||
| #ifndef HAVE_CPP11_SUPPORT | |||
| static const struct PixmapKeyboardInit { | |||
| PixmapKeyboardInit() { | |||
| // kMidiKey2RectMapHorizontal | |||
| kMidiKey2RectMapHorizontal[0] = QRectF(0, 0, 18, 64); // C | |||
| kMidiKey2RectMapHorizontal[1] = QRectF(13, 0, 11, 42); // C# | |||
| kMidiKey2RectMapHorizontal[2] = QRectF(18, 0, 25, 64); // D | |||
| kMidiKey2RectMapHorizontal[3] = QRectF(37, 0, 11, 42); // D# | |||
| kMidiKey2RectMapHorizontal[4] = QRectF(42, 0, 18, 64); // E | |||
| kMidiKey2RectMapHorizontal[5] = QRectF(60, 0, 18, 64); // F | |||
| kMidiKey2RectMapHorizontal[6] = QRectF(73, 0, 11, 42); // F# | |||
| kMidiKey2RectMapHorizontal[7] = QRectF(78, 0, 25, 64); // G | |||
| kMidiKey2RectMapHorizontal[8] = QRectF(97, 0, 11, 42); // G# | |||
| kMidiKey2RectMapHorizontal[9] = QRectF(102, 0, 25, 64); // A | |||
| kMidiKey2RectMapHorizontal[10] = QRectF(121, 0, 11, 42); // A# | |||
| kMidiKey2RectMapHorizontal[11] = QRectF(126, 0, 18, 64); // B | |||
| // kMidiKey2RectMapVertical | |||
| kMidiKey2RectMapVertical[11] = QRectF(0, 0, 64, 18); // B | |||
| kMidiKey2RectMapVertical[10] = QRectF(0, 14, 42, 7); // A# | |||
| kMidiKey2RectMapVertical[9] = QRectF(0, 18, 64, 24); // A | |||
| kMidiKey2RectMapVertical[8] = QRectF(0, 38, 42, 7); // G# | |||
| kMidiKey2RectMapVertical[7] = QRectF(0, 42, 64, 24); // G | |||
| kMidiKey2RectMapVertical[6] = QRectF(0, 62, 42, 7); // F# | |||
| kMidiKey2RectMapVertical[5] = QRectF(0, 66, 64, 18); // F | |||
| kMidiKey2RectMapVertical[4] = QRectF(0, 84, 64, 18); // E | |||
| kMidiKey2RectMapVertical[3] = QRectF(0, 98, 42, 7); // D# | |||
| kMidiKey2RectMapVertical[2] = QRectF(0, 102, 64, 24); // D | |||
| kMidiKey2RectMapVertical[1] = QRectF(0, 122, 42, 7); // C# | |||
| kMidiKey2RectMapVertical[0] = QRectF(0, 126, 64, 18); // C | |||
| // kMidiKeyboard2KeyMap, 3th octave | |||
| kMidiKeyboard2KeyMap[Qt::Key_Z] = 48; | |||
| kMidiKeyboard2KeyMap[Qt::Key_S] = 49; | |||
| kMidiKeyboard2KeyMap[Qt::Key_X] = 50; | |||
| kMidiKeyboard2KeyMap[Qt::Key_D] = 51; | |||
| kMidiKeyboard2KeyMap[Qt::Key_C] = 52; | |||
| kMidiKeyboard2KeyMap[Qt::Key_V] = 53; | |||
| kMidiKeyboard2KeyMap[Qt::Key_G] = 54; | |||
| kMidiKeyboard2KeyMap[Qt::Key_B] = 55; | |||
| kMidiKeyboard2KeyMap[Qt::Key_H] = 56; | |||
| kMidiKeyboard2KeyMap[Qt::Key_N] = 57; | |||
| kMidiKeyboard2KeyMap[Qt::Key_J] = 58; | |||
| kMidiKeyboard2KeyMap[Qt::Key_M] = 59; | |||
| // kMidiKeyboard2KeyMap, 4th octave | |||
| kMidiKeyboard2KeyMap[Qt::Key_Q] = 60; | |||
| kMidiKeyboard2KeyMap[Qt::Key_2] = 61; | |||
| kMidiKeyboard2KeyMap[Qt::Key_W] = 62; | |||
| kMidiKeyboard2KeyMap[Qt::Key_3] = 63; | |||
| kMidiKeyboard2KeyMap[Qt::Key_E] = 64; | |||
| kMidiKeyboard2KeyMap[Qt::Key_R] = 65; | |||
| kMidiKeyboard2KeyMap[Qt::Key_5] = 66; | |||
| kMidiKeyboard2KeyMap[Qt::Key_T] = 67; | |||
| kMidiKeyboard2KeyMap[Qt::Key_6] = 68; | |||
| kMidiKeyboard2KeyMap[Qt::Key_Y] = 69; | |||
| kMidiKeyboard2KeyMap[Qt::Key_7] = 70; | |||
| kMidiKeyboard2KeyMap[Qt::Key_U] = 71; | |||
| // kBlackNotes | |||
| kBlackNotes << 1; | |||
| kBlackNotes << 3; | |||
| kBlackNotes << 6; | |||
| kBlackNotes << 8; | |||
| kBlackNotes << 10; | |||
| } | |||
| } _pixmapKeyboardInitInit; | |||
| #endif | |||
| PixmapKeyboard::PixmapKeyboard(QWidget* parent) | |||
| : QWidget(parent), | |||
| fPixmap(""), | |||
| fPixmapMode(HORIZONTAL), | |||
| fColorStr("orange"), | |||
| fFont("Monospace", 8, QFont::Normal), | |||
| fFont("Monospace", 7, QFont::Normal), | |||
| fOctaves(6), | |||
| fLastMouseNote(-1), | |||
| fWidth(0), | |||
| fHeight(0), | |||
| fNeedsUpdate(false), | |||
| fMidiMap(kMidiKey2RectMapHorizontal) | |||
| { | |||
| setCursor(Qt::PointingHandCursor); | |||
| setMode(HORIZONTAL); | |||
| #ifndef HAVE_CPP11_SUPPORT | |||
| if (kBlackNotes.count() == 0) | |||
| { | |||
| // TODO - rest of data | |||
| kBlackNotes << 1; | |||
| kBlackNotes << 3; | |||
| kBlackNotes << 6; | |||
| kBlackNotes << 8; | |||
| kBlackNotes << 10; | |||
| } | |||
| #endif | |||
| } | |||
| void PixmapKeyboard::allNotesOff() | |||
| { | |||
| fEnabledKeys.clear(); | |||
| fNeedsUpdate = true; | |||
| emit notesOff(); | |||
| QTimer::singleShot(0, this, SLOT(updateOnce())); | |||
| update(); | |||
| } | |||
| void PixmapKeyboard::sendNoteOn(int note, bool sendSignal) | |||
| @@ -146,8 +200,7 @@ void PixmapKeyboard::sendNoteOn(int note, bool sendSignal) | |||
| if (sendSignal) | |||
| emit noteOn(note); | |||
| fNeedsUpdate = true; | |||
| QTimer::singleShot(0, this, SLOT(updateOnce())); | |||
| update(); | |||
| } | |||
| if (fEnabledKeys.count() == 1) | |||
| @@ -163,8 +216,7 @@ void PixmapKeyboard::sendNoteOff(int note, bool sendSignal) | |||
| if (sendSignal) | |||
| emit noteOff(note); | |||
| fNeedsUpdate = true; | |||
| QTimer::singleShot(0, this, SLOT(updateOnce())); | |||
| update(); | |||
| } | |||
| if (fEnabledKeys.count() == 0) | |||
| @@ -214,12 +266,12 @@ void PixmapKeyboard::setMode(Orientation mode, Color color) | |||
| void PixmapKeyboard::setOctaves(int octaves) | |||
| { | |||
| Q_ASSERT(octaves >= 1 && octaves <= 8); | |||
| Q_ASSERT(octaves >= 1 && octaves <= 10); | |||
| if (octaves < 1) | |||
| octaves = 1; | |||
| else if (octaves > 8) | |||
| octaves = 8; | |||
| else if (octaves > 10) | |||
| octaves = 10; | |||
| fOctaves = octaves; | |||
| @@ -239,8 +291,7 @@ void PixmapKeyboard::setOctaves(int octaves) | |||
| void PixmapKeyboard::handleMousePos(const QPoint& pos) | |||
| { | |||
| int note; | |||
| int octave; | |||
| int note, octave; | |||
| QPointF keyPos; | |||
| if (fPixmapMode == HORIZONTAL) | |||
| @@ -262,8 +313,6 @@ void PixmapKeyboard::handleMousePos(const QPoint& pos) | |||
| else | |||
| return; | |||
| octave += 3; | |||
| if (fMidiMap[1].contains(keyPos)) // C# | |||
| note = 1; | |||
| else if (fMidiMap[3].contains(keyPos)) // D# | |||
| @@ -342,7 +391,7 @@ void PixmapKeyboard::mousePressEvent(QMouseEvent* event) | |||
| void PixmapKeyboard::mouseMoveEvent(QMouseEvent* event) | |||
| { | |||
| handleMousePos(event->pos()); | |||
| QWidget::mousePressEvent(event); | |||
| QWidget::mouseMoveEvent(event); | |||
| } | |||
| void PixmapKeyboard::mouseReleaseEvent(QMouseEvent* event) | |||
| @@ -391,27 +440,30 @@ void PixmapKeyboard::paintEvent(QPaintEvent* event) | |||
| if (_isNoteBlack(note)) | |||
| continue; | |||
| if (note < 36) | |||
| // cannot paint this note | |||
| continue; | |||
| else if (note < 48) | |||
| if (note < 12) | |||
| octave = 0; | |||
| else if (note < 60) | |||
| else if (note < 24) | |||
| octave = 1; | |||
| else if (note < 72) | |||
| else if (note < 36) | |||
| octave = 2; | |||
| else if (note < 84) | |||
| else if (note < 48) | |||
| octave = 3; | |||
| else if (note < 96) | |||
| else if (note < 60) | |||
| octave = 4; | |||
| else if (note < 108) | |||
| else if (note < 72) | |||
| octave = 5; | |||
| else if (note < 120) | |||
| else if (note < 84) | |||
| octave = 6; | |||
| else if (note < 132) | |||
| else if (note < 96) | |||
| octave = 7; | |||
| else if (note < 108) | |||
| octave = 8; | |||
| else if (note < 120) | |||
| octave = 9; | |||
| else if (note < 132) | |||
| octave = 10; | |||
| else | |||
| // cannot paint this note either | |||
| // cannot paint this note | |||
| continue; | |||
| if (fPixmapMode == VERTICAL) | |||
| @@ -477,27 +529,30 @@ void PixmapKeyboard::paintEvent(QPaintEvent* event) | |||
| if (! _isNoteBlack(note)) | |||
| continue; | |||
| if (note < 36) | |||
| // cannot paint this note | |||
| continue; | |||
| else if (note < 48) | |||
| if (note < 12) | |||
| octave = 0; | |||
| else if (note < 60) | |||
| else if (note < 24) | |||
| octave = 1; | |||
| else if (note < 72) | |||
| else if (note < 36) | |||
| octave = 2; | |||
| else if (note < 84) | |||
| else if (note < 48) | |||
| octave = 3; | |||
| else if (note < 96) | |||
| else if (note < 60) | |||
| octave = 4; | |||
| else if (note < 108) | |||
| else if (note < 72) | |||
| octave = 5; | |||
| else if (note < 120) | |||
| else if (note < 84) | |||
| octave = 6; | |||
| else if (note < 132) | |||
| else if (note < 96) | |||
| octave = 7; | |||
| else if (note < 108) | |||
| octave = 8; | |||
| else if (note < 120) | |||
| octave = 9; | |||
| else if (note < 132) | |||
| octave = 10; | |||
| else | |||
| // cannot paint this note either | |||
| // cannot paint this note | |||
| continue; | |||
| if (fPixmapMode == VERTICAL) | |||
| @@ -528,28 +583,20 @@ void PixmapKeyboard::paintEvent(QPaintEvent* event) | |||
| for (int i=0; i < fOctaves; ++i) | |||
| { | |||
| if (fPixmapMode == HORIZONTAL) | |||
| painter.drawText(i * 144, 48, 18, 18, Qt::AlignCenter, QString("C%1").arg(i + 2)); | |||
| painter.drawText(i * 144, 48, 18, 18, Qt::AlignCenter, QString("C%1").arg(i-1)); | |||
| else if (fPixmapMode == VERTICAL) | |||
| painter.drawText(45, (fOctaves * 144) - (i * 144) - 16, 18, 18, Qt::AlignCenter, QString("C%1").arg(i + 2)); | |||
| } | |||
| } | |||
| void PixmapKeyboard::updateOnce() | |||
| { | |||
| if (fNeedsUpdate) | |||
| { | |||
| update(); | |||
| fNeedsUpdate = false; | |||
| painter.drawText(45, (fOctaves * 144) - (i * 144) - 16, 18, 18, Qt::AlignCenter, QString("C%1").arg(i-1)); | |||
| } | |||
| } | |||
| bool PixmapKeyboard::_isNoteBlack(int note) const | |||
| { | |||
| int baseNote = note % 12; | |||
| const int baseNote = note % 12; | |||
| return kBlackNotes.contains(baseNote); | |||
| } | |||
| const QRectF& PixmapKeyboard::_getRectFromMidiNote(int note) const | |||
| { | |||
| return fMidiMap[note % 12]; | |||
| const int baseNote = note % 12; | |||
| return fMidiMap[baseNote]; | |||
| } | |||
| @@ -61,15 +61,13 @@ signals: | |||
| protected: | |||
| void handleMousePos(const QPoint&); | |||
| void keyPressEvent(QKeyEvent*); | |||
| void keyReleaseEvent(QKeyEvent*); | |||
| void mousePressEvent(QMouseEvent*); | |||
| void mouseMoveEvent(QMouseEvent*); | |||
| void mouseReleaseEvent(QMouseEvent*); | |||
| void paintEvent(QPaintEvent*); | |||
| private Q_SLOTS: | |||
| void updateOnce(); | |||
| void keyPressEvent(QKeyEvent*) override; | |||
| void keyReleaseEvent(QKeyEvent*) override; | |||
| void mousePressEvent(QMouseEvent*) override; | |||
| void mouseMoveEvent(QMouseEvent*) override; | |||
| void mouseReleaseEvent(QMouseEvent*) override; | |||
| void paintEvent(QPaintEvent*) override; | |||
| private: | |||
| QPixmap fPixmap; | |||
| @@ -83,7 +81,6 @@ private: | |||
| int fWidth; | |||
| int fHeight; | |||
| bool fNeedsUpdate; | |||
| QList<int> fEnabledKeys; | |||
| std::map<int, QRectF>& fMidiMap; | |||
| @@ -103,7 +103,6 @@ class PixmapKeyboard(QWidget): | |||
| self.fOctaves = 6 | |||
| self.fLastMouseNote = -1 | |||
| self.fNeedsUpdate = False | |||
| self.fEnabledKeys = [] | |||
| self.fFont = QFont("Monospace", 7, QFont.Normal) | |||
| @@ -114,7 +113,6 @@ class PixmapKeyboard(QWidget): | |||
| def allNotesOff(self): | |||
| self.fEnabledKeys = [] | |||
| self.fNeedsUpdate = True | |||
| self.emit(SIGNAL("notesOff()")) | |||
| self.update() | |||
| @@ -264,7 +262,7 @@ class PixmapKeyboard(QWidget): | |||
| def mouseMoveEvent(self, event): | |||
| self.handleMousePos(event.pos()) | |||
| QWidget.mousePressEvent(self, event) | |||
| QWidget.mouseMoveEvent(self, event) | |||
| def mouseReleaseEvent(self, event): | |||
| if self.fLastMouseNote != -1: | |||
| @@ -324,7 +322,7 @@ class PixmapKeyboard(QWidget): | |||
| elif note < 132: | |||
| octave = 10 | |||
| else: | |||
| # cannot paint this note either | |||
| # cannot paint this note | |||
| continue | |||
| if self.fPixmapMode == self.VERTICAL: | |||
| @@ -393,7 +391,7 @@ class PixmapKeyboard(QWidget): | |||
| elif note < 132: | |||
| octave = 10 | |||
| else: | |||
| # cannot paint this note either | |||
| # cannot paint this note | |||
| continue | |||
| if self.fPixmapMode == self.VERTICAL: | |||
| @@ -425,4 +423,5 @@ class PixmapKeyboard(QWidget): | |||
| return bool(baseNote in kBlackNotes) | |||
| def _getRectFromMidiNote(self, note): | |||
| return self.fMidiMap.get(str(note % 12)) | |||
| baseNote = note % 12 | |||
| return self.fMidiMap.get(str(baseNote)) | |||