Panner.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "Panner.h"
00017 
00018 #include <QMouseEvent>
00019 #include <QPaintEvent>
00020 #include <QWheelEvent>
00021 #include <QPainter>
00022 
00023 #include <iostream>
00024 #include <cmath>
00025 
00026 Panner::Panner(QWidget *parent) :
00027     QWidget(parent),
00028     m_rectX(0),
00029     m_rectY(0),
00030     m_rectWidth(1),
00031     m_rectHeight(1),
00032     m_scrollUnit(0),
00033     m_defaultCentreX(0),
00034     m_defaultCentreY(0),
00035     m_defaultsSet(false),
00036     m_thumbColour(palette().highlightedText().color()),
00037     m_backgroundAlpha(255),
00038     m_thumbAlpha(255),
00039     m_clicked(false)
00040 {
00041 }
00042 
00043 Panner::~Panner()
00044 {
00045 }
00046 
00047 void
00048 Panner::setAlpha(int backgroundAlpha, int thumbAlpha)
00049 {
00050     m_backgroundAlpha = backgroundAlpha;
00051     m_thumbAlpha = thumbAlpha;
00052 }
00053 
00054 void
00055 Panner::setScrollUnit(float unit)
00056 {
00057     m_scrollUnit = unit;
00058 }
00059 
00060 void
00061 Panner::scroll(bool up)
00062 {
00063     float unit = m_scrollUnit;
00064     if (unit == 0.f) {
00065         unit = float(m_rectHeight) / (6 * float(height()));
00066         if (unit < 0.01) unit = 0.01;
00067     }
00068 
00069     if (!up) {
00070         m_rectY += unit;
00071     } else {
00072         m_rectY -= unit;
00073     }
00074 
00075     normalise();
00076     emitAndUpdate();
00077 }
00078 
00079 void
00080 Panner::mousePressEvent(QMouseEvent *e)
00081 {
00082     if (e->button() == Qt::MidButton ||
00083         ((e->button() == Qt::LeftButton) &&
00084          (e->modifiers() & Qt::ControlModifier))) {
00085         resetToDefault();
00086     } else if (e->button() == Qt::LeftButton) {
00087         m_clicked = true;
00088         m_clickPos = e->pos();
00089         m_dragStartX = m_rectX;
00090         m_dragStartY = m_rectY;
00091     }
00092 }
00093 
00094 void
00095 Panner::mouseDoubleClickEvent(QMouseEvent *e)
00096 {
00097     if (e->button() != Qt::LeftButton) {
00098         return;
00099     }
00100 
00101     emit doubleClicked();
00102 }
00103 
00104 void
00105 Panner::mouseMoveEvent(QMouseEvent *e)
00106 {
00107     if (!m_clicked) return;
00108 
00109     float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
00110     float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
00111     
00112     m_rectX = m_dragStartX + dx;
00113     m_rectY = m_dragStartY + dy;
00114     
00115     normalise();
00116     repaint();
00117     emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
00118     emit rectCentreMoved(centreX(), centreY());
00119 }
00120 
00121 void
00122 Panner::mouseReleaseEvent(QMouseEvent *e)
00123 {
00124     if (!m_clicked) return;
00125 
00126     mouseMoveEvent(e);
00127     m_clicked = false;
00128 }
00129 
00130 void
00131 Panner::wheelEvent(QWheelEvent *e)
00132 {
00133     scroll(e->delta() > 0);
00134 }
00135 
00136 void
00137 Panner::enterEvent(QEvent *)
00138 {
00139     emit mouseEntered();
00140 }
00141 
00142 void
00143 Panner::leaveEvent(QEvent *)
00144 {
00145     emit mouseLeft();
00146 }
00147 
00148 void
00149 Panner::paintEvent(QPaintEvent *)
00150 {
00151     QPainter paint(this);
00152     paint.setRenderHint(QPainter::Antialiasing, false);
00153 
00154     QColor bg(palette().background().color());
00155     bg.setAlpha(m_backgroundAlpha);
00156 
00157     paint.setPen(palette().dark().color());
00158     paint.setBrush(bg);
00159     paint.drawRect(0, 0, width(), height());
00160 
00161     QColor hl(m_thumbColour);
00162     hl.setAlpha(m_thumbAlpha);
00163 
00164     paint.setBrush(hl);
00165 
00166     paint.drawRect(lrintf(width() * m_rectX),
00167                    lrintf(height() * m_rectY),
00168                    lrintf(width() * m_rectWidth),
00169                    lrintf(height() * m_rectHeight));
00170 }
00171 
00172 void
00173 Panner::normalise()
00174 {
00175     if (m_rectWidth > 1.0) m_rectWidth = 1.0;
00176     if (m_rectHeight > 1.0) m_rectHeight = 1.0;
00177     if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
00178     if (m_rectX < 0) m_rectX = 0;
00179     if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
00180     if (m_rectY < 0) m_rectY = 0;
00181 
00182     if (!m_defaultsSet) {
00183         m_defaultCentreX = centreX();
00184         m_defaultCentreY = centreY();
00185         m_defaultsSet = true;
00186     }
00187 }
00188 
00189 void
00190 Panner::emitAndUpdate()
00191 {
00192     emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
00193     emit rectCentreMoved(centreX(), centreY());
00194     update();
00195 }  
00196 
00197 void
00198 Panner::getRectExtents(float &x0, float &y0, float &width, float &height)
00199 {
00200     x0 = m_rectX;
00201     y0 = m_rectY;
00202     width = m_rectWidth;
00203     height = m_rectHeight;
00204 }
00205 
00206 void
00207 Panner::setRectExtents(float x0, float y0, float width, float height)
00208 {
00209 //    std::cerr << "Panner::setRectExtents(" << x0 << ", " << y0 << ", "
00210 //              << width << ", " << height << ")" << std::endl;
00211 
00212     if (m_rectX == x0 &&
00213         m_rectY == y0 &&
00214         m_rectWidth == width &&
00215         m_rectHeight == height) {
00216         return;
00217     }
00218 
00219     m_rectX = x0;
00220     m_rectY = y0;
00221     m_rectWidth = width;
00222     m_rectHeight = height;
00223 
00224     normalise();
00225     emitAndUpdate();
00226 }
00227 
00228 void
00229 Panner::setRectWidth(float width)
00230 {
00231     if (m_rectWidth == width) return;
00232     m_rectWidth = width;
00233     normalise();
00234     emitAndUpdate();
00235 }
00236 
00237 void
00238 Panner::setRectHeight(float height)
00239 {
00240     if (m_rectHeight == height) return;
00241     m_rectHeight = height;
00242     normalise();
00243     emitAndUpdate();
00244 }
00245 
00246 void
00247 Panner::setRectCentreX(float x)
00248 {
00249     float x0 = x - m_rectWidth/2;
00250     if (x0 == m_rectX) return;
00251     m_rectX = x0;
00252     normalise();
00253     emitAndUpdate();
00254 }
00255 
00256 void
00257 Panner::setRectCentreY(float y)
00258 {
00259     float y0 = y - m_rectHeight/2;
00260     if (y0 == m_rectY) return;
00261     m_rectY = y0;
00262     normalise();
00263     emitAndUpdate();
00264 }
00265 
00266 QSize
00267 Panner::sizeHint() const
00268 {
00269     return QSize(30, 30);
00270 }
00271 
00272 void
00273 Panner::setDefaultRectCentre(float cx, float cy)
00274 {
00275     m_defaultCentreX = cx;
00276     m_defaultCentreY = cy;
00277     m_defaultsSet = true;
00278 }
00279 
00280 void
00281 Panner::resetToDefault()
00282 {
00283     float x0 = m_defaultCentreX - m_rectWidth/2;
00284     float y0 = m_defaultCentreY - m_rectHeight/2;
00285     if (x0 == m_rectX && y0 == m_rectY) return;
00286     m_rectX = x0;
00287     m_rectY = y0;
00288     normalise();
00289     emitAndUpdate();
00290 }
00291 
00292 

Generated on Wed Feb 20 15:45:27 2008 for SonicVisualiser by  doxygen 1.5.1