Chris@867: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@867: Chris@867: /* Chris@867: Sonic Visualiser Chris@867: An audio file viewer and annotation editor. Chris@867: Centre for Digital Music, Queen Mary, University of London. Chris@867: This file copyright 2006-2014 Chris Cannam and QMUL. Chris@867: Chris@867: This program is free software; you can redistribute it and/or Chris@867: modify it under the terms of the GNU General Public License as Chris@867: published by the Free Software Foundation; either version 2 of the Chris@867: License, or (at your option) any later version. See the file Chris@867: COPYING included with this distribution for more information. Chris@867: */ Chris@867: Chris@867: #include "AlignmentView.h" Chris@867: Chris@867: #include Chris@867: Chris@868: #include "data/model/SparseOneDimensionalModel.h" Chris@868: Chris@868: #include "layer/TimeInstantLayer.h" Chris@868: Chris@867: using std::vector; Chris@867: Chris@867: AlignmentView::AlignmentView(QWidget *w) : Chris@867: View(w, false), Chris@1408: m_above(nullptr), Chris@1408: m_below(nullptr) Chris@867: { Chris@867: setObjectName(tr("AlignmentView")); Chris@867: } Chris@867: Chris@867: void Chris@976: AlignmentView::globalCentreFrameChanged(sv_frame_t f) Chris@867: { Chris@867: View::globalCentreFrameChanged(f); Chris@867: update(); Chris@867: } Chris@867: Chris@867: void Chris@976: AlignmentView::viewCentreFrameChanged(View *v, sv_frame_t f) Chris@867: { Chris@867: View::viewCentreFrameChanged(v, f); Chris@867: if (v == m_above) { Chris@1266: m_centreFrame = f; Chris@1266: update(); Chris@867: } else if (v == m_below) { Chris@1266: update(); Chris@867: } Chris@867: } Chris@867: Chris@867: void Chris@976: AlignmentView::viewManagerPlaybackFrameChanged(sv_frame_t) Chris@867: { Chris@867: update(); Chris@867: } Chris@867: Chris@867: void Chris@1183: AlignmentView::viewAboveZoomLevelChanged(ZoomLevel level, bool) Chris@867: { Chris@867: m_zoomLevel = level; Chris@867: update(); Chris@867: } Chris@867: Chris@867: void Chris@1183: AlignmentView::viewBelowZoomLevelChanged(ZoomLevel, bool) Chris@867: { Chris@867: update(); Chris@867: } Chris@867: Chris@867: void Chris@867: AlignmentView::setViewAbove(View *v) Chris@867: { Chris@867: if (m_above) { Chris@1408: disconnect(m_above, nullptr, this, nullptr); Chris@867: } Chris@867: Chris@867: m_above = v; Chris@867: Chris@867: if (m_above) { Chris@1266: connect(m_above, Chris@1183: SIGNAL(zoomLevelChanged(ZoomLevel, bool)), Chris@1266: this, Chris@1183: SLOT(viewAboveZoomLevelChanged(ZoomLevel, bool))); Chris@867: } Chris@867: } Chris@867: Chris@867: void Chris@867: AlignmentView::setViewBelow(View *v) Chris@867: { Chris@867: if (m_below) { Chris@1408: disconnect(m_below, nullptr, this, nullptr); Chris@867: } Chris@867: Chris@867: m_below = v; Chris@867: Chris@867: if (m_below) { Chris@1266: connect(m_below, Chris@1183: SIGNAL(zoomLevelChanged(ZoomLevel, bool)), Chris@1266: this, Chris@1183: SLOT(viewBelowZoomLevelChanged(ZoomLevel, bool))); Chris@867: } Chris@867: } Chris@867: Chris@867: void Chris@867: AlignmentView::paintEvent(QPaintEvent *) Chris@867: { Chris@1408: if (m_above == nullptr || m_below == nullptr || !m_manager) return; Chris@867: Chris@867: bool darkPalette = false; Chris@867: if (m_manager) darkPalette = m_manager->getGlobalDarkBackground(); Chris@867: Chris@881: QColor fg, bg; Chris@881: if (darkPalette) { Chris@881: fg = Qt::gray; Chris@881: bg = Qt::black; Chris@881: } else { Chris@881: fg = Qt::black; Chris@881: bg = Qt::gray; Chris@881: } Chris@867: Chris@867: QPainter paint(this); Chris@867: paint.setPen(QPen(fg, 2)); Chris@867: paint.setBrush(Qt::NoBrush); Chris@867: paint.setRenderHint(QPainter::Antialiasing, true); Chris@867: Chris@867: paint.fillRect(rect(), bg); Chris@867: Chris@976: vector keyFrames = getKeyFrames(); Chris@867: Chris@976: foreach (sv_frame_t f, keyFrames) { Chris@1266: int ax = m_above->getXForFrame(f); Chris@1266: sv_frame_t rf = m_above->alignToReference(f); Chris@1266: sv_frame_t bf = m_below->alignFromReference(rf); Chris@1266: int bx = m_below->getXForFrame(bf); Chris@1266: paint.drawLine(ax, 0, bx, height()); Chris@867: } Chris@867: Chris@867: paint.end(); Chris@867: } Chris@867: Chris@976: vector Chris@868: AlignmentView::getKeyFrames() Chris@868: { Chris@868: if (!m_above) { Chris@1266: return getDefaultKeyFrames(); Chris@868: } Chris@868: Chris@1475: ModelId m; Chris@868: Chris@868: // get the topmost such Chris@868: for (int i = 0; i < m_above->getLayerCount(); ++i) { Chris@1266: if (qobject_cast(m_above->getLayer(i))) { Chris@1475: ModelId mm = m_above->getLayer(i)->getModel(); Chris@1475: if (ModelById::isa(mm)) { Chris@1475: m = mm; Chris@1475: } Chris@1266: } Chris@868: } Chris@868: Chris@1475: auto model = ModelById::getAs(m); Chris@1475: if (!model) { Chris@1266: return getDefaultKeyFrames(); Chris@868: } Chris@868: Chris@976: vector keyFrames; Chris@868: Chris@1475: EventVector pp = model->getAllEvents(); Chris@1433: for (EventVector::const_iterator pi = pp.begin(); pi != pp.end(); ++pi) { Chris@1433: keyFrames.push_back(pi->getFrame()); Chris@868: } Chris@868: Chris@868: return keyFrames; Chris@868: } Chris@868: Chris@976: vector Chris@868: AlignmentView::getDefaultKeyFrames() Chris@868: { Chris@976: vector keyFrames; Chris@868: Chris@868: if (!m_above || !m_manager) return keyFrames; Chris@868: Chris@976: sv_samplerate_t rate = m_manager->getMainModelSampleRate(); Chris@868: if (rate == 0) return keyFrames; Chris@868: Chris@976: for (sv_frame_t f = m_above->getModelsStartFrame(); Chris@1266: f <= m_above->getModelsEndFrame(); Chris@1266: f += sv_frame_t(rate * 5 + 0.5)) { Chris@1266: keyFrames.push_back(f); Chris@868: } Chris@868: Chris@868: return keyFrames; Chris@868: } Chris@868: