1 
2 /*
3    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
4    All rights reserved.
5 
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9 
10    1. Redistributions of source code must retain the above copyright
11       notice, this list of conditions and the following disclaimer.
12    2. Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in the
14       documentation and/or other materials provided with the distribution.
15 
16    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 
29 #ifndef KP_VIEW_SCROLLABLE_CONTAINER_H
30 #define KP_VIEW_SCROLLABLE_CONTAINER_H
31 
32 
33 #include <QLabel>
34 #include <QPoint>
35 #include <QScrollArea>
36 #include <QSize>
37 
38 
39 class QCursor;
40 class QEvent;
41 class QKeyEvent;
42 class QMouseEvent;
43 class QRect;
44 class QResizeEvent;
45 class QTimer;
46 
47 class kpView;
48 class kpOverlay;
49 
50 
51 //---------------------------------------------------------------------
52 
53 // REFACTOR: refactor by sharing iface's with kpTool
54 class kpGrip : public QWidget
55 {
56 Q_OBJECT
57 
58 public:
59     enum GripType
60     {
61         Right = 1, Bottom = 2,
62         BottomRight = Right | Bottom
63     };
64 
65     kpGrip (GripType type, QWidget *parent);
66 
67     GripType type () const;
68 
69     static QCursor cursorForType (GripType type);
70 
71     bool containsCursor();
72 
73     bool isDrawing () const;
74 
75     static const int Size;
76 
77 signals:
78     void beganDraw ();
79     void continuedDraw (int viewDX, int viewDY, bool dueToDragScroll);
80     void cancelledDraw ();
81     void endedDraw (int viewDX, int viewDY);
82 
83     void statusMessageChanged (const QString &string);
84 
85     void releasedAllButtons ();
86 
87 public:
88     QString haventBegunDrawUserMessage () const;
89 
90     QString userMessage () const;
91     void setUserMessage (const QString &message);
92 
93 protected:
94     void cancel ();
95 
96 protected:
97     void keyReleaseEvent (QKeyEvent *e) override;
98     void mousePressEvent (QMouseEvent *e) override;
99 public:
100     QPoint viewDeltaPoint () const;
101     void mouseMovedTo (const QPoint &point, bool dueToDragScroll);
102 protected:
103     void mouseMoveEvent (QMouseEvent *e) override;
104     void mouseReleaseEvent (QMouseEvent *e) override;
105 
106     void enterEvent (QEvent *e) override;
107     void leaveEvent (QEvent *e) override;
108 
109 protected:
110     GripType m_type;
111     QPoint m_startPoint, m_currentPoint;
112     QString m_userMessage;
113     bool m_shouldReleaseMouseButtons;
114 };
115 
116 //---------------------------------------------------------------------
117 
118 class kpViewScrollableContainer : public QScrollArea
119 {
120 Q_OBJECT
121 
122 public:
123     kpViewScrollableContainer(QWidget *parent);
124 
125     QSize newDocSize () const;
126     bool haveMovedFromOriginalDocSize () const;
127     QString statusMessage () const;
128     void clearStatusMessage ();
129 
130     kpView *view () const;
131     void setView (kpView *view);
132 
133     void drawResizeLines();  // public only for kpOverlay
134 
135 signals:
136     void contentsMoved();
137 
138     void beganDocResize ();
139     void continuedDocResize (const QSize &size);
140     void cancelledDocResize ();
141     void endedDocResize (const QSize &size);
142 
143     // (string.isEmpty() if kpViewScrollableContainer has nothing to say)
144     void statusMessageChanged (const QString &string);
145 
146     void resized ();
147 
148 public slots:
149     void recalculateStatusMessage ();
150 
151     void updateGrips ();
152 
153     // TODO: Why the need for view's zoomLevel?  We have the view() anyway.
154     bool beginDragScroll (int zoomLevel,
155                           bool *didSomething);
156     bool beginDragScroll (int zoomLevel);
157     bool endDragScroll ();
158 
159 private:
160     void connectGripSignals (kpGrip *grip);
161 
162     QSize newDocSize (int viewDX, int viewDY) const;
163 
164     void calculateDocResizingGrip ();
165     kpGrip *docResizingGrip () const;
166 
167     int bottomResizeLineWidth () const;
168     int rightResizeLineWidth () const;
169 
170     QRect bottomResizeLineRect () const;
171     QRect rightResizeLineRect () const;
172     QRect bottomRightResizeLineRect () const;
173 
174     QRect mapViewToViewport (const QRect &viewRect);
175 
176     void updateResizeLines (int viewX, int viewY,
177                             int viewDX, int viewDY);
178 
179     void disconnectViewSignals ();
180     void connectViewSignals ();
181 
182     QRect noDragScrollRect () const;
183 
184     void wheelEvent(QWheelEvent *e) override;
185     void resizeEvent(QResizeEvent *e) override;
186 
187 private slots:
188     void slotGripBeganDraw ();
189     void slotGripContinuedDraw (int viewDX, int viewDY, bool dueToScrollView);
190     void slotGripCancelledDraw ();
191     void slotGripEndedDraw (int viewDX, int viewDY);
192 
193     void slotGripStatusMessageChanged (const QString &string);
194 
195     void slotContentsMoved ();
196     void slotViewDestroyed ();
197     bool slotDragScroll (bool *didSomething = nullptr);
198 
199 private:
200     kpView *m_view;
201     kpOverlay *m_overlay;
202     kpGrip *m_bottomGrip, *m_rightGrip, *m_bottomRightGrip;
203     kpGrip *m_docResizingGrip;
204     QTimer *m_dragScrollTimer;
205     int m_zoomLevel;
206     bool m_scrollTimerRunOnce;
207     int m_resizeRoundedLastViewX, m_resizeRoundedLastViewY;
208     int m_resizeRoundedLastViewDX, m_resizeRoundedLastViewDY;
209     bool m_haveMovedFromOriginalDocSize;
210     QString m_gripStatusMessage;
211 };
212 
213 #endif  // KP_VIEW_SCROLLABLE_CONTAINER_H
214