Mercurial > hg > svgui
comparison layer/NoteLayer.cpp @ 1216:dc2af6616c83
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:50 +0000 |
parents | ee01a4062747 |
children | a34a2a25907c |
comparison
equal
deleted
inserted
replaced
1048:e8102ff5573b | 1216:dc2af6616c83 |
---|---|
19 #include "base/RealTime.h" | 19 #include "base/RealTime.h" |
20 #include "base/Profiler.h" | 20 #include "base/Profiler.h" |
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 "view/View.h" | |
25 | |
24 #include "ColourDatabase.h" | 26 #include "ColourDatabase.h" |
25 #include "view/View.h" | |
26 | |
27 #include "PianoScale.h" | 27 #include "PianoScale.h" |
28 #include "LinearNumericalScale.h" | 28 #include "LinearNumericalScale.h" |
29 #include "LogNumericalScale.h" | 29 #include "LogNumericalScale.h" |
30 #include "PaintAssistant.h" | |
30 | 31 |
31 #include "data/model/NoteModel.h" | 32 #include "data/model/NoteModel.h" |
32 | 33 |
33 #include "widgets/ItemEditDialog.h" | 34 #include "widgets/ItemEditDialog.h" |
34 #include "widgets/TextAbbrev.h" | 35 #include "widgets/TextAbbrev.h" |
189 m_verticalScale = scale; | 190 m_verticalScale = scale; |
190 emit layerParametersChanged(); | 191 emit layerParametersChanged(); |
191 } | 192 } |
192 | 193 |
193 bool | 194 bool |
194 NoteLayer::isLayerScrollable(const View *v) const | 195 NoteLayer::isLayerScrollable(const LayerGeometryProvider *v) const |
195 { | 196 { |
196 QPoint discard; | 197 QPoint discard; |
197 return !v->shouldIlluminateLocalFeatures(this, discard); | 198 return !v->shouldIlluminateLocalFeatures(this, discard); |
198 } | 199 } |
199 | 200 |
387 | 388 |
388 return mapper; | 389 return mapper; |
389 } | 390 } |
390 | 391 |
391 NoteModel::PointList | 392 NoteModel::PointList |
392 NoteLayer::getLocalPoints(View *v, int x) const | 393 NoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const |
393 { | 394 { |
394 if (!m_model) return NoteModel::PointList(); | 395 if (!m_model) return NoteModel::PointList(); |
395 | 396 |
396 sv_frame_t frame = v->getFrameForX(x); | 397 sv_frame_t frame = v->getFrameForX(x); |
397 | 398 |
430 | 431 |
431 return usePoints; | 432 return usePoints; |
432 } | 433 } |
433 | 434 |
434 bool | 435 bool |
435 NoteLayer::getPointToDrag(View *v, int x, int y, NoteModel::Point &p) const | 436 NoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, NoteModel::Point &p) const |
436 { | 437 { |
437 if (!m_model) return false; | 438 if (!m_model) return false; |
438 | 439 |
439 sv_frame_t frame = v->getFrameForX(x); | 440 sv_frame_t frame = v->getFrameForX(x); |
440 | 441 |
458 | 459 |
459 return true; | 460 return true; |
460 } | 461 } |
461 | 462 |
462 QString | 463 QString |
463 NoteLayer::getFeatureDescription(View *v, QPoint &pos) const | 464 NoteLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const |
464 { | 465 { |
465 int x = pos.x(); | 466 int x = pos.x(); |
466 | 467 |
467 if (!m_model || !m_model->getSampleRate()) return ""; | 468 if (!m_model || !m_model->getSampleRate()) return ""; |
468 | 469 |
545 getYForValue(v, note.value)); | 546 getYForValue(v, note.value)); |
546 return text; | 547 return text; |
547 } | 548 } |
548 | 549 |
549 bool | 550 bool |
550 NoteLayer::snapToFeatureFrame(View *v, sv_frame_t &frame, | 551 NoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, |
551 int &resolution, | 552 int &resolution, |
552 SnapType snap) const | 553 SnapType snap) const |
553 { | 554 { |
554 if (!m_model) { | 555 if (!m_model) { |
555 return Layer::snapToFeatureFrame(v, frame, resolution, snap); | 556 return Layer::snapToFeatureFrame(v, frame, resolution, snap); |
617 frame = snapped; | 618 frame = snapped; |
618 return found; | 619 return found; |
619 } | 620 } |
620 | 621 |
621 void | 622 void |
622 NoteLayer::getScaleExtents(View *v, double &min, double &max, bool &log) const | 623 NoteLayer::getScaleExtents(LayerGeometryProvider *v, double &min, double &max, bool &log) const |
623 { | 624 { |
624 min = 0.0; | 625 min = 0.0; |
625 max = 0.0; | 626 max = 0.0; |
626 log = false; | 627 log = false; |
627 | 628 |
675 | 676 |
676 if (max == min) max = min + 1.0; | 677 if (max == min) max = min + 1.0; |
677 } | 678 } |
678 | 679 |
679 int | 680 int |
680 NoteLayer::getYForValue(View *v, double val) const | 681 NoteLayer::getYForValue(LayerGeometryProvider *v, double val) const |
681 { | 682 { |
682 double min = 0.0, max = 0.0; | 683 double min = 0.0, max = 0.0; |
683 bool logarithmic = false; | 684 bool logarithmic = false; |
684 int h = v->height(); | 685 int h = v->getPaintHeight(); |
685 | 686 |
686 getScaleExtents(v, min, max, logarithmic); | 687 getScaleExtents(v, min, max, logarithmic); |
687 | 688 |
688 #ifdef DEBUG_NOTE_LAYER | 689 #ifdef DEBUG_NOTE_LAYER |
689 cerr << "NoteLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << endl; | 690 cerr << "NoteLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << endl; |
710 #endif | 711 #endif |
711 return y; | 712 return y; |
712 } | 713 } |
713 | 714 |
714 double | 715 double |
715 NoteLayer::getValueForY(View *v, int y) const | 716 NoteLayer::getValueForY(LayerGeometryProvider *v, int y) const |
716 { | 717 { |
717 double min = 0.0, max = 0.0; | 718 double min = 0.0, max = 0.0; |
718 bool logarithmic = false; | 719 bool logarithmic = false; |
719 int h = v->height(); | 720 int h = v->getPaintHeight(); |
720 | 721 |
721 getScaleExtents(v, min, max, logarithmic); | 722 getScaleExtents(v, min, max, logarithmic); |
722 | 723 |
723 double val = min + (double(h - y) * double(max - min)) / h; | 724 double val = min + (double(h - y) * double(max - min)) / h; |
724 | 725 |
739 if (!m_model) return false; | 740 if (!m_model) return false; |
740 return (m_verticalScale == AutoAlignScale); | 741 return (m_verticalScale == AutoAlignScale); |
741 } | 742 } |
742 | 743 |
743 void | 744 void |
744 NoteLayer::paint(View *v, QPainter &paint, QRect rect) const | 745 NoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const |
745 { | 746 { |
746 if (!m_model || !m_model->isOK()) return; | 747 if (!m_model || !m_model->isOK()) return; |
747 | 748 |
748 sv_samplerate_t sampleRate = m_model->getSampleRate(); | 749 sv_samplerate_t sampleRate = m_model->getSampleRate(); |
749 if (!sampleRate) return; | 750 if (!sampleRate) return; |
807 | 808 |
808 paint.setPen(v->getForeground()); | 809 paint.setPen(v->getForeground()); |
809 paint.setBrush(v->getForeground()); | 810 paint.setBrush(v->getForeground()); |
810 | 811 |
811 QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits()); | 812 QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits()); |
812 v->drawVisibleText(paint, | 813 PaintAssistant::drawVisibleText(v, paint, |
813 x - paint.fontMetrics().width(vlabel) - 2, | 814 x - paint.fontMetrics().width(vlabel) - 2, |
814 y + paint.fontMetrics().height()/2 | 815 y + paint.fontMetrics().height()/2 |
815 - paint.fontMetrics().descent(), | 816 - paint.fontMetrics().descent(), |
816 vlabel, View::OutlinedText); | 817 vlabel, PaintAssistant::OutlinedText); |
817 | 818 |
818 QString hlabel = RealTime::frame2RealTime | 819 QString hlabel = RealTime::frame2RealTime |
819 (p.frame, m_model->getSampleRate()).toText(true).c_str(); | 820 (p.frame, m_model->getSampleRate()).toText(true).c_str(); |
820 v->drawVisibleText(paint, | 821 PaintAssistant::drawVisibleText(v, paint, |
821 x, | 822 x, |
822 y - h/2 - paint.fontMetrics().descent() - 2, | 823 y - h/2 - paint.fontMetrics().descent() - 2, |
823 hlabel, View::OutlinedText); | 824 hlabel, PaintAssistant::OutlinedText); |
824 } | 825 } |
825 | 826 |
826 paint.drawRect(x, y - h/2, w, h); | 827 paint.drawRect(x, y - h/2, w, h); |
827 } | 828 } |
828 | 829 |
829 paint.restore(); | 830 paint.restore(); |
830 } | 831 } |
831 | 832 |
832 int | 833 int |
833 NoteLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const | 834 NoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const |
834 { | 835 { |
835 if (!m_model || shouldAutoAlign()) { | 836 if (!m_model || shouldAutoAlign()) { |
836 return 0; | 837 return 0; |
837 } else { | 838 } else { |
838 if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { | 839 if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { |
842 } | 843 } |
843 } | 844 } |
844 } | 845 } |
845 | 846 |
846 void | 847 void |
847 NoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const | 848 NoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const |
848 { | 849 { |
849 if (!m_model || m_model->getPoints().empty()) return; | 850 if (!m_model || m_model->getPoints().empty()) return; |
850 | 851 |
851 QString unit; | 852 QString unit; |
852 double min, max; | 853 double min, max; |
853 bool logarithmic; | 854 bool logarithmic; |
854 | 855 |
855 int w = getVerticalScaleWidth(v, false, paint); | 856 int w = getVerticalScaleWidth(v, false, paint); |
856 int h = v->height(); | 857 int h = v->getPaintHeight(); |
857 | 858 |
858 getScaleExtents(v, min, max, logarithmic); | 859 getScaleExtents(v, min, max, logarithmic); |
859 | 860 |
860 if (logarithmic) { | 861 if (logarithmic) { |
861 LogNumericalScale().paintVertical(v, this, paint, 0, min, max); | 862 LogNumericalScale().paintVertical(v, this, paint, 0, min, max); |
880 mw)); | 881 mw)); |
881 } | 882 } |
882 } | 883 } |
883 | 884 |
884 void | 885 void |
885 NoteLayer::drawStart(View *v, QMouseEvent *e) | 886 NoteLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) |
886 { | 887 { |
887 // SVDEBUG << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; | 888 // SVDEBUG << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; |
888 | 889 |
889 if (!m_model) return; | 890 if (!m_model) return; |
890 | 891 |
904 | 905 |
905 m_editing = true; | 906 m_editing = true; |
906 } | 907 } |
907 | 908 |
908 void | 909 void |
909 NoteLayer::drawDrag(View *v, QMouseEvent *e) | 910 NoteLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) |
910 { | 911 { |
911 // SVDEBUG << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; | 912 // SVDEBUG << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; |
912 | 913 |
913 if (!m_model || !m_editing) return; | 914 if (!m_model || !m_editing) return; |
914 | 915 |
933 m_editingPoint.duration = newDuration; | 934 m_editingPoint.duration = newDuration; |
934 m_editingCommand->addPoint(m_editingPoint); | 935 m_editingCommand->addPoint(m_editingPoint); |
935 } | 936 } |
936 | 937 |
937 void | 938 void |
938 NoteLayer::drawEnd(View *, QMouseEvent *) | 939 NoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) |
939 { | 940 { |
940 // SVDEBUG << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; | 941 // SVDEBUG << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; |
941 if (!m_model || !m_editing) return; | 942 if (!m_model || !m_editing) return; |
942 finish(m_editingCommand); | 943 finish(m_editingCommand); |
943 m_editingCommand = 0; | 944 m_editingCommand = 0; |
944 m_editing = false; | 945 m_editing = false; |
945 } | 946 } |
946 | 947 |
947 void | 948 void |
948 NoteLayer::eraseStart(View *v, QMouseEvent *e) | 949 NoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) |
949 { | 950 { |
950 if (!m_model) return; | 951 if (!m_model) return; |
951 | 952 |
952 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 953 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
953 | 954 |
958 | 959 |
959 m_editing = true; | 960 m_editing = true; |
960 } | 961 } |
961 | 962 |
962 void | 963 void |
963 NoteLayer::eraseDrag(View *, QMouseEvent *) | 964 NoteLayer::eraseDrag(LayerGeometryProvider *, QMouseEvent *) |
964 { | 965 { |
965 } | 966 } |
966 | 967 |
967 void | 968 void |
968 NoteLayer::eraseEnd(View *v, QMouseEvent *e) | 969 NoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) |
969 { | 970 { |
970 if (!m_model || !m_editing) return; | 971 if (!m_model || !m_editing) return; |
971 | 972 |
972 m_editing = false; | 973 m_editing = false; |
973 | 974 |
983 m_editingCommand = 0; | 984 m_editingCommand = 0; |
984 m_editing = false; | 985 m_editing = false; |
985 } | 986 } |
986 | 987 |
987 void | 988 void |
988 NoteLayer::editStart(View *v, QMouseEvent *e) | 989 NoteLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) |
989 { | 990 { |
990 // SVDEBUG << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; | 991 // SVDEBUG << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; |
991 | 992 |
992 if (!m_model) return; | 993 if (!m_model) return; |
993 | 994 |
1006 m_dragStartX = e->x(); | 1007 m_dragStartX = e->x(); |
1007 m_dragStartY = e->y(); | 1008 m_dragStartY = e->y(); |
1008 } | 1009 } |
1009 | 1010 |
1010 void | 1011 void |
1011 NoteLayer::editDrag(View *v, QMouseEvent *e) | 1012 NoteLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) |
1012 { | 1013 { |
1013 // SVDEBUG << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; | 1014 // SVDEBUG << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; |
1014 | 1015 |
1015 if (!m_model || !m_editing) return; | 1016 if (!m_model || !m_editing) return; |
1016 | 1017 |
1035 m_editingPoint.value = float(value); | 1036 m_editingPoint.value = float(value); |
1036 m_editingCommand->addPoint(m_editingPoint); | 1037 m_editingCommand->addPoint(m_editingPoint); |
1037 } | 1038 } |
1038 | 1039 |
1039 void | 1040 void |
1040 NoteLayer::editEnd(View *, QMouseEvent *) | 1041 NoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) |
1041 { | 1042 { |
1042 // SVDEBUG << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; | 1043 // SVDEBUG << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; |
1043 if (!m_model || !m_editing) return; | 1044 if (!m_model || !m_editing) return; |
1044 | 1045 |
1045 if (m_editingCommand) { | 1046 if (m_editingCommand) { |
1063 m_editingCommand = 0; | 1064 m_editingCommand = 0; |
1064 m_editing = false; | 1065 m_editing = false; |
1065 } | 1066 } |
1066 | 1067 |
1067 bool | 1068 bool |
1068 NoteLayer::editOpen(View *v, QMouseEvent *e) | 1069 NoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) |
1069 { | 1070 { |
1070 if (!m_model) return false; | 1071 if (!m_model) return false; |
1071 | 1072 |
1072 NoteModel::Point note(0); | 1073 NoteModel::Point note(0); |
1073 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; | 1074 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; |
1191 | 1192 |
1192 finish(command); | 1193 finish(command); |
1193 } | 1194 } |
1194 | 1195 |
1195 void | 1196 void |
1196 NoteLayer::copy(View *v, Selection s, Clipboard &to) | 1197 NoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) |
1197 { | 1198 { |
1198 if (!m_model) return; | 1199 if (!m_model) return; |
1199 | 1200 |
1200 NoteModel::PointList points = | 1201 NoteModel::PointList points = |
1201 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); | 1202 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); |
1209 } | 1210 } |
1210 } | 1211 } |
1211 } | 1212 } |
1212 | 1213 |
1213 bool | 1214 bool |
1214 NoteLayer::paste(View *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */) | 1215 NoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */) |
1215 { | 1216 { |
1216 if (!m_model) return false; | 1217 if (!m_model) return false; |
1217 | 1218 |
1218 const Clipboard::PointList &points = from.getPoints(); | 1219 const Clipboard::PointList &points = from.getPoints(); |
1219 | 1220 |
1220 bool realign = false; | 1221 bool realign = false; |
1221 | 1222 |
1222 if (clipboardHasDifferentAlignment(v, from)) { | 1223 if (clipboardHasDifferentAlignment(v, from)) { |
1223 | 1224 |
1224 QMessageBox::StandardButton button = | 1225 QMessageBox::StandardButton button = |
1225 QMessageBox::question(v, tr("Re-align pasted items?"), | 1226 QMessageBox::question(v->getView(), tr("Re-align pasted items?"), |
1226 tr("The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer?"), | 1227 tr("The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer?"), |
1227 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, | 1228 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, |
1228 QMessageBox::Yes); | 1229 QMessageBox::Yes); |
1229 | 1230 |
1230 if (button == QMessageBox::Cancel) { | 1231 if (button == QMessageBox::Cancel) { |