changeset 1045:f535f6e5dbb0 alignment-simple

Merge in from SV 3.0-integration branches
author Chris Cannam
date Wed, 02 Mar 2016 17:25:27 +0000
parents f2c63ec85901 (diff) 4e5c1c326794 (current diff)
children 834e94eb1bca
files svgui.pro view/View.h
diffstat 8 files changed, 324 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/svgui.pro	Tue Feb 09 10:59:36 2016 +0000
+++ b/svgui.pro	Wed Mar 02 17:25:27 2016 +0000
@@ -91,13 +91,16 @@
            layer/TimeValueLayer.cpp \
            layer/WaveformLayer.cpp
 
-HEADERS += view/Overview.h \
+HEADERS += view/AlignmentView.h \
+           view/Overview.h \
            view/Pane.h \
            view/PaneStack.h \
            view/View.h \
            view/ViewManager.h \
            view/ViewProxy.h
-SOURCES += view/Overview.cpp \
+           
+SOURCES += view/AlignmentView.cpp \
+           view/Overview.cpp \
            view/Pane.cpp \
            view/PaneStack.cpp \
            view/View.cpp \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/view/AlignmentView.cpp	Wed Mar 02 17:25:27 2016 +0000
@@ -0,0 +1,200 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2014 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "AlignmentView.h"
+
+#include <QPainter>
+
+#include "data/model/SparseOneDimensionalModel.h"
+
+#include "layer/TimeInstantLayer.h"
+
+using std::vector;
+
+AlignmentView::AlignmentView(QWidget *w) :
+    View(w, false),
+    m_above(0),
+    m_below(0)
+{
+    setObjectName(tr("AlignmentView"));
+}
+
+void
+AlignmentView::globalCentreFrameChanged(sv_frame_t f)
+{
+    View::globalCentreFrameChanged(f);
+    update();
+}
+
+void
+AlignmentView::viewCentreFrameChanged(View *v, sv_frame_t f)
+{
+    View::viewCentreFrameChanged(v, f);
+    if (v == m_above) {
+	m_centreFrame = f;
+	update();
+    } else if (v == m_below) {
+	update();
+    }
+}
+
+void
+AlignmentView::viewManagerPlaybackFrameChanged(sv_frame_t)
+{
+    update();
+}
+
+void
+AlignmentView::viewAboveZoomLevelChanged(int level, bool)
+{
+    m_zoomLevel = level;
+    update();
+}
+
+void
+AlignmentView::viewBelowZoomLevelChanged(int, bool)
+{
+    update();
+}
+
+void
+AlignmentView::setViewAbove(View *v)
+{
+    if (m_above) {
+	disconnect(m_above, 0, this, 0);
+    }
+
+    m_above = v;
+
+    if (m_above) {
+	connect(m_above,
+		SIGNAL(zoomLevelChanged(int, bool)),
+		this, 
+		SLOT(viewAboveZoomLevelChanged(int, bool)));
+    }
+}
+
+void
+AlignmentView::setViewBelow(View *v)
+{
+    if (m_below) {
+	disconnect(m_below, 0, this, 0);
+    }
+
+    m_below = v;
+
+    if (m_below) {
+	connect(m_below,
+		SIGNAL(zoomLevelChanged(int, bool)),
+		this, 
+		SLOT(viewBelowZoomLevelChanged(int, bool)));
+    }
+}
+
+void
+AlignmentView::paintEvent(QPaintEvent *)
+{
+    if (m_above == 0 || m_below == 0 || !m_manager) return;
+
+    bool darkPalette = false;
+    if (m_manager) darkPalette = m_manager->getGlobalDarkBackground();
+
+    QColor fg, bg;
+    if (darkPalette) {
+        fg = Qt::gray;
+        bg = Qt::black;
+    } else {
+        fg = Qt::black;
+        bg = Qt::gray;
+    }
+
+    QPainter paint(this);
+    paint.setPen(QPen(fg, 2));
+    paint.setBrush(Qt::NoBrush);
+    paint.setRenderHint(QPainter::Antialiasing, true);
+
+    paint.fillRect(rect(), bg);
+
+    vector<sv_frame_t> keyFrames = getKeyFrames();
+
+    foreach (sv_frame_t f, keyFrames) {
+	int ax = m_above->getXForFrame(f);
+	sv_frame_t rf = m_above->alignToReference(f);
+	sv_frame_t bf = m_below->alignFromReference(rf);
+	int bx = m_below->getXForFrame(bf);
+	paint.drawLine(ax, 0, bx, height());
+    }
+
+    paint.end();
+}
+
+vector<sv_frame_t>
+AlignmentView::getKeyFrames()
+{
+    if (!m_above) {
+	return getDefaultKeyFrames();
+    }
+
+    SparseOneDimensionalModel *m = 0;
+
+    // get the topmost such
+    for (int i = 0; i < m_above->getLayerCount(); ++i) {
+	if (qobject_cast<TimeInstantLayer *>(m_above->getLayer(i))) {
+	    SparseOneDimensionalModel *mm = 
+		qobject_cast<SparseOneDimensionalModel *>
+		(m_above->getLayer(i)->getModel());
+	    if (mm) m = mm;
+	}
+    }
+
+    if (!m) {
+	return getDefaultKeyFrames();
+    }
+
+    vector<sv_frame_t> keyFrames;
+
+    const SparseOneDimensionalModel::PointList pp = m->getPoints();
+    for (SparseOneDimensionalModel::PointList::const_iterator pi = pp.begin();
+	 pi != pp.end(); ++pi) {
+	keyFrames.push_back(pi->frame);
+    }
+
+    return keyFrames;
+}
+
+vector<sv_frame_t>
+AlignmentView::getDefaultKeyFrames()
+{
+    vector<sv_frame_t> keyFrames;
+
+    if (!m_above || !m_manager) return keyFrames;
+
+    sv_samplerate_t rate = m_manager->getMainModelSampleRate();
+    if (rate == 0) return keyFrames;
+
+    for (sv_frame_t f = m_above->getModelsStartFrame(); 
+	 f <= m_above->getModelsEndFrame(); 
+	 f += sv_frame_t(rate * 5 + 0.5)) {
+	keyFrames.push_back(f);
+    }
+    
+    return keyFrames;
+}
+
+
+
+
+
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/view/AlignmentView.h	Wed Mar 02 17:25:27 2016 +0000
@@ -0,0 +1,50 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2014 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef ALIGNMENT_VIEW_H
+#define ALIGNMENT_VIEW_H
+
+#include "View.h"
+
+class AlignmentView : public View
+{
+    Q_OBJECT
+
+public:
+    AlignmentView(QWidget *parent = 0);
+    virtual QString getPropertyContainerIconName() const { return "alignment"; }
+    
+    void setViewAbove(View *view);
+    void setViewBelow(View *view);
+
+public slots:
+    virtual void globalCentreFrameChanged(sv_frame_t);
+    virtual void viewCentreFrameChanged(View *, sv_frame_t);
+    virtual void viewAboveZoomLevelChanged(int, bool);
+    virtual void viewBelowZoomLevelChanged(int, bool);
+    virtual void viewManagerPlaybackFrameChanged(sv_frame_t);
+
+protected:
+    virtual void paintEvent(QPaintEvent *e);
+    virtual bool shouldLabelSelections() const { return false; }
+
+    std::vector<sv_frame_t> getKeyFrames();
+    std::vector<sv_frame_t> getDefaultKeyFrames();
+
+    View *m_above;
+    View *m_below;
+};
+
+#endif
--- a/view/Pane.cpp	Tue Feb 09 10:59:36 2016 +0000
+++ b/view/Pane.cpp	Wed Mar 02 17:25:27 2016 +0000
@@ -717,6 +717,10 @@
 void
 Pane::drawCentreLine(sv_samplerate_t sampleRate, QPainter &paint, bool omitLine)
 {
+    if (omitLine && m_manager->getMainModelSampleRate() == 0) {
+        return;
+    }
+    
     int fontHeight = paint.fontMetrics().height();
     int fontAscent = paint.fontMetrics().ascent();
 
@@ -1943,7 +1947,7 @@
          true, // can move horiz
          canTopLayerMoveVertical(), // can move vert
          canTopLayerMoveVertical() || (m_manager && m_manager->isPlaying()), // resist horiz
-         !(m_manager && m_manager->isPlaying())); // resist vert
+         true); // resist vert
 
     if (m_dragMode == HorizontalDrag ||
         m_dragMode == FreeDrag) {
@@ -2312,7 +2316,7 @@
             m_pendingWheelAngle = 0;
             return;
         }
