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