svgui  1.9
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     m_dragStartX(0),
00041     m_dragStartY(0)
00042 {
00043 }
00044 
00045 Panner::~Panner()
00046 {
00047 }
00048 
00049 void
00050 Panner::setAlpha(int backgroundAlpha, int thumbAlpha)
00051 {
00052     m_backgroundAlpha = backgroundAlpha;
00053     m_thumbAlpha = thumbAlpha;
00054 }
00055 
00056 void
00057 Panner::setScrollUnit(float unit)
00058 {
00059     m_scrollUnit = unit;
00060 }
00061 
00062 void
00063 Panner::scroll(bool up)
00064 {
00065     float unit = m_scrollUnit;
00066     if (unit == 0.f) {
00067         unit = float(m_rectHeight) / (6 * float(height()));
00068         if (unit < 0.01) unit = 0.01;
00069     }
00070 
00071     if (!up) {
00072         m_rectY += unit;
00073     } else {
00074         m_rectY -= unit;
00075     }
00076 
00077     normalise();
00078     emitAndUpdate();
00079 }
00080 
00081 void
00082 Panner::mousePressEvent(QMouseEvent *e)
00083 {
00084     if (e->button() == Qt::MidButton ||
00085         ((e->button() == Qt::LeftButton) &&
00086          (e->modifiers() & Qt::ControlModifier))) {
00087         resetToDefault();
00088     } else if (e->button() == Qt::LeftButton) {
00089         m_clicked = true;
00090         m_clickPos = e->pos();
00091         m_dragStartX = m_rectX;
00092         m_dragStartY = m_rectY;
00093     }
00094 }
00095 
00096 void
00097 Panner::mouseDoubleClickEvent(QMouseEvent *e)
00098 {
00099     if (e->button() != Qt::LeftButton) {
00100         return;
00101     }
00102 
00103     emit doubleClicked();
00104 }
00105 
00106 void
00107 Panner::mouseMoveEvent(QMouseEvent *e)
00108 {
00109     if (!m_clicked) return;
00110 
00111     float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
00112     float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
00113     
00114     m_rectX = m_dragStartX + dx;
00115     m_rectY = m_dragStartY + dy;
00116     
00117     normalise();
00118     repaint();
00119     emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
00120     emit rectCentreMoved(centreX(), centreY());
00121 }
00122 
00123 void
00124 Panner::mouseReleaseEvent(QMouseEvent *e)
00125 {
00126     if (!m_clicked) return;
00127 
00128     mouseMoveEvent(e);
00129     m_clicked = false;
00130 }
00131 
00132 void
00133 Panner::wheelEvent(QWheelEvent *e)
00134 {
00135     scroll(e->delta() > 0);
00136 }
00137 
00138 void
00139 Panner::enterEvent(QEvent *)
00140 {
00141     emit mouseEntered();
00142 }
00143 
00144 void
00145 Panner::leaveEvent(QEvent *)
00146 {
00147     emit mouseLeft();
00148 }
00149 
00150 void
00151 Panner::paintEvent(QPaintEvent *)
00152 {
00153     QPainter paint(this);
00154     paint.setRenderHint(QPainter::Antialiasing, false);
00155 
00156     QColor bg(palette().background().color());
00157     bg.setAlpha(m_backgroundAlpha);
00158 
00159     paint.setPen(palette().dark().color());
00160     paint.setBrush(bg);
00161     paint.drawRect(0, 0, width()-1, height()-1);
00162 
00163     QColor hl(m_thumbColour);
00164     hl.setAlpha(m_thumbAlpha);
00165 
00166     paint.setBrush(hl);
00167 
00168     int rw = lrintf((width() - 1) * m_rectWidth);
00169     int rh = lrintf((height() - 1) * m_rectHeight);
00170     if (rw < 2) rw = 2;
00171     if (rh < 2) rh = 2;
00172 
00173     paint.drawRect(lrintf(width() * m_rectX),
00174                    lrintf(height() * m_rectY),
00175                    rw, rh);
00176 }
00177 
00178 void
00179 Panner::normalise()
00180 {
00181     if (m_rectWidth > 1.0) m_rectWidth = 1.0;
00182     if (m_rectHeight > 1.0) m_rectHeight = 1.0;
00183     if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
00184     if (m_rectX < 0) m_rectX = 0;
00185     if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
00186     if (m_rectY < 0) m_rectY = 0;
00187 
00188     if (!m_defaultsSet) {
00189         m_defaultCentreX = centreX();
00190         m_defaultCentreY = centreY();
00191         m_defaultsSet = true;
00192     }
00193 }
00194 
00195 void
00196 Panner::emitAndUpdate()
00197 {
00198     emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
00199     emit rectCentreMoved(centreX(), centreY());
00200     update();
00201 }  
00202 
00203 void
00204 Panner::getRectExtents(float &x0, float &y0, float &width, float &height)
00205 {
00206     x0 = m_rectX;
00207     y0 = m_rectY;
00208     width = m_rectWidth;
00209     height = m_rectHeight;
00210 }
00211 
00212 void
00213 Panner::setRectExtents(float x0, float y0, float width, float height)
00214 {
00215 //    SVDEBUG << "Panner::setRectExtents(" << x0 << ", " << y0 << ", "
00216 //              << width << ", " << height << ")" << endl;
00217 
00218     if (m_rectX == x0 &&
00219         m_rectY == y0 &&
00220         m_rectWidth == width &&
00221         m_rectHeight == height) {
00222         return;
00223     }
00224 
00225     m_rectX = x0;
00226     m_rectY = y0;
00227     m_rectWidth = width;
00228     m_rectHeight = height;
00229 
00230     normalise();
00231     emitAndUpdate();
00232 }
00233 
00234 void
00235 Panner::setRectWidth(float width)
00236 {
00237     if (m_rectWidth == width) return;
00238     m_rectWidth = width;
00239     normalise();
00240     emitAndUpdate();
00241 }
00242 
00243 void
00244 Panner::setRectHeight(float height)
00245 {
00246     if (m_rectHeight == height) return;
00247     m_rectHeight = height;
00248     normalise();
00249     emitAndUpdate();
00250 }
00251 
00252 void
00253 Panner::setRectCentreX(float x)
00254 {
00255     float x0 = x - m_rectWidth/2;
00256     if (x0 == m_rectX) return;
00257     m_rectX = x0;
00258     normalise();
00259     emitAndUpdate();
00260 }
00261 
00262 void
00263 Panner::setRectCentreY(float y)
00264 {
00265     float y0 = y - m_rectHeight/2;
00266     if (y0 == m_rectY) return;
00267     m_rectY = y0;
00268     normalise();
00269     emitAndUpdate();
00270 }
00271 
00272 QSize
00273 Panner::sizeHint() const
00274 {
00275     return QSize(30, 30);
00276 }
00277 
00278 void
00279 Panner::setDefaultRectCentre(float cx, float cy)
00280 {
00281     m_defaultCentreX = cx;
00282     m_defaultCentreY = cy;
00283     m_defaultsSet = true;
00284 }
00285 
00286 void
00287 Panner::resetToDefault()
00288 {
00289     float x0 = m_defaultCentreX - m_rectWidth/2;
00290     float y0 = m_defaultCentreY - m_rectHeight/2;
00291     if (x0 == m_rectX && y0 == m_rectY) return;
00292     m_rectX = x0;
00293     m_rectY = y0;
00294     normalise();
00295     emitAndUpdate();
00296 }
00297 
00298