Chris@172
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@172
|
2
|
Chris@172
|
3 /*
|
Chris@172
|
4 Sonic Visualiser
|
Chris@172
|
5 An audio file viewer and annotation editor.
|
Chris@172
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@182
|
7 This file copyright 2006 QMUL.
|
Chris@172
|
8
|
Chris@172
|
9 This program is free software; you can redistribute it and/or
|
Chris@172
|
10 modify it under the terms of the GNU General Public License as
|
Chris@172
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@172
|
12 License, or (at your option) any later version. See the file
|
Chris@172
|
13 COPYING included with this distribution for more information.
|
Chris@172
|
14 */
|
Chris@172
|
15
|
Chris@172
|
16 #include "Panner.h"
|
Chris@172
|
17
|
Chris@172
|
18 #include <QMouseEvent>
|
Chris@172
|
19 #include <QPaintEvent>
|
Chris@172
|
20 #include <QWheelEvent>
|
Chris@172
|
21 #include <QPainter>
|
Chris@172
|
22
|
Chris@172
|
23 #include <iostream>
|
Chris@181
|
24 #include <cmath>
|
Martin@175
|
25
|
Chris@172
|
26 Panner::Panner(QWidget *parent) :
|
Chris@172
|
27 QWidget(parent),
|
Chris@172
|
28 m_rectX(0),
|
Chris@172
|
29 m_rectY(0),
|
Chris@172
|
30 m_rectWidth(1),
|
Chris@173
|
31 m_rectHeight(1),
|
Chris@256
|
32 m_scrollUnit(0),
|
Chris@173
|
33 m_defaultCentreX(0),
|
Chris@173
|
34 m_defaultCentreY(0),
|
Chris@173
|
35 m_defaultsSet(false),
|
Chris@174
|
36 m_thumbColour(palette().highlightedText().color()),
|
Chris@174
|
37 m_backgroundAlpha(255),
|
Chris@174
|
38 m_thumbAlpha(255),
|
Chris@173
|
39 m_clicked(false)
|
Chris@172
|
40 {
|
Chris@172
|
41 }
|
Chris@172
|
42
|
Chris@172
|
43 Panner::~Panner()
|
Chris@172
|
44 {
|
Chris@172
|
45 }
|
Chris@172
|
46
|
Chris@172
|
47 void
|
Chris@174
|
48 Panner::setAlpha(int backgroundAlpha, int thumbAlpha)
|
Chris@174
|
49 {
|
Chris@174
|
50 m_backgroundAlpha = backgroundAlpha;
|
Chris@174
|
51 m_thumbAlpha = thumbAlpha;
|
Chris@174
|
52 }
|
Chris@174
|
53
|
Chris@174
|
54 void
|
Chris@256
|
55 Panner::setScrollUnit(float unit)
|
Chris@256
|
56 {
|
Chris@256
|
57 m_scrollUnit = unit;
|
Chris@256
|
58 }
|
Chris@256
|
59
|
Chris@256
|
60 void
|
Chris@256
|
61 Panner::scroll(bool up)
|
Chris@256
|
62 {
|
Chris@256
|
63 float unit = m_scrollUnit;
|
Chris@256
|
64 if (unit == 0.f) {
|
Chris@256
|
65 unit = float(m_rectHeight) / (6 * float(height()));
|
Chris@256
|
66 if (unit < 0.01) unit = 0.01;
|
Chris@256
|
67 }
|
Chris@256
|
68
|
Chris@256
|
69 if (!up) {
|
Chris@256
|
70 m_rectY += unit;
|
Chris@256
|
71 } else {
|
Chris@256
|
72 m_rectY -= unit;
|
Chris@256
|
73 }
|
Chris@256
|
74
|
Chris@256
|
75 normalise();
|
Chris@256
|
76 emitAndUpdate();
|
Chris@256
|
77 }
|
Chris@256
|
78
|
Chris@256
|
79 void
|
Chris@172
|
80 Panner::mousePressEvent(QMouseEvent *e)
|
Chris@172
|
81 {
|
Chris@188
|
82 if (e->button() == Qt::MidButton ||
|
Chris@188
|
83 ((e->button() == Qt::LeftButton) &&
|
Chris@188
|
84 (e->modifiers() & Qt::ControlModifier))) {
|
Chris@188
|
85 resetToDefault();
|
Chris@188
|
86 } else if (e->button() == Qt::LeftButton) {
|
Chris@173
|
87 m_clicked = true;
|
Chris@173
|
88 m_clickPos = e->pos();
|
Chris@173
|
89 m_dragStartX = m_rectX;
|
Chris@173
|
90 m_dragStartY = m_rectY;
|
Chris@173
|
91 }
|
Chris@172
|
92 }
|
Chris@172
|
93
|
Chris@172
|
94 void
|
Chris@172
|
95 Panner::mouseDoubleClickEvent(QMouseEvent *e)
|
Chris@172
|
96 {
|
Chris@188
|
97 if (e->button() != Qt::LeftButton) {
|
Chris@188
|
98 return;
|
Chris@188
|
99 }
|
Chris@188
|
100
|
Chris@188
|
101 emit doubleClicked();
|
Chris@172
|
102 }
|
Chris@172
|
103
|
Chris@172
|
104 void
|
Chris@172
|
105 Panner::mouseMoveEvent(QMouseEvent *e)
|
Chris@172
|
106 {
|
Chris@173
|
107 if (!m_clicked) return;
|
Chris@173
|
108
|
Chris@173
|
109 float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
|
Chris@173
|
110 float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
|
Chris@173
|
111
|
Chris@173
|
112 m_rectX = m_dragStartX + dx;
|
Chris@173
|
113 m_rectY = m_dragStartY + dy;
|
Chris@173
|
114
|
Chris@173
|
115 normalise();
|
Chris@174
|
116 repaint();
|
Chris@174
|
117 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
|
Chris@174
|
118 emit rectCentreMoved(centreX(), centreY());
|
Chris@172
|
119 }
|
Chris@172
|
120
|
Chris@172
|
121 void
|
Chris@172
|
122 Panner::mouseReleaseEvent(QMouseEvent *e)
|
Chris@172
|
123 {
|
Chris@173
|
124 if (!m_clicked) return;
|
Chris@173
|
125
|
Chris@173
|
126 mouseMoveEvent(e);
|
Chris@173
|
127 m_clicked = false;
|
Chris@172
|
128 }
|
Chris@172
|
129
|
Chris@172
|
130 void
|
Chris@172
|
131 Panner::wheelEvent(QWheelEvent *e)
|
Chris@172
|
132 {
|
Chris@256
|
133 scroll(e->delta() > 0);
|
Chris@172
|
134 }
|
Chris@172
|
135
|
Chris@172
|
136 void
|
Chris@189
|
137 Panner::enterEvent(QEvent *)
|
Chris@189
|
138 {
|
Chris@189
|
139 emit mouseEntered();
|
Chris@189
|
140 }
|
Chris@189
|
141
|
Chris@189
|
142 void
|
Chris@189
|
143 Panner::leaveEvent(QEvent *)
|
Chris@189
|
144 {
|
Chris@189
|
145 emit mouseLeft();
|
Chris@189
|
146 }
|
Chris@189
|
147
|
Chris@189
|
148 void
|
Chris@249
|
149 Panner::paintEvent(QPaintEvent *)
|
Chris@172
|
150 {
|
Chris@172
|
151 QPainter paint(this);
|
Chris@172
|
152 paint.setRenderHint(QPainter::Antialiasing, false);
|
Chris@173
|
153
|
Chris@173
|
154 QColor bg(palette().background().color());
|
Chris@174
|
155 bg.setAlpha(m_backgroundAlpha);
|
Chris@173
|
156
|
Chris@172
|
157 paint.setPen(palette().dark().color());
|
Chris@173
|
158 paint.setBrush(bg);
|
Chris@173
|
159 paint.drawRect(0, 0, width(), height());
|
Chris@173
|
160
|
Chris@174
|
161 QColor hl(m_thumbColour);
|
Chris@174
|
162 hl.setAlpha(m_thumbAlpha);
|
Chris@173
|
163
|
Chris@173
|
164 paint.setBrush(hl);
|
Chris@173
|
165
|
Chris@173
|
166 paint.drawRect(lrintf(width() * m_rectX),
|
Chris@173
|
167 lrintf(height() * m_rectY),
|
Chris@173
|
168 lrintf(width() * m_rectWidth),
|
Chris@173
|
169 lrintf(height() * m_rectHeight));
|
Chris@172
|
170 }
|
Chris@172
|
171
|
Chris@172
|
172 void
|
Chris@172
|
173 Panner::normalise()
|
Chris@172
|
174 {
|
Chris@172
|
175 if (m_rectWidth > 1.0) m_rectWidth = 1.0;
|
Chris@172
|
176 if (m_rectHeight > 1.0) m_rectHeight = 1.0;
|
Chris@172
|
177 if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
|
Chris@172
|
178 if (m_rectX < 0) m_rectX = 0;
|
Chris@172
|
179 if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
|
Chris@172
|
180 if (m_rectY < 0) m_rectY = 0;
|
Chris@173
|
181
|
Chris@173
|
182 if (!m_defaultsSet) {
|
Chris@173
|
183 m_defaultCentreX = centreX();
|
Chris@173
|
184 m_defaultCentreY = centreY();
|
Chris@173
|
185 m_defaultsSet = true;
|
Chris@173
|
186 }
|
Chris@172
|
187 }
|
Chris@172
|
188
|
Chris@172
|
189 void
|
Chris@172
|
190 Panner::emitAndUpdate()
|
Chris@172
|
191 {
|
Chris@172
|
192 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
|
Chris@173
|
193 emit rectCentreMoved(centreX(), centreY());
|
Chris@172
|
194 update();
|
Chris@172
|
195 }
|
Chris@172
|
196
|
Chris@172
|
197 void
|
Chris@188
|
198 Panner::getRectExtents(float &x0, float &y0, float &width, float &height)
|
Chris@188
|
199 {
|
Chris@188
|
200 x0 = m_rectX;
|
Chris@188
|
201 y0 = m_rectY;
|
Chris@188
|
202 width = m_rectWidth;
|
Chris@188
|
203 height = m_rectHeight;
|
Chris@188
|
204 }
|
Chris@188
|
205
|
Chris@188
|
206 void
|
Chris@172
|
207 Panner::setRectExtents(float x0, float y0, float width, float height)
|
Chris@172
|
208 {
|
Chris@249
|
209 // std::cerr << "Panner::setRectExtents(" << x0 << ", " << y0 << ", "
|
Chris@249
|
210 // << width << ", " << height << ")" << std::endl;
|
Chris@174
|
211
|
Chris@172
|
212 if (m_rectX == x0 &&
|
Chris@172
|
213 m_rectY == y0 &&
|
Chris@172
|
214 m_rectWidth == width &&
|
Chris@172
|
215 m_rectHeight == height) {
|
Chris@172
|
216 return;
|
Chris@172
|
217 }
|
Chris@173
|
218
|
Chris@172
|
219 m_rectX = x0;
|
Chris@172
|
220 m_rectY = y0;
|
Chris@172
|
221 m_rectWidth = width;
|
Chris@172
|
222 m_rectHeight = height;
|
Chris@173
|
223
|
Chris@172
|
224 normalise();
|
Chris@172
|
225 emitAndUpdate();
|
Chris@172
|
226 }
|
Chris@172
|
227
|
Chris@172
|
228 void
|
Chris@172
|
229 Panner::setRectWidth(float width)
|
Chris@172
|
230 {
|
Chris@172
|
231 if (m_rectWidth == width) return;
|
Chris@172
|
232 m_rectWidth = width;
|
Chris@172
|
233 normalise();
|
Chris@172
|
234 emitAndUpdate();
|
Chris@172
|
235 }
|
Chris@172
|
236
|
Chris@172
|
237 void
|
Chris@172
|
238 Panner::setRectHeight(float height)
|
Chris@172
|
239 {
|
Chris@172
|
240 if (m_rectHeight == height) return;
|
Chris@172
|
241 m_rectHeight = height;
|
Chris@172
|
242 normalise();
|
Chris@172
|
243 emitAndUpdate();
|
Chris@172
|
244 }
|
Chris@172
|
245
|
Chris@172
|
246 void
|
Chris@172
|
247 Panner::setRectCentreX(float x)
|
Chris@172
|
248 {
|
Chris@172
|
249 float x0 = x - m_rectWidth/2;
|
Chris@172
|
250 if (x0 == m_rectX) return;
|
Chris@172
|
251 m_rectX = x0;
|
Chris@172
|
252 normalise();
|
Chris@172
|
253 emitAndUpdate();
|
Chris@172
|
254 }
|
Chris@172
|
255
|
Chris@172
|
256 void
|
Chris@172
|
257 Panner::setRectCentreY(float y)
|
Chris@172
|
258 {
|
Chris@173
|
259 float y0 = y - m_rectHeight/2;
|
Chris@172
|
260 if (y0 == m_rectY) return;
|
Chris@172
|
261 m_rectY = y0;
|
Chris@172
|
262 normalise();
|
Chris@172
|
263 emitAndUpdate();
|
Chris@172
|
264 }
|
Chris@172
|
265
|
Chris@172
|
266 QSize
|
Chris@172
|
267 Panner::sizeHint() const
|
Chris@172
|
268 {
|
Chris@172
|
269 return QSize(30, 30);
|
Chris@172
|
270 }
|
Chris@172
|
271
|
Chris@173
|
272 void
|
Chris@173
|
273 Panner::setDefaultRectCentre(float cx, float cy)
|
Chris@173
|
274 {
|
Chris@173
|
275 m_defaultCentreX = cx;
|
Chris@173
|
276 m_defaultCentreY = cy;
|
Chris@173
|
277 m_defaultsSet = true;
|
Chris@173
|
278 }
|
Chris@172
|
279
|
Chris@173
|
280 void
|
Chris@173
|
281 Panner::resetToDefault()
|
Chris@173
|
282 {
|
Chris@173
|
283 float x0 = m_defaultCentreX - m_rectWidth/2;
|
Chris@173
|
284 float y0 = m_defaultCentreY - m_rectHeight/2;
|
Chris@173
|
285 if (x0 == m_rectX && y0 == m_rectY) return;
|
Chris@173
|
286 m_rectX = x0;
|
Chris@173
|
287 m_rectY = y0;
|
Chris@173
|
288 normalise();
|
Chris@173
|
289 emitAndUpdate();
|
Chris@173
|
290 }
|
Chris@172
|
291
|
Chris@173
|
292
|