summaryrefslogtreecommitdiffstats
path: root/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets')
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp382
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h96
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp425
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h103
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp236
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h88
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp102
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h81
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp71
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h59
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp196
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h89
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp183
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h39
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp127
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h59
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp46
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h45
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp149
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h78
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp248
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h72
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri19
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp66
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h52
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp81
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h63
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp287
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h96
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp79
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h56
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp182
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h75
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp133
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h69
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp117
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h72
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp331
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h110
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp189
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h71
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp134
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h70
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h84
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp286
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h84
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp292
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h66
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h90
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp46
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h103
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp143
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h67
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp463
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h77
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp223
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h118
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp40
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h51
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp346
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h114
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp289
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h68
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h86
64 files changed, 8462 insertions, 0 deletions
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp
new file mode 100644
index 0000000000..00481a638d
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp
@@ -0,0 +1,382 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QDebug>
+#include <QGraphicsLayout>
+
+#include "abstractitemcontainer.h"
+#include "abstractitemview.h"
+#include "abstractviewitem.h"
+#include "scrollbar.h"
+
+AbstractItemContainer::AbstractItemContainer(int bufferSize, QGraphicsWidget *parent)
+ : GvbWidget(parent),
+ m_items(),
+ m_itemView(0),
+ m_prototype(0),
+ m_bufferSize(bufferSize),
+ m_twoColumns(false)
+{
+}
+
+AbstractItemContainer::~AbstractItemContainer()
+{
+ delete m_prototype;
+ m_prototype = 0;
+}
+
+AbstractViewItem *AbstractItemContainer::prototype()
+{
+ return m_prototype;
+}
+
+int AbstractItemContainer::bufferSize() const
+{
+ return m_bufferSize;
+}
+
+bool AbstractItemContainer::event(QEvent *e)
+{
+ if (e->type() == QEvent::LayoutRequest)
+ updateItemBuffer();
+
+ return QGraphicsWidget::event(e);
+}
+
+
+bool AbstractItemContainer::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type()==QEvent::GraphicsSceneResize && m_itemView) {
+ const bool caching = m_itemView->listItemCaching();
+ m_itemView->setListItemCaching(false);
+
+ QSizeF s = m_itemView->size();
+ s.setWidth(s.width()-m_itemView->verticalScrollBar()->size().width());
+ adjustVisibleContainerSize(s);
+
+ m_itemView->updateViewContent();
+ updateItemBuffer();
+
+ m_itemView->setListItemCaching(caching);
+ }
+
+ return QGraphicsWidget::eventFilter(obj, event);
+}
+
+QVariant AbstractItemContainer::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ QVariant ichange = QGraphicsWidget::itemChange(change,value);
+
+ if (change == ItemPositionChange) {
+ if (m_itemView && layout() && !layout()->isActivated())
+ m_itemView->refreshContainerGeometry();
+ }
+ return ichange;
+ }
+
+/*virtual*/
+void AbstractItemContainer::setItemView(AbstractItemView *view)
+{
+ m_itemView = view;
+
+ if (m_itemView) {
+ setParentItem(m_itemView);
+ m_itemView->installEventFilter(this);
+ }
+}
+/*virtual*/
+void AbstractItemContainer::setItemPrototype(AbstractViewItem *ptype)
+{
+ m_prototype = ptype;
+ m_prototype->setParentItem(0);
+ m_prototype->hide();
+}
+
+/*virtual*/
+void AbstractItemContainer::reset()
+{
+ qDeleteAll(m_items);
+ m_items.clear();
+ updateItemBuffer();
+}
+
+
+/*virtual*/
+void AbstractItemContainer::addItem(const QModelIndex &index)
+{
+ if (m_items.count() < maxItemCountInItemBuffer() ||
+ (m_items.count() > 0 &&
+ m_items.first()->modelIndex().row()-1 <= index.row() &&
+ m_items.last()->modelIndex().row() >= index.row())) {
+ int itemPos = 0;
+ if (m_items.count() != 0)
+ itemPos = qMax(0, index.row() - m_items.first()->modelIndex().row());
+
+ if (itemPos >= m_items.count() || m_items.at(itemPos)->modelIndex() != index) {
+ AbstractViewItem *item = 0;
+ if (m_prototype)
+ item = m_prototype->newItemInstance();
+
+ if (item) {
+ item->setModel(m_itemView->model());
+ item->setTwoColumns(m_twoColumns);
+ m_items.insert(itemPos, item);
+ addItemToVisibleLayout(itemPos, item);
+
+ if (item->modelIndex() != index) {
+ item->setModelIndex(index);
+ }
+ }
+ }
+ updateItemBuffer();
+ }
+}
+void AbstractItemContainer::removeItem(const QModelIndex &index)
+{
+ AbstractViewItem *item = findItemByIndex(index);
+
+ if (item) {
+ if (maxItemCountInItemBuffer() < m_items.count()) {
+ m_items.removeOne(item);
+ removeItemFromVisibleLayout(item);
+
+ delete item;
+ }
+ else {
+ m_items.removeOne(item);
+ removeItemFromVisibleLayout(item);
+
+ QModelIndex newIndex = m_itemView->nextIndex(m_items.last()->modelIndex());
+ if (newIndex.isValid()) {
+ // Item readded as last item in buffer.
+ m_items.append(item);
+ addItemToVisibleLayout(m_items.count() - 1, item);
+ item->setModelIndex(newIndex);
+ } else {
+ // Item readded as first item in buffer.
+ newIndex = m_itemView->previousIndex(m_items.first()->modelIndex());
+
+ m_items.prepend(item);
+ addItemToVisibleLayout(0, item);
+ item->setModelIndex(newIndex);
+ }
+ }
+ }
+}
+
+/*virtual*/
+int AbstractItemContainer::itemCount() const
+{
+ return m_items.count();
+}
+
+AbstractViewItem *AbstractItemContainer::firstItem()
+{
+ return m_items.first();
+}
+
+/*virtual*/
+AbstractViewItem* AbstractItemContainer::itemAt(const int row) const
+{
+ if (row<0 || row >= m_items.count())
+ return 0;
+ return m_items.at(row);
+}
+
+AbstractViewItem* AbstractItemContainer::findItemByIndex(const QModelIndex &index) const
+{
+ AbstractViewItem *item = 0;
+ for (int i = 0; i < m_items.count(); ++i) {
+ if (m_items.at(i)->modelIndex() == index) {
+ item = m_items.at(i);
+ break;
+ }
+ }
+ return item;
+}
+
+bool AbstractItemContainer::itemVisibleInView(AbstractViewItem* item, const QRectF &viewRect, bool fullyVisible) const
+{
+ if (!item || !m_itemView)
+ return false;
+
+ QRectF itemRectBoundingRect = item->mapToItem(m_itemView, item->boundingRect()).boundingRect();
+
+ if (fullyVisible && viewRect.contains(itemRectBoundingRect))
+ return true;
+ else if (viewRect.intersects(itemRectBoundingRect))
+ return true;
+
+ return false;
+}
+
+void AbstractItemContainer::updateItemBuffer()
+{
+ if (!m_itemView || (m_itemView && !m_itemView->boundingRect().isValid()))
+ return;
+
+ int maxCount = maxItemCountInItemBuffer();
+
+ if (m_items.count() < maxCount) {
+ // New items needs to be added.
+ QModelIndex index;
+ if (m_items.count() > 0)
+ index = m_items.last()->modelIndex();
+ while (m_items.count() < maxCount) {
+ index = m_itemView->nextIndex(index);
+
+ if (!index.isValid())
+ break;
+
+ insertItem(m_items.count(), index);
+ }
+
+ index = m_items.first()->modelIndex();
+ while (m_items.count() < maxCount) {
+ index = m_itemView->previousIndex(index);
+
+ if (!index.isValid())
+ break;
+
+ insertItem(0, index);
+ }
+ }
+
+ QRectF viewRect = boundingRect();
+
+ while (m_items.count() > maxCount) {
+ int firstVisible = 0;
+ int lastVisible = 0;
+ findFirstAndLastVisibleBufferIndex(firstVisible, lastVisible, viewRect, false);
+
+ AbstractViewItem* item = 0;
+ if (lastVisible != m_items.count() - 1) {
+ item = m_items.takeLast();
+ }
+ else if (firstVisible != 0 && m_items.first()->modelIndex().row() != firstVisible-1) {
+ item = m_items.takeFirst();
+ }
+ else {
+ // All the items are visible. Take the item at the end of the buffer.
+ item = m_items.takeLast();
+ }
+
+ m_items.removeOne(item);
+ removeItemFromVisibleLayout(item);
+ delete item;
+ }
+}
+
+void AbstractItemContainer::insertItem(int pos, const QModelIndex &index)
+{
+ AbstractViewItem *item = 0;
+ if (m_prototype)
+ item = m_prototype->newItemInstance();
+
+ if (item) {
+ item->setModel(m_itemView->model());
+ item->setModelIndex(index);
+ item->setTwoColumns(m_twoColumns);
+ m_items.insert(pos, item);
+ addItemToVisibleLayout(pos, item);
+ item->updateItemContents();
+ if (pos == 0)
+ m_itemView->scrollContentsBy(qreal(0.0),
+ item->effectiveSizeHint(Qt::PreferredSize).height());
+ }
+}
+
+void AbstractItemContainer::findFirstAndLastVisibleBufferIndex(int &firstVisibleBufferIndex,
+ int &lastVisibleBufferIndex,
+ const QRectF &viewRect,
+ bool fullyVisible) const
+{
+ if (layout() && !layout()->isActivated())
+ layout()->activate();
+
+ firstVisibleBufferIndex = -1;
+ lastVisibleBufferIndex = -1;
+
+ int count = m_items.count();
+ for (int i = 0; i < count; ++i) {
+ if (itemVisibleInView(m_items.at(i), viewRect, fullyVisible)) {
+ if (firstVisibleBufferIndex == -1)
+ firstVisibleBufferIndex = i;
+ lastVisibleBufferIndex = i;
+ }
+ else if ( lastVisibleBufferIndex != -1 )
+ break; // lastVisibleBufferIndex is already set
+ }
+}
+
+/*virtual*/
+int AbstractItemContainer::maxItemCountInItemBuffer() const
+{
+ if (m_itemView && !m_itemView->boundingRect().isEmpty())
+ {
+ return m_itemView->indexCount();
+ }
+ return 0;
+}
+
+
+void AbstractItemContainer::themeChange()
+{
+ for (int i = 0; i <m_items.count(); ++i)
+ m_items.at(i)->themeChange();
+}
+
+void AbstractItemContainer::updateContent()
+{
+ for (int i = 0; i <m_items.count(); ++i)
+ m_items.at(i)->updateItemContents();
+}
+
+void AbstractItemContainer::setSubtreeCacheEnabled(bool enabled)
+{
+ for (int i = 0; i <m_items.count(); ++i)
+ m_items.at(i)->setSubtreeCacheEnabled(enabled);
+ if (m_prototype)
+ m_prototype->setSubtreeCacheEnabled(enabled);
+}
+
+void AbstractItemContainer::setTwoColumns(const bool enabled)
+{
+ if (m_twoColumns == enabled)
+ return;
+
+ m_twoColumns = enabled;
+
+ for (int i = 0; i < m_items.count(); ++i)
+ m_items.at(i)->setTwoColumns(enabled);
+}
+
+bool AbstractItemContainer::twoColumns()
+{
+ return m_twoColumns;
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h
new file mode 100644
index 0000000000..7373f66deb
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTITEMCONTAINER_H
+#define ABSTRACTITEMCONTAINER_H
+
+#include <QModelIndex>
+
+#include "gvbwidget.h"
+
+class QGraphicsWidget;
+class AbstractItemView;
+class AbstractViewItem;
+
+class AbstractItemContainer : public GvbWidget
+{
+ Q_OBJECT
+public:
+ AbstractItemContainer(int bufferSize, QGraphicsWidget *parent=0);
+ virtual ~AbstractItemContainer();
+
+ virtual void addItem(const QModelIndex &index);
+ virtual void removeItem(const QModelIndex &index);
+
+ virtual void setItemView(AbstractItemView *view);
+ virtual void setItemPrototype(AbstractViewItem *ptype);
+ virtual void reset();
+ virtual int itemCount() const;
+ virtual AbstractViewItem* itemAt(const int row) const;
+ AbstractViewItem* findItemByIndex(const QModelIndex &index) const;
+ AbstractViewItem *prototype();
+ AbstractViewItem *firstItem();
+ void updateContent();
+ void themeChange();
+ int bufferSize() const;
+ virtual void setTwoColumns(const bool enabled);
+ bool twoColumns();
+
+ void setSubtreeCacheEnabled(const bool enabled);
+ virtual void setListItemCaching(const bool enabled, const int index) = 0;
+
+protected:
+ virtual void adjustVisibleContainerSize(const QSizeF &size) = 0;
+ virtual void addItemToVisibleLayout(int index, AbstractViewItem *item) = 0;
+ virtual void removeItemFromVisibleLayout(AbstractViewItem *item) = 0;
+
+ virtual bool event(QEvent *e);
+ virtual bool eventFilter(QObject *obj, QEvent *event);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual int maxItemCountInItemBuffer() const;
+ bool itemVisibleInView(AbstractViewItem* item, const QRectF &viewRect, bool fullyVisible = true) const;
+
+protected:
+ void updateItemBuffer();
+ void findFirstAndLastVisibleBufferIndex(int &firstVisibleBufferIndex,
+ int &lastVisibleBufferIndex,
+ const QRectF &viewRect,
+ bool fullyVisible) const;
+ QList<AbstractViewItem*> m_items;
+ AbstractItemView *m_itemView;
+ AbstractViewItem *m_prototype;
+ int m_bufferSize;
+
+private:
+ void insertItem(int pos, const QModelIndex &index);
+ bool m_twoColumns;
+
+ Q_DISABLE_COPY(AbstractItemContainer)
+};
+
+#endif // ABSTRACTITEMCONTAINER_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp
new file mode 100644
index 0000000000..961cf4e03c
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp
@@ -0,0 +1,425 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QGraphicsLayout>
+
+#include "abstractitemview.h"
+#include "abstractviewitem.h"
+#include "scrollbar.h"
+
+AbstractItemView::AbstractItemView(QGraphicsWidget *parent)
+ : AbstractScrollArea(parent),
+ m_model(0),
+ m_rootIndex(),
+ m_container(0),
+ m_selectionModel(0),
+ m_currentIndex(),
+ m_scroller()
+{
+ setRootIndex(QModelIndex());
+}
+
+/*virtual*/
+AbstractItemView::~AbstractItemView()
+{
+}
+
+/*virtual*/
+void AbstractItemView::setModel(QAbstractItemModel *model, AbstractViewItem *prototype)
+{
+ if (m_model == model || !model)
+ return;
+
+ if (m_model) {
+ disconnect(m_model, SIGNAL(destroyed()),
+ this, SLOT(_q_modelDestroyed()));
+ disconnect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(dataChanged(QModelIndex,QModelIndex)));
+ disconnect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(rowsInserted(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ this, SLOT(rowsRemoved(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
+ this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)),
+ this, SLOT(columnsInserted(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
+ this, SLOT(columnsAboutToBeInserted(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
+ this, SLOT(columnsRemoved(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ disconnect(m_model, SIGNAL(modelReset()), this, SLOT(reset()));
+ disconnect(m_model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+
+ m_model = 0;
+ }
+
+ setSelectionModel(0);
+
+ m_currentIndex = QModelIndex();
+ m_rootIndex = QModelIndex();
+
+ m_model = model;
+
+ Q_ASSERT_X(m_model->index(0,0) == m_model->index(0,0),
+ "AbstractItemView::setModel",
+ "A model should return the exact same index "
+ "(including its internal id/pointer) when asked for it twice in a row.");
+ Q_ASSERT_X(m_model->index(0,0).parent() == QModelIndex(),
+ "AbstractItemView::setModel",
+ "The parent of a top level index should be invalid");
+
+
+ connect(m_model, SIGNAL(destroyed()), this, SLOT(modelDestroyed()));
+ connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(dataChanged(QModelIndex,QModelIndex)));
+ connect(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
+ this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int)));
+ connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(rowsInserted(QModelIndex,int,int)));
+ connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ this, SLOT(rowsRemoved(QModelIndex,int,int)));
+ connect(m_model, SIGNAL(modelReset()), this, SLOT(reset()));
+ connect(m_model, SIGNAL(layoutChanged()), this, SLOT(layoutChanged()));
+
+ setSelectionModel(new QItemSelectionModel(m_model));
+
+ if (prototype && m_container) {
+ m_container->setItemPrototype(prototype);
+ m_container->reset();
+ }
+}
+
+/*virtual*/
+void AbstractItemView::setContainer(AbstractItemContainer *container)
+{
+ m_container = container;
+ m_container->setItemView(this);
+ m_container->setParentItem(viewport());
+
+ viewport()->setFlag(
+ QGraphicsItem::ItemClipsChildrenToShape, true);
+ m_scroller.setScrollable(this);
+ installEventFilter(&m_scroller);
+}
+
+/*virtual*/
+void AbstractItemView::setRootIndex(const QModelIndex &index)
+{
+ m_rootIndex = index;
+ // TODO fix this if we change index, container should be updated? Or do we need root index?
+}
+
+/*virtual*/
+int AbstractItemView::indexCount() const
+{
+ if (m_model)
+ return m_model->rowCount(m_rootIndex);
+ return 0;
+}
+
+/*virtual*/
+QAbstractItemModel* AbstractItemView::model() const
+{
+ return m_model;
+}
+
+/*virtual*/
+QModelIndex AbstractItemView::nextIndex(const QModelIndex &index) const
+{
+ if (!m_model)
+ return QModelIndex();
+
+ if (index.isValid())
+ return m_model->index(index.row() + 1, 0, m_rootIndex);
+ else
+ return m_model->index(0, 0, m_rootIndex);
+}
+
+/*virtual*/
+QModelIndex AbstractItemView::previousIndex(const QModelIndex &index) const
+{
+ if (!m_model)
+ return QModelIndex();
+
+ if (index.isValid())
+ return m_model->index(index.row() - 1, 0, m_rootIndex);
+ else
+ return m_model->index(m_model->rowCount(m_rootIndex) - 1, 0, m_rootIndex);
+}
+
+/*virtual*/
+void AbstractItemView::setItemPrototype(AbstractViewItem* prototype)
+{
+ if (prototype && m_container) {
+ m_container->setItemPrototype(prototype);
+ m_container->reset();
+ }
+}
+
+void AbstractItemView::setSelectionModel(QItemSelectionModel *smodel)
+{
+ if (smodel && smodel->model() != m_model) {
+ return;
+ }
+ if (m_selectionModel) {
+ disconnect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(currentSelectionChanged(QItemSelection,QItemSelection)));
+
+ disconnect(m_selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(currentIndexChanged(QModelIndex,QModelIndex)));
+
+ delete m_selectionModel;
+ m_selectionModel = 0;
+ }
+
+ m_selectionModel = smodel;
+
+ if (m_selectionModel) {
+ connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(currentSelectionChanged(QItemSelection,QItemSelection)));
+ connect(m_selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(currentIndexChanged(QModelIndex,QModelIndex)));
+ }
+}
+
+/*virtual*/
+void AbstractItemView::currentIndexChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ Q_UNUSED(previous)
+
+ if (current != m_currentIndex)
+ m_currentIndex = current;
+}
+
+/*virtual*/
+void AbstractItemView::currentSelectionChanged(const QItemSelection &selected,
+ const QItemSelection &deselected)
+{
+ Q_UNUSED(selected)
+ Q_UNUSED(deselected)
+}
+
+/*virtual*/
+void AbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ Q_UNUSED(topLeft)
+ Q_UNUSED(bottomRight)
+ // TODO implement if we like to edit view items.
+}
+
+/*virtual*/
+void AbstractItemView::rowsAboutToBeInserted(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // TODO implement
+}
+
+/*virtual*/
+void AbstractItemView::rowsAboutToBeRemoved(const QModelIndex &index,int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+}
+
+/*virtual*/
+void AbstractItemView::rowsRemoved(const QModelIndex &parent,int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ if (start <= m_currentIndex.row() && m_currentIndex.row() <= end) {
+ QModelIndex newCurrentIndex = m_model->index(start, 0, m_rootIndex);
+ if (!newCurrentIndex.isValid()) {
+ newCurrentIndex = m_model->index(qMax(0,start - 1), 0, m_rootIndex);
+ }
+
+ if (m_selectionModel) {
+ m_selectionModel->setCurrentIndex(newCurrentIndex, QItemSelectionModel::NoUpdate);
+ }
+ }
+ for (int i = end; i >= start; --i) //The items are already removed from the model.
+ m_container->removeItem(QModelIndex()); // Indexes are already invalid.
+}
+
+/*virtual*/
+void AbstractItemView::reset()
+{
+ m_rootIndex = QModelIndex();
+
+ if (m_container)
+ m_container->reset();
+
+ setCurrentIndex(QModelIndex());
+
+ ScrollBar *sb = verticalScrollBar();
+
+ if (sb)
+ sb->setSliderSize(0);
+}
+
+/*virtual*/
+void AbstractItemView::rowsInserted(const QModelIndex &parent, int start, int end)
+{
+ if (!m_container)
+ return;
+
+ for (int i = start; i <= end; ++i)
+ m_container->addItem(m_model->index(i, 0, parent));
+
+ refreshContainerGeometry();
+}
+
+/*virtual*/
+void AbstractItemView::modelDestroyed()
+{
+ m_model = 0;
+ setSelectionModel(0);
+ reset();
+}
+
+/*virtual*/
+void AbstractItemView::layoutChanged()
+{
+ m_container->reset();
+}
+
+bool AbstractItemView::event(QEvent *e)
+{
+ bool result = AbstractScrollArea::event(e);
+ if (e && e->type()==QEvent::LayoutRequest) {
+ refreshContainerGeometry();
+ result = true;
+ }
+ if (e && e->type()==QEvent::GraphicsSceneResize) {
+ m_scroller.stopScrolling();
+ refreshContainerGeometry();
+
+ m_container->resize(this->size().width()-verticalScrollBar()->size().width(),
+ m_container->preferredHeight());
+
+ if (verticalScrollBar()->sliderPosition() > verticalScrollBar()->sliderSize())
+ verticalScrollBar()->setSliderPosition(verticalScrollBar()->sliderSize());
+
+ result = true;
+ }
+ return result;
+}
+
+void AbstractItemView::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags selectionFlag)
+{
+ if (m_selectionModel)
+ m_selectionModel->setCurrentIndex(index, selectionFlag);
+}
+
+void AbstractItemView::refreshContainerGeometry()
+{
+ if (!m_container || !m_model)
+ return;
+
+ if (m_container->layout() && !m_container->layout()->isActivated())
+ m_container->layout()->activate();
+
+ ScrollBar *sb = verticalScrollBar();
+
+ if (sb) {
+ AbstractViewItem *item = m_container->itemAt(0);
+ if (item) {
+ qreal oneItemH = item->size().height();
+ sb->setSliderSize(oneItemH*m_model->rowCount(m_rootIndex)-size().height());
+ }
+ if (!sb->isVisible() && verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff &&
+ contentsRect().height() < m_container->boundingRect().height())
+ sb->show();
+ }
+}
+
+void AbstractItemView::scrollContentsBy(qreal dx, qreal dy)
+{
+ AbstractScrollArea::scrollContentsBy(dx, dy);
+
+ if (!viewport() || !m_container || (m_container && m_container->itemCount() <= 0) ||
+ !m_model || (m_model && m_model->rowCount() <= 0) ||
+ (viewport() && viewport()->boundingRect().height() < contentsRect().height()))
+ return;
+
+ qreal itemH = 1;
+
+ AbstractViewItem *item = m_container->itemAt(0);
+ if (item && item->size().height() > 1) {
+ itemH = item->size().height();
+ } else if (item && item->preferredHeight() > 1) {
+ itemH = item->preferredHeight();
+ }
+
+ qreal vpx = m_container->pos().x();
+ qreal vpy = m_container->pos().y();
+
+ if ((vpy+m_container->size().height()-dy > pos().y()+size().height()) &&
+ (qAbs(dy) < itemH) && (vpy-dy <= 0)) {
+ m_container->setPos(vpx, vpy-dy);
+ } else {
+ qreal vPos = verticalScrollBar()->sliderPosition();
+ int startRow = m_model->index(vPos/itemH, 0).row();
+ int itemsInContainer = m_container->itemCount();
+
+ for (int i = 0; i<itemsInContainer; ++i) {
+ AbstractViewItem *changedItem = m_container->itemAt(i);
+ changedItem->setModelIndex(m_model->index(startRow+i,0));
+ m_container->setListItemCaching(listItemCaching(), i);
+ }
+
+ qreal diff = vPos-startRow*itemH;
+
+ if (diff < 0)
+ m_container->setPos(vpx, diff);
+ else
+ m_container->setPos(vpx, -diff);
+ }
+}
+
+void AbstractItemView::changeTheme()
+{
+ if (m_container)
+ m_container->themeChange();
+}
+
+void AbstractItemView::updateViewContent()
+{
+ if (m_container)
+ m_container->updateContent();
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h
new file mode 100644
index 0000000000..8cd295ba89
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTITEMVIEW_H
+#define ABSTRACTITEMVIEW_H
+
+#include <QAbstractItemModel>
+#include <QGraphicsSceneResizeEvent>
+#include <QPersistentModelIndex>
+#include <QItemSelection>
+
+#include "listitemcontainer.h"
+#include "abstractscrollarea.h"
+#include "scroller.h"
+
+class QItemSelectionModel;
+
+class AbstractItemView : public AbstractScrollArea
+{
+ Q_OBJECT
+public:
+ AbstractItemView(QGraphicsWidget *parent = 0);
+ virtual ~AbstractItemView();
+ virtual void setContainer(AbstractItemContainer *container);
+ virtual void setModel(QAbstractItemModel *model, AbstractViewItem *prototype);
+ virtual QAbstractItemModel* model() const;
+ virtual void setItemPrototype(AbstractViewItem* prototype);
+
+ void setSelectionModel(QItemSelectionModel *smodel);
+
+ virtual QModelIndex nextIndex(const QModelIndex &index) const;
+ virtual QModelIndex previousIndex(const QModelIndex &index) const;
+
+ virtual int indexCount() const;
+
+ void refreshContainerGeometry(); // TODO Can this be moved to scroll area?
+
+ void updateViewContent();
+ virtual void scrollContentsBy(qreal dx, qreal dy);
+
+ virtual bool listItemCaching() const = 0;
+ virtual void setListItemCaching(bool enabled) = 0;
+
+protected:
+ virtual bool event(QEvent *e);
+ void changeTheme();
+
+public slots:
+ virtual void setRootIndex(const QModelIndex &index);
+ void setCurrentIndex(const QModelIndex &index,
+ QItemSelectionModel::SelectionFlags selectionFlag = QItemSelectionModel::NoUpdate);
+protected slots:
+ virtual void currentIndexChanged(const QModelIndex &current, const QModelIndex &previous);
+ virtual void currentSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ virtual void rowsAboutToBeInserted(const QModelIndex &index, int start, int end);
+ virtual void rowsInserted(const QModelIndex &parent, int start, int end);
+ virtual void rowsAboutToBeRemoved(const QModelIndex &index,int start, int end);
+ virtual void rowsRemoved(const QModelIndex &parent,int start, int end);
+ virtual void modelDestroyed();
+ virtual void layoutChanged();
+ virtual void reset();
+
+protected:
+
+ QAbstractItemModel *m_model;
+ QPersistentModelIndex m_rootIndex;
+ AbstractItemContainer *m_container;
+ QItemSelectionModel *m_selectionModel;
+ QPersistentModelIndex m_currentIndex;
+
+private:
+ Q_DISABLE_COPY(AbstractItemView)
+ Scroller m_scroller;
+};
+
+
+#endif // ABSTRACTITEMVIEW_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp
new file mode 100644
index 0000000000..39847b8edb
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp
@@ -0,0 +1,236 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsSceneResizeEvent>
+#include <QGraphicsWidget>
+#include <QDebug>
+#include "abstractscrollarea.h"
+#include "scrollbar.h"
+
+AbstractScrollArea::AbstractScrollArea(QGraphicsWidget *parent)
+ : GvbWidget(parent)
+ , m_viewport(0)
+ , m_horizontalScrollBar(0)
+ , m_verticalScrollBar(0)
+ , m_prevHorizontalValue(0.0)
+ , m_prevVerticalValue(0.0)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setContentsMargins(0, 0, 0, 0);
+
+ m_horizontalScrollBar = new ScrollBar(Qt::Horizontal, this);
+ m_horizontalScrollBar->hide();
+ m_horizontalScrollBar->setContentsMargins(0, 0, 0, 0);
+ m_horizontalScrollBarPolicy = Qt::ScrollBarAsNeeded;
+ m_horizontalScrollBar->setZValue(zValue()+1); // Raise scroll bar to top
+ m_horizontalScrollBar->setVisible(false);
+
+ connect(m_horizontalScrollBar, SIGNAL(sliderPositionChange(qreal)),
+ this, SLOT(horizontalScroll(qreal)));
+ connect(m_horizontalScrollBar, SIGNAL(sliderPressed()),
+ this, SLOT(horizontalScrollStart()));
+
+ m_verticalScrollBar = new ScrollBar(Qt::Vertical, this);
+ m_verticalScrollBar->hide();
+ m_verticalScrollBar->setContentsMargins(0, 0, 0, 0);
+ m_verticalScrollBarPolicy = Qt::ScrollBarAsNeeded;
+ m_verticalScrollBar->setZValue(zValue()+1); // Raise scroll bar to top
+ m_verticalScrollBar->setVisible(false);
+
+ connect(m_verticalScrollBar, SIGNAL(sliderPositionChange(qreal)),
+ this, SLOT(verticalScroll(qreal)));
+ connect(m_verticalScrollBar, SIGNAL(sliderPressed()),
+ this, SLOT(verticalScrollStart()));
+
+ QGraphicsWidget *viewport = new QGraphicsWidget;
+ setViewport(viewport);
+}
+
+AbstractScrollArea::~AbstractScrollArea()
+{
+}
+
+ScrollBar *AbstractScrollArea::verticalScrollBar() const
+{
+ return m_verticalScrollBar;
+}
+
+ScrollBar *AbstractScrollArea::horizontalScrollBar() const
+{
+ return m_horizontalScrollBar;
+}
+
+void AbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
+{
+ m_horizontalScrollBarPolicy = policy;
+}
+
+void AbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
+{
+ m_verticalScrollBarPolicy = policy;
+}
+
+Qt::ScrollBarPolicy AbstractScrollArea::verticalScrollBarPolicy() const
+{
+ return m_verticalScrollBarPolicy;
+}
+
+Qt::ScrollBarPolicy AbstractScrollArea::horizontalScrollBarPolicy() const
+{
+ return m_horizontalScrollBarPolicy;
+}
+
+QGraphicsWidget *AbstractScrollArea::viewport() const
+{
+ return m_viewport;
+}
+
+void AbstractScrollArea::setViewport(QGraphicsWidget *viewport)
+{
+ if (m_viewport) {
+ m_viewport->setParentItem(0);
+
+ QList<QGraphicsItem*> children = m_viewport->childItems();
+
+ foreach (QGraphicsItem *child, children)
+ child->setParentItem(0);
+
+ delete m_viewport;
+ }
+
+ m_viewport = viewport;
+
+ if (viewport) {
+
+ m_viewport->setParentItem(this);
+ m_viewport->setContentsMargins(0, 0, 0, 0);
+
+ adjustScrollBars();
+ }
+
+ emit viewportChanged(viewport);
+}
+
+bool AbstractScrollArea::event(QEvent *e)
+{
+ if (e->type() == QEvent::ApplicationLayoutDirectionChange
+ || e->type() == QEvent::LayoutDirectionChange) {
+ } else if (e->type() == QEvent::GraphicsSceneResize) {
+ QGraphicsSceneResizeEvent *event =
+ static_cast<QGraphicsSceneResizeEvent*>(e);
+
+ QSizeF newSize = event->newSize();
+ QRectF hrect = m_horizontalScrollBar->boundingRect();
+ QRectF vrect = m_verticalScrollBar->boundingRect();
+
+ QSizeF vpSize = newSize;
+
+ if (m_horizontalScrollBarPolicy != Qt::ScrollBarAlwaysOff)
+ vpSize.setHeight(newSize.height() - hrect.height());
+ if (m_verticalScrollBarPolicy != Qt::ScrollBarAlwaysOff)
+ vpSize.setWidth(newSize.width() - vrect.width());
+
+ m_viewport->resize(vpSize);
+
+ adjustScrollBars();
+ }
+
+ return QGraphicsWidget::event(e);
+}
+
+
+void AbstractScrollArea::scrollContentsBy(qreal dx, qreal dy)
+{
+ Q_UNUSED(dx)
+ Q_UNUSED(dy)
+ prepareGeometryChange();
+}
+
+void AbstractScrollArea::verticalScrollStart()
+{
+ m_prevVerticalValue = m_verticalScrollBar->sliderPosition();
+}
+
+void AbstractScrollArea::verticalScroll(qreal value)
+{
+ qreal dy = value - m_prevVerticalValue;
+ if (!qFuzzyCompare(dy,qreal(0.0))) {
+ scrollContentsBy(0.0, dy);
+ m_prevVerticalValue = value;
+ }
+}
+
+void AbstractScrollArea::horizontalScrollStart()
+{
+ m_prevHorizontalValue = m_horizontalScrollBar->sliderPosition();
+}
+
+void AbstractScrollArea::horizontalScroll(qreal value)
+{
+ qreal dx = value - m_prevHorizontalValue;
+ if (!qFuzzyCompare(dx,qreal(0.0))) {
+ scrollContentsBy(dx, 0.0);
+ m_prevHorizontalValue = value;
+ }
+}
+
+void AbstractScrollArea::adjustScrollBars()
+{
+ if (m_horizontalScrollBarPolicy == Qt::ScrollBarAlwaysOff) {
+ m_horizontalScrollBar->hide();
+ } else {
+ m_horizontalScrollBar->show();
+
+ QRectF sbgeom = boundingRect();
+
+ sbgeom.setTop(sbgeom.bottom() - m_horizontalScrollBar->boundingRect().height());
+ sbgeom.setRight(sbgeom.right() - m_verticalScrollBar->boundingRect().width());
+ m_horizontalScrollBar->setGeometry(sbgeom);
+ }
+
+ if (m_verticalScrollBarPolicy == Qt::ScrollBarAlwaysOff) {
+ m_verticalScrollBar->hide();
+ QRectF sbgeom = boundingRect();
+ sbgeom.setLeft(sbgeom.right());
+ sbgeom.setBottom(sbgeom.bottom());
+ m_verticalScrollBar->setGeometry(sbgeom);
+ } else {
+ m_verticalScrollBar->show();
+
+ QRectF sbgeom = boundingRect();
+
+ sbgeom.setLeft(sbgeom.right() - m_verticalScrollBar->boundingRect().width());
+ if (m_horizontalScrollBarPolicy != Qt::ScrollBarAlwaysOff)
+ sbgeom.setBottom(sbgeom.bottom() - m_horizontalScrollBar->boundingRect().height());
+ m_verticalScrollBar->setGeometry(sbgeom);
+ }
+}
+
+
+
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h
new file mode 100644
index 0000000000..f681ca9fce
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTSCROLLAREA_H
+#define ABSTRACTSCROLLAREA_H
+
+#include "gvbwidget.h"
+
+class ScrollBar;
+class QGraphicsGridLayout;
+
+class AbstractScrollArea : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+
+ AbstractScrollArea(QGraphicsWidget *parent = 0);
+ ~AbstractScrollArea();
+
+public:
+
+ void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy);
+ void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy);
+ Qt::ScrollBarPolicy verticalScrollBarPolicy() const;
+ Qt::ScrollBarPolicy horizontalScrollBarPolicy() const;
+
+ QGraphicsWidget *viewport() const;
+ void setViewport(QGraphicsWidget *viewport);
+
+ ScrollBar *verticalScrollBar() const;
+ ScrollBar *horizontalScrollBar() const;
+
+signals:
+
+ void viewportChanged(QGraphicsWidget *viewport);
+
+protected:
+
+ virtual bool event(QEvent *e);
+ virtual void scrollContentsBy(qreal dx, qreal dy);
+
+private slots:
+
+ void verticalScrollStart();
+ void verticalScroll(qreal);
+ void horizontalScrollStart();
+ void horizontalScroll(qreal);
+
+private:
+
+ void adjustScrollBars();
+
+ QGraphicsWidget *m_viewport;
+ ScrollBar *m_horizontalScrollBar;
+ ScrollBar *m_verticalScrollBar;
+ Qt::ScrollBarPolicy m_verticalScrollBarPolicy;
+ Qt::ScrollBarPolicy m_horizontalScrollBarPolicy;
+ qreal m_prevHorizontalValue;
+ qreal m_prevVerticalValue;
+};
+
+#endif // ABSTRACTSCROLLAREA_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp
new file mode 100644
index 0000000000..6a6df15e23
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractviewitem.h"
+
+AbstractViewItem::AbstractViewItem(QGraphicsWidget *parent)
+ : GvbWidget(parent),
+ m_index(),
+ m_itemView(0),
+ m_prototype(0)
+{
+}
+
+/*virtual*/
+AbstractViewItem::~AbstractViewItem()
+{
+}
+
+QModelIndex AbstractViewItem::modelIndex() const
+{
+ return m_index;
+}
+
+AbstractViewItem *AbstractViewItem::prototype() const
+{
+ return m_prototype;
+}
+
+AbstractItemView *AbstractViewItem::itemView() const
+{
+ return m_itemView;
+}
+
+void AbstractViewItem::setItemView(AbstractItemView *itemView)
+{
+ m_itemView = itemView;
+}
+
+void AbstractViewItem::setModelIndex(const QModelIndex &index)
+{
+ if (m_index != index) {
+ m_index = index;
+ updateItemContents();
+ }
+}
+
+/*virtual*/
+QSizeF AbstractViewItem::effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+ return GvbWidget::effectiveSizeHint(which, constraint);
+}
+
+/*virtual*/
+bool AbstractViewItem::event(QEvent *e)
+{
+ return QGraphicsWidget::event(e);
+}
+
+/*virtual*/
+void AbstractViewItem::updateItemContents()
+{
+ ; // No impl yet
+}
+
+/*virtual*/
+void AbstractViewItem::themeChange()
+{
+ ; // No impl yet
+}
+
+/*virtual*/
+void AbstractViewItem::setSubtreeCacheEnabled(bool enabled)
+{
+ Q_UNUSED(enabled)
+ ; // No impl
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h
new file mode 100644
index 0000000000..4f9fbf4623
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTVIEWITEM_H
+#define ABSTRACTVIEWITEM_H
+
+#include <QModelIndex>
+
+#include "gvbwidget.h"
+#include "abstractitemview.h"
+#include "listitem.h"
+
+class QGraphicsWidget;
+
+class AbstractViewItem : public GvbWidget
+{
+ Q_OBJECT
+public:
+ AbstractViewItem(QGraphicsWidget *parent = 0);
+ virtual ~AbstractViewItem();
+
+ virtual AbstractViewItem *newItemInstance() = 0;
+
+ QModelIndex modelIndex() const;
+
+ void setModelIndex(const QModelIndex &index);
+
+ AbstractViewItem *prototype() const;
+ AbstractItemView *itemView() const;
+ void setItemView(AbstractItemView *itemView) ;
+ virtual void updateItemContents();
+ virtual void themeChange();
+
+ virtual void setSubtreeCacheEnabled(bool enabled);
+
+ virtual QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+ virtual void setModel(QAbstractItemModel *model) = 0;
+ virtual QVariant data(int role) const = 0;
+ virtual void setData(const QVariant &value, int role = Qt::DisplayRole) = 0;
+ virtual void setTwoColumns(const bool enabled) = 0;
+
+protected:
+ virtual bool event(QEvent *e);
+
+ QPersistentModelIndex m_index;
+
+private:
+ Q_DISABLE_COPY(AbstractViewItem)
+
+ AbstractItemView *m_itemView;
+ AbstractViewItem *m_prototype;
+
+};
+
+#endif // ABSTRACTVIEWITEM_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp
new file mode 100644
index 0000000000..9f5f16d373
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStyleOptionGraphicsItem>
+#include <QGraphicsSceneResizeEvent>
+#include <QPainter>
+#include <QRectF>
+
+#include "backgrounditem.h"
+#include "theme.h"
+
+BackgroundItem::BackgroundItem(const QString &filename, QGraphicsWidget *parent)
+ : GvbWidget(parent),
+ m_background(),
+ m_fileName(filename)
+{
+ setContentsMargins(0,0,0,0);
+
+ connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange()));
+}
+
+BackgroundItem::~BackgroundItem()
+{
+}
+
+void BackgroundItem::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ GvbWidget::resizeEvent(event);
+ m_background = Theme::p()->pixmap(m_fileName, size().toSize());
+}
+
+void BackgroundItem::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_UNUSED(widget)
+ painter->setCompositionMode(QPainter::CompositionMode_Source);
+ painter->drawPixmap(option->exposedRect, m_background, option->exposedRect);
+}
+
+void BackgroundItem::themeChange()
+{
+ m_background = Theme::p()->pixmap(m_fileName, size().toSize());
+ update();
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h
new file mode 100644
index 0000000000..0cb0ee778c
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __BACKGROUNDITEM_H__
+#define __BACKGROUNDITEM_H__
+
+#include <QPixmap>
+
+#include "gvbwidget.h"
+
+class QGraphicsWidget;
+
+class BackgroundItem : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+ BackgroundItem(const QString &filename, QGraphicsWidget *parent=0);
+ ~BackgroundItem();
+
+ void paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget = 0);
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+public slots:
+ void themeChange();
+
+private:
+ QPixmap m_background;
+ QString m_fileName;
+};
+
+#endif /* __BACKGROUNDITEM_H__ */
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp
new file mode 100644
index 0000000000..b8bd55789d
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include "button.h"
+#include "theme.h"
+
+static const int MinTextWidthAsChars = 8;
+
+class ButtonPrivate {
+ Q_DECLARE_PUBLIC(Button)
+
+public:
+
+ ButtonPrivate(Button *button)
+ : down(false)
+ , q_ptr(button)
+ {
+ textItem = new QGraphicsSimpleTextItem(q_ptr);
+ }
+
+ QGraphicsSimpleTextItem *textItem;
+ bool down;
+ Button *q_ptr;
+};
+
+Button::Button(const QString &text, QGraphicsItem *parent, QSizeF minimumSize)
+ : QGraphicsWidget(parent)
+ , d_ptr(new ButtonPrivate(this)), m_background(), m_selected(false)
+{
+ Q_D(Button);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ //setCacheMode(QGraphicsItem::ItemCoordinateCache);
+ if(minimumSize.isValid())
+ setMinimumSize(minimumSize);
+ setContentsMargins(0, 0, 0, 0);
+ d->textItem->setText(text);
+ prepareGeometryChange();
+
+ m_font = Theme::p()->font(Theme::MenuItem);
+ d->textItem->setFont(m_font);
+ connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange()));
+}
+
+Button::~Button()
+{
+ delete d_ptr;
+}
+
+bool Button::isDown()
+{
+ Q_D(Button);
+
+ return d->down;
+}
+
+void Button::setText(const QString &text)
+{
+ Q_D(Button);
+ d->textItem->setText(text);
+ update();
+}
+
+QString Button::text()
+{
+ Q_D(Button);
+ return d->textItem->text();
+}
+
+void Button::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(option);
+
+ if(!m_background.isNull())
+ painter->drawPixmap(QPoint(), m_background);
+ if(m_selected) {
+ painter->setBrush(Qt::black);
+ painter->setOpacity(0.2);
+ painter->drawRect(boundingRect().toRect());
+ }
+}
+
+QSizeF Button::sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint) const
+{
+ Q_D(const Button);
+
+ switch (which)
+ {
+ case Qt::MinimumSize:
+ {
+ QFontMetricsF fm(d->textItem->font());
+ return QSizeF(MinTextWidthAsChars * fm.maxWidth(), fm.height());
+ }
+ case Qt::PreferredSize:
+ {
+ QFontMetricsF fm(d->textItem->font());
+ return QSizeF(fm.horizontalAdvance(d->textItem->text()), fm.height());
+ }
+ default:
+ return QGraphicsWidget::sizeHint(which, constraint);
+ }
+}
+
+void Button::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(Button);
+
+ if (event->button() != Qt::LeftButton ||
+ !sceneBoundingRect().contains(event->scenePos()))
+ return;
+
+ d->down = true;
+
+ prepareGeometryChange();
+ emit pressed();
+
+}
+
+void Button::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(Button);
+
+ if (!d->down || event->button() != Qt::LeftButton)
+ return;
+
+ d->down = false;
+
+ prepareGeometryChange();
+
+ emit released();
+
+ if (sceneBoundingRect().contains(event->scenePos()))
+ emit clicked();
+}
+
+void Button::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+void Button::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ Q_D(Button);
+ QGraphicsWidget::resizeEvent(event);
+
+ QRectF rect = d->textItem->boundingRect();
+ QRectF buttonrect = this->boundingRect();
+ d->textItem->setPos((buttonrect.width() - rect.width())/2, (buttonrect.height() - rect.height())/2 );
+
+ QSize currentSize = buttonrect.size().toSize();
+ if( m_background.size() != currentSize && (currentSize.width() > 0 && currentSize.height() > 0) ) {
+ m_background = Theme::p()->pixmap("status_field_middle.svg", buttonrect.size().toSize());
+ }
+}
+
+void Button::setBackground(QPixmap& background)
+{
+ m_background = background;
+}
+
+void Button::themeChange()
+{
+ Q_D(Button);
+
+ m_font = Theme::p()->font(Theme::MenuItem);
+ d->textItem->setFont(m_font);
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h
new file mode 100644
index 0000000000..8e76b88463
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BUTTON_H
+#define BUTTON_H
+
+#include <QGraphicsWidget>
+
+class ButtonPrivate;
+class QTextDocument;
+
+class QPixmap;
+class QFont;
+
+class Button : public QGraphicsWidget
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(Button)
+
+public:
+
+ Button(const QString &text, QGraphicsItem *parent=0, QSizeF minimumSize = QSizeF());
+ virtual ~Button();
+
+signals:
+
+ void clicked(bool checked = false);
+ void pressed();
+ void released();
+
+public slots:
+
+ void themeChange();
+ void setText(const QString &text);
+ QString text();
+
+public:
+
+ void setBackground(QPixmap& background);
+ bool isDown();
+ void select(bool select){m_selected = select;}
+ void click() {emit clicked();}
+
+private:
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget = 0);
+ QSizeF sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint = QSizeF()) const;
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+private:
+ Q_DISABLE_COPY(Button)
+ ButtonPrivate *d_ptr;
+ QPixmap m_background;
+ QFont m_font;
+ bool m_selected;
+};
+
+#endif // BUTTON_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp
new file mode 100644
index 0000000000..226c60cec8
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+#include <QDebug>
+
+#include "commandline.h"
+
+static void usage(const char *appname)
+{
+ Q_UNUSED(appname);
+ printf(" GraphicsViewBenchmark related options:\n");
+ printf(" -h,-help,--help: This help\n");
+ printf(" -resolution : UI resolution in format WxH where width and height are positive values\n");
+ printf(" -opengl : Enables OpenGL usage. Building PRECONDITIONS: QT_NO_OPENGL is off.\n");
+ printf(" -manual : Run test manually \n");
+ printf("\n The following options are available in manual mode:\n");
+ printf(" -rotation : UI rotation in degrees\n");
+ printf(" -subtree-cache : Enables usage of subtree caching method\n");
+ printf(" -fps : Output FPS count to stdout during application execution\n");
+ printf(" -items : Count of items created to the list\n");
+ printf("\n");
+}
+
+static inline bool argumentOnlyAvailableInManualMode(const char *arg)
+{
+ return (strcmp(arg, "-rotation") == 0)
+ || (strcmp(arg, "-subtree-cache") == 0)
+ || (strcmp(arg, "-fps") == 0)
+ || (strcmp(arg, "-items") == 0);
+}
+
+bool readSettingsFromCommandLine(int argc, char *argv[],
+ Settings& config)
+{
+ bool builtWithOpenGL = false;
+ Settings::Options options;
+
+#ifndef QT_NO_OPENGL
+ builtWithOpenGL = true;
+#endif
+ for (int i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "-manual") == 0) {
+ options |= Settings::ManualTest;
+ argv[i] = 0;
+ break;
+ }
+ }
+
+ for (int i = 1; i < argc; ++i) {
+ if (!argv[i])
+ continue;
+ if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0) {
+ usage(argv[0]);
+ return true;
+ }
+ if (strcmp(argv[i], "-opengl") == 0) {
+ if (builtWithOpenGL) {
+ options |= Settings::UseOpenGL;
+ argv[i] = 0;
+ } else {
+ printf("-opengl parameter can be used only with building PRECONDITIONS: QT_NO_OPENGL is off.\n");
+ usage(argv[0]);
+ return false;
+ }
+ } else if (strcmp(argv[i], "-resolution") == 0) {
+ if (i + 1 >= argc) {
+ printf("-resolution needs an extra parameter specifying the application UI resolution\n");
+ usage(argv[0]);
+ return false;
+ }
+ else {
+ QStringList res = QString(argv[i+1]).split(QLatin1Char('x'));
+ if (res.count() != 2) {
+ printf("-resolution parameter UI resolution should be set in format WxH where width and height are positive values\n");
+ usage(argv[0]);
+ return false;
+ }
+ int width = res.at(0).toInt();
+ int height = res.at(1).toInt();
+
+ config.setSize(QSize(width, height));
+
+ if (width <=0 || height <=0) {
+ printf("-resolution parameter UI resolution should be set in format WxH where width and height are positive values\n");
+ usage(argv[0]);
+ return false;
+ }
+ argv[i] = 0;
+ i++;
+ argv[i] = 0;
+ }
+ }
+
+ if (!argv[i])
+ continue;
+
+ if (!(options & Settings::ManualTest)) {
+ if (argumentOnlyAvailableInManualMode(argv[i])) {
+ printf("\nWrong option: '%s' is only available in manual mode\n\n", argv[i]);
+ usage(argv[0]);
+ return false;
+ }
+ continue;
+ }
+
+ if (strcmp(argv[i], "-rotation") == 0) {
+ if (i + 1 >= argc) {
+ printf("-rotation needs an extra parameter specifying the application UI rotation in degrees\n");
+ usage(argv[0]);
+ return false;
+ }
+ else {
+ bool ok;
+ int angle = QString(argv[i+1]).toInt(&ok);
+ if (!ok) {
+ printf("-rotation parameter should specify rotation angle in degrees\n");
+ usage(argv[0]);
+ return false;
+ }
+ config.setAngle(angle);
+ argv[i] = 0;
+ i++;
+ argv[i] = 0;
+ }
+ } else if (strcmp(argv[i], "-subtree-cache") == 0) {
+ options |= Settings::UseListItemCache;
+ argv[i] = 0;
+ } else if (strcmp(argv[i], "-fps") == 0) {
+ options |= Settings::OutputFps;
+ argv[i] = 0;
+ } else if (strcmp(argv[i], "-items") == 0) {
+ if (i + 1 >= argc) {
+ printf("-items needs an extra parameter specifying amount of list items\n");
+ usage(argv[0]);
+ return false;
+ }
+ else {
+ bool ok;
+ int amount = QString(argv[i+1]).toInt(&ok);
+ if (!ok) {
+ printf("-items needs an extra parameter specifying amount (integer) of list items\n");
+ usage(argv[0]);
+ return false;
+ }
+ config.setListItemCount(amount);
+ argv[i] = 0;
+ i++;
+ argv[i] = 0;
+ }
+ }
+ }
+
+ config.setOptions(options);
+
+ return true;
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h
new file mode 100644
index 0000000000..eaddeac59d
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMMANDLINE_H
+#define COMMANDLINE_H
+
+#include "settings.h"
+
+bool readSettingsFromCommandLine(int argc,
+ char *argv[],
+ Settings& settings);
+
+
+#endif // COMMANDLINE_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp
new file mode 100644
index 0000000000..7809b38050
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QFile>
+#include <QRandomGenerator>
+#include "theme.h"
+
+#include "dummydatagen.h"
+
+DummyDataGenerator::DummyDataGenerator() : m_isMale(false)
+{
+ QFile countryCodeFile(":/contact/areacodes.txt");
+ countryCodeFile.open(QIODevice::ReadOnly);
+ while (!countryCodeFile.atEnd()) {
+ m_countryCodes << QString(countryCodeFile.readLine()).remove("\n");
+ }
+
+ QFile firstNameFFile(":/contact/firstnamesF.txt");
+ firstNameFFile.open(QIODevice::ReadOnly);
+ while (!firstNameFFile.atEnd()) {
+ m_firstNamesF << QString(firstNameFFile.readLine()).remove("\n");
+ }
+
+ QFile firstNameMFile(":/contact/firstnamesM.txt");
+ firstNameMFile.open(QIODevice::ReadOnly);
+ while (!firstNameMFile.atEnd()) {
+ m_firstNamesM << QString(firstNameMFile.readLine()).remove("\n");
+ }
+
+ QFile lastNameFile(":/contact/lastnames.txt");
+ lastNameFile.open(QIODevice::ReadOnly);
+ while (!lastNameFile.atEnd()) {
+ m_lastNames << QString(lastNameFile.readLine()).remove("\n");
+ }
+ Reset();
+}
+
+DummyDataGenerator::~DummyDataGenerator()
+{
+}
+
+void DummyDataGenerator::Reset()
+{
+}
+
+QString DummyDataGenerator::randomPhoneNumber(QString indexNumber)
+{
+ int index = QRandomGenerator::global()->bounded(m_countryCodes.count());
+ QString countryCode = m_countryCodes.at(index);
+ QString areaCode = QString::number(index) + QString("0").repeated(2-QString::number(index).length());
+ QString beginNumber = QString::number(555-index*2);
+ QString endNumber = QString("0").repeated(4-indexNumber.length()) + indexNumber;
+
+ return countryCode + QLatin1Char(' ') + areaCode +QLatin1Char(' ') + beginNumber
+ + QLatin1Char(' ') + endNumber;
+}
+
+QString DummyDataGenerator::randomFirstName()
+{
+ m_isMale = !m_isMale;
+ if (m_isMale)
+ return m_firstNamesM.at(QRandomGenerator::global()->bounded(m_firstNamesM.count()));
+ return m_firstNamesF.at(QRandomGenerator::global()->bounded(m_firstNamesF.count()));
+}
+
+QString DummyDataGenerator::randomLastName()
+{
+ return m_lastNames.at(QRandomGenerator::global()->bounded(m_lastNames.count()));
+}
+
+QString DummyDataGenerator::randomName()
+{
+ return QString(randomFirstName()+QString(", ")+randomLastName());
+}
+
+QString DummyDataGenerator::randomIconItem()
+{
+ QString avatar = Theme::p()->pixmapPath() + "contact_default_icon.svg";
+ if (QRandomGenerator::global()->bounded(4)) {
+ int randVal = 1+QRandomGenerator::global()->bounded(25);
+
+ if (m_isMale && randVal > 15) {
+ randVal -= 15;
+ }
+ if (!m_isMale && randVal <= 10) {
+ randVal += 10;
+ }
+
+ avatar = QString(":/avatars/avatar_%1.png").arg(randVal, 3, 10, QChar('0'));
+ }
+ return avatar;
+}
+
+QString DummyDataGenerator::randomStatusItem()
+{
+ switch (QRandomGenerator::global()->bounded(3)) {
+ case 0: return Theme::p()->pixmapPath() + "contact_status_online.svg";
+ case 1: return Theme::p()->pixmapPath() + "contact_status_offline.svg";
+ case 2: return Theme::p()->pixmapPath() + "contact_status_idle.svg";
+ }
+ return 0;
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h
new file mode 100644
index 0000000000..bcb9681d5d
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __DUMMYDATAGEN_H__
+#define __DUMMYDATAGEN_H__
+
+#include <QObject>
+#include <QStringList>
+
+class DummyDataGenerator : public QObject
+{
+ Q_OBJECT
+public:
+ DummyDataGenerator();
+ ~DummyDataGenerator();
+
+public:
+ void Reset();
+ QString randomPhoneNumber(QString indexNumber);
+ QString randomFirstName();
+ QString randomLastName();
+ QString randomName();
+ QString randomIconItem();
+ QString randomStatusItem();
+
+private:
+ QStringList m_countryCodes;
+ QStringList m_firstNamesF;
+ QStringList m_firstNamesM;
+ QStringList m_lastNames;
+ bool m_isMale;
+};
+
+#endif // __DUMMYDATAGEN_H__
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp
new file mode 100644
index 0000000000..3682ae55e1
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include "gvbwidget.h"
+
+GvbWidget::GvbWidget(QGraphicsItem * parent, Qt::WindowFlags wFlags)
+ : QGraphicsWidget(parent, wFlags)
+{
+
+}
+
+GvbWidget::~GvbWidget()
+{
+}
+
+void GvbWidget::keyPressEvent(QKeyEvent *event)
+{
+ Q_UNUSED(event)
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h
new file mode 100644
index 0000000000..7e247b63a4
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GVBWIDGET_H
+#define GVBWIDGET_H
+
+#include <QGraphicsWidget>
+
+class GvbWidget : public QGraphicsWidget
+{
+ Q_OBJECT
+
+public:
+
+ GvbWidget(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0);
+ ~GvbWidget();
+ virtual void keyPressEvent(QKeyEvent *event);
+};
+
+#endif
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp
new file mode 100644
index 0000000000..a081e1b064
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QSvgRenderer>
+#include <QGraphicsEffect>
+
+#include "iconitem.h"
+
+IconItem::IconItem(const QString &filename, QGraphicsItem *parent)
+ : GvbWidget(parent)
+ , m_filename(filename)
+ , m_rotation(0.0)
+ , m_opacityEffect(0)
+ , m_smoothTransformation(false)
+{
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ setContentsMargins(0,0,0,0);
+ setPreferredSize(58,58);
+}
+
+IconItem::~IconItem()
+{
+}
+
+void IconItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ reload();
+
+ const QPointF c = boundingRect().center();
+ painter->translate(c.x(), c.y());
+ painter->rotate(m_rotation);
+ painter->translate(-c.x(), -c.y());
+
+ if (m_smoothTransformation)
+ painter->setRenderHints(QPainter::SmoothPixmapTransform);
+
+ painter->drawPixmap(0,0, m_pixmap);
+}
+
+QSizeF IconItem::sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint) const
+{
+ switch (which)
+ {
+ case Qt::MinimumSize:
+ case Qt::PreferredSize:
+ case Qt::MaximumSize:
+ return m_pixmap.size();
+
+ default:
+ return GvbWidget::sizeHint(which, constraint);
+ }
+}
+
+void IconItem::reload()
+{
+ const QSize iconSize = size().toSize();
+ if (iconSize.width() == 0 || iconSize.height() == 0)
+ return;
+
+ const QString key = m_filename+QString::number(iconSize.width())+QString::number(iconSize.height());
+ if (QPixmapCache::find(key, m_pixmap))
+ return;
+
+ if (m_filename.endsWith(".svg", Qt::CaseInsensitive))
+ {
+ m_pixmap = QPixmap(iconSize);
+ m_pixmap.fill(Qt::transparent);
+ QSvgRenderer doc(m_filename);
+ QPainter painter(&m_pixmap);
+ painter.setViewport(0, 0, iconSize.width(), iconSize.height());
+ doc.render(&painter);
+ }
+ else
+ {
+ m_pixmap = QPixmap(m_filename).scaled(iconSize);
+ }
+
+ QPixmapCache::insert(key, m_pixmap);
+ updateGeometry();
+}
+
+QString IconItem::fileName() const
+{
+ return m_filename;
+}
+
+void IconItem::setFileName(const QString &filename)
+{
+ if( m_filename != filename) {
+ m_filename = filename;
+ reload();
+ }
+}
+
+void IconItem::setOpacityEffectEnabled(const bool enable)
+{
+ if (!m_opacityEffect)
+ {
+ QRadialGradient gradient(0.5, 0.5, 1.0);
+ gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
+ gradient.setColorAt(0.0, QColor(0,0,0, 255));
+ gradient.setColorAt(0.46, QColor(0,0,0, 255));
+ gradient.setColorAt(0.62, QColor(0,0,0, 0));
+
+ m_opacityEffect = new QGraphicsOpacityEffect;
+ m_opacityEffect->setOpacityMask(gradient);
+ m_opacityEffect->setOpacity(1.0);
+ this->setGraphicsEffect(m_opacityEffect);
+ }
+ m_opacityEffect->setEnabled(enable);
+}
+
+bool IconItem::isOpacityEffectEnabled() const
+{
+ if (m_opacityEffect)
+ return m_opacityEffect->isEnabled();
+
+ return false;
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h
new file mode 100644
index 0000000000..48d1bafe9f
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ICONITEM_H
+#define ICONITEM_H
+
+#include <QPainter>
+
+#include "gvbwidget.h"
+
+class QGraphicsOpacityEffect;
+class QPainter;
+
+class IconItem : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+
+ IconItem(const QString &filename = "", QGraphicsItem *parent = 0);
+
+ virtual ~IconItem();
+
+ QString fileName() const;
+ void setFileName(const QString &filename);
+
+ void setOpacityEffectEnabled(const bool enable);
+ bool isOpacityEffectEnabled() const;
+
+ void setRotation(const qreal rotation) { m_rotation = rotation; }
+ qreal rotation() const { return m_rotation; }
+
+ void setSmoothTransformationEnabled(const bool enable) { m_smoothTransformation = enable; }
+ bool isSmoothTransformationEnabled() const { return m_smoothTransformation; }
+
+private:
+
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget */*widget = 0*/);
+ QSizeF sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint = QSizeF()) const;
+
+private:
+ Q_DISABLE_COPY(IconItem)
+ void reload();
+
+ QString m_filename;
+ QPixmap m_pixmap;
+ qreal m_rotation;
+ QGraphicsOpacityEffect *m_opacityEffect;
+ bool m_smoothTransformation;
+};
+
+#endif
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp
new file mode 100644
index 0000000000..eabe3671e5
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QTime>
+
+#include "itemrecyclinglist.h"
+#include "listitemcontainer.h"
+#include "abstractviewitem.h"
+#include "recycledlistitem.h"
+#include "theme.h"
+#include "scrollbar.h"
+
+ItemRecyclingList::ItemRecyclingList(const int itemBuffer, QGraphicsWidget * parent)
+ : ItemRecyclingListView(parent),
+ m_listModel(new ListModel(this))
+{
+ ListItemContainer *container = new ListItemContainer(itemBuffer, this, this);
+ container->setParentItem(this);
+ ItemRecyclingListView::setContainer(container);
+ ItemRecyclingListView::setModel(m_listModel, new RecycledListItem(this));
+ setObjectName("ItemRecyclingList");
+ connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange()));
+
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+}
+
+/* virtual */
+ItemRecyclingList::~ItemRecyclingList()
+{
+}
+
+/* virtual */
+void ItemRecyclingList::insertItem(int index, RecycledListItem *item)
+{
+ if (index<0)
+ index = 0;
+ if (index > m_listModel->rowCount())
+ index = m_listModel->rowCount();
+ if (m_listModel && item)
+ m_listModel->insert(index,item);
+
+ updateListItemBackgrounds(index);
+}
+
+/* virtual */
+void ItemRecyclingList::addItem(RecycledListItem *item)
+{
+ if (item)
+ m_listModel->appendRow(item);
+
+ const int index = m_listModel->rowCount()-1;
+ updateListItemBackgrounds(index);
+}
+
+/* virtual */
+void ItemRecyclingList::clear()
+{
+ m_listModel->clear();
+}
+
+/* virtual */
+AbstractViewItem *ItemRecyclingList::takeItem(const int row)
+{
+ if (row < 0 || row >= m_listModel->rowCount() || !m_listModel)
+ return 0;
+ return m_listModel->takeItem(row);
+}
+
+/*virtual*/
+void ItemRecyclingList::setItemPrototype(AbstractViewItem* prototype)
+{
+ ItemRecyclingListView::setItemPrototype(prototype);
+}
+
+void ItemRecyclingList::themeChange()
+{
+ const bool caching = listItemCaching();
+ setListItemCaching(false);
+
+ const QString iconName = Theme::p()->pixmapPath()+"contact_default_icon.svg";
+ const int count = m_listModel->rowCount();
+
+ for (int i=0; i<count; ++i)
+ {
+ RecycledListItem *ritem = m_listModel->item(i);
+ if (ritem) {
+ ListItem *item = ritem->item();
+
+ // Update default icons
+ const QString filename = item->icon(ListItem::LeftIcon)->fileName();
+ if (filename.contains("contact_default_icon")) {
+ item->icon(ListItem::LeftIcon)->setFileName(iconName);
+ }
+
+ // Update status icons
+ QString statusIcon = item->icon(ListItem::RightIcon)->fileName();
+ const int index = statusIcon.indexOf("contact_status");
+ if (index != -1) {
+ statusIcon.remove(0, index);
+ item->icon(ListItem::RightIcon)->setFileName(Theme::p()->pixmapPath()+statusIcon);
+ }
+
+ // Update fonts
+ item->setFont(Theme::p()->font(Theme::ContactName), ListItem::FirstPos);
+ item->setFont(Theme::p()->font(Theme::ContactNumber), ListItem::SecondPos);
+ item->setFont(Theme::p()->font(Theme::ContactEmail), ListItem::ThirdPos);
+
+ // Update list dividers
+ if (i%2) {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd());
+ }
+ else {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven());
+ }
+
+ // Update borders
+ item->setBorderPen(Theme::p()->listItemBorderPen());
+ item->setRounding(Theme::p()->listItemRounding());
+
+ // Update icons
+ item->icon(ListItem::LeftIcon)->setRotation(Theme::p()->iconRotation(ListItem::LeftIcon));
+ item->icon(ListItem::RightIcon)->setRotation(Theme::p()->iconRotation(ListItem::RightIcon));
+ item->icon(ListItem::LeftIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::LeftIcon));
+ item->icon(ListItem::RightIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::RightIcon));
+ item->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon));
+ item->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon));
+ }
+ }
+ updateViewContent();
+ setListItemCaching(caching);
+}
+
+void ItemRecyclingList::keyPressEvent(QKeyEvent *event)
+{
+ static QTime keyPressInterval = QTime::currentTime();
+ static qreal step = 0.0;
+ static bool repeat = false;
+ int interval = keyPressInterval.elapsed();
+
+ ScrollBar* sb = verticalScrollBar();
+ qreal currentValue = sb->sliderPosition();
+
+ if(interval < 250 ) {
+ if(!repeat) step = 0.0;
+ step = step + 2.0;
+ if(step > 100) step = 100;
+ repeat = true;
+ }
+ else {
+ step = 1.0;
+ if(m_listModel->item(0)) m_listModel->item(0)->size().height();
+ step = m_listModel->item(0)->size().height();
+ repeat = false;
+ }
+
+ if(event->key() == Qt::Key_Up ) { //Up Arrow
+ sb->setSliderPosition(currentValue - step);
+ }
+
+ if(event->key() == Qt::Key_Down ) { //Down Arrow
+ sb->setSliderPosition(currentValue + step);
+ }
+ keyPressInterval.start();
+}
+
+bool ItemRecyclingList::listItemCaching() const
+{
+ ListItemContainer *container =
+ static_cast<ListItemContainer *>(m_container);
+
+ return container->listItemCaching();
+}
+
+void ItemRecyclingList::setListItemCaching(bool enabled)
+{
+ ListItemContainer *container =
+ static_cast<ListItemContainer *>(m_container);
+ container->setListItemCaching(enabled);
+}
+
+void ItemRecyclingList::updateListItemBackgrounds(int index)
+{
+ const int itemCount = m_listModel->rowCount();
+
+ for (int i=index; i<itemCount; ++i)
+ {
+ RecycledListItem *ritem = m_listModel->item(i);
+ if (ritem) {
+ ListItem *item = ritem->item();
+ if (i%2) {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd());
+ }
+ else {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven());
+ }
+ }
+ }
+}
+
+void ItemRecyclingList::setTwoColumns(const bool enabled)
+{
+ if (twoColumns() == enabled)
+ return;
+
+ const bool caching = listItemCaching();
+ setListItemCaching(false);
+
+ m_container->setTwoColumns(enabled);
+ refreshContainerGeometry();
+
+ setListItemCaching(caching);
+}
+
+bool ItemRecyclingList::twoColumns()
+{
+ return m_container->twoColumns();
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h
new file mode 100644
index 0000000000..a69b60c9e2
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ITEMRECYCLINGLIST_H
+#define ITEMRECYCLINGLIST_H
+
+#include "listitem.h"
+#include "abstractitemview.h"
+#include "listmodel.h"
+#include "itemrecyclinglistview.h"
+#include "recycledlistitem.h"
+
+class QGraphicsWidget;
+
+class ItemRecyclingList : public ItemRecyclingListView
+{
+ Q_OBJECT
+
+public:
+ ItemRecyclingList(const int itemBuffer = 4, QGraphicsWidget * parent = 0);
+ virtual ~ItemRecyclingList();
+
+ virtual void insertItem(int index, RecycledListItem *item);
+ virtual void addItem(RecycledListItem *item);
+ virtual void clear();
+ virtual AbstractViewItem *takeItem(const int row);
+ virtual void setItemPrototype(AbstractViewItem* prototype);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual bool listItemCaching() const;
+ virtual void setListItemCaching(bool enabled);
+
+ void setTwoColumns(const bool enabled);
+ bool twoColumns();
+
+public slots:
+ void themeChange();
+
+private:
+ void updateListItemBackgrounds(int index);
+
+private:
+ Q_DISABLE_COPY(ItemRecyclingList)
+
+ ListModel *m_listModel;
+};
+
+#endif // ITEMRECYCLINGLIST_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri
new file mode 100644
index 0000000000..55b551ef8f
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri
@@ -0,0 +1,19 @@
+HEADERS += $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglist.h \
+ $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglistview.h \
+ $$ROOTDIR/tests/itemrecyclinglist/abstractitemview.h \
+ $$ROOTDIR/tests/itemrecyclinglist/abstractviewitem.h \
+ $$ROOTDIR/tests/itemrecyclinglist/recycledlistitem.h \
+ $$ROOTDIR/tests/itemrecyclinglist/listitemcontainer.h \
+ $$ROOTDIR/tests/itemrecyclinglist/abstractitemcontainer.h \
+ $$ROOTDIR/tests/itemrecyclinglist/listmodel.h
+
+SOURCES += $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglist.cpp \
+ $$ROOTDIR/tests/itemrecyclinglist/itemrecyclinglistview.cpp \
+ $$ROOTDIR/tests/itemrecyclinglist/abstractitemview.cpp \
+ $$ROOTDIR/tests/itemrecyclinglist/abstractviewitem.cpp \
+ $$ROOTDIR/tests/itemrecyclinglist/recycledlistitem.cpp \
+ $$ROOTDIR/tests/itemrecyclinglist/listitemcontainer.cpp \
+ $$ROOTDIR/tests/itemrecyclinglist/abstractitemcontainer.cpp \
+ $$ROOTDIR/tests/itemrecyclinglist/listmodel.cpp
+
+INCLUDEPATH += $$ROOTDIR/tests/itemrecyclinglist
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp
new file mode 100644
index 0000000000..5aa93256ff
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "itemrecyclinglistview.h"
+
+ItemRecyclingListView::ItemRecyclingListView(QGraphicsWidget * parent)
+ : AbstractItemView(parent), m_rootIndex()
+{
+}
+
+/*virtual*/
+ItemRecyclingListView::~ItemRecyclingListView()
+{
+}
+void ItemRecyclingListView::setCurrentRow(const int row)
+{
+ setCurrentIndex(model()->index(row,0));
+}
+
+int ItemRecyclingListView::rows() const
+{
+ if (m_model)
+ return m_model->rowCount();
+ return 0;
+}
+
+/*virtual*/
+void ItemRecyclingListView::rowsInserted(const QModelIndex &parent, int start, int end)
+{
+ if (parent == m_rootIndex) {
+ AbstractItemView::rowsInserted(parent, start, end);
+ }
+}
+
+/*virtual*/
+void ItemRecyclingListView::rowsRemoved(const QModelIndex &parent, int start, int end)
+{
+ if (parent == m_rootIndex) {
+ AbstractItemView::rowsRemoved(parent, start, end);
+ }
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h
new file mode 100644
index 0000000000..467f193604
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ITEMRECYCLINGLISTVIEW_H
+#define ITEMRECYCLINGLISTVIEW_H
+
+#include "abstractitemview.h"
+
+class ItemRecyclingListView : public AbstractItemView
+{
+public:
+ ItemRecyclingListView(QGraphicsWidget * parent = 0);
+ virtual ~ItemRecyclingListView();
+ void setCurrentRow(const int row);
+ int rows() const;
+ virtual bool listItemCaching() const = 0;
+ virtual void setListItemCaching(bool enabled) = 0;
+
+protected:
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+ void rowsRemoved(const QModelIndex &parent,int start,int end);
+
+private:
+ QModelIndex m_rootIndex;
+};
+
+#endif // ITEMRECYCLINGLISTVIEW_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp
new file mode 100644
index 0000000000..5fb2ee1a51
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "label.h"
+
+Label::Label(const QString &text, QGraphicsItem *parent)
+ : GvbWidget(parent)
+{
+ m_textItem = new QGraphicsSimpleTextItem(this);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ setContentsMargins(0, 0, 0, 0);
+ setText(text);
+ // This flag was introduced in Qt 4.6.
+ setFlag(QGraphicsItem::ItemHasNoContents, true);
+}
+
+Label::~Label()
+{
+}
+
+void Label::setText(const QString &text)
+{
+ m_textItem->setText(text);
+ prepareGeometryChange();
+}
+
+QString Label::text() const
+{
+ return m_textItem->text();
+}
+
+void Label::setFont(const QFont font)
+{
+ m_textItem->setFont(font);
+}
+
+void Label::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ GvbWidget::resizeEvent(event);
+}
+
+QSizeF Label::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+ switch (which) {
+ case Qt::MinimumSize:
+ // fall thru
+ case Qt::PreferredSize: {
+ QFontMetricsF fm(m_textItem->font());
+ return QSizeF(fm.horizontalAdvance(m_textItem->text()), fm.height());
+ }
+ default:
+ return GvbWidget::sizeHint(which, constraint);
+ }
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h
new file mode 100644
index 0000000000..2c1f14b20e
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTITEM_H
+#define TEXTITEM_H
+
+#include "gvbwidget.h"
+
+class QPainter;
+class QStyleOptionGraphicsItem;
+class QGraphicsTextItem;
+
+class Label : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+
+ Label(const QString& text, QGraphicsItem *parent = 0);
+ ~Label();
+
+public:
+
+ void setText(const QString& text);
+ QString text() const;
+ void setFont(const QFont font);
+
+private:
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+ QSizeF sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint = QSizeF()) const;
+
+private:
+ Q_DISABLE_COPY(Label)
+ QGraphicsSimpleTextItem *m_textItem;
+};
+
+#endif
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp
new file mode 100644
index 0000000000..1872bcc9d3
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QGraphicsGridLayout>
+#include <QGraphicsLinearLayout>
+#include <QGraphicsSceneMouseEvent>
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+#include "listitem.h"
+#include "theme.h"
+
+struct ItemData
+{
+ QHash<ListItem::TextPos, QString> texts;
+ QHash<ListItem::TextPos, QFont> fonts;
+ QHash<ListItem::IconItemPos, QString> icons;
+ QHash<ListItem::IconItemPos, qreal> iconRotations;
+ QHash<ListItem::IconItemPos, bool> iconSmoothTransformations;
+ QHash<ListItem::IconItemPos, bool> iconOpacityEffets;
+ QPen borderPen;
+ QBrush backgroundBrush;
+ qreal backgroundOpacity;
+ QSize rounding;
+};
+Q_DECLARE_METATYPE(ItemData);
+
+ListItem::ListItem(QGraphicsWidget *parent)
+ : GvbWidget(parent)
+ , m_txtlayout(new QGraphicsGridLayout())
+ , m_layout(new QGraphicsLinearLayout(Qt::Horizontal))
+ , m_liconlayout(new QGraphicsLinearLayout(Qt::Horizontal))
+ , m_riconlayout(new QGraphicsLinearLayout(Qt::Horizontal))
+ , m_fonts()
+ , m_borderPen(Qt::NoPen)
+ , m_backgroundBrush(QBrush())
+ , m_backgroundOpacity(1.0)
+ , m_rounding(0.0, 0.0)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ setContentsMargins(0,4,4,0);
+ m_layout->setContentsMargins(0,0,0,0);
+
+ m_txtlayout->setContentsMargins(0,8,0,8);
+ m_liconlayout->setContentsMargins(8,8,8,8);
+ m_riconlayout->setContentsMargins(0,8,4,8);
+
+ m_layout->insertItem(0, m_liconlayout);
+ m_layout->insertItem(1, m_txtlayout);
+ m_layout->insertItem(2, m_riconlayout);
+
+ m_layout->setStretchFactor(m_liconlayout, 1);
+ m_layout->setStretchFactor(m_txtlayout, 5);
+ m_layout->setStretchFactor(m_riconlayout, 1);
+
+ setFlag(QGraphicsItem::ItemClipsToShape);
+ setLayout(m_layout);
+}
+
+ListItem::~ListItem()
+{
+ if (!m_liconlayout->parentLayoutItem())
+ delete m_liconlayout;
+
+ if (!m_riconlayout->parentLayoutItem())
+ delete m_riconlayout;
+}
+
+void ListItem::setIcon(IconItem *iconItem, const IconItemPos iconPos)
+{
+ if (iconPos == LeftIcon) {
+ if (m_liconlayout->count() > 0 && m_liconlayout->itemAt(0)) {
+ delete m_liconlayout->itemAt(0);
+ m_liconlayout->addItem(iconItem);
+ } else {
+ m_liconlayout->addItem(iconItem);
+ }
+ m_liconlayout->itemAt(0)->setMaximumSize(58, 58);
+ } else if (iconPos == RightIcon) {
+ if (m_riconlayout->count() > 0 && m_riconlayout->itemAt(0)) {
+ delete m_riconlayout->itemAt(0);
+ m_riconlayout->addItem(iconItem);
+ } else {
+ m_riconlayout->addItem(iconItem);
+ }
+ m_riconlayout->itemAt(0)->setMaximumSize(22, 22);
+ }
+ m_layout->invalidate();
+}
+
+IconItem* ListItem::icon(const IconItemPos iconPos) const
+{
+ QGraphicsLayoutItem* item = 0;
+
+ if (iconPos == LeftIcon && m_liconlayout->count() > 0) {
+ item = m_liconlayout->itemAt(0);
+ }
+ else if (iconPos == RightIcon && m_riconlayout->count() > 0) {
+ item = m_riconlayout->itemAt(0);
+ }
+
+ if (item) {
+ IconItem* titem = static_cast<IconItem *>(item);
+ return titem;
+ }
+ return 0;
+}
+
+QVariant ListItem::data(int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ ItemData data;
+
+ if (text(ListItem::FirstPos).size() > 0) {
+ data.texts[ListItem::FirstPos] = text(ListItem::FirstPos);
+ data.fonts[ListItem::FirstPos] = m_fonts[ListItem::FirstPos];
+ }
+ if (text(ListItem::SecondPos).size() > 0) {
+ data.texts[ListItem::SecondPos] = text(ListItem::SecondPos);
+ data.fonts[ListItem::SecondPos] = m_fonts[ListItem::SecondPos];
+ }
+ if (text(ListItem::ThirdPos).size() > 0) {
+ data.texts[ListItem::ThirdPos] = text(ListItem::ThirdPos);
+ data.fonts[ListItem::ThirdPos] = m_fonts[ListItem::ThirdPos];
+ }
+ if (text(ListItem::LastPos).size() > 0) {
+ data.texts[ListItem::LastPos] = text(ListItem::LastPos);
+ data.fonts[ListItem::LastPos] = m_fonts[ListItem::LastPos];
+ }
+
+ if (icon(ListItem::LeftIcon)) {
+ data.icons[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->fileName();
+ data.iconRotations[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->rotation();
+ data.iconSmoothTransformations[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->isSmoothTransformationEnabled();
+ data.iconOpacityEffets[ListItem::LeftIcon] = icon(ListItem::LeftIcon)->isOpacityEffectEnabled();
+ }
+
+ if (icon(ListItem::RightIcon)) {
+ data.icons[ListItem::RightIcon] = icon(ListItem::RightIcon)->fileName();
+ data.iconRotations[ListItem::RightIcon] = icon(ListItem::RightIcon)->rotation();
+ data.iconSmoothTransformations[ListItem::RightIcon] = icon(ListItem::RightIcon)->isSmoothTransformationEnabled();
+ data.iconOpacityEffets[ListItem::RightIcon] = icon(ListItem::RightIcon)->isOpacityEffectEnabled();
+ }
+
+ data.borderPen = m_borderPen;
+ data.backgroundBrush = m_backgroundBrush;
+ data.backgroundOpacity = m_backgroundOpacity;
+ data.rounding = m_rounding;
+
+ QVariant var;
+ var.setValue(data);
+ return var;
+}
+
+void ListItem::setData(const QVariant &value, int role)
+{
+ if (role != Qt::DisplayRole)
+ return;
+
+ ItemData data = value.value<ItemData>();
+ QList<ListItem::TextPos> textkeys = data.texts.keys();
+
+ for (int i = 0; i<textkeys.count(); ++i) {
+ setText(data.texts[textkeys.at(i)], textkeys.at(i));
+ setFont(data.fonts[textkeys.at(i)], textkeys.at(i));
+ }
+
+ QList<ListItem::IconItemPos> iconkeys = data.icons.keys();
+ for (int i = 0; i<iconkeys.count(); ++i) {
+ IconItem *iconItem = icon(iconkeys.at(i));
+ if (iconItem)
+ iconItem->setFileName(data.icons[iconkeys.at(i)]);
+ else {
+ IconItem *iconItem = new IconItem(data.icons[iconkeys.at(i)], this);
+ setIcon(iconItem, iconkeys.at(i));
+ }
+ }
+
+ if (icon(ListItem::LeftIcon)) {
+ icon(ListItem::LeftIcon)->setRotation(data.iconRotations[ListItem::LeftIcon]);
+ icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(data.iconSmoothTransformations[ListItem::LeftIcon]);
+ icon(ListItem::LeftIcon)->setOpacityEffectEnabled(data.iconOpacityEffets[ListItem::LeftIcon]);
+ }
+
+ if (icon(ListItem::RightIcon)) {
+ icon(ListItem::RightIcon)->setRotation(data.iconRotations[ListItem::RightIcon]);
+ icon(ListItem::RightIcon)->setSmoothTransformationEnabled(data.iconSmoothTransformations[ListItem::RightIcon]);
+ icon(ListItem::RightIcon)->setOpacityEffectEnabled(data.iconOpacityEffets[ListItem::RightIcon]);
+ }
+
+ m_borderPen = data.borderPen;
+ m_backgroundBrush = data.backgroundBrush;
+ m_backgroundOpacity = data.backgroundOpacity;
+ m_rounding = data.rounding;
+}
+
+void ListItem::setText(const QString str, const TextPos position)
+{
+ QGraphicsLayoutItem * item = 0;
+
+ if (m_txtlayout->rowCount() > position && position >= 0)
+ item = m_txtlayout->itemAt(position, 0);
+
+ if (!item) {
+ Label *label = new Label(str,this);
+ m_txtlayout->addItem(label, position, 0);
+ if (m_fonts.contains(position))
+ label->setFont(m_fonts[position]);
+ } else {
+ Label *titem = static_cast<Label *>(item);
+ titem->setText(str);
+ }
+}
+
+void ListItem::setFont(const QFont font, const TextPos position)
+{
+ m_fonts.insert(position, font);
+ QGraphicsLayoutItem * item = 0;
+
+ if (m_txtlayout->rowCount() > position && position >= 0)
+ item = m_txtlayout->itemAt(position, 0);
+
+ if (item) {
+ Label *titem = static_cast<Label *>(item);
+ titem->setFont(font);
+ }
+}
+
+QString ListItem::text(const TextPos position) const
+{
+ QGraphicsLayoutItem * item = 0;
+
+ if (m_txtlayout->rowCount() > position && position >= 0)
+ item = m_txtlayout->itemAt(position, 0);
+
+ if (item) {
+ Label *titem = static_cast<Label *>(item);
+ return titem->text();
+ }
+ return "";
+}
+
+void ListItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
+{
+ const int penWidth = m_borderPen.width();
+ QRectF r = rect();
+ r.adjust(penWidth, penWidth, -penWidth, -penWidth);
+
+ if (m_borderPen != Qt::NoPen) {
+ painter->setPen(m_borderPen);
+ painter->drawRoundedRect(r, m_rounding.width(), m_rounding.height());
+ }
+
+ if (m_backgroundBrush != Qt::NoBrush) {
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(m_backgroundBrush);
+ painter->setOpacity(m_backgroundOpacity);
+ painter->drawRoundedRect(r, m_rounding.width(), m_rounding.height());
+ }
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h
new file mode 100644
index 0000000000..4f033803ac
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LISTITEM_H
+#define LISTITEM_H
+
+#include <QPen>
+#include "iconitem.h"
+#include "label.h"
+#include "gvbwidget.h"
+
+class QGraphicsGridLayout;
+class QGraphicsLinearLayout;
+class QGraphicsSceneMouseEvent;
+class QGraphicsItem;
+
+class ListItem : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+
+ enum TextPos {
+ FirstPos = 0,
+ SecondPos = 1,
+ ThirdPos = 2,
+ LastPos = 3
+ };
+
+ enum IconItemPos {
+ LeftIcon = 0,
+ RightIcon = 1
+ };
+
+ ListItem(QGraphicsWidget *parent = 0);
+ virtual ~ListItem();
+
+ void setIcon(IconItem *iconItem, const IconItemPos iconPos);
+ IconItem* icon(const IconItemPos position) const;
+ void setText(const QString str, const TextPos position);
+ QString text(const TextPos position) const;
+ void setFont(const QFont font, const TextPos position);
+
+ QVariant data(int role = Qt::DisplayRole) const;
+ void setData(const QVariant &value, int role = Qt::DisplayRole);
+
+ void setBorderPen(const QPen pen) { m_borderPen = pen; }
+ void setBackgroundBrush(const QBrush brush) { m_backgroundBrush = brush; }
+ void setBackgroundOpacity(const qreal opacity) { m_backgroundOpacity = opacity; }
+ void setRounding(const QSize rounding) { m_rounding = rounding; }
+
+protected:
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+private:
+ Q_DISABLE_COPY(ListItem)
+ QGraphicsGridLayout *m_txtlayout;
+ QGraphicsLinearLayout *m_layout;
+ QGraphicsLinearLayout *m_liconlayout;
+ QGraphicsLinearLayout *m_riconlayout;
+ QHash<TextPos, QFont> m_fonts;
+
+ QPen m_borderPen;
+ QBrush m_backgroundBrush;
+ qreal m_backgroundOpacity;
+ QSize m_rounding;
+};
+
+#endif // LISTITEM_H
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp
new file mode 100644
index 0000000000..0e4520d0a8
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsItem>
+#include <QPainter>
+#include <QDebug>
+#include "listitemcache.h"
+
+ListItemCache::ListItemCache()
+{
+}
+
+ListItemCache::~ListItemCache()
+{
+ QPixmapCache::remove(m_cacheKey);
+}
+
+void ListItemCache::draw(QPainter * painter)
+{
+ QRectF irect = sourceBoundingRect(Qt::LogicalCoordinates);
+ QRectF vrect = painter->clipPath().boundingRect();
+
+ if (vrect.intersects(irect)) {
+ QRectF newVisibleRect = irect.intersected(vrect);
+ QPixmap pixmap;
+
+ if (!QPixmapCache::find(m_cacheKey, &pixmap) ||
+ m_visibleRect.toRect() != newVisibleRect.toRect()) {
+ //qDebug() << "ListItemCache: caching" << m_visibleRect
+ // << "->" << newVisibleRect;
+
+ pixmap = QPixmap(sourceBoundingRect().toRect().size());
+ pixmap.fill(Qt::transparent);
+
+ QPainter pixmapPainter(&pixmap);
+ drawSource(&pixmapPainter);
+ pixmapPainter.end();
+ m_cacheKey = QPixmapCache::insert(pixmap);
+
+ m_visibleRect = newVisibleRect;
+ }
+
+ //qDebug() << "ListItemCache: blitting" << m_visibleRect;
+ painter->drawPixmap(0, 0, pixmap);
+ }
+}
+
+void ListItemCache::sourceChanged(ChangeFlags)
+{
+ QPixmapCache::remove(m_cacheKey);
+}
+
+
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h
new file mode 100644
index 0000000000..ba35023bbc
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LISTITEMCACHE_H
+#define LISTITEMCACHE_H
+
+#include <QGraphicsEffect>
+#include <QPixmapCache>
+
+class ListItemCache : public QGraphicsEffect
+{
+ Q_OBJECT
+
+public:
+
+ ListItemCache();
+ ~ListItemCache();
+
+public: // QGraphicsEffect
+
+ void draw(QPainter *painter);
+ void sourceChanged(ChangeFlags flags);
+
+private:
+
+ QPixmapCache::Key m_cacheKey;
+ QRectF m_visibleRect;
+};
+
+#endif // LISTITEMCACHE_H
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp
new file mode 100644
index 0000000000..496919214d
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmath.h>
+#include <QGraphicsLinearLayout>
+#include <QGraphicsScene>
+
+#include "listitemcontainer.h"
+#include "abstractviewitem.h"
+
+#include "recycledlistitem.h"
+#include "listitemcache.h"
+#include "itemrecyclinglist.h"
+
+ListItemContainer::ListItemContainer(int bufferSize, ItemRecyclingList *view, QGraphicsWidget *parent)
+ : AbstractItemContainer(bufferSize, parent)
+ , m_view(view)
+ , m_layout(new QGraphicsLinearLayout(Qt::Vertical))
+ , m_listItemCaching(false)
+{
+ setContentsMargins(0,0,0,0);
+ m_layout->setContentsMargins(0,0,0,0);
+ m_layout->setSpacing(0);
+ setLayout(m_layout);
+}
+
+/*virtual*/
+ListItemContainer::~ListItemContainer()
+{
+ setListItemCaching(false);
+ for (int i = 0; i < m_items.count(); ++i) {
+ m_layout->removeItem(m_items.at(i));
+ m_items.at(i)->setParentItem(0);
+ }
+ qDeleteAll(m_items);
+ m_items.clear();
+}
+
+bool ListItemContainer::listItemCaching() const
+{
+ return m_listItemCaching;
+}
+
+void ListItemContainer::setListItemCaching(const bool enabled)
+{
+ if (m_listItemCaching == enabled)
+ return;
+
+ m_listItemCaching = enabled;
+
+ const int itemCount = m_layout->count();
+
+ for (int i = 0; i < itemCount; ++i)
+ setListItemCaching(enabled, i);
+}
+
+/*virtual*/
+void ListItemContainer::adjustVisibleContainerSize(const QSizeF &size)
+{
+ m_layout->setPreferredWidth(size.width());
+}
+
+/*virtual*/
+void ListItemContainer::addItemToVisibleLayout(int index, AbstractViewItem *item)
+{
+ m_layout->insertItem(index,item);
+
+ setListItemCaching(m_listItemCaching, index);
+}
+
+/*virtual*/
+void ListItemContainer::removeItemFromVisibleLayout(AbstractViewItem *item)
+{
+ m_layout->removeItem(item);
+
+ RecycledListItem *recycledItem = static_cast<RecycledListItem*>(item);
+
+ if (!recycledItem)
+ return;
+
+ ListItem *listItem = recycledItem->item();
+
+ setListItemCaching(false, listItem);
+}
+
+/*virtual*/
+int ListItemContainer::maxItemCountInItemBuffer() const
+{
+ int count = AbstractItemContainer::maxItemCountInItemBuffer();
+
+ if (count > 0) {
+ int currentItemCount = m_items.count();
+ qreal heightOfOneItem = 0;
+ if (currentItemCount > 0)
+ {
+ heightOfOneItem = m_layout->effectiveSizeHint(Qt::PreferredSize).height() / currentItemCount;
+ }
+ int guess = 0;
+ if( heightOfOneItem <= 0 ) {
+ if (m_prototype) {
+ heightOfOneItem = m_prototype->effectiveSizeHint(Qt::PreferredSize).height();
+ }
+ else
+ heightOfOneItem = 50; // TODO magic number, do we have better guess if prototype is not set?
+ }
+ if (heightOfOneItem > 0) {
+ guess = qCeil(m_itemView->boundingRect().height() / heightOfOneItem) + m_bufferSize;
+
+ if (guess < currentItemCount) {
+ if( guess > currentItemCount-2) { // TODO magic number here, Can we use buffer size?
+ guess = currentItemCount;
+ }
+ }
+ }
+ count = qMin(guess, count);
+ }
+ return count;
+}
+
+void ListItemContainer::setListItemCaching(const bool enabled, const int index)
+{
+ RecycledListItem *recycledItem = static_cast<RecycledListItem*>(m_layout->itemAt(index));
+
+ if (!recycledItem)
+ return;
+
+ ListItem *listItem = recycledItem->item();
+
+ if (!listItem)
+ return;
+
+ setListItemCaching(enabled, listItem);
+}
+
+void ListItemContainer::setListItemCaching(const bool enabled, ListItem *listItem)
+{
+ if (!listItem)
+ return;
+
+ // Deletes the effect.
+ listItem->setGraphicsEffect(0);
+
+ if (enabled) {
+ ListItemCache* cache = new ListItemCache;
+ Q_ASSERT(!listItem->graphicsEffect());
+ listItem->setGraphicsEffect(cache);
+ }
+}
+
+void ListItemContainer::setTwoColumns(const bool twoColumns)
+{
+ AbstractItemContainer::setTwoColumns(twoColumns);
+
+ if (!m_layout->isActivated())
+ m_layout->activate();
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h
new file mode 100644
index 0000000000..62c9450c38
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LISTITEMCONTAINER_H
+#define LISTITEMCONTAINER_H
+
+#include <QGraphicsWidget>
+#include <QColor>
+
+#include "abstractitemcontainer.h"
+
+class QGraphicsLinearLayout;
+class AbstractViewItem;
+class ListItemCache;
+class ListItem;
+class ItemRecyclingList;
+
+class ListItemContainer : public AbstractItemContainer
+{
+ Q_OBJECT
+
+public:
+ ListItemContainer(int bufferSize, ItemRecyclingList *view, QGraphicsWidget *parent=0);
+ virtual ~ListItemContainer();
+
+ virtual void setTwoColumns(const bool twoColumns);
+
+ bool listItemCaching() const;
+ void setListItemCaching(const bool enabled);
+ virtual void setListItemCaching(const bool enabled, const int index);
+
+protected:
+
+ virtual void addItemToVisibleLayout(int index, AbstractViewItem *item);
+ virtual void removeItemFromVisibleLayout(AbstractViewItem *item);
+
+ virtual void adjustVisibleContainerSize(const QSizeF &size);
+ virtual int maxItemCountInItemBuffer() const;
+
+private:
+ Q_DISABLE_COPY(ListItemContainer)
+
+ ItemRecyclingList *m_view;
+ QGraphicsLinearLayout *m_layout;
+
+ void setListItemCaching(const bool enabled, ListItem *listItem);
+ bool m_listItemCaching;
+};
+
+#endif // LISTITEMCONTAINER_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp
new file mode 100644
index 0000000000..fe87a2abc4
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "listmodel.h"
+#include "recycledlistitem.h"
+
+ListModel::ListModel(QObject *parent)
+ : QAbstractListModel(parent)
+ , m_items()
+{
+
+}
+
+ListModel::~ListModel()
+{
+ qDeleteAll(m_items);
+ m_items.clear();
+}
+
+int ListModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+ return m_items.count();
+}
+
+QVariant ListModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (index.row() >= m_items.size() || index.row() < 0)
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return QVariant::fromValue(m_items.at(index.row())->data(role));
+ default:
+ return QVariant();
+ }
+}
+
+bool ListModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ // TODO implement if we like to edit list items
+ Q_UNUSED(index)
+ Q_UNUSED(value)
+ Q_UNUSED(role)
+ return false;
+}
+
+void ListModel::clear()
+{
+ m_items.clear();
+ reset();
+}
+
+QModelIndex ListModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (hasIndex(row, column, parent))
+ return createIndex(row, column, m_items.at(row));
+
+ return QModelIndex();
+}
+
+void ListModel::insert(int row, RecycledListItem *item)
+{
+ if (item)
+ item->setModel(this);
+ if (!item || m_items.contains(item) ) {
+ return;
+ }
+ if (row < 0)
+ row = 0;
+ else if (row > m_items.count())
+ row = m_items.count();
+ beginInsertRows(QModelIndex(), row, row);
+ m_items.insert(row, item);
+ endInsertRows();
+}
+
+void ListModel::appendRow(RecycledListItem *item)
+{
+ if (!item) return;
+ item->setModel(this);
+ insert(rowCount(),item);
+}
+
+RecycledListItem *ListModel::item(const int row) const
+{
+ if (row < 0 || row > m_items.count())
+ return 0;
+ return m_items.at(row);
+}
+
+RecycledListItem *ListModel::takeItem(const int row)
+{
+ if (row < 0 || row >= m_items.count())
+ return 0;
+
+ beginRemoveRows(QModelIndex(), row, row);
+ RecycledListItem *item = m_items.takeAt(row);
+ endRemoveRows();
+
+ return item;
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h
new file mode 100644
index 0000000000..623c90dedc
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LISTMODEL_H
+#define LISTMODEL_H
+
+#include <QAbstractListModel>
+
+class RecycledListItem;
+class ListItemCache;
+
+class ListModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+
+ ListModel(QObject *parent = 0);
+ ~ListModel();
+
+public:
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+
+ void insert(const int row, RecycledListItem *item);
+ void appendRow(RecycledListItem *item);
+
+ void clear();
+
+ RecycledListItem *item(const int row) const;
+
+ RecycledListItem *takeItem(const int row);
+
+private:
+ Q_DISABLE_COPY(ListModel)
+ QList<RecycledListItem *> m_items;
+};
+
+#endif // LISTMODEL_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp
new file mode 100644
index 0000000000..6e09a09d81
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsSceneResizeEvent>
+#include <QGraphicsGridLayout>
+#include <QGraphicsLinearLayout>
+#include <QTimer>
+#include "listwidget.h"
+
+ListWidget::ListWidget(QGraphicsWidget * parent)
+ : GvbWidget(parent),
+ m_layout(new QGraphicsLinearLayout(Qt::Vertical)),
+ m_listView(new SimpleListView(this))
+{
+ //listView->setViewport(listView->content());
+ //listView->content()->setParentItem(listView);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setContentsMargins(0,0,0,0);
+ m_layout->setContentsMargins(0,0,0,0);
+ m_listView->setContentsMargins(0,0,0,0);
+ m_layout->addItem(m_listView);
+ setLayout(m_layout);
+
+ m_scroller.setScrollable(m_listView);
+ m_listView->installEventFilter(&m_scroller);
+ m_listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+}
+
+ListWidget::~ListWidget()
+{
+
+}
+
+void ListWidget::addItem(QGraphicsWidget *item)
+{
+ m_listView->addItem(item);
+}
+
+void ListWidget::insertItem(int index, QGraphicsWidget *item)
+{
+ m_listView->insertItem(index, item);
+}
+
+QGraphicsWidget* ListWidget::takeItem(int row)
+{
+ return m_listView->takeItem(row);
+}
+
+QGraphicsWidget* ListWidget::itemAt(int row)
+{
+ return m_listView->itemAt(row);
+}
+
+/* virtual */
+void ListWidget::resizeEvent( QGraphicsSceneResizeEvent * event )
+{
+ QGraphicsWidget::resizeEvent(event);
+}
+
+int ListWidget::itemCount() const
+{
+ if (m_listView)
+ return m_listView->itemCount();
+ return 0;
+}
+
+ScrollBar* ListWidget::verticalScrollBar() const
+{
+ if (m_listView)
+ return m_listView->verticalScrollBar();
+ return 0;
+}
+
+bool ListWidget::listItemCaching() const
+{
+ return m_listView->listItemCaching();
+}
+
+void ListWidget::setListItemCaching(bool enable)
+{
+ m_listView->setListItemCaching(enable);
+}
+
+void ListWidget::setTwoColumns(const bool twoColumns)
+{
+ m_listView->setTwoColumns(twoColumns);
+}
+
+bool ListWidget::twoColumns()
+{
+ return m_listView->twoColumns();
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h
new file mode 100644
index 0000000000..0dfd41a1c3
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LISTWIDGET_H
+#define LISTWIDGET_H
+
+#include <QGraphicsWidget>
+#include "simplelistview.h"
+#include "scroller.h"
+#include "gvbwidget.h"
+
+class AbstractViewItem;
+class QGraphicsSceneResizeEvent;
+class QGraphicsGridLayout;
+class QGraphicsLinearLayout;
+
+class ListWidget : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+ ListWidget(QGraphicsWidget * parent = 0);
+ virtual ~ListWidget();
+ void addItem(QGraphicsWidget *item);
+ void insertItem(int index, QGraphicsWidget *item);
+ QGraphicsWidget* takeItem(int row);
+ QGraphicsWidget* itemAt(int row);
+ int itemCount() const;
+ bool listItemCaching() const;
+ void setListItemCaching(bool enable);
+ ScrollBar* verticalScrollBar() const;
+
+ void setTwoColumns(const bool twoColumns);
+ bool twoColumns();
+
+protected:
+ virtual void resizeEvent( QGraphicsSceneResizeEvent * event );
+
+private:
+ Q_DISABLE_COPY(ListWidget)
+
+ QGraphicsLinearLayout *m_layout;
+ SimpleListView *m_listView;
+ Scroller m_scroller;
+};
+
+#endif
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp
new file mode 100644
index 0000000000..c8ccb60dbb
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp
@@ -0,0 +1,331 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QApplication>
+#include <QGraphicsLinearLayout>
+#ifndef QT_NO_OPENGL
+#include <QGLWidget>
+#endif
+#include <QObject>
+
+#include "button.h"
+#include "label.h"
+#include "menu.h"
+#include "topbar.h"
+#include "backgrounditem.h"
+#include "theme.h"
+#include "mainview.h"
+#include "gvbwidget.h"
+
+MainView::MainView(const bool enableOpenGL, const bool outputFps, const bool imageRendering, QWidget *parent)
+ : QGraphicsView(parent)
+ , m_scene(0)
+ , m_mainLayout(0)
+ , m_mainWidget(0)
+ , m_testWidget(0)
+ , m_imageBasedRendering(imageRendering)
+ , m_pixmapToRender(0)
+ , m_OutputFps(outputFps)
+ , m_fpsUpdated()
+ , m_Fpss()
+ , m_angle(0)
+ , m_enableOpenGL(enableOpenGL)
+{
+ construct();
+}
+
+MainView::~MainView()
+{
+ if (!m_scene->parent())
+ delete m_scene;
+
+ delete m_pixmapToRender;
+}
+
+void MainView::setTestWidget(QGraphicsWidget *testWidget)
+{
+ if (!testWidget)
+ return;
+
+ if (m_testWidget) {
+ m_mainLayout->removeItem(m_testWidget);
+ if (!m_testWidget->parent() && !m_testWidget->parentLayoutItem())
+ delete m_testWidget;
+ }
+ m_testWidget = testWidget;
+ m_mainLayout->addItem(m_testWidget);
+ resizeContent(size());
+}
+
+QGraphicsWidget *MainView::takeTestWidget()
+{
+ if (m_testWidget) {
+ m_mainLayout->removeItem(m_testWidget);
+ QGraphicsWidget *tmp = m_testWidget;
+ m_testWidget = 0;
+ return tmp;
+ }
+ return 0;
+}
+
+QGraphicsWidget *MainView::testWidget()
+{
+ return m_testWidget;
+}
+
+void MainView::setImageBasedRendering(const bool imageBasedRendering)
+{
+ m_imageBasedRendering = imageBasedRendering;
+ delete m_pixmapToRender;
+ m_pixmapToRender = 0;
+ viewport()->update();
+}
+
+bool MainView::imageBasedRendering() const
+{
+ return m_imageBasedRendering;
+}
+
+qreal MainView::fps()
+{
+ if (m_Fpss.count() <= 0)
+ updateFps();
+
+ if (m_Fpss.count() <= 0)
+ return 0.0;
+
+ qreal sum = 0;
+ int count = m_Fpss.count();
+ for (int i = 0; i<count; ++i)
+ sum += m_Fpss.at(i);
+ m_Fpss.clear();
+ fpsReset();
+ return sum/qreal(count);
+}
+
+void MainView::fpsReset()
+{
+ m_frameCount = 0;
+ m_fpsFirstTs.start();
+ m_fpsLatestTs = m_fpsFirstTs;
+ m_fpsUpdated.start();
+}
+
+void MainView::rotateContent(int angle)
+{
+ bool portrait = ((m_angle+angle)%90 == 0) && ((m_angle+angle)%180 != 0);
+ bool landscape = ((m_angle+angle)%180 == 0);
+ if (!portrait && !landscape)
+ return;
+
+ m_angle = (m_angle + angle)%360;
+
+ rotate(angle);
+
+ resizeContent(size());
+}
+
+int MainView::rotationAngle() const
+{
+ return m_angle;
+}
+
+void MainView::resizeContent(const QSize &s)
+{
+ QSizeF l_size(s);
+ QSizeF p_size(l_size.height(), l_size.width());
+ bool portrait = (m_angle%90 == 0) && (m_angle%180 != 0);
+ if (portrait) {
+ m_mainWidget->resize(p_size);
+ m_backGround->resize(p_size);
+ }
+ else {
+ m_mainWidget->resize(l_size);
+ m_backGround->resize(l_size);
+ }
+ m_menu->setPos(m_topBar->getStatusBarLocation());
+ setSceneRect(QRectF(m_mainWidget->pos(), m_mainWidget->size()));
+}
+
+void MainView::resizeEvent(QResizeEvent * event)
+{
+ QGraphicsView::resizeEvent(event);
+ resizeContent(event->size());
+}
+
+void MainView::paintEvent (QPaintEvent *event)
+{
+ if (m_imageBasedRendering) {
+ if (!m_pixmapToRender)
+ m_pixmapToRender = new QPixmap(size());
+
+ if (m_pixmapToRender->size() != size()) {
+ delete m_pixmapToRender;
+ m_pixmapToRender = new QPixmap(size());
+ }
+ QPainter p(m_pixmapToRender);
+ render(&p);
+ p.end();
+ }
+ else {
+ QGraphicsView::paintEvent(event);
+ }
+
+ if (!m_OutputFps)
+ emit repainted();
+
+ m_frameCount++;
+ m_fpsLatestTs.start();
+ if(m_fpsUpdated.elapsed() > 2000) {
+ updateFps();
+ m_fpsUpdated.start();
+ }
+}
+
+void MainView::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_F) {
+ if (isFullScreen())
+ showNormal();
+ else
+ showFullScreen();
+ }
+
+ //S60 3.x specific
+ if(m_menu->menuVisible()) {
+ m_menu->keyPressEvent(event);
+ return;
+ }
+
+ if(event->key() == 16777235 ) { //Up Arrow
+ GvbWidget* widget = qobject_cast<GvbWidget*>(m_testWidget);
+ if(widget)
+ widget->keyPressEvent(event);
+ }
+
+ if(event->key() == 16777237 ) { //Down Arrow
+ GvbWidget* widget = qobject_cast<GvbWidget*>(m_testWidget);
+ if(widget)
+ widget->keyPressEvent(event);
+ }
+
+ if(event->key() == 17825792 ) { //LSK
+ if(!m_menu->menuVisible())
+ m_menu->menuShowHide();
+ }
+
+ if(event->key() == 17825793 ) { //RSK
+ QApplication::quit();
+ }
+}
+
+void MainView::construct()
+{
+ m_scene = new QGraphicsScene;
+
+#ifndef QT_NO_OPENGL
+ if (m_enableOpenGL) {
+ qDebug() << "OpenGL enabled";
+ m_scene->setSortCacheEnabled(false);
+ setViewport(new QGLWidget);
+
+ // Qt doc says: This is the preferred update mode for
+ // viewports that do not support partial updates, such as QGLWidget...
+ setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+ } else
+#endif
+ setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+
+ setScene(m_scene);
+ m_scene->setItemIndexMethod(QGraphicsScene::NoIndex);
+
+ //setCacheMode(QGraphicsView::CacheBackground);
+ setAlignment(Qt::AlignLeft | Qt::AlignTop);
+
+ // Turn off automatic background
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ setAttribute(Qt::WA_NoBackground);
+ setAttribute(Qt::WA_NoSystemBackground);
+ setAutoFillBackground(false);
+
+ //Background
+ m_backGround = new BackgroundItem("background.svg");
+ m_scene->addItem(m_backGround);
+ m_backGround->setZValue(0);
+
+ //Menu
+ m_menu = new Menu(this);
+ m_scene->addItem(m_menu); //Add menu to the scene directly
+ m_menu->setZValue(10); //Bring to front
+
+ m_mainLayout = new QGraphicsLinearLayout(Qt::Vertical);
+ m_mainLayout->setContentsMargins(0,0,0,0);
+ m_mainLayout->setSpacing(0);
+
+ m_mainWidget = new QGraphicsWidget;
+ m_mainWidget->setLayout(m_mainLayout);
+ m_mainWidget->setZValue(1);
+ m_scene->addItem(m_mainWidget);
+
+ //Topbar
+ m_topBar = new TopBar(this, 0);
+ m_mainLayout->addItem(m_topBar);
+ m_topBar->setZValue(1);
+ connect(m_topBar, SIGNAL(clicked(bool)), m_menu, SLOT(menuShowHide()));
+
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setContentsMargins(0,0,0,0);
+ setViewportMargins(0,0,0,0);
+ setFrameShape(QFrame::NoFrame);
+
+ fpsReset();
+ m_fpsUpdated.start();
+}
+
+void MainView::updateFps()
+{
+ int msecs = m_fpsFirstTs.msecsTo(m_fpsLatestTs);
+ qreal fps = 0;
+ if (msecs > 0) {
+ fps = m_frameCount * 1000.0 / msecs;
+
+ if (m_OutputFps)
+ qDebug() << "FPS: " << fps;
+
+ m_Fpss.append(fps);
+ }
+ m_fpsFirstTs = m_fpsLatestTs;
+ m_frameCount = 0;
+}
+
+Menu *MainView::menu()
+{
+ return m_menu;
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h
new file mode 100644
index 0000000000..d7fe404023
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __MAINWINDOW_H__
+#define __MAINWINDOW_H__
+
+#include <QGraphicsView>
+#include <QTime>
+#include <QTimer>
+
+#include "settings.h"
+
+class QGraphicsScene;
+class QGraphicsLinearLayout;
+class QResizeEvent;
+class Label;
+class Menu;
+class BackgroundItem;
+class TopBar;
+
+class MainView : public QGraphicsView {
+
+Q_OBJECT
+
+public:
+ MainView(const bool enableOpenGL, const bool outputFps, const bool imageBasedRendering = false, QWidget *parent = 0);
+ ~MainView();
+
+ void setTestWidget(QGraphicsWidget *testWidget);
+ QGraphicsWidget *takeTestWidget();
+ QGraphicsWidget *testWidget();
+
+ qreal fps();
+ void fpsReset();
+ void setImageBasedRendering(const bool imageBasedRendering);
+ bool imageBasedRendering() const;
+ Menu *menu();
+ int rotationAngle() const;
+
+signals:
+ void repainted();
+
+public slots:
+ void rotateContent(int angle);
+
+protected:
+
+ virtual void resizeEvent(QResizeEvent * event);
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void wheelEvent(QWheelEvent *event) { Q_UNUSED (event); };
+
+private slots:
+ void updateFps();
+
+private:
+ void construct();
+ void resizeContent(const QSize &s);
+
+private:
+ Q_DISABLE_COPY(MainView)
+
+ QGraphicsScene *m_scene;
+ QGraphicsLinearLayout *m_mainLayout;
+ QGraphicsWidget *m_mainWidget;
+ QGraphicsWidget *m_testWidget;
+ Menu* m_menu;
+ BackgroundItem* m_backGround;
+ TopBar* m_topBar;
+
+ bool m_imageBasedRendering;
+ QPixmap *m_pixmapToRender;
+ // Used for FPS
+ int m_frameCount;
+ QTime m_fpsFirstTs;
+ QTime m_fpsLatestTs;
+ bool m_OutputFps;
+ QTime m_fpsUpdated;
+ QList<qreal> m_Fpss;
+
+ int m_angle;
+ bool m_enableOpenGL;
+};
+
+#endif //__MAINWINDOW_H__
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp
new file mode 100644
index 0000000000..1cc75d569b
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsView>
+#include <QGraphicsWidget>
+#include <QGraphicsLinearLayout>
+#include <QList>
+
+#include "button.h"
+#include "menu.h"
+#include "themeevent.h"
+#include "theme.h"
+
+static const int MinMenuItemWidth = 150;
+static const int MinMenuItemHeight = 40;
+
+Menu::Menu(QGraphicsView* parent) : QGraphicsWidget(),
+ m_Parent(parent), m_Layout(new QGraphicsLinearLayout(Qt::Vertical, this)),
+ m_ButtonContainer(0), m_isMenuVisible(false), m_currentSelectedIndex(-1)
+{
+ init();
+}
+
+Menu::~Menu()
+{
+ for(int i = 0; i < m_ButtonContainer->count(); i++ ) {
+ delete m_ButtonContainer->at(i);
+ }
+ m_ButtonContainer->clear();
+
+ delete m_ButtonContainer;
+ m_ButtonContainer = 0;
+}
+
+void Menu::init()
+{
+ m_ButtonContainer = new QList<Button*>;
+
+ m_Layout->setContentsMargins(0,0,0,0);
+ m_Layout->setSpacing(0);
+
+ setMinimumWidth(150);
+
+ setLayout(m_Layout);
+
+ connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange()));
+}
+
+Button* Menu::addMenuItem(const QString itemName, QObject* receiver, const char* member)
+{
+ Button* button = new Button(itemName ,this);
+ button->setVisible(m_isMenuVisible);
+ connect(button, SIGNAL(clicked(bool)), receiver, member);
+ connect(button, SIGNAL(clicked(bool)), this, SLOT(menuShowHide()));
+ m_ButtonContainer->append(button);
+ button->setMinimumWidth(MinMenuItemWidth);
+ button->setMinimumHeight(MinMenuItemHeight);
+ return button;
+}
+
+void Menu::menuShowHide()
+{
+ m_isMenuVisible ? menuHide() : menuShow();
+ m_isMenuVisible = !m_isMenuVisible;
+}
+
+void Menu::menuShow()
+{
+ for(int i = 0; i < m_ButtonContainer->count(); i++) {
+ Button* button = m_ButtonContainer->at(i);
+ m_Layout->addItem(button);
+ button->show();
+ }
+}
+
+void Menu::menuHide()
+{
+ for(int i = 0; i < m_ButtonContainer->count(); i++) {
+ Button* button = m_ButtonContainer->at(i);
+ button->select(false);
+ button->hide();
+ m_Layout->removeItem(button);
+ }
+ m_currentSelectedIndex = -1;
+}
+
+void Menu::themeChange()
+{
+ QPixmap pixmap = Theme::p()->pixmap("status_field_middle.svg",
+ QSize(MinMenuItemWidth, MinMenuItemHeight));
+
+ for(int i = 0; i < m_ButtonContainer->count(); i++) {
+ Button* button = m_ButtonContainer->at(i);
+ button->setBackground(pixmap);
+ }
+ update();
+}
+
+void Menu::keyPressEvent(QKeyEvent *event)
+{
+ //S60 3.x specific
+ if(event->key() == 16777235 ) { //Up Arrow
+ if(m_currentSelectedIndex > 0) { //One step up
+ Button* button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(false);
+ button->update();
+
+ m_currentSelectedIndex--;
+ button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(true);
+ button->update();
+ }
+ else { //Jump to bottom
+ if(m_currentSelectedIndex >= 0) {
+ Button* button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(false);
+ button->update();
+ }
+ m_currentSelectedIndex = m_ButtonContainer->count() -1;
+ if(m_currentSelectedIndex >= 0) {
+ Button* button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(true);
+ button->update();
+ }
+ }
+ }
+
+ if(event->key() == 16777237 ) { //Down Arrow
+ if (m_currentSelectedIndex < m_ButtonContainer->count()-1) { //One step down
+ if(m_currentSelectedIndex >= 0) {
+ Button* button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(false);
+ button->update();
+ }
+ m_currentSelectedIndex++;
+ Button* button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(true);
+ button->update();
+ }
+ else { //Jump to top
+ if(m_currentSelectedIndex >= 0) {
+ Button* button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(false);
+ button->update();
+ m_currentSelectedIndex = 0;
+ button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->select(true);
+ button->update();
+ }
+ }
+ }
+
+ if(event->key() == 17825792 || event->key() == 16842752 || //LSK, center key or enter
+ event->key() == 16777221 ) {
+ if(m_currentSelectedIndex >= 0) {
+ Button* button = m_ButtonContainer->at(m_currentSelectedIndex);
+ button->click();
+ }
+ }
+
+ if(event->key() == 17825793 ) { //RSK
+ menuShowHide();
+ }
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h
new file mode 100644
index 0000000000..074d5b9d95
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __MENU_H__
+#define __MENU_H__
+
+#include <QGraphicsWidget>
+#include <QList>
+
+class QGraphicsView;
+class QGraphicsLinearLayout;
+class Button;
+
+class Menu : public QGraphicsWidget
+{
+ Q_OBJECT
+public:
+ Menu(QGraphicsView* parent);
+ ~Menu();
+
+public:
+ Button* addMenuItem(const QString itemName, QObject* receiver, const char* member);
+ inline bool menuVisible() { return m_isMenuVisible; }
+ virtual void keyPressEvent(QKeyEvent *event);
+
+public slots:
+ void themeChange();
+
+public slots:
+ void menuShowHide();
+
+private:
+ void init();
+ void menuShow();
+ void menuHide();
+
+private:
+ Q_DISABLE_COPY(Menu)
+ QGraphicsView* m_Parent;
+ QGraphicsLinearLayout* m_Layout;
+ QList<Button*>* m_ButtonContainer;
+ bool m_isMenuVisible;
+ int m_currentSelectedIndex;
+};
+
+#endif // __MENU_H__
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp
new file mode 100644
index 0000000000..c0aed25abb
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsGridLayout>
+#include <QDebug>
+
+#include "recycledlistitem.h"
+#include "listmodel.h"
+
+static const int MinItemHeight = 70;
+static const int MinItemWidth = 276;
+
+RecycledListItem::RecycledListItem(QGraphicsWidget *parent)
+ : AbstractViewItem(parent),
+ m_item(new ListItem(this)),
+ m_item2(0),
+ m_model(0),
+ m_layout(new QGraphicsGridLayout())
+{
+ m_item->setMinimumWidth(MinItemWidth);
+ setContentsMargins(0,0,0,0);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_layout->addItem(m_item, 0, 0);
+ setLayout(m_layout);
+ m_layout->setContentsMargins(0,0,0,0);
+ m_layout->setSpacing(0);
+ m_layout->setHorizontalSpacing(0.0);
+ m_layout->setVerticalSpacing(0.0);
+}
+
+RecycledListItem::~RecycledListItem()
+{
+}
+
+void RecycledListItem::setModel(QAbstractItemModel *model)
+{
+ m_model = model;
+}
+
+/*virtual*/
+AbstractViewItem *RecycledListItem::newItemInstance()
+{
+ RecycledListItem* item = new RecycledListItem();
+ return item;
+}
+
+QSizeF RecycledListItem::effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+ QSizeF s = m_item->effectiveSizeHint(which,constraint);
+ if (m_item2)
+ s.setWidth(s.width()*2);
+ if (s.height()<MinItemHeight)
+ s.setHeight(MinItemHeight);
+ return s;
+}
+
+QVariant RecycledListItem::data(int role) const
+{
+ if (m_item && role == Qt::DisplayRole)
+ return m_item->data();
+
+ return QVariant();
+}
+
+void RecycledListItem::setData(const QVariant &value, int role)
+{
+ if (m_item && role == Qt::DisplayRole) {
+ m_item->setData(value);
+ if (m_item2) {
+ m_item2->setData(value);
+ }
+ }
+}
+
+/*virtual*/
+void RecycledListItem::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ AbstractViewItem::resizeEvent(event);
+}
+
+void RecycledListItem::updateItemContents()
+{
+ AbstractViewItem::updateItemContents();
+ if (m_model && m_index.isValid())
+ setData(m_model->data(m_index,Qt::DisplayRole), Qt::DisplayRole);
+}
+
+void RecycledListItem::setTwoColumns(const bool enabled)
+{
+ if (m_item2 && enabled)
+ return;
+
+ if (enabled) {
+ m_item2 = new ListItem();
+ m_item2->setMinimumWidth(MinItemWidth);
+ m_layout->addItem(m_item2, 0, 1);
+ updateItemContents();
+ }
+ else {
+ if (m_layout->count() > 1) {
+ m_layout->removeAt(1);
+ }
+ delete m_item2;
+ m_item2 = 0;
+ }
+
+ if (!m_layout->isActivated())
+ m_layout->activate();
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h
new file mode 100644
index 0000000000..021a8b8902
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RECYCLEDLISTITEM_H
+#define RECYCLEDLISTITEM_H
+
+#include "abstractviewitem.h"
+
+class ListItem;
+class QGraphicsWidget;
+class QGraphicsGridLayout;
+
+class RecycledListItem : public AbstractViewItem
+{
+ Q_OBJECT
+public:
+ RecycledListItem(QGraphicsWidget *parent=0);
+ virtual ~RecycledListItem();
+
+ virtual void setModel(QAbstractItemModel *model);
+
+ virtual AbstractViewItem *newItemInstance();
+ virtual void updateItemContents();
+
+ virtual QVariant data(int role) const;
+ virtual void setData(const QVariant &value, int role = Qt::DisplayRole);
+
+ ListItem *item() { return m_item; }
+
+ void setTwoColumns(const bool enabled);
+
+protected:
+ virtual QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+ virtual void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+private:
+ Q_DISABLE_COPY(RecycledListItem)
+
+ ListItem *m_item;
+ ListItem *m_item2;
+ QAbstractItemModel *m_model;
+ QGraphicsGridLayout *m_layout;
+};
+
+#endif // RECYCLEDLISTITEM_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h
new file mode 100644
index 0000000000..b03f09048a
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __RESOURCEMONINTERFACE_H__
+#define __RESOURCEMONINTERFACE_H__
+
+class ResourceMonitorInterface
+{
+public:
+ struct MemoryAllocation
+ {
+ int allocatedInAppThread;
+ int numberOfAllocatedCellsInAppThread;
+ int availableMemoryInAppThreadHeap;
+ qint64 availableMemoryInSystem;
+ qint64 totalMemoryInSystem;
+ MemoryAllocation() :
+ allocatedInAppThread(0),
+ numberOfAllocatedCellsInAppThread(0),
+ availableMemoryInAppThreadHeap(0),
+ availableMemoryInSystem(0),
+ totalMemoryInSystem(0)
+ {}
+ };
+
+ struct CpuUsage
+ {
+ qreal systemUsage;
+ qreal appTreadUsage;
+ CpuUsage() :
+ systemUsage(0.0),
+ appTreadUsage(0.0)
+ {}
+ };
+
+public:
+ virtual ~ResourceMonitorInterface() {}
+
+public:
+ //for symbian, prepares the resource monitor for data capture, opens handle to ekern null
+ //thread and sets initial values
+ virtual bool Prepare(QString applicationThreadName) = 0;
+
+ //functions for CPU load and memory - Call Prepare before calling these
+ virtual CpuUsage CPULoad()=0;
+ virtual MemoryAllocation MemoryLoad()=0;
+
+ virtual void BeginMeasureMemoryLoad()=0;
+ virtual MemoryAllocation EndMeasureMemoryLoad()=0;
+
+ virtual void BeginMeasureCPULoad()=0;
+ virtual CpuUsage EndMeasureCPULoad()=0;
+
+};
+
+Q_DECLARE_INTERFACE(ResourceMonitorInterface,
+ "com.trolltech.Plugin.ResourceMonitorInterface/1.0");
+
+#endif //__RESOURCEMONINTERFACE_H__
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp
new file mode 100644
index 0000000000..81f123e2b7
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsWidget>
+#include <QPainter>
+#include <QGraphicsSceneMouseEvent>
+#include <QDebug>
+
+#include "scrollbar.h"
+#include "theme.h"
+
+class ScrollBarPrivate {
+ Q_DECLARE_PUBLIC(ScrollBar)
+
+public:
+
+ ScrollBarPrivate(Qt::Orientation orientation, ScrollBar *scrollBar)
+ : orientation(orientation)
+ , sliderPosition(0.0)
+ , sliderSize(0.0)
+ , sliderDown(false)
+ , q_ptr(scrollBar)
+ {
+ construct();
+ }
+
+ void themeChange()
+ {
+ construct();
+ updateSlider();
+ }
+
+ void construct()
+ {
+ scrollerPixmap = Theme::p()->pixmap("scroll.svg");
+ scrollBarPixmap = Theme::p()->pixmap("scrollbar.svg");
+
+ if (orientation == Qt::Horizontal) {
+ scrollerPixmap = scrollerPixmap.transformed(QTransform().rotate(90));
+ scrollBarPixmap = scrollBarPixmap.transformed(QTransform().rotate(90));
+ }
+ }
+
+ void setSliderPosition(qreal pos)
+ {
+ if (pos < 0.0)
+ pos = 0.0;
+
+ if (pos > sliderSize)
+ pos = sliderSize;
+
+ sliderPosition = pos;
+
+ if (!qFuzzyCompare(pos, sliderPosition))
+ updateSlider();
+ }
+
+ void updateSlider()
+ {
+ QRectF oldSlider = slider;
+ slider = q_func()->boundingRect();
+
+ qreal x = 0;
+ qreal y = 0;
+ qreal w = scrollerPixmap.width();
+ qreal h = scrollerPixmap.height();
+
+ //Adjust the scrollBar in relation to the scroller
+
+ if (orientation == Qt::Horizontal) {
+ qreal scrollBarHeight = scrollBarPixmap.height();
+
+ if (h > scrollBarHeight) {
+ slider.setTop((h - scrollBarHeight)/2.0);
+ slider.setHeight(scrollBarHeight);
+ }
+ } else {
+ qreal scrollBarWidth = scrollBarPixmap.width();
+
+ if (w > scrollBarWidth) {
+ slider.setLeft((w - scrollBarWidth)/2.0);
+ }
+ slider.setWidth(scrollBarWidth);
+ }
+
+ if(oldSlider != slider && (slider.size().width() > 0 &&slider.size().height() > 0 )) {
+ scrollBarPixmap = Theme::p()->pixmap("scrollbar.svg", slider.size().toSize());
+ }
+ cursor = QRectF(x, y, w, h);
+
+ if (orientation == Qt::Horizontal) {
+ qreal dx = qreal(int(sliderPosition)) * (slider.width() - cursor.width()) / sliderSize;
+ cursor.translate(dx, 0.0);
+ } else {
+ qreal dy = qreal(int(sliderPosition)) * (slider.height() - cursor.height()) / sliderSize;
+ cursor.translate(0.0, dy);
+ }
+ }
+
+ Qt::Orientation orientation;
+ qreal sliderPosition;
+ qreal sliderSize;
+
+ QPointF pressPos;
+ bool sliderDown;
+
+ QRectF slider;
+ QRectF cursor;
+ QPixmap scrollerPixmap;
+ QPixmap scrollBarPixmap;
+
+ ScrollBar *q_ptr;
+};
+
+ScrollBar::ScrollBar(Qt::Orientation orientation, QGraphicsWidget *parent)
+ : QGraphicsWidget(parent)
+ , d_ptr(new ScrollBarPrivate(orientation, this))
+{
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
+ setContentsMargins(0, 0, 0, 0);
+
+ connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange()));
+}
+
+ScrollBar::~ScrollBar()
+{
+ delete d_ptr;
+}
+
+qreal ScrollBar::sliderSize() const
+{
+ Q_D(const ScrollBar);
+ return d->sliderSize;
+}
+
+void ScrollBar::setSliderSize(const qreal s)
+{
+ Q_D(ScrollBar);
+ d->sliderSize = s;
+}
+
+void ScrollBar::setSliderPosition(qreal pos)
+{
+ Q_D(ScrollBar);
+
+ d->setSliderPosition(pos);
+ prepareGeometryChange();
+ emit sliderPositionChange(d->sliderPosition);
+}
+
+qreal ScrollBar::sliderPosition() const
+{
+ Q_D(const ScrollBar);
+ return d->sliderPosition;
+}
+
+bool ScrollBar::sliderDown() const
+{
+ Q_D(const ScrollBar);
+ return d->sliderDown;
+}
+
+void ScrollBar::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_D(ScrollBar);
+ Q_UNUSED(widget);
+ Q_UNUSED(option);
+
+ d->updateSlider();
+
+ QRect sliderRect = d->slider.toRect();
+ painter->drawPixmap(sliderRect.topLeft(), d->scrollBarPixmap);
+
+ QRect cursorRect = d->cursor.toRect();
+ painter->drawPixmap(cursorRect.topLeft(), d->scrollerPixmap);
+}
+
+QSizeF ScrollBar::sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint) const
+{
+ Q_D(const ScrollBar);
+
+ QSizeF s;
+
+ if (d->orientation == Qt::Horizontal)
+ s = QSizeF(-1, qMax(d->scrollBarPixmap.height(), d->scrollerPixmap.height()));
+ else
+ s = QSizeF(qMax(d->scrollBarPixmap.width(), d->scrollerPixmap.width()), -1);
+
+ switch (which)
+ {
+ case Qt::MinimumSize:
+ return s;
+
+ case Qt::MaximumSize:
+ return s;
+
+ default:
+ return QGraphicsWidget::sizeHint(which, constraint);
+ }
+}
+
+void ScrollBar::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(ScrollBar);
+
+ d->updateSlider();
+
+ if (d->cursor.contains(event->pos())) {
+ d->sliderDown = true;
+ d->pressPos = event->pos();
+ emit sliderPressed();
+ }
+}
+
+void ScrollBar::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(ScrollBar);
+ Q_UNUSED(event);
+
+ d->sliderDown = false;
+}
+
+void ScrollBar::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(ScrollBar);
+
+ if (!d->sliderDown)
+ return;
+
+ if (d->orientation == Qt::Horizontal) {
+ qreal f = (event->pos().x() - d->pressPos.x())/(d->slider.width() - d->cursor.width());
+ qreal dx = f * d->sliderSize;
+
+ d->setSliderPosition(d->sliderPosition + dx);
+ } else {
+ qreal f = (event->pos().y() - d->pressPos.y())/(d->slider.height() - d->cursor.height());
+ qreal dy = f * d->sliderSize;
+
+ d->setSliderPosition(d->sliderPosition + dy);
+ }
+
+ d->pressPos = event->pos();
+
+ prepareGeometryChange();
+ emit sliderPositionChange(d->sliderPosition);
+}
+
+void ScrollBar::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ QGraphicsWidget::resizeEvent(event);
+}
+
+void ScrollBar::themeChange()
+{
+ Q_D(ScrollBar);
+ d->themeChange();
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h
new file mode 100644
index 0000000000..966052676c
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCROLLBAR_H
+#define SCROLLBAR_H
+
+#include <QGraphicsWidget>
+#include <QPixmap>
+
+class ScrollBarPrivate;
+
+class ScrollBar : public QGraphicsWidget
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(ScrollBar)
+
+public:
+
+ ScrollBar(Qt::Orientation orientation, QGraphicsWidget *parent=0);
+ virtual ~ScrollBar();
+
+public:
+
+ bool sliderDown() const;
+ qreal sliderPosition() const;
+ qreal sliderSize() const;
+ void setSliderSize(const qreal s);
+
+signals:
+
+ void sliderPressed();
+
+ void sliderPositionChange(qreal position);
+
+public slots:
+
+ void setSliderPosition(qreal pos);
+ void themeChange();
+
+private:
+
+ void paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget);
+
+ QSizeF sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint = QSizeF()) const;
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+private:
+ Q_DISABLE_COPY(ScrollBar)
+ ScrollBarPrivate *d_ptr;
+};
+
+#endif // SCROLLBAR_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp
new file mode 100644
index 0000000000..203ea7e046
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QScrollBar>
+#include <QEvent>
+#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsView>
+#include <QDebug>
+
+#include "scroller.h"
+#include "scroller_p.h"
+#include "abstractscrollarea.h"
+#include "scrollbar.h"
+
+const int ScrollStep = 1;
+const int UpdateScrollingInterval = 55;
+const int UpdateScrollingSmoothInterval = 0;
+static const qreal MaxScrollingSpeed = 48.0;
+
+ScrollerPrivate::ScrollerPrivate(Scroller *scroller)
+ : m_scrollArea(0)
+ , m_scrollFactor(1.0)
+ , m_state(Stopped)
+ , q_ptr(scroller)
+ , m_eventViewport(0)
+{
+}
+
+ScrollerPrivate::~ScrollerPrivate()
+{
+}
+
+void ScrollerPrivate::stopScrolling()
+{
+ m_state = ScrollerPrivate::Started;
+ m_cursorPos = QCursor::pos();
+ m_speed = QPoint(0, 0);
+
+ if (m_scrollTimer.isActive())
+ m_scrollTimer.stop();
+}
+
+//Maps screen coordinates to scrollArea coordinates though current m_eventViewport widget
+QPointF ScrollerPrivate::mapToScrollArea(const QPoint &point)
+{
+ if (!m_scrollArea || !m_eventViewport)
+ return point;
+
+ QObject *vparent = m_eventViewport->parent();
+ if (!vparent)
+ return point;
+
+ QGraphicsView *view = qobject_cast<QGraphicsView*>(vparent);
+ if (!view)
+ return point;
+
+ QPoint pt = view->mapFromGlobal(point);
+ return m_scrollArea->mapFromScene(view->mapToScene(pt));
+}
+
+bool ScrollerPrivate::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj != m_scrollArea
+ || (event->type() != QEvent::GraphicsSceneMouseMove
+ && event->type() != QEvent::GraphicsSceneMousePress
+ && event->type() != QEvent::GraphicsSceneMouseRelease
+ /*&& event->type() != QEvent::GraphicsSceneKeyPressed
+ && event->type() != QEvent::GraphicsSceneKeyReleased*/))
+ return false;
+
+ QGraphicsSceneMouseEvent* mouseEvent =
+ static_cast<QGraphicsSceneMouseEvent*>(event);
+
+ m_eventViewport = mouseEvent->widget();
+
+ bool eventConsumed = false;
+
+ switch (m_state) {
+ case ScrollerPrivate::Stopped:
+ if (mouseEvent->type() == QEvent::GraphicsSceneMousePress &&
+ mouseEvent->buttons() == Qt::LeftButton) {
+ m_cursorPos = QCursor::pos();
+ m_speed = QPointF(0.0, 0.0);
+ m_state = Started;
+ }
+
+ eventConsumed = true;
+ break;
+
+ case ScrollerPrivate::Started:
+ if (mouseEvent->type() == QEvent::GraphicsSceneMouseMove) {
+ m_cursorPos = QCursor::pos();
+ m_state = ManualScrolling;
+
+ if (!m_scrollTimer.isActive())
+ m_scrollTimer.start(UpdateScrollingInterval);
+ else {
+ m_scrollTimer.stop();
+ m_scrollTimer.start(UpdateScrollingInterval);
+ }
+
+ } else if (mouseEvent->type() == QEvent::MouseButtonRelease) {
+ m_speed = QPoint(0, 0);
+ m_state = Stopped;
+
+ if (m_scrollTimer.isActive())
+ m_scrollTimer.stop();
+ }
+ eventConsumed = true;
+ break;
+
+ case ScrollerPrivate::ManualScrolling:
+ if (mouseEvent->type() == QEvent::GraphicsSceneMouseMove &&
+ m_scrollArea->viewport()->boundingRect().contains(mouseEvent->pos()) ) {
+
+ ScrollBar *hscroll = m_scrollArea->horizontalScrollBar();
+ ScrollBar *vscroll = m_scrollArea->verticalScrollBar();
+
+ QPointF d = m_scrollFactor * (mapToScrollArea(QCursor::pos()) - mapToScrollArea(m_cursorPos));
+
+ hscroll->setSliderPosition(hscroll->sliderPosition() - d.x());
+ vscroll->setSliderPosition(vscroll->sliderPosition() - d.y());
+
+ if (m_lastCursorTime.elapsed() > UpdateScrollingInterval) {
+ m_speed = mapToScrollArea(QCursor::pos()) - mapToScrollArea(m_cursorPos);
+ m_lastCursorTime.restart();
+ }
+
+ m_lastFrameTime.restart();
+
+ m_cursorPos = QCursor::pos();
+ } else if (mouseEvent->type() == QEvent::GraphicsSceneMouseRelease) {
+ m_state = AutoScrolling;
+ m_scrollSlowAccum = 0;
+ if (m_scrollTimer.isActive()) {
+ m_scrollTimer.stop();
+ m_scrollTimer.start(UpdateScrollingSmoothInterval);
+ }
+ }
+ eventConsumed = true;
+ break;
+
+ case ScrollerPrivate::AutoScrolling:
+ if (mouseEvent->type() == QEvent::GraphicsSceneMousePress) {
+ stopScrolling();
+ } else if (mouseEvent->type() == QEvent::MouseButtonRelease) {
+ m_state = Stopped;
+ }
+ eventConsumed = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return eventConsumed;
+}
+
+void ScrollerPrivate::updateScrolling()
+{
+ bool scrollOngoing = false;
+
+ if (!m_scrollArea) {
+ m_scrollTimer.stop();
+ return;
+ }
+
+ if (m_state == ManualScrolling) {
+ scrollOngoing = true;
+ m_speed = mapToScrollArea(QCursor::pos()) - mapToScrollArea(m_cursorPos);
+ m_cursorPos = QCursor::pos();
+ } else if (m_state == AutoScrolling) {
+ scrollOngoing = true;
+
+
+ qreal x = qMax(-MaxScrollingSpeed, qMin(m_speed.x(), MaxScrollingSpeed));
+ qreal y = qMax(-MaxScrollingSpeed, qMin(m_speed.y(), MaxScrollingSpeed));
+
+ int sinceLast = m_lastFrameTime.elapsed();
+ int slowdown = (ScrollStep * sinceLast) + m_scrollSlowAccum;
+ m_scrollSlowAccum = slowdown & 0x3F;
+ slowdown >>= 6;
+
+ if (x > 0)
+ x= qMax(qreal(0.0), x - slowdown);
+ else
+ x = qMin(qreal(0.0), x + slowdown);
+
+ if (y > 0)
+ y = qMax(qreal(0.0), y - slowdown);
+ else
+ y = qMin(qreal(0.0), y + slowdown);
+
+ m_speed = QPoint(x,y);
+
+ if (m_speed != QPoint(0,0)) {
+ QPointF d;
+
+ int xstep = (int(m_speed.x()) * sinceLast)>>6; // >>6 ~= *60 /1000 (==*64 /1024)
+ int ystep = (int(m_speed.y()) * sinceLast)>>6;
+ //qDebug() << sinceLast << "speedy" << speed.y()<<"ystep" << ystep;
+ QPoint step = QPoint(xstep,ystep);
+
+ if (ystep > 0)
+ d = (m_scrollArea->pos() + step);
+ else
+ d = -(m_scrollArea->pos() - step);
+
+ ScrollBar *hscroll = m_scrollArea->horizontalScrollBar();
+ ScrollBar *vscroll = m_scrollArea->verticalScrollBar();
+
+ hscroll->setSliderPosition(hscroll->sliderPosition() - m_scrollFactor * d.x());
+ vscroll->setSliderPosition(vscroll->sliderPosition() - m_scrollFactor * d.y());
+ } else {
+ m_state = Stopped;
+ scrollOngoing = false;
+ }
+ }
+
+ m_lastFrameTime.restart();
+
+ if (!scrollOngoing)
+ m_scrollTimer.stop();
+}
+
+
+Scroller::Scroller(QObject *parent)
+ : QObject(parent), d_ptr(new ScrollerPrivate(this))
+{
+ Q_D(Scroller);
+ connect(&d->m_scrollTimer, SIGNAL(timeout()), this, SLOT(updateScrolling()));
+}
+
+Scroller::~Scroller()
+{
+ delete d_ptr;
+}
+
+void Scroller::setScrollable(AbstractScrollArea *area)
+{
+ Q_D(Scroller);
+
+ if (!area)
+ return;
+
+ d->m_scrollArea = area;
+}
+
+void Scroller::setScrollFactor(qreal scrollFactor)
+{
+ Q_D(Scroller);
+
+ d->m_scrollFactor = scrollFactor;
+}
+
+bool Scroller::eventFilter(QObject *obj, QEvent *event)
+{
+ Q_D(Scroller);
+ return d->eventFilter(obj, event);
+}
+
+void Scroller::stopScrolling()
+{
+ Q_D(Scroller);
+ d->stopScrolling();
+}
+#include "moc_scroller.cpp"
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h
new file mode 100644
index 0000000000..8f40dcfd16
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCROLLER_H
+#define SCROLLER_H
+
+#include <QObject>
+
+class ScrollerPrivate;
+class AbstractScrollArea;
+
+class Scroller : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ Scroller(QObject *parent = 0);
+ virtual ~Scroller();
+
+public:
+
+ void setScrollable(AbstractScrollArea *area);
+ void setScrollFactor(qreal scrollFactor);
+ void stopScrolling();
+
+private:
+
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+private:
+
+ Q_DECLARE_PRIVATE(Scroller)
+ Q_DISABLE_COPY(Scroller)
+
+ Q_PRIVATE_SLOT(d_ptr, void updateScrolling())
+
+ ScrollerPrivate * const d_ptr;
+};
+
+#endif // SCROLLER_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h
new file mode 100644
index 0000000000..cf11c7fa02
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCROLLER_P_H
+#define SCROLLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QPoint>
+#include <QTimer>
+#include <QTime>
+
+#include "scroller.h"
+
+class AbstractScrollArea;
+
+class ScrollerPrivate
+{
+ Q_DECLARE_PUBLIC(Scroller)
+
+public:
+ enum State {
+ Stopped,
+ Started,
+ ManualScrolling,
+ AutoScrolling
+ };
+
+ ScrollerPrivate(Scroller *scroller);
+ ~ScrollerPrivate();
+ void stopScrolling();
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+ AbstractScrollArea *m_scrollArea;
+ qreal m_scrollFactor;
+ QPoint m_cursorPos;
+ QPointF m_speed;
+ State m_state;
+ QTime m_lastCursorTime;
+ QTime m_lastFrameTime;
+ QTimer m_scrollTimer;
+ int m_scrollSlowAccum;
+
+private Q_SLOTS:
+
+ void updateScrolling();
+
+private:
+
+ Q_DISABLE_COPY(ScrollerPrivate)
+ Scroller * const q_ptr;
+ QPointF mapToScrollArea(const QPoint &point);
+ QWidget *m_eventViewport;
+};
+
+#endif // SCROLLER_P_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp
new file mode 100644
index 0000000000..9cb44882a6
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "settings.h"
+
+
+Settings::Settings()
+ : QObject(),
+ m_scriptName(),
+ m_outputFileName(),
+ m_resultFormat(0),
+ m_size(0,0),
+ m_angle(0),
+ m_listItemCount(200),
+ m_options()
+{
+}
+
+Settings::~Settings()
+{
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h
new file mode 100644
index 0000000000..dc228162c4
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <QObject>
+#include <QSize>
+#include <QString>
+#include <QFlags>
+
+class Settings : public QObject {
+ Q_OBJECT
+
+public:
+ enum Option {
+ NoOptions = 0x1,
+ UseListItemCache = 0x2,
+ UseOpenGL = 0x4,
+ OutputFps = 0x8,
+ NoResourceUsage = 0x10,
+ ManualTest = 0x20
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
+ Settings();
+ ~Settings();
+
+ const QString &scriptName() const
+ { return m_scriptName; }
+ void setScriptName(const QString& scriptName)
+ { m_scriptName = scriptName; }
+
+ const QString &outputFileName() const
+ { return m_outputFileName; }
+ void setOutputFileName(const QString& outputFileName)
+ { m_outputFileName = outputFileName; }
+
+ int resultFormat() const
+ { return m_resultFormat; }
+ void setResultFormat(int resultFormat)
+ { m_resultFormat = resultFormat; }
+
+ const QSize& size() const
+ { return m_size; }
+ void setSize(const QSize& size)
+ { m_size = size; }
+
+ int angle() const
+ { return m_angle; }
+ void setAngle(int angle)
+ { m_angle = angle; }
+
+ const Options& options() const
+ { return m_options; }
+ void setOptions(Options options)
+ { m_options = options; }
+
+ int listItemCount()
+ { return m_listItemCount; }
+
+ void setListItemCount(int items)
+ { m_listItemCount = items; }
+
+private:
+
+ QString m_scriptName;
+ QString m_outputFileName;
+ int m_resultFormat;
+ QSize m_size;
+ int m_angle;
+ int m_listItemCount;
+ Options m_options;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Settings::Options)
+
+#endif
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp
new file mode 100644
index 0000000000..941cab8c21
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QGraphicsLinearLayout>
+#include <QFont>
+#include <QTime>
+
+#include "simplelist.h"
+static const int MinItemWidth = 276;
+
+SimpleList::SimpleList(QGraphicsWidget *parent)
+ : GvbWidget(parent),
+ m_list(new ListWidget(this))
+{
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout();
+ layout->setContentsMargins(0,0,0,0);
+ setContentsMargins(0,0,0,0);
+ setLayout(layout);
+ layout->addItem(m_list);
+ setObjectName("SimpleList");
+}
+
+/*virtual*/
+SimpleList::~SimpleList()
+{
+}
+
+void SimpleList::addItem(ListItem *item)
+{
+ item->setMinimumWidth(MinItemWidth);
+ m_list->addItem(item);
+}
+
+void SimpleList::insertItem(int index, ListItem *item)
+{
+ item->setMinimumWidth(MinItemWidth);
+ m_list->insertItem(index, item);
+}
+
+ListItem* SimpleList::takeItem(int row)
+{
+ return static_cast<ListItem*>(m_list->takeItem(row));
+}
+
+ListItem* SimpleList::itemAt(int row)
+{
+ return static_cast<ListItem*>(m_list->itemAt(row));
+}
+
+int SimpleList::itemCount() const
+{
+ if (m_list)
+ return m_list->itemCount();
+ return 0;
+}
+
+ScrollBar* SimpleList::verticalScrollBar() const
+{
+ if (m_list)
+ return m_list->verticalScrollBar();
+ return 0;
+}
+
+bool SimpleList::listItemCaching() const
+{
+ return m_list->listItemCaching();
+}
+
+void SimpleList::setListItemCaching(bool enable)
+{
+ m_list->setListItemCaching(enable);
+}
+
+void SimpleList::keyPressEvent(QKeyEvent *event)
+{
+ static QTime keyPressInterval = QTime::currentTime();
+ static qreal step = 0.0;
+ static bool repeat = false;
+ int interval = keyPressInterval.elapsed();
+
+ ScrollBar* sb = verticalScrollBar();
+ qreal currentValue = sb->sliderPosition();
+
+ if(interval < 250 ) {
+ if(!repeat) step = 0.0;
+ step = step + 2.0;
+ if(step > 100) step = 100;
+ repeat = true;
+ }
+ else {
+ step = 1.0;
+ if(itemAt(0))
+ step = itemAt(0)->size().height();
+ repeat = false;
+ }
+
+ if(event->key() == Qt::Key_Up ) { //Up Arrow
+ sb->setSliderPosition(currentValue - step);
+ }
+
+ if(event->key() == Qt::Key_Down ) { //Down Arrow
+ sb->setSliderPosition(currentValue + step);
+ }
+ keyPressInterval.start();
+}
+
+
+void SimpleList::setTwoColumns(const bool twoColumns)
+{
+ m_list->setTwoColumns(twoColumns);
+}
+
+bool SimpleList::twoColumns()
+{
+ return m_list->twoColumns();
+}
+
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h
new file mode 100644
index 0000000000..3c1ec4f82a
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIMPLELIST_H_
+#define SIMPLELIST_H_
+
+
+#include "gvbwidget.h"
+#include "listitem.h"
+#include "listwidget.h"
+
+class QGraphicsWidget;
+
+class SimpleList : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+ SimpleList(QGraphicsWidget *parent=0);
+ virtual ~SimpleList();
+ void addItem(ListItem *item);
+ void insertItem(int index, ListItem *item);
+ ListItem* takeItem(int row);
+ ListItem* itemAt(int row);
+ int itemCount() const;
+ virtual void keyPressEvent(QKeyEvent *event);
+ bool listItemCaching() const;
+ void setListItemCaching(bool enable);
+
+ void setTwoColumns(const bool twoColumns);
+ bool twoColumns();
+
+public slots:
+ ScrollBar* verticalScrollBar() const;
+
+private:
+ Q_DISABLE_COPY(SimpleList)
+
+ ListWidget *m_list;
+};
+
+#endif /* LISTTEST_H_ */
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp
new file mode 100644
index 0000000000..67f34859c1
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp
@@ -0,0 +1,463 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "simplelistview.h"
+#include "scrollbar.h"
+#include "simplelistview.h"
+#include "scrollbar.h"
+#include "listitem.h"
+#include "listitemcache.h"
+#include "theme.h"
+
+class SimpleListViewPrivate
+{
+ Q_DECLARE_PUBLIC(SimpleListView)
+
+public:
+
+ SimpleListViewPrivate(SimpleListView *button)
+ : m_content(0)
+ , m_layout(0)
+ , m_twoColumns(false)
+ , q_ptr(button)
+ , m_listItemCaching(false)
+ {
+ Q_Q(SimpleListView);
+
+ m_layout = new QGraphicsGridLayout();
+ m_layout->setContentsMargins(0, 0, 0, 0);
+ m_layout->setSpacing(0);
+ m_layout->setColumnSpacing(0,0);
+ m_layout->setColumnSpacing(1,0);
+ m_layout->setRowSpacing(0,0);
+ m_layout->setRowSpacing(1,0);
+ m_content = new QGraphicsWidget;
+ m_content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_content->setParentItem(q->viewport());
+ m_content->setLayout(m_layout);
+
+ q->horizontalScrollBar()->setSliderSize(0.0);
+
+ QObject::connect(Theme::p(), SIGNAL(themeChanged()), q, SLOT(themeChange()));
+ }
+
+ ~SimpleListViewPrivate()
+ {
+ if (!m_content->parentItem() && !m_content->parent())
+ delete m_content;
+ }
+
+ void resizeContents(QSizeF s)
+ {
+ Q_UNUSED(s);
+ Q_Q(SimpleListView);
+
+ if (!m_content)
+ return;
+
+ const bool caching = q->listItemCaching();
+ q->setListItemCaching(false);
+
+ m_content->resize(q->viewport()->size().width(),
+ m_layout->preferredHeight());
+ const bool clip =
+ m_content->size().width() > q->viewport()->size().width()
+ || m_content->size().height() > q->viewport()->size().height();
+
+ q->viewport()->setFlag(
+ QGraphicsItem::ItemClipsChildrenToShape, clip);
+
+ q->setListItemCaching(caching);
+ }
+
+ void resizeScrollBars()
+ {
+ Q_Q(SimpleListView);
+
+ if (!m_content)
+ return;
+
+ m_content->resize(m_content->size().width(),
+ m_layout->preferredHeight());
+
+ QRectF contentRect = m_content->boundingRect();
+ QRectF listRect = q->boundingRect();
+
+ // List do not have horizontal scroll bar visible.
+ q->horizontalScrollBar()->setSliderSize(0.0);
+
+ if (contentRect.height()-q->boundingRect().height() > 0) {
+ q->verticalScrollBar()->setSliderSize(contentRect.height()-q->boundingRect().height());
+ if (q->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff &&
+ !q->verticalScrollBar()->isVisible()) {
+ q->verticalScrollBar()->show();
+ }
+ }
+ else if (q->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded ||
+ q->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
+ q->verticalScrollBar()->setSliderSize(0.0);
+ q->verticalScrollBar()->hide();
+ }
+ else {
+ q->verticalScrollBar()->setSliderSize(0.0);
+ }
+
+ qreal pos = 0.0;
+ if ((m_content->boundingRect().height() - q->boundingRect().height()) != 0) {
+ qreal min = qMin(-contentRect.top(), m_content->pos().y());
+ qreal diff = contentRect.height() - listRect.height();
+ pos = qAbs(contentRect.top() + min) / diff;
+ }
+
+ q->verticalScrollBar()->setSliderPosition(pos);
+ }
+
+ void updateListContents()
+ {
+ Q_Q(SimpleListView);
+
+ const bool caching = q->listItemCaching();
+ q->setListItemCaching(false);
+
+ const QString defaultIcon = Theme::p()->pixmapPath()+"contact_default_icon.svg";
+ const int itemCount = m_layout->count();
+
+ for (int i=0; i<itemCount; ++i) {
+ ListItem* item = static_cast<ListItem*>(m_layout->itemAt(i));
+
+ // Update default icons
+ const QString filename = item->icon(ListItem::LeftIcon)->fileName();
+ if (filename.contains("contact_default_icon")) {
+ item->icon(ListItem::LeftIcon)->setFileName(defaultIcon);
+ }
+
+ // Update status icons
+ QString statusIcon = item->icon(ListItem::RightIcon)->fileName();
+ const int index = statusIcon.indexOf("contact_status");
+ if (index != -1) {
+ statusIcon.remove(0, index);
+ item->icon(ListItem::RightIcon)->setFileName(Theme::p()->pixmapPath()+statusIcon);
+ }
+
+ // Update fonts
+ item->setFont(Theme::p()->font(Theme::ContactName), ListItem::FirstPos);
+ item->setFont(Theme::p()->font(Theme::ContactNumber), ListItem::SecondPos);
+ item->setFont(Theme::p()->font(Theme::ContactEmail), ListItem::ThirdPos);
+
+ // Update list dividers
+ if (i%2) {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd());
+ }
+ else {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven());
+ }
+
+ // Update borders
+ item->setBorderPen(Theme::p()->listItemBorderPen());
+ item->setRounding(Theme::p()->listItemRounding());
+
+ // Update icons
+ item->icon(ListItem::LeftIcon)->setRotation(Theme::p()->iconRotation(ListItem::LeftIcon));
+ item->icon(ListItem::RightIcon)->setRotation(Theme::p()->iconRotation(ListItem::RightIcon));
+ item->icon(ListItem::LeftIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::LeftIcon));
+ item->icon(ListItem::RightIcon)->setOpacityEffectEnabled(Theme::p()->isIconOpacityEffectEnabled(ListItem::RightIcon));
+ item->icon(ListItem::LeftIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::LeftIcon));
+ item->icon(ListItem::RightIcon)->setSmoothTransformationEnabled(Theme::p()->isIconSmoothTransformationEnabled(ListItem::RightIcon));
+ }
+ q->setListItemCaching(caching);
+ }
+
+ void updateListItemBackgrounds(int index)
+ {
+ Q_Q(SimpleListView);
+
+ const bool caching = q->listItemCaching();
+ q->setListItemCaching(false);
+
+ const int itemCount = m_layout->count();
+
+ for (int i=index; i<itemCount; ++i) {
+ ListItem* item = static_cast<ListItem*>(m_layout->itemAt(i));
+ if (i%2) {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushOdd());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityOdd());
+ }
+ else {
+ item->setBackgroundBrush(Theme::p()->listItemBackgroundBrushEven());
+ item->setBackgroundOpacity(Theme::p()->listItemBackgroundOpacityEven());
+ }
+ }
+
+ q->setListItemCaching(caching);
+ }
+
+ void setTwoColumns(const bool twoColumns)
+ {
+ if(twoColumns == m_twoColumns)
+ return;
+
+ Q_Q(SimpleListView);
+ m_twoColumns = twoColumns;
+
+ bool cache = q->listItemCaching();
+ q->setListItemCaching(false);
+
+ QList<QGraphicsLayoutItem *> moveditems;
+ if(twoColumns) {
+ int half = m_layout->count()/2;
+ for (int i = m_layout->count()-1; i>=half; --i) {
+ QGraphicsLayoutItem *item = m_layout->itemAt(i);
+ m_layout->removeAt(i);
+ moveditems.append(item);
+ }
+ for ( int i = 0; i < moveditems.count(); ++i)
+ m_layout->addItem(moveditems.at(i), i, 1);
+
+ m_layout->setColumnSpacing(0,0);
+ m_layout->setColumnSpacing(1,0);
+ m_layout->setRowSpacing(0,0);
+ m_layout->setRowSpacing(1,0);
+ }
+ else {
+ int count = m_layout->count()/2;
+ for (int i = m_layout->count()-1; i>=0; --i) {
+ if (i >= count)
+ moveditems.append(m_layout->itemAt(i));
+ else
+ moveditems.insert(moveditems.begin(), m_layout->itemAt(i));
+ m_layout->removeAt(i);
+ }
+ for (int i = 0; i<moveditems.count(); ++i) {
+ m_layout->addItem(moveditems.at(i), m_layout->count(), 0);
+ }
+ }
+
+ resizeContents(q->size());
+ resizeScrollBars();
+
+ q->setListItemCaching(cache);
+ }
+
+ bool twoColumns()
+ {
+ return m_twoColumns;
+ }
+
+ QGraphicsWidget *m_content;
+ QGraphicsGridLayout *m_layout;
+ bool m_twoColumns;
+ SimpleListView *q_ptr;
+ bool m_listItemCaching;
+};
+
+SimpleListView::SimpleListView(QGraphicsWidget *parent)
+ : AbstractScrollArea(parent)
+ , d_ptr(new SimpleListViewPrivate(this))
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setContentsMargins(0, 0, 0, 0);
+ verticalScrollBar()->hide();
+ horizontalScrollBar()->hide();
+}
+
+SimpleListView::~SimpleListView()
+{
+ Q_D(SimpleListView);
+
+ if (d->m_content) {
+ d->m_content->setParentItem(0);
+ }
+
+ delete d_ptr;
+}
+
+void SimpleListView::addItem(QGraphicsWidget *item)
+{
+ Q_D(SimpleListView);
+
+ Q_ASSERT(item);
+
+ insertItem(d->m_layout->count(), item);
+}
+
+void SimpleListView::insertItem(int index, QGraphicsWidget *item)
+{
+ Q_D(SimpleListView);
+
+ // Grid layout doe not have insert item method.
+ // We need to first remove all items, add new item and
+ // append old items to layout.
+ QList<QGraphicsLayoutItem *> moveditems;
+
+ for (int i = d->m_layout->count()-1; i >= index; --i) {
+ moveditems.append(d->m_layout->itemAt(i));
+ d->m_layout->removeAt(i);
+ }
+ moveditems.append(item);
+
+ for (int i = moveditems.count()-1; i>=0; --i) {
+ d->m_layout->addItem(moveditems.at(i), d->m_layout->count(), 0);
+ }
+
+ ListItemCache *cache = new ListItemCache;
+ item->setGraphicsEffect(cache);
+ cache->setEnabled(listItemCaching());
+
+ d->resizeScrollBars();
+ d->updateListItemBackgrounds(index);
+}
+
+QGraphicsWidget *SimpleListView::takeItem(int index)
+{
+ Q_D(SimpleListView);
+
+ QGraphicsWidget *item = 0;
+
+ if (index >= 0 && d->m_layout->count() > index) {
+ QList<QGraphicsLayoutItem *> moveditems;
+ for (int i = d->m_layout->count()-1; i >=0; --i) {
+ if (index != i)
+ moveditems.insert(moveditems.begin(), d->m_layout->itemAt(i));
+ else {
+ item = static_cast<QGraphicsWidget*>(d->m_layout->itemAt(index));
+ item->setGraphicsEffect(0);
+ }
+
+ d->m_layout->removeAt(i);
+ }
+
+ for (int i = 0; i < moveditems.count(); ++i)
+ d->m_layout->addItem(moveditems.at(i), d->m_layout->count(), 0);
+ }
+ d->resizeScrollBars();
+ return item;
+}
+
+QGraphicsWidget *SimpleListView::itemAt(int row)
+{
+ Q_D(SimpleListView);
+
+ QGraphicsWidget *item = 0;
+
+ if (row >= 0 && d->m_layout->count() > row) {
+ item = static_cast<QGraphicsWidget*>(d->m_layout->itemAt(row));
+ }
+
+ return item;
+}
+
+int SimpleListView::itemCount()
+{
+ Q_D(SimpleListView);
+ return d->m_layout->count();
+}
+
+bool SimpleListView::listItemCaching() const
+{
+ Q_D(const SimpleListView);
+ return d->m_listItemCaching;
+}
+
+void SimpleListView::setListItemCaching(bool enabled)
+{
+ Q_D(SimpleListView);
+
+ if (d->m_listItemCaching == enabled)
+ return;
+
+ d->m_listItemCaching = enabled;
+
+ for (int i = 0; i < d->m_layout->count(); ++i) {
+ ListItem *item = static_cast<ListItem*>(d->m_layout->itemAt(i));
+ ListItemCache *cache = static_cast<ListItemCache *>(
+ item->graphicsEffect());
+ cache->setEnabled(enabled);
+ }
+}
+
+void SimpleListView::scrollContentsBy(qreal dx, qreal dy)
+{
+ Q_D(SimpleListView);
+ Q_UNUSED(dx)
+ QRectF contentRect = d->m_content->boundingRect();
+ QRectF viewportRect = viewport()->boundingRect();
+ QPointF contentPos = d->m_content->pos();
+
+ qreal newy = contentPos.y() - dy;
+ qreal miny = qMin(qreal(0.0), -(contentRect.height() - viewportRect.height()));
+
+ if (newy < miny)
+ newy = miny;
+ else if (newy > 0)
+ newy = 0.0;
+
+ d->m_content->setPos(contentPos.x(), newy);
+}
+
+void SimpleListView::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ Q_D(SimpleListView);
+
+ AbstractScrollArea::resizeEvent(event);
+ d->resizeContents(event->newSize());
+ d->resizeScrollBars();
+}
+
+QSizeF SimpleListView::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
+{
+ Q_D(const SimpleListView);
+
+ if (which == Qt::PreferredSize)
+ return d->m_content->size();
+
+ return AbstractScrollArea::sizeHint(which, constraint);
+}
+
+void SimpleListView::themeChange()
+{
+ Q_D(SimpleListView);
+
+ d->updateListContents();
+ d->resizeScrollBars();
+}
+
+void SimpleListView::setTwoColumns(const bool twoColumns)
+{
+ Q_D(SimpleListView);
+ d->setTwoColumns(twoColumns);
+}
+
+bool SimpleListView::twoColumns()
+{
+ Q_D(SimpleListView);
+ return d->twoColumns();
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h
new file mode 100644
index 0000000000..ad606cda8f
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SIMPLELISTVIEW_H
+#define SIMPLELISTVIEW_H
+
+#include "scrollbar.h"
+#include "abstractscrollarea.h"
+
+class SimpleListViewPrivate;
+
+class SimpleListView : public AbstractScrollArea
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(SimpleListView)
+
+public:
+
+ SimpleListView(QGraphicsWidget *parent = 0);
+ virtual ~SimpleListView();
+
+public:
+
+ void addItem(QGraphicsWidget *item);
+ void insertItem(int index, QGraphicsWidget *item);
+ QGraphicsWidget* takeItem(int row);
+ QGraphicsWidget* itemAt(int row);
+ int itemCount();
+ void updateListContents();
+
+ void setTwoColumns(const bool twoColumns);
+ bool twoColumns();
+
+public slots:
+
+ void themeChange();
+ bool listItemCaching() const;
+ void setListItemCaching(bool enabled);
+
+protected:
+
+ virtual void scrollContentsBy(qreal dx, qreal dy);
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+ QSizeF sizeHint(Qt::SizeHint which,
+ const QSizeF & constraint) const;
+
+private:
+
+ SimpleListViewPrivate *d_ptr;
+};
+
+#endif
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp
new file mode 100644
index 0000000000..06851b0fd8
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QPainter>
+#include <QPixmapCache>
+#include <QSvgRenderer>
+
+#include "theme.h"
+
+Q_DECLARE_METATYPE(Theme::Themes*)
+
+Theme::Theme(QObject *parent)
+ : QObject(parent)
+ , m_currentTheme()
+ , m_availableThemes()
+ , m_fonts()
+ , m_pixmapPath()
+ , m_listItemBackgroundBrushEven()
+ , m_listItemBackgroundOpacityEven()
+ , m_listItemBackgroundBrushOdd()
+ , m_listItemBackgroundOpacityOdd()
+ , m_listItemBorderPen(QPen())
+ , m_listItemRounding()
+ , m_iconOpacityEffectEnabled()
+ , m_iconRotation()
+ , m_iconSmoothTransformation()
+{
+ m_availableThemes << "Blue" << "Lime";
+
+ // Set blue theme as a default theme without emiting themeChanged() signal
+ setBlueTheme();
+}
+
+Theme::~Theme()
+{
+}
+
+Theme* Theme::p()
+{
+ static Theme t;
+ return &t;
+}
+
+void Theme::setTheme(const QString theme)
+{
+ if (theme.compare("blue", Qt::CaseInsensitive) == 0)
+ {
+ setTheme(Theme::Blue);
+ }
+ else if (theme.compare("lime", Qt::CaseInsensitive) == 0)
+ {
+ setTheme(Theme::Lime);
+ }
+ else
+ {
+ qDebug() << "Unknown theme";
+ }
+}
+
+void Theme::setTheme(const Themes theme)
+{
+ if (m_currentTheme == theme)
+ return;
+
+ switch (theme)
+ {
+ case Theme::Blue:
+ setBlueTheme();
+ emit themeChanged();
+ break;
+
+ case Theme::Lime:
+ setLimeTheme();
+ emit themeChanged();
+ break;
+ }
+}
+
+void Theme::setBlueTheme()
+{
+ m_currentTheme = Theme::Blue;
+
+ m_fonts[ContactName].setFamily("Arial");
+ m_fonts[ContactName].setPixelSize(16);
+ m_fonts[ContactName].setStyle(QFont::StyleNormal);
+ m_fonts[ContactName].setWeight(QFont::Normal);
+
+ m_fonts[ContactNumber].setFamily("Arial");
+ m_fonts[ContactNumber].setPixelSize(14);
+ m_fonts[ContactNumber].setStyle(QFont::StyleNormal);
+
+ m_fonts[ContactEmail].setFamily("Arial");
+ m_fonts[ContactEmail].setPixelSize(14);
+ m_fonts[ContactEmail].setStyle(QFont::StyleNormal);
+
+ m_fonts[TitleBar].setFamily("Arial");
+ m_fonts[TitleBar].setPixelSize(36);
+ m_fonts[TitleBar].setStyle(QFont::StyleNormal);
+
+ m_fonts[StatusBar].setFamily("Arial");
+ m_fonts[StatusBar].setPixelSize(16);
+ m_fonts[StatusBar].setStyle(QFont::StyleNormal);
+
+ m_fonts[MenuItem].setFamily("Arial");
+ m_fonts[MenuItem].setPixelSize(14);
+ m_fonts[MenuItem].setStyle(QFont::StyleNormal);
+
+ m_pixmapPath = ":/themes/blue/";
+
+ m_listItemBackgroundBrushEven = QBrush(Qt::NoBrush);
+ m_listItemBackgroundOpacityEven = 1.0;
+ m_listItemBackgroundBrushOdd = QBrush(QColor(44,214,250), Qt::SolidPattern);
+ m_listItemBackgroundOpacityOdd = 1.0;
+
+ m_listItemBorderPen = QPen(Qt::NoPen);
+ m_listItemRounding = QSize(0.0, 0.0);
+
+ m_iconOpacityEffectEnabled[ListItem::LeftIcon] = false;
+ m_iconOpacityEffectEnabled[ListItem::RightIcon] = false;
+
+ m_iconRotation[ListItem::LeftIcon] = 0.0;
+ m_iconRotation[ListItem::RightIcon] = 0.0;
+
+ m_iconSmoothTransformation[ListItem::LeftIcon] = false;
+ m_iconSmoothTransformation[ListItem::RightIcon] = false;
+}
+
+void Theme::setLimeTheme()
+{
+ m_currentTheme = Theme::Lime;
+
+ m_fonts[ContactName].setFamily("Arial");
+ m_fonts[ContactName].setPixelSize(16);
+ m_fonts[ContactName].setStyle(QFont::StyleItalic);
+ m_fonts[ContactName].setWeight(QFont::Bold);
+
+ m_fonts[ContactNumber].setFamily("Arial");
+ m_fonts[ContactNumber].setPixelSize(14);
+ m_fonts[ContactNumber].setStyle(QFont::StyleItalic);
+
+ m_fonts[ContactEmail].setFamily("Arial");
+ m_fonts[ContactEmail].setPixelSize(14);
+ m_fonts[ContactEmail].setStyle(QFont::StyleItalic);
+
+ m_fonts[TitleBar].setFamily("Arial");
+ m_fonts[TitleBar].setPixelSize(36);
+ m_fonts[TitleBar].setStyle(QFont::StyleItalic);
+
+ m_fonts[StatusBar].setFamily("Arial");
+ m_fonts[StatusBar].setPixelSize(16);
+ m_fonts[StatusBar].setStyle(QFont::StyleItalic);
+
+ m_fonts[MenuItem].setFamily("Arial");
+ m_fonts[MenuItem].setPixelSize(14);
+ m_fonts[MenuItem].setStyle(QFont::StyleItalic);
+
+ m_pixmapPath = ":/themes/lime/";
+
+ m_listItemBackgroundBrushEven = QBrush(QPixmap(":/avatars/avatar_014.png"));
+ m_listItemBackgroundOpacityEven = 0.05;
+
+ m_listItemBackgroundBrushOdd = QBrush(QPixmap(":/avatars/avatar_012.png"));
+ m_listItemBackgroundOpacityOdd = 0.15;
+
+ m_listItemBorderPen = QPen(QColor(0,0,0,55), 3, Qt::SolidLine);
+ m_listItemRounding = QSize(12.0, 12.0);
+
+ m_iconOpacityEffectEnabled[ListItem::LeftIcon] = true;
+ m_iconOpacityEffectEnabled[ListItem::RightIcon] = false;
+
+ m_iconRotation[ListItem::LeftIcon] = -4.0;
+ m_iconRotation[ListItem::RightIcon] = 0.0;
+
+ m_iconSmoothTransformation[ListItem::LeftIcon] = true;
+ m_iconSmoothTransformation[ListItem::RightIcon] = false;
+}
+
+QPixmap Theme::pixmap(const QString filename, QSize size)
+{
+ if (filename.endsWith(".svg", Qt::CaseInsensitive))
+ {
+ QSvgRenderer doc(m_pixmapPath+filename);
+ if (size == QSize(0,0))
+ size = doc.defaultSize();
+ QPixmap pix(size.width(),size.height());
+ pix.fill(Qt::transparent);
+ QPainter painter(&pix);
+ painter.setViewport(0, 0, size.width(), size.height());
+ doc.render(&painter);
+ return pix;
+ }
+ else
+ {
+ QPixmap pix(m_pixmapPath+filename);
+ return pix.scaled(size);
+ }
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h
new file mode 100644
index 0000000000..4aafd0c288
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef THEME_H
+#define THEME_H
+
+#include <QPen>
+#include <QPainter>
+
+#include "gvbwidget.h"
+#include "listitem.h"
+
+class Theme : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum Themes
+ {
+ Blue = 0,
+ Lime = 1,
+ };
+
+ enum Fonts
+ {
+ ContactName,
+ ContactNumber,
+ ContactEmail,
+ TitleBar,
+ StatusBar,
+ MenuItem,
+ };
+
+ virtual ~Theme();
+
+ static Theme* p();
+
+ void setTheme(const QString theme);
+ void setTheme(const Themes theme);
+
+ Themes theme() const { return m_currentTheme; }
+ QString currentThemeName() { return m_availableThemes.at(m_currentTheme); }
+ QStringList themes() const { return m_availableThemes; }
+ int themesCount() const { return m_availableThemes.count(); }
+
+ QPixmap pixmap(const QString filename = "", QSize size = QSize(0,0));
+ QFont font(Fonts type) const { return m_fonts[type]; }
+ QString pixmapPath() const { return m_pixmapPath; }
+
+ QBrush listItemBackgroundBrushEven() const { return m_listItemBackgroundBrushEven; }
+ QBrush listItemBackgroundBrushOdd() const { return m_listItemBackgroundBrushOdd; }
+ qreal listItemBackgroundOpacityEven() const { return m_listItemBackgroundOpacityEven; }
+ qreal listItemBackgroundOpacityOdd() const { return m_listItemBackgroundOpacityOdd; }
+
+ QPen listItemBorderPen() const { return m_listItemBorderPen; }
+ QSize listItemRounding() const { return m_listItemRounding; }
+
+ bool isIconOpacityEffectEnabled(const ListItem::IconItemPos iconPos) const { return m_iconOpacityEffectEnabled[iconPos]; }
+
+ qreal iconRotation(const ListItem::IconItemPos iconPos) const { return m_iconRotation[iconPos]; }
+ bool isIconSmoothTransformationEnabled(const ListItem::IconItemPos iconPos) const { return m_iconSmoothTransformation[iconPos]; }
+
+signals:
+ void themeChanged();
+
+private:
+ Theme(QObject *parent = 0);
+
+ void setBlueTheme();
+ void setLimeTheme();
+
+private:
+ Q_DISABLE_COPY(Theme)
+
+ Themes m_currentTheme;
+ QStringList m_availableThemes;
+ QHash<Fonts, QFont> m_fonts;
+ QString m_pixmapPath;
+
+ QBrush m_listItemBackgroundBrushEven;
+ qreal m_listItemBackgroundOpacityEven;
+ QBrush m_listItemBackgroundBrushOdd;
+ qreal m_listItemBackgroundOpacityOdd;
+
+ QPen m_listItemBorderPen;
+ QSize m_listItemRounding;
+
+ QHash<ListItem::IconItemPos, bool> m_iconOpacityEffectEnabled;
+ QHash<ListItem::IconItemPos, qreal> m_iconRotation;
+ QHash<ListItem::IconItemPos, bool> m_iconSmoothTransformation;
+};
+
+#endif // THEME_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp
new file mode 100644
index 0000000000..1209b4a0f7
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "themeevent.h"
+
+ThemeEvent::ThemeEvent( const QString &newTheme, Type type) : QEvent(type),
+ m_theme(newTheme)
+{
+
+}
+
+ThemeEvent::~ThemeEvent()
+{
+
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h
new file mode 100644
index 0000000000..4ae63d8755
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __THEMEEVENT_H__
+#define __THEMEEVENT_H__
+
+#include <QEvent>
+#include <QString>
+
+static QEvent::Type ThemeEventType = (QEvent::Type) 1010;
+
+class ThemeEvent : public QEvent
+{
+public:
+ explicit ThemeEvent(const QString &newTheme, QEvent::Type type = ThemeEventType );
+ ~ThemeEvent();
+
+public:
+ inline QString getTheme() { return m_theme; }
+
+private:
+ QString m_theme;
+};
+
+
+#endif /* __THEMEEVENT_H__ */
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp
new file mode 100644
index 0000000000..7c3d97b859
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp
@@ -0,0 +1,346 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGraphicsView>
+#include <QStyleOptionGraphicsItem>
+#include <QGraphicsSceneResizeEvent>
+#include <QPixmap>
+#include <QFont>
+
+#include "themeevent.h"
+#include "theme.h"
+#include "topbar.h"
+#include "mainview.h"
+
+TopBar::TopBar(QGraphicsView* mainView, QGraphicsWidget* parent) :
+ GvbWidget(parent), m_mainView(mainView), m_isLimeTheme(false),
+ m_orientation(TopBar::None), m_topBarPixmap(), m_sizesBlue(), m_sizesLime()
+{
+ setDefaultSizes();
+
+ m_titleFont = Theme::p()->font(Theme::TitleBar);
+ m_statusFont = Theme::p()->font(Theme::StatusBar);
+
+ connect(Theme::p(), SIGNAL(themeChanged()), this, SLOT(themeChange()));
+}
+
+TopBar::~TopBar()
+{
+}
+
+void TopBar::resizeEvent(QGraphicsSceneResizeEvent* /*event*/)
+{
+ //Check orientation
+ QString topbarName;
+ QSize mainViewSize = m_mainView->size();
+ int rotationAngle = static_cast<MainView*>(m_mainView)->rotationAngle();
+ if(rotationAngle == 90 || rotationAngle == 270 ) {
+ int wd = mainViewSize.width();
+ int ht = mainViewSize.height();
+ mainViewSize.setWidth(ht);
+ mainViewSize.setHeight(wd);
+ }
+ bool m_orientationChanged = false;
+ if(mainViewSize.height() >= mainViewSize.width()) {
+ if(m_orientation == TopBar::Landscape)
+ m_orientationChanged = true;
+ m_orientation = TopBar::Portrait;
+ topbarName = "topbar.svg";
+ }
+ else {
+ if(m_orientation == TopBar::Portrait)
+ m_orientationChanged = true;
+ m_orientation = TopBar::Landscape;
+ topbarName = "topbar_horisontal.svg";
+ }
+
+ //Calculate new size, resize by height, don't make it wider than the screen
+ QHash<QString, QSize>sizes = (Theme::p()->theme() == Theme::Blue) ?
+ m_sizesBlue : m_sizesLime;
+
+ //Get current size for topbarpixmap
+ QSize currentSize = !m_topBarPixmap.isNull() && !m_orientationChanged ?
+ m_topBarPixmap.size() : sizes[topbarName];
+ QSize newSize = !m_orientationChanged ? QSize(currentSize) : sizes[topbarName];
+
+ //Scale according to aspect ratio
+ newSize.scale(size().toSize(), Qt::KeepAspectRatio);
+
+ //fix width to window widht if previous scaling produced too narrow image
+ if(newSize.width() < size().width()) {
+ newSize.scale(size().toSize(), Qt::KeepAspectRatioByExpanding);
+ }
+
+ //Calculate scaling factor for rest of the graphics scaling
+ qreal scaleFactor = (newSize.width() *1.0) / (currentSize.width() * 1.0);
+
+ //Scale graphics, if the scalefactor applies
+ //This is really heavy since the SVG graphics are read again from the resource
+ if(scaleFactor != 1 || m_topBarPixmap.isNull() ) {
+ m_topBarPixmap = Theme::p()->pixmap(topbarName, newSize );
+ m_topBarUserIcon = Theme::p()->pixmap("user_default_icon.svg",
+ !m_topBarUserIcon.isNull() && !m_orientationChanged ? m_topBarUserIcon.size()* scaleFactor : sizes["user_default_icon.svg"] * scaleFactor);
+
+ m_topBarUserStatus = Theme::p()->pixmap("user_status_online.svg",
+ !m_topBarUserStatus.isNull() && !m_orientationChanged ? m_topBarUserStatus.size() * scaleFactor : sizes["user_status_online.svg"] * scaleFactor);
+
+ m_topBarStatusBarLeft = Theme::p()->pixmap("status_field_left.svg",
+ !m_topBarStatusBarLeft.isNull() && !m_orientationChanged ? m_topBarStatusBarLeft.size()* scaleFactor : sizes["status_field_left.svg"] * scaleFactor);
+
+ m_topBarStatusBarRight = Theme::p()->pixmap("status_field_right.svg",
+ !m_topBarStatusBarRight.isNull() && !m_orientationChanged ? m_topBarStatusBarRight.size()* scaleFactor : sizes["status_field_right.svg"] * scaleFactor);
+
+ m_topBarStatusBarMiddle = Theme::p()->pixmap("status_field_middle.svg",
+ !m_topBarStatusBarMiddle.isNull() && !m_orientationChanged ? m_topBarStatusBarMiddle.size() * scaleFactor : QSize(185, sizes["status_field_middle.svg"].height()) * scaleFactor);
+
+ //Update the sizeHint to match the size of the scaled m_topBarPixmap
+ updateGeometry();
+
+ //Point Update - Positions relative to the Top Bar "Backgroud" size.
+ //TODO: consider some layout instead of calculating relative locations
+ QSize topBarPixmapSize = m_topBarPixmap.size();
+ QSize topBarUserIconSize = m_topBarUserIcon.size();
+ QSize topBarUserStatusSize = m_topBarUserStatus.size();
+ QSize topBarStatusBarLeftSize = m_topBarStatusBarLeft.size();
+ QSize topBarStatusBarMiddleSize = m_topBarStatusBarMiddle.size();
+
+ //Location for Title text 5% width, 35% height of the background pixmap
+ m_topBarTitlePoint = QPoint(topBarPixmapSize.width()* 0.05,
+ topBarPixmapSize.height() * 0.35);
+
+ //User Icon location
+ //Placing 70% of the width and 10% of the height of the top bar background
+ m_topBarUserIconPoint = QPoint((topBarPixmapSize.width() * 0.7), (topBarPixmapSize.height() * 0.1));
+
+ //If Blue theme is in use - position user status icon on the right side of the user icon
+ if(!m_isLimeTheme) {
+ //Place the status icon on top of the right edge of the user icon, lower it by 35% of the height of the user icon
+ m_topBarUserStatusPoint = QPoint( ( (m_topBarUserIconPoint.x()+topBarUserIconSize.width() ) -
+ ( topBarUserStatusSize.width()/2 )),
+ (m_topBarUserIconPoint.y() + (topBarUserIconSize.height() * 0.35 )));
+ }
+ //If Lime theme is in use - position user status icon on the left side of the user icon
+ else {
+ //Place the status icon on top of the left side of the user icon, lower it by 50% of the height of the user icon
+ //and move left by 5% of the icon
+ m_topBarUserStatusPoint = QPoint( m_topBarUserIconPoint.x() + ( topBarUserIconSize.width() * 0.05),
+ (m_topBarUserIconPoint.y() + (topBarUserIconSize.height() * 0.5 )));
+ }
+
+ //Status bar
+ //Placing the left side of the status bar 5% of the width, 50% of the height of the top bar background
+ //Set the text baseline 80% of the height of the status bar
+ m_topBarStatusBarLeftPoint = QPoint( (topBarPixmapSize.width()* 0.05),
+ (topBarPixmapSize.height() * 0.5));
+ m_topBarStatusBarMiddlePoint = QPoint( (m_topBarStatusBarLeftPoint.x() + topBarStatusBarLeftSize.width()),
+ (m_topBarStatusBarLeftPoint.y()));
+ m_topBarStatusBarRightPoint = QPoint( (m_topBarStatusBarMiddlePoint.x() + topBarStatusBarMiddleSize.width()),
+ (m_topBarStatusBarMiddlePoint.y() ) );
+ m_topBarStatusBarTextPoint = QPoint(m_topBarStatusBarMiddlePoint.x(),
+ m_topBarStatusBarMiddlePoint.y() + (topBarStatusBarMiddleSize.height()*0.8) );
+ } //if scalefactor
+}
+
+void TopBar::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget */*widget*/ )
+{
+ //Topbar background
+ painter->drawPixmap(option->exposedRect, m_topBarPixmap, option->exposedRect);
+
+ //User Icon
+ painter->drawPixmap(m_topBarUserIconPoint, m_topBarUserIcon);
+
+ //User Status
+ painter->drawPixmap(m_topBarUserStatusPoint, m_topBarUserStatus);
+
+ //Status bar
+ painter->drawPixmap(m_topBarStatusBarLeftPoint, m_topBarStatusBarLeft);
+ painter->drawPixmap(m_topBarStatusBarMiddlePoint, m_topBarStatusBarMiddle);
+ painter->drawPixmap(m_topBarStatusBarRightPoint, m_topBarStatusBarRight);
+
+ //Title text
+ painter->save();
+ painter->setFont(m_titleFont);
+ painter->setOpacity(0.7);
+ painter->setPen(Qt::white);
+ painter->drawText(m_topBarTitlePoint, QString("Contacts") );
+ //Status text
+ painter->setFont(m_statusFont);
+ painter->setOpacity(1.0);
+ painter->drawText(m_topBarStatusBarTextPoint, QString("My Status (fixed)") );
+ painter->restore();
+}
+
+QRectF TopBar::boundingRect() const
+{
+ //It's possible that m_topBarPixmap is not allocated yet,
+ //in this case default size is used for setting boundingRect
+ QHash<QString, QSize>sizes = (Theme::p()->theme() == Theme::Blue) ?
+ m_sizesBlue : m_sizesLime;
+
+ if (!m_topBarPixmap.isNull())
+ return QRectF(0, 0, m_topBarPixmap.size().width(), m_topBarPixmap.size().height());
+ else
+ return QRectF(0, 0, sizes["topbar.svg"].width(), sizes["topbar.svg"].height());
+}
+
+void TopBar::themeChange()
+{
+ m_titleFont = Theme::p()->font(Theme::TitleBar);
+ m_statusFont = Theme::p()->font(Theme::StatusBar);
+
+ //Calculate the scaling factor
+ QHash<QString, QSize>sizes = (Theme::p()->theme() == Theme::Blue) ?
+ m_sizesBlue : m_sizesLime;
+
+ QString topbarString= m_orientation == TopBar::Portrait ?
+ "topbar.svg" : "topbar_horisontal.svg";
+
+ QSize topBarSize = sizes[topbarString];
+ QSize newSize = QSize(topBarSize);
+
+ //Scale according to aspect ratio
+ newSize.scale(size().toSize(), Qt::KeepAspectRatio);
+
+ //fix width to window widht if previous scaling produced too narrow image
+ if(newSize.width() < size().width()) {
+ newSize.scale(size().toSize(), Qt::KeepAspectRatioByExpanding);
+ }
+
+ //Calculate scaling factor for rest of the graphics scaling
+ qreal scaleFactor = (newSize.width() *1.0) / (topBarSize.width() * 1.0);
+
+ //Background
+ m_topBarPixmap = Theme::p()->pixmap(topbarString, sizes[topbarString] * scaleFactor);
+
+ //User Icon
+ m_topBarUserIcon = Theme::p()->pixmap("user_default_icon.svg", sizes["user_default_icon.svg"] * scaleFactor);
+
+ //User Status
+ m_topBarUserStatus = Theme::p()->pixmap("user_status_online.svg", sizes["user_status_online.svg"] * scaleFactor);
+
+ //Status Bar
+ m_topBarStatusBarLeft = Theme::p()->pixmap("status_field_left.svg", sizes["status_field_left.svg"] * scaleFactor);
+ m_topBarStatusBarRight = Theme::p()->pixmap("status_field_right.svg", sizes["status_field_right.svg"] * scaleFactor);
+ m_topBarStatusBarMiddle = Theme::p()->pixmap("status_field_middle.svg",
+ QSize(185, sizes["status_field_middle.svg"].height())* scaleFactor);
+
+ //Update Drawing points for Top Bar elements, points are relative to the top bar background size
+ QSize topBarPixmapSize = m_topBarPixmap.size();
+ QSize topBarUserIconSize = m_topBarUserIcon.size();
+ QSize topBarUserStatusSize = m_topBarUserStatus.size();
+ QSize topBarStatusBarLeftSize = m_topBarStatusBarLeft.size();
+ QSize topBarStatusBarMiddleSize = m_topBarStatusBarMiddle.size();
+
+ //Theme Check
+ (Theme::p()->theme() == Theme::Lime) ? m_isLimeTheme = true : m_isLimeTheme = false;
+
+ //User Icon location
+ //Placing 70% of the width and 10% of the height of the top bar background
+ m_topBarUserIconPoint = QPoint((0.7*topBarPixmapSize.width()), (0.1*topBarPixmapSize.height()));
+
+ //If Blue theme is in use - position user status icon on the right side of the user icon
+ if(!m_isLimeTheme) {
+ //Place the status icon on top of the right edge of the user icon, lower it by 35% of the height of the user icon
+ m_topBarUserStatusPoint = QPoint( ( (m_topBarUserIconPoint.x()+topBarUserIconSize.width() ) - ( topBarUserStatusSize.width()/2 )),
+ (m_topBarUserIconPoint.y() + (topBarUserIconSize.height() * 0.35 )));
+ }
+ //If Lime theme is in use - position user status icon on the left side of the user icon
+ else {
+ //Place the status icon on top of the left side of the user icon, lower it by 50% of the height of the user icon
+ //and move left by 5% of the icon
+ m_topBarUserStatusPoint = QPoint( m_topBarUserIconPoint.x() + ( topBarUserIconSize.width() * 0.05),
+ (m_topBarUserIconPoint.y() + (topBarUserIconSize.height() * 0.5 )));
+ }
+
+ //Status bar
+ //Placing the left side of the status bar 5% of the width, 50% of the height of the top bar background
+ //Set the text baseline 80% of the height of the status bar
+ m_topBarStatusBarLeftPoint = QPoint( (topBarPixmapSize.width()* 0.05),
+ (topBarPixmapSize.height() * 0.5));
+ m_topBarStatusBarMiddlePoint = QPoint( (m_topBarStatusBarLeftPoint.x() + topBarStatusBarLeftSize.width()),
+ (m_topBarStatusBarLeftPoint.y()));
+ m_topBarStatusBarRightPoint = QPoint( (m_topBarStatusBarMiddlePoint.x() + topBarStatusBarMiddleSize.width()),
+ (m_topBarStatusBarMiddlePoint.y() ) );
+ m_topBarStatusBarTextPoint = QPoint(m_topBarStatusBarMiddlePoint.x(),
+ m_topBarStatusBarMiddlePoint.y() + (topBarStatusBarMiddleSize.height()*0.8) );
+
+ update();
+}
+
+QSizeF TopBar::sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint) const
+{
+ //It's possible that m_topBarPixmap is not allocated yet,
+ //in this case default size is used for setting size hint
+ QHash<QString, QSize>sizes = (Theme::p()->theme() == Theme::Blue) ?
+ m_sizesBlue : m_sizesLime;
+
+ int height = !m_topBarPixmap.isNull() ?
+ m_topBarPixmap.height() : sizes["topbar.svg"].height();
+
+ switch (which)
+ {
+ case Qt::MinimumSize:
+ return QSizeF(-1, height);
+
+ case Qt::MaximumSize:
+ return QSizeF(-1, height);
+
+ default:
+ return QGraphicsWidget::sizeHint(which, constraint);
+ }
+}
+
+void TopBar::setDefaultSizes()
+{
+ m_sizesBlue["topbar.svg"] = QSize(356,96);
+ m_sizesBlue["topbar_horisontal.svg"] = QSize(636,96);
+ m_sizesBlue["user_default_icon.svg"] = QSize(68,68);
+ m_sizesBlue["user_status_online.svg"] = QSize(38,38);
+ m_sizesBlue["status_field_left.svg"] = QSize(14,24);
+ m_sizesBlue["status_field_right.svg"] = QSize(10,24);
+ m_sizesBlue["status_field_middle.svg"] = QSize(14,24);
+
+ m_sizesLime["topbar.svg"] = QSize(356,96);
+ m_sizesLime["topbar_horisontal.svg"] = QSize(636,96);
+ m_sizesLime["user_default_icon.svg"] = QSize(84,68);
+ m_sizesLime["user_status_online.svg"] = QSize(24,24);
+ m_sizesLime["status_field_left.svg"] = QSize(14,24);
+ m_sizesLime["status_field_right.svg"] = QSize(10,24);
+ m_sizesLime["status_field_middle.svg"] = QSize(14,24);
+}
+
+void TopBar::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ QRect rect = m_topBarStatusBarMiddle.rect();
+ rect.moveTopLeft(m_topBarStatusBarMiddlePoint);
+ QPointF scenePoint = event->scenePos();
+ if(rect.contains(scenePoint.toPoint())) {
+ emit clicked();
+ }
+}
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h
new file mode 100644
index 0000000000..53750ca706
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __TOPBAR_H__
+#define __TOPBAR_H__
+
+#include <QObject>
+#include <QHash>
+
+#include "gvbwidget.h"
+
+class QPixmap;
+class QPoint;
+class QGraphicsView;
+class QFont;
+
+class TopBar : public GvbWidget
+{
+ Q_OBJECT
+
+public:
+ enum Orientation
+ {
+ Portrait,
+ Landscape,
+ None
+ };
+
+public:
+ TopBar(QGraphicsView* mainView, QGraphicsWidget* parent);
+ ~TopBar();
+
+public:
+ void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0 );
+ QRectF boundingRect() const;
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+ inline QPoint getStatusBarLocation()
+ {
+ return m_topBarStatusBarMiddlePoint + m_topBarStatusBarMiddle.rect().bottomLeft();
+ }
+
+public slots:
+ void themeChange();
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+
+signals:
+ void clicked(bool checked = false);
+
+private:
+ QSizeF sizeHint(Qt::SizeHint which,
+ const QSizeF &constraint = QSizeF()) const;
+ void setDefaultSizes();
+
+private:
+ Q_DISABLE_COPY(TopBar)
+
+ QGraphicsView* m_mainView;
+ bool m_isLimeTheme;
+ Orientation m_orientation;
+
+ //Fonts
+ QFont m_titleFont;
+ QFont m_statusFont;
+
+ //Pixmaps
+ QPixmap m_topBarPixmap;
+ QPixmap m_topBarUserIcon;
+ QPixmap m_topBarUserStatus;
+ QPixmap m_topBarStatusBarLeft;
+ QPixmap m_topBarStatusBarRight;
+ QPixmap m_topBarStatusBarMiddle;
+
+ //Drawing points
+ QPoint m_topBarUserIconPoint;
+ QPoint m_topBarUserStatusPoint;
+ QPoint m_topBarStatusBarLeftPoint;
+ QPoint m_topBarStatusBarRightPoint;
+ QPoint m_topBarStatusBarMiddlePoint;
+ QPoint m_topBarStatusBarTextPoint;
+ QPoint m_topBarTitlePoint;
+
+ //Sizes
+ QHash<QString, QSize> m_sizesBlue;
+ QHash<QString, QSize> m_sizesLime;
+};
+
+#endif // __TOPBAR_H__
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp
new file mode 100644
index 0000000000..59ed50157b
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "webview.h"
+#include "webview_p.h"
+#include <QtGui>
+
+static const int MotionEndWaitTime = 2000;
+static const int TileSideLength = 128;
+
+WebViewPrivate::WebViewPrivate(WebView *w)
+ : q(w)
+ , cache(0)
+{
+ web = new QGraphicsWebView;
+
+ web->setParentItem(q->viewport());
+
+ web->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ web->page()->mainFrame()->setScrollBarPolicy(
+ Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+ web->page()->mainFrame()->setScrollBarPolicy(
+ Qt::Vertical, Qt::ScrollBarAlwaysOff);
+ web->setZValue(3);
+
+// cache = new WebViewCache(web);
+// web->setGraphicsEffect(cache);
+
+ adjustSize();
+}
+
+void WebViewPrivate::adjustSize()
+{
+ QSizeF contentSize = web->page()->mainFrame()->contentsSize();
+ QPointF pos = web->pos();
+
+ qreal w = qMax(contentSize.width(), q->viewport()->boundingRect().width());
+ qreal h = qMax(contentSize.height(), q->viewport()->boundingRect().height());
+
+ if (web->boundingRect().size() != QSizeF(w, h)) {
+ //qDebug() << "WebView: adjustSize:" << QSizeF(w, h);
+
+ web->resize(w, h);
+ web->setPos(pos);
+
+ if (w > q->viewport()->boundingRect().width())
+ q->horizontalScrollBar()->setSliderSize(w);
+ else
+ q->horizontalScrollBar()->setSliderSize(0.0);
+
+ if (h > q->viewport()->boundingRect().height())
+ q->verticalScrollBar()->setSliderSize(h);
+ else
+ q->verticalScrollBar()->setSliderSize(0.0);
+ }
+}
+
+void WebViewPrivate::_q_loadStarted()
+{
+ qDebug() << "WebView: load started";
+ adjustSize();
+}
+
+void WebViewPrivate::_q_loadProgress(int progress)
+{
+ Q_UNUSED(progress)
+// qDebug() << "WebView: load progress" << progress;
+ adjustSize();
+}
+
+void WebViewPrivate::_q_loadFinished(bool ok)
+{
+ qDebug() << "WebView: load finished" << (ok ? "ok" : "not ok");
+ adjustSize();
+}
+
+void WebViewPrivate::_q_viewportChanged(QGraphicsWidget* viewport)
+{
+ web->setParentItem(viewport);
+ viewport->setFlag(QGraphicsItem::ItemClipsChildrenToShape,
+ true);
+ adjustSize();
+}
+
+void WebViewPrivate::_q_motionEnded()
+{
+ motionTimer.stop();
+ qDebug() << "Motion ended";
+ q->prepareGeometryChange();
+}
+
+WebViewCache::WebViewCache(QGraphicsWebView *webView)
+ : m_webView(webView)
+{
+}
+
+WebViewCache::~WebViewCache()
+{
+}
+
+void WebViewCache::draw(QPainter * painter, QGraphicsEffectSource * source)
+{
+ const QGraphicsItem *item = source->graphicsItem();
+
+ QSizeF itemSize = item->boundingRect().size();
+
+ if (!qFuzzyCompare(itemSize.width(), m_itemSize.width()) ||
+ !qFuzzyCompare(itemSize.height(), m_itemSize.height())) {
+ qDebug() << "Refresh tile cache, for new size" << itemSize;
+
+ for (int i = 0; i < m_tilePixmaps.size(); i++) {
+ QPixmapCache::remove(m_tilePixmaps[i]);
+ }
+
+ m_tilePixmaps.clear();
+ m_tileRects.clear();
+
+ int itemWidth = itemSize.width() + 0.5;
+ int itemHeight = itemSize.height() + 0.5;
+
+ int tilesX = itemWidth / TileSideLength;
+ int tilesY = itemHeight / TileSideLength;
+
+ if ((itemWidth % TileSideLength) != 0) {
+ ++tilesX;
+ }
+
+ if ((itemHeight % TileSideLength) != 0) {
+ ++tilesY;
+ }
+
+ int tilesCount = tilesX * tilesY;
+
+ m_tilePixmaps.resize(tilesCount);
+ m_tileRects.resize(tilesCount);
+
+ for (int i = 0; i < tilesX; i++) {
+ for (int j = 0; j < tilesY; j++) {
+ int x = i * TileSideLength;
+ int y = j * TileSideLength;
+
+ m_tileRects[i + j * tilesX]
+ = QRectF(x, y, TileSideLength, TileSideLength);
+ }
+ }
+
+ m_itemSize = itemSize;
+ }
+
+ const QGraphicsItem *parentItem = item->parentItem();
+ QPointF itemPos = item->pos();
+ QRectF parentRect = parentItem->boundingRect();
+
+ for (int i = 0; i < m_tileRects.size(); i++) {
+ QRectF tileRect = m_tileRects[i].translated(itemPos);
+
+ if (!tileRect.intersects(parentRect) && !tileRect.contains(parentRect)) {
+ continue;
+ }
+
+ QPixmap tilePixmap;
+
+ if (!QPixmapCache::find(m_tilePixmaps[i], &tilePixmap)) {
+ tilePixmap = QPixmap(TileSideLength, TileSideLength);
+
+ QWebFrame *webFrame = m_webView->page()->mainFrame();
+
+ QPainter tilePainter(&tilePixmap);
+ tilePainter.translate(-m_tileRects[i].left(), -m_tileRects[i].top());
+ webFrame->render(&tilePainter, m_tileRects[i].toRect());
+ tilePainter.end();
+
+ m_tilePixmaps[i] = QPixmapCache::insert(tilePixmap);
+ }
+
+ tileRect = tileRect.translated(-itemPos);
+
+ painter->drawPixmap(tileRect.topLeft(), tilePixmap);
+ }
+}
+
+WebView::WebView(QGraphicsWidget *parent)
+ : AbstractScrollArea(parent)
+ , d(new WebViewPrivate(this))
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setContentsMargins(0, 0, 0, 0);
+ connect(d->web->page(), SIGNAL(loadStarted()),
+ this, SLOT(_q_loadStarted()));
+ connect(d->web->page(), SIGNAL(loadProgress(int)),
+ this, SLOT(_q_loadProgress(int)));
+ connect(d->web->page(), SIGNAL(loadFinished(bool)),
+ this, SLOT(_q_loadFinished(bool)));
+ connect(this, SIGNAL(viewportChanged(QGraphicsWidget*)),
+ this, SLOT(_q_viewportChanged(QGraphicsWidget*)));
+ connect(&d->motionTimer, SIGNAL(timeout()),
+ this, SLOT(_q_motionEnded()));
+}
+
+WebView::~WebView()
+{
+ d->web->setGraphicsEffect(0);
+ delete d->cache;
+}
+
+void WebView::setUrl(const QUrl& url)
+{
+ d->adjustSize();
+ d->web->setUrl(url);
+}
+
+void WebView::scrollContentsBy(qreal dx, qreal dy)
+{
+ if (qFuzzyCompare((float)dy, 0.0f) && qFuzzyCompare((float)dx, 0.0f))
+ return;
+
+ if (!d->motionTimer.isActive()) {
+ d->motionTimer.start(MotionEndWaitTime);
+ }
+
+ QSizeF contentSize = d->web->page()->mainFrame()->contentsSize();
+ QRectF viewportRect = viewport()->boundingRect();
+ QPointF pos = d->web->pos();
+
+ qreal w = qMax(contentSize.width(), viewportRect.width());
+ qreal h = qMax(contentSize.height(), viewportRect.height());
+
+ qreal minx = qMin(0.0f, (float) -(w - viewportRect.width()));
+ qreal miny = qMin(0.0f, (float) -(h - viewportRect.height()));
+
+ qreal x = d->web->pos().x() - dx;
+
+ if (x < minx)
+ x = minx;
+ else if (x > 0)
+ x = 0.0;
+
+ qreal y = d->web->pos().y() - dy;
+
+ if (y < miny)
+ y = miny;
+ else if (y > 0)
+ y = 0.0;
+
+ d->web->setPos(x, y);
+}
+
+QSizeF WebView::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
+{
+ if (which == Qt::PreferredSize) {
+ QSizeF contentSize = d->web->page()->mainFrame()->contentsSize();
+ return contentSize;
+ }
+
+ return AbstractScrollArea::sizeHint(which, constraint);
+}
+
+void WebView::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ AbstractScrollArea::resizeEvent(event);
+ d->adjustSize();
+}
+
+#include "moc_webview.cpp"
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h
new file mode 100644
index 0000000000..a18df35957
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEBVIEW_H
+#define WEBVIEW_H
+
+#include "scrollbar.h"
+#include "abstractscrollarea.h"
+
+class WebViewPrivate;
+
+class WebView : public AbstractScrollArea
+{
+ Q_OBJECT
+
+public:
+
+ WebView(QGraphicsWidget *parent = 0);
+ ~WebView();
+
+public:
+
+ void setUrl(const QUrl& url);
+
+private:
+
+ void scrollContentsBy(qreal dx, qreal dy);
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint) const;
+
+private:
+
+ Q_PRIVATE_SLOT(d, void _q_loadStarted())
+ Q_PRIVATE_SLOT(d, void _q_loadProgress(int))
+ Q_PRIVATE_SLOT(d, void _q_loadFinished(bool))
+ Q_PRIVATE_SLOT(d, void _q_viewportChanged(QGraphicsWidget*))
+ Q_PRIVATE_SLOT(d, void _q_motionEnded())
+
+ WebViewPrivate *d;
+ friend class WebViewPrivate;
+};
+
+#endif // WEBVIEW_H
diff --git a/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h
new file mode 100644
index 0000000000..bd4047c134
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEBVIEW_P_H
+#define WEBVIEW_P_H
+
+#include "webview.h"
+#include <QtWebKit/qgraphicswebview.h>
+#include <QtWebKit/qwebpage.h>
+#include <QtWebKit/qwebframe.h>
+#include <QGraphicsEffect>
+#include <QPainter>
+#include <QPixmapCache>
+#include <QTimer>
+#include <QDebug>
+
+class WebViewCache;
+
+class WebViewPrivate {
+public:
+
+ WebViewPrivate(WebView *w);
+ void adjustSize();
+ void _q_loadStarted();
+ void _q_loadProgress(int);
+ void _q_loadFinished(bool);
+ void _q_viewportChanged(QGraphicsWidget*);
+ void _q_motionEnded();
+
+ WebView *q;
+ QGraphicsWebView *web;
+ WebViewCache *cache;
+ QTimer motionTimer;
+};
+
+class WebViewCache : public QGraphicsEffect
+{
+ Q_OBJECT
+
+public:
+
+ WebViewCache(QGraphicsWebView *webView);
+ virtual ~WebViewCache();
+
+public:
+
+ void refresh();
+
+ void draw(QPainter * painter, QGraphicsEffectSource * source);
+
+private:
+
+ QVector<QRectF> m_tileRects;
+ QVector<QPixmapCache::Key> m_tilePixmaps;
+ QSizeF m_itemSize;
+ QGraphicsWebView *m_webView;
+
+ friend class WebViewPrivate;
+};
+
+#endif // WEBVIEW_P_H