Mercurial > hg > svgui
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(); |