annotate panned.cpp @ 344:ccc55539e066

If the user cancels the first startup dialog (it has no cancel button, but they could use the WM close button), go no further
author Chris Cannam
date Wed, 16 Mar 2011 10:25:06 +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 }