tests/benchmarks/uimodels/GraphicsViewBenchmark/widgets/webview.cpp
changeset 3 41300fa6a67c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
       
     1 #include "webview.h"
       
     2 #include "webview_p.h"
       
     3 #include <QtGui>
       
     4 
       
     5 static const int MotionEndWaitTime = 2000;
       
     6 static const int TileSideLength = 128;
       
     7 
       
     8 WebViewPrivate::WebViewPrivate(WebView *w) 
       
     9     : q(w)
       
    10     , cache(0)
       
    11 {
       
    12     web = new QGraphicsWebView;
       
    13 
       
    14     web->setParentItem(q->viewport());
       
    15 
       
    16     web->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
       
    17     web->page()->mainFrame()->setScrollBarPolicy(
       
    18         Qt::Horizontal, Qt::ScrollBarAlwaysOff); 	
       
    19     web->page()->mainFrame()->setScrollBarPolicy(
       
    20         Qt::Vertical, Qt::ScrollBarAlwaysOff);
       
    21     web->setZValue(3);
       
    22 
       
    23 //    cache = new WebViewCache(web);
       
    24 //    web->setGraphicsEffect(cache);
       
    25  
       
    26     adjustSize();
       
    27 }
       
    28 
       
    29 void WebViewPrivate::adjustSize()
       
    30 {
       
    31     QSizeF contentSize = web->page()->mainFrame()->contentsSize();
       
    32     QPointF pos = web->pos();
       
    33 
       
    34     qreal w = qMax(contentSize.width(), q->viewport()->boundingRect().width());
       
    35     qreal h = qMax(contentSize.height(), q->viewport()->boundingRect().height());
       
    36 
       
    37     if (web->boundingRect().size() != QSizeF(w, h)) {
       
    38         //qDebug() << "WebView: adjustSize:" << QSizeF(w, h);
       
    39 
       
    40         web->resize(w, h);
       
    41         web->setPos(pos);
       
    42 
       
    43         if (w > q->viewport()->boundingRect().width())
       
    44             q->horizontalScrollBar()->setSliderSize(w);
       
    45         else
       
    46             q->horizontalScrollBar()->setSliderSize(0.0);
       
    47         
       
    48 
       
    49         if (h > q->viewport()->boundingRect().height()) 
       
    50             q->verticalScrollBar()->setSliderSize(h);
       
    51         else
       
    52             q->verticalScrollBar()->setSliderSize(0.0);
       
    53     }
       
    54 }
       
    55 
       
    56 void WebViewPrivate::_q_loadStarted()
       
    57 {
       
    58     qDebug() << "WebView: load started";
       
    59     adjustSize();
       
    60 }
       
    61 
       
    62 void WebViewPrivate::_q_loadProgress(int progress)
       
    63 {
       
    64     Q_UNUSED(progress)
       
    65 //    qDebug() << "WebView: load progress" << progress;
       
    66     adjustSize();
       
    67 }
       
    68 
       
    69 void WebViewPrivate::_q_loadFinished(bool ok)
       
    70 {
       
    71     qDebug() << "WebView: load finished" << (ok ? "ok" : "not ok");
       
    72     adjustSize();
       
    73 }
       
    74 
       
    75 void WebViewPrivate::_q_viewportChanged(QGraphicsWidget* viewport)
       
    76 {
       
    77     web->setParentItem(viewport);
       
    78     viewport->setFlag(QGraphicsItem::ItemClipsChildrenToShape, 
       
    79                       true);
       
    80     adjustSize();
       
    81 }
       
    82 
       
    83 void WebViewPrivate::_q_motionEnded()
       
    84 {
       
    85     motionTimer.stop();
       
    86     qDebug() << "Motion ended";
       
    87     q->prepareGeometryChange();
       
    88 }
       
    89 
       
    90 WebViewCache::WebViewCache(QGraphicsWebView *webView)
       
    91     : m_webView(webView)
       
    92 {
       
    93    
       
    94 }
       
    95 
       
    96 WebViewCache::~WebViewCache()
       
    97 {
       
    98 }
       
    99 
       
   100 void WebViewCache::draw(QPainter * painter, QGraphicsEffectSource * source)
       
   101 {
       
   102     const QGraphicsItem *item = source->graphicsItem();
       
   103 
       
   104     QSizeF itemSize = item->boundingRect().size();
       
   105 
       
   106     if (!qFuzzyCompare(itemSize.width(), m_itemSize.width()) ||
       
   107             !qFuzzyCompare(itemSize.height(), m_itemSize.height())) {
       
   108         qDebug() << "Refresh tile cache, for new size" << itemSize;
       
   109 
       
   110         for (int i = 0; i < m_tilePixmaps.size(); i++) {
       
   111             QPixmapCache::remove(m_tilePixmaps[i]);
       
   112         }
       
   113 
       
   114         m_tilePixmaps.clear();
       
   115         m_tileRects.clear();
       
   116 
       
   117         int itemWidth = itemSize.width() + 0.5;
       
   118         int itemHeight = itemSize.height() + 0.5;
       
   119 
       
   120         int tilesX = itemWidth / TileSideLength;
       
   121         int tilesY = itemHeight / TileSideLength;
       
   122 
       
   123         if ((itemWidth % TileSideLength) != 0) {
       
   124             ++tilesX;
       
   125         }
       
   126 
       
   127         if ((itemHeight % TileSideLength) != 0) {
       
   128             ++tilesY;
       
   129         }
       
   130 
       
   131         int tilesCount = tilesX * tilesY;
       
   132 
       
   133         m_tilePixmaps.resize(tilesCount);
       
   134         m_tileRects.resize(tilesCount);
       
   135 
       
   136         for (int i = 0; i < tilesX; i++) {
       
   137             for (int j = 0; j < tilesY; j++) {
       
   138                 int x = i * TileSideLength;
       
   139                 int y = j * TileSideLength;
       
   140                 
       
   141                 m_tileRects[i + j * tilesX] 
       
   142                     = QRectF(x, y, TileSideLength, TileSideLength);
       
   143             }
       
   144         }
       
   145 
       
   146         m_itemSize = itemSize;
       
   147     }
       
   148 
       
   149     const QGraphicsItem *parentItem = item->parentItem();
       
   150     QPointF itemPos = item->pos();
       
   151     QRectF parentRect = parentItem->boundingRect();
       
   152 
       
   153     for (int i = 0; i < m_tileRects.size(); i++) {
       
   154         QRectF tileRect = m_tileRects[i].translated(itemPos);
       
   155 
       
   156         if (!tileRect.intersects(parentRect) && !tileRect.contains(parentRect)) {
       
   157             continue;
       
   158         }
       
   159 
       
   160         QPixmap tilePixmap;
       
   161 
       
   162         if (!QPixmapCache::find(m_tilePixmaps[i], &tilePixmap)) {
       
   163             tilePixmap = QPixmap(TileSideLength, TileSideLength);
       
   164 
       
   165             QWebFrame *webFrame = m_webView->page()->mainFrame();
       
   166 
       
   167             QPainter tilePainter(&tilePixmap); 
       
   168             tilePainter.translate(-m_tileRects[i].left(), -m_tileRects[i].top());
       
   169             webFrame->render(&tilePainter, m_tileRects[i].toRect());
       
   170             tilePainter.end();
       
   171 
       
   172             m_tilePixmaps[i] = QPixmapCache::insert(tilePixmap);
       
   173         } 
       
   174 
       
   175         tileRect = tileRect.translated(-itemPos);
       
   176 
       
   177         painter->drawPixmap(tileRect.topLeft(), tilePixmap);
       
   178     }
       
   179 }
       
   180 
       
   181 WebView::WebView(QGraphicsWidget *parent)
       
   182     : AbstractScrollArea(parent)
       
   183     , d(new WebViewPrivate(this))
       
   184 {
       
   185     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
       
   186     setContentsMargins(0, 0, 0, 0);
       
   187     connect(d->web->page(), SIGNAL(loadStarted()),
       
   188             this, SLOT(_q_loadStarted()));
       
   189     connect(d->web->page(), SIGNAL(loadProgress(int)),
       
   190             this, SLOT(_q_loadProgress(int)));
       
   191     connect(d->web->page(), SIGNAL(loadFinished(bool)),
       
   192             this, SLOT(_q_loadFinished(bool)));
       
   193     connect(this, SIGNAL(viewportChanged(QGraphicsWidget*)),
       
   194             this, SLOT(_q_viewportChanged(QGraphicsWidget*)));
       
   195     connect(&d->motionTimer, SIGNAL(timeout()), 
       
   196             this, SLOT(_q_motionEnded()));
       
   197 }
       
   198 
       
   199 WebView::~WebView()
       
   200 {
       
   201     d->web->setGraphicsEffect(0);
       
   202     delete d->cache;
       
   203 }
       
   204 
       
   205 void WebView::setUrl(const QUrl& url)
       
   206 {
       
   207     d->adjustSize();
       
   208     d->web->setUrl(url);
       
   209 }
       
   210 
       
   211 void WebView::scrollContentsBy(qreal dx, qreal dy)
       
   212 {
       
   213     if (qFuzzyCompare((float)dy, 0.0f) && qFuzzyCompare((float)dx, 0.0f))
       
   214         return;
       
   215 
       
   216     if (!d->motionTimer.isActive()) {
       
   217         d->motionTimer.start(MotionEndWaitTime);
       
   218     }
       
   219 
       
   220     QSizeF contentSize = d->web->page()->mainFrame()->contentsSize();
       
   221     QRectF viewportRect = viewport()->boundingRect();
       
   222     QPointF pos = d->web->pos();
       
   223 
       
   224     qreal w = qMax(contentSize.width(), viewportRect.width());
       
   225     qreal h = qMax(contentSize.height(), viewportRect.height());
       
   226 
       
   227     qreal minx = qMin(0.0f, (float) -(w - viewportRect.width()));
       
   228     qreal miny = qMin(0.0f, (float) -(h - viewportRect.height()));
       
   229 
       
   230     qreal x = d->web->pos().x() - dx;
       
   231 
       
   232     if (x < minx)
       
   233         x = minx;
       
   234     else if (x > 0) 
       
   235         x = 0.0;
       
   236 
       
   237    qreal y = d->web->pos().y() - dy;
       
   238 
       
   239     if (y < miny)
       
   240         y = miny;
       
   241     else if (y > 0) 
       
   242         y = 0.0;
       
   243 
       
   244     d->web->setPos(x, y);
       
   245 }
       
   246 
       
   247 QSizeF WebView::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
       
   248 { 
       
   249     if (which == Qt::PreferredSize) {
       
   250         QSizeF contentSize = d->web->page()->mainFrame()->contentsSize();
       
   251         return contentSize;
       
   252     }
       
   253 
       
   254     return AbstractScrollArea::sizeHint(which, constraint);
       
   255 }
       
   256 
       
   257 void WebView::resizeEvent(QGraphicsSceneResizeEvent *event)
       
   258 {
       
   259     AbstractScrollArea::resizeEvent(event);
       
   260     d->adjustSize();
       
   261 }
       
   262 
       
   263 #include "moc_webview.cpp"