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@172
|
7 This file copyright 2006 Chris Cannam.
|
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@172
|
24
|
Chris@172
|
25 Panner::Panner(QWidget *parent) :
|
Chris@172
|
26 QWidget(parent),
|
Chris@172
|
27 m_rectX(0),
|
Chris@172
|
28 m_rectY(0),
|
Chris@172
|
29 m_rectWidth(1),
|
Chris@173
|
30 m_rectHeight(1),
|
Chris@173
|
31 m_defaultCentreX(0),
|
Chris@173
|
32 m_defaultCentreY(0),
|
Chris@173
|
33 m_defaultsSet(false),
|
Chris@173
|
34 m_clicked(false)
|
Chris@172
|
35 {
|
Chris@172
|
36 }
|
Chris@172
|
37
|
Chris@172
|
38 Panner::~Panner()
|
Chris@172
|
39 {
|
Chris@172
|
40 }
|
Chris@172
|
41
|
Chris@172
|
42 void
|
Chris@172
|
43 Panner::mousePressEvent(QMouseEvent *e)
|
Chris@172
|
44 {
|
Chris@173
|
45 if (e->button() == Qt::LeftButton) {
|
Chris@173
|
46 m_clicked = true;
|
Chris@173
|
47 m_clickPos = e->pos();
|
Chris@173
|
48 m_dragStartX = m_rectX;
|
Chris@173
|
49 m_dragStartY = m_rectY;
|
Chris@173
|
50 } else if (e->button() == Qt::MidButton) {
|
Chris@173
|
51 resetToDefault();
|
Chris@173
|
52 }
|
Chris@172
|
53 }
|
Chris@172
|
54
|
Chris@172
|
55 void
|
Chris@172
|
56 Panner::mouseDoubleClickEvent(QMouseEvent *e)
|
Chris@172
|
57 {
|
Chris@173
|
58 resetToDefault();
|
Chris@172
|
59 }
|
Chris@172
|
60
|
Chris@172
|
61 void
|
Chris@172
|
62 Panner::mouseMoveEvent(QMouseEvent *e)
|
Chris@172
|
63 {
|
Chris@173
|
64 if (!m_clicked) return;
|
Chris@173
|
65
|
Chris@173
|
66 float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
|
Chris@173
|
67 float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
|
Chris@173
|
68
|
Chris@173
|
69 m_rectX = m_dragStartX + dx;
|
Chris@173
|
70 m_rectY = m_dragStartY + dy;
|
Chris@173
|
71
|
Chris@173
|
72 normalise();
|
Chris@173
|
73 emitAndUpdate();
|
Chris@172
|
74 }
|
Chris@172
|
75
|
Chris@172
|
76 void
|
Chris@172
|
77 Panner::mouseReleaseEvent(QMouseEvent *e)
|
Chris@172
|
78 {
|
Chris@173
|
79 if (!m_clicked) return;
|
Chris@173
|
80
|
Chris@173
|
81 mouseMoveEvent(e);
|
Chris@173
|
82 m_clicked = false;
|
Chris@172
|
83 }
|
Chris@172
|
84
|
Chris@172
|
85 void
|
Chris@172
|
86 Panner::wheelEvent(QWheelEvent *e)
|
Chris@172
|
87 {
|
Chris@173
|
88 if (e->delta() > 0) {
|
Chris@173
|
89 m_rectY += 0.1;
|
Chris@173
|
90 } else {
|
Chris@173
|
91 m_rectY -= 0.1;
|
Chris@173
|
92 }
|
Chris@173
|
93
|
Chris@173
|
94 normalise();
|
Chris@173
|
95 emitAndUpdate();
|
Chris@172
|
96 }
|
Chris@172
|
97
|
Chris@172
|
98 void
|
Chris@172
|
99 Panner::paintEvent(QPaintEvent *e)
|
Chris@172
|
100 {
|
Chris@172
|
101 QPainter paint(this);
|
Chris@172
|
102 paint.setRenderHint(QPainter::Antialiasing, false);
|
Chris@173
|
103
|
Chris@173
|
104 QColor bg(palette().background().color());
|
Chris@173
|
105 bg.setAlpha(80);
|
Chris@173
|
106
|
Chris@172
|
107 paint.setPen(palette().dark().color());
|
Chris@173
|
108 paint.setBrush(bg);
|
Chris@173
|
109 paint.drawRect(0, 0, width(), height());
|
Chris@173
|
110
|
Chris@173
|
111 QColor hl(palette().highlight().color());
|
Chris@173
|
112 hl.setAlpha(80);
|
Chris@173
|
113
|
Chris@173
|
114 paint.setBrush(hl);
|
Chris@173
|
115
|
Chris@173
|
116 paint.drawRect(lrintf(width() * m_rectX),
|
Chris@173
|
117 lrintf(height() * m_rectY),
|
Chris@173
|
118 lrintf(width() * m_rectWidth),
|
Chris@173
|
119 lrintf(height() * m_rectHeight));
|
Chris@172
|
120 }
|
Chris@172
|
121
|
Chris@172
|
122 void
|
Chris@172
|
123 Panner::normalise()
|
Chris@172
|
124 {
|
Chris@172
|
125 if (m_rectWidth > 1.0) m_rectWidth = 1.0;
|
Chris@172
|
126 if (m_rectHeight > 1.0) m_rectHeight = 1.0;
|
Chris@172
|
127 if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
|
Chris@172
|
128 if (m_rectX < 0) m_rectX = 0;
|
Chris@172
|
129 if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
|
Chris@172
|
130 if (m_rectY < 0) m_rectY = 0;
|
Chris@173
|
131
|
Chris@173
|
132 if (!m_defaultsSet) {
|
Chris@173
|
133 m_defaultCentreX = centreX();
|
Chris@173
|
134 m_defaultCentreY = centreY();
|
Chris@173
|
135 m_defaultsSet = true;
|
Chris@173
|
136 }
|
Chris@172
|
137 }
|
Chris@172
|
138
|
Chris@172
|
139 void
|
Chris@172
|
140 Panner::emitAndUpdate()
|
Chris@172
|
141 {
|
Chris@172
|
142 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
|
Chris@173
|
143 emit rectCentreMoved(centreX(), centreY());
|
Chris@172
|
144 update();
|
Chris@172
|
145 }
|
Chris@172
|
146
|
Chris@172
|
147 void
|
Chris@172
|
148 Panner::setRectExtents(float x0, float y0, float width, float height)
|
Chris@172
|
149 {
|
Chris@172
|
150 if (m_rectX == x0 &&
|
Chris@172
|
151 m_rectY == y0 &&
|
Chris@172
|
152 m_rectWidth == width &&
|
Chris@172
|
153 m_rectHeight == height) {
|
Chris@172
|
154 return;
|
Chris@172
|
155 }
|
Chris@173
|
156
|
Chris@172
|
157 m_rectX = x0;
|
Chris@172
|
158 m_rectY = y0;
|
Chris@172
|
159 m_rectWidth = width;
|
Chris@172
|
160 m_rectHeight = height;
|
Chris@173
|
161
|
Chris@172
|
162 normalise();
|
Chris@172
|
163 emitAndUpdate();
|
Chris@172
|
164 }
|
Chris@172
|
165
|
Chris@172
|
166 void
|
Chris@172
|
167 Panner::setRectWidth(float width)
|
Chris@172
|
168 {
|
Chris@172
|
169 if (m_rectWidth == width) return;
|
Chris@172
|
170 m_rectWidth = width;
|
Chris@172
|
171 normalise();
|
Chris@172
|
172 emitAndUpdate();
|
Chris@172
|
173 }
|
Chris@172
|
174
|
Chris@172
|
175 void
|
Chris@172
|
176 Panner::setRectHeight(float height)
|
Chris@172
|
177 {
|
Chris@172
|
178 if (m_rectHeight == height) return;
|
Chris@172
|
179 m_rectHeight = height;
|
Chris@172
|
180 normalise();
|
Chris@172
|
181 emitAndUpdate();
|
Chris@172
|
182 }
|
Chris@172
|
183
|
Chris@172
|
184 void
|
Chris@172
|
185 Panner::setRectCentreX(float x)
|
Chris@172
|
186 {
|
Chris@172
|
187 float x0 = x - m_rectWidth/2;
|
Chris@172
|
188 if (x0 == m_rectX) return;
|
Chris@172
|
189 m_rectX = x0;
|
Chris@172
|
190 normalise();
|
Chris@172
|
191 emitAndUpdate();
|
Chris@172
|
192 }
|
Chris@172
|
193
|
Chris@172
|
194 void
|
Chris@172
|
195 Panner::setRectCentreY(float y)
|
Chris@172
|
196 {
|
Chris@173
|
197 float y0 = y - m_rectHeight/2;
|
Chris@172
|
198 if (y0 == m_rectY) return;
|
Chris@172
|
199 m_rectY = y0;
|
Chris@172
|
200 normalise();
|
Chris@172
|
201 emitAndUpdate();
|
Chris@172
|
202 }
|
Chris@172
|
203
|
Chris@172
|
204 QSize
|
Chris@172
|
205 Panner::sizeHint() const
|
Chris@172
|
206 {
|
Chris@172
|
207 return QSize(30, 30);
|
Chris@172
|
208 }
|
Chris@172
|
209
|
Chris@173
|
210 void
|
Chris@173
|
211 Panner::setDefaultRectCentre(float cx, float cy)
|
Chris@173
|
212 {
|
Chris@173
|
213 m_defaultCentreX = cx;
|
Chris@173
|
214 m_defaultCentreY = cy;
|
Chris@173
|
215 m_defaultsSet = true;
|
Chris@173
|
216 }
|
Chris@172
|
217
|
Chris@173
|
218 void
|
Chris@173
|
219 Panner::resetToDefault()
|
Chris@173
|
220 {
|
Chris@173
|
221 float x0 = m_defaultCentreX - m_rectWidth/2;
|
Chris@173
|
222 float y0 = m_defaultCentreY - m_rectHeight/2;
|
Chris@173
|
223 if (x0 == m_rectX && y0 == m_rectY) return;
|
Chris@173
|
224 m_rectX = x0;
|
Chris@173
|
225 m_rectY = y0;
|
Chris@173
|
226 normalise();
|
Chris@173
|
227 emitAndUpdate();
|
Chris@173
|
228 }
|
Chris@172
|
229
|
Chris@173
|
230
|