Mercurial > hg > svgui
comparison layer/RegionLayer.cpp @ 1459:42c87368287c
Merge from branch single-point
author | Chris Cannam |
---|---|
date | Fri, 17 May 2019 10:02:52 +0100 |
parents | 5b9692768beb |
children | 696e569ff21b |
comparison
equal
deleted
inserted
replaced
1441:8d5bf4ab98ef | 1459:42c87368287c |
---|---|
259 m_distributionMap.clear(); | 259 m_distributionMap.clear(); |
260 if (!m_model) return; | 260 if (!m_model) return; |
261 | 261 |
262 // SVDEBUG << "RegionLayer::recalcSpacing" << endl; | 262 // SVDEBUG << "RegionLayer::recalcSpacing" << endl; |
263 | 263 |
264 for (RegionModel::PointList::const_iterator i = m_model->getPoints().begin(); | 264 EventVector allEvents = m_model->getAllEvents(); |
265 i != m_model->getPoints().end(); ++i) { | 265 for (const Event &e: allEvents) { |
266 m_distributionMap[i->value]++; | 266 m_distributionMap[e.getValue()]++; |
267 // SVDEBUG << "RegionLayer::recalcSpacing: value found: " << i->value << " (now have " << m_distributionMap[i->value] << " of this value)" << endl; | 267 // SVDEBUG << "RegionLayer::recalcSpacing: value found: " << e.getValue() << " (now have " << m_distributionMap[e.getValue()] << " of this value)" << endl; |
268 } | 268 } |
269 | 269 |
270 int n = 0; | 270 int n = 0; |
271 | 271 |
272 for (SpacingMap::const_iterator i = m_distributionMap.begin(); | 272 for (SpacingMap::const_iterator i = m_distributionMap.begin(); |
301 max = m_model->getValueMaximum(); | 301 max = m_model->getValueMaximum(); |
302 | 302 |
303 return true; | 303 return true; |
304 } | 304 } |
305 | 305 |
306 RegionModel::PointList | 306 EventVector |
307 RegionLayer::getLocalPoints(LayerGeometryProvider *v, int x) const | 307 RegionLayer::getLocalPoints(LayerGeometryProvider *v, int x) const |
308 { | 308 { |
309 if (!m_model) return RegionModel::PointList(); | 309 if (!m_model) return EventVector(); |
310 | 310 |
311 sv_frame_t frame = v->getFrameForX(x); | 311 sv_frame_t frame = v->getFrameForX(x); |
312 | 312 |
313 RegionModel::PointList onPoints = | 313 EventVector local = m_model->getEventsCovering(frame); |
314 m_model->getPoints(frame); | 314 if (!local.empty()) return local; |
315 | 315 |
316 if (!onPoints.empty()) { | 316 int fuzz = ViewManager::scalePixelSize(2); |
317 return onPoints; | 317 sv_frame_t start = v->getFrameForX(x - fuzz); |
318 } | 318 sv_frame_t end = v->getFrameForX(x + fuzz); |
319 | 319 |
320 RegionModel::PointList prevPoints = | 320 local = m_model->getEventsStartingWithin(frame, end - frame); |
321 m_model->getPreviousPoints(frame); | 321 if (!local.empty()) return local; |
322 RegionModel::PointList nextPoints = | 322 |
323 m_model->getNextPoints(frame); | 323 local = m_model->getEventsSpanning(start, frame - start); |
324 | 324 if (!local.empty()) return local; |
325 RegionModel::PointList usePoints = prevPoints; | 325 |
326 | 326 return {}; |
327 if (prevPoints.empty()) { | |
328 usePoints = nextPoints; | |
329 } else if (long(prevPoints.begin()->frame) < v->getStartFrame() && | |
330 !(nextPoints.begin()->frame > v->getEndFrame())) { | |
331 usePoints = nextPoints; | |
332 } else if (long(nextPoints.begin()->frame) - frame < | |
333 frame - long(prevPoints.begin()->frame)) { | |
334 usePoints = nextPoints; | |
335 } | |
336 | |
337 if (!usePoints.empty()) { | |
338 int fuzz = ViewManager::scalePixelSize(2); | |
339 int px = v->getXForFrame(usePoints.begin()->frame); | |
340 if ((px > x && px - x > fuzz) || | |
341 (px < x && x - px > fuzz + 1)) { | |
342 usePoints.clear(); | |
343 } | |
344 } | |
345 | |
346 return usePoints; | |
347 } | 327 } |
348 | 328 |
349 bool | 329 bool |
350 RegionLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, RegionModel::Point &p) const | 330 RegionLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const |
351 { | 331 { |
352 if (!m_model) return false; | 332 if (!m_model) return false; |
353 | 333 |
354 sv_frame_t frame = v->getFrameForX(x); | 334 sv_frame_t frame = v->getFrameForX(x); |
355 | 335 |
356 RegionModel::PointList onPoints = m_model->getPoints(frame); | 336 EventVector onPoints = m_model->getEventsCovering(frame); |
357 if (onPoints.empty()) return false; | 337 if (onPoints.empty()) return false; |
358 | 338 |
359 int nearestDistance = -1; | 339 int nearestDistance = -1; |
360 | 340 for (const auto &p: onPoints) { |
361 for (RegionModel::PointList::const_iterator i = onPoints.begin(); | 341 int distance = getYForValue(v, p.getValue()) - y; |
362 i != onPoints.end(); ++i) { | |
363 | |
364 int distance = getYForValue(v, (*i).value) - y; | |
365 if (distance < 0) distance = -distance; | 342 if (distance < 0) distance = -distance; |
366 if (nearestDistance == -1 || distance < nearestDistance) { | 343 if (nearestDistance == -1 || distance < nearestDistance) { |
367 nearestDistance = distance; | 344 nearestDistance = distance; |
368 p = *i; | 345 point = p; |
369 } | 346 } |
370 } | 347 } |
371 | 348 |
372 return true; | 349 return true; |
373 } | 350 } |
374 | 351 |
375 QString | 352 QString |
376 RegionLayer::getLabelPreceding(sv_frame_t frame) const | 353 RegionLayer::getLabelPreceding(sv_frame_t frame) const |
377 { | 354 { |
378 if (!m_model) return ""; | 355 if (!m_model) return ""; |
379 RegionModel::PointList points = m_model->getPreviousPoints(frame); | 356 EventVector points = m_model->getEventsStartingWithin |
380 for (RegionModel::PointList::const_iterator i = points.begin(); | 357 (m_model->getStartFrame(), frame - m_model->getStartFrame()); |
381 i != points.end(); ++i) { | 358 if (!points.empty()) { |
382 if (i->label != "") return i->label; | 359 for (auto i = points.rbegin(); i != points.rend(); ++i) { |
383 } | 360 if (i->getLabel() != QString()) { |
384 return ""; | 361 return i->getLabel(); |
362 } | |
363 } | |
364 } | |
365 return QString(); | |
385 } | 366 } |
386 | 367 |
387 QString | 368 QString |
388 RegionLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const | 369 RegionLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const |
389 { | 370 { |
390 int x = pos.x(); | 371 int x = pos.x(); |
391 | 372 |
392 if (!m_model || !m_model->getSampleRate()) return ""; | 373 if (!m_model || !m_model->getSampleRate()) return ""; |
393 | 374 |
394 RegionModel::PointList points = getLocalPoints(v, x); | 375 EventVector points = getLocalPoints(v, x); |
395 | 376 |
396 if (points.empty()) { | 377 if (points.empty()) { |
397 if (!m_model->isReady()) { | 378 if (!m_model->isReady()) { |
398 return tr("In progress"); | 379 return tr("In progress"); |
399 } else { | 380 } else { |
400 return tr("No local points"); | 381 return tr("No local points"); |
401 } | 382 } |
402 } | 383 } |
403 | 384 |
404 RegionRec region(0); | 385 Event region; |
405 RegionModel::PointList::iterator i; | 386 EventVector::iterator i; |
406 | 387 |
407 //!!! harmonise with whatever decision is made about point y | 388 //!!! harmonise with whatever decision is made about point y |
408 //!!! coords in paint method | 389 //!!! coords in paint method |
409 | 390 |
410 for (i = points.begin(); i != points.end(); ++i) { | 391 for (i = points.begin(); i != points.end(); ++i) { |
411 | 392 |
412 int y = getYForValue(v, i->value); | 393 int y = getYForValue(v, i->getValue()); |
413 int h = 3; | 394 int h = 3; |
414 | 395 |
415 if (m_model->getValueQuantization() != 0.0) { | 396 if (m_model->getValueQuantization() != 0.0) { |
416 h = y - getYForValue(v, i->value + m_model->getValueQuantization()); | 397 h = y - getYForValue |
398 (v, i->getValue() + m_model->getValueQuantization()); | |
417 if (h < 3) h = 3; | 399 if (h < 3) h = 3; |
418 } | 400 } |
419 | 401 |
420 if (pos.y() >= y - h && pos.y() <= y) { | 402 if (pos.y() >= y - h && pos.y() <= y) { |
421 region = *i; | 403 region = *i; |
423 } | 405 } |
424 } | 406 } |
425 | 407 |
426 if (i == points.end()) return tr("No local points"); | 408 if (i == points.end()) return tr("No local points"); |
427 | 409 |
428 RealTime rt = RealTime::frame2RealTime(region.frame, | 410 RealTime rt = RealTime::frame2RealTime(region.getFrame(), |
429 m_model->getSampleRate()); | 411 m_model->getSampleRate()); |
430 RealTime rd = RealTime::frame2RealTime(region.duration, | 412 RealTime rd = RealTime::frame2RealTime(region.getDuration(), |
431 m_model->getSampleRate()); | 413 m_model->getSampleRate()); |
432 | 414 |
433 QString valueText; | 415 QString valueText; |
434 | 416 |
435 valueText = tr("%1 %2").arg(region.value).arg(getScaleUnits()); | 417 valueText = tr("%1 %2").arg(region.getValue()).arg(getScaleUnits()); |
436 | 418 |
437 QString text; | 419 QString text; |
438 | 420 |
439 if (region.label == "") { | 421 if (region.getLabel() == "") { |
440 text = QString(tr("Time:\t%1\nValue:\t%2\nDuration:\t%3\nNo label")) | 422 text = QString(tr("Time:\t%1\nValue:\t%2\nDuration:\t%3\nNo label")) |
441 .arg(rt.toText(true).c_str()) | 423 .arg(rt.toText(true).c_str()) |
442 .arg(valueText) | 424 .arg(valueText) |
443 .arg(rd.toText(true).c_str()); | 425 .arg(rd.toText(true).c_str()); |
444 } else { | 426 } else { |
445 text = QString(tr("Time:\t%1\nValue:\t%2\nDuration:\t%3\nLabel:\t%4")) | 427 text = QString(tr("Time:\t%1\nValue:\t%2\nDuration:\t%3\nLabel:\t%4")) |
446 .arg(rt.toText(true).c_str()) | 428 .arg(rt.toText(true).c_str()) |
447 .arg(valueText) | 429 .arg(valueText) |
448 .arg(rd.toText(true).c_str()) | 430 .arg(rd.toText(true).c_str()) |
449 .arg(region.label); | 431 .arg(region.getLabel()); |
450 } | 432 } |
451 | 433 |
452 pos = QPoint(v->getXForFrame(region.frame), | 434 pos = QPoint(v->getXForFrame(region.getFrame()), |
453 getYForValue(v, region.value)); | 435 getYForValue(v, region.getValue())); |
454 return text; | 436 return text; |
455 } | 437 } |
456 | 438 |
457 bool | 439 bool |
458 RegionLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, | 440 RegionLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, |
461 { | 443 { |
462 if (!m_model) { | 444 if (!m_model) { |
463 return Layer::snapToFeatureFrame(v, frame, resolution, snap); | 445 return Layer::snapToFeatureFrame(v, frame, resolution, snap); |
464 } | 446 } |
465 | 447 |
448 // SnapLeft / SnapRight: return frame of nearest feature in that | |
449 // direction no matter how far away | |
450 // | |
451 // SnapNeighbouring: return frame of feature that would be used in | |
452 // an editing operation, i.e. closest feature in either direction | |
453 // but only if it is "close enough" | |
454 | |
466 resolution = m_model->getResolution(); | 455 resolution = m_model->getResolution(); |
467 RegionModel::PointList points; | |
468 | 456 |
469 if (snap == SnapNeighbouring) { | 457 if (snap == SnapNeighbouring) { |
470 | 458 EventVector points = getLocalPoints(v, v->getXForFrame(frame)); |
471 points = getLocalPoints(v, v->getXForFrame(frame)); | |
472 if (points.empty()) return false; | 459 if (points.empty()) return false; |
473 frame = points.begin()->frame; | 460 frame = points.begin()->getFrame(); |
474 return true; | 461 return true; |
475 } | 462 } |
476 | 463 |
477 points = m_model->getPoints(frame, frame); | 464 // Normally we snap to the start frame of whichever event we |
478 sv_frame_t snapped = frame; | 465 // find. However here, for SnapRight only, if the end frame of |
479 bool found = false; | 466 // whichever event we would have snapped to had we been snapping |
480 | 467 // left is closer than the start frame of the next event to the |
481 for (RegionModel::PointList::const_iterator i = points.begin(); | 468 // right, then we snap to that frame instead. Clear? |
482 i != points.end(); ++i) { | 469 |
483 | 470 Event left; |
484 if (snap == SnapRight) { | 471 bool haveLeft = false; |
485 | 472 if (m_model->getNearestEventMatching |
486 // The best frame to snap to is the end frame of whichever | 473 (frame, [](Event) { return true; }, EventSeries::Backward, left)) { |
487 // feature we would have snapped to the start frame of if | 474 haveLeft = true; |
488 // we had been snapping left. | 475 } |
489 | 476 |
490 if (i->frame <= frame) { | 477 if (snap == SnapLeft) { |
491 if (i->frame + i->duration > frame) { | 478 frame = left.getFrame(); |
492 snapped = i->frame + i->duration; | 479 return haveLeft; |
493 found = true; // don't break, as the next may be better | 480 } |
481 | |
482 Event right; | |
483 bool haveRight = false; | |
484 if (m_model->getNearestEventMatching | |
485 (frame, [](Event) { return true; }, EventSeries::Forward, right)) { | |
486 haveRight = true; | |
487 } | |
488 | |
489 if (haveLeft) { | |
490 sv_frame_t leftEnd = left.getFrame() + left.getDuration(); | |
491 if (leftEnd > frame) { | |
492 if (haveRight) { | |
493 if (leftEnd - frame < right.getFrame() - frame) { | |
494 frame = leftEnd; | |
495 } else { | |
496 frame = right.getFrame(); | |
494 } | 497 } |
495 } else { | 498 } else { |
496 if (!found) { | 499 frame = leftEnd; |
497 snapped = i->frame; | |
498 found = true; | |
499 } | |
500 break; | |
501 } | 500 } |
502 | 501 return true; |
503 } else if (snap == SnapLeft) { | 502 } |
504 | 503 } |
505 if (i->frame <= frame) { | 504 |
506 snapped = i->frame; | 505 if (haveRight) { |
507 found = true; // don't break, as the next may be better | 506 frame = right.getFrame(); |
508 } else { | 507 return true; |
509 break; | 508 } |
510 } | 509 |
511 | 510 return false; |
512 } else { // nearest | |
513 | |
514 RegionModel::PointList::const_iterator j = i; | |
515 ++j; | |
516 | |
517 if (j == points.end()) { | |
518 | |
519 snapped = i->frame; | |
520 found = true; | |
521 break; | |
522 | |
523 } else if (j->frame >= frame) { | |
524 | |
525 if (j->frame - frame < frame - i->frame) { | |
526 snapped = j->frame; | |
527 } else { | |
528 snapped = i->frame; | |
529 } | |
530 found = true; | |
531 break; | |
532 } | |
533 } | |
534 } | |
535 | |
536 frame = snapped; | |
537 return found; | |
538 } | 511 } |
539 | 512 |
540 bool | 513 bool |
541 RegionLayer::snapToSimilarFeature(LayerGeometryProvider *v, sv_frame_t &frame, | 514 RegionLayer::snapToSimilarFeature(LayerGeometryProvider *v, sv_frame_t &frame, |
542 int &resolution, | 515 int &resolution, |
544 { | 517 { |
545 if (!m_model) { | 518 if (!m_model) { |
546 return Layer::snapToSimilarFeature(v, frame, resolution, snap); | 519 return Layer::snapToSimilarFeature(v, frame, resolution, snap); |
547 } | 520 } |
548 | 521 |
522 // snap is only permitted to be SnapLeft or SnapRight here. We | |
523 // don't do the same trick as in snapToFeatureFrame, of snapping | |
524 // to the end of a feature sometimes. | |
525 | |
549 resolution = m_model->getResolution(); | 526 resolution = m_model->getResolution(); |
550 | 527 |
551 const RegionModel::PointList &points = m_model->getPoints(); | 528 Event ref; |
552 RegionModel::PointList close = m_model->getPoints(frame, frame); | 529 Event e; |
553 | 530 float matchvalue; |
554 RegionModel::PointList::const_iterator i; | 531 bool found; |
555 | 532 |
556 sv_frame_t matchframe = frame; | 533 found = m_model->getNearestEventMatching |
557 double matchvalue = 0.f; | 534 (frame, [](Event) { return true; }, EventSeries::Backward, ref); |
558 | 535 |
559 for (i = close.begin(); i != close.end(); ++i) { | 536 if (!found) { |
560 if (i->frame > frame) break; | 537 return false; |
561 matchvalue = i->value; | 538 } |
562 matchframe = i->frame; | 539 |
563 } | 540 matchvalue = ref.getValue(); |
564 | 541 |
565 sv_frame_t snapped = frame; | 542 found = m_model->getNearestEventMatching |
566 bool found = false; | 543 (frame, |
567 bool distant = false; | 544 [matchvalue](Event e) { |
568 double epsilon = 0.0001; | 545 double epsilon = 0.0001; |
569 | 546 return fabs(e.getValue() - matchvalue) < epsilon; |
570 i = close.begin(); | 547 }, |
571 | 548 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward, |
572 // Scan through the close points first, then the more distant ones | 549 e); |
573 // if no suitable close one is found. So the while-termination | 550 |
574 // condition here can only happen once i has passed through the | 551 if (!found) { |
575 // whole of the close container and then the whole of the separate | 552 return false; |
576 // points container. The two iterators are totally distinct, but | 553 } |
577 // have the same type so we cheekily use the same variable and a | 554 |
578 // single loop for both. | 555 frame = e.getFrame(); |
579 | 556 return true; |
580 while (i != points.end()) { | |
581 | |
582 if (!distant) { | |
583 if (i == close.end()) { | |
584 // switch from the close container to the points container | |
585 i = points.begin(); | |
586 distant = true; | |
587 } | |
588 } | |
589 | |
590 if (snap == SnapRight) { | |
591 | |
592 if (i->frame > matchframe && | |
593 fabs(i->value - matchvalue) < epsilon) { | |
594 snapped = i->frame; | |
595 found = true; | |
596 break; | |
597 } | |
598 | |
599 } else if (snap == SnapLeft) { | |
600 | |
601 if (i->frame < matchframe) { | |
602 if (fabs(i->value - matchvalue) < epsilon) { | |
603 snapped = i->frame; | |
604 found = true; // don't break, as the next may be better | |
605 } | |
606 } else if (found || distant) { | |
607 break; | |
608 } | |
609 | |
610 } else { | |
611 // no other snap types supported | |
612 } | |
613 | |
614 ++i; | |
615 } | |
616 | |
617 frame = snapped; | |
618 return found; | |
619 } | 557 } |
620 | 558 |
621 QString | 559 QString |
622 RegionLayer::getScaleUnits() const | 560 RegionLayer::getScaleUnits() const |
623 { | 561 { |
880 int x0 = rect.left() - 40, x1 = rect.right(); | 818 int x0 = rect.left() - 40, x1 = rect.right(); |
881 | 819 |
882 sv_frame_t wholeFrame0 = v->getFrameForX(0); | 820 sv_frame_t wholeFrame0 = v->getFrameForX(0); |
883 sv_frame_t wholeFrame1 = v->getFrameForX(v->getPaintWidth()); | 821 sv_frame_t wholeFrame1 = v->getFrameForX(v->getPaintWidth()); |
884 | 822 |
885 RegionModel::PointList points(m_model->getPoints(wholeFrame0, wholeFrame1)); | 823 EventVector points(m_model->getEventsSpanning(wholeFrame0, |
824 wholeFrame1 - wholeFrame0)); | |
886 if (points.empty()) return; | 825 if (points.empty()) return; |
887 | 826 |
888 paint.setPen(getBaseQColor()); | 827 paint.setPen(getBaseQColor()); |
889 | 828 |
890 QColor brushColour(getBaseQColor()); | 829 QColor brushColour(getBaseQColor()); |
896 double min = m_model->getValueMinimum(); | 835 double min = m_model->getValueMinimum(); |
897 double max = m_model->getValueMaximum(); | 836 double max = m_model->getValueMaximum(); |
898 if (max == min) max = min + 1.0; | 837 if (max == min) max = min + 1.0; |
899 | 838 |
900 QPoint localPos; | 839 QPoint localPos; |
901 RegionModel::Point illuminatePoint(0); | 840 Event illuminatePoint(0); |
902 bool shouldIlluminate = false; | 841 bool shouldIlluminate = false; |
903 | 842 |
904 if (v->shouldIlluminateLocalFeatures(this, localPos)) { | 843 if (v->shouldIlluminateLocalFeatures(this, localPos)) { |
905 shouldIlluminate = getPointToDrag(v, localPos.x(), localPos.y(), | 844 shouldIlluminate = getPointToDrag(v, localPos.x(), localPos.y(), |
906 illuminatePoint); | 845 illuminatePoint); |
915 //!!! if it does have distinct values, we should still ensure y | 854 //!!! if it does have distinct values, we should still ensure y |
916 //!!! coord is never completely flat on the top or bottom | 855 //!!! coord is never completely flat on the top or bottom |
917 | 856 |
918 int fontHeight = paint.fontMetrics().height(); | 857 int fontHeight = paint.fontMetrics().height(); |
919 | 858 |
920 for (RegionModel::PointList::const_iterator i = points.begin(); | 859 for (EventVector::const_iterator i = points.begin(); |
921 i != points.end(); ++i) { | 860 i != points.end(); ++i) { |
922 | 861 |
923 const RegionModel::Point &p(*i); | 862 const Event &p(*i); |
924 | 863 |
925 int x = v->getXForFrame(p.frame); | 864 int x = v->getXForFrame(p.getFrame()); |
926 int w = v->getXForFrame(p.frame + p.duration) - x; | 865 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; |
927 int y = getYForValue(v, p.value); | 866 int y = getYForValue(v, p.getValue()); |
928 int h = 9; | 867 int h = 9; |
929 int ex = x + w; | 868 int ex = x + w; |
930 | 869 |
931 int gap = v->scalePixelSize(2); | 870 int gap = v->scalePixelSize(2); |
932 | 871 |
933 RegionModel::PointList::const_iterator j = i; | 872 EventVector::const_iterator j = i; |
934 ++j; | 873 ++j; |
935 | 874 |
936 if (j != points.end()) { | 875 if (j != points.end()) { |
937 const RegionModel::Point &q(*j); | 876 const Event &q(*j); |
938 int nx = v->getXForFrame(q.frame); | 877 int nx = v->getXForFrame(q.getFrame()); |
939 if (nx < ex) ex = nx; | 878 if (nx < ex) ex = nx; |
940 } | 879 } |
941 | 880 |
942 if (m_model->getValueQuantization() != 0.0) { | 881 if (m_model->getValueQuantization() != 0.0) { |
943 h = y - getYForValue(v, p.value + m_model->getValueQuantization()); | 882 h = y - getYForValue |
883 (v, p.getValue() + m_model->getValueQuantization()); | |
944 if (h < 3) h = 3; | 884 if (h < 3) h = 3; |
945 } | 885 } |
946 | 886 |
947 if (w < 1) w = 1; | 887 if (w < 1) w = 1; |
948 | 888 |
949 if (m_plotStyle == PlotSegmentation) { | 889 if (m_plotStyle == PlotSegmentation) { |
950 paint.setPen(getForegroundQColor(v->getView())); | 890 paint.setPen(getForegroundQColor(v->getView())); |
951 paint.setBrush(getColourForValue(v, p.value)); | 891 paint.setBrush(getColourForValue(v, p.getValue())); |
952 } else { | 892 } else { |
953 paint.setPen(getBaseQColor()); | 893 paint.setPen(getBaseQColor()); |
954 paint.setBrush(brushColour); | 894 paint.setBrush(brushColour); |
955 } | 895 } |
956 | 896 |
957 if (m_plotStyle == PlotSegmentation) { | 897 if (m_plotStyle == PlotSegmentation) { |
958 | 898 |
959 if (ex <= x) continue; | 899 if (ex <= x) continue; |
960 | 900 |
961 if (!shouldIlluminate || | 901 if (!shouldIlluminate || illuminatePoint != p) { |
962 // "illuminatePoint != p" | |
963 RegionModel::Point::Comparator()(illuminatePoint, p) || | |
964 RegionModel::Point::Comparator()(p, illuminatePoint)) { | |
965 | 902 |
966 paint.setPen(QPen(getForegroundQColor(v->getView()), 1)); | 903 paint.setPen(QPen(getForegroundQColor(v->getView()), 1)); |
967 paint.drawLine(x, 0, x, v->getPaintHeight()); | 904 paint.drawLine(x, 0, x, v->getPaintHeight()); |
968 paint.setPen(Qt::NoPen); | 905 paint.setPen(Qt::NoPen); |
969 | 906 |
973 | 910 |
974 paint.drawRect(x, -1, ex - x, v->getPaintHeight() + gap); | 911 paint.drawRect(x, -1, ex - x, v->getPaintHeight() + gap); |
975 | 912 |
976 } else { | 913 } else { |
977 | 914 |
978 if (shouldIlluminate && | 915 if (shouldIlluminate && illuminatePoint == p) { |
979 // "illuminatePoint == p" | |
980 !RegionModel::Point::Comparator()(illuminatePoint, p) && | |
981 !RegionModel::Point::Comparator()(p, illuminatePoint)) { | |
982 | 916 |
983 paint.setPen(v->getForeground()); | 917 paint.setPen(v->getForeground()); |
984 paint.setBrush(v->getForeground()); | 918 paint.setBrush(v->getForeground()); |
985 | 919 |
986 QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits()); | 920 QString vlabel = |
921 QString("%1%2").arg(p.getValue()).arg(getScaleUnits()); | |
987 PaintAssistant::drawVisibleText(v, paint, | 922 PaintAssistant::drawVisibleText(v, paint, |
988 x - paint.fontMetrics().width(vlabel) - gap, | 923 x - paint.fontMetrics().width(vlabel) - gap, |
989 y + paint.fontMetrics().height()/2 | 924 y + paint.fontMetrics().height()/2 |
990 - paint.fontMetrics().descent(), | 925 - paint.fontMetrics().descent(), |
991 vlabel, PaintAssistant::OutlinedText); | 926 vlabel, PaintAssistant::OutlinedText); |
992 | 927 |
993 QString hlabel = RealTime::frame2RealTime | 928 QString hlabel = RealTime::frame2RealTime |
994 (p.frame, m_model->getSampleRate()).toText(true).c_str(); | 929 (p.getFrame(), m_model->getSampleRate()).toText(true).c_str(); |
995 PaintAssistant::drawVisibleText(v, paint, | 930 PaintAssistant::drawVisibleText(v, paint, |
996 x, | 931 x, |
997 y - h/2 - paint.fontMetrics().descent() - gap, | 932 y - h/2 - paint.fontMetrics().descent() - gap, |
998 hlabel, PaintAssistant::OutlinedText); | 933 hlabel, PaintAssistant::OutlinedText); |
999 } | 934 } |
1006 } | 941 } |
1007 | 942 |
1008 int nextLabelMinX = -100; | 943 int nextLabelMinX = -100; |
1009 int lastLabelY = 0; | 944 int lastLabelY = 0; |
1010 | 945 |
1011 for (RegionModel::PointList::const_iterator i = points.begin(); | 946 for (EventVector::const_iterator i = points.begin(); |
1012 i != points.end(); ++i) { | 947 i != points.end(); ++i) { |
1013 | 948 |
1014 const RegionModel::Point &p(*i); | 949 const Event &p(*i); |
1015 | 950 |
1016 int x = v->getXForFrame(p.frame); | 951 int x = v->getXForFrame(p.getFrame()); |
1017 int w = v->getXForFrame(p.frame + p.duration) - x; | 952 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; |
1018 int y = getYForValue(v, p.value); | 953 int y = getYForValue(v, p.getValue()); |
1019 | 954 |
1020 QString label = p.label; | 955 QString label = p.getLabel(); |
1021 if (label == "") { | 956 if (label == "") { |
1022 label = QString("%1%2").arg(p.value).arg(getScaleUnits()); | 957 label = QString("%1%2").arg(p.getValue()).arg(getScaleUnits()); |
1023 } | 958 } |
1024 int labelWidth = paint.fontMetrics().width(label); | 959 int labelWidth = paint.fontMetrics().width(label); |
1025 | 960 |
1026 int gap = v->scalePixelSize(2); | 961 int gap = v->scalePixelSize(2); |
1027 | 962 |
1036 } | 971 } |
1037 | 972 |
1038 bool illuminated = false; | 973 bool illuminated = false; |
1039 | 974 |
1040 if (m_plotStyle != PlotSegmentation) { | 975 if (m_plotStyle != PlotSegmentation) { |
1041 | 976 if (shouldIlluminate && illuminatePoint == p) { |
1042 if (shouldIlluminate && | |
1043 // "illuminatePoint == p" | |
1044 !RegionModel::Point::Comparator()(illuminatePoint, p) && | |
1045 !RegionModel::Point::Comparator()(p, illuminatePoint)) { | |
1046 | |
1047 illuminated = true; | 977 illuminated = true; |
1048 } | 978 } |
1049 } | 979 } |
1050 | 980 |
1051 if (!illuminated) { | 981 if (!illuminated) { |
1099 } | 1029 } |
1100 | 1030 |
1101 void | 1031 void |
1102 RegionLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const | 1032 RegionLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const |
1103 { | 1033 { |
1104 if (!m_model || m_model->getPoints().empty()) return; | 1034 if (!m_model || m_model->isEmpty()) return; |
1105 | 1035 |
1106 QString unit; | 1036 QString unit; |
1107 double min, max; | 1037 double min, max; |
1108 bool logarithmic; | 1038 bool logarithmic; |
1109 | 1039 |
1150 if (frame < 0) frame = 0; | 1080 if (frame < 0) frame = 0; |
1151 frame = frame / m_model->getResolution() * m_model->getResolution(); | 1081 frame = frame / m_model->getResolution() * m_model->getResolution(); |
1152 | 1082 |
1153 double value = getValueForY(v, e->y()); | 1083 double value = getValueForY(v, e->y()); |
1154 | 1084 |
1155 m_editingPoint = RegionModel::Point(frame, float(value), 0, ""); | 1085 m_editingPoint = Event(frame, float(value), 0, ""); |
1156 m_originalPoint = m_editingPoint; | 1086 m_originalPoint = m_editingPoint; |
1157 | 1087 |
1158 if (m_editingCommand) finish(m_editingCommand); | 1088 if (m_editingCommand) finish(m_editingCommand); |
1159 m_editingCommand = new RegionModel::EditCommand(m_model, | 1089 m_editingCommand = new ChangeEventsCommand(m_model, |
1160 tr("Draw Region")); | 1090 tr("Draw Region")); |
1161 m_editingCommand->addPoint(m_editingPoint); | 1091 m_editingCommand->add(m_editingPoint); |
1162 | 1092 |
1163 recalcSpacing(); | 1093 recalcSpacing(); |
1164 | 1094 |
1165 m_editing = true; | 1095 m_editing = true; |
1166 } | 1096 } |
1172 | 1102 |
1173 sv_frame_t frame = v->getFrameForX(e->x()); | 1103 sv_frame_t frame = v->getFrameForX(e->x()); |
1174 if (frame < 0) frame = 0; | 1104 if (frame < 0) frame = 0; |
1175 frame = frame / m_model->getResolution() * m_model->getResolution(); | 1105 frame = frame / m_model->getResolution() * m_model->getResolution(); |
1176 | 1106 |
1177 double newValue = m_editingPoint.value; | 1107 double newValue = m_editingPoint.getValue(); |
1178 if (m_verticalScale != EqualSpaced) newValue = getValueForY(v, e->y()); | 1108 if (m_verticalScale != EqualSpaced) newValue = getValueForY(v, e->y()); |
1179 | 1109 |
1180 sv_frame_t newFrame = m_editingPoint.frame; | 1110 sv_frame_t newFrame = m_editingPoint.getFrame(); |
1181 sv_frame_t newDuration = frame - newFrame; | 1111 sv_frame_t newDuration = frame - newFrame; |
1182 if (newDuration < 0) { | 1112 if (newDuration < 0) { |
1183 newFrame = frame; | 1113 newFrame = frame; |
1184 newDuration = -newDuration; | 1114 newDuration = -newDuration; |
1185 } else if (newDuration == 0) { | 1115 } else if (newDuration == 0) { |
1186 newDuration = 1; | 1116 newDuration = 1; |
1187 } | 1117 } |
1188 | 1118 |
1189 m_editingCommand->deletePoint(m_editingPoint); | 1119 m_editingCommand->remove(m_editingPoint); |
1190 m_editingPoint.frame = newFrame; | 1120 m_editingPoint = m_editingPoint |
1191 m_editingPoint.value = float(newValue); | 1121 .withFrame(newFrame) |
1192 m_editingPoint.duration = newDuration; | 1122 .withValue(float(newValue)) |
1193 m_editingCommand->addPoint(m_editingPoint); | 1123 .withDuration(newDuration); |
1124 m_editingCommand->add(m_editingPoint); | |
1194 | 1125 |
1195 recalcSpacing(); | 1126 recalcSpacing(); |
1196 } | 1127 } |
1197 | 1128 |
1198 void | 1129 void |
1232 { | 1163 { |
1233 if (!m_model || !m_editing) return; | 1164 if (!m_model || !m_editing) return; |
1234 | 1165 |
1235 m_editing = false; | 1166 m_editing = false; |
1236 | 1167 |
1237 RegionModel::Point p(0); | 1168 Event p(0); |
1238 if (!getPointToDrag(v, e->x(), e->y(), p)) return; | 1169 if (!getPointToDrag(v, e->x(), e->y(), p)) return; |
1239 if (p.frame != m_editingPoint.frame || p.value != m_editingPoint.value) return; | 1170 if (p.getFrame() != m_editingPoint.getFrame() || |
1240 | 1171 p.getValue() != m_editingPoint.getValue()) return; |
1241 m_editingCommand = new RegionModel::EditCommand | 1172 |
1173 m_editingCommand = new ChangeEventsCommand | |
1242 (m_model, tr("Erase Region")); | 1174 (m_model, tr("Erase Region")); |
1243 | 1175 |
1244 m_editingCommand->deletePoint(m_editingPoint); | 1176 m_editingCommand->remove(m_editingPoint); |
1245 | 1177 |
1246 finish(m_editingCommand); | 1178 finish(m_editingCommand); |
1247 m_editingCommand = nullptr; | 1179 m_editingCommand = nullptr; |
1248 m_editing = false; | 1180 m_editing = false; |
1249 recalcSpacing(); | 1181 recalcSpacing(); |
1256 | 1188 |
1257 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) { | 1189 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) { |
1258 return; | 1190 return; |
1259 } | 1191 } |
1260 | 1192 |
1261 m_dragPointX = v->getXForFrame(m_editingPoint.frame); | 1193 m_dragPointX = v->getXForFrame(m_editingPoint.getFrame()); |
1262 m_dragPointY = getYForValue(v, m_editingPoint.value); | 1194 m_dragPointY = getYForValue(v, m_editingPoint.getValue()); |
1263 | 1195 |
1264 m_originalPoint = m_editingPoint; | 1196 m_originalPoint = m_editingPoint; |
1265 | 1197 |
1266 if (m_editingCommand) { | 1198 if (m_editingCommand) { |
1267 finish(m_editingCommand); | 1199 finish(m_editingCommand); |
1288 if (frame < 0) frame = 0; | 1220 if (frame < 0) frame = 0; |
1289 frame = frame / m_model->getResolution() * m_model->getResolution(); | 1221 frame = frame / m_model->getResolution() * m_model->getResolution(); |
1290 | 1222 |
1291 // Do not bisect between two values, if one of those values is | 1223 // Do not bisect between two values, if one of those values is |
1292 // that of the point we're actually moving ... | 1224 // that of the point we're actually moving ... |
1293 int avoid = m_spacingMap[m_editingPoint.value]; | 1225 int avoid = m_spacingMap[m_editingPoint.getValue()]; |
1294 | 1226 |
1295 // ... unless there are other points with the same value | 1227 // ... unless there are other points with the same value |
1296 if (m_distributionMap[m_editingPoint.value] > 1) avoid = -1; | 1228 if (m_distributionMap[m_editingPoint.getValue()] > 1) avoid = -1; |
1297 | 1229 |
1298 double value = getValueForY(v, newy, avoid); | 1230 double value = getValueForY(v, newy, avoid); |
1299 | 1231 |
1300 if (!m_editingCommand) { | 1232 if (!m_editingCommand) { |
1301 m_editingCommand = new RegionModel::EditCommand(m_model, | 1233 m_editingCommand = new ChangeEventsCommand(m_model, |
1302 tr("Drag Region")); | 1234 tr("Drag Region")); |
1303 } | 1235 } |
1304 | 1236 |
1305 m_editingCommand->deletePoint(m_editingPoint); | 1237 m_editingCommand->remove(m_editingPoint); |
1306 m_editingPoint.frame = frame; | 1238 m_editingPoint = m_editingPoint |
1307 m_editingPoint.value = float(value); | 1239 .withFrame(frame) |
1308 m_editingCommand->addPoint(m_editingPoint); | 1240 .withValue(float(value)); |
1241 m_editingCommand->add(m_editingPoint); | |
1309 recalcSpacing(); | 1242 recalcSpacing(); |
1310 } | 1243 } |
1311 | 1244 |
1312 void | 1245 void |
1313 RegionLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) | 1246 RegionLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) |
1316 | 1249 |
1317 if (m_editingCommand) { | 1250 if (m_editingCommand) { |
1318 | 1251 |
1319 QString newName = m_editingCommand->getName(); | 1252 QString newName = m_editingCommand->getName(); |
1320 | 1253 |
1321 if (m_editingPoint.frame != m_originalPoint.frame) { | 1254 if (m_editingPoint.getFrame() != m_originalPoint.getFrame()) { |
1322 if (m_editingPoint.value != m_originalPoint.value) { | 1255 if (m_editingPoint.getValue() != m_originalPoint.getValue()) { |
1323 newName = tr("Edit Region"); | 1256 newName = tr("Edit Region"); |
1324 } else { | 1257 } else { |
1325 newName = tr("Relocate Region"); | 1258 newName = tr("Relocate Region"); |
1326 } | 1259 } |
1327 } else { | 1260 } else { |
1340 bool | 1273 bool |
1341 RegionLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) | 1274 RegionLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) |
1342 { | 1275 { |
1343 if (!m_model) return false; | 1276 if (!m_model) return false; |
1344 | 1277 |
1345 RegionModel::Point region(0); | 1278 Event region(0); |
1346 if (!getPointToDrag(v, e->x(), e->y(), region)) return false; | 1279 if (!getPointToDrag(v, e->x(), e->y(), region)) return false; |
1347 | 1280 |
1348 ItemEditDialog *dialog = new ItemEditDialog | 1281 ItemEditDialog *dialog = new ItemEditDialog |
1349 (m_model->getSampleRate(), | 1282 (m_model->getSampleRate(), |
1350 ItemEditDialog::ShowTime | | 1283 ItemEditDialog::ShowTime | |
1351 ItemEditDialog::ShowDuration | | 1284 ItemEditDialog::ShowDuration | |
1352 ItemEditDialog::ShowValue | | 1285 ItemEditDialog::ShowValue | |
1353 ItemEditDialog::ShowText, | 1286 ItemEditDialog::ShowText, |
1354 getScaleUnits()); | 1287 getScaleUnits()); |
1355 | 1288 |
1356 dialog->setFrameTime(region.frame); | 1289 dialog->setFrameTime(region.getFrame()); |
1357 dialog->setValue(region.value); | 1290 dialog->setValue(region.getValue()); |
1358 dialog->setFrameDuration(region.duration); | 1291 dialog->setFrameDuration(region.getDuration()); |
1359 dialog->setText(region.label); | 1292 dialog->setText(region.getLabel()); |
1360 | 1293 |
1361 if (dialog->exec() == QDialog::Accepted) { | 1294 if (dialog->exec() == QDialog::Accepted) { |
1362 | 1295 |
1363 RegionModel::Point newRegion = region; | 1296 Event newRegion = region |
1364 newRegion.frame = dialog->getFrameTime(); | 1297 .withFrame(dialog->getFrameTime()) |
1365 newRegion.value = dialog->getValue(); | 1298 .withValue(dialog->getValue()) |
1366 newRegion.duration = dialog->getFrameDuration(); | 1299 .withDuration(dialog->getFrameDuration()) |
1367 newRegion.label = dialog->getText(); | 1300 .withLabel(dialog->getText()); |
1368 | 1301 |
1369 RegionModel::EditCommand *command = new RegionModel::EditCommand | 1302 ChangeEventsCommand *command = new ChangeEventsCommand |
1370 (m_model, tr("Edit Region")); | 1303 (m_model, tr("Edit Region")); |
1371 command->deletePoint(region); | 1304 command->remove(region); |
1372 command->addPoint(newRegion); | 1305 command->add(newRegion); |
1373 finish(command); | 1306 finish(command); |
1374 } | 1307 } |
1375 | 1308 |
1376 delete dialog; | 1309 delete dialog; |
1377 recalcSpacing(); | 1310 recalcSpacing(); |
1381 void | 1314 void |
1382 RegionLayer::moveSelection(Selection s, sv_frame_t newStartFrame) | 1315 RegionLayer::moveSelection(Selection s, sv_frame_t newStartFrame) |
1383 { | 1316 { |
1384 if (!m_model) return; | 1317 if (!m_model) return; |
1385 | 1318 |
1386 RegionModel::EditCommand *command = | 1319 ChangeEventsCommand *command = |
1387 new RegionModel::EditCommand(m_model, tr("Drag Selection")); | 1320 new ChangeEventsCommand(m_model, tr("Drag Selection")); |
1388 | 1321 |
1389 RegionModel::PointList points = | 1322 EventVector points = |
1390 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); | 1323 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1391 | 1324 |
1392 for (RegionModel::PointList::iterator i = points.begin(); | 1325 for (EventVector::iterator i = points.begin(); |
1393 i != points.end(); ++i) { | 1326 i != points.end(); ++i) { |
1394 | 1327 |
1395 if (s.contains(i->frame)) { | 1328 Event newPoint = (*i) |
1396 RegionModel::Point newPoint(*i); | 1329 .withFrame(i->getFrame() + newStartFrame - s.getStartFrame()); |
1397 newPoint.frame = i->frame + newStartFrame - s.getStartFrame(); | 1330 command->remove(*i); |
1398 command->deletePoint(*i); | 1331 command->add(newPoint); |
1399 command->addPoint(newPoint); | |
1400 } | |
1401 } | 1332 } |
1402 | 1333 |
1403 finish(command); | 1334 finish(command); |
1404 recalcSpacing(); | 1335 recalcSpacing(); |
1405 } | 1336 } |
1406 | 1337 |
1407 void | 1338 void |
1408 RegionLayer::resizeSelection(Selection s, Selection newSize) | 1339 RegionLayer::resizeSelection(Selection s, Selection newSize) |
1409 { | 1340 { |
1410 if (!m_model) return; | 1341 if (!m_model || !s.getDuration()) return; |
1411 | 1342 |
1412 RegionModel::EditCommand *command = | 1343 ChangeEventsCommand *command = |
1413 new RegionModel::EditCommand(m_model, tr("Resize Selection")); | 1344 new ChangeEventsCommand(m_model, tr("Resize Selection")); |
1414 | 1345 |
1415 RegionModel::PointList points = | 1346 EventVector points = |
1416 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); | 1347 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1417 | 1348 |
1418 double ratio = | 1349 double ratio = double(newSize.getDuration()) / double(s.getDuration()); |
1419 double(newSize.getEndFrame() - newSize.getStartFrame()) / | 1350 double oldStart = double(s.getStartFrame()); |
1420 double(s.getEndFrame() - s.getStartFrame()); | 1351 double newStart = double(newSize.getStartFrame()); |
1421 | 1352 |
1422 for (RegionModel::PointList::iterator i = points.begin(); | 1353 for (Event p: points) { |
1423 i != points.end(); ++i) { | 1354 |
1424 | 1355 double newFrame = (double(p.getFrame()) - oldStart) * ratio + newStart; |
1425 if (s.contains(i->frame)) { | 1356 double newDuration = double(p.getDuration()) * ratio; |
1426 | 1357 |
1427 double targetStart = double(i->frame); | 1358 Event newPoint = p |
1428 targetStart = double(newSize.getStartFrame()) + | 1359 .withFrame(lrint(newFrame)) |
1429 targetStart - double(s.getStartFrame()) * ratio; | 1360 .withDuration(lrint(newDuration)); |
1430 | 1361 command->remove(p); |
1431 double targetEnd = double(i->frame + i->duration); | 1362 command->add(newPoint); |
1432 targetEnd = double(newSize.getStartFrame()) + | |
1433 targetEnd - double(s.getStartFrame()) * ratio; | |
1434 | |
1435 RegionModel::Point newPoint(*i); | |
1436 newPoint.frame = lrint(targetStart); | |
1437 newPoint.duration = lrint(targetEnd - targetStart); | |
1438 command->deletePoint(*i); | |
1439 command->addPoint(newPoint); | |
1440 } | |
1441 } | 1363 } |
1442 | 1364 |
1443 finish(command); | 1365 finish(command); |
1444 recalcSpacing(); | 1366 recalcSpacing(); |
1445 } | 1367 } |
1447 void | 1369 void |
1448 RegionLayer::deleteSelection(Selection s) | 1370 RegionLayer::deleteSelection(Selection s) |
1449 { | 1371 { |
1450 if (!m_model) return; | 1372 if (!m_model) return; |
1451 | 1373 |
1452 RegionModel::EditCommand *command = | 1374 ChangeEventsCommand *command = |
1453 new RegionModel::EditCommand(m_model, tr("Delete Selected Points")); | 1375 new ChangeEventsCommand(m_model, tr("Delete Selected Points")); |
1454 | 1376 |
1455 RegionModel::PointList points = | 1377 EventVector points = |
1456 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); | 1378 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1457 | 1379 |
1458 for (RegionModel::PointList::iterator i = points.begin(); | 1380 for (EventVector::iterator i = points.begin(); |
1459 i != points.end(); ++i) { | 1381 i != points.end(); ++i) { |
1460 | 1382 |
1461 if (s.contains(i->frame)) { | 1383 if (s.contains(i->getFrame())) { |
1462 command->deletePoint(*i); | 1384 command->remove(*i); |
1463 } | 1385 } |
1464 } | 1386 } |
1465 | 1387 |
1466 finish(command); | 1388 finish(command); |
1467 recalcSpacing(); | 1389 recalcSpacing(); |
1470 void | 1392 void |
1471 RegionLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) | 1393 RegionLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) |
1472 { | 1394 { |
1473 if (!m_model) return; | 1395 if (!m_model) return; |
1474 | 1396 |
1475 RegionModel::PointList points = | 1397 EventVector points = |
1476 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); | 1398 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1477 | 1399 |
1478 for (RegionModel::PointList::iterator i = points.begin(); | 1400 for (Event p: points) { |
1479 i != points.end(); ++i) { | 1401 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); |
1480 if (s.contains(i->frame)) { | |
1481 Clipboard::Point point(i->frame, i->value, i->duration, i->label); | |
1482 point.setReferenceFrame(alignToReference(v, i->frame)); | |
1483 to.addPoint(point); | |
1484 } | |
1485 } | 1402 } |
1486 } | 1403 } |
1487 | 1404 |
1488 bool | 1405 bool |
1489 RegionLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */) | 1406 RegionLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */) |
1490 { | 1407 { |
1491 if (!m_model) return false; | 1408 if (!m_model) return false; |
1492 | 1409 |
1493 const Clipboard::PointList &points = from.getPoints(); | 1410 const EventVector &points = from.getPoints(); |
1494 | 1411 |
1495 bool realign = false; | 1412 bool realign = false; |
1496 | 1413 |
1497 if (clipboardHasDifferentAlignment(v, from)) { | 1414 if (clipboardHasDifferentAlignment(v, from)) { |
1498 | 1415 |
1509 if (button == QMessageBox::Yes) { | 1426 if (button == QMessageBox::Yes) { |
1510 realign = true; | 1427 realign = true; |
1511 } | 1428 } |
1512 } | 1429 } |
1513 | 1430 |
1514 RegionModel::EditCommand *command = | 1431 ChangeEventsCommand *command = |
1515 new RegionModel::EditCommand(m_model, tr("Paste")); | 1432 new ChangeEventsCommand(m_model, tr("Paste")); |
1516 | 1433 |
1517 for (Clipboard::PointList::const_iterator i = points.begin(); | 1434 for (EventVector::const_iterator i = points.begin(); |
1518 i != points.end(); ++i) { | 1435 i != points.end(); ++i) { |
1519 | 1436 |
1520 if (!i->haveFrame()) continue; | |
1521 sv_frame_t frame = 0; | 1437 sv_frame_t frame = 0; |
1522 | 1438 |
1523 if (!realign) { | 1439 if (!realign) { |
1524 | 1440 |
1525 frame = i->getFrame(); | 1441 frame = i->getFrame(); |
1526 | 1442 |
1527 } else { | 1443 } else { |
1528 | 1444 |
1529 if (i->haveReferenceFrame()) { | 1445 if (i->hasReferenceFrame()) { |
1530 frame = i->getReferenceFrame(); | 1446 frame = i->getReferenceFrame(); |
1531 frame = alignFromReference(v, frame); | 1447 frame = alignFromReference(v, frame); |
1532 } else { | 1448 } else { |
1533 frame = i->getFrame(); | 1449 frame = i->getFrame(); |
1534 } | 1450 } |
1535 } | 1451 } |
1536 | 1452 |
1537 RegionModel::Point newPoint(frame); | 1453 Event p = *i; |
1538 | 1454 Event newPoint = p; |
1539 if (i->haveLabel()) newPoint.label = i->getLabel(); | 1455 if (!p.hasValue()) { |
1540 if (i->haveValue()) newPoint.value = i->getValue(); | 1456 newPoint = newPoint.withValue((m_model->getValueMinimum() + |
1541 else newPoint.value = (m_model->getValueMinimum() + | 1457 m_model->getValueMaximum()) / 2); |
1542 m_model->getValueMaximum()) / 2; | 1458 } |
1543 if (i->haveDuration()) newPoint.duration = i->getDuration(); | 1459 if (!p.hasDuration()) { |
1544 else { | |
1545 sv_frame_t nextFrame = frame; | 1460 sv_frame_t nextFrame = frame; |
1546 Clipboard::PointList::const_iterator j = i; | 1461 EventVector::const_iterator j = i; |
1547 for (; j != points.end(); ++j) { | 1462 for (; j != points.end(); ++j) { |
1548 if (!j->haveFrame()) continue; | |
1549 if (j != i) break; | 1463 if (j != i) break; |
1550 } | 1464 } |
1551 if (j != points.end()) { | 1465 if (j != points.end()) { |
1552 nextFrame = j->getFrame(); | 1466 nextFrame = j->getFrame(); |
1553 } | 1467 } |
1554 if (nextFrame == frame) { | 1468 if (nextFrame == frame) { |
1555 newPoint.duration = m_model->getResolution(); | 1469 newPoint = newPoint.withDuration(m_model->getResolution()); |
1556 } else { | 1470 } else { |
1557 newPoint.duration = nextFrame - frame; | 1471 newPoint = newPoint.withDuration(nextFrame - frame); |
1558 } | 1472 } |
1559 } | 1473 } |
1560 | 1474 |
1561 command->addPoint(newPoint); | 1475 command->add(newPoint); |
1562 } | 1476 } |
1563 | 1477 |
1564 finish(command); | 1478 finish(command); |
1565 recalcSpacing(); | 1479 recalcSpacing(); |
1566 return true; | 1480 return true; |