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>
23 #include <drumstick/pianokeybd.h>
24 #include <drumstick/pianoscene.h>
25 #include <qmath.h>
26 
38 namespace drumstick { namespace widgets {
39 
40 class PianoScene::PianoScenePrivate
41 {
42 public:
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 
102 const int KEYWIDTH = 180;
103 const int KEYHEIGHT = 720;
104 
105 static qreal sceneWidth(int keys) {
106  return KEYWIDTH * qCeil( keys * 7.0 / 12.0 );
107 }
108 
117 PianoScene::PianoScene ( const int baseOctave,
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 
171 { }
172 
177 QSize PianoScene::sizeHint() const
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 
238 void 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 
259 void 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 
273 void PianoScene::showKeyOn( PianoKey* key, int vel )
274 {
275  setHighlightColorFromPolicy(key, vel);
276  displayKeyOn(key);
277 }
278 
284 void 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 
304 void 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 
316 void 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 
329 void 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 
342 int PianoScene::baseOctave() const { return d->m_baseOctave; }
343 
351 void 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 
370 void 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 
388 void 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 
418 void PianoScene::keyOn( PianoKey* key )
419 {
420  triggerNoteOn(key->getNote(), d->m_velocity);
421  showKeyOn(key, d->m_velocity);
422 }
423 
428 void PianoScene::keyOff( PianoKey* key )
429 {
430  triggerNoteOff(key->getNote(), 0);
431  showKeyOff(key, 0);
432 }
433 
439 void 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 
451 void 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 
462 void 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 
474 void 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 
496 PianoKey* 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 
512 void 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 
534 void 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 
551 void 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 
569 int 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 
586 PianoKey* 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 
598 void 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 
616 void 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 
710 void 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 
759 void PianoScene::setMinNote(const int note)
760 {
761  if (d->m_minNote != note) {
762  d->m_minNote = note;
763  hideOrShowKeys();
764  }
765 }
766 
772 {
773  return d->m_maxNote;
774 }
775 
780 void PianoScene::setMaxNote(const int note)
781 {
782  if (d->m_maxNote != note) {
783  d->m_maxNote = note;
784  hideOrShowKeys();
785  }
786 }
787 
793 {
794  return d->m_transpose;
795 }
796 
801 void PianoScene::setBaseOctave(const int base)
802 {
803  if (d->m_baseOctave != base) {
804  d->m_baseOctave = base;
805  hideOrShowKeys();
806  refreshLabels();
807  }
808 }
809 
815 {
816  return d->m_numKeys;
817 }
818 
824 {
825  return d->m_startKey;
826 }
827 
833 bool PianoScene::isOctaveStart(const int note)
834 {
835  return (note + d->m_transpose + 12) % 12 == 0;
836 }
837 
843 QString 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;
939  refreshLabels();
940  }
941 }
942 
949 {
950  return d->m_alterations;
951 }
952 
959 {
960  if (d->m_alterations != use) {
961  d->m_alterations = use;
962  refreshLabels();
963  }
964 }
965 
971 {
972  return d->m_octave;
973 }
974 
980 {
981  if (d->m_orientation != orientation) {
982  d->m_orientation = orientation;
983  refreshLabels();
984  }
985 }
986 
987 bool PianoScene::isKeyboardEnabled() const
988 {
989  return d->m_keyboardEnabled;
990 }
991 
992 void PianoScene::setOctave(const LabelCentralOctave octave)
993 {
994  if (d->m_octave != octave) {
995  d->m_octave = octave;
996  refreshLabels();
997  }
998 }
999 
1000 LabelOrientation PianoScene::getOrientation() const
1001 {
1002  return d->m_orientation;
1003 }
1004 
1009 void PianoScene::setTranspose(const int transpose)
1010 {
1011  if (d->m_transpose != transpose && transpose > -12 && transpose < 12) {
1012  d->m_transpose = transpose;
1013  hideOrShowKeys();
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 
1043 QStringList PianoScene::customNoteNames() const
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 
1070 void PianoScene::setVelocity(const int velocity)
1071 {
1072  d->m_velocity = velocity;
1073 }
1074 
1081 {
1082  return d->m_channel;
1083 }
1084 
1090 void PianoScene::setChannel(const int channel)
1091 {
1092  d->m_channel = channel;
1093 }
1094 
1099 void 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 
1120 void 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 
1140 void 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 
1160 void 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 
1180 void 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 
1223 void PianoScene::setShowColorScale(const bool show)
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
void showNoteOff(const int note, int vel=-1)
Displays deactivated the corresponding key for a given MIDI note, with MIDI velocity.
Definition: pianoscene.cpp:329
The PianoHandler class callbacks.
Definition: pianokeybd.h:71
bool isMouseEnabled() const
Returns whether the computer keyboard note generation is enabled.
QSize sizeHint() const
Returns the calculated size of the scene.
Definition: pianoscene.cpp:177
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items...
void triggerNoteOn(const int note, const int vel)
Performs a Note On MIDI event for the given MIDI note number and velocity.
Definition: pianoscene.cpp:351
bool velocityTint() const
Returns whether the velocity parameter of note events is used to influence the highlight key colors...
LabelOrientation
Labels Orientation.
Definition: pianokeybd.h:127
PianoPalette getBackgroundPalette()
Returns the background palette.
The PianoKeybd class.
Definition: pianokeybd.h:158
void setHighlightPalette(const PianoPalette &p)
Assigns the active highlight palette.
void showKeyOff(PianoKey *key, int vel)
Displays as deactivated a key.
Definition: pianoscene.cpp:284
void setShowColorScale(const bool show)
Enables or disables the color scale key background mode.
void allKeysOff()
Deactivates all keys.
Definition: pianoscene.cpp:697
void refreshLabels()
Refresh the visibility and other attributes of the labels shown over the piano keys.
Definition: pianoscene.cpp:896
void keyOn(const int note)
Produces a MIDI Note On event and highlights the corresponding key for the given MIDI note number...
Definition: pianoscene.cpp:462
void keyPressEvent(QKeyEvent *keyEvent) override
This event handler, for event keyEvent, is reimplemented to receive keypress events.
Definition: pianoscene.cpp:598
void setVelocityTint(const bool enable)
Enables or disables the velocity parameter of note events to influence the highlight key colors...
The PianoPalette class.
Definition: pianopalette.h:59
QHash< int, int > KeyboardMap
KeyboardMap.
Definition: pianokeybd.h:96
void signalName(const QString &name)
signalName is emitted for each note created, and contains a string with the MIDI note number and the ...
void setKeyPressedColor(const QColor &color)
Assigns a single color for key highlight.
Definition: pianoscene.cpp:710
void useStandardNoteNames()
Assigns the standard note names, clearing the list of custom note names.
KeyboardMap * getKeyboardMap() const
Returns the computer keyboard note map.
Definition: pianoscene.cpp:195
void setOrientation(const LabelOrientation orientation)
Assigns the label orientation policy.
Definition: pianoscene.cpp:979
Single highlihgting color for all keys.
Definition: pianopalette.h:46
Two highlihgting colors (naturals/alterations)
Definition: pianopalette.h:47
int getMaxNote() const
Returns the maximum MIDI note number that will be displayed.
Definition: pianoscene.cpp:771
The QObject class is the base class of all Qt objects.
int numKeys() const
Returns the number of keys that will be displayed.
Definition: pianoscene.cpp:814
void setPianoHandler(PianoHandler *handler)
Assigns a PianoHandler pointer for processing note events.
Definition: pianoscene.cpp:220
void retranslate()
Retranslates the standard note names.
void showKeyOn(PianoKey *key, QColor color, int vel)
Displays highlighted the activated key with the supplied color and note velocity. ...
Definition: pianoscene.cpp:259
LabelVisibility showLabels() const
Returns the label visibility policy (display note names over the piano keys).
Show always note names.
Definition: pianokeybd.h:112
void setMaxNote(const int note)
Assigns the maximum MIDI note number that will be displayed.
Definition: pianoscene.cpp:780
void setMouseEnabled(const bool enable)
Enables or disables the mouse note generation.
PianoHandler * getPianoHandler() const
Gets the PianoHandler pointer to the note receiver.
Definition: pianoscene.cpp:207
Don&#39;t show octave numbers.
Definition: pianokeybd.h:146
Drumstick common.
Definition: alsaclient.cpp:68
LabelVisibility
Labels Visibility.
Definition: pianokeybd.h:108
void setKeyboardMap(KeyboardMap *map)
Assigns the computer keyboard note map.
Definition: pianoscene.cpp:186
bool isTouchEnabled() const
Returns whether the touch screen note generation is enabled.
Foreground font colors for names.
Definition: pianopalette.h:51
Two background colors (naturals/alterations)
Definition: pianopalette.h:50
Show sharps on black keys.
Definition: pianokeybd.h:119
void displayKeyOn(PianoKey *key)
Displays the note label over a highligted key.
Definition: pianoscene.cpp:238
void refreshKeys()
Refresh the background colors of all the piano keys.
Definition: pianoscene.cpp:916
Show only note C names.
Definition: pianokeybd.h:110
PianoScene class declaration.
void triggerNoteOff(const int note, const int vel)
Performs a Note Off MIDI event for the given MIDI note number and velocity.
Definition: pianoscene.cpp:370
Don&#39;t show note names.
Definition: pianokeybd.h:109
int getVelocity()
Returns the MIDI note velocity parameter that is assigned to the MIDI OUT notes.
PianoKey * getPianoKey(const int key) const
Returns the piano key object corresponding to the given computer keyboard key.
Definition: pianoscene.cpp:586
void keyReleaseEvent(QKeyEvent *keyEvent) override
This event handler, for event keyEvent, is reimplemented to receive key release events.
Definition: pianoscene.cpp:616
Background colors for each chromatic scale note.
Definition: pianopalette.h:49
void setMinNote(const int note)
Assigns the minimum MIDI note number that will be displayed.
Definition: pianoscene.cpp:759
int startKey() const
Returns the first key number that will be displayed.
Definition: pianoscene.cpp:823
void setTranspose(const int transpose)
Assigns the transpose amount in semitones.
int getNoteFromKey(const int key) const
Returns the note number for the given computer keyboard key code.
Definition: pianoscene.cpp:569
QColor getKeyPressedColor() const
Returns the single highlight palette color.
int getChannel() const
Returns the MIDI channel that is assigned to the output events, or used to filter the input events (u...
PianoKey * getKeyForPos(const QPointF &p) const
Returns the piano key for the given scene point coordenates.
Definition: pianoscene.cpp:496
Show names when notes are activated.
Definition: pianokeybd.h:111
bool event(QEvent *event) override
Processes touch screen events.
Definition: pianoscene.cpp:635
void useCustomNoteNames(const QStringList &names)
Assigns the list of custom note names, and enables this mode.
int getMinNote() const
Returns the minimum MIDI note number that will be displayed.
Definition: pianoscene.cpp:738
void setVelocity(const int velocity)
Assigns the MIDI note velocity parameter that is assigned to the MIDI OUT notes.
QStringList customNoteNames() const
Returns the custom note names list.
void noteOn(int n, int v)
This signal is emitted for each Note On MIDI event created using the computer keyboard, mouse or touch screen.
void setShowLabels(const LabelVisibility show)
Assigns the label visibility policy to the piano keys.
Definition: pianoscene.cpp:934
void noteOff(int n, int v)
This signal is emitted for each Note Off MIDI event created using the computer keyboard, mouse or touch screen.
void setKeyboardEnabled(const bool enable)
Enables or disables the computer keyboard note generation.
LabelAlteration
Labels for Alterations.
Definition: pianokeybd.h:118
QStringList standardNoteNames() const
Returns the standard note names list.
void resetKeyPressedColor()
Assigns the default highlight palette colors and assigns it to the scene.
Definition: pianoscene.cpp:725
Show flats on black keys.
Definition: pianokeybd.h:120
QString noteName(PianoKey *key)
Returns the note name string that will be displayed over a given piano key.
Definition: pianoscene.cpp:843
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...
Definition: pianoscene.cpp:304
void keyOff(const int note)
Produces a MIDI Note Off event and deactivates the corresponding key for the given MIDI note number...
Definition: pianoscene.cpp:474
Central C, MIDI note #60 is C4.
Definition: pianokeybd.h:148
Different highlihgting colors for each channel.
Definition: pianopalette.h:48
bool isOctaveStart(const int note)
Returns whether the given note number is a octave startup note.
Definition: pianoscene.cpp:833
LabelCentralOctave
Labels Central Octave.
Definition: pianokeybd.h:145
void setForegroundPalette(const PianoPalette &p)
Assigns the active foreground palette.
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...
Definition: pianoscene.cpp:388
void hideOrShowKeys()
Hides or shows keys.
Definition: pianoscene.cpp:746
void setBaseOctave(const int base)
Assigns the octave base number.
Definition: pianoscene.cpp:801
Piano Keyboard Widget.
Do not show names on black keys.
Definition: pianokeybd.h:121
PianoScene(const int baseOctave, const int numKeys, const int startKey, const QColor &keyPressedColor=QColor(), QObject *parent=nullptr)
Constructor.
Definition: pianoscene.cpp:117
PianoPalette getForegroundPalette()
Returns the active foreground palette.
LabelAlteration alterations() const
Returns the alterations name policy.
Definition: pianoscene.cpp:948
void setRawKeyboardMode(const bool b)
Assigns the low level computer keyboard mode.
bool showColorScale() const
Returns whether the color scale mode is enabled.
int baseOctave() const
Returns the base octave number.
Definition: pianoscene.cpp:342
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override
This event handler, for event mouseEvent, is reimplemented to receive mouse press events for the scen...
Definition: pianoscene.cpp:534
LabelCentralOctave getOctave() const
Returns the central octave name policy.
Definition: pianoscene.cpp:970
bool getRawKeyboardMode() const
Returns whether the low level computer keyboard mode is enabled.
Definition: pianoscene.cpp:486
void setBackgroundPalette(const PianoPalette &p)
Assigns the active background palette.
The QEvent class is the base class of all event classes.
void setAlterations(const LabelAlteration use)
Assigns the alterations name policy.
Definition: pianoscene.cpp:958
void setChannel(const int channel)
Assigns the MIDI channel that is included into the output events, or used to filter the input events ...
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override
This event handler, for event mouseEvent, is reimplemented to receive mouse release events for the sc...
Definition: pianoscene.cpp:551
void setTouchEnabled(const bool enable)
Enables or disables the touch screen note generation.
int getTranspose() const
Returns the transpose amount in semitones.
Definition: pianoscene.cpp:792
PianoPalette getHighlightPalette()
Returns the palette used for highlighting the played keys.
Definition: pianoscene.cpp:229
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override
This event handler, for event mouseEvent, is reimplemented to receive mouse move events for the scene...
Definition: pianoscene.cpp:512