svgui
1.9
|
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