annotate panned.cpp @ 268:b8ded5213d16

* Revert the grapher change from revision ec2baee80833 on Dec 19th 2010. The change definitely performed worse than the original (now reinstated) logic in the real-world soundsoftware-site case, with far more connection overlaps and ambiguous placements.
author Chris Cannam
date Mon, 17 Jan 2011 11:44:17 +0000
parents 8fd71f570884
children
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
cannam@45 5
Chris@57 6 Based on HgExplorer by Jari Korhonen
Chris@57 7 Copyright (c) 2010 Jari Korhonen
Chris@244 8 Copyright (c) 2011 Chris Cannam
Chris@244 9 Copyright (c) 2011 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 "panned.h"
Chris@131 19 #include "debug.h"
cannam@45 20
cannam@45 21 #include <QScrollBar>
Chris@53 22 #include <QWheelEvent>
Chris@168 23 #include <QTimer>
Chris@168 24
Chris@168 25 #include <cmath>
cannam@45 26
cannam@45 27 #include <iostream>
cannam@45 28
Chris@168 29 Panned::Panned() :
Chris@168 30 m_dragging(false)
cannam@45 31 {
Chris@168 32 m_dragTimer = new QTimer(this);
Chris@168 33 m_dragTimerMs = 50;
Chris@168 34 connect(m_dragTimer, SIGNAL(timeout()), this, SLOT(dragTimerTimeout()));
Chris@56 35 setRenderHints(QPainter::Antialiasing |
Chris@56 36 QPainter::TextAntialiasing);
cannam@45 37 }
cannam@45 38
cannam@45 39 void
cannam@45 40 Panned::resizeEvent(QResizeEvent *ev)
cannam@45 41 {
Chris@131 42 DEBUG << "Panned::resizeEvent()" << endl;
Chris@131 43
Chris@60 44 QPointF nearpt = mapToScene(0, 0);
Chris@60 45 QPointF farpt = mapToScene(width(), height());
Chris@60 46 QSizeF sz(farpt.x()-nearpt.x(), farpt.y()-nearpt.y());
Chris@60 47 QRectF pr(nearpt, sz);
cannam@45 48
Chris@132 49 QGraphicsView::resizeEvent(ev);
Chris@132 50
cannam@45 51 if (pr != m_pannedRect) {
Chris@132 52 DEBUG << "Panned: setting panned rect to " << pr << endl;
cannam@45 53 m_pannedRect = pr;
Chris@133 54 centerOn(pr.center());
Chris@133 55 emit pannedRectChanged(pr);
Chris@133 56 }
Chris@133 57 }
Chris@133 58
Chris@133 59 void
Chris@133 60 Panned::setScene(QGraphicsScene *s)
Chris@133 61 {
Chris@133 62 if (!scene()) {
Chris@133 63 QGraphicsView::setScene(s);
Chris@133 64 return;
Chris@133 65 }
Chris@133 66
Chris@133 67 QPointF nearpt = mapToScene(0, 0);
Chris@133 68 QPointF farpt = mapToScene(width(), height());
Chris@133 69 QSizeF sz(farpt.x()-nearpt.x(), farpt.y()-nearpt.y());
Chris@133 70 QRectF pr(nearpt, sz);
Chris@133 71
Chris@133 72 QGraphicsView::setScene(s);
Chris@133 73
Chris@133 74 DEBUG << "Panned::setScene: pr = " << pr << ", sceneRect = " << sceneRect() << endl;
Chris@133 75
Chris@133 76 if (scene() && sceneRect().intersects(pr)) {
Chris@133 77 DEBUG << "Panned::setScene: restoring old rect " << pr << endl;
Chris@133 78 m_pannedRect = pr;
Chris@133 79 centerOn(pr.center());
cannam@45 80 emit pannedRectChanged(pr);
cannam@45 81 }
cannam@45 82 }
cannam@45 83
cannam@45 84 void
cannam@45 85 Panned::paintEvent(QPaintEvent *e)
cannam@45 86 {
cannam@45 87 QGraphicsView::paintEvent(e);
cannam@45 88 }
cannam@45 89
cannam@45 90 void
cannam@45 91 Panned::drawForeground(QPainter *paint, const QRectF &)
cannam@45 92 {
Chris@60 93 QPointF nearpt = mapToScene(0, 0);
Chris@60 94 QPointF farpt = mapToScene(width(), height());
Chris@60 95 QSizeF sz(farpt.x()-nearpt.x(), farpt.y()-nearpt.y());
Chris@60 96 QRectF pr(nearpt, sz);
cannam@45 97
cannam@45 98 if (pr != m_pannedRect) {
Chris@133 99 DEBUG << "Panned::drawForeground: visible rect " << pr << " differs from panned rect " << m_pannedRect << ", updating panned rect" <<endl;
cannam@45 100 if (pr.x() != m_pannedRect.x()) emit pannedContentsScrolled();
cannam@45 101 m_pannedRect = pr;
cannam@45 102 emit pannedRectChanged(pr);
cannam@45 103 }
cannam@45 104 }
cannam@45 105
cannam@45 106 void
Chris@53 107 Panned::zoomIn()
Chris@53 108 {
Chris@53 109 QMatrix m = matrix();
Chris@53 110 m.scale(1.0 / 1.1, 1.0 / 1.1);
Chris@53 111 setMatrix(m);
Chris@53 112 }
Chris@53 113
Chris@53 114 void
Chris@53 115 Panned::zoomOut()
Chris@53 116 {
Chris@53 117 QMatrix m = matrix();
Chris@53 118 m.scale(1.1, 1.1);
Chris@53 119 setMatrix(m);
Chris@53 120 }
Chris@53 121
Chris@53 122 void
cannam@45 123 Panned::slotSetPannedRect(QRectF pr)
cannam@45 124 {
cannam@45 125 centerOn(pr.center());
cannam@45 126 // setSceneRect(pr);
cannam@45 127 // m_pannedRect = pr;
cannam@45 128 }
cannam@45 129
cannam@45 130 void
cannam@45 131 Panned::wheelEvent(QWheelEvent *ev)
cannam@45 132 {
Chris@53 133 if (ev->modifiers() & Qt::ControlModifier) {
Chris@53 134 int d = ev->delta();
Chris@53 135 if (d > 0) {
Chris@53 136 while (d > 0) {
Chris@53 137 zoomOut();
Chris@53 138 d -= 120;
Chris@53 139 }
Chris@53 140 } else {
Chris@53 141 while (d < 0) {
Chris@53 142 zoomIn();
Chris@53 143 d += 120;
Chris@53 144 }
Chris@53 145 }
Chris@53 146 } else {
Chris@53 147 emit wheelEventReceived(ev);
Chris@53 148 QGraphicsView::wheelEvent(ev);
Chris@53 149 }
cannam@45 150 }
cannam@45 151
cannam@45 152 void
cannam@45 153 Panned::slotEmulateWheelEvent(QWheelEvent *ev)
cannam@45 154 {
cannam@45 155 QGraphicsView::wheelEvent(ev);
cannam@45 156 }
cannam@45 157
cannam@45 158 void
Chris@168 159 Panned::mousePressEvent(QMouseEvent *ev)
Chris@168 160 {
Chris@168 161 if (dragMode() != QGraphicsView::ScrollHandDrag ||
Chris@168 162 ev->button() != Qt::LeftButton) {
Chris@168 163 QGraphicsView::mousePressEvent(ev);
Chris@168 164 return;
Chris@168 165 }
Chris@168 166
Chris@168 167 DEBUG << "Panned::mousePressEvent: have left button in drag mode" << endl;
Chris@168 168
Chris@168 169 setDragMode(QGraphicsView::NoDrag);
Chris@168 170 QGraphicsView::mousePressEvent(ev);
Chris@168 171 setDragMode(QGraphicsView::ScrollHandDrag);
Chris@168 172
Chris@168 173 if (!ev->isAccepted()) {
Chris@168 174 ev->accept();
Chris@168 175 m_dragging = true;
Chris@168 176 m_lastDragPos = ev->pos();
Chris@168 177 m_lastOrigin = QPoint(horizontalScrollBar()->value(),
Chris@168 178 verticalScrollBar()->value());
Chris@168 179 m_velocity = QPointF(0, 0);
Chris@168 180 m_dragTimer->start(m_dragTimerMs);
Chris@168 181 }
Chris@168 182
Chris@168 183 }
Chris@168 184
Chris@168 185 void
Chris@168 186 Panned::mouseMoveEvent(QMouseEvent *ev)
Chris@168 187 {
Chris@168 188 if (!m_dragging) {
Chris@168 189 QGraphicsView::mouseMoveEvent(ev);
Chris@168 190 return;
Chris@168 191 }
Chris@168 192 DEBUG << "Panned::mouseMoveEvent: dragging" << endl;
Chris@168 193 ev->accept();
Chris@168 194 QScrollBar *hBar = horizontalScrollBar();
Chris@168 195 QScrollBar *vBar = verticalScrollBar();
Chris@168 196 QPoint delta = ev->pos() - m_lastDragPos;
Chris@168 197 hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
Chris@168 198 vBar->setValue(vBar->value() - delta.y());
Chris@168 199 m_lastDragPos = ev->pos();
Chris@168 200 }
Chris@168 201
Chris@168 202 void
Chris@168 203 Panned::mouseReleaseEvent(QMouseEvent *ev)
Chris@168 204 {
Chris@168 205 if (!m_dragging) {
Chris@168 206 QGraphicsView::mouseReleaseEvent(ev);
Chris@168 207 return;
Chris@168 208 }
Chris@168 209 DEBUG << "Panned::mouseReleaseEvent: dragging" << endl;
Chris@168 210 ev->accept();
Chris@168 211 m_dragging = false;
Chris@168 212 }
Chris@168 213
Chris@168 214 void
Chris@168 215 Panned::dragTimerTimeout()
Chris@168 216 {
Chris@168 217 QPoint origin = QPoint(horizontalScrollBar()->value(),
Chris@168 218 verticalScrollBar()->value());
Chris@168 219 if (m_dragging) {
Chris@168 220 m_velocity = QPointF
Chris@168 221 (float(origin.x() - m_lastOrigin.x()) / m_dragTimerMs,
Chris@168 222 float(origin.y() - m_lastOrigin.y()) / m_dragTimerMs);
Chris@168 223 m_lastOrigin = origin;
Chris@168 224 DEBUG << "Panned::dragTimerTimeout: velocity = " << m_velocity << endl;
Chris@168 225 } else {
Chris@168 226 if (origin == m_lastOrigin) {
Chris@168 227 m_dragTimer->stop();
Chris@168 228 }
Chris@168 229 float x = m_velocity.x(), y = m_velocity.y();
Chris@168 230 if (fabsf(x) > 1.0/m_dragTimerMs) x = x * 0.9f;
Chris@168 231 else x = 0.f;
Chris@168 232 if (fabsf(y) > 1.0/m_dragTimerMs) y = y * 0.9f;
Chris@168 233 else y = 0.f;
Chris@168 234 m_velocity = QPointF(x, y);
Chris@168 235 DEBUG << "Panned::dragTimerTimeout: velocity adjusted to " << m_velocity << endl;
Chris@168 236 m_lastOrigin = origin;
Chris@168 237 //!!! need to store origin in floats
Chris@168 238 horizontalScrollBar()->setValue(m_lastOrigin.x() +
Chris@168 239 m_velocity.x() * m_dragTimerMs);
Chris@168 240 verticalScrollBar()->setValue(m_lastOrigin.y() +
Chris@168 241 m_velocity.y() * m_dragTimerMs);
Chris@168 242 }
Chris@168 243 }
Chris@168 244
Chris@168 245 void
cannam@45 246 Panned::leaveEvent(QEvent *)
cannam@45 247 {
cannam@45 248 emit mouseLeaves();
cannam@45 249 }