comparison layer/RegionLayer.cpp @ 550:d666f5f8b154

* Make a better job of picking the proper point to drag, edit, delete etc in note and region layers * Some work to do with region dragging, but this still needs more thought
author Chris Cannam
date Mon, 28 Sep 2009 12:29:12 +0000
parents b73f486fc2e4
children c2ba2796cbee
comparison
equal deleted inserted replaced
549:e6122e4999a3 550:d666f5f8b154
323 usePoints.clear(); 323 usePoints.clear();
324 } 324 }
325 } 325 }
326 326
327 return usePoints; 327 return usePoints;
328 }
329
330 bool
331 RegionLayer::getPointToDrag(View *v, int x, int y, RegionModel::Point &p) const
332 {
333 if (!m_model) return false;
334
335 long frame = v->getFrameForX(x);
336
337 RegionModel::PointList onPoints = m_model->getPoints(frame);
338 if (onPoints.empty()) return false;
339
340 int nearestDistance = -1;
341
342 for (RegionModel::PointList::const_iterator i = onPoints.begin();
343 i != onPoints.end(); ++i) {
344
345 int distance = getYForValue(v, (*i).value) - y;
346 if (distance < 0) distance = -distance;
347 if (nearestDistance == -1 || distance < nearestDistance) {
348 nearestDistance = distance;
349 p = *i;
350 }
351 }
352
353 return true;
328 } 354 }
329 355
330 QString 356 QString
331 RegionLayer::getFeatureDescription(View *v, QPoint &pos) const 357 RegionLayer::getFeatureDescription(View *v, QPoint &pos) const
332 { 358 {
758 int textY = 0; 784 int textY = 0;
759 if (m_plotStyle == PlotSegmentation) { 785 if (m_plotStyle == PlotSegmentation) {
760 textY = v->getTextLabelHeight(this, paint); 786 textY = v->getTextLabelHeight(this, paint);
761 } 787 }
762 788
789 int fontHeight = paint.fontMetrics().height();
790 int fontAscent = paint.fontMetrics().ascent();
791
763 for (RegionModel::PointList::const_iterator i = points.begin(); 792 for (RegionModel::PointList::const_iterator i = points.begin();
764 i != points.end(); ++i) { 793 i != points.end(); ++i) {
765 794
766 const RegionModel::Point &p(*i); 795 const RegionModel::Point &p(*i);
767 796
779 int nx = v->getXForFrame(q.frame); 808 int nx = v->getXForFrame(q.frame);
780 if (nx < ex) ex = nx; 809 if (nx < ex) ex = nx;
781 } 810 }
782 811
783 if (m_plotStyle != PlotSegmentation) { 812 if (m_plotStyle != PlotSegmentation) {
784 textY = y - paint.fontMetrics().height() 813 textY = y - fontHeight + fontAscent;
785 + paint.fontMetrics().ascent(); 814 if (textY < fontAscent + 1) {
786 if (textY < paint.fontMetrics().ascent() + 1) { 815 textY = fontAscent + 1;
787 textY = paint.fontMetrics().ascent() + 1;
788 } 816 }
789 } 817 }
790 818
791 if (m_model->getValueQuantization() != 0.0) { 819 if (m_model->getValueQuantization() != 0.0) {
792 h = y - getYForValue(v, p.value + m_model->getValueQuantization()); 820 h = y - getYForValue(v, p.value + m_model->getValueQuantization());
827 paint.drawLine(x, y+1, x + w, y+1); 855 paint.drawLine(x, y+1, x + w, y+1);
828 paint.drawLine(x, y - h/2, x, y + h/2); 856 paint.drawLine(x, y - h/2, x, y + h/2);
829 paint.drawLine(x+w, y - h/2, x + w, y + h/2); 857 paint.drawLine(x+w, y - h/2, x + w, y + h/2);
830 } 858 }
831 859
832 if (p.label != "") { 860 QString label = p.label;
833 // if (ex > x + 6 + paint.fontMetrics().width(p.label)) { 861 if (label == "") {
834 paint.drawText(x + 5, textY, p.label); 862 label = QString("[%1]").arg(p.value);
835 // } 863 }
836 } 864 v->drawVisibleText(paint, x + 5, textY, label, View::OutlinedText);
837 } 865 }
838 866
839 paint.restore(); 867 paint.restore();
840 } 868 }
841 869
850 if (frame < 0) frame = 0; 878 if (frame < 0) frame = 0;
851 frame = frame / m_model->getResolution() * m_model->getResolution(); 879 frame = frame / m_model->getResolution() * m_model->getResolution();
852 880
853 float value = getValueForY(v, e->y()); 881 float value = getValueForY(v, e->y());
854 882
855 m_editingPoint = RegionModel::Point(frame, value, 0, tr("New Region")); 883 m_editingPoint = RegionModel::Point(frame, value, 0, "");
856 m_originalPoint = m_editingPoint; 884 m_originalPoint = m_editingPoint;
857 885
858 if (m_editingCommand) finish(m_editingCommand); 886 if (m_editingCommand) finish(m_editingCommand);
859 m_editingCommand = new RegionModel::EditCommand(m_model, 887 m_editingCommand = new RegionModel::EditCommand(m_model,
860 tr("Draw Region")); 888 tr("Draw Region"));
861 m_editingCommand->addPoint(m_editingPoint); 889 m_editingCommand->addPoint(m_editingPoint);
890
891 recalcSpacing();
862 892
863 m_editing = true; 893 m_editing = true;
864 } 894 }
865 895
866 void 896 void
889 m_editingCommand->deletePoint(m_editingPoint); 919 m_editingCommand->deletePoint(m_editingPoint);
890 m_editingPoint.frame = newFrame; 920 m_editingPoint.frame = newFrame;
891 m_editingPoint.value = newValue; 921 m_editingPoint.value = newValue;
892 m_editingPoint.duration = newDuration; 922 m_editingPoint.duration = newDuration;
893 m_editingCommand->addPoint(m_editingPoint); 923 m_editingCommand->addPoint(m_editingPoint);
924
925 // recalcSpacing();
894 } 926 }
895 927
896 void 928 void
897 RegionLayer::drawEnd(View *, QMouseEvent *) 929 RegionLayer::drawEnd(View *, QMouseEvent *)
898 { 930 {
899 // std::cerr << "RegionLayer::drawEnd(" << e->x() << "," << e->y() << ")" << std::endl; 931 // std::cerr << "RegionLayer::drawEnd(" << e->x() << "," << e->y() << ")" << std::endl;
900 if (!m_model || !m_editing) return; 932 if (!m_model || !m_editing) return;
901 finish(m_editingCommand); 933 finish(m_editingCommand);
902 m_editingCommand = 0; 934 m_editingCommand = 0;
903 m_editing = false; 935 m_editing = false;
936
937 recalcSpacing();
904 } 938 }
905 939
906 void 940 void
907 RegionLayer::eraseStart(View *v, QMouseEvent *e) 941 RegionLayer::eraseStart(View *v, QMouseEvent *e)
908 { 942 {
909 if (!m_model) return; 943 if (!m_model) return;
910 944
945 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
946 /*
911 RegionModel::PointList points = getLocalPoints(v, e->x()); 947 RegionModel::PointList points = getLocalPoints(v, e->x());
912 if (points.empty()) return; 948 if (points.empty()) return;
913 949
914 m_editingPoint = *points.begin(); 950 m_editingPoint = *points.begin();
915 951 */
916 if (m_editingCommand) { 952 if (m_editingCommand) {
917 finish(m_editingCommand); 953 finish(m_editingCommand);
918 m_editingCommand = 0; 954 m_editingCommand = 0;
919 } 955 }
920 956
921 m_editing = true; 957 m_editing = true;
958 recalcSpacing();
922 } 959 }
923 960
924 void 961 void
925 RegionLayer::eraseDrag(View *v, QMouseEvent *e) 962 RegionLayer::eraseDrag(View *v, QMouseEvent *e)
926 { 963 {
930 RegionLayer::eraseEnd(View *v, QMouseEvent *e) 967 RegionLayer::eraseEnd(View *v, QMouseEvent *e)
931 { 968 {
932 if (!m_model || !m_editing) return; 969 if (!m_model || !m_editing) return;
933 970
934 m_editing = false; 971 m_editing = false;
935 972 /*
936 RegionModel::PointList points = getLocalPoints(v, e->x()); 973 RegionModel::PointList points = getLocalPoints(v, e->x());
937 if (points.empty()) return; 974 if (points.empty()) return;
938 if (points.begin()->frame != m_editingPoint.frame || 975 if (points.begin()->frame != m_editingPoint.frame ||
939 points.begin()->value != m_editingPoint.value) return; 976 points.begin()->value != m_editingPoint.value) return;
977 */
978 RegionModel::Point p(0);
979 if (!getPointToDrag(v, e->x(), e->y(), p)) return;
980 if (p.frame != m_editingPoint.frame || p.value != m_editingPoint.value) return;
940 981
941 m_editingCommand = new RegionModel::EditCommand 982 m_editingCommand = new RegionModel::EditCommand
942 (m_model, tr("Erase Region")); 983 (m_model, tr("Erase Region"));
943 984
944 m_editingCommand->deletePoint(m_editingPoint); 985 m_editingCommand->deletePoint(m_editingPoint);
945 986
946 finish(m_editingCommand); 987 finish(m_editingCommand);
947 m_editingCommand = 0; 988 m_editingCommand = 0;
948 m_editing = false; 989 m_editing = false;
990 recalcSpacing();
949 } 991 }
950 992
951 void 993 void
952 RegionLayer::editStart(View *v, QMouseEvent *e) 994 RegionLayer::editStart(View *v, QMouseEvent *e)
953 { 995 {
954 // std::cerr << "RegionLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; 996 std::cerr << "RegionLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl;
955 997
956 if (!m_model) return; 998 if (!m_model) return;
957 999
958 RegionModel::PointList points = getLocalPoints(v, e->x()); 1000 // OrderedPointList opoints = getNearbyPoints(v, e->x(), e->y());
959 if (points.empty()) return; 1001 // RegionLayer:
960 1002
961 m_editingPoint = *points.begin(); 1003 // RegionModel::PointList points = getLocalPoints(v, e->x());
1004 // if (points.empty()) return;
1005
1006 // m_editingPoint = *points.begin();
1007
1008 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) {
1009 return;
1010 }
1011
962 m_originalPoint = m_editingPoint; 1012 m_originalPoint = m_editingPoint;
963 1013
964 if (m_editingCommand) { 1014 if (m_editingCommand) {
965 finish(m_editingCommand); 1015 finish(m_editingCommand);
966 m_editingCommand = 0; 1016 m_editingCommand = 0;
967 } 1017 }
968 1018
969 m_editing = true; 1019 m_editing = true;
1020 m_dragYOrigin = e->y();
1021 m_dragYRebase = e->y();
1022 recalcSpacing();
970 } 1023 }
971 1024
972 void 1025 void
973 RegionLayer::editDrag(View *v, QMouseEvent *e) 1026 RegionLayer::editDrag(View *v, QMouseEvent *e)
974 { 1027 {
975 // std::cerr << "RegionLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; 1028 std::cerr << "RegionLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl;
976 1029
977 if (!m_model || !m_editing) return; 1030 if (!m_model || !m_editing) return;
978 1031
979 long frame = v->getFrameForX(e->x()); 1032 long frame = v->getFrameForX(e->x());
980 if (frame < 0) frame = 0; 1033 if (frame < 0) frame = 0;
981 frame = frame / m_model->getResolution() * m_model->getResolution(); 1034 frame = frame / m_model->getResolution() * m_model->getResolution();
982 1035
983 float value = getValueForY(v, e->y()); 1036 int activeY = e->y() + (m_dragYRebase - m_dragYOrigin);
1037 float value = getValueForY(v, activeY);
984 1038
985 if (!m_editingCommand) { 1039 if (!m_editingCommand) {
986 m_editingCommand = new RegionModel::EditCommand(m_model, 1040 m_editingCommand = new RegionModel::EditCommand(m_model,
987 tr("Drag Region")); 1041 tr("Drag Region"));
1042 }
1043
1044 if (m_verticalScale == EqualSpaced) {
1045 if (getYForValue(v, value) != getYForValue(v, m_editingPoint.value)) {
1046 m_dragYRebase = e->y();
1047 }
988 } 1048 }
989 1049
990 m_editingCommand->deletePoint(m_editingPoint); 1050 m_editingCommand->deletePoint(m_editingPoint);
991 m_editingPoint.frame = frame; 1051 m_editingPoint.frame = frame;
992 m_editingPoint.value = value; 1052 m_editingPoint.value = value;
993 m_editingCommand->addPoint(m_editingPoint); 1053 m_editingCommand->addPoint(m_editingPoint);
994 } 1054 recalcSpacing();
995 1055 }
996 void 1056
997 RegionLayer::editEnd(View *, QMouseEvent *) 1057 void
998 { 1058 RegionLayer::editEnd(View *, QMouseEvent *e)
999 // std::cerr << "RegionLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; 1059 {
1060 std::cerr << "RegionLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl;
1000 if (!m_model || !m_editing) return; 1061 if (!m_model || !m_editing) return;
1001 1062
1002 if (m_editingCommand) { 1063 if (m_editingCommand) {
1003 1064
1004 QString newName = m_editingCommand->getName(); 1065 QString newName = m_editingCommand->getName();
1017 finish(m_editingCommand); 1078 finish(m_editingCommand);
1018 } 1079 }
1019 1080
1020 m_editingCommand = 0; 1081 m_editingCommand = 0;
1021 m_editing = false; 1082 m_editing = false;
1083 recalcSpacing();
1022 } 1084 }
1023 1085
1024 bool 1086 bool
1025 RegionLayer::editOpen(View *v, QMouseEvent *e) 1087 RegionLayer::editOpen(View *v, QMouseEvent *e)
1026 { 1088 {
1027 if (!m_model) return false; 1089 if (!m_model) return false;
1028 1090 /*
1029 RegionModel::PointList points = getLocalPoints(v, e->x()); 1091 RegionModel::PointList points = getLocalPoints(v, e->x());
1030 if (points.empty()) return false; 1092 if (points.empty()) return false;
1031 1093 */
1032 RegionModel::Point region = *points.begin(); 1094
1095 RegionModel::Point region(0);
1096 if (!getPointToDrag(v, e->x(), e->y(), region)) return false;
1097
1098 // RegionModel::Point region = *points.begin();
1033 1099
1034 ItemEditDialog *dialog = new ItemEditDialog 1100 ItemEditDialog *dialog = new ItemEditDialog
1035 (m_model->getSampleRate(), 1101 (m_model->getSampleRate(),
1036 ItemEditDialog::ShowTime | 1102 ItemEditDialog::ShowTime |
1037 ItemEditDialog::ShowDuration | 1103 ItemEditDialog::ShowDuration |
1058 command->addPoint(newRegion); 1124 command->addPoint(newRegion);
1059 finish(command); 1125 finish(command);
1060 } 1126 }
1061 1127
1062 delete dialog; 1128 delete dialog;
1129 recalcSpacing();
1063 return true; 1130 return true;
1064 } 1131 }
1065 1132
1066 void 1133 void
1067 RegionLayer::moveSelection(Selection s, size_t newStartFrame) 1134 RegionLayer::moveSelection(Selection s, size_t newStartFrame)
1084 command->addPoint(newPoint); 1151 command->addPoint(newPoint);
1085 } 1152 }
1086 } 1153 }
1087 1154
1088 finish(command); 1155 finish(command);
1156 recalcSpacing();
1089 } 1157 }
1090 1158
1091 void 1159 void
1092 RegionLayer::resizeSelection(Selection s, Selection newSize) 1160 RegionLayer::resizeSelection(Selection s, Selection newSize)
1093 { 1161 {
1123 command->addPoint(newPoint); 1191 command->addPoint(newPoint);
1124 } 1192 }
1125 } 1193 }
1126 1194
1127 finish(command); 1195 finish(command);
1196 recalcSpacing();
1128 } 1197 }
1129 1198
1130 void 1199 void
1131 RegionLayer::deleteSelection(Selection s) 1200 RegionLayer::deleteSelection(Selection s)
1132 { 1201 {
1145 command->deletePoint(*i); 1214 command->deletePoint(*i);
1146 } 1215 }
1147 } 1216 }
1148 1217
1149 finish(command); 1218 finish(command);
1219 recalcSpacing();
1150 } 1220 }
1151 1221
1152 void 1222 void
1153 RegionLayer::copy(View *v, Selection s, Clipboard &to) 1223 RegionLayer::copy(View *v, Selection s, Clipboard &to)
1154 { 1224 {
1242 1312
1243 command->addPoint(newPoint); 1313 command->addPoint(newPoint);
1244 } 1314 }
1245 1315
1246 finish(command); 1316 finish(command);
1317 recalcSpacing();
1247 return true; 1318 return true;
1248 } 1319 }
1249 1320
1250 void 1321 void
1251 RegionLayer::toXml(QTextStream &stream, 1322 RegionLayer::toXml(QTextStream &stream,