drumstick 2.0.0
pianoscene.cpp
Go to the documentation of this file.
1/*
2 Virtual Piano Widget for Qt5
3 Copyright (C) 2008-2020, Pedro Lopez-Cabanillas <plcl@users.sf.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include <QApplication>
20#include <QGraphicsSceneMouseEvent>
21#include <QKeyEvent>
22#include <QPalette>
25#include <qmath.h>
26
31
37
38namespace drumstick { namespace widgets {
39
40class PianoScene::PianoScenePrivate
41{
42public:
43 PianoScenePrivate ( const int baseOctave,
44 const int numKeys,
45 const int startKey ):
46 m_baseOctave( baseOctave ),
47 m_numKeys( numKeys ),
48 m_startKey( startKey ),
49 m_minNote( 0 ),
50 m_maxNote( 127 ),
51 m_transpose( 0 ),
52 m_showLabels( ShowNever ),
53 m_alterations( ShowSharps ),
54 m_octave( OctaveC4 ),
55 m_orientation( HorizontalOrientation ),
56 m_rawkbd( false ),
57 m_keyboardEnabled( true ),
58 m_mouseEnabled( true ),
59 m_touchEnabled( true ),
60 m_mousePressed( false ),
61 m_velocity( 100 ),
62 m_channel( 0 ),
63 m_velocityTint( true ),
64 m_handler( nullptr ),
65 m_keybdMap( nullptr ),
66 m_showColorScale( false ),
67 m_hilightPalette(PianoPalette(PAL_SINGLE)),
68 m_backgroundPalette(PianoPalette(PAL_KEYS)),
69 m_foregroundPalette(PianoPalette(PAL_FONT))
70 { }
71 int m_baseOctave;
72 int m_numKeys;
73 int m_startKey;
74 int m_minNote;
75 int m_maxNote;
76 int m_transpose;
77 LabelVisibility m_showLabels;
78 LabelAlteration m_alterations;
79 LabelCentralOctave m_octave;
80 LabelOrientation m_orientation;
81 bool m_rawkbd;
82 bool m_keyboardEnabled;
83 bool m_mouseEnabled;
84 bool m_touchEnabled;
85 bool m_mousePressed;
86 int m_velocity;
87 int m_channel;
88 bool m_velocityTint;
89 PianoHandler *m_handler;
90 KeyboardMap *m_keybdMap;
91 QHash<int, PianoKey *> m_keys;
92 QMap<int, KeyLabel *> m_labels;
93 QStringList m_noteNames;
94 QStringList m_names_s;
95 QStringList m_names_f;
96 bool m_showColorScale;
97 PianoPalette m_hilightPalette;
98 PianoPalette m_backgroundPalette;
99 PianoPalette m_foregroundPalette;
100};
101
102const int KEYWIDTH = 180;
103const int KEYHEIGHT = 720;
104
105static qreal sceneWidth(int keys) {
106 return KEYWIDTH * qCeil( keys * 7.0 / 12.0 );
107}
108
118 const int numKeys,
119 const int startKey,
120 const QColor& keyPressedColor,
121 QObject * parent )
122 : QGraphicsScene( QRectF(0, 0, sceneWidth(numKeys), KEYHEIGHT), parent ),
123 d(new PianoScenePrivate(baseOctave, numKeys, startKey))
124{
125 if (keyPressedColor.isValid()) {
126 setKeyPressedColor(keyPressedColor);
127 }
128 QBrush hilightBrush(getKeyPressedColor());
129 PianoKeybd* view = dynamic_cast<PianoKeybd*>(parent);
130 if (view != nullptr) {
131 setFont(view->font());
132 }
133 int upperLimit = d->m_numKeys + d->m_startKey;
134 int adj = d->m_startKey % 12;
135 if (adj >= 5) adj++;
136 for(int i = d->m_startKey; i < upperLimit; ++i)
137 {
138 float x = 0;
139 PianoKey* key = nullptr;
140 KeyLabel* lbl = nullptr;
141 int ocs = i / 12 * 7;
142 int j = i % 12;
143 if (j >= 5) j++;
144 if ((j % 2) == 0) {
145 x = (ocs + qFloor((j-adj) / 2.0)) * KEYWIDTH;
146 key = new PianoKey( QRectF(x, 0, KEYWIDTH, KEYHEIGHT), false, i );
147 lbl = new KeyLabel(key);
148 lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(0));
149 } else {
150 x = (ocs + qFloor((j-adj) / 2.0)) * KEYWIDTH + KEYWIDTH * 0.6 + 1;
151 key = new PianoKey( QRectF( x, 0, KEYWIDTH * 0.8 - 1, KEYHEIGHT * 0.6 ), true, i );
152 key->setZValue( 1 );
153 lbl = new KeyLabel(key);
154 lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(1));
155 }
156 addItem( key );
157 lbl->setFont(font());
158 key->setAcceptTouchEvents(true);
159 key->setPressedBrush(hilightBrush);
160 d->m_keys.insert(i, key);
161 d->m_labels.insert(i, lbl);
162 }
163 hideOrShowKeys();
164 retranslate();
165}
166
172
178{
179 return {static_cast<int>(sceneWidth(d->m_numKeys)), KEYHEIGHT};
180}
181
187{
188 d->m_keybdMap = map;
189}
190
196{
197 return d->m_keybdMap;
198}
199
208{
209 return d->m_handler;
210}
211
221{
222 d->m_handler = handler;
223}
224
230{
231 return d->m_hilightPalette;
232}
233
238void PianoScene::displayKeyOn(PianoKey* key)
239{
240 key->setPressed(true);
241 int n = key->getNote() + d->m_baseOctave*12 + d->m_transpose;
242 QString s = QString("#%1 (%2)").arg(n).arg(noteName(key));
243 emit signalName(s);
244 KeyLabel* lbl = dynamic_cast<KeyLabel*>(key->childItems().constFirst());
245 if (lbl != nullptr) {
246 lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(key->isBlack() ? 3 : 2));
247 if (d->m_showLabels == ShowActivated) {
248 lbl->setVisible(true);
249 }
250 }
251}
252
259void PianoScene::showKeyOn( PianoKey* key, QColor color, int vel )
260{
261 if (d->m_velocityTint && vel >= 0 && color.isValid() ) {
262 QBrush hilightBrush(color.lighter(200 - vel));
263 key->setPressedBrush(hilightBrush);
264 }
265 displayKeyOn(key);
266}
267
273void PianoScene::showKeyOn( PianoKey* key, int vel )
274{
276 displayKeyOn(key);
277}
278
284void PianoScene::showKeyOff( PianoKey* key, int vel)
285{
286 Q_UNUSED(vel)
287 key->setPressed(false);
288 emit signalName(QString());
289 KeyLabel* lbl = dynamic_cast<KeyLabel*>(key->childItems().constFirst());
290 if (lbl != nullptr) {
291 lbl->restoreColor();
292 if (d->m_showLabels == ShowActivated) {
293 lbl->setVisible(false);
294 }
295 }
296}
297
304void PianoScene::showNoteOn( const int note, QColor color, int vel )
305{
306 int n = note - d->m_baseOctave*12 - d->m_transpose;
307 if ((note >= d->m_minNote) && (note <= d->m_maxNote) && d->m_keys.contains(n) && color.isValid())
308 showKeyOn(d->m_keys.value(n), color, vel);
309}
310
316void PianoScene::showNoteOn( const int note, int vel )
317{
318 int n = note - d->m_baseOctave*12 - d->m_transpose;
319 if ((note >= d->m_minNote) && (note <= d->m_maxNote) && d->m_keys.contains(n)) {
320 showKeyOn(d->m_keys.value(n), vel);
321 }
322}
323
329void PianoScene::showNoteOff( const int note, int vel )
330{
331 int n = note - d->m_baseOctave*12 - d->m_transpose;
332 if ((note >= d->m_minNote) && (note <= d->m_maxNote) && d->m_keys.contains(n)) {
333 showKeyOff(d->m_keys.value(n), vel);
334 }
335}
336
342int PianoScene::baseOctave() const { return d->m_baseOctave; }
343
351void PianoScene::triggerNoteOn( const int note, const int vel )
352{
353 int n = d->m_baseOctave*12 + note + d->m_transpose;
354 if ((n >= d->m_minNote) && (n <= d->m_maxNote)) {
355 if (d->m_handler != nullptr) {
356 d->m_handler->noteOn(n, vel);
357 } else {
358 emit noteOn(n, vel);
359 }
360 }
361}
362
370void PianoScene::triggerNoteOff( const int note, const int vel )
371{
372 int n = d->m_baseOctave*12 + note + d->m_transpose;
373 if ((n >= d->m_minNote) && (n <= d->m_maxNote)) {
374 if (d->m_handler != nullptr) {
375 d->m_handler->noteOff(n, vel);
376 } else {
377 emit noteOff(n, vel);
378 }
379 }
380}
381
388void PianoScene::setHighlightColorFromPolicy(PianoKey* key, int vel)
389{
390 QColor c;
391 switch (d->m_hilightPalette.paletteId()) {
392 case PAL_SINGLE:
393 c = d->m_hilightPalette.getColor(0);
394 break;
395 case PAL_DOUBLE:
396 c = d->m_hilightPalette.getColor(key->getType());
397 break;
398 case PAL_CHANNELS:
399 c = d->m_hilightPalette.getColor(d->m_channel);
400 break;
401 default:
402 return;
403 }
404 if (c.isValid()) {
405 if (d->m_velocityTint) {
406 QBrush h(c.lighter(200 - vel));
407 key->setPressedBrush(h);
408 } else {
409 key->setPressedBrush(c);
410 }
411 }
412}
413
418void PianoScene::keyOn( PianoKey* key )
419{
420 triggerNoteOn(key->getNote(), d->m_velocity);
421 showKeyOn(key, d->m_velocity);
422}
423
428void PianoScene::keyOff( PianoKey* key )
429{
430 triggerNoteOff(key->getNote(), 0);
431 showKeyOff(key, 0);
432}
433
439void PianoScene::keyOn( PianoKey* key, qreal pressure )
440{
441 int vel = d->m_velocity * pressure;
442 triggerNoteOn(key->getNote(), vel);
443 showKeyOn(key, vel);
444}
445
451void PianoScene::keyOff( PianoKey* key, qreal pressure )
452{
453 int vel = d->m_velocity * pressure;
454 triggerNoteOff(key->getNote(), vel);
455 showKeyOff(key, vel);
456}
457
462void PianoScene::keyOn(const int note)
463{
464 if (d->m_keys.contains(note))
465 keyOn(d->m_keys.value(note));
466 else
467 triggerNoteOn(note, d->m_velocity);
468}
469
474void PianoScene::keyOff(const int note)
475{
476 if (d->m_keys.contains(note))
477 keyOff(d->m_keys.value(note));
478 else
479 triggerNoteOff(note, d->m_velocity);
480}
481
487{
488 return d->m_rawkbd;
489}
490
496PianoKey* PianoScene::getKeyForPos( const QPointF& p ) const
497{
498 PianoKey* key = nullptr;
499 QList<QGraphicsItem *> ptitems = this->items(p, Qt::IntersectsItemShape, Qt::DescendingOrder);
500 foreach(QGraphicsItem *itm, ptitems) {
501 key = dynamic_cast<PianoKey*>(itm);
502 if (key != nullptr)
503 break;
504 }
505 return key;
506}
507
512void PianoScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent )
513{
514 if (d->m_mouseEnabled) {
515 if (d->m_mousePressed) {
516 PianoKey* key = getKeyForPos(mouseEvent->scenePos());
517 PianoKey* lastkey = getKeyForPos(mouseEvent->lastScenePos());
518 if ((lastkey != nullptr) && (lastkey != key) && lastkey->isPressed()) {
519 keyOff(lastkey);
520 }
521 if ((key != nullptr) && !key->isPressed()) {
522 keyOn(key);
523 }
524 mouseEvent->accept();
525 return;
526 }
527 }
528}
529
534void PianoScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent )
535{
536 if (d->m_mouseEnabled) {
537 PianoKey* key = getKeyForPos(mouseEvent->scenePos());
538 if (key != nullptr && !key->isPressed()) {
539 keyOn(key);
540 d->m_mousePressed = true;
541 mouseEvent->accept();
542 return;
543 }
544 }
545}
546
551void PianoScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent )
552{
553 if (d->m_mouseEnabled) {
554 d->m_mousePressed = false;
555 PianoKey* key = getKeyForPos(mouseEvent->scenePos());
556 if (key != nullptr && key->isPressed()) {
557 keyOff(key);
558 mouseEvent->accept();
559 return;
560 }
561 }
562}
563
569int PianoScene::getNoteFromKey( const int key ) const
570{
571 if (d->m_keybdMap != nullptr) {
572 KeyboardMap::ConstIterator it = d->m_keybdMap->constFind(key);
573 if ((it != d->m_keybdMap->constEnd()) && (it.key() == key)) {
574 int note = it.value();
575 return note;
576 }
577 }
578 return -1;
579}
580
586PianoKey* PianoScene::getPianoKey( const int key ) const
587{
588 int note = getNoteFromKey(key);
589 if (d->m_keys.contains(note))
590 return d->m_keys.value(note);
591 return nullptr;
592}
593
598void PianoScene::keyPressEvent ( QKeyEvent * keyEvent )
599{
600 if ( d->m_keyboardEnabled) {
601 if ( !d->m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats
602 int note = getNoteFromKey(keyEvent->key());
603 if (note > -1)
604 keyOn(note);
605 }
606 keyEvent->accept();
607 return;
608 }
609 keyEvent->ignore();
610}
611
616void PianoScene::keyReleaseEvent ( QKeyEvent * keyEvent )
617{
618 if (d->m_keyboardEnabled) {
619 if ( !d->m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats
620 int note = getNoteFromKey(keyEvent->key());
621 if (note > -1)
622 keyOff(note);
623 }
624 keyEvent->accept();
625 return;
626 }
627 keyEvent->ignore();
628}
629
636{
637 switch(event->type()) {
638 case QEvent::TouchBegin:
639 case QEvent::TouchEnd:
640 case QEvent::TouchUpdate:
641 {
642 QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event);
643 if (d->m_touchEnabled && touchEvent->device()->type() == QTouchDevice::DeviceType::TouchScreen) {
644 QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
645 foreach(const QTouchEvent::TouchPoint& touchPoint, touchPoints) {
646 switch (touchPoint.state()) {
647 //case Qt::TouchPointPrimary:
648 case Qt::TouchPointStationary:
649 continue;
650 case Qt::TouchPointReleased: {
651 PianoKey* key = getKeyForPos(touchPoint.scenePos());
652 if (key != nullptr && key->isPressed()) {
653 keyOff(key, touchPoint.pressure());
654 }
655 break;
656 }
657 case Qt::TouchPointPressed: {
658 PianoKey* key = getKeyForPos(touchPoint.scenePos());
659 if (key != nullptr && !key->isPressed()) {
660 keyOn(key, touchPoint.pressure());
661 key->ensureVisible();
662 }
663 break;
664 }
665 case Qt::TouchPointMoved: {
666 PianoKey* key = getKeyForPos(touchPoint.scenePos());
667 PianoKey* lastkey = getKeyForPos(touchPoint.lastScenePos());
668 if ((lastkey != nullptr) && (lastkey != key) && lastkey->isPressed()) {
669 keyOff(lastkey, touchPoint.pressure());
670 }
671 if ((key != nullptr) && !key->isPressed()) {
672 keyOn(key, touchPoint.pressure());
673 }
674 break;
675 }
676 default:
677 //qDebug() << "TouchPoint state: " << touchPoint.state();
678 break;
679 }
680 }
681 //qDebug() << "accepted event: " << event;
682 event->accept();
683 return true;
684 }
685 break;
686 }
687 default:
688 break;
689 }
690 //qDebug() << "unprocessed event: " << event;
691 return QGraphicsScene::event(event);
692}
693
698{
699 foreach(PianoKey* key, d->m_keys) {
700 key->setPressed(false);
701 }
702}
703
710void PianoScene::setKeyPressedColor(const QColor& color)
711{
712 if (color.isValid()) {
713 d->m_hilightPalette = PianoPalette(PAL_SINGLE);
714 d->m_hilightPalette.setColor(0, color);
715 QBrush hilightBrush(color);
716 for (PianoKey* key : qAsConst(d->m_keys)) {
717 key->setPressedBrush(hilightBrush);
718 }
719 }
720}
721
726{
727 d->m_hilightPalette.resetColors();
728 QBrush hilightBrush(getKeyPressedColor());
729 for (PianoKey* key : qAsConst(d->m_keys)) {
730 key->setPressedBrush(hilightBrush);
731 }
732}
733
739{
740 return d->m_minNote;
741}
742
747{
748 for (PianoKey* key : qAsConst(d->m_keys)) {
749 int n = d->m_baseOctave*12 + key->getNote() + d->m_transpose;
750 bool b = !(n > d->m_maxNote) && !(n < d->m_minNote);
751 key->setVisible(b);
752 }
753}
754
759void PianoScene::setMinNote(const int note)
760{
761 if (d->m_minNote != note) {
762 d->m_minNote = note;
764 }
765}
766
772{
773 return d->m_maxNote;
774}
775
780void PianoScene::setMaxNote(const int note)
781{
782 if (d->m_maxNote != note) {
783 d->m_maxNote = note;
785 }
786}
787
793{
794 return d->m_transpose;
795}
796
801void PianoScene::setBaseOctave(const int base)
802{
803 if (d->m_baseOctave != base) {
804 d->m_baseOctave = base;
807 }
808}
809
815{
816 return d->m_numKeys;
817}
818
824{
825 return d->m_startKey;
826}
827
833bool PianoScene::isOctaveStart(const int note)
834{
835 return (note + d->m_transpose + 12) % 12 == 0;
836}
837
843QString PianoScene::noteName( PianoKey* key )
844{
845 Q_ASSERT(key != nullptr);
846 int note = key->getNote();
847 int num = (note + d->m_transpose + 12) % 12;
848 int adj = ((note + d->m_transpose < 0) ? 2 : 1) - d->m_octave + 1;
849 int oct = d->m_baseOctave + ((note + d->m_transpose) / 12) - adj;
850 if (d->m_noteNames.isEmpty()) {
851 QString name;
852 if (!d->m_names_f.isEmpty() && !d->m_names_s.isEmpty()) {
853 switch(d->m_alterations) {
854 case ShowFlats:
855 name = d->m_names_f.value(num);
856 break;
857 case ShowSharps:
858 name = d->m_names_s.value(num);
859 break;
860 case ShowNothing:
861 if (key->isBlack()) {
862 return QString();
863 }
864 name = d->m_names_s.value(num);
865 break;
866 default:
867 break;
868 }
869 }
870 if (d->m_octave==OctaveNothing) {
871 return name;
872 } else {
873 return QString("%1%2").arg(name).arg(oct);
874 }
875 } else {
876 if (d->m_noteNames.length() == 128) {
877 int n = d->m_baseOctave*12 + note + d->m_transpose;
878 //qDebug() << Q_FUNC_INFO << n << note;
879 if (n >= 0 && n < d->m_noteNames.length()) {
880 return d->m_noteNames.value(n);
881 }
882 } else if (d->m_noteNames.length() >= 12) {
883 if (d->m_octave==OctaveNothing) {
884 return d->m_noteNames.value(num);
885 } else {
886 return QString("%1%2").arg(d->m_noteNames.value(num)).arg(oct);
887 }
888 }
889 return QString();
890 }
891}
892
897{
898 for (KeyLabel* lbl : qAsConst(d->m_labels)) {
899 PianoKey* key = dynamic_cast<PianoKey*>(lbl->parentItem());
900 if (key != nullptr) {
901 lbl->setVisible(false);
902 lbl->setFont(font());
903 lbl->setDefaultTextColor(d->m_foregroundPalette.getColor(key->isBlack() ? 1 : 0));
904 lbl->setOrientation(d->m_orientation);
905 lbl->setPlainText(noteName(key));
906 lbl->adjust();
907 lbl->setVisible((d->m_showLabels == ShowAlways) ||
908 (d->m_showLabels == ShowMinimum && isOctaveStart(key->getNote())));
909 }
910 }
911}
912
917{
918 for (PianoKey* key : qAsConst(d->m_keys)) {
919 if (d->m_showColorScale && (d->m_backgroundPalette.paletteId() == PAL_SCALE)) {
920 int degree = key->getNote() % 12;
921 key->setBrush(d->m_backgroundPalette.getColor(degree));
922 } else {
923 key->setBrush(d->m_backgroundPalette.getColor(key->isBlack() ? 1 : 0));
924 }
925 key->setPressed(false);
926 }
927}
928
935{
936 //qDebug() << Q_FUNC_INFO << show;
937 if (d->m_showLabels != show) {
938 d->m_showLabels = show;
940 }
941}
942
949{
950 return d->m_alterations;
951}
952
959{
960 if (d->m_alterations != use) {
961 d->m_alterations = use;
963 }
964}
965
971{
972 return d->m_octave;
973}
974
980{
981 if (d->m_orientation != orientation) {
982 d->m_orientation = orientation;
984 }
985}
986
987bool PianoScene::isKeyboardEnabled() const
988{
989 return d->m_keyboardEnabled;
990}
991
992void PianoScene::setOctave(const LabelCentralOctave octave)
993{
994 if (d->m_octave != octave) {
995 d->m_octave = octave;
996 refreshLabels();
997 }
998}
999
1000LabelOrientation PianoScene::getOrientation() const
1001{
1002 return d->m_orientation;
1003}
1004
1009void PianoScene::setTranspose(const int transpose)
1010{
1011 if (d->m_transpose != transpose && transpose > -12 && transpose < 12) {
1012 d->m_transpose = transpose;
1014 refreshLabels();
1015 }
1016}
1017
1024{
1025 return d->m_showLabels;
1026}
1027
1033{
1034 if (d->m_rawkbd != b) {
1035 d->m_rawkbd = b;
1036 }
1037}
1038
1044{
1045 return d->m_noteNames;
1046}
1047
1053{
1054 return d->m_names_s;
1055}
1056
1062{
1063 return d->m_velocity;
1064}
1065
1070void PianoScene::setVelocity(const int velocity)
1071{
1072 d->m_velocity = velocity;
1073}
1074
1081{
1082 return d->m_channel;
1083}
1084
1090void PianoScene::setChannel(const int channel)
1091{
1092 d->m_channel = channel;
1093}
1094
1099void PianoScene::useCustomNoteNames(const QStringList& names)
1100{
1101 //qDebug() << Q_FUNC_INFO << names;
1102 d->m_noteNames = names;
1103 refreshLabels();
1104}
1105
1110{
1111 //qDebug() << Q_FUNC_INFO;
1112 d->m_noteNames.clear();
1113 refreshLabels();
1114}
1115
1120void PianoScene::setKeyboardEnabled(const bool enable)
1121{
1122 if (enable != d->m_keyboardEnabled) {
1123 d->m_keyboardEnabled = enable;
1124 }
1125}
1126
1132{
1133 return d->m_mouseEnabled;
1134}
1135
1140void PianoScene::setMouseEnabled(const bool enable)
1141{
1142 if (enable != d->m_mouseEnabled) {
1143 d->m_mouseEnabled = enable;
1144 }
1145}
1146
1152{
1153 return d->m_touchEnabled;
1154}
1155
1160void PianoScene::setTouchEnabled(const bool enable)
1161{
1162 if (enable != d->m_touchEnabled) {
1163 d->m_touchEnabled = enable;
1164 }
1165}
1166
1172{
1173 return d->m_velocityTint;
1174}
1175
1180void PianoScene::setVelocityTint(const bool enable)
1181{
1182 d->m_velocityTint = enable;
1183}
1184
1189{
1190 d->m_names_s = QStringList{
1191 tr("C"),
1192 tr("C♯"),
1193 tr("D"),
1194 tr("D♯"),
1195 tr("E"),
1196 tr("F"),
1197 tr("F♯"),
1198 tr("G"),
1199 tr("G♯"),
1200 tr("A"),
1201 tr("A♯"),
1202 tr("B")};
1203 d->m_names_f = QStringList{
1204 tr("C"),
1205 tr("D♭"),
1206 tr("D"),
1207 tr("E♭"),
1208 tr("E"),
1209 tr("F"),
1210 tr("G♭"),
1211 tr("G"),
1212 tr("A♭"),
1213 tr("A"),
1214 tr("B♭"),
1215 tr("B")};
1216 refreshLabels();
1217}
1218
1224{
1225 if (d->m_showColorScale != show) {
1226 d->m_showColorScale = show;
1227 refreshKeys();
1228 invalidate();
1229 }
1230}
1231
1237{
1238 return d->m_hilightPalette.getColor(0);
1239}
1240
1246{
1247 if (d->m_hilightPalette != p) {
1248 d->m_hilightPalette = p;
1249 refreshKeys();
1250 invalidate();
1251 }
1252}
1253
1259{
1260 return d->m_backgroundPalette;
1261}
1262
1268{
1269 if (d->m_backgroundPalette != p) {
1270 d->m_backgroundPalette = p;
1271 refreshKeys();
1272 invalidate();
1273 }
1274}
1275
1281{
1282 return d->m_foregroundPalette;
1283}
1284
1290{
1291 if (d->m_foregroundPalette != p) {
1292 d->m_foregroundPalette = p;
1293 refreshLabels();
1294 invalidate();
1295 }
1296}
1297
1303{
1304 return d->m_showColorScale;
1305}
1306
1307} // namespace widgets
1308} // namespace drumstick
The QEvent class is the base class of all event classes.
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items.
The QObject class is the base class of all Qt objects.
The PianoHandler class callbacks.
Definition pianokeybd.h:72
The PianoKeybd class.
Definition pianokeybd.h:159
The PianoPalette class.
void allKeysOff()
Deactivates all keys.
void triggerNoteOn(const int note, const int vel)
Performs a Note On MIDI event for the given MIDI note number and velocity.
void resetKeyPressedColor()
Assigns the default highlight palette colors and assigns it to the scene.
void keyOff(const int note)
Produces a MIDI Note Off event and deactivates the corresponding key for the given MIDI note number.
void showKeyOff(PianoKey *key, int vel)
Displays as deactivated a key.
void setBackgroundPalette(const PianoPalette &p)
Assigns the active background palette.
void setKeyPressedColor(const QColor &color)
Assigns a single color for key highlight.
void setRawKeyboardMode(const bool b)
Assigns the low level computer keyboard mode.
void keyOn(const int note)
Produces a MIDI Note On event and highlights the corresponding key for the given MIDI note number.
void useStandardNoteNames()
Assigns the standard note names, clearing the list of custom note names.
void hideOrShowKeys()
Hides or shows keys.
LabelCentralOctave getOctave() const
Returns the central octave name policy.
PianoScene(const int baseOctave, const int numKeys, const int startKey, const QColor &keyPressedColor=QColor(), QObject *parent=nullptr)
Constructor.
bool event(QEvent *event) override
Processes touch screen events.
int baseOctave() const
Returns the base octave number.
PianoPalette getForegroundPalette()
Returns the active foreground palette.
void setHighlightPalette(const PianoPalette &p)
Assigns the active highlight palette.
void setShowColorScale(const bool show)
Enables or disables the color scale key background mode.
void setPianoHandler(PianoHandler *handler)
Assigns a PianoHandler pointer for processing note events.
void setKeyboardMap(KeyboardMap *map)
Assigns the computer keyboard note map.
void noteOff(int n, int v)
This signal is emitted for each Note Off MIDI event created using the computer keyboard,...
void setVelocity(const int velocity)
Assigns the MIDI note velocity parameter that is assigned to the MIDI OUT notes.
void setMinNote(const int note)
Assigns the minimum MIDI note number that will be displayed.
bool showColorScale() const
Returns whether the color scale mode is enabled.
void setBaseOctave(const int base)
Assigns the octave base number.
PianoKey * getKeyForPos(const QPointF &p) const
Returns the piano key for the given scene point coordenates.
void signalName(const QString &name)
signalName is emitted for each note created, and contains a string with the MIDI note number and the ...
int numKeys() const
Returns the number of keys that will be displayed.
PianoPalette getHighlightPalette()
Returns the palette used for highlighting the played keys.
void setKeyboardEnabled(const bool enable)
Enables or disables the computer keyboard note generation.
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override
This event handler, for event mouseEvent, is reimplemented to receive mouse move events for the scene...
void triggerNoteOff(const int note, const int vel)
Performs a Note Off MIDI event for the given MIDI note number and velocity.
PianoKey * getPianoKey(const int key) const
Returns the piano key object corresponding to the given computer keyboard key.
int getVelocity()
Returns the MIDI note velocity parameter that is assigned to the MIDI OUT notes.
int getChannel() const
Returns the MIDI channel that is assigned to the output events, or used to filter the input events (u...
void setForegroundPalette(const PianoPalette &p)
Assigns the active foreground palette.
void keyPressEvent(QKeyEvent *keyEvent) override
This event handler, for event keyEvent, is reimplemented to receive keypress events.
void setVelocityTint(const bool enable)
Enables or disables the velocity parameter of note events to influence the highlight key colors.
bool velocityTint() const
Returns whether the velocity parameter of note events is used to influence the highlight key colors.
QColor getKeyPressedColor() const
Returns the single highlight palette color.
int getNoteFromKey(const int key) const
Returns the note number for the given computer keyboard key code.
void refreshLabels()
Refresh the visibility and other attributes of the labels shown over the piano keys.
void showNoteOff(const int note, int vel=-1)
Displays deactivated the corresponding key for a given MIDI note, with MIDI velocity.
void setShowLabels(const LabelVisibility show)
Assigns the label visibility policy to the piano keys.
void refreshKeys()
Refresh the background colors of all the piano keys.
QSize sizeHint() const
Returns the calculated size of the scene.
bool isOctaveStart(const int note)
Returns whether the given note number is a octave startup note.
void setAlterations(const LabelAlteration use)
Assigns the alterations name policy.
PianoPalette getBackgroundPalette()
Returns the background palette.
QStringList standardNoteNames() const
Returns the standard note names list.
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override
This event handler, for event mouseEvent, is reimplemented to receive mouse press events for the scen...
void setTranspose(const int transpose)
Assigns the transpose amount in semitones.
int getMaxNote() const
Returns the maximum MIDI note number that will be displayed.
LabelAlteration alterations() const
Returns the alterations name policy.
void setHighlightColorFromPolicy(PianoKey *key, const int vel)
Assigns to the given key the highlight color from the active highlight palette and the given MIDI vel...
PianoHandler * getPianoHandler() const
Gets the PianoHandler pointer to the note receiver.
void showKeyOn(PianoKey *key, QColor color, int vel)
Displays highlighted the activated key with the supplied color and note velocity.
KeyboardMap * getKeyboardMap() const
Returns the computer keyboard note map.
bool isMouseEnabled() const
Returns whether the computer keyboard note generation is enabled.
bool getRawKeyboardMode() const
Returns whether the low level computer keyboard mode is enabled.
void noteOn(int n, int v)
This signal is emitted for each Note On MIDI event created using the computer keyboard,...
void showNoteOn(const int note, QColor color, int vel=-1)
Displays highlighted the corresponding key for a given MIDI note, with a color and MIDI velocity.
void keyReleaseEvent(QKeyEvent *keyEvent) override
This event handler, for event keyEvent, is reimplemented to receive key release events.
void setMaxNote(const int note)
Assigns the maximum MIDI note number that will be displayed.
void retranslate()
Retranslates the standard note names.
int startKey() const
Returns the first key number that will be displayed.
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override
This event handler, for event mouseEvent, is reimplemented to receive mouse release events for the sc...
void setTouchEnabled(const bool enable)
Enables or disables the touch screen note generation.
void displayKeyOn(PianoKey *key)
Displays the note label over a highligted key.
void useCustomNoteNames(const QStringList &names)
Assigns the list of custom note names, and enables this mode.
void setMouseEnabled(const bool enable)
Enables or disables the mouse note generation.
void setChannel(const int channel)
Assigns the MIDI channel that is included into the output events, or used to filter the input events ...
int getMinNote() const
Returns the minimum MIDI note number that will be displayed.
void setOrientation(const LabelOrientation orientation)
Assigns the label orientation policy.
QStringList customNoteNames() const
Returns the custom note names list.
LabelVisibility showLabels() const
Returns the label visibility policy (display note names over the piano keys).
bool isTouchEnabled() const
Returns whether the touch screen note generation is enabled.
int getTranspose() const
Returns the transpose amount in semitones.
QString noteName(PianoKey *key)
Returns the note name string that will be displayed over a given piano key.
LabelAlteration
Labels for Alterations.
Definition pianokeybd.h:118
LabelCentralOctave
Labels Central Octave.
Definition pianokeybd.h:145
LabelVisibility
Labels Visibility.
Definition pianokeybd.h:108
LabelOrientation
Labels Orientation.
Definition pianokeybd.h:127
QHash< int, int > KeyboardMap
KeyboardMap.
Definition pianokeybd.h:96
@ ShowSharps
Show sharps on black keys.
Definition pianokeybd.h:119
@ ShowNothing
Do not show names on black keys.
Definition pianokeybd.h:121
@ ShowFlats
Show flats on black keys.
Definition pianokeybd.h:120
@ OctaveNothing
Don't show octave numbers.
Definition pianokeybd.h:146
@ OctaveC4
Central C, MIDI note #60 is C4.
Definition pianokeybd.h:148
@ ShowAlways
Show always note names.
Definition pianokeybd.h:112
@ ShowMinimum
Show only note C names.
Definition pianokeybd.h:110
@ ShowActivated
Show names when notes are activated.
Definition pianokeybd.h:111
@ ShowNever
Don't show note names.
Definition pianokeybd.h:109
@ HorizontalOrientation
Show horizontal names.
Definition pianokeybd.h:128
@ PAL_SCALE
Background colors for each chromatic scale note.
@ PAL_SINGLE
Single highlihgting color for all keys.
@ PAL_CHANNELS
Different highlihgting colors for each channel.
@ PAL_KEYS
Two background colors (naturals/alterations).
@ PAL_DOUBLE
Two highlihgting colors (naturals/alterations).
@ PAL_FONT
Foreground font colors for names.
Drumstick common.
Piano Keyboard Widget.
PianoScene class declaration.