Mercurial > hg > svgui
changeset 1052:834e94eb1bca 3.0-integration
Merge from branch "alignment-simple"
author | Chris Cannam |
---|---|
date | Thu, 21 Apr 2016 15:06:05 +0100 |
parents | 3691af49291c (current diff) f535f6e5dbb0 (diff) |
children | 38a53c7b81f6 |
files | svgui.pro |
diffstat | 8 files changed, 324 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/svgui.pro Fri Mar 18 14:25:05 2016 +0000 +++ b/svgui.pro Thu Apr 21 15:06:05 2016 +0100 @@ -94,13 +94,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 Thu Apr 21 15:06:05 2016 +0100 @@ -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 Thu Apr 21 15:06:05 2016 +0100 @@ -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 Fri Mar 18 14:25:05 2016 +0000 +++ b/view/Pane.cpp Thu Apr 21 15:06:05 2016 +0100 @@ -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 Fri Mar 18 14:25:05 2016 +0000 +++ b/view/PaneStack.cpp Thu Apr 21 15:06:05 2016 +0100 @@ -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 Fri Mar 18 14:25:05 2016 +0000 +++ b/view/PaneStack.h Thu Apr 21 15:06:05 2016 +0100 @@ -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; };