99 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
1010 ******************************************************************************/
1111
12+ #include " message.hpp"
13+
1214#include " QTMScrollView.hpp"
15+ #include " QTMApplication.hpp"
1316
1417#include < QScrollBar>
15- #include < QApplication>
16- #include < QResizeEvent>
18+ #include < QPainter>
19+ #include < QBoxLayout>
20+ #include < QPaintEvent>
1721#include < QStyle>
1822
1923
24+ /* ! Provide automatic centering of the working area inside the viewport.
25+
26+ The only purpose of this widget is to provide this centering. To support this
27+ we "un-wired" the event redirection built-in in QAbstractScrollArea (from the
28+ viewport widget to the QAbstractScrollArea) and re-wired event redirection
29+ from the surface to the QTMScrollView (see event())
30+
31+ All relevant events like resize, I/O events and the like which are sent to the
32+ surface are resent QTMScrollView::surfaceEvent() for handling. This allows to
33+ concentrate all the logic in only one object.
34+ */
35+ class QTMSurface : public QWidget {
36+
37+ QTMScrollView* sv;
38+ public:
39+ QTMSurface (QWidget* p, QTMScrollView* _sv) : QWidget (p), sv (_sv) { }
40+
41+ protected:
42+ virtual bool event (QEvent *event) {
43+ return sv->surfaceEvent (event) ? true : QWidget::event (event);
44+ }
45+ };
46+
2047/* ! Constructor.
2148
49+ NOTE:
50+ We tell the p_surface to use all available space by default (this is needed by
51+ embedded widgets) by setting the SizePolicy to (Expanding, Expanding).
52+ In order to draw the vertical margins around the working area use a horizontal
53+ policy of Fixedl, as in qt_tm_widget_rep (see SLOT_SCROLLABLE there)
54+
2255 NOTE:
2356 Don't try to disable double buffering even if we do our own: the flag
2457 Qt::WA_PaintOnScreen is only supported on X11 and anyway makes things slower
2558 */
26-
2759QTMScrollView::QTMScrollView (QWidget *_parent):
2860 QAbstractScrollArea (_parent),
2961 editor_flag (false ),
3062 p_extents (QRect(0 ,0 ,0 ,0 ))
3163{
3264 QWidget *_viewport = QAbstractScrollArea::viewport ();
33- _viewport->setBackgroundRole (QPalette::Mid);
34- _viewport->setAutoFillBackground (true );
35- // alternative settings
36- // _viewport->setAttribute (Qt::WA_OpaquePaintEvent);
37- // _viewport->setAttribute (Qt::WA_StaticContents);
38- // _viewport->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
39- // _viewport->setAttribute(Qt::WA_MacNoClickThrough);
40- // _viewport->setAttribute(Qt::WA_NoSystemBackground);
41- setFrameShape (QFrame::NoFrame);
65+ _viewport->setBackgroundRole (QPalette::Mid);
66+ _viewport->setAutoFillBackground (true );
67+ setFrameShape (QFrame::NoFrame);
68+
69+ p_surface = new QTMSurface (_viewport, this );
70+ p_surface->setAttribute (Qt::WA_NoSystemBackground);
71+ p_surface->setAttribute (Qt::WA_StaticContents);
72+ p_surface->setAttribute (Qt::WA_MacNoClickThrough);
73+ p_surface->setAutoFillBackground (false );
74+ p_surface->setBackgroundRole (QPalette::NoRole);
75+ p_surface->setAttribute (Qt::WA_OpaquePaintEvent);
76+ p_surface->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
77+
78+ QHBoxLayout *layout = new QHBoxLayout ();
79+ layout->addWidget (p_surface, 0 , Qt::AlignHCenter | Qt::AlignVCenter);
80+ layout->setContentsMargins (0 ,0 ,0 ,0 );
81+ _viewport->setLayout (layout);
4282}
4383
4484void
@@ -103,32 +143,39 @@ QTMScrollView::updateScrollBars (void) {
103143 QScrollBar *_hScrollBar = QAbstractScrollArea::horizontalScrollBar ();
104144 QScrollBar *_vScrollBar = QAbstractScrollArea::verticalScrollBar ();
105145
106- // (mg) see edit_interface_rep::apply_changes () (set_extent)
107- // for the 2 pixel mismatch. I'm not really sure why is needed.
108- int xw = p_extents.width () - 2 ;
109- int xh = p_extents.height ()- 2 ;
110- int w = _viewport->width ();
111- int h = _viewport->height ();
146+ int xw = p_extents.width ();
147+ int xh = p_extents.height ();
148+ int w = _viewport->width () ; // -2
149+ int h = _viewport->height (); // -2
112150 int sbw= qApp->style ()->pixelMetric (QStyle::PM_ScrollBarExtent);
113151 if (_hScrollBar->maximum () > _hScrollBar->minimum ()) h += sbw;
114152 if (_vScrollBar->maximum () > _vScrollBar->minimum ()) w += sbw;
153+ if (xw > w) h -= sbw;
154+ if (xh > h) w -= sbw;
115155 if (!editor_flag) {
116156 if (xw < w) xw= w;
117157 if (xh < h) xh= h;
118158 }
119- int cw = (xw > w ? xw - w + sbw : 0 );
159+
160+ int cw = (xw > w ? xw - w : 0 );
120161 if (_hScrollBar->sliderPosition () > cw)
121162 _hScrollBar->setSliderPosition (cw);
122163 _hScrollBar->setRange (0 , cw);
123164 _hScrollBar->setSingleStep ((w >> 4 ) + 1 );
124165 _hScrollBar->setPageStep (w);
125166
126- int ch = (xh > h ? xh - h + sbw : 0 );
167+ int ch = (xh > h ? xh - h : 0 );
127168 if (_vScrollBar->sliderPosition () > ch)
128169 _vScrollBar->setSliderPosition (ch);
129170 _vScrollBar->setRange (0 , ch);
130171 _vScrollBar->setSingleStep ((h >> 4 ) + 1 );
131172 _vScrollBar->setPageStep (h);
173+
174+ surface ()->setMinimumWidth (w < xw? w: xw);
175+ surface ()->setMinimumHeight (h < xh? h: xh);
176+
177+ // we may need a relayout if the surface width is changed
178+ updateGeometry ();
132179}
133180
134181/* ! Scroll area updater */
@@ -138,13 +185,87 @@ QTMScrollView::scrollContentsBy ( int dx, int dy ) {
138185 if (dy) p_origin.setY (p_origin.y () - dy);
139186}
140187
188+ bool
189+ QTMScrollView::viewportEvent (QEvent *e)
190+ {
191+ switch (e->type ()) {
192+ case QEvent::Resize:
193+ case QEvent::Paint:
194+ case QEvent::MouseButtonPress:
195+ case QEvent::MouseButtonRelease:
196+ case QEvent::MouseButtonDblClick:
197+ #if QT_VERSION >= 0x040600
198+ case QEvent::TouchBegin:
199+ case QEvent::TouchUpdate:
200+ case QEvent::TouchEnd:
201+ #endif
202+ case QEvent::MouseMove:
203+ case QEvent::ContextMenu:
204+ case QEvent::Wheel:
205+ case QEvent::Drop:
206+ case QEvent::DragEnter:
207+ case QEvent::DragMove:
208+ case QEvent::DragLeave:
209+ // return QFrame::event(e);
210+ return false ; // let the viewport widget handle the event
211+ case QEvent::LayoutRequest:
212+ #if QT_VERSION >= 0x040600
213+ #ifndef QT_NO_GESTURES
214+ case QEvent::Gesture:
215+ case QEvent::GestureOverride:
216+ return event (e);
217+ #endif
218+ #endif
219+ default :
220+ break ;
221+ }
222+ return false ; // let the viewport widget handle the event
223+ }
224+
225+ bool
226+ QTMScrollView::surfaceEvent (QEvent *e)
227+ {
228+ switch (e->type ()) {
229+ case QEvent::Resize:
230+ case QEvent::Paint:
231+ case QEvent::MouseButtonPress:
232+ case QEvent::MouseButtonRelease:
233+ case QEvent::MouseButtonDblClick:
234+ #if QT_VERSION >= 0x040600
235+ case QEvent::TouchBegin:
236+ case QEvent::TouchUpdate:
237+ case QEvent::TouchEnd:
238+ #endif
239+ case QEvent::MouseMove:
240+ case QEvent::ContextMenu:
241+ case QEvent::Wheel:
242+ case QEvent::Drop:
243+ case QEvent::DragEnter:
244+ case QEvent::DragMove:
245+ case QEvent::DragLeave:
246+ return QFrame::event (e);
247+ case QEvent::LayoutRequest:
248+ #if QT_VERSION >= 0x040600
249+ #ifndef QT_NO_GESTURES
250+ case QEvent::Gesture:
251+ case QEvent::GestureOverride:
252+ return event (e);
253+ #endif
254+ #endif
255+ default :
256+ break ;
257+ }
258+ return false ; // let the surface widget handle the event
259+ }
260+
141261bool
142262QTMScrollView::event (QEvent *event) {
143263 switch (event->type ()) {
144264 case QEvent::Resize:
145265 {
146266 bool res = QAbstractScrollArea::event (event);
147267 QResizeEvent *re = static_cast <QResizeEvent*> (event);
268+ updateScrollBars ();
148269 resizeEventBis (re);
149270 return res;
150271 }
@@ -154,9 +275,19 @@ QTMScrollView::event (QEvent *event) {
154275 return QAbstractScrollArea::event (event);
155276}
156277
157-
158278void
159279QTMScrollView::resizeEventBis (QResizeEvent *event) {
160280 (void ) event;
161281}
162-
282+
283+ /*
284+ // this code is wrong
285+ void
286+ QTMScrollView::wheelEvent ( QWheelEvent *wheelEvent ) {
287+ if (wheelEvent->modifiers()
288+ & (Qt::ShiftModifier | Qt::ControlModifier)) {
289+ setOrigin(QPoint(p_origin.x() + wheelEvent->delta(), p_origin.y()));
290+ }
291+ else QAbstractScrollArea::wheelEvent(wheelEvent);
292+ }
293+ */
0 commit comments