diff -r 0f2326c2a325 -r 1c3b8676e58c ginebra2/ContentViews/WebContentAnimationItem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ginebra2/ContentViews/WebContentAnimationItem.cpp Tue Jul 06 14:03:49 2010 +0300 @@ -0,0 +1,177 @@ +/* +* 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 "WebContentAnimationItem.h" + +#include +#include +#include +#include + +static const int MinDoubleClickZoomTargetWidth = 100; //Target block width for applying double tap zoom +static const int ZoomCommitDuration = 50; //Timeout before commiting zoom +static const qreal ZoomableContentMinWidth = 300.; + +namespace GVA { + +WebContentAnimationItem::WebContentAnimationItem(QGraphicsWidget* parent, Qt::WindowFlags wFlags) + : QGraphicsWidget(parent, wFlags) + , m_zoomCommitTimer(this) + , m_viewportMetaData(0) +{ + setFlag(QGraphicsItem::ItemHasNoContents, true); + setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); + setFlag(QGraphicsItem::ItemClipsToShape, true); + + setFiltersChildEvents(true); + + connect(&m_zoomCommitTimer, SIGNAL(timeout()), this, SLOT(commitZoom())); + m_zoomCommitTimer.setSingleShot(true); +} + +WebContentAnimationItem::~WebContentAnimationItem() +{} + +void WebContentAnimationItem::setWebView(QGraphicsWebView* webView) +{ + Q_ASSERT(m_webView); + m_webView = webView; + + //Enabling resize to contents avoids scrollbars in mainframe + m_webView->setResizesToContents(true); + m_webView->setParentItem(this); + m_webView->setAttribute(Qt::WA_OpaquePaintEvent, true); +} + +void WebContentAnimationItem::updatePreferredContentSize(const QSize& size) +{ + // FIXME: we have bug in QtWebKit API when tileCacheEnabled is true. + // this causes viewport not to reset between the page loads. + // Thus, we need to update viewport manually until we have fix for this. + + m_webView->page()->setPreferredContentsSize(size); + resize(contentsSize()); +} + +QSize WebContentAnimationItem::contentsSize() const +{ + return m_webView->page()->mainFrame()->contentsSize(); +} + +void WebContentAnimationItem::setZoomScale(qreal value, bool immediateCommit) +{ + value = qBound(m_viewportMetaData->m_minimumScale, value, m_viewportMetaData->m_maximumScale); + qreal curZoomScale = zoomScale(); + + if (qFuzzyCompare(value, curZoomScale)) { + notifyZoomActions(curZoomScale); + return; + } + + if (!immediateCommit) + disableContentUpdates(); + + m_webView->setScale(value); + + if (immediateCommit) + commitZoom(); + else + m_zoomCommitTimer.start(ZoomCommitDuration); +} + +qreal WebContentAnimationItem::zoomScale() const +{ + if (!m_webView) + return 1.; + + return m_webView->scale(); +} + +QRectF WebContentAnimationItem::findZoomableRectForPoint(const QPointF& point) +{ + QPointF zoomPoint = m_webView->mapFromParent(point); + + QWebHitTestResult hitResult = m_webView->page()->mainFrame()->hitTestContent(zoomPoint.toPoint()); + QWebElement targetElement = hitResult.enclosingBlockElement(); + + while (!targetElement.isNull() && targetElement.geometry().width() < MinDoubleClickZoomTargetWidth) + targetElement = targetElement.parent(); + + if (!targetElement.isNull()) { + QRectF elementRect = targetElement.geometry(); + qreal overMinWidth = elementRect.width() - ZoomableContentMinWidth; + if (overMinWidth < 0) + elementRect.adjust(overMinWidth / 2, 0, -overMinWidth / 2, 0); + zoomPoint.setX(elementRect.x()); + QRectF resultRect(zoomPoint, elementRect.size()); + return QRectF(m_webView->mapToParent(resultRect.topLeft()), + m_webView->mapToParent(resultRect.bottomRight())); + } + return QRectF(); +} + +void WebContentAnimationItem::disableContentUpdates() +{ + //Disable tiling updates + m_webView->setTiledBackingStoreFrozen(true); +} + +void WebContentAnimationItem::enableContentUpdates() +{ + //Enable tiling updates + m_webView->setTiledBackingStoreFrozen(false); +} + +void WebContentAnimationItem::commitZoom() +{ + m_zoomCommitTimer.stop(); + notifyZoomActions(zoomScale()); + enableContentUpdates(); +} + +void WebContentAnimationItem::resizeEvent(QGraphicsSceneResizeEvent* event) +{ + QGraphicsWidget::resizeEvent(event); + setZoomScale(size().width() / contentsSize().width()); +} + +void WebContentAnimationItem::notifyZoomActions(qreal newScale) +{ + bool enableZoomIn = false; + bool enableZoomOut = false; + + if (m_viewportMetaData->m_userScalable) { + + if (newScale > m_viewportMetaData->m_minimumScale) + enableZoomOut = true; + else + enableZoomOut = false; + + if (newScale < m_viewportMetaData->m_maximumScale) + enableZoomIn = true; + else + enableZoomIn = false; + } + + emit updateZoomActions(enableZoomIn, enableZoomOut); +} + +} //namespace GVA