changeset 211:e2baee498ec8

* Rejig handling of scrolling views. Ensures, among other things, that playing when there is a scroll mode view present (e.g. a spectrum) does not drag any page mode views into scroll mode with it.
author Chris Cannam
date Thu, 01 Mar 2007 11:55:46 +0000
parents 748985c7e2c1
children e554ab9a4408
files view/Overview.cpp view/Overview.h view/View.cpp view/View.h view/ViewManager.cpp view/ViewManager.h
diffstat 6 files changed, 130 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/view/Overview.cpp	Wed Feb 28 11:20:14 2007 +0000
+++ b/view/Overview.cpp	Thu Mar 01 11:55:46 2007 +0000
@@ -32,6 +32,7 @@
     setObjectName(tr("Overview"));
     m_followPan = false;
     m_followZoom = false;
+    setPlaybackFollow(PlaybackIgnore);
 }
 
 void
@@ -47,36 +48,39 @@
 }
 
 void
-Overview::registerView(View *widget)
+Overview::registerView(View *view)
 {
-    m_widgets.insert(widget);
+    m_views.insert(view);
     update(); 
 }
 
 void
-Overview::unregisterView(View *widget)
+Overview::unregisterView(View *view)
 {
-    m_widgets.erase(widget);
+    m_views.erase(view);
     update();
 }
 
 void
-Overview::viewManagerCentreFrameChanged(void *p, unsigned long f, bool)
+Overview::globalCentreFrameChanged(unsigned long f)
 {
-//    std::cerr << "Overview[" << this << "]::viewManagerCentreFrameChanged(" 
-//	      << p << ", " << f << ")" << std::endl;
+    update();
+}
 
-    if (p == this) return;
-    if (m_widgets.find(p) != m_widgets.end()) {
+void
+Overview::viewCentreFrameChanged(View *v, unsigned long f)
+{
+    if (m_views.find(v) != m_views.end()) {
 	update();
     }
-}
+}    
 
 void
 Overview::viewManagerZoomLevelChanged(void *p, unsigned long z, bool)
 {
     if (p == this) return;
-    if (m_widgets.find(p) != m_widgets.end()) {
+    View *v = (View *)p;
+    if (m_views.find(v) != m_views.end()) {
 	update();
     }
 }
@@ -113,7 +117,7 @@
     }
     if (centreFrame != m_centreFrame) {
 	m_centreFrame = centreFrame;
-	emit centreFrameChanged(this, m_centreFrame, false);
+	emit centreFrameChanged(m_centreFrame, false, PlaybackIgnore);
     }
 
     View::paintEvent(e);
@@ -135,7 +139,7 @@
     int prevx0 = -10;
     int prevx1 = -10;
 
-    for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
+    for (ViewSet::iterator i = m_views.begin(); i != m_views.end(); ++i) {
 	if (!*i) continue;
 
 	View *w = (View *)*i;
@@ -164,7 +168,7 @@
 Overview::mousePressEvent(QMouseEvent *e)
 {
     m_clickPos = e->pos();
-    for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
+    for (ViewSet::iterator i = m_views.begin(); i != m_views.end(); ++i) {
 	if (*i) {
 	    m_clickedInRange = true;
 	    m_dragCentreFrame = ((View *)*i)->getCentreFrame();
@@ -206,7 +210,7 @@
     
     if (std::max(m_centreFrame, newCentreFrame) -
 	std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
-	emit centreFrameChanged(this, newCentreFrame, true);
+	emit centreFrameChanged(newCentreFrame, true, PlaybackIgnore);
     }
 }
 
@@ -214,7 +218,7 @@
 Overview::mouseDoubleClickEvent(QMouseEvent *e)
 {
     long frame = getFrameForX(e->x());
-    emit centreFrameChanged(this, frame, true);
+    emit centreFrameChanged(frame, true, PlaybackIgnore);
 }
 
 void
--- a/view/Overview.h	Wed Feb 28 11:20:14 2007 +0000
+++ b/view/Overview.h	Thu Mar 01 11:55:46 2007 +0000
@@ -34,8 +34,8 @@
 public:
     Overview(QWidget *parent = 0);
 
-    void registerView(View *widget);
-    void unregisterView(View *widget);
+    void registerView(View *view);
+    void unregisterView(View *view);
 
     virtual QString getPropertyContainerIconName() const { return "panner"; }
 
@@ -43,7 +43,8 @@
     virtual void modelChanged(size_t startFrame, size_t endFrame);
     virtual void modelReplaced();
 
-    virtual void viewManagerCentreFrameChanged(void *, unsigned long, bool);
+    virtual void globalCentreFrameChanged(unsigned long);
+    virtual void viewCentreFrameChanged(View *, unsigned long);
     virtual void viewManagerZoomLevelChanged(void *, unsigned long, bool);
     virtual void viewManagerPlaybackFrameChanged(unsigned long);
 
@@ -62,8 +63,8 @@
     bool m_clickedInRange;
     size_t m_dragCentreFrame;
     
-    typedef std::set<void *> WidgetSet;
-    WidgetSet m_widgets;
+    typedef std::set<View *> ViewSet;
+    ViewSet m_views;
 };
 
 #endif
--- a/view/View.cpp	Wed Feb 28 11:20:14 2007 +0000
+++ b/view/View.cpp	Thu Mar 01 11:55:46 2007 +0000
@@ -327,7 +327,7 @@
 	    changeVisible = true;
 	}
 
-	if (e) emit centreFrameChanged(this, f, m_followPan);
+	if (e) emit centreFrameChanged(f, m_followPan, m_followPlay);
     }
 
     return changeVisible;
