comparison layer/NoteLayer.cpp @ 701:084f65094203

Extend numerical and colour scales (and piano where applicable) to note and region layers
author Chris Cannam
date Wed, 04 Dec 2013 13:39:41 +0000
parents 26b1ffe412f9
children ceb9a2992d96
comparison
equal deleted inserted replaced
700:7846175403f1 701:084f65094203
21 #include "base/Pitch.h" 21 #include "base/Pitch.h"
22 #include "base/LogRange.h" 22 #include "base/LogRange.h"
23 #include "base/RangeMapper.h" 23 #include "base/RangeMapper.h"
24 #include "ColourDatabase.h" 24 #include "ColourDatabase.h"
25 #include "view/View.h" 25 #include "view/View.h"
26
26 #include "PianoScale.h" 27 #include "PianoScale.h"
28 #include "LinearNumericalScale.h"
29 #include "LogNumericalScale.h"
27 30
28 #include "data/model/NoteModel.h" 31 #include "data/model/NoteModel.h"
29 32
30 #include "widgets/ItemEditDialog.h" 33 #include "widgets/ItemEditDialog.h"
34 #include "widgets/TextAbbrev.h"
31 35
32 #include <QPainter> 36 #include <QPainter>
33 #include <QPainterPath> 37 #include <QPainterPath>
34 #include <QMouseEvent> 38 #include <QMouseEvent>
35 #include <QTextStream> 39 #include <QTextStream>
103 return tr("Scale"); 107 return tr("Scale");
104 } 108 }
105 return SingleColourLayer::getPropertyGroupName(name); 109 return SingleColourLayer::getPropertyGroupName(name);
106 } 110 }
107 111
112 QString
113 NoteLayer::getScaleUnits() const
114 {
115 if (m_model) return m_model->getScaleUnits();
116 else return "";
117 }
118
108 int 119 int
109 NoteLayer::getPropertyRangeAndValue(const PropertyName &name, 120 NoteLayer::getPropertyRangeAndValue(const PropertyName &name,
110 int *min, int *max, int *deflt) const 121 int *min, int *max, int *deflt) const
111 { 122 {
112 int val = 0; 123 int val = 0;
122 } else if (name == "Scale Units") { 133 } else if (name == "Scale Units") {
123 134
124 if (deflt) *deflt = 0; 135 if (deflt) *deflt = 0;
125 if (m_model) { 136 if (m_model) {
126 val = UnitDatabase::getInstance()->getUnitId 137 val = UnitDatabase::getInstance()->getUnitId
127 (m_model->getScaleUnits()); 138 (getScaleUnits());
128 } 139 }
129 140
130 } else { 141 } else {
131 142
132 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt); 143 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt);
183 } 194 }
184 195
185 bool 196 bool
186 NoteLayer::shouldConvertMIDIToHz() const 197 NoteLayer::shouldConvertMIDIToHz() const
187 { 198 {
188 QString unit = m_model->getScaleUnits(); 199 QString unit = getScaleUnits();
189 return (unit != "Hz"); 200 return (unit != "Hz");
190 // if (unit == "" || 201 // if (unit == "" ||
191 // unit.startsWith("MIDI") || 202 // unit.startsWith("MIDI") ||
192 // unit.startsWith("midi")) return true; 203 // unit.startsWith("midi")) return true;
193 // return false; 204 // return false;
203 214
204 if (shouldConvertMIDIToHz()) { 215 if (shouldConvertMIDIToHz()) {
205 unit = "Hz"; 216 unit = "Hz";
206 min = Pitch::getFrequencyForPitch(lrintf(min)); 217 min = Pitch::getFrequencyForPitch(lrintf(min));
207 max = Pitch::getFrequencyForPitch(lrintf(max + 1)); 218 max = Pitch::getFrequencyForPitch(lrintf(max + 1));
208 } else unit = m_model->getScaleUnits(); 219 } else unit = getScaleUnits();
209 220
210 if (m_verticalScale == MIDIRangeScale || 221 if (m_verticalScale == MIDIRangeScale ||
211 m_verticalScale == LogScale) logarithmic = true; 222 m_verticalScale == LogScale) logarithmic = true;
212 223
213 return true; 224 return true;
497 pitchText = tr("%1 (%2, %3 Hz)") 508 pitchText = tr("%1 (%2, %3 Hz)")
498 .arg(Pitch::getPitchLabel(mnote, cents)) 509 .arg(Pitch::getPitchLabel(mnote, cents))
499 .arg(mnote) 510 .arg(mnote)
500 .arg(freq); 511 .arg(freq);
501 512
502 } else if (m_model->getScaleUnits() == "Hz") { 513 } else if (getScaleUnits() == "Hz") {
503 514
504 pitchText = tr("%1 Hz (%2, %3)") 515 pitchText = tr("%1 Hz (%2, %3)")
505 .arg(note.value) 516 .arg(note.value)
506 .arg(Pitch::getPitchLabelForFrequency(note.value)) 517 .arg(Pitch::getPitchLabelForFrequency(note.value))
507 .arg(Pitch::getPitchForFrequency(note.value)); 518 .arg(Pitch::getPitchForFrequency(note.value));
508 519
509 } else { 520 } else {
510 pitchText = tr("%1 %2") 521 pitchText = tr("%1 %2")
511 .arg(note.value).arg(m_model->getScaleUnits()); 522 .arg(note.value).arg(getScaleUnits());
512 } 523 }
513 524
514 QString text; 525 QString text;
515 526
516 if (note.label == "") { 527 if (note.label == "") {
610 max = 0.0; 621 max = 0.0;
611 log = false; 622 log = false;
612 623
613 QString queryUnits; 624 QString queryUnits;
614 if (shouldConvertMIDIToHz()) queryUnits = "Hz"; 625 if (shouldConvertMIDIToHz()) queryUnits = "Hz";
615 else queryUnits = m_model->getScaleUnits(); 626 else queryUnits = getScaleUnits();
616 627
617 if (shouldAutoAlign()) { 628 if (shouldAutoAlign()) {
618 629
619 if (!v->getValueExtents(queryUnits, min, max, log)) { 630 if (!v->getValueExtents(queryUnits, min, max, log)) {
620 631
791 !NoteModel::Point::Comparator()(p, illuminatePoint)) { 802 !NoteModel::Point::Comparator()(p, illuminatePoint)) {
792 803
793 paint.setPen(v->getForeground()); 804 paint.setPen(v->getForeground());
794 paint.setBrush(v->getForeground()); 805 paint.setBrush(v->getForeground());
795 806
796 QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits()); 807 QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits());
797 v->drawVisibleText(paint, 808 v->drawVisibleText(paint,
798 x - paint.fontMetrics().width(vlabel) - 2, 809 x - paint.fontMetrics().width(vlabel) - 2,
799 y + paint.fontMetrics().height()/2 810 y + paint.fontMetrics().height()/2
800 - paint.fontMetrics().descent(), 811 - paint.fontMetrics().descent(),
801 vlabel, View::OutlinedText); 812 vlabel, View::OutlinedText);
813 824
814 paint.restore(); 825 paint.restore();
815 } 826 }
816 827
817 int 828 int
818 NoteLayer::getVerticalScaleWidth(View *, bool, QPainter &paint) const 829 NoteLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const
819 { 830 {
820 if (!m_model || shouldAutoAlign()) { 831 if (!m_model || shouldAutoAlign()) {
821 return 0; 832 return 0;
822 } else if (m_verticalScale == LogScale || 833 } else {
823 m_verticalScale == MIDIRangeScale) { 834 if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) {
824 return 10; 835 return LogNumericalScale().getWidth(v, paint) + 10; // for piano
836 } else {
837 return LinearNumericalScale().getWidth(v, paint);
838 }
839 }
840 }
841
842 void
843 NoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const
844 {
845 if (!m_model) return;
846
847 QString unit;
848 float min, max;
849 bool logarithmic;
850
851 int w = getVerticalScaleWidth(v, false, paint);
852 int h = v->height();
853
854 getScaleExtents(v, min, max, logarithmic);
855
856 if (logarithmic) {
857 LogNumericalScale().paintVertical(v, this, paint, 0, min, max);
825 } else { 858 } else {
826 return 0; 859 LinearNumericalScale().paintVertical(v, this, paint, 0, min, max);
827 } 860 }
828 } 861
829 862 if (logarithmic && (getScaleUnits() == "Hz")) {
830 void
831 NoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const
832 {
833 if (m_verticalScale == LogScale ||
834 m_verticalScale == MIDIRangeScale) {
835 float fmin, fmax;
836 getDisplayExtents(fmin, fmax);
837 PianoScale().paintPianoVertical 863 PianoScale().paintPianoVertical
838 (v, paint, QRect(0, 0, 10, v->height()), fmin, fmax); 864 (v, paint, QRect(w - 10, 0, 10, h),
839 paint.drawLine(10, 0, 10, v->height()); 865 LogRange::unmap(min),
866 LogRange::unmap(max));
867 paint.drawLine(w, 0, w, h);
868 }
869
870 if (getScaleUnits() != "") {
871 int mw = w - 5;
872 paint.drawText(5,
873 5 + paint.fontMetrics().ascent(),
874 TextAbbrev::abbreviate(getScaleUnits(),
875 paint.fontMetrics(),
876 mw));
840 } 877 }
841 } 878 }
842 879
843 void 880 void
844 NoteLayer::drawStart(View *v, QMouseEvent *e) 881 NoteLayer::drawStart(View *v, QMouseEvent *e)
1037 (m_model->getSampleRate(), 1074 (m_model->getSampleRate(),
1038 ItemEditDialog::ShowTime | 1075 ItemEditDialog::ShowTime |
1039 ItemEditDialog::ShowDuration | 1076 ItemEditDialog::ShowDuration |
1040 ItemEditDialog::ShowValue | 1077 ItemEditDialog::ShowValue |
1041 ItemEditDialog::ShowText, 1078 ItemEditDialog::ShowText,
1042 m_model->getScaleUnits()); 1079 getScaleUnits());
1043 1080
1044 dialog->setFrameTime(note.frame); 1081 dialog->setFrameTime(note.frame);
1045 dialog->setValue(note.value); 1082 dialog->setValue(note.value);
1046 dialog->setFrameDuration(note.duration); 1083 dialog->setFrameDuration(note.duration);
1047 dialog->setText(note.label); 1084 dialog->setText(note.label);