-        
+
         while (abs(m_pendingWheelAngle) >= 120) {
 
             int sign = (m_pendingWheelAngle < 0 ? -1 : 1);
--- a/view/PaneStack.cpp	Tue Feb 09 10:59:36 2016 +0000
+++ b/view/PaneStack.cpp	Wed Mar 02 17:25:27 2016 +0000
@@ -21,6 +21,7 @@
 #include "widgets/ClickableLabel.h"
 #include "layer/Layer.h"
 #include "ViewManager.h"
+#include "AlignmentView.h"
 
 #include <QApplication>
 #include <QHBoxLayout>
@@ -40,6 +41,7 @@
     QFrame(parent),
     m_currentPane(0),
     m_showAccessories(true),
+    m_showAlignmentViews(false),
     m_splitter(new QSplitter),
     m_propertyStackStack(new QStackedWidget),
     m_viewManager(viewManager),
@@ -67,6 +69,15 @@
     m_showAccessories = show;
 }
 
+void
+PaneStack::setShowAlignmentViews(bool show)
+{
+    m_showAlignmentViews = show;
+    foreach (const PaneRec &r, m_panes) {
+        r.alignmentView->setVisible(m_showAlignmentViews);
+    }
+}
+
 Pane *
 PaneStack::addPane(bool suppressPropertyBox)
 {
@@ -112,6 +123,12 @@
     layout->addWidget(pane, 0, 1, 2, 1);
     layout->setColumnStretch(1, 20);
 
+    AlignmentView *av = new AlignmentView(frame);
+    av->setFixedHeight(40);//!!!
+    av->setVisible(m_showAlignmentViews);
+    av->setViewManager(m_viewManager);
+    layout->addWidget(av, 2, 1);
+
     QWidget *properties = 0;
     if (suppressPropertyBox) {
 	properties = new QFrame();
@@ -139,6 +156,7 @@
     rec.currentIndicator = currentIndicator;
     rec.frame = frame;
     rec.layout = layout;
+    rec.alignmentView = av;
     m_panes.push_back(rec);
 
     frame->setLayout(layout);
@@ -167,11 +185,34 @@
     }
 
     showOrHidePaneAccessories();
+    relinkAlignmentViews();
 
     return pane;
 }
 
 void
