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>
|
cannam@45
|
24
|
cannam@45
|
25 #include <iostream>
|
cannam@45
|
26
|
cannam@45
|
27 class PannerScene : public QGraphicsScene
|
cannam@45
|
28 {
|
cannam@45
|
29 public:
|
cannam@45
|
30 friend class Panner;
|
cannam@45
|
31 };
|
cannam@45
|
32
|
cannam@45
|
33 Panner::Panner() :
|
cannam@45
|
34 m_clicked(false)
|
cannam@45
|
35 {
|
cannam@45
|
36 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
cannam@45
|
37 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
cannam@45
|
38 setOptimizationFlags(QGraphicsView::DontSavePainterState);
|
cannam@45
|
39 setMouseTracking(true);
|
cannam@45
|
40 setInteractive(false);
|
cannam@45
|
41 }
|
cannam@45
|
42
|
cannam@45
|
43 void
|
cannam@45
|
44 Panner::setScene(QGraphicsScene *s)
|
cannam@45
|
45 {
|
cannam@45
|
46 if (scene()) {
|
cannam@45
|
47 disconnect(scene(), SIGNAL(sceneRectChanged(const QRectF &)),
|
cannam@45
|
48 this, SLOT(slotSceneRectChanged(const QRectF &)));
|
cannam@45
|
49 }
|
cannam@45
|
50 QGraphicsView::setScene(s);
|
cannam@45
|
51 if (scene()) fitInView(sceneRect(), Qt::IgnoreAspectRatio);
|
cannam@45
|
52 m_cache = QPixmap();
|
cannam@45
|
53 connect(scene(), SIGNAL(sceneRectChanged(const QRectF &)),
|
cannam@45
|
54 this, SLOT(slotSceneRectChanged(const QRectF &)));
|
cannam@45
|
55 }
|
cannam@45
|
56
|
cannam@45
|
57 void
|
cannam@45
|
58 Panner::connectToPanned(Panned *p)
|
cannam@45
|
59 {
|
cannam@45
|
60 connect(p, SIGNAL(pannedRectChanged(QRectF)),
|
cannam@45
|
61 this, SLOT(slotSetPannedRect(QRectF)));
|
cannam@45
|
62
|
cannam@45
|
63 connect(this, SIGNAL(pannedRectChanged(QRectF)),
|
cannam@45
|
64 p, SLOT(slotSetPannedRect(QRectF)));
|
cannam@45
|
65 }
|
cannam@45
|
66
|
cannam@45
|
67 void
|
cannam@45
|
68 Panner::slotSetPannedRect(QRectF rect)
|
cannam@45
|
69 {
|
cannam@45
|
70 m_pannedRect = rect;
|
cannam@45
|
71 viewport()->update();
|
cannam@45
|
72 }
|
cannam@45
|
73
|
cannam@45
|
74 void
|
cannam@45
|
75 Panner::resizeEvent(QResizeEvent *)
|
cannam@45
|
76 {
|
cannam@45
|
77 if (scene()) fitInView(sceneRect(), Qt::IgnoreAspectRatio);
|
cannam@45
|
78 m_cache = QPixmap();
|
cannam@45
|
79 }
|
cannam@45
|
80
|
cannam@45
|
81 void
|
cannam@45
|
82 Panner::slotSceneRectChanged(const QRectF &newRect)
|
cannam@45
|
83 {
|
cannam@45
|
84 if (!scene()) return; // spurious
|
cannam@45
|
85 fitInView(newRect, Qt::IgnoreAspectRatio);
|
cannam@45
|
86 m_cache = QPixmap();
|
cannam@45
|
87 viewport()->update();
|
cannam@45
|
88 }
|
cannam@45
|
89
|
cannam@45
|
90 void
|
cannam@45
|
91 Panner::paintEvent(QPaintEvent *e)
|
cannam@45
|
92 {
|
cannam@45
|
93 QPaintEvent *e2 = new QPaintEvent(e->region().boundingRect());
|
cannam@45
|
94 QGraphicsView::paintEvent(e2);
|
cannam@45
|
95
|
cannam@45
|
96 QPainter paint;
|
cannam@45
|
97 paint.begin(viewport());
|
cannam@45
|
98 paint.setClipRegion(e->region());
|
cannam@45
|
99
|
cannam@45
|
100 QPainterPath path;
|
cannam@45
|
101 path.addRect(rect());
|
cannam@45
|
102 path.addPolygon(mapFromScene(m_pannedRect));
|
cannam@45
|
103
|
cannam@45
|
104 QColor c(QColor::fromHsv(211, 194, 238));
|
cannam@45
|
105 c.setAlpha(80);
|
cannam@45
|
106 paint.setPen(Qt::NoPen);
|
cannam@45
|
107 paint.setBrush(c);
|
cannam@45
|
108 paint.drawPath(path);
|
cannam@45
|
109
|
cannam@45
|
110 paint.setBrush(Qt::NoBrush);
|
cannam@45
|
111 paint.setPen(QPen(QColor::fromHsv(211, 194, 238), 0));
|
cannam@45
|
112 paint.drawConvexPolygon(mapFromScene(m_pannedRect));
|
cannam@45
|
113
|
cannam@45
|
114 paint.end();
|
cannam@45
|
115
|
cannam@45
|
116 emit pannerChanged(m_pannedRect);
|
cannam@45
|
117 }
|
cannam@45
|
118
|
cannam@45
|
119 void
|
cannam@45
|
120 Panner::updateScene(const QList<QRectF> &rects)
|
cannam@45
|
121 {
|
cannam@45
|
122 if (!m_cache.isNull()) m_cache = QPixmap();
|
cannam@45
|
123 QGraphicsView::updateScene(rects);
|
cannam@45
|
124 }
|
cannam@45
|
125
|
cannam@45
|
126 void
|
cannam@45
|
127 Panner::drawItems(QPainter *painter, int numItems,
|
cannam@45
|
128 QGraphicsItem *items[],
|
cannam@45
|
129 const QStyleOptionGraphicsItem options[])
|
cannam@45
|
130 {
|
cannam@45
|
131 if (m_cache.size() != viewport()->size()) {
|
cannam@45
|
132
|
cannam@45
|
133 QGraphicsScene *s = scene();
|
cannam@45
|
134 if (!s) return;
|
cannam@45
|
135 PannerScene *ps = static_cast<PannerScene *>(s);
|
cannam@45
|
136
|
cannam@45
|
137 m_cache = QPixmap(viewport()->size());
|
cannam@45
|
138 m_cache.fill(Qt::transparent);
|
cannam@45
|
139 QPainter cachePainter;
|
cannam@45
|
140 cachePainter.begin(&m_cache);
|
cannam@45
|
141 cachePainter.setTransform(viewportTransform());
|
cannam@45
|
142 ps->drawItems(&cachePainter, numItems, items, options);
|
cannam@45
|
143 cachePainter.end();
|
cannam@45
|
144 }
|
cannam@45
|
145
|
cannam@45
|
146 painter->save();
|
cannam@45
|
147 painter->setTransform(QTransform());
|
cannam@45
|
148 painter->drawPixmap(0, 0, m_cache);
|
cannam@45
|
149 painter->restore();
|
cannam@45
|
150 }
|
cannam@45
|
151
|
cannam@45
|
152 void
|
cannam@45
|
153 Panner::mousePressEvent(QMouseEvent *e)
|
cannam@45
|
154 {
|
cannam@45
|
155 if (e->button() != Qt::LeftButton) {
|
cannam@45
|
156 QGraphicsView::mouseDoubleClickEvent(e);
|
cannam@45
|
157 return;
|
cannam@45
|
158 }
|
cannam@45
|
159 m_clicked = true;
|
cannam@45
|
160 m_clickedRect = m_pannedRect;
|
cannam@45
|
161 m_clickedPoint = e->pos();
|
cannam@45
|
162 }
|
cannam@45
|
163
|
cannam@45
|
164 void
|
cannam@45
|
165 Panner::mouseDoubleClickEvent(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
|
cannam@45
|
172 moveTo(e->pos());
|
cannam@45
|
173 }
|
cannam@45
|
174
|
cannam@45
|
175 void
|
cannam@45
|
176 Panner::mouseMoveEvent(QMouseEvent *e)
|
cannam@45
|
177 {
|
cannam@45
|
178 if (!m_clicked) return;
|
cannam@45
|
179 QPointF cp = mapToScene(m_clickedPoint);
|
cannam@45
|
180 QPointF mp = mapToScene(e->pos());
|
cannam@45
|
181 QPointF delta = mp - cp;
|
cannam@45
|
182 QRectF nr = m_clickedRect;
|
cannam@45
|
183 nr.translate(delta);
|
cannam@45
|
184 slotSetPannedRect(nr);
|
cannam@45
|
185 emit pannedRectChanged(m_pannedRect);
|
cannam@45
|
186 viewport()->update();
|
cannam@45
|
187 }
|
cannam@45
|
188
|
cannam@45
|
189 void
|
cannam@45
|
190 Panner::mouseReleaseEvent(QMouseEvent *e)
|
cannam@45
|
191 {
|
cannam@45
|
192 if (e->button() != Qt::LeftButton) {
|
cannam@45
|
193 QGraphicsView::mouseDoubleClickEvent(e);
|
cannam@45
|
194 return;
|
cannam@45
|
195 }
|
cannam@45
|
196
|
cannam@45
|
197 if (m_clicked) {
|
cannam@45
|
198 mouseMoveEvent(e);
|
cannam@45
|
199 }
|
cannam@45
|
200
|
cannam@45
|
201 m_clicked = false;
|
cannam@45
|
202 viewport()->update();
|
cannam@45
|
203 }
|
cannam@45
|
204
|
cannam@45
|
205 void
|
cannam@45
|
206 Panner::wheelEvent(QWheelEvent *e)
|
cannam@45
|
207 {
|
cannam@45
|
208 if (e->delta() > 0) {
|
cannam@45
|
209 emit zoomOut();
|
cannam@45
|
210 } else {
|
cannam@45
|
211 emit zoomIn();
|
cannam@45
|
212 }
|
cannam@45
|
213 }
|
cannam@45
|
214
|
cannam@45
|
215 void
|
cannam@45
|
216 Panner::moveTo(QPoint p)
|
cannam@45
|
217 {
|
cannam@45
|
218 QPointF sp = mapToScene(p);
|
cannam@45
|
219 QRectF nr = m_pannedRect;
|
cannam@45
|
220 double d = sp.x() - nr.center().x();
|
cannam@45
|
221 nr.translate(d, 0);
|
cannam@45
|
222 slotSetPannedRect(nr);
|
cannam@45
|
223 emit pannedRectChanged(m_pannedRect);
|
cannam@45
|
224 viewport()->update();
|
cannam@45
|
225 }
|
cannam@45
|
226
|