71 void gestureEvent(QGestureEvent *event) |
71 void gestureEvent(QGestureEvent *event) |
72 { |
72 { |
73 QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); |
73 QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); |
74 if (pan) { |
74 if (pan) { |
75 switch(pan->state()) { |
75 switch(pan->state()) { |
76 case Qt::GestureStarted: qDebug("area: Pan: started"); break; |
76 case Qt::GestureStarted: qDebug() << this << "Pan: started"; break; |
77 case Qt::GestureFinished: qDebug("area: Pan: finished"); break; |
77 case Qt::GestureFinished: qDebug() << this << "Pan: finished"; break; |
78 case Qt::GestureCanceled: qDebug("area: Pan: canceled"); break; |
78 case Qt::GestureCanceled: qDebug() << this << "Pan: canceled"; break; |
79 case Qt::GestureUpdated: break; |
79 case Qt::GestureUpdated: break; |
80 default: qDebug("area: Pan: <unknown state>"); break; |
80 default: qDebug() << this << "Pan: <unknown state>"; break; |
81 } |
81 } |
82 |
82 |
83 if (pan->state() == Qt::GestureStarted) |
83 if (pan->state() == Qt::GestureStarted) |
84 outside = false; |
84 outside = false; |
85 event->ignore(); |
85 event->ignore(); |
86 event->ignore(pan); |
86 event->ignore(pan); |
87 if (outside) |
87 if (outside) |
88 return; |
88 return; |
89 |
89 |
90 const QPointF offset = pan->offset(); |
90 const QPointF delta = pan->delta(); |
91 const QPointF totalOffset = pan->totalOffset(); |
91 const QPointF totalOffset = pan->offset(); |
92 QScrollBar *vbar = verticalScrollBar(); |
92 QScrollBar *vbar = verticalScrollBar(); |
93 QScrollBar *hbar = horizontalScrollBar(); |
93 QScrollBar *hbar = horizontalScrollBar(); |
94 |
94 |
95 if ((vbar->value() == vbar->minimum() && totalOffset.y() > 10) || |
95 if ((vbar->value() == vbar->minimum() && totalOffset.y() > 10) || |
96 (vbar->value() == vbar->maximum() && totalOffset.y() < -10)) { |
96 (vbar->value() == vbar->maximum() && totalOffset.y() < -10)) { |
132 void gestureEvent(QGestureEvent *event) |
132 void gestureEvent(QGestureEvent *event) |
133 { |
133 { |
134 QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); |
134 QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); |
135 if (pan) { |
135 if (pan) { |
136 switch (pan->state()) { |
136 switch (pan->state()) { |
137 case Qt::GestureStarted: qDebug("slider: Pan: started"); break; |
137 case Qt::GestureStarted: qDebug() << this << "Pan: started"; break; |
138 case Qt::GestureFinished: qDebug("slider: Pan: finished"); break; |
138 case Qt::GestureFinished: qDebug() << this << "Pan: finished"; break; |
139 case Qt::GestureCanceled: qDebug("slider: Pan: canceled"); break; |
139 case Qt::GestureCanceled: qDebug() << this << "Pan: canceled"; break; |
140 case Qt::GestureUpdated: break; |
140 case Qt::GestureUpdated: break; |
141 default: qDebug("slider: Pan: <unknown state>"); break; |
141 default: qDebug() << this << "Pan: <unknown state>"; break; |
142 } |
142 } |
143 |
143 |
144 if (pan->state() == Qt::GestureStarted) |
144 if (pan->state() == Qt::GestureStarted) |
145 outside = false; |
145 outside = false; |
146 event->ignore(); |
146 event->ignore(); |
147 event->ignore(pan); |
147 event->ignore(pan); |
148 if (outside) |
148 if (outside) |
149 return; |
149 return; |
150 const QPointF offset = pan->offset(); |
150 const QPointF delta = pan->delta(); |
151 const QPointF totalOffset = pan->totalOffset(); |
151 const QPointF totalOffset = pan->offset(); |
152 if (orientation() == Qt::Horizontal) { |
152 if (orientation() == Qt::Horizontal) { |
153 if ((value() == minimum() && totalOffset.x() < -10) || |
153 if ((value() == minimum() && totalOffset.x() < -10) || |
154 (value() == maximum() && totalOffset.x() > 10)) { |
154 (value() == maximum() && totalOffset.x() > 10)) { |
155 outside = true; |
155 outside = true; |
156 return; |
156 return; |
157 } |
157 } |
158 if (totalOffset.y() < 40 && totalOffset.y() > -40) { |
158 if (totalOffset.y() < 40 && totalOffset.y() > -40) { |
159 setValue(value() + offset.x()); |
159 setValue(value() + delta.x()); |
160 event->accept(pan); |
160 event->accept(pan); |
161 } else { |
161 } else { |
162 outside = true; |
162 outside = true; |
163 } |
163 } |
164 } else if (orientation() == Qt::Vertical) { |
164 } else if (orientation() == Qt::Vertical) { |
184 { |
184 { |
185 public: |
185 public: |
186 MainWindow() |
186 MainWindow() |
187 { |
187 { |
188 rootScrollArea = new ScrollArea; |
188 rootScrollArea = new ScrollArea; |
|
189 rootScrollArea->setObjectName(QLatin1String("rootScrollArea")); |
189 setCentralWidget(rootScrollArea); |
190 setCentralWidget(rootScrollArea); |
190 |
191 |
191 QWidget *root = new QWidget; |
192 QWidget *root = new QWidget; |
192 root->setFixedSize(3000, 3000); |
193 root->setFixedSize(3000, 3000); |
193 rootScrollArea->setWidget(root); |
194 rootScrollArea->setWidget(root); |
194 |
195 |
195 Slider *verticalSlider = new Slider(Qt::Vertical, root); |
196 Slider *verticalSlider = new Slider(Qt::Vertical, root); |
|
197 verticalSlider->setObjectName(QLatin1String("verticalSlider")); |
196 verticalSlider ->move(650, 1100); |
198 verticalSlider ->move(650, 1100); |
197 Slider *horizontalSlider = new Slider(Qt::Horizontal, root); |
199 Slider *horizontalSlider = new Slider(Qt::Horizontal, root); |
|
200 horizontalSlider->setObjectName(QLatin1String("horizontalSlider")); |
198 horizontalSlider ->move(600, 1000); |
201 horizontalSlider ->move(600, 1000); |
199 |
202 |
200 childScrollArea = new ScrollArea(root); |
203 childScrollArea = new ScrollArea(root); |
|
204 childScrollArea->setObjectName(QLatin1String("childScrollArea")); |
201 childScrollArea->move(500, 500); |
205 childScrollArea->move(500, 500); |
202 QWidget *w = new QWidget; |
206 QWidget *w = new QWidget; |
203 w->setMinimumWidth(400); |
207 w->setMinimumWidth(700); |
204 QVBoxLayout *l = new QVBoxLayout(w); |
208 QVBoxLayout *l = new QVBoxLayout(w); |
205 l->setMargin(20); |
209 l->setMargin(20); |
206 for (int i = 0; i < 100; ++i) { |
210 for (int i = 0; i < 100; ++i) { |
207 QWidget *w = new QWidget; |
211 QWidget *w = new QWidget; |
208 QHBoxLayout *ll = new QHBoxLayout(w); |
212 QHBoxLayout *ll = new QHBoxLayout(w); |
209 ll->addWidget(new QLabel(QString("Label %1").arg(i))); |
213 ll->addWidget(new QLabel(QString("Label %1").arg(i))); |
210 ll->addWidget(new QPushButton(QString("Button %1").arg(i))); |
214 ll->addWidget(new QPushButton(QString("Button %1").arg(i))); |
211 l->addWidget(w); |
215 l->addWidget(w); |
212 } |
216 } |
213 childScrollArea->setWidget(w); |
217 childScrollArea->setWidget(w); |
|
218 #if defined(Q_OS_WIN) |
|
219 // Windows can force Qt to create a native window handle for an |
|
220 // intermediate widget and that will block gesture to get touch events. |
|
221 // So this hack to make sure gestures get all touch events they need. |
|
222 foreach (QObject *w, children()) |
|
223 if (w->isWidgetType()) |
|
224 static_cast<QWidget *>(w)->setAttribute(Qt::WA_AcceptTouchEvents); |
|
225 #endif |
214 } |
226 } |
215 private: |
227 private: |
216 ScrollArea *rootScrollArea; |
228 ScrollArea *rootScrollArea; |
217 ScrollArea *childScrollArea; |
229 ScrollArea *childScrollArea; |
218 }; |
230 }; |
219 |
231 |
220 int main(int argc, char **argv) |
232 int main(int argc, char **argv) |
221 { |
233 { |
222 QApplication app(argc, argv); |
234 QApplication app(argc, argv); |
223 app.registerGestureRecognizer(new MousePanGestureRecognizer); |
235 QGestureRecognizer::registerRecognizer(new MousePanGestureRecognizer); |
224 MainWindow w; |
236 MainWindow w; |
225 w.show(); |
237 w.show(); |
226 return app.exec(); |
238 return app.exec(); |
227 } |
239 } |
228 |
240 |