comparison base/View.cpp @ 10:ec6886f0e673

* Fix update and play limits for play-selection mode when not looping * Fix playback in loop mode when no selection -- but the GUI update for this is still wrong on the flyback * Various fixes and improvements to making selections, particularly during playback * Draw selection under non-opaque non-scrollable layers, so as to improve cacheing * Show selection limits as text when drawing selection * Allow user to find missing audio files when loading session * Cross-fade selections when in play-selection mode -- mostly. We don't cross-fade on a processing block boundary, and unfortunately with short selections the selection boundary is quite likely to coincide with a block boundary.
author Chris Cannam
date Wed, 25 Jan 2006 17:46:28 +0000
parents 73d85d19919f
children f67ddc287bc3
comparison
equal deleted inserted replaced
9:73d85d19919f 10:ec6886f0e673
202 View::setStartFrame(long f) 202 View::setStartFrame(long f)
203 { 203 {
204 setCentreFrame(f + m_zoomLevel * (width() / 2)); 204 setCentreFrame(f + m_zoomLevel * (width() / 2));
205 } 205 }
206 206
207 void 207 bool
208 View::setCentreFrame(size_t f, bool e) 208 View::setCentreFrame(size_t f, bool e)
209 { 209 {
210 bool changeVisible = false;
211
210 if (m_centreFrame != f) { 212 if (m_centreFrame != f) {
211 213
212 int formerPixel = m_centreFrame / m_zoomLevel; 214 int formerPixel = m_centreFrame / m_zoomLevel;
213 215
214 m_centreFrame = f; 216 m_centreFrame = f;
219 221
220 #ifdef DEBUG_VIEW_WIDGET_PAINT 222 #ifdef DEBUG_VIEW_WIDGET_PAINT
221 std::cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << std::endl; 223 std::cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << std::endl;
222 #endif 224 #endif
223 update(); 225 update();
226
227 changeVisible = true;
224 } 228 }
225 229
226 if (e) emit centreFrameChanged(this, f, m_followPan); 230 if (e) emit centreFrameChanged(this, f, m_followPan);
227 } 231 }
232
233 return changeVisible;
228 } 234 }
229 235
230 void 236 void
231 View::setZoomLevel(size_t z) 237 View::setZoomLevel(size_t z)
232 { 238 {
490 if (!visible) return; 496 if (!visible) return;
491 497
492 switch (m_followPlay) { 498 switch (m_followPlay) {
493 499
494 case PlaybackScrollContinuous: 500 case PlaybackScrollContinuous:
495 if (QApplication::mouseButtons() == Qt::NoButton) { 501 if (QApplication::mouseButtons() == Qt::NoButton &&
502 QApplication::keyboardModifiers() == Qt::NoModifier) {
496 setCentreFrame(f, false); 503 setCentreFrame(f, false);
497 } 504 }
498 break; 505 break;
499 506
500 case PlaybackScrollPage: 507 case PlaybackScrollPage:
501 { 508 {
509 int xold = (long(oldPlayPointerFrame) - getStartFrame()) / m_zoomLevel;
510 repaint(xold - 1, 0, 3, height());
511
502 long w = width() * getZoomLevel(); 512 long w = width() * getZoomLevel();
503 w -= w/5; 513 w -= w/5;
504 long sf = (f / w) * w - w/8; 514 long sf = (f / w) * w - w/8;
515
516 if (m_manager &&
517 m_manager->isPlaying() &&
518 m_manager->getPlaySelectionMode()) {
519 ViewManager::SelectionList selections = m_manager->getSelections();
520 if (!selections.empty()) {
521 size_t selectionStart = selections.begin()->getStartFrame();
522 if (sf < long(selectionStart) - w / 10) {
523 sf = long(selectionStart) - w / 10;
524 }
525 }
526 }
527
505 #ifdef DEBUG_VIEW_WIDGET_PAINT 528 #ifdef DEBUG_VIEW_WIDGET_PAINT
506 std::cerr << "PlaybackScrollPage: f = " << f << ", sf = " << sf << ", start frame " 529 std::cerr << "PlaybackScrollPage: f = " << f << ", sf = " << sf << ", start frame "
507 << getStartFrame() << std::endl; 530 << getStartFrame() << std::endl;
508 #endif 531 #endif
509 setCentreFrame(sf + width() * getZoomLevel() / 2, false); 532
510 int xold = (long(oldPlayPointerFrame) - getStartFrame()) / m_zoomLevel; 533 if (QApplication::mouseButtons() == Qt::NoButton &&
534 QApplication::keyboardModifiers() == Qt::NoModifier) {
535 bool changed =
536 setCentreFrame(sf + width() * getZoomLevel() / 2, false);
537 if (changed) {
538 xold = (long(oldPlayPointerFrame) -
539 getStartFrame()) / m_zoomLevel;
540 update(xold - 1, 0, 3, height());
541 }
542 }
543
511 int xnew = (long(m_playPointerFrame) - getStartFrame()) / m_zoomLevel; 544 int xnew = (long(m_playPointerFrame) - getStartFrame()) / m_zoomLevel;
512 update(xold - 1, 0, 3, height());
513 update(xnew - 1, 0, 3, height()); 545 update(xnew - 1, 0, 3, height());
546
514 break; 547 break;
515 } 548 }
516 549
517 case PlaybackIgnore: 550 case PlaybackIgnore:
518 if (long(f) >= getStartFrame() && f < getEndFrame()) { 551 if (long(f) >= getStartFrame() && f < getEndFrame()) {
815 LayerList scrollables = getScrollableBackLayers(layersChanged); 848 LayerList scrollables = getScrollableBackLayers(layersChanged);
816 LayerList nonScrollables = getNonScrollableFrontLayers(layersChanged); 849 LayerList nonScrollables = getNonScrollableFrontLayers(layersChanged);
817 bool selectionCacheable = nonScrollables.empty(); 850 bool selectionCacheable = nonScrollables.empty();
818 bool haveSelections = m_manager && !m_manager->getSelections().empty(); 851 bool haveSelections = m_manager && !m_manager->getSelections().empty();
819 bool selectionDrawn = false; 852 bool selectionDrawn = false;
853
854 if (!selectionCacheable) {
855 selectionCacheable = true;
856 for (LayerList::const_iterator i = nonScrollables.begin();
857 i != nonScrollables.end(); ++i) {
858 if ((*i)->isLayerOpaque()) {
859 selectionCacheable = false;
860 break;
861 }
862 }
863 }
820 864
821 #ifdef DEBUG_VIEW_WIDGET_PAINT 865 #ifdef DEBUG_VIEW_WIDGET_PAINT
822 std::cerr << "View(" << this << ")::paintEvent: have " << scrollables.size() 866 std::cerr << "View(" << this << ")::paintEvent: have " << scrollables.size()
823 << " scrollable back layers and " << nonScrollables.size() 867 << " scrollable back layers and " << nonScrollables.size()
824 << " non-scrollable front layers" << std::endl; 868 << " non-scrollable front layers" << std::endl;
1042 1086
1043 paint.save(); 1087 paint.save();
1044 paint.setPen(QColor(150, 150, 255)); 1088 paint.setPen(QColor(150, 150, 255));
1045 paint.setBrush(QColor(150, 150, 255, 80)); 1089 paint.setBrush(QColor(150, 150, 255, 80));
1046 1090
1091 int sampleRate = getModelsSampleRate();
1092
1093 const QFontMetrics &metrics = paint.fontMetrics();
1094
1047 for (ViewManager::SelectionList::iterator i = selections.begin(); 1095 for (ViewManager::SelectionList::iterator i = selections.begin();
1048 i != selections.end(); ++i) { 1096 i != selections.end(); ++i) {
1049 1097
1050 int p0 = -1, p1 = -1; 1098 int p0 = -1, p1 = -1;
1051 1099
1052 if (int(i->getStartFrame()) >= getStartFrame()) { 1100 p0 = (long(i->getStartFrame()) - getStartFrame()) / m_zoomLevel;
1053 p0 = (i->getStartFrame() - getStartFrame()) / m_zoomLevel; 1101 p1 = (long(i->getEndFrame()) - getStartFrame()) / m_zoomLevel;
1054 } 1102
1055 1103 if (p1 < 0 || p0 > width()) continue;
1056 if (int(i->getEndFrame()) >= getStartFrame()) {
1057 p1 = (i->getEndFrame() - getStartFrame()) / m_zoomLevel;
1058 }
1059
1060 if (p0 == -1 && p1 == -1) continue;
1061
1062 if (p1 > width()) p1 = width() + 1;
1063 1104
1064 #ifdef DEBUG_VIEW_WIDGET_PAINT 1105 #ifdef DEBUG_VIEW_WIDGET_PAINT
1065 std::cerr << "View::drawSelections: " << p0 << ",-1 [" << (p1-p0) << "x" << (height()+1) << "]" << std::endl; 1106 std::cerr << "View::drawSelections: " << p0 << ",-1 [" << (p1-p0) << "x" << (height()+1) << "]" << std::endl;
1066 #endif 1107 #endif
1067 1108
1068 paint.drawRect(p0, -1, p1 - p0, height() + 1); 1109 paint.drawRect(p0, -1, p1 - p0, height() + 1);
1110
1111 if (sampleRate && shouldLabelSelections()) {
1112
1113 QString startText = QString("%1 / %2")
1114 .arg(QString::fromStdString
1115 (RealTime::frame2RealTime
1116 (i->getStartFrame(), sampleRate).toText(true)))
1117 .arg(i->getStartFrame());
1118
1119 QString endText = QString(" %1 / %2")
1120 .arg(QString::fromStdString
1121 (RealTime::frame2RealTime
1122 (i->getEndFrame(), sampleRate).toText(true)))
1123 .arg(i->getEndFrame());
1124
1125 QString durationText = QString("(%1 / %2) ")
1126 .arg(QString::fromStdString
1127 (RealTime::frame2RealTime
1128 (i->getEndFrame() - i->getStartFrame(), sampleRate)
1129 .toText(true)))
1130 .arg(i->getEndFrame() - i->getStartFrame());
1131
1132 int sw = metrics.width(startText),
1133 ew = metrics.width(endText),
1134 dw = metrics.width(durationText);
1135
1136 int sy = metrics.ascent() + metrics.height() + 4;
1137 int ey = sy;
1138 int dy = sy + metrics.height();
1139
1140 int sx = p0 + 2;
1141 int ex = sx;
1142 int dx = sx;
1143
1144 if (sw + ew > (p1 - p0)) {
1145 ey += metrics.height();
1146 dy += metrics.height();
1147 }
1148
1149 if (ew < (p1 - p0)) {
1150 ex = p1 - 2 - ew;
1151 }
1152
1153 if (dw < (p1 - p0)) {
1154 dx = p1 - 2 - dw;
1155 }
1156
1157 paint.drawText(sx, sy, startText);
1158 paint.drawText(ex, ey, endText);
1159 paint.drawText(dx, dy, durationText);
1160 }
1069 } 1161 }
1070 1162
1071 paint.restore(); 1163 paint.restore();
1072 } 1164 }
1073 1165