Mercurial > hg > svcore
diff 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 |
line wrap: on
line diff
--- a/base/View.cpp Tue Jan 24 16:20:58 2006 +0000 +++ b/base/View.cpp Wed Jan 25 17:46:28 2006 +0000 @@ -204,9 +204,11 @@ setCentreFrame(f + m_zoomLevel * (width() / 2)); } -void +bool View::setCentreFrame(size_t f, bool e) { + bool changeVisible = false; + if (m_centreFrame != f) { int formerPixel = m_centreFrame / m_zoomLevel; @@ -221,10 +223,14 @@ std::cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << std::endl; #endif update(); + + changeVisible = true; } if (e) emit centreFrameChanged(this, f, m_followPan); } + + return changeVisible; } void @@ -492,25 +498,52 @@ switch (m_followPlay) { case PlaybackScrollContinuous: - if (QApplication::mouseButtons() == Qt::NoButton) { + if (QApplication::mouseButtons() == Qt::NoButton && + QApplication::keyboardModifiers() == Qt::NoModifier) { setCentreFrame(f, false); } break; case PlaybackScrollPage: { + int xold = (long(oldPlayPointerFrame) - getStartFrame()) / m_zoomLevel; + repaint(xold - 1, 0, 3, height()); + long w = width() * getZoomLevel(); w -= w/5; long sf = (f / w) * w - w/8; + + if (m_manager && + m_manager->isPlaying() && + m_manager->getPlaySelectionMode()) { + ViewManager::SelectionList selections = m_manager->getSelections(); + if (!selections.empty()) { + size_t selectionStart = selections.begin()->getStartFrame(); + if (sf < long(selectionStart) - w / 10) { + sf = long(selectionStart) - w / 10; + } + } + } + #ifdef DEBUG_VIEW_WIDGET_PAINT std::cerr << "PlaybackScrollPage: f = " << f << ", sf = " << sf << ", start frame " << getStartFrame() << std::endl; #endif - setCentreFrame(sf + width() * getZoomLevel() / 2, false); - int xold = (long(oldPlayPointerFrame) - getStartFrame()) / m_zoomLevel; + + if (QApplication::mouseButtons() == Qt::NoButton && + QApplication::keyboardModifiers() == Qt::NoModifier) { + bool changed = + setCentreFrame(sf + width() * getZoomLevel() / 2, false); + if (changed) { + xold = (long(oldPlayPointerFrame) - + getStartFrame()) / m_zoomLevel; + update(xold - 1, 0, 3, height()); + } + } + int xnew = (long(m_playPointerFrame) - getStartFrame()) / m_zoomLevel; - update(xold - 1, 0, 3, height()); update(xnew - 1, 0, 3, height()); + break; } @@ -818,6 +851,17 @@ bool haveSelections = m_manager && !m_manager->getSelections().empty(); bool selectionDrawn = false; + if (!selectionCacheable) { + selectionCacheable = true; + for (LayerList::const_iterator i = nonScrollables.begin(); + i != nonScrollables.end(); ++i) { + if ((*i)->isLayerOpaque()) { + selectionCacheable = false; + break; + } + } + } + #ifdef DEBUG_VIEW_WIDGET_PAINT std::cerr << "View(" << this << ")::paintEvent: have " << scrollables.size() << " scrollable back layers and " << nonScrollables.size() @@ -1044,28 +1088,76 @@ paint.setPen(QColor(150, 150, 255)); paint.setBrush(QColor(150, 150, 255, 80)); + int sampleRate = getModelsSampleRate(); + + const QFontMetrics &metrics = paint.fontMetrics(); + for (ViewManager::SelectionList::iterator i = selections.begin(); i != selections.end(); ++i) { int p0 = -1, p1 = -1; - if (int(i->getStartFrame()) >= getStartFrame()) { - p0 = (i->getStartFrame() - getStartFrame()) / m_zoomLevel; - } + p0 = (long(i->getStartFrame()) - getStartFrame()) / m_zoomLevel; + p1 = (long(i->getEndFrame()) - getStartFrame()) / m_zoomLevel; - if (int(i->getEndFrame()) >= getStartFrame()) { - p1 = (i->getEndFrame() - getStartFrame()) / m_zoomLevel; - } - - if (p0 == -1 && p1 == -1) continue; - - if (p1 > width()) p1 = width() + 1; + if (p1 < 0 || p0 > width()) continue; #ifdef DEBUG_VIEW_WIDGET_PAINT std::cerr << "View::drawSelections: " << p0 << ",-1 [" << (p1-p0) << "x" << (height()+1) << "]" << std::endl; #endif paint.drawRect(p0, -1, p1 - p0, height() + 1); + + if (sampleRate && shouldLabelSelections()) { + + QString startText = QString("%1 / %2") + .arg(QString::fromStdString + (RealTime::frame2RealTime + (i->getStartFrame(), sampleRate).toText(true))) + .arg(i->getStartFrame()); + + QString endText = QString(" %1 / %2") + .arg(QString::fromStdString + (RealTime::frame2RealTime + (i->getEndFrame(), sampleRate).toText(true))) + .arg(i->getEndFrame()); + + QString durationText = QString("(%1 / %2) ") + .arg(QString::fromStdString + (RealTime::frame2RealTime + (i->getEndFrame() - i->getStartFrame(), sampleRate) + .toText(true))) + .arg(i->getEndFrame() - i->getStartFrame()); + + int sw = metrics.width(startText), + ew = metrics.width(endText), + dw = metrics.width(durationText); + + int sy = metrics.ascent() + metrics.height() + 4; + int ey = sy; + int dy = sy + metrics.height(); + + int sx = p0 + 2; + int ex = sx; + int dx = sx; + + if (sw + ew > (p1 - p0)) { + ey += metrics.height(); + dy += metrics.height(); + } + + if (ew < (p1 - p0)) { + ex = p1 - 2 - ew; + } + + if (dw < (p1 - p0)) { + dx = p1 - 2 - dw; + } + + paint.drawText(sx, sy, startText); + paint.drawText(ex, ey, endText); + paint.drawText(dx, dy, durationText); + } } paint.restore();