comparison panner.cpp @ 45:4286836bb3c9

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