Mercurial > hg > svgui
comparison layer/FlexiNoteLayer.cpp @ 945:bb80983c9e61 osx-retina
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 20 Apr 2015 09:18:55 +0100 |
parents | 4fe7a09be0fe 26da827e8fb5 |
children | 8bf05426d950 |
comparison
equal
deleted
inserted
replaced
920:e39d5d2734ed | 945:bb80983c9e61 |
---|---|
1133 tr("Drag Point")); | 1133 tr("Drag Point")); |
1134 } | 1134 } |
1135 | 1135 |
1136 m_editingCommand->deletePoint(m_editingPoint); | 1136 m_editingCommand->deletePoint(m_editingPoint); |
1137 | 1137 |
1138 std::cerr << "edit mode: " << m_editMode << std::endl; | 1138 std::cerr << "edit mode: " << m_editMode << " intelligent actions = " |
1139 << m_intelligentActions << std::endl; | |
1139 | 1140 |
1140 switch (m_editMode) { | 1141 switch (m_editMode) { |
1141 case LeftBoundary : { | 1142 case LeftBoundary : { |
1142 // left | 1143 // left |
1143 if (m_intelligentActions && dragFrame <= m_greatestLeftNeighbourFrame) dragFrame = m_greatestLeftNeighbourFrame + 1; | 1144 if (m_intelligentActions && dragFrame <= m_greatestLeftNeighbourFrame) dragFrame = m_greatestLeftNeighbourFrame + 1; |
1162 // right | 1163 // right |
1163 if (m_intelligentActions && dragFrame + m_originalPoint.duration >= m_smallestRightNeighbourFrame) { | 1164 if (m_intelligentActions && dragFrame + m_originalPoint.duration >= m_smallestRightNeighbourFrame) { |
1164 dragFrame = m_smallestRightNeighbourFrame - m_originalPoint.duration; | 1165 dragFrame = m_smallestRightNeighbourFrame - m_originalPoint.duration; |
1165 } | 1166 } |
1166 m_editingPoint.frame = dragFrame; | 1167 m_editingPoint.frame = dragFrame; |
1168 | |
1167 m_editingPoint.value = float(value); | 1169 m_editingPoint.value = float(value); |
1170 | |
1171 // Re-analyse region within +/- 1 semitone of the dragged value | |
1172 float cents = 0; | |
1173 int midiPitch = Pitch::getPitchForFrequency(m_editingPoint.value, ¢s); | |
1174 double lower = Pitch::getFrequencyForPitch(midiPitch - 1, cents); | |
1175 double higher = Pitch::getFrequencyForPitch(midiPitch + 1, cents); | |
1176 | |
1177 emit reAnalyseRegion(m_editingPoint.frame, | |
1178 m_editingPoint.frame + m_editingPoint.duration, | |
1179 float(lower), float(higher)); | |
1168 break; | 1180 break; |
1169 } | 1181 } |
1170 case SplitNote: // nothing | 1182 case SplitNote: // nothing |
1171 break; | 1183 break; |
1172 } | 1184 } |
1173 updateNoteValue(v, m_editingPoint); | 1185 |
1186 // updateNoteValueFromPitchCurve(v, m_editingPoint); | |
1174 m_editingCommand->addPoint(m_editingPoint); | 1187 m_editingCommand->addPoint(m_editingPoint); |
1188 | |
1175 std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl; | 1189 std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl; |
1176 | |
1177 } | 1190 } |
1178 | 1191 |
1179 void | 1192 void |
1180 FlexiNoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *e) | 1193 FlexiNoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *e) |
1181 { | 1194 { |
1185 if (!m_model || !m_editing) return; | 1198 if (!m_model || !m_editing) return; |
1186 | 1199 |
1187 if (m_editingCommand) { | 1200 if (m_editingCommand) { |
1188 | 1201 |
1189 QString newName = m_editingCommand->getName(); | 1202 QString newName = m_editingCommand->getName(); |
1203 | |
1204 if (m_editMode == DragNote) { | |
1205 //!!! command nesting is wrong? | |
1206 emit materialiseReAnalysis(); | |
1207 } | |
1208 | |
1209 m_editingCommand->deletePoint(m_editingPoint); | |
1210 updateNoteValueFromPitchCurve(v, m_editingPoint); | |
1211 m_editingCommand->addPoint(m_editingPoint); | |
1190 | 1212 |
1191 if (m_editingPoint.frame != m_originalPoint.frame) { | 1213 if (m_editingPoint.frame != m_originalPoint.frame) { |
1192 if (m_editingPoint.value != m_originalPoint.value) { | 1214 if (m_editingPoint.value != m_originalPoint.value) { |
1193 newName = tr("Edit Point"); | 1215 newName = tr("Edit Point"); |
1194 } else { | 1216 } else { |
1208 | 1230 |
1209 void | 1231 void |
1210 FlexiNoteLayer::splitStart(LayerGeometryProvider *v, QMouseEvent *e) | 1232 FlexiNoteLayer::splitStart(LayerGeometryProvider *v, QMouseEvent *e) |
1211 { | 1233 { |
1212 // GF: note splitting starts (!! remove printing soon) | 1234 // GF: note splitting starts (!! remove printing soon) |
1213 std::cerr << "splitStart" << std::endl; | 1235 std::cerr << "splitStart (n.b. editStart will be called later, if the user drags the mouse)" << std::endl; |
1214 if (!m_model) return; | 1236 if (!m_model) return; |
1215 | 1237 |
1216 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 1238 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
1217 // m_originalPoint = m_editingPoint; | 1239 // m_originalPoint = m_editingPoint; |
1218 // | 1240 // |
1225 } | 1247 } |
1226 | 1248 |
1227 m_editing = true; | 1249 m_editing = true; |
1228 m_dragStartX = e->x(); | 1250 m_dragStartX = e->x(); |
1229 m_dragStartY = e->y(); | 1251 m_dragStartY = e->y(); |
1230 | |
1231 } | 1252 } |
1232 | 1253 |
1233 void | 1254 void |
1234 FlexiNoteLayer::splitEnd(LayerGeometryProvider *v, QMouseEvent *e) | 1255 FlexiNoteLayer::splitEnd(LayerGeometryProvider *v, QMouseEvent *e) |
1235 { | 1256 { |
1278 FlexiNote newNote2(frame, note.value, | 1299 FlexiNote newNote2(frame, note.value, |
1279 note.duration - newNote1.duration, | 1300 note.duration - newNote1.duration, |
1280 note.level, note.label); | 1301 note.level, note.label); |
1281 | 1302 |
1282 if (m_intelligentActions) { | 1303 if (m_intelligentActions) { |
1283 if (updateNoteValue(v, newNote1)) { | 1304 if (updateNoteValueFromPitchCurve(v, newNote1)) { |
1284 command->addPoint(newNote1); | 1305 command->addPoint(newNote1); |
1285 } | 1306 } |
1286 if (updateNoteValue(v, newNote2)) { | 1307 if (updateNoteValueFromPitchCurve(v, newNote2)) { |
1287 command->addPoint(newNote2); | 1308 command->addPoint(newNote2); |
1288 } | 1309 } |
1289 } else { | 1310 } else { |
1290 command->addPoint(newNote1); | 1311 command->addPoint(newNote1); |
1291 command->addPoint(newNote2); | 1312 command->addPoint(newNote2); |
1337 SparseTimeValueModel * | 1358 SparseTimeValueModel * |
1338 FlexiNoteLayer::getAssociatedPitchModel(LayerGeometryProvider *v) const | 1359 FlexiNoteLayer::getAssociatedPitchModel(LayerGeometryProvider *v) const |
1339 { | 1360 { |
1340 // Better than we used to do, but still not very satisfactory | 1361 // Better than we used to do, but still not very satisfactory |
1341 | 1362 |
1342 cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl; | 1363 // cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl; |
1343 | 1364 |
1344 for (int i = 0; i < v->getView()->getLayerCount(); ++i) { | 1365 for (int i = 0; i < v->getView()->getLayerCount(); ++i) { |
1345 Layer *layer = v->getView()->getLayer(i); | 1366 Layer *layer = v->getView()->getLayer(i); |
1346 if (layer && | 1367 if (layer && |
1347 layer->getLayerPresentationName() != "candidate") { | 1368 layer->getLayerPresentationName() != "candidate") { |
1348 cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl; | 1369 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl; |
1349 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *> | 1370 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *> |
1350 (layer->getModel()); | 1371 (layer->getModel()); |
1351 cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl; | 1372 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl; |
1352 if (model && model->getScaleUnits() == "Hz") { | 1373 if (model && model->getScaleUnits() == "Hz") { |
1353 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; | 1374 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; |
1354 return model; | 1375 return model; |
1355 } | 1376 } |
1356 } | 1377 } |
1357 } | 1378 } |
1379 cerr << "FlexiNoteLayer::getAssociatedPitchModel: failed to find a model" << endl; | |
1358 return 0; | 1380 return 0; |
1359 } | 1381 } |
1360 | 1382 |
1361 void | 1383 void |
1362 FlexiNoteLayer::snapSelectedNotesToPitchTrack(LayerGeometryProvider *v, Selection s) | 1384 FlexiNoteLayer::snapSelectedNotesToPitchTrack(LayerGeometryProvider *v, Selection s) |
1386 cerr << "snapSelectedNotesToPitchTrack: making new note" << endl; | 1408 cerr << "snapSelectedNotesToPitchTrack: making new note" << endl; |
1387 FlexiNote newNote(note); | 1409 FlexiNote newNote(note); |
1388 | 1410 |
1389 command->deletePoint(note); | 1411 command->deletePoint(note); |
1390 | 1412 |
1391 if (updateNoteValue(v, newNote)) { | 1413 if (updateNoteValueFromPitchCurve(v, newNote)) { |
1392 command->addPoint(newNote); | 1414 command->addPoint(newNote); |
1393 } | 1415 } |
1394 } | 1416 } |
1395 | 1417 |
1396 finish(command); | 1418 finish(command); |
1432 command->deletePoint(*i); | 1454 command->deletePoint(*i); |
1433 | 1455 |
1434 ++i; | 1456 ++i; |
1435 } | 1457 } |
1436 | 1458 |
1437 updateNoteValue(v, newNote); | 1459 updateNoteValueFromPitchCurve(v, newNote); |
1438 command->addPoint(newNote); | 1460 command->addPoint(newNote); |
1439 finish(command); | 1461 finish(command); |
1440 } | 1462 } |
1441 | 1463 |
1442 bool | 1464 bool |
1443 FlexiNoteLayer::updateNoteValue(LayerGeometryProvider *v, FlexiNoteModel::Point ¬e) const | 1465 FlexiNoteLayer::updateNoteValueFromPitchCurve(LayerGeometryProvider *v, FlexiNoteModel::Point ¬e) const |
1444 { | 1466 { |
1445 SparseTimeValueModel *model = getAssociatedPitchModel(v); | 1467 SparseTimeValueModel *model = getAssociatedPitchModel(v); |
1446 if (!model) return false; | 1468 if (!model) return false; |
1447 | 1469 |
1448 std::cerr << model->getTypeName() << std::endl; | 1470 std::cerr << model->getTypeName() << std::endl; |
1473 if (size % 2 == 0) { | 1495 if (size % 2 == 0) { |
1474 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2; | 1496 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2; |
1475 } else { | 1497 } else { |
1476 median = pitchValues[size/2]; | 1498 median = pitchValues[size/2]; |
1477 } | 1499 } |
1500 | |
1501 std::cerr << "updateNoteValueFromPitchCurve: corrected from " << note.value << " to median " << median << std::endl; | |
1478 | 1502 |
1479 note.value = float(median); | 1503 note.value = float(median); |
1480 | 1504 |
1481 return true; | 1505 return true; |
1482 } | 1506 } |
1490 if (!getNoteToEdit(v, e->x(), e->y(), note)) { | 1514 if (!getNoteToEdit(v, e->x(), e->y(), note)) { |
1491 // v->getView()->setCursor(Qt::UpArrowCursor); | 1515 // v->getView()->setCursor(Qt::UpArrowCursor); |
1492 return; | 1516 return; |
1493 } | 1517 } |
1494 | 1518 |
1495 bool closeToLeft = false, closeToRight = false, closeToTop = false, closeToBottom = false; | 1519 bool closeToLeft = false, closeToRight = false, |
1496 getRelativeMousePosition(v, note, e->x(), e->y(), closeToLeft, closeToRight, closeToTop, closeToBottom); | 1520 closeToTop = false, closeToBottom = false; |
1497 // if (!closeToLeft) return; | 1521 getRelativeMousePosition(v, note, e->x(), e->y(), |
1498 // if (closeToTop) v->getView()->setCursor(Qt::SizeVerCursor); | 1522 closeToLeft, closeToRight, |
1499 | 1523 closeToTop, closeToBottom); |
1500 if (closeToLeft) { v->getView()->setCursor(Qt::SizeHorCursor); m_editMode = LeftBoundary; return; } | 1524 |
1501 if (closeToRight) { v->getView()->setCursor(Qt::SizeHorCursor); m_editMode = RightBoundary; return; } | 1525 if (closeToLeft) { |
1502 if (closeToTop) { v->getView()->setCursor(Qt::CrossCursor); m_editMode = DragNote; return; } | 1526 v->getView()->setCursor(Qt::SizeHorCursor); |
1503 if (closeToBottom) { v->getView()->setCursor(Qt::UpArrowCursor); m_editMode = SplitNote; return; } | 1527 m_editMode = LeftBoundary; |
1504 | 1528 cerr << "edit mode -> LeftBoundary" << endl; |
1505 v->getView()->setCursor(Qt::ArrowCursor); | 1529 } else if (closeToRight) { |
1506 | 1530 v->getView()->setCursor(Qt::SizeHorCursor); |
1507 std::cerr << "Mouse moved in edit mode over FlexiNoteLayer" << std::endl; | 1531 m_editMode = RightBoundary; |
1508 // v->getView()->setCursor(Qt::SizeHorCursor); | 1532 cerr << "edit mode -> RightBoundary" << endl; |
1509 | 1533 } else if (closeToTop) { |
1534 v->getView()->setCursor(Qt::CrossCursor); | |
1535 m_editMode = DragNote; | |
1536 cerr << "edit mode -> DragNote" << endl; | |
1537 } else if (closeToBottom) { | |
1538 v->getView()->setCursor(Qt::UpArrowCursor); | |
1539 m_editMode = SplitNote; | |
1540 cerr << "edit mode -> SplitNote" << endl; | |
1541 } else { | |
1542 v->getView()->setCursor(Qt::ArrowCursor); | |
1543 } | |
1510 } | 1544 } |
1511 | 1545 |
1512 void | 1546 void |
1513 FlexiNoteLayer::getRelativeMousePosition(LayerGeometryProvider *v, FlexiNoteModel::Point ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const | 1547 FlexiNoteLayer::getRelativeMousePosition(LayerGeometryProvider *v, FlexiNoteModel::Point ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const |
1514 { | 1548 { |