annotate panner.cpp @ 46:bd3accba9b3f

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