diff view/Panner.cpp @ 127:89c625dda204

* Reorganising code base. This revision will not compile.
author Chris Cannam
date Mon, 31 Jul 2006 11:44:37 +0000
parents
children 33929e0c3c6b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/view/Panner.cpp	Mon Jul 31 11:44:37 2006 +0000
@@ -0,0 +1,216 @@
+/* -*- 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 Chris Cannam.
+    
+    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 "Panner.h"
+#include "base/Layer.h"
+#include "base/Model.h"
+#include "base/ZoomConstraint.h"
+
+#include <QPaintEvent>
+#include <QPainter>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+Panner::Panner(QWidget *w) :
+    View(w, false),
+    m_clickedInRange(false)
+{
+    setObjectName(tr("Panner"));
+    m_followPan = false;
+    m_followZoom = false;
+}
+
+void
+Panner::modelChanged(size_t startFrame, size_t endFrame)
+{
+    View::modelChanged(startFrame, endFrame);
+}
+
+void
+Panner::modelReplaced()
+{
+    View::modelReplaced();
+}
+
+void
+Panner::registerView(View *widget)
+{
+    m_widgets.insert(widget);
+    update(); 
+}
+
+void
+Panner::unregisterView(View *widget)
+{
+    m_widgets.erase(widget);
+    update();
+}
+
+void
+Panner::viewManagerCentreFrameChanged(void *p, unsigned long f, bool)
+{
+//    std::cerr << "Panner[" << this << "]::viewManagerCentreFrameChanged(" 
+//	      << p << ", " << f << ")" << std::endl;
+
+    if (p == this) return;
+    if (m_widgets.find(p) != m_widgets.end()) {
+	update();
+    }
+}
+
+void
+Panner::viewManagerZoomLevelChanged(void *p, unsigned long z, bool)
+{
+    if (p == this) return;
+    if (m_widgets.find(p) != m_widgets.end()) {
+	update();
+    }
+}
+
+void
+Panner::viewManagerPlaybackFrameChanged(unsigned long f)
+{
+    bool changed = false;
+
+    if (getXForFrame(m_playPointerFrame) != getXForFrame(f)) changed = true;
+    m_playPointerFrame = f;
+
+    if (changed) update();
+}
+
+void
+Panner::paintEvent(QPaintEvent *e)
+{
+    // Recalculate zoom in case the size of the widget has changed.
+
+    size_t startFrame = getModelsStartFrame();
+    size_t frameCount = getModelsEndFrame() - getModelsStartFrame();
+    int zoomLevel = frameCount / width();
+    if (zoomLevel < 1) zoomLevel = 1;
+    zoomLevel = getZoomConstraintBlockSize(zoomLevel,
+					   ZoomConstraint::RoundUp);
+    if (zoomLevel != m_zoomLevel) {
+	m_zoomLevel = zoomLevel;
+	emit zoomLevelChanged(this, m_zoomLevel, m_followZoom);
+    }
+    size_t centreFrame = startFrame + m_zoomLevel * (width() / 2);
+    if (centreFrame > (startFrame + getModelsEndFrame())/2) {
+	centreFrame = (startFrame + getModelsEndFrame())/2;
+    }
+    if (centreFrame != m_centreFrame) {
+	m_centreFrame = centreFrame;
+	emit centreFrameChanged(this, m_centreFrame, false);
+    }
+
+    View::paintEvent(e);
+
+    QPainter paint;
+    paint.begin(this);
+
+    QRect r(rect());
+
+    if (e) {
+	r = e->rect();
+	paint.setClipRect(r);
+    }
+
+    paint.setPen(Qt::black);
+
+    int y = 0;
+
+    int prevx0 = -10;
+    int prevx1 = -10;
+
+    for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
+	if (!*i) continue;
+
+	View *w = (View *)*i;
+
+	long f0 = w->getFrameForX(0);
+	long f1 = w->getFrameForX(w->width());
+
+	int x0 = getXForFrame(f0);
+	int x1 = getXForFrame(f1);
+
+	if (x0 != prevx0 || x1 != prevx1) {
+	    y += height() / 10 + 1;
+	    prevx0 = x0;
+	    prevx1 = x1;
+	}
+
+	if (x1 <= x0) x1 = x0 + 1;
+	
+	paint.drawRect(x0, y, x1 - x0, height() - 2 * y);
+    }
+
+    paint.end();
+}
+
+void
+Panner::mousePressEvent(QMouseEvent *e)
+{
+    m_clickPos = e->pos();
+    for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
+	if (*i) {
+	    m_clickedInRange = true;
+	    m_dragCentreFrame = ((View *)*i)->getCentreFrame();
+	    break;
+	}
+    }
+}
+
+void
+Panner::mouseReleaseEvent(QMouseEvent *e)
+{
+    if (m_clickedInRange) {
+	mouseMoveEvent(e);
+    }
+    m_clickedInRange = false;
+}
+
+void
+Panner::mouseMoveEvent(QMouseEvent *e)
+{
+    if (!m_clickedInRange) return;
+
+    long xoff = int(e->x()) - int(m_clickPos.x());
+    long frameOff = xoff * m_zoomLevel;
+    
+    size_t newCentreFrame = m_dragCentreFrame;
+    if (frameOff > 0) {
+	newCentreFrame += frameOff;
+    } else if (newCentreFrame >= size_t(-frameOff)) {
+	newCentreFrame += frameOff;
+    } else {
+	newCentreFrame = 0;
+    }
+
+    if (newCentreFrame >= getModelsEndFrame()) {
+	newCentreFrame = getModelsEndFrame();
+	if (newCentreFrame > 0) --newCentreFrame;
+    }
+    
+    if (std::max(m_centreFrame, newCentreFrame) -
+	std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
+	emit centreFrameChanged(this, newCentreFrame, true);
+    }
+}
+
+#ifdef INCLUDE_MOCFILES
+#include "Panner.moc.cpp"
+#endif
+