comparison layer/NoteLayer.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
46 46
47 //#define DEBUG_NOTE_LAYER 1 47 //#define DEBUG_NOTE_LAYER 1
48 48
49 NoteLayer::NoteLayer() : 49 NoteLayer::NoteLayer() :
50 SingleColourLayer(), 50 SingleColourLayer(),
51 m_model(nullptr),
52 m_editing(false), 51 m_editing(false),
53 m_dragPointX(0), 52 m_dragPointX(0),
54 m_dragPointY(0), 53 m_dragPointY(0),
55 m_dragStartX(0), 54 m_dragStartX(0),
56 m_dragStartY(0), 55 m_dragStartY(0),
63 m_scaleMaximum(0) 62 m_scaleMaximum(0)
64 { 63 {
65 SVDEBUG << "constructed NoteLayer" << endl; 64 SVDEBUG << "constructed NoteLayer" << endl;
66 } 65 }
67 66
68 void 67 int
69 NoteLayer::setModel(NoteModel *model) 68 NoteLayer::getCompletion(LayerGeometryProvider *) const
70 { 69 {
71 if (m_model == model) return; 70 auto model = ModelById::get(m_model);
72 m_model = model; 71 if (model) return model->getCompletion();
73 72 else return 0;
74 connectSignals(m_model); 73 }
75 74
76 // SVDEBUG << "NoteLayer::setModel(" << model << ")" << endl; 75 void
77 76 NoteLayer::setModel(ModelId modelId)
77 {
78 auto newModel = ModelById::getAs<NoteModel>(modelId);
79
80 if (!modelId.isNone() && !newModel) {
81 throw std::logic_error("Not a NoteModel");
82 }
83
84 if (m_model == modelId) return;
85 m_model = modelId;
86
87 if (newModel) {
88 connectSignals(m_model);
89 }
90
78 m_scaleMinimum = 0; 91 m_scaleMinimum = 0;
79 m_scaleMaximum = 0; 92 m_scaleMaximum = 0;
80 93
81 emit modelReplaced(); 94 emit modelReplaced();
82 } 95 }
116 } 129 }
117 130
118 QString 131 QString
119 NoteLayer::getScaleUnits() const 132 NoteLayer::getScaleUnits() const
120 { 133 {
121 if (m_model) return m_model->getScaleUnits(); 134 auto model = ModelById::getAs<NoteModel>(m_model);
135 if (model) return model->getScaleUnits();
122 else return ""; 136 else return "";
123 } 137 }
124 138
125 int 139 int
126 NoteLayer::getPropertyRangeAndValue(const PropertyName &name, 140 NoteLayer::getPropertyRangeAndValue(const PropertyName &name,
137 val = int(m_verticalScale); 151 val = int(m_verticalScale);
138 152
139 } else if (name == "Scale Units") { 153 } else if (name == "Scale Units") {
140 154
141 if (deflt) *deflt = 0; 155 if (deflt) *deflt = 0;
142 if (m_model) { 156 auto model = ModelById::getAs<NoteModel>(m_model);
157 if (model) {
143 val = UnitDatabase::getInstance()->getUnitId 158 val = UnitDatabase::getInstance()->getUnitId
144 (getScaleUnits()); 159 (model->getScaleUnits());
145 } 160 }
146 161
147 } else { 162 } else {
148 163
149 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt); 164 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt);
172 NoteLayer::setProperty(const PropertyName &name, int value) 187 NoteLayer::setProperty(const PropertyName &name, int value)
173 { 188 {
174 if (name == "Vertical Scale") { 189 if (name == "Vertical Scale") {
175 setVerticalScale(VerticalScale(value)); 190 setVerticalScale(VerticalScale(value));
176 } else if (name == "Scale Units") { 191 } else if (name == "Scale Units") {
177 if (m_model) { 192 auto model = ModelById::getAs<NoteModel>(m_model);
178 m_model->setScaleUnits 193 if (model) {
194 model->setScaleUnits
179 (UnitDatabase::getInstance()->getUnitById(value)); 195 (UnitDatabase::getInstance()->getUnitById(value));
180 emit modelChanged(); 196 emit modelChanged(m_model);
181 } 197 }
182 } else { 198 } else {
183 return SingleColourLayer::setProperty(name, value); 199 return SingleColourLayer::setProperty(name, value);
184 } 200 }
185 } 201 }
212 228
213 bool 229 bool
214 NoteLayer::getValueExtents(double &min, double &max, 230 NoteLayer::getValueExtents(double &min, double &max,
215 bool &logarithmic, QString &unit) const 231 bool &logarithmic, QString &unit) const
216 { 232 {
217 if (!m_model) return false; 233 auto model = ModelById::getAs<NoteModel>(m_model);
218 min = m_model->getValueMinimum(); 234 if (!model) return false;
219 max = m_model->getValueMaximum(); 235 min = model->getValueMinimum();
236 max = model->getValueMaximum();
220 237
221 if (shouldConvertMIDIToHz()) { 238 if (shouldConvertMIDIToHz()) {
222 unit = "Hz"; 239 unit = "Hz";
223 min = Pitch::getFrequencyForPitch(int(lrint(min))); 240 min = Pitch::getFrequencyForPitch(int(lrint(min)));
224 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); 241 max = Pitch::getFrequencyForPitch(int(lrint(max + 1)));
225 } else unit = getScaleUnits(); 242 } else unit = getScaleUnits();
226 243
227 if (m_verticalScale == MIDIRangeScale || 244 if (m_verticalScale == MIDIRangeScale ||
228 m_verticalScale == LogScale) logarithmic = true; 245 m_verticalScale == LogScale) {
246 logarithmic = true;
247 }
229 248
230 return true; 249 return true;
231 } 250 }
232 251
233 bool 252 bool
234 NoteLayer::getDisplayExtents(double &min, double &max) const 253 NoteLayer::getDisplayExtents(double &min, double &max) const
235 { 254 {
236 if (!m_model || shouldAutoAlign()) return false; 255 auto model = ModelById::getAs<NoteModel>(m_model);
256 if (!model || shouldAutoAlign()) return false;
237 257
238 if (m_verticalScale == MIDIRangeScale) { 258 if (m_verticalScale == MIDIRangeScale) {
239 min = Pitch::getFrequencyForPitch(0); 259 min = Pitch::getFrequencyForPitch(0);
240 max = Pitch::getFrequencyForPitch(127); 260 max = Pitch::getFrequencyForPitch(127);
241 return true; 261 return true;
242 } 262 }
243 263
244 if (m_scaleMinimum == m_scaleMaximum) { 264 if (m_scaleMinimum == m_scaleMaximum) {
245 min = m_model->getValueMinimum(); 265 min = model->getValueMinimum();
246 max = m_model->getValueMaximum(); 266 max = model->getValueMaximum();
247 } else { 267 } else {
248 min = m_scaleMinimum; 268 min = m_scaleMinimum;
249 max = m_scaleMaximum; 269 max = m_scaleMaximum;
250 } 270 }
251 271
262 } 282 }
263 283
264 bool 284 bool
265 NoteLayer::setDisplayExtents(double min, double max) 285 NoteLayer::setDisplayExtents(double min, double max)
266 { 286 {
267 if (!m_model) return false; 287 if (m_model.isNone()) return false;
268 288
269 if (min == max) { 289 if (min == max) {
270 if (min == 0.f) { 290 if (min == 0.f) {
271 max = 1.f; 291 max = 1.f;
272 } else { 292 } else {
286 } 306 }
287 307
288 int 308 int
289 NoteLayer::getVerticalZoomSteps(int &defaultStep) const 309 NoteLayer::getVerticalZoomSteps(int &defaultStep) const
290 { 310 {
291 if (shouldAutoAlign()) return 0; 311 if (shouldAutoAlign() || m_model.isNone()) return 0;
292 if (!m_model) return 0;
293
294 defaultStep = 0; 312 defaultStep = 0;
295 return 100; 313 return 100;
296 } 314 }
297 315
298 int 316 int
299 NoteLayer::getCurrentVerticalZoomStep() const 317 NoteLayer::getCurrentVerticalZoomStep() const
300 { 318 {
301 if (shouldAutoAlign()) return 0; 319 if (shouldAutoAlign() || m_model.isNone()) return 0;
302 if (!m_model) return 0;
303 320
304 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); 321 RangeMapper *mapper = getNewVerticalZoomRangeMapper();
305 if (!mapper) return 0; 322 if (!mapper) return 0;
306 323
307 double dmin, dmax; 324 double dmin, dmax;
317 //!!! lots of duplication with TimeValueLayer 334 //!!! lots of duplication with TimeValueLayer
318 335
319 void 336 void
320 NoteLayer::setVerticalZoomStep(int step) 337 NoteLayer::setVerticalZoomStep(int step)
321 { 338 {
322 if (shouldAutoAlign()) return; 339 if (shouldAutoAlign() || m_model.isNone()) return;
323 if (!m_model) return;
324 340
325 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); 341 RangeMapper *mapper = getNewVerticalZoomRangeMapper();
326 if (!mapper) return; 342 if (!mapper) return;
327 343
328 double min, max; 344 double min, max;
368 } 384 }
369 385
370 RangeMapper * 386 RangeMapper *
371 NoteLayer::getNewVerticalZoomRangeMapper() const 387 NoteLayer::getNewVerticalZoomRangeMapper() const
372 { 388 {
373 if (!m_model) return nullptr; 389 if (m_model.isNone()) return nullptr;
374 390
375 RangeMapper *mapper; 391 RangeMapper *mapper;
376 392
377 double min, max; 393 double min, max;
378 bool logarithmic; 394 bool logarithmic;
391 } 407 }
392 408
393 EventVector 409 EventVector
394 NoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const 410 NoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const
395 { 411 {
396 if (!m_model) return {}; 412 auto model = ModelById::getAs<NoteModel>(m_model);
413 if (!model) return {};
397 414
398 sv_frame_t frame = v->getFrameForX(x); 415 sv_frame_t frame = v->getFrameForX(x);
399 416
400 EventVector local = m_model->getEventsCovering(frame); 417 EventVector local = model->getEventsCovering(frame);
401 if (!local.empty()) return local; 418 if (!local.empty()) return local;
402 419
403 int fuzz = ViewManager::scalePixelSize(2); 420 int fuzz = ViewManager::scalePixelSize(2);
404 sv_frame_t start = v->getFrameForX(x - fuzz); 421 sv_frame_t start = v->getFrameForX(x - fuzz);
405 sv_frame_t end = v->getFrameForX(x + fuzz); 422 sv_frame_t end = v->getFrameForX(x + fuzz);
406 423
407 local = m_model->getEventsStartingWithin(frame, end - frame); 424 local = model->getEventsStartingWithin(frame, end - frame);
408 if (!local.empty()) return local; 425 if (!local.empty()) return local;
409 426
410 local = m_model->getEventsSpanning(start, frame - start); 427 local = model->getEventsSpanning(start, frame - start);
411 if (!local.empty()) return local; 428 if (!local.empty()) return local;
412 429
413 return {}; 430 return {};
414 } 431 }
415 432
416 bool 433 bool
417 NoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const 434 NoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const
418 { 435 {
419 if (!m_model) return false; 436 auto model = ModelById::getAs<NoteModel>(m_model);
437 if (!model) return false;
420 438
421 sv_frame_t frame = v->getFrameForX(x); 439 sv_frame_t frame = v->getFrameForX(x);
422 440
423 EventVector onPoints = m_model->getEventsCovering(frame); 441 EventVector onPoints = model->getEventsCovering(frame);
424 if (onPoints.empty()) return false; 442 if (onPoints.empty()) return false;
425 443
426 int nearestDistance = -1; 444 int nearestDistance = -1;
427 for (const auto &p: onPoints) { 445 for (const auto &p: onPoints) {
428 int distance = getYForValue(v, p.getValue()) - y; 446 int distance = getYForValue(v, p.getValue()) - y;
439 QString 457 QString
440 NoteLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const 458 NoteLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
441 { 459 {
442 int x = pos.x(); 460 int x = pos.x();
443 461
444 if (!m_model || !m_model->getSampleRate()) return ""; 462 auto model = ModelById::getAs<NoteModel>(m_model);
463 if (!model || !model->getSampleRate()) return "";
445 464
446 EventVector points = getLocalPoints(v, x); 465 EventVector points = getLocalPoints(v, x);
447 466
448 if (points.empty()) { 467 if (points.empty()) {
449 if (!m_model->isReady()) { 468 if (!model->isReady()) {
450 return tr("In progress"); 469 return tr("In progress");
451 } else { 470 } else {
452 return tr("No local points"); 471 return tr("No local points");
453 } 472 }
454 } 473 }
459 for (i = points.begin(); i != points.end(); ++i) { 478 for (i = points.begin(); i != points.end(); ++i) {
460 479
461 int y = getYForValue(v, i->getValue()); 480 int y = getYForValue(v, i->getValue());
462 int h = 3; 481 int h = 3;
463 482
464 if (m_model->getValueQuantization() != 0.0) { 483 if (model->getValueQuantization() != 0.0) {
465 h = y - getYForValue 484 h = y - getYForValue
466 (v, i->getValue() + m_model->getValueQuantization()); 485 (v, i->getValue() + model->getValueQuantization());
467 if (h < 3) h = 3; 486 if (h < 3) h = 3;
468 } 487 }
469 488
470 if (pos.y() >= y - h && pos.y() <= y) { 489 if (pos.y() >= y - h && pos.y() <= y) {
471 note = *i; 490 note = *i;
474 } 493 }
475 494
476 if (i == points.end()) return tr("No local points"); 495 if (i == points.end()) return tr("No local points");
477 496
478 RealTime rt = RealTime::frame2RealTime(note.getFrame(), 497 RealTime rt = RealTime::frame2RealTime(note.getFrame(),
479 m_model->getSampleRate()); 498 model->getSampleRate());
480 RealTime rd = RealTime::frame2RealTime(note.getDuration(), 499 RealTime rd = RealTime::frame2RealTime(note.getDuration(),
481 m_model->getSampleRate()); 500 model->getSampleRate());
482 501
483 QString pitchText; 502 QString pitchText;
484 503
485 float value = note.getValue(); 504 float value = note.getValue();
486 505
528 bool 547 bool
529 NoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, 548 NoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
530 int &resolution, 549 int &resolution,
531 SnapType snap) const 550 SnapType snap) const
532 { 551 {
533 if (!m_model) { 552 auto model = ModelById::getAs<NoteModel>(m_model);
553 if (!model) {
534 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 554 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
535 } 555 }
536 556
537 // SnapLeft / SnapRight: return frame of nearest feature in that 557 // SnapLeft / SnapRight: return frame of nearest feature in that
538 // direction no matter how far away 558 // direction no matter how far away
539 // 559 //
540 // SnapNeighbouring: return frame of feature that would be used in 560 // SnapNeighbouring: return frame of feature that would be used in
541 // an editing operation, i.e. closest feature in either direction 561 // an editing operation, i.e. closest feature in either direction
542 // but only if it is "close enough" 562 // but only if it is "close enough"
543 563
544 resolution = m_model->getResolution(); 564 resolution = model->getResolution();
545 565
546 if (snap == SnapNeighbouring) { 566 if (snap == SnapNeighbouring) {
547 EventVector points = getLocalPoints(v, v->getXForFrame(frame)); 567 EventVector points = getLocalPoints(v, v->getXForFrame(frame));
548 if (points.empty()) return false; 568 if (points.empty()) return false;
549 frame = points.begin()->getFrame(); 569 frame = points.begin()->getFrame();
550 return true; 570 return true;
551 } 571 }
552 572
553 Event e; 573 Event e;
554 if (m_model->getNearestEventMatching 574 if (model->getNearestEventMatching
555 (frame, 575 (frame,
556 [](Event) { return true; }, 576 [](Event) { return true; },
557 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward, 577 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward,
558 e)) { 578 e)) {
559 frame = e.getFrame(); 579 frame = e.getFrame();
568 { 588 {
569 min = 0.0; 589 min = 0.0;
570 max = 0.0; 590 max = 0.0;
571 log = false; 591 log = false;
572 592
593 auto model = ModelById::getAs<NoteModel>(m_model);
594 if (!model) return;
595
573 QString queryUnits; 596 QString queryUnits;
574 if (shouldConvertMIDIToHz()) queryUnits = "Hz"; 597 if (shouldConvertMIDIToHz()) queryUnits = "Hz";
575 else queryUnits = getScaleUnits(); 598 else queryUnits = getScaleUnits();
576 599
577 if (shouldAutoAlign()) { 600 if (shouldAutoAlign()) {
578 601
579 if (!v->getValueExtents(queryUnits, min, max, log)) { 602 if (!v->getValueExtents(queryUnits, min, max, log)) {
580 603
581 min = m_model->getValueMinimum(); 604 min = model->getValueMinimum();
582 max = m_model->getValueMaximum(); 605 max = model->getValueMaximum();
583 606
584 if (shouldConvertMIDIToHz()) { 607 if (shouldConvertMIDIToHz()) {
585 min = Pitch::getFrequencyForPitch(int(lrint(min))); 608 min = Pitch::getFrequencyForPitch(int(lrint(min)));
586 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); 609 max = Pitch::getFrequencyForPitch(int(lrint(max + 1)));
587 } 610 }
679 } 702 }
680 703
681 bool 704 bool
682 NoteLayer::shouldAutoAlign() const 705 NoteLayer::shouldAutoAlign() const
683 { 706 {
684 if (!m_model) return false; 707 if (m_model.isNone()) return false;
685 return (m_verticalScale == AutoAlignScale); 708 return (m_verticalScale == AutoAlignScale);
686 } 709 }
687 710
688 void 711 void
689 NoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const 712 NoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const
690 { 713 {
691 if (!m_model || !m_model->isOK()) return; 714 auto model = ModelById::getAs<NoteModel>(m_model);
692 715 if (!model || !model->isOK()) return;
693 sv_samplerate_t sampleRate = m_model->getSampleRate(); 716
717 sv_samplerate_t sampleRate = model->getSampleRate();
694 if (!sampleRate) return; 718 if (!sampleRate) return;
695 719
696 // Profiler profiler("NoteLayer::paint", true); 720 // Profiler profiler("NoteLayer::paint", true);
697 721
698 int x0 = rect.left(), x1 = rect.right(); 722 int x0 = rect.left(), x1 = rect.right();
699 sv_frame_t frame0 = v->getFrameForX(x0); 723 sv_frame_t frame0 = v->getFrameForX(x0);
700 sv_frame_t frame1 = v->getFrameForX(x1); 724 sv_frame_t frame1 = v->getFrameForX(x1);
701 725
702 EventVector points(m_model->getEventsSpanning(frame0, frame1 - frame0)); 726 EventVector points(model->getEventsSpanning(frame0, frame1 - frame0));
703 if (points.empty()) return; 727 if (points.empty()) return;
704 728
705 paint.setPen(getBaseQColor()); 729 paint.setPen(getBaseQColor());
706 730
707 QColor brushColour(getBaseQColor()); 731 QColor brushColour(getBaseQColor());
708 brushColour.setAlpha(80); 732 brushColour.setAlpha(80);
709 733
710 // SVDEBUG << "NoteLayer::paint: resolution is " 734 // SVDEBUG << "NoteLayer::paint: resolution is "
711 // << m_model->getResolution() << " frames" << endl; 735 // << model->getResolution() << " frames" << endl;
712 736
713 double min = m_model->getValueMinimum(); 737 double min = model->getValueMinimum();
714 double max = m_model->getValueMaximum(); 738 double max = model->getValueMaximum();
715 if (max == min) max = min + 1.0; 739 if (max == min) max = min + 1.0;
716 740
717 QPoint localPos; 741 QPoint localPos;
718 Event illuminatePoint; 742 Event illuminatePoint;
719 bool shouldIlluminate = false; 743 bool shouldIlluminate = false;
737 int x = v->getXForFrame(p.getFrame()); 761 int x = v->getXForFrame(p.getFrame());
738 int y = getYForValue(v, p.getValue()); 762 int y = getYForValue(v, p.getValue());
739 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; 763 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x;
740 int h = 3; 764 int h = 3;
741 765
742 if (m_model->getValueQuantization() != 0.0) { 766 if (model->getValueQuantization() != 0.0) {
743 h = y - getYForValue(v, p.getValue() + m_model->getValueQuantization()); 767 h = y - getYForValue(v, p.getValue() + model->getValueQuantization());
744 if (h < 3) h = 3; 768 if (h < 3) h = 3;
745 } 769 }
746 770
747 if (w < 1) w = 1; 771 if (w < 1) w = 1;
748 paint.setPen(getBaseQColor()); 772 paint.setPen(getBaseQColor());
750 774
751 if (shouldIlluminate && illuminatePoint == p) { 775 if (shouldIlluminate && illuminatePoint == p) {
752 776
753 paint.setPen(v->getForeground()); 777 paint.setPen(v->getForeground());
754 paint.setBrush(v->getForeground()); 778 paint.setBrush(v->getForeground());
779
780 // Qt 5.13 deprecates QFontMetrics::width(), but its suggested
781 // replacement (horizontalAdvance) was only added in Qt 5.11
782 // which is too new for us
783 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
755 784
756 QString vlabel = QString("%1%2").arg(p.getValue()).arg(getScaleUnits()); 785 QString vlabel = QString("%1%2").arg(p.getValue()).arg(getScaleUnits());
757 PaintAssistant::drawVisibleText(v, paint, 786 PaintAssistant::drawVisibleText(v, paint,
758 x - paint.fontMetrics().width(vlabel) - 2, 787 x - paint.fontMetrics().width(vlabel) - 2,
759 y + paint.fontMetrics().height()/2 788 y + paint.fontMetrics().height()/2
760 - paint.fontMetrics().descent(), 789 - paint.fontMetrics().descent(),
761 vlabel, PaintAssistant::OutlinedText); 790 vlabel, PaintAssistant::OutlinedText);
762 791
763 QString hlabel = RealTime::frame2RealTime 792 QString hlabel = RealTime::frame2RealTime
764 (p.getFrame(), m_model->getSampleRate()).toText(true).c_str(); 793 (p.getFrame(), model->getSampleRate()).toText(true).c_str();
765 PaintAssistant::drawVisibleText(v, paint, 794 PaintAssistant::drawVisibleText(v, paint,
766 x, 795 x,
767 y - h/2 - paint.fontMetrics().descent() - 2, 796 y - h/2 - paint.fontMetrics().descent() - 2,
768 hlabel, PaintAssistant::OutlinedText); 797 hlabel, PaintAssistant::OutlinedText);
769 } 798 }
775 } 804 }
776 805
777 int 806 int
778 NoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const 807 NoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const
779 { 808 {
780 if (!m_model) { 809 if (m_model.isNone()) {
781 return 0; 810 return 0;
782 } 811 }
783 812
784 if (shouldAutoAlign() && !valueExtentsMatchMine(v)) { 813 if (shouldAutoAlign() && !valueExtentsMatchMine(v)) {
785 return 0; 814 return 0;
793 } 822 }
794 823
795 void 824 void
796 NoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const 825 NoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const
797 { 826 {
798 if (!m_model || m_model->isEmpty()) return; 827 auto model = ModelById::getAs<NoteModel>(m_model);
828 if (!model || model->isEmpty()) return;
799 829
800 QString unit; 830 QString unit;
801 double min, max; 831 double min, max;
802 bool logarithmic; 832 bool logarithmic;
803 833
833 void 863 void
834 NoteLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) 864 NoteLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e)
835 { 865 {
836 // SVDEBUG << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; 866 // SVDEBUG << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
837 867
838 if (!m_model) return; 868 auto model = ModelById::getAs<NoteModel>(m_model);
869 if (!model) return;
839 870
840 sv_frame_t frame = v->getFrameForX(e->x()); 871 sv_frame_t frame = v->getFrameForX(e->x());
841 if (frame < 0) frame = 0; 872 if (frame < 0) frame = 0;
842 frame = frame / m_model->getResolution() * m_model->getResolution(); 873 frame = frame / model->getResolution() * model->getResolution();
843 874
844 double value = getValueForY(v, e->y()); 875 double value = getValueForY(v, e->y());
845 876
846 m_editingPoint = Event(frame, float(value), 0, 0.8f, tr("New Point")); 877 m_editingPoint = Event(frame, float(value), 0, 0.8f, tr("New Point"));
847 m_originalPoint = m_editingPoint; 878 m_originalPoint = m_editingPoint;
848 879
849 if (m_editingCommand) finish(m_editingCommand); 880 if (m_editingCommand) finish(m_editingCommand);
850 m_editingCommand = new ChangeEventsCommand(m_model, tr("Draw Point")); 881 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Draw Point"));
851 m_editingCommand->add(m_editingPoint); 882 m_editingCommand->add(m_editingPoint);
852 883
853 m_editing = true; 884 m_editing = true;
854 } 885 }
855 886
856 void 887 void
857 NoteLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) 888 NoteLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e)
858 { 889 {
859 // SVDEBUG << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; 890 // SVDEBUG << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
860 891
861 if (!m_model || !m_editing) return; 892 auto model = ModelById::getAs<NoteModel>(m_model);
893 if (!model || !m_editing) return;
862 894
863 sv_frame_t frame = v->getFrameForX(e->x()); 895 sv_frame_t frame = v->getFrameForX(e->x());
864 if (frame < 0) frame = 0; 896 if (frame < 0) frame = 0;
865 frame = frame / m_model->getResolution() * m_model->getResolution(); 897 frame = frame / model->getResolution() * model->getResolution();
866 898
867 double newValue = getValueForY(v, e->y()); 899 double newValue = getValueForY(v, e->y());
868 900
869 sv_frame_t newFrame = m_editingPoint.getFrame(); 901 sv_frame_t newFrame = m_editingPoint.getFrame();
870 sv_frame_t newDuration = frame - newFrame; 902 sv_frame_t newDuration = frame - newFrame;
885 917
886 void 918 void
887 NoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) 919 NoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *)
888 { 920 {
889 // SVDEBUG << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; 921 // SVDEBUG << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl;
890 if (!m_model || !m_editing) return; 922 auto model = ModelById::getAs<NoteModel>(m_model);
923 if (!model || !m_editing) return;
891 finish(m_editingCommand); 924 finish(m_editingCommand);
892 m_editingCommand = nullptr; 925 m_editingCommand = nullptr;
893 m_editing = false; 926 m_editing = false;
894 } 927 }
895 928
896 void 929 void
897 NoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) 930 NoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e)
898 { 931 {
899 if (!m_model) return; 932 auto model = ModelById::getAs<NoteModel>(m_model);
933 if (!model) return;
900 934
901 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; 935 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
902 936
903 if (m_editingCommand) { 937 if (m_editingCommand) {
904 finish(m_editingCommand); 938 finish(m_editingCommand);
914 } 948 }
915 949
916 void 950 void
917 NoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) 951 NoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e)
918 { 952 {
919 if (!m_model || !m_editing) return; 953 auto model = ModelById::getAs<NoteModel>(m_model);
954 if (!model || !m_editing) return;
920 955
921 m_editing = false; 956 m_editing = false;
922 957
923 Event p(0); 958 Event p(0);
924 if (!getPointToDrag(v, e->x(), e->y(), p)) return; 959 if (!getPointToDrag(v, e->x(), e->y(), p)) return;
925 if (p.getFrame() != m_editingPoint.getFrame() || 960 if (p.getFrame() != m_editingPoint.getFrame() ||
926 p.getValue() != m_editingPoint.getValue()) return; 961 p.getValue() != m_editingPoint.getValue()) return;
927 962
928 m_editingCommand = new ChangeEventsCommand(m_model, tr("Erase Point")); 963 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Erase Point"));
929 964
930 m_editingCommand->remove(m_editingPoint); 965 m_editingCommand->remove(m_editingPoint);
931 966
932 finish(m_editingCommand); 967 finish(m_editingCommand);
933 m_editingCommand = nullptr; 968 m_editingCommand = nullptr;
937 void 972 void
938 NoteLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) 973 NoteLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e)
939 { 974 {
940 // SVDEBUG << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; 975 // SVDEBUG << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
941 976
942 if (!m_model) return; 977 auto model = ModelById::getAs<NoteModel>(m_model);
978 if (!model) return;
943 979
944 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; 980 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
945 m_originalPoint = m_editingPoint; 981 m_originalPoint = m_editingPoint;
946 982
947 m_dragPointX = v->getXForFrame(m_editingPoint.getFrame()); 983 m_dragPointX = v->getXForFrame(m_editingPoint.getFrame());
960 void 996 void
961 NoteLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) 997 NoteLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e)
962 { 998 {
963 // SVDEBUG << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; 999 // SVDEBUG << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl;
964 1000
965 if (!m_model || !m_editing) return; 1001 auto model = ModelById::getAs<NoteModel>(m_model);
1002 if (!model || !m_editing) return;
966 1003
967 int xdist = e->x() - m_dragStartX; 1004 int xdist = e->x() - m_dragStartX;
968 int ydist = e->y() - m_dragStartY; 1005 int ydist = e->y() - m_dragStartY;
969 int newx = m_dragPointX + xdist; 1006 int newx = m_dragPointX + xdist;
970 int newy = m_dragPointY + ydist; 1007 int newy = m_dragPointY + ydist;
971 1008
972 sv_frame_t frame = v->getFrameForX(newx); 1009 sv_frame_t frame = v->getFrameForX(newx);
973 if (frame < 0) frame = 0; 1010 if (frame < 0) frame = 0;
974 frame = frame / m_model->getResolution() * m_model->getResolution(); 1011 frame = frame / model->getResolution() * model->getResolution();
975 1012
976 double value = getValueForY(v, newy); 1013 double value = getValueForY(v, newy);
977 1014
978 if (!m_editingCommand) { 1015 if (!m_editingCommand) {
979 m_editingCommand = new ChangeEventsCommand(m_model, 1016 m_editingCommand = new ChangeEventsCommand
980 tr("Drag Point")); 1017 (m_model.untyped, tr("Drag Point"));
981 } 1018 }
982 1019
983 m_editingCommand->remove(m_editingPoint); 1020 m_editingCommand->remove(m_editingPoint);
984 m_editingPoint = m_editingPoint 1021 m_editingPoint = m_editingPoint
985 .withFrame(frame) 1022 .withFrame(frame)
989 1026
990 void 1027 void
991 NoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) 1028 NoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *)
992 { 1029 {
993 // SVDEBUG << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; 1030 // SVDEBUG << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl;
994 if (!m_model || !m_editing) return; 1031 auto model = ModelById::getAs<NoteModel>(m_model);
1032 if (!model || !m_editing) return;
995 1033
996 if (m_editingCommand) { 1034 if (m_editingCommand) {
997 1035
998 QString newName = m_editingCommand->getName(); 1036 QString newName = m_editingCommand->getName();
999 1037
1016 } 1054 }
1017 1055
1018 bool 1056 bool
1019 NoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) 1057 NoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e)
1020 { 1058 {
1021 if (!m_model) return false; 1059 auto model = ModelById::getAs<NoteModel>(m_model);
1060 if (!model) return false;
1022 1061
1023 Event note(0); 1062 Event note(0);
1024 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; 1063 if (!getPointToDrag(v, e->x(), e->y(), note)) return false;
1025 1064
1026 // Event note = *points.begin(); 1065 // Event note = *points.begin();
1027 1066
1028 ItemEditDialog *dialog = new ItemEditDialog 1067 ItemEditDialog *dialog = new ItemEditDialog
1029 (m_model->getSampleRate(), 1068 (model->getSampleRate(),
1030 ItemEditDialog::ShowTime | 1069 ItemEditDialog::ShowTime |
1031 ItemEditDialog::ShowDuration | 1070 ItemEditDialog::ShowDuration |
1032 ItemEditDialog::ShowValue | 1071 ItemEditDialog::ShowValue |
1033 ItemEditDialog::ShowText, 1072 ItemEditDialog::ShowText,
1034 getScaleUnits()); 1073 getScaleUnits());
1048 .withValue(dialog->getValue()) 1087 .withValue(dialog->getValue())
1049 .withDuration(dialog->getFrameDuration()) 1088 .withDuration(dialog->getFrameDuration())
1050 .withLabel(dialog->getText()); 1089 .withLabel(dialog->getText());
1051 1090
1052 ChangeEventsCommand *command = new ChangeEventsCommand 1091 ChangeEventsCommand *command = new ChangeEventsCommand
1053 (m_model, tr("Edit Point")); 1092 (m_model.untyped, tr("Edit Point"));
1054 command->remove(note); 1093 command->remove(note);
1055 command->add(newNote); 1094 command->add(newNote);
1056 finish(command); 1095 finish(command);
1057 } 1096 }
1058 1097
1064 } 1103 }
1065 1104
1066 void 1105 void
1067 NoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame) 1106 NoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
1068 { 1107 {
1069 if (!m_model) return; 1108 auto model = ModelById::getAs<NoteModel>(m_model);
1109 if (!model) return;
1070 1110
1071 ChangeEventsCommand *command = 1111 ChangeEventsCommand *command =
1072 new ChangeEventsCommand(m_model, tr("Drag Selection")); 1112 new ChangeEventsCommand(m_model.untyped, tr("Drag Selection"));
1073 1113
1074 EventVector points = 1114 EventVector points =
1075 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 1115 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
1076 1116
1077 for (Event p: points) { 1117 for (Event p: points) {
1078 command->remove(p); 1118 command->remove(p);
1079 Event moved = p.withFrame(p.getFrame() + 1119 Event moved = p.withFrame(p.getFrame() +
1080 newStartFrame - s.getStartFrame()); 1120 newStartFrame - s.getStartFrame());
1085 } 1125 }
1086 1126
1087 void 1127 void
1088 NoteLayer::resizeSelection(Selection s, Selection newSize) 1128 NoteLayer::resizeSelection(Selection s, Selection newSize)
1089 { 1129 {
1090 if (!m_model || !s.getDuration()) return; 1130 auto model = ModelById::getAs<NoteModel>(m_model);
1131 if (!model || !s.getDuration()) return;
1091 1132
1092 ChangeEventsCommand *command = 1133 ChangeEventsCommand *command =
1093 new ChangeEventsCommand(m_model, tr("Resize Selection")); 1134 new ChangeEventsCommand(m_model.untyped, tr("Resize Selection"));
1094 1135
1095 EventVector points = 1136 EventVector points =
1096 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 1137 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
1097 1138
1098 double ratio = double(newSize.getDuration()) / double(s.getDuration()); 1139 double ratio = double(newSize.getDuration()) / double(s.getDuration());
1099 double oldStart = double(s.getStartFrame()); 1140 double oldStart = double(s.getStartFrame());
1100 double newStart = double(newSize.getStartFrame()); 1141 double newStart = double(newSize.getStartFrame());
1101 1142
1115 } 1156 }
1116 1157
1117 void 1158 void
1118 NoteLayer::deleteSelection(Selection s) 1159 NoteLayer::deleteSelection(Selection s)
1119 { 1160 {
1120 if (!m_model) return; 1161 auto model = ModelById::getAs<NoteModel>(m_model);
1162 if (!model) return;
1121 1163
1122 ChangeEventsCommand *command = 1164 ChangeEventsCommand *command =
1123 new ChangeEventsCommand(m_model, tr("Delete Selected Points")); 1165 new ChangeEventsCommand(m_model.untyped, tr("Delete Selected Points"));
1124 1166
1125 EventVector points = 1167 EventVector points =
1126 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 1168 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
1127 1169
1128 for (Event p: points) { 1170 for (Event p: points) {
1129 command->remove(p); 1171 command->remove(p);
1130 } 1172 }
1131 1173
1133 } 1175 }
1134 1176
1135 void 1177 void
1136 NoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) 1178 NoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to)
1137 { 1179 {
1138 if (!m_model) return; 1180 auto model = ModelById::getAs<NoteModel>(m_model);
1181 if (!model) return;
1139 1182
1140 EventVector points = 1183 EventVector points =
1141 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 1184 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
1142 1185
1143 for (Event p: points) { 1186 for (Event p: points) {
1144 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); 1187 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame())));
1145 } 1188 }
1146 } 1189 }
1147 1190
1148 bool 1191 bool
1149 NoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from, 1192 NoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from,
1150 sv_frame_t /* frameOffset */, bool /* interactive */) 1193 sv_frame_t /* frameOffset */, bool /* interactive */)
1151 { 1194 {
1152 if (!m_model) return false; 1195 auto model = ModelById::getAs<NoteModel>(m_model);
1196 if (!model) return false;
1153 1197
1154 const EventVector &points = from.getPoints(); 1198 const EventVector &points = from.getPoints();
1155 1199
1156 bool realign = false; 1200 bool realign = false;
1157 1201
1171 realign = true; 1215 realign = true;
1172 } 1216 }
1173 } 1217 }
1174 1218
1175 ChangeEventsCommand *command = 1219 ChangeEventsCommand *command =
1176 new ChangeEventsCommand(m_model, tr("Paste")); 1220 new ChangeEventsCommand(m_model.untyped, tr("Paste"));
1177 1221
1178 for (EventVector::const_iterator i = points.begin(); 1222 for (EventVector::const_iterator i = points.begin();
1179 i != points.end(); ++i) { 1223 i != points.end(); ++i) {
1180 1224
1181 sv_frame_t frame = 0; 1225 sv_frame_t frame = 0;
1195 } 1239 }
1196 1240
1197 Event p = *i; 1241 Event p = *i;
1198 Event newPoint = p; 1242 Event newPoint = p;
1199 if (!p.hasValue()) { 1243 if (!p.hasValue()) {
1200 newPoint = newPoint.withValue((m_model->getValueMinimum() + 1244 newPoint = newPoint.withValue((model->getValueMinimum() +
1201 m_model->getValueMaximum()) / 2); 1245 model->getValueMaximum()) / 2);
1202 } 1246 }
1203 if (!p.hasDuration()) { 1247 if (!p.hasDuration()) {
1204 sv_frame_t nextFrame = frame; 1248 sv_frame_t nextFrame = frame;
1205 EventVector::const_iterator j = i; 1249 EventVector::const_iterator j = i;
1206 for (; j != points.end(); ++j) { 1250 for (; j != points.end(); ++j) {
1208 } 1252 }
1209 if (j != points.end()) { 1253 if (j != points.end()) {
1210 nextFrame = j->getFrame(); 1254 nextFrame = j->getFrame();
1211 } 1255 }
1212 if (nextFrame == frame) { 1256 if (nextFrame == frame) {
1213 newPoint = newPoint.withDuration(m_model->getResolution()); 1257 newPoint = newPoint.withDuration(model->getResolution());
1214 } else { 1258 } else {
1215 newPoint = newPoint.withDuration(nextFrame - frame); 1259 newPoint = newPoint.withDuration(nextFrame - frame);
1216 } 1260 }
1217 } 1261 }
1218 1262
1231 } 1275 }
1232 1276
1233 void 1277 void
1234 NoteLayer::addNoteOff(sv_frame_t frame, int pitch) 1278 NoteLayer::addNoteOff(sv_frame_t frame, int pitch)
1235 { 1279 {
1280 auto model = ModelById::getAs<NoteModel>(m_model);
1281
1236 for (NoteSet::iterator i = m_pendingNoteOns.begin(); 1282 for (NoteSet::iterator i = m_pendingNoteOns.begin();
1237 i != m_pendingNoteOns.end(); ++i) { 1283 i != m_pendingNoteOns.end(); ++i) {
1238 1284
1239 Event p = *i; 1285 Event p = *i;
1240 1286
1241 if (lrintf(p.getValue()) == pitch) { 1287 if (lrintf(p.getValue()) == pitch) {
1242 m_pendingNoteOns.erase(i); 1288 m_pendingNoteOns.erase(i);
1243 Event note = p.withDuration(frame - p.getFrame()); 1289 Event note = p.withDuration(frame - p.getFrame());
1244 if (m_model) { 1290 if (model) {
1245 ChangeEventsCommand *c = new ChangeEventsCommand 1291 ChangeEventsCommand *c = new ChangeEventsCommand
1246 (m_model, tr("Record Note")); 1292 (m_model.untyped, tr("Record Note"));
1247 c->add(note); 1293 c->add(note);
1248 // execute and bundle: 1294 // execute and bundle:
1249 CommandHistory::getInstance()->addCommand(c, true, true); 1295 CommandHistory::getInstance()->addCommand(c, true, true);
1250 } 1296 }
1251 break; 1297 break;