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 &note, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const 1176 FlexiNoteLayer::getRelativeMousePosition(View *v, FlexiNoteModel::Point &note, 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