Mercurial > hg > svgui
comparison layer/FlexiNoteLayer.cpp @ 651:76c5dfe333ee tonioni
introduced horizongal note editing constraints; debugged note edit
author | matthiasm |
---|---|
date | Mon, 17 Jun 2013 18:00:24 +0100 |
parents | 2ad082c5a090 |
children | 35c3323a78a2 |
comparison
equal
deleted
inserted
replaced
649:2ad082c5a090 | 651:76c5dfe333ee |
---|---|
800 | 800 |
801 if (w < 1) w = 1; | 801 if (w < 1) w = 1; |
802 paint.setPen(getBaseQColor()); | 802 paint.setPen(getBaseQColor()); |
803 paint.setBrush(brushColour); | 803 paint.setBrush(brushColour); |
804 | 804 |
805 if (shouldIlluminate && | 805 // if (shouldIlluminate && |
806 // "illuminatePoint == p" | 806 // // "illuminatePoint == p" |
807 !FlexiNoteModel::Point::Comparator()(illuminatePoint, p) && | 807 // !FlexiNoteModel::Point::Comparator()(illuminatePoint, p) && |
808 !FlexiNoteModel::Point::Comparator()(p, illuminatePoint)) { | 808 // !FlexiNoteModel::Point::Comparator()(p, illuminatePoint)) { |
809 | 809 // |
810 paint.setPen(v->getForeground()); | 810 // paint.setPen(v->getForeground()); |
811 paint.setBrush(v->getForeground()); | 811 // paint.setBrush(v->getForeground()); |
812 | 812 // |
813 QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits()); | 813 // QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits()); |
814 v->drawVisibleText(paint, | 814 // v->drawVisibleText(paint, |
815 x - paint.fontMetrics().width(vlabel) - 2, | 815 // x - paint.fontMetrics().width(vlabel) - 2, |
816 y + paint.fontMetrics().height()/2 | 816 // y + paint.fontMetrics().height()/2 |
817 - paint.fontMetrics().descent(), | 817 // - paint.fontMetrics().descent(), |
818 vlabel, View::OutlinedText); | 818 // vlabel, View::OutlinedText); |
819 | 819 // |
820 QString hlabel = RealTime::frame2RealTime | 820 // QString hlabel = RealTime::frame2RealTime |
821 (p.frame, m_model->getSampleRate()).toText(true).c_str(); | 821 // (p.frame, m_model->getSampleRate()).toText(true).c_str(); |
822 v->drawVisibleText(paint, | 822 // v->drawVisibleText(paint, |
823 x, | 823 // x, |
824 y - h/2 - paint.fontMetrics().descent() - 2, | 824 // y - h/2 - paint.fontMetrics().descent() - 2, |
825 hlabel, View::OutlinedText); | 825 // hlabel, View::OutlinedText); |
826 } | 826 // } |
827 | 827 |
828 paint.drawRect(x, y - h/2, w, h); | 828 paint.drawRect(x, y - h/2, w, h); |
829 } | 829 } |
830 | 830 |
831 paint.restore(); | 831 paint.restore(); |
941 std::cerr << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; | 941 std::cerr << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; |
942 | 942 |
943 if (!m_model) return; | 943 if (!m_model) return; |
944 | 944 |
945 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 945 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
946 m_originalPoint = m_editingPoint; | 946 m_originalPoint = FlexiNote(m_editingPoint); |
947 | 947 |
948 if (m_editMode == rightBoundary) { | 948 if (m_editMode == RightBoundary) { |
949 m_dragPointX = v->getXForFrame(m_editingPoint.frame + m_editingPoint.duration); | 949 m_dragPointX = v->getXForFrame(m_editingPoint.frame + m_editingPoint.duration); |
950 } else { | 950 } else { |
951 m_dragPointX = v->getXForFrame(m_editingPoint.frame); | 951 m_dragPointX = v->getXForFrame(m_editingPoint.frame); |
952 } | 952 } |
953 m_dragPointY = getYForValue(v, m_editingPoint.value); | 953 m_dragPointY = getYForValue(v, m_editingPoint.value); |
954 | 954 |
958 } | 958 } |
959 | 959 |
960 m_editing = true; | 960 m_editing = true; |
961 m_dragStartX = e->x(); | 961 m_dragStartX = e->x(); |
962 m_dragStartY = e->y(); | 962 m_dragStartY = e->y(); |
963 | |
964 long onset = m_originalPoint.frame; | |
965 long offset = m_originalPoint.frame + m_originalPoint.duration - 1; | |
966 | |
967 m_greatestLeftNeighbourFrame = -1; | |
968 m_smallestRightNeighbourFrame = std::numeric_limits<long>::max(); | |
969 | |
970 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin(); | |
971 i != m_model->getPoints().end(); ++i) { | |
972 FlexiNote currentNote = *i; | |
973 | |
974 // left boundary | |
975 if (currentNote.frame + currentNote.duration - 1 < onset) { | |
976 m_greatestLeftNeighbourFrame = currentNote.frame + currentNote.duration - 1; | |
977 } | |
978 | |
979 // right boundary | |
980 if (currentNote.frame > offset) { | |
981 m_smallestRightNeighbourFrame = currentNote.frame; | |
982 break; | |
983 } | |
984 } | |
985 std::cerr << "note frame: " << onset << ", left boundary: " << m_greatestLeftNeighbourFrame << ", right boundary: " << m_smallestRightNeighbourFrame << std::endl; | |
963 } | 986 } |
964 | 987 |
965 void | 988 void |
966 FlexiNoteLayer::editDrag(View *v, QMouseEvent *e) | 989 FlexiNoteLayer::editDrag(View *v, QMouseEvent *e) |
967 { | 990 { |
976 int newy = m_dragPointY + ydist; | 999 int newy = m_dragPointY + ydist; |
977 | 1000 |
978 long frame = v->getFrameForX(newx); | 1001 long frame = v->getFrameForX(newx); |
979 if (frame < 0) frame = 0; | 1002 if (frame < 0) frame = 0; |
980 frame = frame / m_model->getResolution() * m_model->getResolution(); | 1003 frame = frame / m_model->getResolution() * m_model->getResolution(); |
981 | 1004 |
982 float value = getValueForY(v, newy); | 1005 float value = getValueForY(v, newy); |
983 | 1006 |
984 if (!m_editingCommand) { | 1007 if (!m_editingCommand) { |
985 m_editingCommand = new FlexiNoteModel::EditCommand(m_model, | 1008 m_editingCommand = new FlexiNoteModel::EditCommand(m_model, |
986 tr("Drag Point")); | 1009 tr("Drag Point")); |
987 } | 1010 } |
988 | 1011 |
989 m_editingCommand->deletePoint(m_editingPoint); | 1012 m_editingCommand->deletePoint(m_editingPoint); |
990 if (m_editMode == leftBoundary) | 1013 |
991 m_editingPoint.duration = m_editingPoint.duration + (m_editingPoint.frame - frame); // GF: left boundary change | 1014 std::cerr << "edit mode: " << m_editMode << std::endl; |
992 if (m_editMode == rightBoundary) { | 1015 switch (m_editMode) { |
993 m_editingPoint.duration = frame - m_editingPoint.frame; // GF: right boundary change | 1016 case LeftBoundary : { |
994 } else { | 1017 if ((frame > m_greatestLeftNeighbourFrame) |
995 m_editingPoint.frame = frame; | 1018 && (frame < m_originalPoint.frame + m_originalPoint.duration - 1) |
996 } | 1019 && (frame < m_smallestRightNeighbourFrame)) { |
997 m_editingPoint.value = value; | 1020 m_editingPoint.duration = m_editingPoint.frame + m_editingPoint.duration - frame + 1; |
1021 m_editingPoint.frame = frame; | |
1022 } | |
1023 break; | |
1024 } | |
1025 case RightBoundary : { | |
1026 long tempDuration = frame - m_originalPoint.frame; | |
1027 if (tempDuration > 0 && m_originalPoint.frame + tempDuration - 1 < m_smallestRightNeighbourFrame) { | |
1028 m_editingPoint.duration = tempDuration; | |
1029 } | |
1030 break; | |
1031 } | |
1032 case DragNote : { | |
1033 if (frame <= m_smallestRightNeighbourFrame - m_editingPoint.duration | |
1034 && frame > m_greatestLeftNeighbourFrame) { | |
1035 m_editingPoint.frame = frame; // only move if it doesn't overlap with right note or left note | |
1036 } | |
1037 m_editingPoint.value = value; | |
1038 break; | |
1039 } | |
1040 } | |
1041 | |
998 m_editingCommand->addPoint(m_editingPoint); | 1042 m_editingCommand->addPoint(m_editingPoint); |
999 std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl; | 1043 std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl; |
1000 | 1044 |
1001 } | 1045 } |
1002 | 1046 |
1023 } | 1067 } |
1024 | 1068 |
1025 m_editingCommand->setName(newName); | 1069 m_editingCommand->setName(newName); |
1026 finish(m_editingCommand); | 1070 finish(m_editingCommand); |
1027 } | 1071 } |
1072 | |
1073 setVerticalRangeToNoteRange(); | |
1028 | 1074 |
1029 m_editingCommand = 0; | 1075 m_editingCommand = 0; |
1030 m_editing = false; | 1076 m_editing = false; |
1031 } | 1077 } |
1032 | 1078 |
1057 void | 1103 void |
1058 FlexiNoteLayer::splitEnd(View *v, QMouseEvent *e) | 1104 FlexiNoteLayer::splitEnd(View *v, QMouseEvent *e) |
1059 { | 1105 { |
1060 // GF: note splitting ends. (!! remove printing soon) | 1106 // GF: note splitting ends. (!! remove printing soon) |
1061 std::cerr << "splitEnd" << std::endl; | 1107 std::cerr << "splitEnd" << std::endl; |
1062 if (!m_model || !m_editing || m_editMode != splitNote) return; | 1108 if (!m_model || !m_editing || m_editMode != SplitNote) return; |
1063 | 1109 |
1064 int xdist = e->x() - m_dragStartX; | 1110 int xdist = e->x() - m_dragStartX; |
1065 int ydist = e->y() - m_dragStartY; | 1111 int ydist = e->y() - m_dragStartY; |
1066 if (xdist != 0 || ydist != 0) { | 1112 if (xdist != 0 || ydist != 0) { |
1067 std::cerr << "mouse moved" << std::endl; | 1113 std::cerr << "mouse moved" << std::endl; |
1112 bool closeToLeft = false, closeToRight = false, closeToTop = false, closeToBottom = false; | 1158 bool closeToLeft = false, closeToRight = false, closeToTop = false, closeToBottom = false; |
1113 getRelativeMousePosition(v, note, e->x(), e->y(), closeToLeft, closeToRight, closeToTop, closeToBottom); | 1159 getRelativeMousePosition(v, note, e->x(), e->y(), closeToLeft, closeToRight, closeToTop, closeToBottom); |
1114 // if (!closeToLeft) return; | 1160 // if (!closeToLeft) return; |
1115 // if (closeToTop) v->setCursor(Qt::SizeVerCursor); | 1161 // if (closeToTop) v->setCursor(Qt::SizeVerCursor); |
1116 | 1162 |
1117 if (closeToLeft) { v->setCursor(Qt::SizeHorCursor); m_editMode = leftBoundary; return; } | 1163 if (closeToLeft) { v->setCursor(Qt::SizeHorCursor); m_editMode = LeftBoundary; return; } |
1118 if (closeToRight) { v->setCursor(Qt::SizeHorCursor); m_editMode = rightBoundary; return; } | 1164 if (closeToRight) { v->setCursor(Qt::SizeHorCursor); m_editMode = RightBoundary; return; } |
1119 if (closeToTop) { v->setCursor(Qt::CrossCursor); m_editMode = dragNote; return; } | 1165 if (closeToTop) { v->setCursor(Qt::CrossCursor); m_editMode = DragNote; return; } |
1120 if (closeToBottom) { v->setCursor(Qt::UpArrowCursor); m_editMode = splitNote; return; } | 1166 if (closeToBottom) { v->setCursor(Qt::UpArrowCursor); m_editMode = SplitNote; return; } |
1121 | 1167 |
1122 v->setCursor(Qt::ArrowCursor); | 1168 v->setCursor(Qt::ArrowCursor); |
1123 | 1169 |
1124 // std::cerr << "Mouse moved in edit mode over FlexiNoteLayer" << std::endl; | 1170 // std::cerr << "Mouse moved in edit mode over FlexiNoteLayer" << std::endl; |
1125 // v->setCursor(Qt::SizeHorCursor); | 1171 // v->setCursor(Qt::SizeHorCursor); |
1130 FlexiNoteLayer::getRelativeMousePosition(View *v, FlexiNoteModel::Point ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const | 1176 FlexiNoteLayer::getRelativeMousePosition(View *v, FlexiNoteModel::Point ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const |
1131 { | 1177 { |
1132 // GF: TODO: consoloidate the tolerance values | 1178 // GF: TODO: consoloidate the tolerance values |
1133 if (!m_model) return; | 1179 if (!m_model) return; |
1134 | 1180 |
1135 int ctol = 2; | 1181 int ctol = 0; |
1136 int noteStartX = v->getXForFrame(note.frame); | 1182 int noteStartX = v->getXForFrame(note.frame); |
1137 int noteEndX = v->getXForFrame(note.frame + note.duration); | 1183 int noteEndX = v->getXForFrame(note.frame + note.duration); |
1138 int noteValueY = getYForValue(v,note.value); | 1184 int noteValueY = getYForValue(v,note.value); |
1139 int noteStartY = noteValueY - (NOTE_HEIGHT / 2); | 1185 int noteStartY = noteValueY - (NOTE_HEIGHT / 2); |
1140 int noteEndY = noteValueY + (NOTE_HEIGHT / 2); | 1186 int noteEndY = noteValueY + (NOTE_HEIGHT / 2); |
1142 bool closeToNote = false; | 1188 bool closeToNote = false; |
1143 | 1189 |
1144 if (y >= noteStartY-ctol && y <= noteEndY+ctol && x >= noteStartX-ctol && x <= noteEndX+ctol) closeToNote = true; | 1190 if (y >= noteStartY-ctol && y <= noteEndY+ctol && x >= noteStartX-ctol && x <= noteEndX+ctol) closeToNote = true; |
1145 if (!closeToNote) return; | 1191 if (!closeToNote) return; |
1146 | 1192 |
1147 int tol = 4; | 1193 int tol = NOTE_HEIGHT / 2; |
1148 | 1194 |
1149 if (x >= noteStartX - tol && x <= noteStartX + tol) closeToLeft = true; | 1195 if (x >= noteStartX - tol && x <= noteStartX + tol) closeToLeft = true; |
1150 if (x >= noteEndX - tol && x <= noteEndX + tol) closeToRight = true; | 1196 if (x >= noteEndX - tol && x <= noteEndX + tol) closeToRight = true; |
1151 if (y >= noteStartY - tol && y <= noteStartY + tol) closeToTop = true; | 1197 if (y >= noteStartY - tol && y <= noteStartY + tol) closeToTop = true; |
1152 if (y >= noteEndY - tol && y <= noteEndY + tol) closeToBottom = true; | 1198 if (y >= noteEndY - tol && y <= noteEndY + tol) closeToBottom = true; |
1446 float min = attributes.value("scaleMinimum").toFloat(&ok); | 1492 float min = attributes.value("scaleMinimum").toFloat(&ok); |
1447 float max = attributes.value("scaleMaximum").toFloat(&alsoOk); | 1493 float max = attributes.value("scaleMaximum").toFloat(&alsoOk); |
1448 if (ok && alsoOk) setDisplayExtents(min, max); | 1494 if (ok && alsoOk) setDisplayExtents(min, max); |
1449 } | 1495 } |
1450 | 1496 |
1451 | 1497 void |
1498 FlexiNoteLayer::setVerticalRangeToNoteRange() | |
1499 { | |
1500 float minf = std::numeric_limits<float>::max();; | |
1501 float maxf = 0; | |
1502 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin(); | |
1503 i != m_model->getPoints().end(); ++i) { | |
1504 FlexiNote note = *i; | |
1505 if (note.value < minf) minf = note.value; | |
1506 else if (note.value > maxf) maxf = note.value; | |
1507 std::cerr << "min frequency:" << minf << ", max frequency: " << maxf << std::endl; | |
1508 } | |
1509 | |
1510 if (this) { | |
1511 setDisplayExtents(minf,maxf); | |
1512 } | |
1513 } | |
1514 | |
1515 |