@@ -531,25 +531,32 @@
 View::setViewManager(ViewManager *manager)
 {
     if (m_manager) {
-	m_manager->disconnect(this, SLOT(viewManagerCentreFrameChanged(void *, unsigned long, bool)));
+	m_manager->disconnect(this, SLOT(globalCentreFrameChanged(unsigned long)));
+	m_manager->disconnect(this, SLOT(viewCentreFrameChanged(View *, unsigned long)));
+	m_manager->disconnect(this, SLOT(viewManagerPlaybackFrameChanged(unsigned long)));
 	m_manager->disconnect(this, SLOT(viewManagerZoomLevelChanged(void *, unsigned long, bool)));
-	disconnect(m_manager, SIGNAL(centreFrameChanged(void *, unsigned long, bool)));
+        m_manager->disconnect(this, SLOT(toolModeChanged()));
+        m_manager->disconnect(this, SLOT(selectionChanged()));
+        m_manager->disconnect(this, SLOT(overlayModeChanged()));
+        m_manager->disconnect(this, SLOT(zoomWheelsEnabledChanged()));
+        disconnect(m_manager, SIGNAL(viewCentreFrameChanged(unsigned long, bool, PlaybackFollowMode)));
 	disconnect(m_manager, SIGNAL(zoomLevelChanged(void *, unsigned long, bool)));
-	disconnect(m_manager, SIGNAL(toolModeChanged()));
-	disconnect(m_manager, SIGNAL(selectionChanged()));
-	disconnect(m_manager, SIGNAL(inProgressSelectionChanged()));
     }
 
     m_manager = manager;
     if (m_followPan) setCentreFrame(m_manager->getGlobalCentreFrame(), false);
     if (m_followZoom) setZoomLevel(m_manager->getGlobalZoom());
 
-    connect(m_manager, SIGNAL(centreFrameChanged(void *, unsigned long, bool)),
-	    this, SLOT(viewManagerCentreFrameChanged(void *, unsigned long, bool)));
+    connect(m_manager, SIGNAL(globalCentreFrameChanged(unsigned long)),
+	    this, SLOT(globalCentreFrameChanged(unsigned long)));
+    connect(m_manager, SIGNAL(viewCentreFrameChanged(unsigned long)),
+	    this, SLOT(viewCentreFrameChanged(View *, unsigned long)));
     connect(m_manager, SIGNAL(playbackFrameChanged(unsigned long)),
 	    this, SLOT(viewManagerPlaybackFrameChanged(unsigned long)));
+
     connect(m_manager, SIGNAL(zoomLevelChanged(void *, unsigned long, bool)),
 	    this, SLOT(viewManagerZoomLevelChanged(void *, unsigned long, bool)));
+
     connect(m_manager, SIGNAL(toolModeChanged()),
 	    this, SLOT(toolModeChanged()));
     connect(m_manager, SIGNAL(selectionChanged()),
@@ -561,8 +568,11 @@
     connect(m_manager, SIGNAL(zoomWheelsEnabledChanged()),
             this, SLOT(zoomWheelsEnabledChanged()));
 
-    connect(this, SIGNAL(centreFrameChanged(void *, unsigned long, bool)),
-	    m_manager, SIGNAL(centreFrameChanged(void *, unsigned long, bool)));
+    connect(this, SIGNAL(centreFrameChanged(unsigned long, bool,
+                                            PlaybackFollowMode)),
+            m_manager, SLOT(viewCentreFrameChanged(unsigned long, bool,
+                                                   PlaybackFollowMode)));
+
     connect(this, SIGNAL(zoomLevelChanged(void *, unsigned long, bool)),
 	    m_manager, SIGNAL(zoomLevelChanged(void *, unsigned long, bool)));
 
@@ -705,14 +715,9 @@
     if (long(startFrame) < myStartFrame) startFrame = myStartFrame;
     if (endFrame > myEndFrame) endFrame = myEndFrame;
 
-    int x0 = getXForFrame(startFrame);
-    int x1 = getXForFrame(endFrame + 1);
-    if (x1 < x0) x1 = x0;
-
     checkProgress(obj);
 
     update();
-//!!!    update(x0, 0, x1 - x0 + 1, height());
 }    
 
 void
@@ -767,20 +772,20 @@
 }
 
 void
