tests/manual/gestures/scrollarea/main.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    48     Q_OBJECT
    48     Q_OBJECT
    49 public:
    49 public:
    50     ScrollArea(QWidget *parent = 0)
    50     ScrollArea(QWidget *parent = 0)
    51         : QScrollArea(parent), outside(false)
    51         : QScrollArea(parent), outside(false)
    52     {
    52     {
    53         viewport()->grabGesture(Qt::PanGesture);
    53         viewport()->grabGesture(Qt::PanGesture, Qt::ReceivePartialGestures);
    54     }
    54     }
    55 
    55 
    56 protected:
    56 protected:
    57     bool viewportEvent(QEvent *event)
    57     bool viewportEvent(QEvent *event)
    58     {
    58     {
    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)) {
   100             if ((hbar->value() == hbar->minimum() && totalOffset.x() > 10) ||
   100             if ((hbar->value() == hbar->minimum() && totalOffset.x() > 10) ||
   101                 (hbar->value() == hbar->maximum() && totalOffset.x() < -10)) {
   101                 (hbar->value() == hbar->maximum() && totalOffset.x() < -10)) {
   102                 outside = true;
   102                 outside = true;
   103                 return;
   103                 return;
   104             }
   104             }
   105             vbar->setValue(vbar->value() - offset.y());
   105             vbar->setValue(vbar->value() - delta.y());
   106             hbar->setValue(hbar->value() - offset.x());
   106             hbar->setValue(hbar->value() - delta.x());
   107             event->accept(pan);
   107             event->accept(pan);
   108         }
   108         }
   109     }
   109     }
   110 
   110 
   111 private:
   111 private:
   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) {
   166                     (value() == minimum() && totalOffset.y() > 10)) {
   166                     (value() == minimum() && totalOffset.y() > 10)) {
   167                     outside = true;
   167                     outside = true;
   168                     return;
   168                     return;
   169                 }
   169                 }
   170                 if (totalOffset.x() < 40 && totalOffset.x() > -40) {
   170                 if (totalOffset.x() < 40 && totalOffset.x() > -40) {
   171                     setValue(value() - offset.y());
   171                     setValue(value() - delta.y());
   172                     event->accept(pan);
   172                     event->accept(pan);
   173                 } else {
   173                 } else {
   174                     outside = true;
   174                     outside = true;
   175                 }
   175                 }
   176             }
   176             }
   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