comparison layer/NoteLayer.cpp @ 551:c2ba2796cbee sv-v1.7

* Big improvements to editing behaviour in note and region models
author Chris Cannam
date Fri, 02 Oct 2009 13:56:10 +0000
parents d666f5f8b154
children f4960f8ce798
comparison
equal deleted inserted replaced
550:d666f5f8b154 551:c2ba2796cbee
34 #include <QTextStream> 34 #include <QTextStream>
35 #include <QMessageBox> 35 #include <QMessageBox>
36 36
37 #include <iostream> 37 #include <iostream>
38 #include <cmath> 38 #include <cmath>
39 #include <utility>
39 40
40 NoteLayer::NoteLayer() : 41 NoteLayer::NoteLayer() :
41 SingleColourLayer(), 42 SingleColourLayer(),
42 m_model(0), 43 m_model(0),
43 m_editing(false), 44 m_editing(false),
412 long frame = v->getFrameForX(x); 413 long frame = v->getFrameForX(x);
413 414
414 NoteModel::PointList onPoints = m_model->getPoints(frame); 415 NoteModel::PointList onPoints = m_model->getPoints(frame);
415 if (onPoints.empty()) return false; 416 if (onPoints.empty()) return false;
416 417
417 std::cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << std::endl; 418 // std::cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << std::endl;
418 419
419 int nearestDistance = -1; 420 int nearestDistance = -1;
420 421
421 for (NoteModel::PointList::const_iterator i = onPoints.begin(); 422 for (NoteModel::PointList::const_iterator i = onPoints.begin();
422 i != onPoints.end(); ++i) { 423 i != onPoints.end(); ++i) {
729 float min = m_model->getValueMinimum(); 730 float min = m_model->getValueMinimum();
730 float max = m_model->getValueMaximum(); 731 float max = m_model->getValueMaximum();
731 if (max == min) max = min + 1.0; 732 if (max == min) max = min + 1.0;
732 733
733 QPoint localPos; 734 QPoint localPos;
734 long illuminateFrame = -1; 735 NoteModel::Point illuminatePoint(0);
736 bool shouldIlluminate = false;
735 737
736 if (v->shouldIlluminateLocalFeatures(this, localPos)) { 738 if (v->shouldIlluminateLocalFeatures(this, localPos)) {
737 NoteModel::PointList localPoints = 739 shouldIlluminate = getPointToDrag(v, localPos.x(), localPos.y(),
738 getLocalPoints(v, localPos.x()); 740 illuminatePoint);
739 if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame;
740 } 741 }
741 742
742 paint.save(); 743 paint.save();
743 paint.setRenderHint(QPainter::Antialiasing, false); 744 paint.setRenderHint(QPainter::Antialiasing, false);
744 745
759 760
760 if (w < 1) w = 1; 761 if (w < 1) w = 1;
761 paint.setPen(getBaseQColor()); 762 paint.setPen(getBaseQColor());
762 paint.setBrush(brushColour); 763 paint.setBrush(brushColour);
763 764
764 if (illuminateFrame == p.frame) { 765 if (shouldIlluminate &&
765 if (localPos.y() >= y - h && localPos.y() < y) { 766 // "illuminatePoint == p"
766 paint.setPen(v->getForeground()); 767 !NoteModel::Point::Comparator()(illuminatePoint, p) &&
767 paint.setBrush(v->getForeground()); 768 !NoteModel::Point::Comparator()(p, illuminatePoint)) {
768 } 769
770 paint.setPen(v->getForeground());
771 paint.setBrush(v->getForeground());
772
773 QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits());
774 v->drawVisibleText(paint,
775 x - paint.fontMetrics().width(vlabel) - 2,
776 y + paint.fontMetrics().height()/2
777 - paint.fontMetrics().descent(),
778 vlabel, View::OutlinedText);
779
780 QString hlabel = RealTime::frame2RealTime
781 (p.frame, m_model->getSampleRate()).toText(true).c_str();
782 v->drawVisibleText(paint,
783 x,
784 y - h/2 - paint.fontMetrics().descent() - 2,
785 hlabel, View::OutlinedText);
769 } 786 }
770 787
771 paint.drawRect(x, y - h/2, w, h); 788 paint.drawRect(x, y - h/2, w, h);
772
773 /// if (p.label != "") {
774 /// paint.drawText(x + 5, y - paint.fontMetrics().height() + paint.fontMetrics().ascent(), p.label);
775 /// }
776 } 789 }
777 790
778 paint.restore(); 791 paint.restore();
779 } 792 }
780 793
844 void 857 void
845 NoteLayer::eraseStart(View *v, QMouseEvent *e) 858 NoteLayer::eraseStart(View *v, QMouseEvent *e)
846 { 859 {
847 if (!m_model) return; 860 if (!m_model) return;
848 861
849 // NoteModel::PointList points = getLocalPoints(v, e->x());
850 // if (points.empty()) return;
851
852 // m_editingPoint = *points.begin();
853
854 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; 862 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
855 863
856 if (m_editingCommand) { 864 if (m_editingCommand) {
857 finish(m_editingCommand); 865 finish(m_editingCommand);
858 m_editingCommand = 0; 866 m_editingCommand = 0;
871 { 879 {
872 if (!m_model || !m_editing) return; 880 if (!m_model || !m_editing) return;
873 881
874 m_editing = false; 882 m_editing = false;
875 883
876 /*
877 NoteModel::PointList points = getLocalPoints(v, e->x());
878 if (points.empty()) return;
879 if (points.begin()->frame != m_editingPoint.frame ||
880 points.begin()->value != m_editingPoint.value) return;
881 */
882
883 NoteModel::Point p(0); 884 NoteModel::Point p(0);
884 if (!getPointToDrag(v, e->x(), e->y(), p)) return; 885 if (!getPointToDrag(v, e->x(), e->y(), p)) return;
885 if (p.frame != m_editingPoint.frame || p.value != m_editingPoint.value) return; 886 if (p.frame != m_editingPoint.frame || p.value != m_editingPoint.value) return;
886 887
887 m_editingCommand = new NoteModel::EditCommand(m_model, tr("Erase Point")); 888 m_editingCommand = new NoteModel::EditCommand(m_model, tr("Erase Point"));
898 { 899 {
899 // std::cerr << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; 900 // std::cerr << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl;
900 901
901 if (!m_model) return; 902 if (!m_model) return;
902 903
903 /*
904 NoteModel::PointList points = getLocalPoints(v, e->x());
905 if (points.empty()) return;
906
907 m_editingPoint = *points.begin();
908 */
909
910 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; 904 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
911 m_originalPoint = m_editingPoint; 905 m_originalPoint = m_editingPoint;
906
907 m_dragPointX = v->getXForFrame(m_editingPoint.frame);
908 m_dragPointY = getYForValue(v, m_editingPoint.value);
912 909
913 if (m_editingCommand) { 910 if (m_editingCommand) {
914 finish(m_editingCommand); 911 finish(m_editingCommand);
915 m_editingCommand = 0; 912 m_editingCommand = 0;
916 } 913 }
917 914
918 m_editing = true; 915 m_editing = true;
916 m_dragStartX = e->x();
917 m_dragStartY = e->y();
919 } 918 }
920 919
921 void 920 void
922 NoteLayer::editDrag(View *v, QMouseEvent *e) 921 NoteLayer::editDrag(View *v, QMouseEvent *e)
923 { 922 {
924 // std::cerr << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; 923 // std::cerr << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl;
925 924
926 if (!m_model || !m_editing) return; 925 if (!m_model || !m_editing) return;
927 926
928 long frame = v->getFrameForX(e->x()); 927 int xdist = e->x() - m_dragStartX;
928 int ydist = e->y() - m_dragStartY;
929 int newx = m_dragPointX + xdist;
930 int newy = m_dragPointY + ydist;
931
932 long frame = v->getFrameForX(newx);
929 if (frame < 0) frame = 0; 933 if (frame < 0) frame = 0;
930 frame = frame / m_model->getResolution() * m_model->getResolution(); 934 frame = frame / m_model->getResolution() * m_model->getResolution();
931 935
932 float value = getValueForY(v, e->y()); 936 float value = getValueForY(v, newy);
933 937
934 if (!m_editingCommand) { 938 if (!m_editingCommand) {
935 m_editingCommand = new NoteModel::EditCommand(m_model, 939 m_editingCommand = new NoteModel::EditCommand(m_model,
936 tr("Drag Point")); 940 tr("Drag Point"));
937 } 941 }
972 976
973 bool 977 bool
974 NoteLayer::editOpen(View *v, QMouseEvent *e) 978 NoteLayer::editOpen(View *v, QMouseEvent *e)
975 { 979 {
976 if (!m_model) return false; 980 if (!m_model) return false;
977 /*
978 NoteModel::PointList points = getLocalPoints(v, e->x());
979 if (points.empty()) return false;
980 */
981 981
982 NoteModel::Point note(0); 982 NoteModel::Point note(0);
983 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; 983 if (!getPointToDrag(v, e->x(), e->y(), note)) return false;
984 984
985 // NoteModel::Point note = *points.begin(); 985 // NoteModel::Point note = *points.begin();