Mercurial > hg > easyhg
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 |