-View::viewManagerCentreFrameChanged(void *p, unsigned long f, bool locked)
+View::globalCentreFrameChanged(unsigned long f)
 {
-    if (m_followPan && p != this && locked) {
-	if (m_manager && (sender() == m_manager)) {
-#ifdef DEBUG_VIEW_WIDGET_PAINT
-	    std::cerr << this << ": manager frame changed " << f << " from " << p << std::endl;
-#endif
-	    setCentreFrame(f);
-	    if (p == this) repaint();
-	}
+    if (m_followPan) {
+        setCentreFrame(f, false);
     }
 }
 
 void
+View::viewCentreFrameChanged(View *v, unsigned long f)
+{
+    // We do nothing with this, but a subclass might
+}
+
+void
 View::viewManagerPlaybackFrameChanged(unsigned long f)
 {
     if (m_manager) {
@@ -797,7 +802,7 @@
 
     case PlaybackScrollContinuous:
 	if (QApplication::mouseButtons() == Qt::NoButton) {
-	    setCentreFrame(f, true); //!!!
+	    setCentreFrame(f, false);
 	}
 	break;
 
@@ -1391,23 +1396,32 @@
     }
     paint.end();
 
-    if (m_followPlay != PlaybackScrollContinuous) {
+    bool showPlayPointer = true;
+    if (m_followPlay == PlaybackScrollContinuous) {
+        showPlayPointer = false;
+    } else if (long(m_playPointerFrame) <= getStartFrame() ||
+               m_playPointerFrame >= getEndFrame()) {
+        showPlayPointer = false;
+    } else if (m_manager && !m_manager->isPlaying()) {
+        if (m_playPointerFrame == getCentreFrame() &&
+            m_followPlay != PlaybackIgnore) {
+            showPlayPointer = false;
+        }
+    }
+
+    if (showPlayPointer) {
 
 	paint.begin(this);
 
-	if (long(m_playPointerFrame) > getStartFrame() &&
-	    m_playPointerFrame < getEndFrame()) {
-
-	    int playx = getXForFrame(m_playPointerFrame);
-
-	    paint.setPen(Qt::black);
-	    paint.drawLine(playx - 1, 0, playx - 1, height() - 1);
-	    paint.drawLine(playx + 1, 0, playx + 1, height() - 1);
-	    paint.drawPoint(playx, 0);
-	    paint.drawPoint(playx, height() - 1);
-	    paint.setPen(Qt::white);
-	    paint.drawLine(playx, 1, playx, height() - 2);
-	}
+        int playx = getXForFrame(m_playPointerFrame);
+        
+        paint.setPen(Qt::black);
+        paint.drawLine(playx - 1, 0, playx - 1, height() - 1);
+        paint.drawLine(playx + 1, 0, playx + 1, height() - 1);
+        paint.drawPoint(playx, 0);
+        paint.drawPoint(playx, height() - 1);
+        paint.setPen(Qt::white);
+        paint.drawLine(playx, 1, playx, height() - 2);
 
 	paint.end();
     }
--- a/view/View.h	Wed Feb 28 11:20:14 2007 +0000
+++ b/view/View.h	Thu Mar 01 11:55:46 2007 +0000
@@ -189,11 +189,6 @@
 	return false;
     }
 
-    enum PlaybackFollowMode {
-	PlaybackScrollContinuous,
-	PlaybackScrollPage,
-	PlaybackIgnore
-    };
     virtual void setPlaybackFollow(PlaybackFollowMode m);
     virtual PlaybackFollowMode getPlaybackFollow() const { return m_followPlay; }
 
@@ -240,7 +235,10 @@
     void propertyContainerNameChanged(PropertyContainer *pc);
     void propertyChanged(PropertyContainer::PropertyName);
 
-    void centreFrameChanged(void *, unsigned long, bool);
+    void centreFrameChanged(unsigned long frame,
+                            bool globalScroll,
+                            PlaybackFollowMode followMode);
+
     void zoomLevelChanged(void *, unsigned long, bool);
 
     void contextHelpChanged(const QString &);
@@ -254,7 +252,8 @@
     virtual void layerParameterRangesChanged();
     virtual void layerNameChanged();
 
-    virtual void viewManagerCentreFrameChanged(void *, unsigned long, bool);
+    virtual void globalCentreFrameChanged(unsigned long);
+    virtual void viewCentreFrameChanged(View *, unsigned long);
     virtual void viewManagerPlaybackFrameChanged(unsigned long);
     virtual void viewManagerZoomLevelChanged(void *, unsigned long, bool);
 
--- a/view/ViewManager.cpp	Wed Feb 28 11:20:14 2007 +0000
+++ b/view/ViewManager.cpp	Thu Mar 01 11:55:46 2007 +0000
@@ -17,6 +17,7 @@
 #include "base/AudioPlaySource.h"
 #include "data/model/Model.h"
 #include "base/CommandHistory.h"
+#include "View.h"
 
 #include <QSettings>
 
@@ -48,10 +49,6 @@
     settings.endGroup();
 
     connect(this, 
-	    SIGNAL(centreFrameChanged(void *, unsigned long, bool)),
-	    SLOT(considerSeek(void *, unsigned long, bool)));
-
-    connect(this, 
 	    SIGNAL(zoomLevelChanged(void *, unsigned long, bool)),
 	    SLOT(considerZoomChange(void *, unsigned long, bool)));
 }
@@ -76,6 +73,7 @@
     std::cout << "ViewManager::setGlobalCentreFrame to " << f << std::endl;
 #endif
     m_globalCentreFrame = f;
+    emit globalCentreFrameChanged(f);
 }
 
 unsigned long
