annotate panner.cpp @ 93:dfb7a274b90f

* Highlight untracked files that are newer than last repo interaction
author Chris Cannam
date Wed, 24 Nov 2010 13:50:33 +0000
parents b0a90ac84b8b
children 5fc7b4fc77a8
rev   line source
Chris@57 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@45 2
cannam@45 3 /*
Chris@57 4 EasyMercurial
Chris@57 5
Chris@57 6 Based on HgExplorer by Jari Korhonen
Chris@57 7 Copyright (c) 2010 Jari Korhonen
Chris@57 8 Copyright (c) 2010 Chris Cannam
Chris@57 9 Copyright (c) 2010 Queen Mary, University of London
Chris@57 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);
Chris@48 38 setOptimizationFlags(QGraphicsView::DontSavePainterState |
Chris@48 39 QGraphicsView::IndirectPainting);
cannam@45 40 setMouseTracking(true);
cannam@45 41 setInteractive(false);
cannam@45 42 }
cannam@45 43
cannam@45 44 void
cannam@45 45 Panner::setScene(QGraphicsScene *s)
cannam@45 46 {
cannam@45 47 if (scene()) {
cannam@45 48 disconnect(scene(), SIGNAL(sceneRectChanged(const QRectF &)),
cannam@45 49 this, SLOT(slotSceneRectChanged(const QRectF &)));
cannam@45 50 }
cannam@45 51 QGraphicsView::setScene(s);
cannam@45 52 if (scene()) fitInView(sceneRect(), Qt::IgnoreAspectRatio);
cannam@45 53 m_cache = QPixmap();
cannam@45 54 connect(scene(), SIGNAL(sceneRectChanged(const QRectF &)),
cannam@45 55 this, SLOT(slotSceneRectChanged(const QRectF &)));
cannam@45 56 }
cannam@45 57
cannam@45 58 void
cannam@45 59 Panner::connectToPanned(Panned *p)
cannam@45 60 {
cannam@45 61 connect(p, SIGNAL(pannedRectChanged(QRectF)),
cannam@45 62 this, SLOT(slotSetPannedRect(QRectF)));
cannam@45 63
cannam@45 64 connect(this, SIGNAL(pannedRectChanged(QRectF)),
cannam@45 65 p, SLOT(slotSetPannedRect(QRectF)));
Chris@53 66
Chris@53 67 connect(this, SIGNAL(zoomIn()),
Chris@53 68 p, SLOT(zoomIn()));
Chris@53 69
Chris@53 70 connect(this, SIGNAL(zoomOut()),
Chris@53 71 p, SLOT(zoomOut()));
cannam@45 72 }
cannam@45 73
cannam@45 74 void
cannam@45 75 Panner::slotSetPannedRect(QRectF rect)
cannam@45 76 {
cannam@45 77 m_pannedRect = rect;
cannam@45 78 viewport()->update();
cannam@45 79 }
cannam@45 80
cannam@45 81 void
cannam@45 82 Panner::resizeEvent(QResizeEvent *)
cannam@45 83 {
cannam@45 84 if (scene()) fitInView(sceneRect(), Qt::IgnoreAspectRatio);
cannam@45 85 m_cache = QPixmap();
cannam@45 86 }
cannam@45 87
cannam@45 88 void
cannam@45 89 Panner::slotSceneRectChanged(const QRectF &newRect)
cannam@45 90 {
cannam@45 91 if (!scene()) return; // spurious
cannam@45 92 fitInView(newRect, Qt::IgnoreAspectRatio);
cannam@45 93 m_cache = QPixmap();
cannam@45 94 viewport()->update();
cannam@45 95 }
cannam@45 96
cannam@45 97 void
cannam@45 98 Panner::paintEvent(QPaintEvent *e)
cannam@45 99 {
cannam@45 100 QPaintEvent *e2 = new QPaintEvent(e->region().boundingRect());
cannam@45 101 QGraphicsView::paintEvent(e2);
cannam@45 102
cannam@45 103 QPainter paint;
cannam@45 104 paint.begin(viewport());
cannam@45 105 paint.setClipRegion(e->region());
cannam@45 106
cannam@45 107 QPainterPath path;
cannam@45 108 path.addRect(rect());
cannam@45 109 path.addPolygon(mapFromScene(m_pannedRect));
cannam@45 110
cannam@45 111 QColor c(QColor::fromHsv(211, 194, 238));
cannam@45 112 c.setAlpha(80);
cannam@45 113 paint.setPen(Qt::NoPen);
cannam@45 114 paint.setBrush(c);
cannam@45 115 paint.drawPath(path);
cannam@45 116
cannam@45 117 paint.setBrush(Qt::NoBrush);
cannam@45 118 paint.setPen(QPen(QColor::fromHsv(211, 194, 238), 0));
cannam@45 119 paint.drawConvexPolygon(mapFromScene(m_pannedRect));
cannam@45 120
cannam@45 121 paint.end();
cannam@45 122
cannam@45 123 emit pannerChanged(m_pannedRect);
cannam@45 124 }
cannam@45 125
cannam@45 126 void
cannam@45 127 Panner::updateScene(const QList<QRectF> &rects)
cannam@45 128 {
cannam@45 129 if (!m_cache.isNull()) m_cache = QPixmap();
cannam@45 130 QGraphicsView::updateScene(rects);
cannam@45 131 }
cannam@45 132
cannam@45 133 void
cannam@45 134 Panner::drawItems(QPainter *painter, int numItems,
cannam@45 135 QGraphicsItem *items[],
cannam@45 136 const QStyleOptionGraphicsItem options[])
cannam@45 137 {
cannam@45 138 if (m_cache.size() != viewport()->size()) {
cannam@45 139
Chris@48 140 std::cerr << "Panner: recreating cache" << std::endl;
Chris@48 141
cannam@45 142 QGraphicsScene *s = scene();
cannam@45 143 if (!s) return;
cannam@45 144 PannerScene *ps = static_cast<PannerScene *>(s);
cannam@45 145
cannam@45 146 m_cache = QPixmap(viewport()->size());
cannam@45 147 m_cache.fill(Qt::transparent);
cannam@45 148 QPainter cachePainter;
cannam@45 149 cachePainter.begin(&m_cache);
cannam@45 150 cachePainter.setTransform(viewportTransform());
cannam@45 151 ps->drawItems(&cachePainter, numItems, items, options);
cannam@45 152 cachePainter.end();
cannam@45 153 }
cannam@45 154
cannam@45 155 painter->save();
cannam@45 156 painter->setTransform(QTransform());
cannam@45 157 painter->drawPixmap(0, 0, m_cache);
cannam@45 158 painter->restore();
cannam@45 159 }
cannam@45 160
cannam@45 161 void
cannam@45 162 Panner::mousePressEvent(QMouseEvent *e)
cannam@45 163 {
cannam@45 164 if (e->button() != Qt::LeftButton) {
cannam@45 165 QGraphicsView::mouseDoubleClickEvent(e);
cannam@45 166 return;
cannam@45 167 }
cannam@45 168 m_clicked = true;
cannam@45 169 m_clickedRect = m_pannedRect;
cannam@45 170 m_clickedPoint = e->pos();
cannam@45 171 }
cannam@45 172
cannam@45 173 void
cannam@45 174 Panner::mouseDoubleClickEvent(QMouseEvent *e)
cannam@45 175 {
cannam@45 176 if (e->button() != Qt::LeftButton) {
cannam@45 177 QGraphicsView::mouseDoubleClickEvent(e);
cannam@45 178 return;
cannam@45 179 }
cannam@45 180
cannam@45 181 moveTo(e->pos());
cannam@45 182 }
cannam@45 183
cannam@45 184 void
cannam@45 185 Panner::mouseMoveEvent(QMouseEvent *e)
cannam@45 186 {
cannam@45 187 if (!m_clicked) return;
cannam@45 188 QPointF cp = mapToScene(m_clickedPoint);
cannam@45 189 QPointF mp = mapToScene(e->pos());
cannam@45 190 QPointF delta = mp - cp;
cannam@45 191 QRectF nr = m_clickedRect;
cannam@45 192 nr.translate(delta);
cannam@45 193 slotSetPannedRect(nr);
cannam@45 194 emit pannedRectChanged(m_pannedRect);
cannam@45 195 viewport()->update();
cannam@45 196 }
cannam@45 197
cannam@45 198 void
cannam@45 199 Panner::mouseReleaseEvent(QMouseEvent *e)
cannam@45 200 {
cannam@45 201 if (e->button() != Qt::LeftButton) {
cannam@45 202 QGraphicsView::mouseDoubleClickEvent(e);
cannam@45 203 return;
cannam@45 204 }
cannam@45 205
cannam@45 206 if (m_clicked) {
cannam@45 207 mouseMoveEvent(e);
cannam@45 208 }
cannam@45 209
cannam@45 210 m_clicked = false;
cannam@45 211 viewport()->update();
cannam@45 212 }
cannam@45 213
cannam@45 214 void
cannam@45 215 Panner::wheelEvent(QWheelEvent *e)
cannam@45 216 {
Chris@53 217 int d = e->delta();
Chris@53 218 if (d > 0) {
Chris@53 219 while (d > 0) {
Chris@53 220 emit zoomOut();
Chris@53 221 d -= 120;
Chris@53 222 }
cannam@45 223 } else {
Chris@53 224 while (d < 0) {
Chris@53 225 emit zoomIn();
Chris@53 226 d += 120;
Chris@53 227 }
cannam@45 228 }
cannam@45 229 }
cannam@45 230
cannam@45 231 void
cannam@45 232 Panner::moveTo(QPoint p)
cannam@45 233 {
cannam@45 234 QPointF sp = mapToScene(p);
cannam@45 235 QRectF nr = m_pannedRect;
cannam@45 236 double d = sp.x() - nr.center().x();
cannam@45 237 nr.translate(d, 0);
cannam@45 238 slotSetPannedRect(nr);
cannam@45 239 emit pannedRectChanged(m_pannedRect);
cannam@45 240 viewport()->update();
cannam@45 241 }
cannam@45 242