+PaneStack::relinkAlignmentViews()
+{
+    for (int i = 0; i < (int)m_panes.size(); ++i) {
+        m_panes[i].alignmentView->setViewAbove(m_panes[i].pane);
+        if (i + 1 < (int)m_panes.size()) {
+            m_panes[i].alignmentView->setViewBelow(m_panes[i+1].pane);
+        } else {
+            m_panes[i].alignmentView->setViewBelow(0);
+        }
+    }
+}
+
+void
+PaneStack::unlinkAlignmentViews()
+{
+    for (int i = 0; i < (int)m_panes.size(); ++i) {
+        m_panes[i].alignmentView->setViewAbove(0);
+        m_panes[i].alignmentView->setViewBelow(0);
+    }
+}
+
+void
 PaneStack::setPropertyStackMinWidth(int mw)
 {
     for (std::vector<PaneRec>::iterator i = m_panes.begin();
@@ -279,6 +320,7 @@
     }
 
     emit paneAboutToBeDeleted(pane);
+    unlinkAlignmentViews();
 
     cerr << "PaneStack::deletePane: about to delete parent " << pane->parent() << " of pane " << pane << endl;
 
@@ -303,6 +345,7 @@
     }
 
     showOrHidePaneAccessories();
+    relinkAlignmentViews();
 
     emit paneDeleted();
 }
@@ -362,6 +405,8 @@
 	++i;
     }
 
+    relinkAlignmentViews();
+
     cerr << "WARNING: PaneStack::hidePane(" << pane << "): Pane not found in visible panes" << endl;
 }
 
@@ -386,6 +431,8 @@
 	++i;
     }
 
+    relinkAlignmentViews();
+
     cerr << "WARNING: PaneStack::showPane(" << pane << "): Pane not found in hidden panes" << endl;
 }
 
--- a/view/PaneStack.h	Tue Feb 09 10:59:36 2016 +0000
+++ b/view/PaneStack.h	Wed Mar 02 17:25:27 2016 +0000
@@ -34,6 +34,7 @@
 class ViewManager;
 class PropertyContainer;
 class PropertyStack;
+class AlignmentView;
 
 class PaneStack : public QFrame
 {
@@ -73,6 +74,8 @@
     
     void setShowPaneAccessories(bool show); // current indicator, close button
 
+    void setShowAlignmentViews(bool show);
+
     void sizePanesEqually();
 
 signals:
@@ -114,18 +117,20 @@
 
     struct PaneRec
     {
-	Pane        *pane;
-	QWidget     *propertyStack;
-        QPushButton *xButton;
-	QLabel      *currentIndicator;
-        QFrame      *frame;
-        QGridLayout *layout;
+	Pane          *pane;
+	QWidget       *propertyStack;
+        QPushButton   *xButton;
+	QLabel        *currentIndicator;
+        QFrame        *frame;
+        QGridLayout   *layout;
+        AlignmentView *alignmentView;
     };
 
     std::vector<PaneRec> m_panes;
     std::vector<PaneRec> m_hiddenPanes;
 
     bool m_showAccessories;
+    bool m_showAlignmentViews;
 
     QSplitter *m_splitter;
     QStackedWidget *m_propertyStackStack;
@@ -136,6 +141,9 @@
 
     void showOrHidePaneAccessories();
 
+    void unlinkAlignmentViews();
+    void relinkAlignmentViews();
+
     LayoutStyle m_layoutStyle;
 };
 
--- a/view/View.h	Tue Feb 09 10:59:36 2016 +0000
+++ b/view/View.h	Wed Mar 02 17:25:27 2016 +0000
@@ -373,7 +373,7 @@
                             bool globalScroll,
                             PlaybackFollowMode followMode);
 
-    void zoomLevelChanged(int, bool);
+    void zoomLevelChanged(int level, bool locked);
 
     void contextHelpChanged(const QString &);
 
--- a/view/ViewManager.cpp	Tue Feb 09 10:59:36 2016 +0000
+++ b/view/ViewManager.cpp	Wed Mar 02 17:25:27 2016 +0000
@@ -741,3 +741,4 @@
     if (pixels != 0 && scaled == 0) scaled = 1;
     return scaled;
 }
+