File indexing completed on 2024-05-12 04:06:24

0001 /*
0002     SPDX-FileCopyrightText: 2010 Stefan Majewsky <majewsky@gmx.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef PALAPELI_INTERACTORS_H
0008 #define PALAPELI_INTERACTORS_H
0009 
0010 #include "interactor.h"
0011 
0012 #include <QGraphicsItem>
0013 
0014 namespace Palapeli
0015 {
0016     class Piece;
0017 
0018     //This interactor is assigned to LeftButton;NoModifier by default.
0019     //1. When you click on and drag a selected piece, all selected pieces are moved.
0020     //2. When you click on and drag an unselected piece, all other pieces are deselected, the clicked piece is selected and moved.
0021     class MovePieceInteractor : public QObject, public Palapeli::Interactor
0022     {
0023         Q_OBJECT
0024         public:
0025             explicit MovePieceInteractor(QGraphicsView* view);
0026         protected:
0027             bool startInteraction(const Palapeli::MouseEvent& event) override;
0028             void continueInteraction(const Palapeli::MouseEvent& event) override;
0029             void stopInteraction(const Palapeli::MouseEvent& event) override;
0030         protected Q_SLOTS:
0031             void pieceReplacedBy(Palapeli::Piece* replacement);
0032         private:
0033             void determineSelectedItems(QGraphicsItem* clickedItem, Palapeli::Piece* clickedPiece);
0034 
0035             QList<Palapeli::Piece*> m_currentPieces;
0036             QPointF m_baseScenePosition, m_currentOffset;
0037             QPoint m_baseViewPosition;
0038             QList<QPointF> m_basePositions;
0039     };
0040 
0041     //This interactor is assigned to LeftButton;ControlModifier by default.
0042     //When you click on a piece, its selection state will be toggled.
0043     class SelectPieceInteractor : public Palapeli::Interactor
0044     {
0045         public:
0046             explicit SelectPieceInteractor(QGraphicsView* view);
0047         protected:
0048             bool startInteraction(const Palapeli::MouseEvent& event) override;
0049             void stopInteraction(const Palapeli::MouseEvent& event) override;
0050         private:
0051             Palapeli::Piece* m_currentPiece;
0052     };
0053 
0054     //This interactor is assigned to LeftButton;ShiftModifier by default.
0055     // 1. When you click on a piece in the puzzle table it is transferred
0056     //    immediately to the currently selected piece-holder.
0057     // 2. When you select one or more pieces on the puzzle table and click
0058     //    anywhere on the puzzle table, all the selected pieces are
0059     //    transferred immediately to the currently selected piece-holder.
0060     // 3. When you select one or more pieces in the currently selected
0061     //    piece-holder and then click anywhere on the puzzle table or in
0062     //    another piece-holder, all the selected pieces are transferred
0063     //    immediately to the place where you clicked.
0064     //
0065     //The transferred pieces are set selected when they arrive and are
0066     //arranged tidily in a grid pattern. In case 3, the top-left of the
0067     //grid is where you clicked.
0068     class TeleportPieceInteractor : public Palapeli::Interactor
0069     {
0070         public:
0071             explicit TeleportPieceInteractor(QGraphicsView* view);
0072         protected:
0073             bool startInteraction(const Palapeli::MouseEvent& event) override;
0074     };
0075 
0076     //This interactor is assigned to RightButton;NoModifier by default.
0077     //Dragging will drag the viewport (only translations, no rotation or zooming).
0078     class MoveViewportInteractor : public Palapeli::Interactor
0079     {
0080         public:
0081             explicit MoveViewportInteractor(QGraphicsView* view);
0082         protected:
0083             bool startInteraction(const Palapeli::MouseEvent& event) override;
0084             void continueInteraction(const Palapeli::MouseEvent& event) override;
0085         private:
0086             QPoint m_lastPos;
0087     };
0088 
0089     //This interactor is assigned to MidButton;NoModifier by default.
0090     //Clicking on a view will toggle it between close-up and distant views.
0091     class ToggleCloseUpInteractor : public Palapeli::Interactor
0092     {
0093         public:
0094             explicit ToggleCloseUpInteractor(QGraphicsView* view);
0095         protected:
0096             bool startInteraction(const Palapeli::MouseEvent& event) override;
0097     };
0098 
0099     //This interactor is assigned to wheel:Vertical;NoModifier by default.
0100     //Turning the wheel will zoom the viewport.
0101     class ZoomViewportInteractor : public Palapeli::Interactor
0102     {
0103         public:
0104             explicit ZoomViewportInteractor(QGraphicsView* view);
0105         protected:
0106             void doInteraction(const Palapeli::WheelEvent& event) override;
0107     };
0108 
0109     //This interactor is assigned to nothing by default.
0110     //Turning the wheel will scroll the viewport either horizontally or vertically.
0111     class ScrollViewportInteractor : public Palapeli::Interactor
0112     {
0113         public:
0114             ScrollViewportInteractor(Qt::Orientation orientation, QGraphicsView* view);
0115         protected:
0116             void doInteraction(const Palapeli::WheelEvent& event) override;
0117         private:
0118             Qt::Orientation m_orientation;
0119     };
0120 
0121     class RubberBandItem : public QGraphicsItem
0122     {
0123         public:
0124             explicit RubberBandItem(QGraphicsItem* parent = nullptr);
0125 
0126             QRectF rect() const;
0127             void setRect(const QRectF& rect);
0128 
0129             QRectF boundingRect() const override;
0130             void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = nullptr) override;
0131         private:
0132             QRectF m_rect;
0133     };
0134 
0135     //This interactor is assigned to LeftClick;NoModifier by default.
0136     //When you click on a free area of the view and drag the mouse, a rectangular rubberband will appear. All pieces inside the rubberband will be selected, all other pieces are deselected.
0137     class RubberBandInteractor : public Palapeli::Interactor
0138     {
0139         public:
0140             explicit RubberBandInteractor(QGraphicsView* view);
0141             ~RubberBandInteractor() override;
0142         protected:
0143             void sceneChangeEvent(QGraphicsScene* oldScene, QGraphicsScene* newScene) override;
0144             bool startInteraction(const Palapeli::MouseEvent& event) override;
0145             void continueInteraction(const Palapeli::MouseEvent& event) override;
0146             void stopInteraction(const Palapeli::MouseEvent& event) override;
0147         private:
0148             Palapeli::RubberBandItem* m_item;
0149             QPointF m_basePosition;
0150     };
0151 
0152     //This interactor is assigned to nothing by default.
0153     //When the interactor is triggered, the scene constraint is toggled.
0154     class ToggleConstraintInteractor : public Palapeli::Interactor
0155     {
0156         public:
0157             explicit ToggleConstraintInteractor(QGraphicsView* view);
0158         protected:
0159             bool startInteraction(const Palapeli::MouseEvent& event) override;
0160     };
0161 }
0162 
0163 #endif // PALAPELI_INTERACTORS_H