Mercurial > hg > svgui
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, |