File indexing completed on 2024-04-21 04:20:48

0001 
0002 /*
0003    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0004    All rights reserved.
0005 
0006    Redistribution and use in source and binary forms, with or without
0007    modification, are permitted provided that the following conditions
0008    are met:
0009 
0010    1. Redistributions of source code must retain the above copyright
0011       notice, this list of conditions and the following disclaimer.
0012    2. Redistributions in binary form must reproduce the above copyright
0013       notice, this list of conditions and the following disclaimer in the
0014       documentation and/or other materials provided with the distribution.
0015 
0016    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026 */
0027 
0028 
0029 #ifndef KP_VIEW_SCROLLABLE_CONTAINER_H
0030 #define KP_VIEW_SCROLLABLE_CONTAINER_H
0031 
0032 
0033 #include <QPoint>
0034 #include <QScrollArea>
0035 #include <QSize>
0036 
0037 
0038 class QCursor;
0039 class QEvent;
0040 class QKeyEvent;
0041 class QMouseEvent;
0042 class QRect;
0043 class QResizeEvent;
0044 class QTimer;
0045 
0046 class kpView;
0047 class kpOverlay;
0048 
0049 
0050 //---------------------------------------------------------------------
0051 
0052 // REFACTOR: refactor by sharing iface's with kpTool
0053 class kpGrip : public QWidget
0054 {
0055 Q_OBJECT
0056 
0057 public:
0058     enum GripType
0059     {
0060         Right = 1, Bottom = 2,
0061         BottomRight = Right | Bottom
0062     };
0063 
0064     kpGrip (GripType type, QWidget *parent);
0065 
0066     GripType type () const;
0067 
0068     static QCursor cursorForType (GripType type);
0069 
0070     bool containsCursor();
0071 
0072     bool isDrawing () const;
0073 
0074     static const int Size;
0075 
0076 Q_SIGNALS:
0077     void beganDraw ();
0078     void continuedDraw (int viewDX, int viewDY, bool dueToDragScroll);
0079     void cancelledDraw ();
0080     void endedDraw (int viewDX, int viewDY);
0081 
0082     void statusMessageChanged (const QString &string);
0083 
0084     void releasedAllButtons ();
0085 
0086 public:
0087     QString haventBegunDrawUserMessage () const;
0088 
0089     QString userMessage () const;
0090     void setUserMessage (const QString &message);
0091 
0092 protected:
0093     void cancel ();
0094 
0095 protected:
0096     void keyReleaseEvent (QKeyEvent *e) override;
0097     void mousePressEvent (QMouseEvent *e) override;
0098 public:
0099     QPoint viewDeltaPoint () const;
0100     void mouseMovedTo (const QPoint &point, bool dueToDragScroll);
0101 protected:
0102     void mouseMoveEvent (QMouseEvent *e) override;
0103     void mouseReleaseEvent (QMouseEvent *e) override;
0104 
0105 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0106     void enterEvent (QEnterEvent *e) override;
0107 #else
0108     void enterEvent (QEvent *e) override;
0109 #endif
0110     void leaveEvent (QEvent *e) override;
0111 
0112 protected:
0113     GripType m_type;
0114     QPoint m_startPoint, m_currentPoint;
0115     QString m_userMessage;
0116     bool m_shouldReleaseMouseButtons;
0117 };
0118 
0119 //---------------------------------------------------------------------
0120 
0121 class kpViewScrollableContainer : public QScrollArea
0122 {
0123 Q_OBJECT
0124 
0125 public:
0126     explicit kpViewScrollableContainer(QWidget *parent);
0127 
0128     QSize newDocSize () const;
0129     bool haveMovedFromOriginalDocSize () const;
0130     QString statusMessage () const;
0131     void clearStatusMessage ();
0132 
0133     kpView *view () const;
0134     void setView (kpView *view);
0135 
0136     void drawResizeLines();  // public only for kpOverlay
0137 
0138 Q_SIGNALS:
0139     void contentsMoved();
0140 
0141     void beganDocResize ();
0142     void continuedDocResize (const QSize &size);
0143     void cancelledDocResize ();
0144     void endedDocResize (const QSize &size);
0145 
0146     // (string.isEmpty() if kpViewScrollableContainer has nothing to say)
0147     void statusMessageChanged (const QString &string);
0148 
0149     void resized ();
0150 
0151 public Q_SLOTS:
0152     void recalculateStatusMessage ();
0153 
0154     void updateGrips ();
0155 
0156     // TODO: Why the need for view's zoomLevel?  We have the view() anyway.
0157     bool beginDragScroll (int zoomLevel,
0158                           bool *didSomething);
0159     bool beginDragScroll (int zoomLevel);
0160     bool endDragScroll ();
0161 
0162 private:
0163     void connectGripSignals (kpGrip *grip);
0164 
0165     QSize newDocSize (int viewDX, int viewDY) const;
0166 
0167     void calculateDocResizingGrip ();
0168     kpGrip *docResizingGrip () const;
0169 
0170     int bottomResizeLineWidth () const;
0171     int rightResizeLineWidth () const;
0172 
0173     QRect bottomResizeLineRect () const;
0174     QRect rightResizeLineRect () const;
0175     QRect bottomRightResizeLineRect () const;
0176 
0177     QRect mapViewToViewport (const QRect &viewRect);
0178 
0179     void updateResizeLines (int viewX, int viewY,
0180                             int viewDX, int viewDY);
0181 
0182     void disconnectViewSignals ();
0183     void connectViewSignals ();
0184 
0185     QRect noDragScrollRect () const;
0186 
0187     void wheelEvent(QWheelEvent *e) override;
0188     void resizeEvent(QResizeEvent *e) override;
0189 
0190 private Q_SLOTS:
0191     void slotGripBeganDraw ();
0192     void slotGripContinuedDraw (int viewDX, int viewDY, bool dueToScrollView);
0193     void slotGripCancelledDraw ();
0194     void slotGripEndedDraw (int viewDX, int viewDY);
0195 
0196     void slotGripStatusMessageChanged (const QString &string);
0197 
0198     void slotContentsMoved ();
0199     void slotViewDestroyed ();
0200     bool slotDragScroll (bool *didSomething = nullptr);
0201 
0202 private:
0203     kpView *m_view;
0204     kpOverlay *m_overlay;
0205     kpGrip *m_bottomGrip, *m_rightGrip, *m_bottomRightGrip;
0206     kpGrip *m_docResizingGrip;
0207     QTimer *m_dragScrollTimer;
0208     int m_zoomLevel;
0209     bool m_scrollTimerRunOnce;
0210     int m_resizeRoundedLastViewX, m_resizeRoundedLastViewY;
0211     int m_resizeRoundedLastViewDX, m_resizeRoundedLastViewDY;
0212     bool m_haveMovedFromOriginalDocSize;
0213     QString m_gripStatusMessage;
0214 };
0215 
0216 #endif  // KP_VIEW_SCROLLABLE_CONTAINER_H