Mercurial > hg > svgui
comparison layer/FlexiNoteLayer.cpp @ 1486:ac0a8addabcf
Merge from branch by-id
author | Chris Cannam |
---|---|
date | Wed, 17 Jul 2019 14:25:16 +0100 |
parents | e540aa5d89cd |
children | 0fa49a6ce64f |
comparison
equal
deleted
inserted
replaced
1468:de41a11cabc2 | 1486:ac0a8addabcf |
---|---|
51 | 51 |
52 #define NOTE_HEIGHT 16 | 52 #define NOTE_HEIGHT 16 |
53 | 53 |
54 FlexiNoteLayer::FlexiNoteLayer() : | 54 FlexiNoteLayer::FlexiNoteLayer() : |
55 SingleColourLayer(), | 55 SingleColourLayer(), |
56 m_model(nullptr), | |
57 m_editing(false), | 56 m_editing(false), |
58 m_intelligentActions(true), | 57 m_intelligentActions(true), |
59 m_dragPointX(0), | 58 m_dragPointX(0), |
60 m_dragPointY(0), | 59 m_dragPointY(0), |
61 m_dragStartX(0), | 60 m_dragStartX(0), |
71 m_scaleMaximum(77) | 70 m_scaleMaximum(77) |
72 { | 71 { |
73 } | 72 } |
74 | 73 |
75 void | 74 void |
76 FlexiNoteLayer::setModel(NoteModel *model) | 75 FlexiNoteLayer::setModel(ModelId modelId) |
77 { | 76 { |
78 if (m_model == model) return; | 77 auto newModel = ModelById::getAs<NoteModel>(modelId); |
79 m_model = model; | 78 |
80 | 79 if (!modelId.isNone() && !newModel) { |
81 connectSignals(m_model); | 80 throw std::logic_error("Not a NoteModel"); |
82 | 81 } |
83 // m_scaleMinimum = 0; | 82 |
84 // m_scaleMaximum = 0; | 83 if (m_model == modelId) return; |
84 m_model = modelId; | |
85 | |
86 if (newModel) { | |
87 connectSignals(m_model); | |
88 } | |
85 | 89 |
86 emit modelReplaced(); | 90 emit modelReplaced(); |
87 } | 91 } |
88 | 92 |
89 Layer::PropertyList | 93 Layer::PropertyList |
121 } | 125 } |
122 | 126 |
123 QString | 127 QString |
124 FlexiNoteLayer::getScaleUnits() const | 128 FlexiNoteLayer::getScaleUnits() const |
125 { | 129 { |
126 if (m_model) return m_model->getScaleUnits(); | 130 auto model = ModelById::getAs<NoteModel>(m_model); |
131 if (model) return model->getScaleUnits(); | |
127 else return ""; | 132 else return ""; |
128 } | 133 } |
129 | 134 |
130 int | 135 int |
131 FlexiNoteLayer::getPropertyRangeAndValue(const PropertyName &name, | 136 FlexiNoteLayer::getPropertyRangeAndValue(const PropertyName &name, |
142 val = int(m_verticalScale); | 147 val = int(m_verticalScale); |
143 | 148 |
144 } else if (name == "Scale Units") { | 149 } else if (name == "Scale Units") { |
145 | 150 |
146 if (deflt) *deflt = 0; | 151 if (deflt) *deflt = 0; |
147 if (m_model) { | 152 auto model = ModelById::getAs<NoteModel>(m_model); |
153 if (model) { | |
148 val = UnitDatabase::getInstance()->getUnitId | 154 val = UnitDatabase::getInstance()->getUnitId |
149 (getScaleUnits()); | 155 (getScaleUnits()); |
150 } | 156 } |
151 | 157 |
152 } else { | 158 } else { |
177 FlexiNoteLayer::setProperty(const PropertyName &name, int value) | 183 FlexiNoteLayer::setProperty(const PropertyName &name, int value) |
178 { | 184 { |
179 if (name == "Vertical Scale") { | 185 if (name == "Vertical Scale") { |
180 setVerticalScale(VerticalScale(value)); | 186 setVerticalScale(VerticalScale(value)); |
181 } else if (name == "Scale Units") { | 187 } else if (name == "Scale Units") { |
182 if (m_model) { | 188 auto model = ModelById::getAs<NoteModel>(m_model); |
183 m_model->setScaleUnits | 189 if (model) { |
190 model->setScaleUnits | |
184 (UnitDatabase::getInstance()->getUnitById(value)); | 191 (UnitDatabase::getInstance()->getUnitById(value)); |
185 emit modelChanged(); | 192 emit modelChanged(m_model); |
186 } | 193 } |
187 } else { | 194 } else { |
188 return SingleColourLayer::setProperty(name, value); | 195 return SingleColourLayer::setProperty(name, value); |
189 } | 196 } |
190 } | 197 } |
213 // unit.startsWith("MIDI") || | 220 // unit.startsWith("MIDI") || |
214 // unit.startsWith("midi")) return true; | 221 // unit.startsWith("midi")) return true; |
215 // return false; | 222 // return false; |
216 } | 223 } |
217 | 224 |
225 int | |
226 FlexiNoteLayer::getCompletion(LayerGeometryProvider *) const | |
227 { | |
228 auto model = ModelById::get(m_model); | |
229 if (model) return model->getCompletion(); | |
230 else return 0; | |
231 } | |
232 | |
218 bool | 233 bool |
219 FlexiNoteLayer::getValueExtents(double &min, double &max, | 234 FlexiNoteLayer::getValueExtents(double &min, double &max, |
220 bool &logarithmic, QString &unit) const | 235 bool &logarithmic, QString &unit) const |
221 { | 236 { |
222 if (!m_model) return false; | 237 auto model = ModelById::getAs<NoteModel>(m_model); |
223 min = m_model->getValueMinimum(); | 238 if (!model) return false; |
224 max = m_model->getValueMaximum(); | 239 min = model->getValueMinimum(); |
240 max = model->getValueMaximum(); | |
225 | 241 |
226 if (shouldConvertMIDIToHz()) { | 242 if (shouldConvertMIDIToHz()) { |
227 unit = "Hz"; | 243 unit = "Hz"; |
228 min = Pitch::getFrequencyForPitch(int(lrint(min))); | 244 min = Pitch::getFrequencyForPitch(int(lrint(min))); |
229 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); | 245 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); |
236 } | 252 } |
237 | 253 |
238 bool | 254 bool |
239 FlexiNoteLayer::getDisplayExtents(double &min, double &max) const | 255 FlexiNoteLayer::getDisplayExtents(double &min, double &max) const |
240 { | 256 { |
241 if (!m_model || shouldAutoAlign()) { | 257 auto model = ModelById::getAs<NoteModel>(m_model); |
258 if (!model || shouldAutoAlign()) { | |
242 // std::cerr << "No model or shouldAutoAlign()" << std::endl; | 259 // std::cerr << "No model or shouldAutoAlign()" << std::endl; |
243 return false; | 260 return false; |
244 } | 261 } |
245 | 262 |
246 if (m_verticalScale == MIDIRangeScale) { | 263 if (m_verticalScale == MIDIRangeScale) { |
248 max = Pitch::getFrequencyForPitch(127); | 265 max = Pitch::getFrequencyForPitch(127); |
249 return true; | 266 return true; |
250 } | 267 } |
251 | 268 |
252 if (m_scaleMinimum == m_scaleMaximum) { | 269 if (m_scaleMinimum == m_scaleMaximum) { |
253 min = m_model->getValueMinimum(); | 270 min = model->getValueMinimum(); |
254 max = m_model->getValueMaximum(); | 271 max = model->getValueMaximum(); |
255 } else { | 272 } else { |
256 min = m_scaleMinimum; | 273 min = m_scaleMinimum; |
257 max = m_scaleMaximum; | 274 max = m_scaleMaximum; |
258 } | 275 } |
259 | 276 |
270 } | 287 } |
271 | 288 |
272 bool | 289 bool |
273 FlexiNoteLayer::setDisplayExtents(double min, double max) | 290 FlexiNoteLayer::setDisplayExtents(double min, double max) |
274 { | 291 { |
275 if (!m_model) return false; | 292 auto model = ModelById::getAs<NoteModel>(m_model); |
293 if (!model) return false; | |
276 | 294 |
277 if (min == max) { | 295 if (min == max) { |
278 if (min == 0.f) { | 296 if (min == 0.f) { |
279 max = 1.f; | 297 max = 1.f; |
280 } else { | 298 } else { |
295 | 313 |
296 int | 314 int |
297 FlexiNoteLayer::getVerticalZoomSteps(int &defaultStep) const | 315 FlexiNoteLayer::getVerticalZoomSteps(int &defaultStep) const |
298 { | 316 { |
299 if (shouldAutoAlign()) return 0; | 317 if (shouldAutoAlign()) return 0; |
300 if (!m_model) return 0; | 318 auto model = ModelById::getAs<NoteModel>(m_model); |
319 if (!model) return 0; | |
301 | 320 |
302 defaultStep = 0; | 321 defaultStep = 0; |
303 return 100; | 322 return 100; |
304 } | 323 } |
305 | 324 |
306 int | 325 int |
307 FlexiNoteLayer::getCurrentVerticalZoomStep() const | 326 FlexiNoteLayer::getCurrentVerticalZoomStep() const |
308 { | 327 { |
309 if (shouldAutoAlign()) return 0; | 328 if (shouldAutoAlign()) return 0; |
310 if (!m_model) return 0; | 329 auto model = ModelById::getAs<NoteModel>(m_model); |
330 if (!model) return 0; | |
311 | 331 |
312 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); | 332 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); |
313 if (!mapper) return 0; | 333 if (!mapper) return 0; |
314 | 334 |
315 double dmin, dmax; | 335 double dmin, dmax; |
326 | 346 |
327 void | 347 void |
328 FlexiNoteLayer::setVerticalZoomStep(int step) | 348 FlexiNoteLayer::setVerticalZoomStep(int step) |
329 { | 349 { |
330 if (shouldAutoAlign()) return; | 350 if (shouldAutoAlign()) return; |
331 if (!m_model) return; | 351 auto model = ModelById::getAs<NoteModel>(m_model); |
352 if (!model) return; | |
332 | 353 |
333 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); | 354 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); |
334 if (!mapper) return; | 355 if (!mapper) return; |
335 | 356 |
336 double min, max; | 357 double min, max; |
376 } | 397 } |
377 | 398 |
378 RangeMapper * | 399 RangeMapper * |
379 FlexiNoteLayer::getNewVerticalZoomRangeMapper() const | 400 FlexiNoteLayer::getNewVerticalZoomRangeMapper() const |
380 { | 401 { |
381 if (!m_model) return nullptr; | 402 auto model = ModelById::getAs<NoteModel>(m_model); |
403 if (!model) return nullptr; | |
382 | 404 |
383 RangeMapper *mapper; | 405 RangeMapper *mapper; |
384 | 406 |
385 double min, max; | 407 double min, max; |
386 bool logarithmic; | 408 bool logarithmic; |
399 } | 421 } |
400 | 422 |
401 EventVector | 423 EventVector |
402 FlexiNoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const | 424 FlexiNoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const |
403 { | 425 { |
404 if (!m_model) return {}; | 426 auto model = ModelById::getAs<NoteModel>(m_model); |
427 if (!model) return {}; | |
405 | 428 |
406 sv_frame_t frame = v->getFrameForX(x); | 429 sv_frame_t frame = v->getFrameForX(x); |
407 | 430 |
408 EventVector local = m_model->getEventsCovering(frame); | 431 EventVector local = model->getEventsCovering(frame); |
409 if (!local.empty()) return local; | 432 if (!local.empty()) return local; |
410 | 433 |
411 int fuzz = ViewManager::scalePixelSize(2); | 434 int fuzz = ViewManager::scalePixelSize(2); |
412 sv_frame_t start = v->getFrameForX(x - fuzz); | 435 sv_frame_t start = v->getFrameForX(x - fuzz); |
413 sv_frame_t end = v->getFrameForX(x + fuzz); | 436 sv_frame_t end = v->getFrameForX(x + fuzz); |
414 | 437 |
415 local = m_model->getEventsStartingWithin(frame, end - frame); | 438 local = model->getEventsStartingWithin(frame, end - frame); |
416 if (!local.empty()) return local; | 439 if (!local.empty()) return local; |
417 | 440 |
418 local = m_model->getEventsSpanning(start, frame - start); | 441 local = model->getEventsSpanning(start, frame - start); |
419 if (!local.empty()) return local; | 442 if (!local.empty()) return local; |
420 | 443 |
421 return {}; | 444 return {}; |
422 } | 445 } |
423 | 446 |
424 bool | 447 bool |
425 FlexiNoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const | 448 FlexiNoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const |
426 { | 449 { |
427 if (!m_model) return false; | 450 auto model = ModelById::getAs<NoteModel>(m_model); |
451 if (!model) return false; | |
428 | 452 |
429 sv_frame_t frame = v->getFrameForX(x); | 453 sv_frame_t frame = v->getFrameForX(x); |
430 | 454 |
431 EventVector onPoints = m_model->getEventsCovering(frame); | 455 EventVector onPoints = model->getEventsCovering(frame); |
432 if (onPoints.empty()) return false; | 456 if (onPoints.empty()) return false; |
433 | 457 |
434 int nearestDistance = -1; | 458 int nearestDistance = -1; |
435 for (const auto &p: onPoints) { | 459 for (const auto &p: onPoints) { |
436 int distance = getYForValue(v, p.getValue()) - y; | 460 int distance = getYForValue(v, p.getValue()) - y; |
446 | 470 |
447 bool | 471 bool |
448 FlexiNoteLayer::getNoteToEdit(LayerGeometryProvider *v, int x, int y, Event &point) const | 472 FlexiNoteLayer::getNoteToEdit(LayerGeometryProvider *v, int x, int y, Event &point) const |
449 { | 473 { |
450 // GF: find the note that is closest to the cursor | 474 // GF: find the note that is closest to the cursor |
451 if (!m_model) return false; | 475 auto model = ModelById::getAs<NoteModel>(m_model); |
476 if (!model) return false; | |
452 | 477 |
453 sv_frame_t frame = v->getFrameForX(x); | 478 sv_frame_t frame = v->getFrameForX(x); |
454 | 479 |
455 EventVector onPoints = m_model->getEventsCovering(frame); | 480 EventVector onPoints = model->getEventsCovering(frame); |
456 if (onPoints.empty()) return false; | 481 if (onPoints.empty()) return false; |
457 | 482 |
458 int nearestDistance = -1; | 483 int nearestDistance = -1; |
459 for (const auto &p: onPoints) { | 484 for (const auto &p: onPoints) { |
460 int distance = getYForValue(v, p.getValue()) - y; | 485 int distance = getYForValue(v, p.getValue()) - y; |
471 QString | 496 QString |
472 FlexiNoteLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const | 497 FlexiNoteLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const |
473 { | 498 { |
474 int x = pos.x(); | 499 int x = pos.x(); |
475 | 500 |
476 if (!m_model || !m_model->getSampleRate()) return ""; | 501 auto model = ModelById::getAs<NoteModel>(m_model); |
502 if (!model || !model->getSampleRate()) return ""; | |
477 | 503 |
478 EventVector points = getLocalPoints(v, x); | 504 EventVector points = getLocalPoints(v, x); |
479 | 505 |
480 if (points.empty()) { | 506 if (points.empty()) { |
481 if (!m_model->isReady()) { | 507 if (!model->isReady()) { |
482 return tr("In progress"); | 508 return tr("In progress"); |
483 } else { | 509 } else { |
484 return tr("No local points"); | 510 return tr("No local points"); |
485 } | 511 } |
486 } | 512 } |
491 for (i = points.begin(); i != points.end(); ++i) { | 517 for (i = points.begin(); i != points.end(); ++i) { |
492 | 518 |
493 int y = getYForValue(v, i->getValue()); | 519 int y = getYForValue(v, i->getValue()); |
494 int h = NOTE_HEIGHT; // GF: larger notes | 520 int h = NOTE_HEIGHT; // GF: larger notes |
495 | 521 |
496 if (m_model->getValueQuantization() != 0.0) { | 522 if (model->getValueQuantization() != 0.0) { |
497 h = y - getYForValue | 523 h = y - getYForValue |
498 (v, i->getValue() + m_model->getValueQuantization()); | 524 (v, i->getValue() + model->getValueQuantization()); |
499 if (h < NOTE_HEIGHT) h = NOTE_HEIGHT; | 525 if (h < NOTE_HEIGHT) h = NOTE_HEIGHT; |
500 } | 526 } |
501 | 527 |
502 // GF: this is not quite correct | 528 // GF: this is not quite correct |
503 if (pos.y() >= y - 4 && pos.y() <= y + h) { | 529 if (pos.y() >= y - 4 && pos.y() <= y + h) { |
507 } | 533 } |
508 | 534 |
509 if (i == points.end()) return tr("No local points"); | 535 if (i == points.end()) return tr("No local points"); |
510 | 536 |
511 RealTime rt = RealTime::frame2RealTime(note.getFrame(), | 537 RealTime rt = RealTime::frame2RealTime(note.getFrame(), |
512 m_model->getSampleRate()); | 538 model->getSampleRate()); |
513 RealTime rd = RealTime::frame2RealTime(note.getDuration(), | 539 RealTime rd = RealTime::frame2RealTime(note.getDuration(), |
514 m_model->getSampleRate()); | 540 model->getSampleRate()); |
515 | 541 |
516 QString pitchText; | 542 QString pitchText; |
517 | 543 |
518 if (shouldConvertMIDIToHz()) { | 544 if (shouldConvertMIDIToHz()) { |
519 | 545 |
560 bool | 586 bool |
561 FlexiNoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, | 587 FlexiNoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, |
562 int &resolution, | 588 int &resolution, |
563 SnapType snap) const | 589 SnapType snap) const |
564 { | 590 { |
565 if (!m_model) { | 591 auto model = ModelById::getAs<NoteModel>(m_model); |
592 if (!model) { | |
566 return Layer::snapToFeatureFrame(v, frame, resolution, snap); | 593 return Layer::snapToFeatureFrame(v, frame, resolution, snap); |
567 } | 594 } |
568 | 595 |
569 resolution = m_model->getResolution(); | 596 resolution = model->getResolution(); |
570 EventVector points; | 597 EventVector points; |
571 | 598 |
572 if (snap == SnapNeighbouring) { | 599 if (snap == SnapNeighbouring) { |
573 | 600 |
574 points = getLocalPoints(v, v->getXForFrame(frame)); | 601 points = getLocalPoints(v, v->getXForFrame(frame)); |
575 if (points.empty()) return false; | 602 if (points.empty()) return false; |
576 frame = points.begin()->getFrame(); | 603 frame = points.begin()->getFrame(); |
577 return true; | 604 return true; |
578 } | 605 } |
579 | 606 |
580 points = m_model->getEventsCovering(frame); | 607 points = model->getEventsCovering(frame); |
581 sv_frame_t snapped = frame; | 608 sv_frame_t snapped = frame; |
582 bool found = false; | 609 bool found = false; |
583 | 610 |
584 for (EventVector::const_iterator i = points.begin(); | 611 for (EventVector::const_iterator i = points.begin(); |
585 i != points.end(); ++i) { | 612 i != points.end(); ++i) { |
648 | 675 |
649 if (shouldAutoAlign()) { | 676 if (shouldAutoAlign()) { |
650 | 677 |
651 if (!v->getValueExtents(queryUnits, min, max, log)) { | 678 if (!v->getValueExtents(queryUnits, min, max, log)) { |
652 | 679 |
653 min = m_model->getValueMinimum(); | 680 auto model = ModelById::getAs<NoteModel>(m_model); |
654 max = m_model->getValueMaximum(); | 681 min = model->getValueMinimum(); |
682 max = model->getValueMaximum(); | |
655 | 683 |
656 if (shouldConvertMIDIToHz()) { | 684 if (shouldConvertMIDIToHz()) { |
657 min = Pitch::getFrequencyForPitch(int(lrint(min))); | 685 min = Pitch::getFrequencyForPitch(int(lrint(min))); |
658 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); | 686 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); |
659 } | 687 } |
750 } | 778 } |
751 | 779 |
752 bool | 780 bool |
753 FlexiNoteLayer::shouldAutoAlign() const | 781 FlexiNoteLayer::shouldAutoAlign() const |
754 { | 782 { |
755 if (!m_model) return false; | |
756 return (m_verticalScale == AutoAlignScale); | 783 return (m_verticalScale == AutoAlignScale); |
757 } | 784 } |
758 | 785 |
759 void | 786 void |
760 FlexiNoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const | 787 FlexiNoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const |
761 { | 788 { |
762 if (!m_model || !m_model->isOK()) return; | 789 auto model = ModelById::getAs<NoteModel>(m_model); |
763 | 790 if (!model || !model->isOK()) return; |
764 sv_samplerate_t sampleRate = m_model->getSampleRate(); | 791 |
792 sv_samplerate_t sampleRate = model->getSampleRate(); | |
765 if (!sampleRate) return; | 793 if (!sampleRate) return; |
766 | 794 |
767 // Profiler profiler("FlexiNoteLayer::paint", true); | 795 // Profiler profiler("FlexiNoteLayer::paint", true); |
768 | 796 |
769 int x0 = rect.left(), x1 = rect.right(); | 797 int x0 = rect.left(), x1 = rect.right(); |
770 sv_frame_t frame0 = v->getFrameForX(x0); | 798 sv_frame_t frame0 = v->getFrameForX(x0); |
771 sv_frame_t frame1 = v->getFrameForX(x1); | 799 sv_frame_t frame1 = v->getFrameForX(x1); |
772 | 800 |
773 EventVector points(m_model->getEventsSpanning(frame0, frame1 - frame0)); | 801 EventVector points(model->getEventsSpanning(frame0, frame1 - frame0)); |
774 if (points.empty()) return; | 802 if (points.empty()) return; |
775 | 803 |
776 paint.setPen(getBaseQColor()); | 804 paint.setPen(getBaseQColor()); |
777 | 805 |
778 QColor brushColour(getBaseQColor()); | 806 QColor brushColour(getBaseQColor()); |
779 brushColour.setAlpha(80); | 807 brushColour.setAlpha(80); |
780 | 808 |
781 // SVDEBUG << "FlexiNoteLayer::paint: resolution is " | 809 // SVDEBUG << "FlexiNoteLayer::paint: resolution is " |
782 // << m_model->getResolution() << " frames" << endl; | 810 // << model->getResolution() << " frames" << endl; |
783 | 811 |
784 double min = m_model->getValueMinimum(); | 812 double min = model->getValueMinimum(); |
785 double max = m_model->getValueMaximum(); | 813 double max = model->getValueMaximum(); |
786 if (max == min) max = min + 1.0; | 814 if (max == min) max = min + 1.0; |
787 | 815 |
788 QPoint localPos; | 816 QPoint localPos; |
789 Event illuminatePoint(0); | 817 Event illuminatePoint(0); |
790 bool shouldIlluminate = false; | 818 bool shouldIlluminate = false; |
808 int x = v->getXForFrame(p.getFrame()); | 836 int x = v->getXForFrame(p.getFrame()); |
809 int y = getYForValue(v, p.getValue()); | 837 int y = getYForValue(v, p.getValue()); |
810 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; | 838 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; |
811 int h = NOTE_HEIGHT; //GF: larger notes | 839 int h = NOTE_HEIGHT; //GF: larger notes |
812 | 840 |
813 if (m_model->getValueQuantization() != 0.0) { | 841 if (model->getValueQuantization() != 0.0) { |
814 h = y - getYForValue(v, p.getValue() + m_model->getValueQuantization()); | 842 h = y - getYForValue(v, p.getValue() + model->getValueQuantization()); |
815 if (h < NOTE_HEIGHT) h = NOTE_HEIGHT; //GF: larger notes | 843 if (h < NOTE_HEIGHT) h = NOTE_HEIGHT; //GF: larger notes |
816 } | 844 } |
817 | 845 |
818 if (w < 1) w = 1; | 846 if (w < 1) w = 1; |
819 paint.setPen(getBaseQColor()); | 847 paint.setPen(getBaseQColor()); |
825 paint.drawLine(x+w, -1, x+w, v->getPaintHeight() + 1); | 853 paint.drawLine(x+w, -1, x+w, v->getPaintHeight() + 1); |
826 | 854 |
827 paint.setPen(v->getForeground()); | 855 paint.setPen(v->getForeground()); |
828 | 856 |
829 QString vlabel = tr("freq: %1%2") | 857 QString vlabel = tr("freq: %1%2") |
830 .arg(p.getValue()).arg(m_model->getScaleUnits()); | 858 .arg(p.getValue()).arg(model->getScaleUnits()); |
831 PaintAssistant::drawVisibleText | 859 PaintAssistant::drawVisibleText |
832 (v, paint, | 860 (v, paint, |
833 x, | 861 x, |
834 y - h/2 - 2 - paint.fontMetrics().height() | 862 y - h/2 - 2 - paint.fontMetrics().height() |
835 - paint.fontMetrics().descent(), | 863 - paint.fontMetrics().descent(), |
836 vlabel, PaintAssistant::OutlinedText); | 864 vlabel, PaintAssistant::OutlinedText); |
837 | 865 |
838 QString hlabel = tr("dur: %1") | 866 QString hlabel = tr("dur: %1") |
839 .arg(RealTime::frame2RealTime | 867 .arg(RealTime::frame2RealTime |
840 (p.getDuration(), m_model->getSampleRate()).toText(true) | 868 (p.getDuration(), model->getSampleRate()).toText(true) |
841 .c_str()); | 869 .c_str()); |
842 PaintAssistant::drawVisibleText | 870 PaintAssistant::drawVisibleText |
843 (v, paint, | 871 (v, paint, |
844 x, | 872 x, |
845 y - h/2 - paint.fontMetrics().descent() - 2, | 873 y - h/2 - paint.fontMetrics().descent() - 2, |
867 } | 895 } |
868 | 896 |
869 int | 897 int |
870 FlexiNoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const | 898 FlexiNoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const |
871 { | 899 { |
872 if (!m_model || shouldAutoAlign()) { | 900 if (shouldAutoAlign()) { |
873 return 0; | 901 return 0; |
874 } else { | 902 } else { |
875 if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { | 903 if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { |
876 return LogNumericalScale().getWidth(v, paint) + 10; // for piano | 904 return LogNumericalScale().getWidth(v, paint) + 10; // for piano |
877 } else { | 905 } else { |
881 } | 909 } |
882 | 910 |
883 void | 911 void |
884 FlexiNoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const | 912 FlexiNoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const |
885 { | 913 { |
886 if (!m_model || m_model->isEmpty()) return; | 914 auto model = ModelById::getAs<NoteModel>(m_model); |
915 if (!model || model->isEmpty()) return; | |
887 | 916 |
888 QString unit; | 917 QString unit; |
889 double min, max; | 918 double min, max; |
890 bool logarithmic; | 919 bool logarithmic; |
891 | 920 |
921 void | 950 void |
922 FlexiNoteLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) | 951 FlexiNoteLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) |
923 { | 952 { |
924 // SVDEBUG << "FlexiNoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; | 953 // SVDEBUG << "FlexiNoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; |
925 | 954 |
926 if (!m_model) return; | 955 auto model = ModelById::getAs<NoteModel>(m_model); |
956 if (!model) return; | |
927 | 957 |
928 sv_frame_t frame = v->getFrameForX(e->x()); | 958 sv_frame_t frame = v->getFrameForX(e->x()); |
929 if (frame < 0) frame = 0; | 959 if (frame < 0) frame = 0; |
930 frame = frame / m_model->getResolution() * m_model->getResolution(); | 960 frame = frame / model->getResolution() * model->getResolution(); |
931 | 961 |
932 double value = getValueForY(v, e->y()); | 962 double value = getValueForY(v, e->y()); |
933 | 963 |
934 m_editingPoint = Event(frame, float(value), 0, 0.8f, tr("New Point")); | 964 m_editingPoint = Event(frame, float(value), 0, 0.8f, tr("New Point")); |
935 m_originalPoint = m_editingPoint; | 965 m_originalPoint = m_editingPoint; |
936 | 966 |
937 if (m_editingCommand) finish(m_editingCommand); | 967 if (m_editingCommand) finish(m_editingCommand); |
938 m_editingCommand = new ChangeEventsCommand(m_model, tr("Draw Point")); | 968 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Draw Point")); |
939 m_editingCommand->add(m_editingPoint); | 969 m_editingCommand->add(m_editingPoint); |
940 | 970 |
941 m_editing = true; | 971 m_editing = true; |
942 } | 972 } |
943 | 973 |
944 void | 974 void |
945 FlexiNoteLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) | 975 FlexiNoteLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) |
946 { | 976 { |
947 // SVDEBUG << "FlexiNoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; | 977 // SVDEBUG << "FlexiNoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; |
948 | 978 |
949 if (!m_model || !m_editing) return; | 979 auto model = ModelById::getAs<NoteModel>(m_model); |
980 if (!model || !m_editing) return; | |
950 | 981 |
951 sv_frame_t frame = v->getFrameForX(e->x()); | 982 sv_frame_t frame = v->getFrameForX(e->x()); |
952 if (frame < 0) frame = 0; | 983 if (frame < 0) frame = 0; |
953 frame = frame / m_model->getResolution() * m_model->getResolution(); | 984 frame = frame / model->getResolution() * model->getResolution(); |
954 | 985 |
955 double newValue = getValueForY(v, e->y()); | 986 double newValue = getValueForY(v, e->y()); |
956 | 987 |
957 sv_frame_t newFrame = m_editingPoint.getFrame(); | 988 sv_frame_t newFrame = m_editingPoint.getFrame(); |
958 sv_frame_t newDuration = frame - newFrame; | 989 sv_frame_t newDuration = frame - newFrame; |
973 | 1004 |
974 void | 1005 void |
975 FlexiNoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) | 1006 FlexiNoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) |
976 { | 1007 { |
977 // SVDEBUG << "FlexiNoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; | 1008 // SVDEBUG << "FlexiNoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; |
978 if (!m_model || !m_editing) return; | 1009 auto model = ModelById::getAs<NoteModel>(m_model); |
1010 if (!model || !m_editing) return; | |
979 finish(m_editingCommand); | 1011 finish(m_editingCommand); |
980 m_editingCommand = nullptr; | 1012 m_editingCommand = nullptr; |
981 m_editing = false; | 1013 m_editing = false; |
982 } | 1014 } |
983 | 1015 |
984 void | 1016 void |
985 FlexiNoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) | 1017 FlexiNoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) |
986 { | 1018 { |
987 if (!m_model) return; | 1019 auto model = ModelById::getAs<NoteModel>(m_model); |
1020 if (!model) return; | |
988 | 1021 |
989 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 1022 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
990 | 1023 |
991 if (m_editingCommand) { | 1024 if (m_editingCommand) { |
992 finish(m_editingCommand); | 1025 finish(m_editingCommand); |
1002 } | 1035 } |
1003 | 1036 |
1004 void | 1037 void |
1005 FlexiNoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) | 1038 FlexiNoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) |
1006 { | 1039 { |
1007 if (!m_model || !m_editing) return; | 1040 if (!m_editing) return; |
1008 | |
1009 m_editing = false; | 1041 m_editing = false; |
1010 | 1042 |
1011 Event p(0); | 1043 Event p(0); |
1012 if (!getPointToDrag(v, e->x(), e->y(), p)) return; | 1044 if (!getPointToDrag(v, e->x(), e->y(), p)) return; |
1013 if (p.getFrame() != m_editingPoint.getFrame() || p.getValue() != m_editingPoint.getValue()) return; | 1045 if (p.getFrame() != m_editingPoint.getFrame() || |
1014 | 1046 p.getValue() != m_editingPoint.getValue()) return; |
1015 m_editingCommand = new ChangeEventsCommand(m_model, tr("Erase Point")); | 1047 |
1048 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Erase Point")); | |
1016 m_editingCommand->remove(m_editingPoint); | 1049 m_editingCommand->remove(m_editingPoint); |
1017 finish(m_editingCommand); | 1050 finish(m_editingCommand); |
1018 m_editingCommand = nullptr; | 1051 m_editingCommand = nullptr; |
1019 m_editing = false; | 1052 m_editing = false; |
1020 } | 1053 } |
1023 FlexiNoteLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) | 1056 FlexiNoteLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) |
1024 { | 1057 { |
1025 // SVDEBUG << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; | 1058 // SVDEBUG << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; |
1026 std::cerr << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; | 1059 std::cerr << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; |
1027 | 1060 |
1028 if (!m_model) return; | 1061 auto model = ModelById::getAs<NoteModel>(m_model); |
1062 if (!model) return; | |
1029 | 1063 |
1030 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 1064 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
1031 m_originalPoint = m_editingPoint; | 1065 m_originalPoint = m_editingPoint; |
1032 | 1066 |
1033 if (m_editMode == RightBoundary) { | 1067 if (m_editMode == RightBoundary) { |
1054 m_originalPoint.getDuration() - 1; | 1088 m_originalPoint.getDuration() - 1; |
1055 | 1089 |
1056 m_greatestLeftNeighbourFrame = -1; | 1090 m_greatestLeftNeighbourFrame = -1; |
1057 m_smallestRightNeighbourFrame = std::numeric_limits<int>::max(); | 1091 m_smallestRightNeighbourFrame = std::numeric_limits<int>::max(); |
1058 | 1092 |
1059 EventVector allEvents = m_model->getAllEvents(); | 1093 EventVector allEvents = model->getAllEvents(); |
1060 | 1094 |
1061 for (auto currentNote: allEvents) { | 1095 for (auto currentNote: allEvents) { |
1062 | 1096 |
1063 // left boundary | 1097 // left boundary |
1064 if (currentNote.getFrame() + currentNote.getDuration() - 1 < onset) { | 1098 if (currentNote.getFrame() + currentNote.getDuration() - 1 < onset) { |
1080 FlexiNoteLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) | 1114 FlexiNoteLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) |
1081 { | 1115 { |
1082 // SVDEBUG << "FlexiNoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; | 1116 // SVDEBUG << "FlexiNoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; |
1083 std::cerr << "FlexiNoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; | 1117 std::cerr << "FlexiNoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; |
1084 | 1118 |
1085 if (!m_model || !m_editing) return; | 1119 auto model = ModelById::getAs<NoteModel>(m_model); |
1120 if (!model || !m_editing) return; | |
1086 | 1121 |
1087 int xdist = e->x() - m_dragStartX; | 1122 int xdist = e->x() - m_dragStartX; |
1088 int ydist = e->y() - m_dragStartY; | 1123 int ydist = e->y() - m_dragStartY; |
1089 int newx = m_dragPointX + xdist; | 1124 int newx = m_dragPointX + xdist; |
1090 int newy = m_dragPointY + ydist; | 1125 int newy = m_dragPointY + ydist; |
1091 | 1126 |
1092 sv_frame_t dragFrame = v->getFrameForX(newx); | 1127 sv_frame_t dragFrame = v->getFrameForX(newx); |
1093 if (dragFrame < 0) dragFrame = 0; | 1128 if (dragFrame < 0) dragFrame = 0; |
1094 dragFrame = dragFrame / m_model->getResolution() * m_model->getResolution(); | 1129 dragFrame = dragFrame / model->getResolution() * model->getResolution(); |
1095 | 1130 |
1096 double value = getValueForY(v, newy); | 1131 double value = getValueForY(v, newy); |
1097 | 1132 |
1098 if (!m_editingCommand) { | 1133 if (!m_editingCommand) { |
1099 m_editingCommand = new ChangeEventsCommand(m_model, tr("Drag Point")); | 1134 m_editingCommand = |
1135 new ChangeEventsCommand(m_model.untyped, tr("Drag Point")); | |
1100 } | 1136 } |
1101 m_editingCommand->remove(m_editingPoint); | 1137 m_editingCommand->remove(m_editingPoint); |
1102 | 1138 |
1103 std::cerr << "edit mode: " << m_editMode << " intelligent actions = " | 1139 std::cerr << "edit mode: " << m_editMode << " intelligent actions = " |
1104 << m_intelligentActions << std::endl; | 1140 << m_intelligentActions << std::endl; |
1180 FlexiNoteLayer::editEnd(LayerGeometryProvider *v, QMouseEvent *e) | 1216 FlexiNoteLayer::editEnd(LayerGeometryProvider *v, QMouseEvent *e) |
1181 { | 1217 { |
1182 std::cerr << "FlexiNoteLayer::editEnd(" | 1218 std::cerr << "FlexiNoteLayer::editEnd(" |
1183 << e->x() << "," << e->y() << ")" << std::endl; | 1219 << e->x() << "," << e->y() << ")" << std::endl; |
1184 | 1220 |
1185 if (!m_model || !m_editing) return; | 1221 auto model = ModelById::getAs<NoteModel>(m_model); |
1222 if (!model || !m_editing) return; | |
1186 | 1223 |
1187 if (m_editingCommand) { | 1224 if (m_editingCommand) { |
1188 | 1225 |
1189 QString newName = m_editingCommand->getName(); | 1226 QString newName = m_editingCommand->getName(); |
1190 | 1227 |
1216 } | 1253 } |
1217 | 1254 |
1218 void | 1255 void |
1219 FlexiNoteLayer::splitStart(LayerGeometryProvider *v, QMouseEvent *e) | 1256 FlexiNoteLayer::splitStart(LayerGeometryProvider *v, QMouseEvent *e) |
1220 { | 1257 { |
1258 auto model = ModelById::getAs<NoteModel>(m_model); | |
1259 if (!model) return; | |
1260 | |
1221 // GF: note splitting starts (!! remove printing soon) | 1261 // GF: note splitting starts (!! remove printing soon) |
1222 std::cerr << "splitStart (n.b. editStart will be called later, if the user drags the mouse)" << std::endl; | 1262 std::cerr << "splitStart (n.b. editStart will be called later, if the user drags the mouse)" << std::endl; |
1223 if (!m_model) return; | |
1224 | 1263 |
1225 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 1264 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
1226 // m_originalPoint = m_editingPoint; | 1265 // m_originalPoint = m_editingPoint; |
1227 // | 1266 // |
1228 // m_dragPointX = v->getXForFrame(m_editingPoint.getFrame()); | 1267 // m_dragPointX = v->getXForFrame(m_editingPoint.getFrame()); |
1239 } | 1278 } |
1240 | 1279 |
1241 void | 1280 void |
1242 FlexiNoteLayer::splitEnd(LayerGeometryProvider *v, QMouseEvent *e) | 1281 FlexiNoteLayer::splitEnd(LayerGeometryProvider *v, QMouseEvent *e) |
1243 { | 1282 { |
1283 auto model = ModelById::getAs<NoteModel>(m_model); | |
1244 // GF: note splitting ends. (!! remove printing soon) | 1284 // GF: note splitting ends. (!! remove printing soon) |
1245 std::cerr << "splitEnd" << std::endl; | 1285 std::cerr << "splitEnd" << std::endl; |
1246 if (!m_model || !m_editing || m_editMode != SplitNote) return; | 1286 if (!model || !m_editing || m_editMode != SplitNote) return; |
1247 | 1287 |
1248 int xdist = e->x() - m_dragStartX; | 1288 int xdist = e->x() - m_dragStartX; |
1249 int ydist = e->y() - m_dragStartY; | 1289 int ydist = e->y() - m_dragStartY; |
1250 if (xdist != 0 || ydist != 0) { | 1290 if (xdist != 0 || ydist != 0) { |
1251 std::cerr << "mouse moved" << std::endl; | 1291 std::cerr << "mouse moved" << std::endl; |
1264 } | 1304 } |
1265 | 1305 |
1266 void | 1306 void |
1267 FlexiNoteLayer::splitNotesAt(LayerGeometryProvider *v, sv_frame_t frame, QMouseEvent *e) | 1307 FlexiNoteLayer::splitNotesAt(LayerGeometryProvider *v, sv_frame_t frame, QMouseEvent *e) |
1268 { | 1308 { |
1269 EventVector onPoints = m_model->getEventsCovering(frame); | 1309 auto model = ModelById::getAs<NoteModel>(m_model); |
1310 if (!model) return; | |
1311 | |
1312 EventVector onPoints = model->getEventsCovering(frame); | |
1270 if (onPoints.empty()) return; | 1313 if (onPoints.empty()) return; |
1271 | 1314 |
1272 Event note(*onPoints.begin()); | 1315 Event note(*onPoints.begin()); |
1273 | 1316 |
1274 ChangeEventsCommand *command = new ChangeEventsCommand | 1317 auto command = new ChangeEventsCommand(m_model.untyped, tr("Edit Point")); |
1275 (m_model, tr("Edit Point")); | |
1276 command->remove(note); | 1318 command->remove(note); |
1277 | 1319 |
1278 if (!e || !(e->modifiers() & Qt::ShiftModifier)) { | 1320 if (!e || !(e->modifiers() & Qt::ShiftModifier)) { |
1279 | 1321 |
1280 int gap = 0; // MM: I prefer a gap of 0, but we can decide later | 1322 int gap = 0; // MM: I prefer a gap of 0, but we can decide later |
1304 } | 1346 } |
1305 | 1347 |
1306 void | 1348 void |
1307 FlexiNoteLayer::addNote(LayerGeometryProvider *v, QMouseEvent *e) | 1349 FlexiNoteLayer::addNote(LayerGeometryProvider *v, QMouseEvent *e) |
1308 { | 1350 { |
1351 auto model = ModelById::getAs<NoteModel>(m_model); | |
1309 std::cerr << "addNote" << std::endl; | 1352 std::cerr << "addNote" << std::endl; |
1310 if (!m_model) return; | 1353 if (!model) return; |
1311 | 1354 |
1312 sv_frame_t duration = 10000; | 1355 sv_frame_t duration = 10000; |
1313 | 1356 |
1314 sv_frame_t frame = v->getFrameForX(e->x()); | 1357 sv_frame_t frame = v->getFrameForX(e->x()); |
1315 double value = getValueForY(v, e->y()); | 1358 double value = getValueForY(v, e->y()); |
1316 | 1359 |
1317 EventVector noteList = m_model->getAllEvents(); | 1360 EventVector noteList = model->getAllEvents(); |
1318 | 1361 |
1319 if (m_intelligentActions) { | 1362 if (m_intelligentActions) { |
1320 sv_frame_t smallestRightNeighbourFrame = 0; | 1363 sv_frame_t smallestRightNeighbourFrame = 0; |
1321 for (EventVector::const_iterator i = noteList.begin(); | 1364 for (EventVector::const_iterator i = noteList.begin(); |
1322 i != noteList.end(); ++i) { | 1365 i != noteList.end(); ++i) { |
1331 duration = (duration > 0) ? duration : 0; | 1374 duration = (duration > 0) ? duration : 0; |
1332 } | 1375 } |
1333 } | 1376 } |
1334 | 1377 |
1335 if (!m_intelligentActions || | 1378 if (!m_intelligentActions || |
1336 (m_model->getEventsCovering(frame).empty() && duration > 0)) { | 1379 (model->getEventsCovering(frame).empty() && duration > 0)) { |
1337 Event newNote(frame, float(value), duration, 100.f, tr("new note")); | 1380 Event newNote(frame, float(value), duration, 100.f, tr("new note")); |
1338 ChangeEventsCommand *command = new ChangeEventsCommand | 1381 auto command = new ChangeEventsCommand(m_model.untyped, tr("Add Point")); |
1339 (m_model, tr("Add Point")); | |
1340 command->add(newNote); | 1382 command->add(newNote); |
1341 finish(command); | 1383 finish(command); |
1342 } | 1384 } |
1343 } | 1385 } |
1344 | 1386 |
1345 SparseTimeValueModel * | 1387 ModelId |
1346 FlexiNoteLayer::getAssociatedPitchModel(LayerGeometryProvider *v) const | 1388 FlexiNoteLayer::getAssociatedPitchModel(LayerGeometryProvider *v) const |
1347 { | 1389 { |
1348 // Better than we used to do, but still not very satisfactory | 1390 // Better than we used to do, but still not very satisfactory |
1349 | 1391 |
1350 // cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl; | 1392 // cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl; |
1352 for (int i = 0; i < v->getView()->getLayerCount(); ++i) { | 1394 for (int i = 0; i < v->getView()->getLayerCount(); ++i) { |
1353 Layer *layer = v->getView()->getLayer(i); | 1395 Layer *layer = v->getView()->getLayer(i); |
1354 if (layer && | 1396 if (layer && |
1355 layer->getLayerPresentationName() != "candidate") { | 1397 layer->getLayerPresentationName() != "candidate") { |
1356 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl; | 1398 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl; |
1357 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *> | 1399 auto modelId = layer->getModel(); |
1358 (layer->getModel()); | 1400 auto model = ModelById::getAs<SparseTimeValueModel>(modelId); |
1359 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl; | |
1360 if (model && model->getScaleUnits() == "Hz") { | 1401 if (model && model->getScaleUnits() == "Hz") { |
1361 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; | 1402 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; |
1362 return model; | 1403 return modelId; |
1363 } | 1404 } |
1364 } | 1405 } |
1365 } | 1406 } |
1366 cerr << "FlexiNoteLayer::getAssociatedPitchModel: failed to find a model" << endl; | 1407 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: failed to find a model" << endl; |
1367 return nullptr; | 1408 return {}; |
1368 } | 1409 } |
1369 | 1410 |
1370 void | 1411 void |
1371 FlexiNoteLayer::snapSelectedNotesToPitchTrack(LayerGeometryProvider *v, Selection s) | 1412 FlexiNoteLayer::snapSelectedNotesToPitchTrack(LayerGeometryProvider *v, Selection s) |
1372 { | 1413 { |
1373 if (!m_model) return; | 1414 auto model = ModelById::getAs<NoteModel>(m_model); |
1415 if (!model) return; | |
1374 | 1416 |
1375 EventVector points = | 1417 EventVector points = |
1376 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1418 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1377 | 1419 |
1378 ChangeEventsCommand *command = new ChangeEventsCommand | 1420 auto command = new ChangeEventsCommand(m_model.untyped, tr("Snap Notes")); |
1379 (m_model, tr("Snap Notes")); | |
1380 | 1421 |
1381 cerr << "snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() << " to " << s.getEndFrame() << endl; | 1422 cerr << "snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() << " to " << s.getEndFrame() << endl; |
1382 | 1423 |
1383 for (EventVector::iterator i = points.begin(); | 1424 for (EventVector::iterator i = points.begin(); |
1384 i != points.end(); ++i) { | 1425 i != points.end(); ++i) { |
1406 } | 1447 } |
1407 | 1448 |
1408 void | 1449 void |
1409 FlexiNoteLayer::mergeNotes(LayerGeometryProvider *v, Selection s, bool inclusive) | 1450 FlexiNoteLayer::mergeNotes(LayerGeometryProvider *v, Selection s, bool inclusive) |
1410 { | 1451 { |
1452 auto model = ModelById::getAs<NoteModel>(m_model); | |
1453 if (!model) return; | |
1454 | |
1411 EventVector points; | 1455 EventVector points; |
1412 if (inclusive) { | 1456 if (inclusive) { |
1413 points = m_model->getEventsSpanning(s.getStartFrame(), s.getDuration()); | 1457 points = model->getEventsSpanning(s.getStartFrame(), s.getDuration()); |
1414 } else { | 1458 } else { |
1415 points = m_model->getEventsWithin(s.getStartFrame(), s.getDuration()); | 1459 points = model->getEventsWithin(s.getStartFrame(), s.getDuration()); |
1416 } | 1460 } |
1417 | 1461 |
1418 EventVector::iterator i = points.begin(); | 1462 EventVector::iterator i = points.begin(); |
1419 if (i == points.end()) return; | 1463 if (i == points.end()) return; |
1420 | 1464 |
1421 ChangeEventsCommand *command = | 1465 auto command = new ChangeEventsCommand(m_model.untyped, tr("Merge Notes")); |
1422 new ChangeEventsCommand(m_model, tr("Merge Notes")); | |
1423 | 1466 |
1424 Event newNote(*i); | 1467 Event newNote(*i); |
1425 | 1468 |
1426 while (i != points.end()) { | 1469 while (i != points.end()) { |
1427 | 1470 |
1444 } | 1487 } |
1445 | 1488 |
1446 bool | 1489 bool |
1447 FlexiNoteLayer::updateNoteValueFromPitchCurve(LayerGeometryProvider *v, Event ¬e) const | 1490 FlexiNoteLayer::updateNoteValueFromPitchCurve(LayerGeometryProvider *v, Event ¬e) const |
1448 { | 1491 { |
1449 SparseTimeValueModel *model = getAssociatedPitchModel(v); | 1492 ModelId modelId = getAssociatedPitchModel(v); |
1493 auto model = ModelById::getAs<SparseTimeValueModel>(modelId); | |
1450 if (!model) return false; | 1494 if (!model) return false; |
1451 | 1495 |
1452 std::cerr << model->getTypeName() << std::endl; | 1496 std::cerr << model->getTypeName() << std::endl; |
1453 | 1497 |
1454 EventVector dataPoints = | 1498 EventVector dataPoints = |
1523 } | 1567 } |
1524 | 1568 |
1525 void | 1569 void |
1526 FlexiNoteLayer::getRelativeMousePosition(LayerGeometryProvider *v, Event ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const | 1570 FlexiNoteLayer::getRelativeMousePosition(LayerGeometryProvider *v, Event ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const |
1527 { | 1571 { |
1528 // GF: TODO: consoloidate the tolerance values | 1572 // GF: TODO: consolidate the tolerance values |
1529 if (!m_model) return; | |
1530 | 1573 |
1531 int ctol = 0; | 1574 int ctol = 0; |
1532 int noteStartX = v->getXForFrame(note.getFrame()); | 1575 int noteStartX = v->getXForFrame(note.getFrame()); |
1533 int noteEndX = v->getXForFrame(note.getFrame() + note.getDuration()); | 1576 int noteEndX = v->getXForFrame(note.getFrame() + note.getDuration()); |
1534 int noteValueY = getYForValue(v,note.getValue()); | 1577 int noteValueY = getYForValue(v,note.getValue()); |
1553 | 1596 |
1554 bool | 1597 bool |
1555 FlexiNoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) | 1598 FlexiNoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) |
1556 { | 1599 { |
1557 std::cerr << "Opening note editor dialog" << std::endl; | 1600 std::cerr << "Opening note editor dialog" << std::endl; |
1558 if (!m_model) return false; | 1601 auto model = ModelById::getAs<NoteModel>(m_model); |
1602 if (!model) return false; | |
1559 | 1603 |
1560 Event note(0); | 1604 Event note(0); |
1561 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; | 1605 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; |
1562 | 1606 |
1563 // Event note = *points.begin(); | 1607 // Event note = *points.begin(); |
1564 | 1608 |
1565 ItemEditDialog *dialog = new ItemEditDialog | 1609 ItemEditDialog *dialog = new ItemEditDialog |
1566 (m_model->getSampleRate(), | 1610 (model->getSampleRate(), |
1567 ItemEditDialog::ShowTime | | 1611 ItemEditDialog::ShowTime | |
1568 ItemEditDialog::ShowDuration | | 1612 ItemEditDialog::ShowDuration | |
1569 ItemEditDialog::ShowValue | | 1613 ItemEditDialog::ShowValue | |
1570 ItemEditDialog::ShowText, | 1614 ItemEditDialog::ShowText, |
1571 getScaleUnits()); | 1615 getScaleUnits()); |
1581 .withFrame(dialog->getFrameTime()) | 1625 .withFrame(dialog->getFrameTime()) |
1582 .withValue(dialog->getValue()) | 1626 .withValue(dialog->getValue()) |
1583 .withDuration(dialog->getFrameDuration()) | 1627 .withDuration(dialog->getFrameDuration()) |
1584 .withLabel(dialog->getText()); | 1628 .withLabel(dialog->getText()); |
1585 | 1629 |
1586 ChangeEventsCommand *command = new ChangeEventsCommand | 1630 auto command = new ChangeEventsCommand(m_model.untyped, tr("Edit Point")); |
1587 (m_model, tr("Edit Point")); | |
1588 command->remove(note); | 1631 command->remove(note); |
1589 command->add(newNote); | 1632 command->add(newNote); |
1590 finish(command); | 1633 finish(command); |
1591 } | 1634 } |
1592 | 1635 |
1595 } | 1638 } |
1596 | 1639 |
1597 void | 1640 void |
1598 FlexiNoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame) | 1641 FlexiNoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame) |
1599 { | 1642 { |
1600 if (!m_model) return; | 1643 auto model = ModelById::getAs<NoteModel>(m_model); |
1601 | 1644 if (!model) return; |
1602 ChangeEventsCommand *command = | 1645 |
1603 new ChangeEventsCommand(m_model, tr("Drag Selection")); | 1646 auto command = new ChangeEventsCommand(m_model.untyped, tr("Drag Selection")); |
1604 | 1647 |
1605 EventVector points = | 1648 EventVector points = |
1606 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1649 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1607 | 1650 |
1608 for (Event p: points) { | 1651 for (Event p: points) { |
1609 command->remove(p); | 1652 command->remove(p); |
1610 Event moved = p.withFrame(p.getFrame() + | 1653 Event moved = p.withFrame(p.getFrame() + |
1611 newStartFrame - s.getStartFrame()); | 1654 newStartFrame - s.getStartFrame()); |
1616 } | 1659 } |
1617 | 1660 |
1618 void | 1661 void |
1619 FlexiNoteLayer::resizeSelection(Selection s, Selection newSize) | 1662 FlexiNoteLayer::resizeSelection(Selection s, Selection newSize) |
1620 { | 1663 { |
1621 if (!m_model || !s.getDuration()) return; | 1664 auto model = ModelById::getAs<NoteModel>(m_model); |
1622 | 1665 if (!model || !s.getDuration()) return; |
1623 ChangeEventsCommand *command = | 1666 |
1624 new ChangeEventsCommand(m_model, tr("Resize Selection")); | 1667 auto command = new ChangeEventsCommand(m_model.untyped, tr("Resize Selection")); |
1625 | 1668 |
1626 EventVector points = | 1669 EventVector points = |
1627 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1670 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1628 | 1671 |
1629 double ratio = double(newSize.getDuration()) / double(s.getDuration()); | 1672 double ratio = double(newSize.getDuration()) / double(s.getDuration()); |
1630 double oldStart = double(s.getStartFrame()); | 1673 double oldStart = double(s.getStartFrame()); |
1631 double newStart = double(newSize.getStartFrame()); | 1674 double newStart = double(newSize.getStartFrame()); |
1632 | 1675 |
1646 } | 1689 } |
1647 | 1690 |
1648 void | 1691 void |
1649 FlexiNoteLayer::deleteSelection(Selection s) | 1692 FlexiNoteLayer::deleteSelection(Selection s) |
1650 { | 1693 { |
1651 if (!m_model) return; | 1694 auto model = ModelById::getAs<NoteModel>(m_model); |
1652 | 1695 if (!model) return; |
1653 ChangeEventsCommand *command = | 1696 |
1654 new ChangeEventsCommand(m_model, tr("Delete Selected Points")); | 1697 auto command = |
1698 new ChangeEventsCommand(m_model.untyped, tr("Delete Selected Points")); | |
1655 | 1699 |
1656 EventVector points = | 1700 EventVector points = |
1657 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1701 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1658 | 1702 |
1659 for (Event p: points) { | 1703 for (Event p: points) { |
1660 command->remove(p); | 1704 command->remove(p); |
1661 } | 1705 } |
1662 | 1706 |
1664 } | 1708 } |
1665 | 1709 |
1666 void | 1710 void |
1667 FlexiNoteLayer::deleteSelectionInclusive(Selection s) | 1711 FlexiNoteLayer::deleteSelectionInclusive(Selection s) |
1668 { | 1712 { |
1669 if (!m_model) return; | 1713 auto model = ModelById::getAs<NoteModel>(m_model); |
1670 | 1714 if (!model) return; |
1671 ChangeEventsCommand *command = | 1715 |
1672 new ChangeEventsCommand(m_model, tr("Delete Selected Points")); | 1716 auto command = |
1717 new ChangeEventsCommand(m_model.untyped, tr("Delete Selected Points")); | |
1673 | 1718 |
1674 EventVector points = | 1719 EventVector points = |
1675 m_model->getEventsSpanning(s.getStartFrame(), s.getDuration()); | 1720 model->getEventsSpanning(s.getStartFrame(), s.getDuration()); |
1676 | 1721 |
1677 for (Event p: points) { | 1722 for (Event p: points) { |
1678 command->remove(p); | 1723 command->remove(p); |
1679 } | 1724 } |
1680 | 1725 |
1682 } | 1727 } |
1683 | 1728 |
1684 void | 1729 void |
1685 FlexiNoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) | 1730 FlexiNoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) |
1686 { | 1731 { |
1687 if (!m_model) return; | 1732 auto model = ModelById::getAs<NoteModel>(m_model); |
1733 if (!model) return; | |
1688 | 1734 |
1689 EventVector points = | 1735 EventVector points = |
1690 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1736 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1691 | 1737 |
1692 for (Event p: points) { | 1738 for (Event p: points) { |
1693 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); | 1739 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); |
1694 } | 1740 } |
1695 } | 1741 } |
1696 | 1742 |
1697 bool | 1743 bool |
1698 FlexiNoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /*frameOffset */, bool /* interactive */) | 1744 FlexiNoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /*frameOffset */, bool /* interactive */) |
1699 { | 1745 { |
1700 if (!m_model) return false; | 1746 auto model = ModelById::getAs<NoteModel>(m_model); |
1747 if (!model) return false; | |
1701 | 1748 |
1702 const EventVector &points = from.getPoints(); | 1749 const EventVector &points = from.getPoints(); |
1703 | 1750 |
1704 bool realign = false; | 1751 bool realign = false; |
1705 | 1752 |
1718 if (button == QMessageBox::Yes) { | 1765 if (button == QMessageBox::Yes) { |
1719 realign = true; | 1766 realign = true; |
1720 } | 1767 } |
1721 } | 1768 } |
1722 | 1769 |
1723 ChangeEventsCommand *command = | 1770 auto command = new ChangeEventsCommand(m_model.untyped, tr("Paste")); |
1724 new ChangeEventsCommand(m_model, tr("Paste")); | |
1725 | 1771 |
1726 for (EventVector::const_iterator i = points.begin(); | 1772 for (EventVector::const_iterator i = points.begin(); |
1727 i != points.end(); ++i) { | 1773 i != points.end(); ++i) { |
1728 | 1774 |
1729 sv_frame_t frame = 0; | 1775 sv_frame_t frame = 0; |
1743 } | 1789 } |
1744 | 1790 |
1745 Event p = *i; | 1791 Event p = *i; |
1746 Event newPoint = p; | 1792 Event newPoint = p; |
1747 if (!p.hasValue()) { | 1793 if (!p.hasValue()) { |
1748 newPoint = newPoint.withValue((m_model->getValueMinimum() + | 1794 newPoint = newPoint.withValue((model->getValueMinimum() + |
1749 m_model->getValueMaximum()) / 2); | 1795 model->getValueMaximum()) / 2); |
1750 } | 1796 } |
1751 if (!p.hasDuration()) { | 1797 if (!p.hasDuration()) { |
1752 sv_frame_t nextFrame = frame; | 1798 sv_frame_t nextFrame = frame; |
1753 EventVector::const_iterator j = i; | 1799 EventVector::const_iterator j = i; |
1754 for (; j != points.end(); ++j) { | 1800 for (; j != points.end(); ++j) { |
1756 } | 1802 } |
1757 if (j != points.end()) { | 1803 if (j != points.end()) { |
1758 nextFrame = j->getFrame(); | 1804 nextFrame = j->getFrame(); |
1759 } | 1805 } |
1760 if (nextFrame == frame) { | 1806 if (nextFrame == frame) { |
1761 newPoint = newPoint.withDuration(m_model->getResolution()); | 1807 newPoint = newPoint.withDuration(model->getResolution()); |
1762 } else { | 1808 } else { |
1763 newPoint = newPoint.withDuration(nextFrame - frame); | 1809 newPoint = newPoint.withDuration(nextFrame - frame); |
1764 } | 1810 } |
1765 } | 1811 } |
1766 | 1812 |
1787 Event p = *i; | 1833 Event p = *i; |
1788 | 1834 |
1789 if (lrintf(p.getValue()) == pitch) { | 1835 if (lrintf(p.getValue()) == pitch) { |
1790 m_pendingNoteOns.erase(i); | 1836 m_pendingNoteOns.erase(i); |
1791 Event note = p.withDuration(frame - p.getFrame()); | 1837 Event note = p.withDuration(frame - p.getFrame()); |
1792 if (m_model) { | 1838 auto c = new ChangeEventsCommand |
1793 ChangeEventsCommand *c = new ChangeEventsCommand | 1839 (m_model.untyped, tr("Record Note")); |
1794 (m_model, tr("Record Note")); | 1840 c->add(note); |
1795 c->add(note); | 1841 // execute and bundle: |
1796 // execute and bundle: | 1842 CommandHistory::getInstance()->addCommand(c, true, true); |
1797 CommandHistory::getInstance()->addCommand(c, true, true); | |
1798 } | |
1799 break; | 1843 break; |
1800 } | 1844 } |
1801 } | 1845 } |
1802 } | 1846 } |
1803 | 1847 |
1838 } | 1882 } |
1839 | 1883 |
1840 void | 1884 void |
1841 FlexiNoteLayer::setVerticalRangeToNoteRange(LayerGeometryProvider *v) | 1885 FlexiNoteLayer::setVerticalRangeToNoteRange(LayerGeometryProvider *v) |
1842 { | 1886 { |
1887 auto model = ModelById::getAs<NoteModel>(m_model); | |
1888 if (!model) return; | |
1889 | |
1843 double minf = std::numeric_limits<double>::max(); | 1890 double minf = std::numeric_limits<double>::max(); |
1844 double maxf = 0; | 1891 double maxf = 0; |
1845 bool hasNotes = 0; | 1892 bool hasNotes = 0; |
1846 EventVector allPoints = m_model->getAllEvents(); | 1893 EventVector allPoints = model->getAllEvents(); |
1847 for (EventVector::const_iterator i = allPoints.begin(); | 1894 for (EventVector::const_iterator i = allPoints.begin(); |
1848 i != allPoints.end(); ++i) { | 1895 i != allPoints.end(); ++i) { |
1849 hasNotes = 1; | 1896 hasNotes = 1; |
1850 Event note = *i; | 1897 Event note = *i; |
1851 if (note.getValue() < minf) minf = note.getValue(); | 1898 if (note.getValue() < minf) minf = note.getValue(); |