File indexing completed on 2024-05-12 04:06:22
0001 /* 0002 SPDX-FileCopyrightText: 2010 Stefan Majewsky <majewsky@gmx.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "constraintinteractor.h" 0008 #include "scene.h" 0009 0010 #include <KLocalizedString> 0011 0012 Palapeli::ConstraintInteractor::ConstraintInteractor(QGraphicsView* view) 0013 : Palapeli::Interactor(10, Palapeli::MouseInteractor, view) //priority: less than interaction with pieces, but more than interaction with viewport 0014 { 0015 setMetadata(TableInteraction, i18n("Change size of puzzle table area by dragging its edges"), QIcon()); 0016 } 0017 0018 QList<Palapeli::ConstraintInteractor::Side> Palapeli::ConstraintInteractor::touchingSides(const QPointF& scenePos) const 0019 { 0020 QList<Side> result; 0021 // The scene must be Palapeli::Scene type, to get handleWidth(). 0022 Palapeli::Scene* scene = qobject_cast<Palapeli::Scene*>(this->scene()); 0023 if (!scene) 0024 return result; // No scene, so no sides touching. 0025 const QRectF sceneRect = scene->sceneRect(); 0026 const qreal w = scene->handleWidth(); 0027 const QSizeF handleSize = QSizeF(w, w); 0028 if ((scenePos.x() > sceneRect.left()) && (scenePos.x() < sceneRect.left() + handleSize.width())) 0029 result << LeftSide; 0030 else if ((scenePos.x() < sceneRect.right()) && (scenePos.x() > sceneRect.right() - handleSize.width())) 0031 result << RightSide; 0032 if ((scenePos.y() > sceneRect.top()) && (scenePos.y() < sceneRect.top() + handleSize.height())) 0033 result << TopSide; 0034 else if ((scenePos.y() < sceneRect.bottom()) && (scenePos.y() > sceneRect.bottom() - handleSize.height())) 0035 result << BottomSide; 0036 return result; 0037 } 0038 0039 bool Palapeli::ConstraintInteractor::startInteraction(const Palapeli::MouseEvent& event) 0040 { 0041 if (!scene()) 0042 return false; 0043 //determine touching sides 0044 m_draggingSides = touchingSides(event.scenePos); 0045 if (m_draggingSides.isEmpty()) 0046 return false; 0047 //record the position where we grabbed the handles (more precisely: its distance to the sides of the scene rect) 0048 m_baseSceneRectOffset = QPointF(); 0049 const QRectF sceneRect = scene()->sceneRect(); 0050 if (m_draggingSides.contains(LeftSide)) 0051 m_baseSceneRectOffset.rx() = event.scenePos.x() - sceneRect.left(); 0052 else if (m_draggingSides.contains(RightSide)) 0053 m_baseSceneRectOffset.rx() = event.scenePos.x() - sceneRect.right(); 0054 if (m_draggingSides.contains(TopSide)) 0055 m_baseSceneRectOffset.ry() = event.scenePos.y() - sceneRect.top(); 0056 else if (m_draggingSides.contains(BottomSide)) 0057 m_baseSceneRectOffset.ry() = event.scenePos.y() - sceneRect.bottom(); 0058 return true; 0059 } 0060 0061 void Palapeli::ConstraintInteractor::continueInteraction(const Palapeli::MouseEvent& event) 0062 { 0063 // In this method, we need the scene() to be Palapeli::Scene type. 0064 Palapeli::Scene* scene = qobject_cast<Palapeli::Scene*>(this->scene()); 0065 if (!scene) 0066 return; 0067 QRectF sceneRect = scene->sceneRect(); 0068 //change scene rect 0069 const QPointF newBounds = event.scenePos - m_baseSceneRectOffset; 0070 if (m_draggingSides.contains(LeftSide)) 0071 sceneRect.setLeft(newBounds.x()); 0072 else if (m_draggingSides.contains(RightSide)) 0073 sceneRect.setRight(newBounds.x()); 0074 if (m_draggingSides.contains(TopSide)) 0075 sceneRect.setTop(newBounds.y()); 0076 else if (m_draggingSides.contains(BottomSide)) 0077 sceneRect.setBottom(newBounds.y()); 0078 scene->setSceneRect(sceneRect | scene->extPiecesBoundingRect()); 0079 } 0080 0081 void Palapeli::ConstraintInteractor::stopInteraction(const Palapeli::MouseEvent& event) 0082 { 0083 Q_UNUSED(event) 0084 m_draggingSides.clear(); 0085 }