@@ -335,18 +333,32 @@
 }
 
 void
-ViewManager::considerSeek(void *p, unsigned long f, bool locked)
+ViewManager::viewCentreFrameChanged(unsigned long f, bool locked,
+                                    PlaybackFollowMode mode)
 {
+    View *v = dynamic_cast<View *>(sender());
+
     if (locked) {
-	m_globalCentreFrame = f;
+        m_globalCentreFrame = f;
+        emit globalCentreFrameChanged(f);
+    } else {
+        if (v) emit viewCentreFrameChanged(v, f);
     }
 
+    if (mode == PlaybackIgnore) {
+        return;
+    }
+
+    seek(f);
+}
+
+void
+ViewManager::seek(unsigned long f)
+{
 #ifdef DEBUG_VIEW_MANAGER 
-    std::cout << "ViewManager::considerSeek(" << p << ", " << f << ", " << locked << ")" << std::endl;
+    std::cout << "ViewManager::seek(" << f << ")" << std::endl;
 #endif
 
-    if (p == this || !locked) return;
-
     if (m_playSource && m_playSource->isPlaying()) {
 	unsigned long playFrame = m_playSource->getCurrentPlayingFrame();
 	unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame);
@@ -356,9 +368,13 @@
 #ifdef DEBUG_VIEW_MANAGER 
 	    std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl;
 #endif
+            emit playbackFrameChanged(f);
 	}
     } else {
-	m_playbackFrame = f; //!!! only if that view is in scroll mode?
+        if (m_playbackFrame != f) {
+            m_playbackFrame = f;
+            emit playbackFrameChanged(f);
+        }
     }
 }
 
--- a/view/ViewManager.h	Wed Feb 28 11:20:14 2007 +0000
+++ b/view/ViewManager.h	Thu Mar 01 11:55:46 2007 +0000
@@ -28,6 +28,14 @@
 class AudioPlaySource;
 class Model;
 
+enum PlaybackFollowMode {
+    PlaybackScrollContinuous,
+    PlaybackScrollPage,
+    PlaybackIgnore
+};
+
+class View;
+
 /**
  * The ViewManager manages properties that may need to be synchronised
  * between separate Views.  For example, it handles signals associated
@@ -133,13 +141,16 @@
     bool getZoomWheelsEnabled() const { return m_zoomWheelsEnabled; }
 
 signals:
-    /** Emitted when a widget pans.  The originator identifies the widget. */
-    void centreFrameChanged(void *originator, unsigned long frame, bool locked);
+    /** Emitted when user causes the global centre frame to change. */
+    void globalCentreFrameChanged(unsigned long frame);
 
-    /** Emitted when a widget zooms.  The originator identifies the widget. */
+    /** Emitted when user scrolls a view, but doesn't affect global centre. */
+    void viewCentreFrameChanged(View *v, unsigned long frame);
+
+    /** Emitted when a view zooms.  The originator identifies the view. */
     void zoomLevelChanged(void *originator, unsigned long zoom, bool locked);
 
-    /** Emitted when a widget zooms. */
+    /** Emitted when a view zooms. */
     void zoomLevelChanged();
 
     /** Emitted when the playback frame changes. */
@@ -171,10 +182,13 @@
     /** Emitted when the zoom wheels have been toggled. */
     void zoomWheelsEnabledChanged();
 
+public slots:
+    void viewCentreFrameChanged(unsigned long, bool, PlaybackFollowMode);
+
 protected slots:
     void checkPlayStatus();
     void playStatusChanged(bool playing);
-    void considerSeek(void *, unsigned long, bool);
+    void seek(unsigned long);
     void considerZoomChange(void *, unsigned long, bool);
 
 protected: