File indexing completed on 2024-05-19 15:27:52
0001 /* This file is part of KGraphViewer. 0002 Copyright (C) 2005-2007 Gael de Chalendar <kleag@free.fr> 0003 0004 KGraphViewer is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU General Public 0006 License as published by the Free Software Foundation, version 2. 0007 0008 This program is distributed in the hope that it will be useful, 0009 but WITHOUT ANY WARRANTY; without even the implied warranty of 0010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0011 General Public License for more details. 0012 0013 You should have received a copy of the GNU General Public License 0014 along with this program; if not, write to the Free Software 0015 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0016 02110-1301, USA 0017 */ 0018 0019 /* This file was callgraphview.cpp, part of KCachegrind. 0020 Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> 0021 0022 KCachegrind is free software; you can redistribute it and/or 0023 modify it under the terms of the GNU General Public 0024 License as published by the Free Software Foundation, version 2. 0025 */ 0026 0027 /* 0028 * Callgraph View 0029 */ 0030 0031 #include "pannerview.h" 0032 #include "dotgraphview.h" 0033 #include "kgraphviewerlib_debug.h" 0034 0035 #include <iostream> 0036 #include <math.h> 0037 #include <stdlib.h> 0038 0039 #include <QDebug> 0040 #include <QGraphicsScene> 0041 #include <QMouseEvent> 0042 #include <QPainter> 0043 0044 #include <klocalizedstring.h> 0045 0046 namespace KGraphViewer 0047 { 0048 // 0049 // PannerView 0050 // 0051 PannerView::PannerView(DotGraphView *parent) 0052 : QGraphicsView(parent) 0053 , m_drawContents(true) 0054 , m_parent(parent) 0055 { 0056 m_movingZoomRect = false; 0057 0058 // why doesn't this avoid flicker ? 0059 // viewport()->setBackgroundMode(Qt::NoBackground); 0060 0061 // if there are ever graphic glitches to be found, remove this again 0062 setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing | QGraphicsView::DontClipPainter | QGraphicsView::DontSavePainterState); 0063 0064 setToolTip(i18n("View of the complete graph. Click and drag to move the visible part.")); 0065 setWhatsThis( 0066 i18n("<h1>View of the Complete Graph</h1>" 0067 "<p>Single clicking somewhere without the red square will move the center of the " 0068 "view to where the mouse was clicked.</p><p>Clicking and dragging within the red square " 0069 "will cause the view to follow the movement.</p>")); 0070 } 0071 0072 void PannerView::setZoomRect(QRectF r) 0073 { 0074 // qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::setZoomRect " << r; 0075 if (r == m_zoomRect) { 0076 return; 0077 } 0078 scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer); 0079 // get new zoom rect 0080 m_zoomRect = r; 0081 qreal q = mapToScene(15, 0).x(); 0082 if (!m_zoomRect.isValid() || m_zoomRect.width() < q || m_zoomRect.height() < q) { 0083 double factor = ((double)m_zoomRect.width()) / m_zoomRect.height(); 0084 qreal newWidth, newHeight; 0085 if (factor < 1.0) { 0086 newWidth = q; 0087 newHeight = newWidth / factor; 0088 } else { 0089 newHeight = q; 0090 newWidth = newHeight * factor; 0091 } 0092 qreal newXPos = m_zoomRect.x() + (m_zoomRect.width() - newWidth) / 2; 0093 qreal newYPos = m_zoomRect.y() + (m_zoomRect.height() - newHeight) / 2; 0094 m_zoomRect.setX(newXPos); 0095 m_zoomRect.setY(newYPos); 0096 m_zoomRect.setWidth(newWidth); 0097 m_zoomRect.setHeight(newHeight); 0098 } 0099 scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer); 0100 } 0101 0102 void PannerView::moveZoomRectTo(const QPointF &newPos, bool notify) 0103 { 0104 if (!m_zoomRect.isValid()) { 0105 return; 0106 } 0107 0108 if (m_zoomRect.center() == newPos) { 0109 qCDebug(KGRAPHVIEWERLIB_LOG) << "same pos, don't do anything"; 0110 return; 0111 } 0112 0113 scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer); 0114 m_zoomRect.moveCenter(newPos); 0115 scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer); 0116 0117 if (m_zoomRect.isValid() && notify) { 0118 emit zoomRectMovedTo(newPos); 0119 m_lastPos = newPos; 0120 } 0121 } 0122 0123 void PannerView::drawForeground(QPainter *p, const QRectF &rect) 0124 { 0125 if (m_zoomRect.isValid() && rect.intersects(m_zoomRect)) { 0126 p->save(); 0127 if (m_zoomRect.width() > 10 && m_zoomRect.height() > 10) { 0128 p->setPen(Qt::red); 0129 // subtract pen width, i.e. draw inside 0130 qreal penWidth = p->pen().widthF(); 0131 p->drawRect(m_zoomRect.adjusted(-penWidth, -penWidth, -penWidth, -penWidth)); 0132 } else { 0133 QBrush brush(Qt::red); 0134 p->fillRect(m_zoomRect, brush); 0135 } 0136 p->restore(); 0137 } 0138 } 0139 0140 void PannerView::mousePressEvent(QMouseEvent *e) 0141 { 0142 if (e->button() != Qt::LeftButton) { 0143 return; 0144 } 0145 /* qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::mousePressEvent " 0146 << mapToScene(e->pos()) << " / " << m_zoomRect << " / " << m_zoomRect.center() <<endl;*/ 0147 moveZoomRectTo(mapToScene(e->pos())); 0148 m_movingZoomRect = true; 0149 } 0150 0151 void PannerView::mouseMoveEvent(QMouseEvent *e) 0152 { 0153 if (!m_movingZoomRect) { 0154 return; 0155 } 0156 0157 // qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::mouseMoveEvent " << pos; 0158 moveZoomRectTo(mapToScene(e->pos())); 0159 } 0160 0161 void PannerView::mouseReleaseEvent(QMouseEvent *e) 0162 { 0163 if (e->button() != Qt::LeftButton) { 0164 return; 0165 } 0166 moveZoomRectTo(mapToScene(e->pos())); 0167 // qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::mouseReleaseEvent " << pos; 0168 m_movingZoomRect = false; 0169 emit zoomRectMoveFinished(); 0170 } 0171 0172 void PannerView::contextMenuEvent(QContextMenuEvent *event) 0173 { 0174 m_parent->contextMenuEvent(event); 0175 } 0176 0177 } 0178 0179 #include "moc_pannerview.cpp"