ginebra2/WebTouchNavigation.cpp
author hgs
Wed, 01 Sep 2010 13:56:21 -0400
changeset 11 786160610b4d
parent 3 0954f5dd2cd0
child 16 3c88a81ff781
permissions -rw-r--r--
201035

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not,
* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
*
* Description:
*
*/

#include <QTimer>
#include <QGraphicsWebView>
#include <QWebPage>
#include <QWebFrame>
#include <QGraphicsScene>
#include <QGraphicsView>

#include "WebTouchNavigation.h"
#include "KineticHelper.h"

#define SCROLL_TIMEOUT   40

namespace GVA {
using namespace qstmGesture;




DecelEdit::DecelEdit(WebTouchNavigation* nav) : QLineEdit(), m_nav(nav)
{
    setMaxLength(6);
    connect(this, SIGNAL(editingFinished()), this, SLOT(setDecel()));
//    connect(this, SIGNAL(returnPressed ()), this, SLOT(setDecel()));
}

void DecelEdit::setDecel()
{
    QString txt = text();
    bool ok = false;
    int decel = txt.toInt(&ok);
    m_nav->m_kinetic->setDeceleration((qreal)decel);
    hide();
}


WebTouchNavigation::WebTouchNavigation(QGraphicsWebView* view) :
         m_view(view),
         m_scrollTimer(0)

{
    m_webPage = m_view->page();
    m_kinetic = new KineticHelper(this);
    m_decelEdit = new DecelEdit(this);
}

WebTouchNavigation::~WebTouchNavigation()
{
    disconnect(m_scrollTimer, SIGNAL(timeout()),this,SLOT(pan()));
    delete m_scrollTimer;

    delete m_kinetic;
}


void WebTouchNavigation::handleQStmGesture(QStm_Gesture* gesture)
{
    QStm_GestureType type = gesture->getGestureStmType();

    switch (type) {
        case QStmTapGestureType:
        {
            doTap(gesture);
            break;
        }
        case QStmPanGestureType:
        {
            doPan(gesture);
            break;
        }
        case QStmFlickGestureType:
        {
            doFlick(gesture);
            break;
        }
        case QStmDoubleTapGestureType:
        {
            m_decelEdit->show();
            break;
        }
        case QStmTouchGestureType:
        {
            doTouch(gesture);
            break;
        }
    }
}

void WebTouchNavigation::doTouch(QStm_Gesture* gesture)
{
    stopScrolling();
    if (m_kinetic->isScrolling()) {
        m_kinetic->stopScrolling();
    }
}

void WebTouchNavigation::stopScrolling()
{
    if (m_scrollTimer && m_scrollTimer->isActive()) {
        m_scrollTimer->stop();
        m_scrollDelta = QPoint(0,0);
    }
}


void WebTouchNavigation::doFlick(QStm_Gesture* gesture)
{

    QPointF pos = mapFromGlobal(gesture->position());
    m_kineticSpeed = gesture->getSpeedVec();
    QStm_GestureDirection direction = static_cast<QStm_GestureDirection>(gesture->getDirection());

    if (direction == ENorth || direction == ESouth) {
        m_kineticSpeed.setY(0.0);
    }
    else if (direction == EEast || direction == EWest) {
        m_kineticSpeed.setX(0.0);
    }

    m_kineticSpeed *= -1.0;
    m_frame = m_webPage->frameAt(pos.toPoint());
    m_kinetic->startScrolling();
}

void WebTouchNavigation::doPan(QStm_Gesture* gesture)
{
    if (gesture->gestureState() == Qt::GestureFinished) {
        stopScrolling();
    }
    else {
      m_scrollDelta += gesture->getLengthAndDirection();
      Q_ASSERT(m_scrollDelta.x() != 0 || m_scrollDelta.y() != 0);
      QPointF pos = mapFromGlobal(gesture->position());
      m_frame = m_webPage->frameAt(pos.toPoint());
      if (!m_scrollTimer) {
          m_scrollTimer = new QTimer(this);
          m_scrollTimer->setSingleShot(false);
          QObject::connect(m_scrollTimer, SIGNAL(timeout()), this, SLOT(pan()));
      }

      if (!m_scrollTimer->isActive()) {
          m_scrollTimer->stop();
          m_scrollTimer->start(SCROLL_TIMEOUT);
      }
    }
}

void WebTouchNavigation::pan()
{
    if (m_scrollDelta.x() != 0 || m_scrollDelta.y() != 0) {
        m_frame->scroll(-m_scrollDelta.x(), m_scrollDelta.y());
        m_scrollDelta = QPoint(0,0);
    }
}

void WebTouchNavigation::doTap(QStm_Gesture* gesture)
{
    QPoint gpos = gesture->position();
    QPoint pos = mapFromGlobal(gpos).toPoint();
    Qt::MouseButtons buttons = Qt::LeftButton;
    buttons &= ~Qt::RightButton;
    buttons &= ~Qt::MidButton;
    buttons &= Qt::MouseButtonMask;

    QMouseEvent mdown (QEvent::MouseButtonPress, pos, gpos, Qt::LeftButton, buttons, Qt::NoModifier);
    QMouseEvent mup (QEvent::MouseButtonRelease, pos, gpos, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);

    m_webPage->event(&mdown);
    m_webPage->event(&mup);
}




QPointF WebTouchNavigation::mapFromGlobal(const QPointF& gpos)
{
    QGraphicsScene* scene = m_view->scene();
    QList<QGraphicsView*> gvList = scene->views();
    QList<QGraphicsView*>::iterator it;

    for (it = gvList.begin(); it != gvList.end(); it++) {
        if (static_cast<QGraphicsView*>(*it)->hasFocus()) {
            QWidget* viewport = static_cast<QGraphicsView*>(*it)->viewport();
            return m_view->mapFromScene(viewport->mapFromGlobal(gpos.toPoint()));
        }
    }

    return QPointF(0.0, 0.0);
}


void WebTouchNavigation::scrollTo(QPoint& pos)
{
    m_frame->setScrollPosition(pos);
}


QPoint WebTouchNavigation::getScrollPosition()
{
    return m_frame->scrollPosition();
}

QPoint WebTouchNavigation::getInitialPosition()
{
    return m_frame->scrollPosition();
}

QPointF WebTouchNavigation::getInitialSpeed()
{
    return m_kineticSpeed;
}



}