cannam@45
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
cannam@45
|
2
|
cannam@45
|
3 /*
|
cannam@45
|
4 Rosegarden
|
cannam@45
|
5 A MIDI and audio sequencer and musical notation editor.
|
cannam@45
|
6 Copyright 2000-2010 the Rosegarden development team.
|
cannam@45
|
7
|
cannam@45
|
8 Other copyrights also apply to some parts of this work. Please
|
cannam@45
|
9 see the AUTHORS file and individual file headers for details.
|
cannam@45
|
10
|
cannam@45
|
11 This program is free software; you can redistribute it and/or
|
cannam@45
|
12 modify it under the terms of the GNU General Public License as
|
cannam@45
|
13 published by the Free Software Foundation; either version 2 of the
|
cannam@45
|
14 License, or (at your option) any later version. See the file
|
cannam@45
|
15 COPYING included with this distribution for more information.
|
cannam@45
|
16 */
|
cannam@45
|
17
|
cannam@45
|
18 #include "panner.h"
|
cannam@45
|
19 #include "panned.h"
|
cannam@45
|
20
|
cannam@45
|
21 #include <QPolygon>
|
cannam@45
|
22 #include <QMouseEvent>
|
cannam@45
|
23 #include <QColor>
|
Chris@46
|
24 #include <QGLWidget>
|
cannam@45
|
25
|
cannam@45
|
26 #include <iostream>
|
cannam@45
|
27
|
cannam@45
|
28 class PannerScene : public QGraphicsScene
|
cannam@45
|
29 {
|
cannam@45
|
30 public:
|
cannam@45
|
31 friend class Panner;
|
cannam@45
|
32 };
|
cannam@45
|
33
|
cannam@45
|
34 Panner::Panner() :
|
cannam@45
|
35 m_clicked(false)
|
cannam@45
|
36 {
|
Chris@46
|
37 // setViewport(new QGLWidget());
|
cannam@45
|
38 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
cannam@45
|
39 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
Chris@48
|
40 setOptimizationFlags(QGraphicsView::DontSavePainterState |
|
Chris@48
|
41 QGraphicsView::IndirectPainting);
|
Chris@53
|
42 setRenderHints(QPainter::Antialiasing);
|
cannam@45
|
43 setMouseTracking(true);
|
cannam@45
|
44 setInteractive(false);
|
cannam@45
|
45 }
|
cannam@45
|
46
|
cannam@45
|
47 void
|
cannam@45
|
48 Panner::setScene(QGraphicsScene *s)
|
cannam@45
|
49 {
|
cannam@45
|
50 if (scene()) {
|
cannam@45
|
51 disconnect(scene(), SIGNAL(sceneRectChanged(const QRectF &)),
|
cannam@45
|
52 this, SLOT(slotSceneRectChanged(const QRectF &)));
|
cannam@45
|
53 }
|
cannam@45
|
54 QGraphicsView::setScene(s);
|
cannam@45
|
55 if (scene()) fitInView(sceneRect(), Qt::IgnoreAspectRatio);
|
cannam@45
|
56 m_cache = QPixmap();
|
cannam@45
|
57 connect(scene(), SIGNAL(sceneRectChanged(const QRectF &)),
|
cannam@45
|
58 this, SLOT(slotSceneRectChanged(const QRectF &)));
|
cannam@45
|
59 }
|
cannam@45
|
60
|
cannam@45
|
61 void
|
cannam@45
|
62 Panner::connectToPanned(Panned *p)
|
cannam@45
|
63 {
|
cannam@45
|
64 connect(p, SIGNAL(pannedRectChanged(QRectF)),
|
cannam@45
|
65 this, SLOT(slotSetPannedRect(QRectF)));
|
cannam@45
|
66
|
cannam@45
|
67 connect(this, SIGNAL(pannedRectChanged(QRectF)),
|
cannam@45
|
68 p, SLOT(slotSetPannedRect(QRectF)));
|
Chris@53
|
69
|
Chris@53
|
70 connect(this, SIGNAL(zoomIn()),
|
Chris@53
|
71 p, SLOT(zoomIn()));
|
Chris@53
|
72
|
Chris@53
|
73 connect(this, SIGNAL(zoomOut()),
|
Chris@53
|
74 p, SLOT(zoomOut()));
|
cannam@45
|
75 }
|
cannam@45
|
76
|
cannam@45
|
77 void
|
cannam@45
|
78 Panner::slotSetPannedRect(QRectF rect)
|
cannam@45
|
79 {
|
cannam@45
|
80 m_pannedRect = rect;
|
cannam@45
|
81 viewport()->update();
|
cannam@45
|
82 }
|
cannam@45
|
83
|
cannam@45
|
84 void
|
cannam@45
|
85 Panner::resizeEvent(QResizeEvent *)
|
cannam@45
|
86 {
|
cannam@45
|
87 if (scene()) fitInView(sceneRect(), Qt::IgnoreAspectRatio);
|
cannam@45
|
88 m_cache = QPixmap();
|
cannam@45
|
89 }
|
cannam@45
|
90
|
cannam@45
|
91 void
|
cannam@45
|
92 Panner::slotSceneRectChanged(const QRectF &newRect)
|
cannam@45
|
93 {
|
cannam@45
|
94 if (!scene()) return; // spurious
|
cannam@45
|
95 fitInView(newRect, Qt::IgnoreAspectRatio);
|
cannam@45
|
96 m_cache = QPixmap();
|
cannam@45
|
97 viewport()->update();
|
cannam@45
|
98 }
|
cannam@45
|
99
|
cannam@45
|
100 void
|
cannam@45
|
101 Panner::paintEvent(QPaintEvent *e)
|
cannam@45
|
102 {
|
cannam@45
|
103 QPaintEvent *e2 = new QPaintEvent(e->region().boundingRect());
|
cannam@45
|
104 QGraphicsView::paintEvent(e2);
|
cannam@45
|
105
|
cannam@45
|
106 QPainter paint;
|
cannam@45
|
107 paint.begin(viewport());
|
cannam@45
|
108 paint.setClipRegion(e->region());
|
cannam@45
|
109
|
cannam@45
|
110 QPainterPath path;
|
cannam@45
|
111 path.addRect(rect());
|
cannam@45
|
112 path.addPolygon(mapFromScene(m_pannedRect));
|
cannam@45
|
113
|
cannam@45
|
114 QColor c(QColor::fromHsv(211, 194, 238));
|
cannam@45
|
115 c.setAlpha(80);
|
cannam@45
|
116 paint.setPen(Qt::NoPen);
|
cannam@45
|
117 paint.setBrush(c);
|
cannam@45
|
118 paint.drawPath(path);
|
cannam@45
|
119
|
cannam@45
|
120 paint.setBrush(Qt::NoBrush);
|
cannam@45
|
121 paint.setPen(QPen(QColor::fromHsv(211, 194, 238), 0));
|
cannam@45
|
122 paint.drawConvexPolygon(mapFromScene(m_pannedRect));
|
cannam@45
|
123
|
cannam@45
|
124 paint.end();
|
cannam@45
|
125
|
cannam@45
|
126 emit pannerChanged(m_pannedRect);
|
cannam@45
|
127 }
|
cannam@45
|
128
|
cannam@45
|
129 void
|
cannam@45
|
130 Panner::updateScene(const QList<QRectF> &rects)
|
cannam@45
|
131 {
|
cannam@45
|
132 if (!m_cache.isNull()) m_cache = QPixmap();
|
cannam@45
|
133 QGraphicsView::updateScene(rects);
|
cannam@45
|
134 }
|
cannam@45
|
135
|
cannam@45
|
136 void
|
cannam@45
|
137 Panner::drawItems(QPainter *painter, int numItems,
|
cannam@45
|
138 QGraphicsItem *items[],
|
cannam@45
|
139 const QStyleOptionGraphicsItem options[])
|
cannam@45
|
140 {
|
cannam@45
|
141 if (m_cache.size() != viewport()->size()) {
|
cannam@45
|
142
|
Chris@48
|
143 std::cerr << "Panner: recreating cache" << std::endl;
|
Chris@48
|
144
|
cannam@45
|
145 QGraphicsScene *s = scene();
|
cannam@45
|
146 if (!s) return;
|
cannam@45
|
147 PannerScene *ps = static_cast<PannerScene *>(s);
|
cannam@45
|
148
|
cannam@45
|
149 m_cache = QPixmap(viewport()->size());
|
cannam@45
|
150 m_cache.fill(Qt::transparent);
|
cannam@45
|
151 QPainter cachePainter;
|
cannam@45
|
152 cachePainter.begin(&m_cache);
|
cannam@45
|
153 cachePainter.setTransform(viewportTransform());
|
cannam@45
|
154 ps->drawItems(&cachePainter, numItems, items, options);
|
cannam@45
|
155 cachePainter.end();
|
cannam@45
|
156 }
|
cannam@45
|
157
|
cannam@45
|
158 painter->save();
|
cannam@45
|
159 painter->setTransform(QTransform());
|
cannam@45
|
160 painter->drawPixmap(0, 0, m_cache);
|
cannam@45
|
161 painter->restore();
|
cannam@45
|
162 }
|
cannam@45
|
163
|
cannam@45
|
164 void
|
cannam@45
|
165 Panner::mousePressEvent(QMouseEvent *e)
|
cannam@45
|
166 {
|
cannam@45
|
167 if (e->button() != Qt::LeftButton) {
|
cannam@45
|
168 QGraphicsView::mouseDoubleClickEvent(e);
|
cannam@45
|
169 return;
|
cannam@45
|
170 }
|
cannam@45
|
171 m_clicked = true;
|
cannam@45
|
172 m_clickedRect = m_pannedRect;
|
cannam@45
|
173 m_clickedPoint = e->pos();
|
cannam@45
|
174 }
|
cannam@45
|
175
|
cannam@45
|
176 void
|
cannam@45
|
177 Panner::mouseDoubleClickEvent(QMouseEvent *e)
|
cannam@45
|
178 {
|
cannam@45
|
179 if (e->button() != Qt::LeftButton) {
|
cannam@45
|
180 QGraphicsView::mouseDoubleClickEvent(e);
|
cannam@45
|
181 return;
|
cannam@45
|
182 }
|
cannam@45
|
183
|
cannam@45
|
184 moveTo(e->pos());
|
cannam@45
|
185 }
|
cannam@45
|
186
|
cannam@45
|
187 void
|
cannam@45
|
188 Panner::mouseMoveEvent(QMouseEvent *e)
|
cannam@45
|
189 {
|
cannam@45
|
190 if (!m_clicked) return;
|
cannam@45
|
191 QPointF cp = mapToScene(m_clickedPoint);
|
cannam@45
|
192 QPointF mp = mapToScene(e->pos());
|
cannam@45
|
193 QPointF delta = mp - cp;
|
cannam@45
|
194 QRectF nr = m_clickedRect;
|
cannam@45
|
195 nr.translate(delta);
|
cannam@45
|
196 slotSetPannedRect(nr);
|
cannam@45
|
197 emit pannedRectChanged(m_pannedRect);
|
cannam@45
|
198 viewport()->update();
|
cannam@45
|
199 }
|
cannam@45
|
200
|
cannam@45
|
201 void
|
cannam@45
|
202 Panner::mouseReleaseEvent(QMouseEvent *e)
|
cannam@45
|
203 {
|
cannam@45
|
204 if (e->button() != Qt::LeftButton) {
|
cannam@45
|
205 QGraphicsView::mouseDoubleClickEvent(e);
|
cannam@45
|
206 return;
|
cannam@45
|
207 }
|
cannam@45
|
208
|
cannam@45
|
209 if (m_clicked) {
|
cannam@45
|
210 mouseMoveEvent(e);
|
cannam@45
|
211 }
|
cannam@45
|
212
|
cannam@45
|
213 m_clicked = false;
|
cannam@45
|
214 viewport()->update();
|
cannam@45
|
215 }
|
cannam@45
|
216
|
cannam@45
|
217 void
|
cannam@45
|
218 Panner::wheelEvent(QWheelEvent *e)
|
cannam@45
|
219 {
|
Chris@53
|
220 int d = e->delta();
|
Chris@53
|
221 if (d > 0) {
|
Chris@53
|
222 while (d > 0) {
|
Chris@53
|
223 emit zoomOut();
|
Chris@53
|
224 d -= 120;
|
Chris@53
|
225 }
|
cannam@45
|
226 } else {
|
Chris@53
|
227 while (d < 0) {
|
Chris@53
|
228 emit zoomIn();
|
Chris@53
|
229 d += 120;
|
Chris@53
|
230 }
|
cannam@45
|
231 }
|
cannam@45
|
232 }
|
cannam@45
|
233
|
cannam@45
|
234 void
|
cannam@45
|
235 Panner::moveTo(QPoint p)
|
cannam@45
|
236 {
|
cannam@45
|
237 QPointF sp = mapToScene(p);
|
cannam@45
|
238 QRectF nr = m_pannedRect;
|
cannam@45
|
239 double d = sp.x() - nr.center().x();
|
cannam@45
|
240 nr.translate(d, 0);
|
cannam@45
|
241 slotSetPannedRect(nr);
|
cannam@45
|
242 emit pannedRectChanged(m_pannedRect);
|
cannam@45
|
243 viewport()->update();
|
cannam@45
|
244 }
|
cannam@45
|
245
|