File indexing completed on 2024-04-28 04:21:28
0001 // SPDX-FileCopyrightText: 2003-2010 Jesper K. Pedersen <blackie@kde.org> 0002 // SPDX-FileCopyrightText: 2022 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0003 // 0004 // SPDX-License-Identifier: GPL-2.0-or-later 0005 0006 #include "ViewHandler.h" 0007 0008 #include <QMouseEvent> 0009 #include <QRubberBand> 0010 #include <qapplication.h> 0011 #include <qcursor.h> 0012 #include <qpainter.h> 0013 0014 /** 0015 * \class Viewer::ViewHandler 0016 * \brief Mouse handler used during zooming and panning actions 0017 */ 0018 0019 Viewer::ViewHandler::ViewHandler(Viewer::ImageDisplay *display) 0020 : QObject(display) 0021 , m_scale(false) 0022 , m_pan(false) 0023 , m_errorX(0) 0024 , m_errorY(0) 0025 , m_rubberBand(new QRubberBand(QRubberBand::Rectangle, display)) 0026 , m_display(display) 0027 { 0028 } 0029 0030 bool Viewer::ViewHandler::mousePressEvent(QMouseEvent *e, const QPoint &unTranslatedPos, double /*scaleFactor*/) 0031 { 0032 m_pan = false; 0033 m_scale = false; 0034 0035 if ((e->button() & Qt::LeftButton)) { 0036 if ((e->modifiers() & Qt::ControlModifier)) { 0037 m_pan = true; 0038 } else { 0039 m_scale = true; 0040 } 0041 } else if (e->button() & Qt::MiddleButton) { 0042 m_pan = true; 0043 } 0044 0045 if (m_pan) { 0046 // panning 0047 m_last = unTranslatedPos; 0048 qApp->setOverrideCursor(Qt::SizeAllCursor); 0049 m_errorX = 0; 0050 m_errorY = 0; 0051 return true; 0052 } else if (m_scale) { 0053 // scaling 0054 m_start = e->pos(); 0055 m_untranslatedStart = unTranslatedPos; 0056 qApp->setOverrideCursor(Qt::CrossCursor); 0057 return true; 0058 } else { 0059 return true; 0060 } 0061 } 0062 0063 bool Viewer::ViewHandler::mouseMoveEvent(QMouseEvent *, 0064 const QPoint &unTranslatedPos, double scaleFactor) 0065 { 0066 if (m_scale) { 0067 m_rubberBand->setGeometry(QRect(m_untranslatedStart, unTranslatedPos).normalized()); 0068 m_rubberBand->show(); 0069 return true; 0070 } else if (m_pan) { 0071 // This code need to be taking the error into account, consider this situation: 0072 // The user moves the mouse very slowly, only 1 pixel at a time, scale factor is 3 0073 // Then translated delta would be 1/3 which every time would be 0074 // rounded down to 0, and the panning would never move any pixels. 0075 double deltaX = m_errorX + (m_last.x() - unTranslatedPos.x()) / scaleFactor; 0076 double deltaY = m_errorY + (m_last.y() - unTranslatedPos.y()) / scaleFactor; 0077 QPoint deltaPoint = QPoint((int)deltaX, (int)deltaY); 0078 m_errorX = deltaX - ((double)((int)deltaX)); 0079 m_errorY = deltaY - ((double)((int)deltaY)); 0080 0081 m_display->pan(deltaPoint); 0082 m_last = unTranslatedPos; 0083 return true; 0084 } else 0085 return false; 0086 } 0087 0088 bool Viewer::ViewHandler::mouseReleaseEvent(QMouseEvent *e, const QPoint & /*unTranslatedPos*/, double /*scaleFactor*/) 0089 { 0090 if (m_scale) { 0091 qApp->restoreOverrideCursor(); 0092 m_rubberBand->hide(); 0093 m_scale = false; 0094 if ((e->pos() - m_start).manhattanLength() > 1) { 0095 m_display->zoom(m_start, e->pos()); 0096 return true; 0097 } else 0098 return false; 0099 } else if (m_pan) { 0100 qApp->restoreOverrideCursor(); 0101 m_pan = false; 0102 return true; 0103 } else 0104 return false; 0105 } 0106 0107 void Viewer::ViewHandler::hideEvent() 0108 { 0109 // In case the escape key is pressed while viewing or scaling, then we need to restore the override cursor 0110 // (As in that case we will not see a key release event) 0111 if (m_pan || m_scale) { 0112 qApp->restoreOverrideCursor(); 0113 m_pan = false; 0114 m_scale = false; 0115 } 0116 } 0117 // vi:expandtab:tabstop=4 shiftwidth=4: 0118 0119 #include "moc_ViewHandler.cpp"