tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtTest/QtTest>
       
    43 #include <QtGui/qgraphicsanchorlayout.h>
       
    44 #include <QtGui/qgraphicslinearlayout.h>
       
    45 #include <QtGui/qgraphicswidget.h>
       
    46 #include <QtGui/qgraphicsview.h>
       
    47 
       
    48 class tst_QGraphicsAnchorLayout : public QObject
       
    49 {
       
    50     Q_OBJECT
       
    51 public:
       
    52     tst_QGraphicsAnchorLayout() {}
       
    53     ~tst_QGraphicsAnchorLayout() {}
       
    54 
       
    55 private slots:
       
    56     void s60_hard_complex_data();
       
    57     void s60_hard_complex();
       
    58     void linearVsAnchorSizeHints_data();
       
    59     void linearVsAnchorSizeHints();
       
    60     void linearVsAnchorSetGeometry_data();
       
    61     void linearVsAnchorSetGeometry();
       
    62     void linearVsAnchorNested_data();
       
    63     void linearVsAnchorNested();
       
    64 };
       
    65 
       
    66 
       
    67 class RectWidget : public QGraphicsWidget
       
    68 {
       
    69 public:
       
    70     RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){}
       
    71 
       
    72     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
    73     {
       
    74         Q_UNUSED(option);
       
    75         Q_UNUSED(widget);
       
    76         painter->drawRoundRect(rect());
       
    77         painter->drawLine(rect().topLeft(), rect().bottomRight());
       
    78         painter->drawLine(rect().bottomLeft(), rect().topRight());
       
    79     }
       
    80 };
       
    81 
       
    82 static QGraphicsWidget *createItem(const QSizeF &minimum = QSizeF(100.0, 100.0),
       
    83                                    const QSizeF &preferred = QSize(150.0, 100.0),
       
    84                                    const QSizeF &maximum = QSizeF(200.0, 100.0),
       
    85                                    const QString &name = QString())
       
    86 {
       
    87     QGraphicsWidget *w = new RectWidget;
       
    88     w->setMinimumSize(minimum);
       
    89     w->setPreferredSize(preferred);
       
    90     w->setMaximumSize(maximum);
       
    91     w->setData(0, name);
       
    92     return w;
       
    93 }
       
    94 
       
    95 static void setAnchor(QGraphicsAnchorLayout *l,
       
    96                       QGraphicsLayoutItem *firstItem,
       
    97                       Qt::AnchorPoint firstEdge,
       
    98                       QGraphicsLayoutItem *secondItem,
       
    99                       Qt::AnchorPoint secondEdge,
       
   100                       qreal spacing)
       
   101 {
       
   102     QGraphicsAnchor *anchor = l->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
       
   103     anchor->setSpacing(spacing);
       
   104 }
       
   105 
       
   106 void tst_QGraphicsAnchorLayout::s60_hard_complex_data()
       
   107 {
       
   108     QTest::addColumn<int>("whichSizeHint");
       
   109     QTest::newRow("minimumSizeHint")
       
   110         << int(Qt::MinimumSize);
       
   111     QTest::newRow("preferredSizeHint")
       
   112         << int(Qt::PreferredSize);
       
   113     QTest::newRow("maximumSizeHint")
       
   114         << int(Qt::MaximumSize);
       
   115     // Add it as a reference to see how much overhead the body of effectiveSizeHint takes.
       
   116     QTest::newRow("noSizeHint")
       
   117         << -1;
       
   118 }
       
   119 
       
   120 void tst_QGraphicsAnchorLayout::s60_hard_complex()
       
   121 {
       
   122     QFETCH(int, whichSizeHint);
       
   123 
       
   124     // Test for "hard" complex case, taken from wiki
       
   125     // https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases
       
   126     QSizeF min(0, 10);
       
   127     QSizeF pref(50, 10);
       
   128     QSizeF max(100, 10);
       
   129 
       
   130     QGraphicsWidget *a = createItem(min, pref, max, "a");
       
   131     QGraphicsWidget *b = createItem(min, pref, max, "b");
       
   132     QGraphicsWidget *c = createItem(min, pref, max, "c");
       
   133     QGraphicsWidget *d = createItem(min, pref, max, "d");
       
   134     QGraphicsWidget *e = createItem(min, pref, max, "e");
       
   135     QGraphicsWidget *f = createItem(min, pref, max, "f");
       
   136     QGraphicsWidget *g = createItem(min, pref, max, "g");
       
   137 
       
   138     QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout;
       
   139     l->setContentsMargins(0, 0, 0, 0);
       
   140 
       
   141     //<!-- Trunk -->
       
   142     setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 10);
       
   143     setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 10);
       
   144     setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft, 10);
       
   145     setAnchor(l, c, Qt::AnchorRight, d, Qt::AnchorLeft, 10);
       
   146     setAnchor(l, d, Qt::AnchorRight, l, Qt::AnchorRight, 10);
       
   147 
       
   148     //<!-- Above trunk -->
       
   149     setAnchor(l, b, Qt::AnchorLeft, e, Qt::AnchorLeft, 10);
       
   150     setAnchor(l, e, Qt::AnchorRight, d, Qt::AnchorLeft, 10);
       
   151 
       
   152     //<!-- Below trunk -->
       
   153     setAnchor(l, a, Qt::AnchorHorizontalCenter, g, Qt::AnchorLeft, 10);
       
   154     setAnchor(l, g, Qt::AnchorRight, f, Qt::AnchorHorizontalCenter, 10);
       
   155     setAnchor(l, c, Qt::AnchorLeft, f, Qt::AnchorLeft, 10);
       
   156     setAnchor(l, f, Qt::AnchorRight, d, Qt::AnchorRight, 10);
       
   157 
       
   158     //<!-- vertical is simpler -->
       
   159     setAnchor(l, l, Qt::AnchorTop, e, Qt::AnchorTop, 0);
       
   160     setAnchor(l, e, Qt::AnchorBottom, a, Qt::AnchorTop, 0);
       
   161     setAnchor(l, e, Qt::AnchorBottom, b, Qt::AnchorTop, 0);
       
   162     setAnchor(l, e, Qt::AnchorBottom, c, Qt::AnchorTop, 0);
       
   163     setAnchor(l, e, Qt::AnchorBottom, d, Qt::AnchorTop, 0);
       
   164     setAnchor(l, a, Qt::AnchorBottom, f, Qt::AnchorTop, 0);
       
   165     setAnchor(l, a, Qt::AnchorBottom, b, Qt::AnchorBottom, 0);
       
   166     setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorBottom, 0);
       
   167     setAnchor(l, a, Qt::AnchorBottom, d, Qt::AnchorBottom, 0);
       
   168     setAnchor(l, f, Qt::AnchorBottom, g, Qt::AnchorTop, 0);
       
   169     setAnchor(l, g, Qt::AnchorBottom, l, Qt::AnchorBottom, 0);
       
   170 
       
   171     // It won't query the size hint if it already has a size set.
       
   172     // If only one of the sizes is unset it will query sizeHint only of for that hint type.
       
   173     l->setMinimumSize(60,40);
       
   174     l->setPreferredSize(220,40);
       
   175     l->setMaximumSize(240,40);
       
   176 
       
   177     switch (whichSizeHint) {
       
   178     case Qt::MinimumSize:
       
   179         l->setMinimumSize(-1, -1);
       
   180         break;
       
   181     case Qt::PreferredSize:
       
   182         l->setPreferredSize(-1, -1);
       
   183         break;
       
   184     case Qt::MaximumSize:
       
   185         l->setMaximumSize(-1, -1);
       
   186         break;
       
   187     default:
       
   188         break;
       
   189     }
       
   190 
       
   191     QSizeF sizeHint;
       
   192     // warm up instruction cache
       
   193     l->invalidate();
       
   194     sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
       
   195     // ...then measure...
       
   196     QBENCHMARK {
       
   197         l->invalidate();
       
   198         sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
       
   199     }
       
   200 }
       
   201 
       
   202 static QGraphicsLayout* createLayouts(int whichLayout)
       
   203 {
       
   204     QSizeF min(0, 10);
       
   205     QSizeF pref(50, 10);
       
   206     QSizeF max(100, 10);
       
   207 
       
   208     QGraphicsWidget *a = createItem(min, pref, max, "a");
       
   209     QGraphicsWidget *b = createItem(min, pref, max, "b");
       
   210     QGraphicsWidget *c = createItem(min, pref, max, "c");
       
   211     QGraphicsWidget *d = createItem(min, pref, max, "d");
       
   212 
       
   213     QGraphicsLayout *l;
       
   214     if (whichLayout == 0) {
       
   215         l = new QGraphicsLinearLayout;
       
   216         QGraphicsLinearLayout *linear = static_cast<QGraphicsLinearLayout *>(l);
       
   217         linear->setContentsMargins(0, 0, 0, 0);
       
   218 
       
   219         linear->addItem(a);
       
   220         linear->addItem(b);
       
   221         linear->addItem(c);
       
   222         linear->addItem(d);
       
   223     } else {
       
   224         l = new QGraphicsAnchorLayout;
       
   225         QGraphicsAnchorLayout *anchor = static_cast<QGraphicsAnchorLayout *>(l);
       
   226         anchor->setContentsMargins(0, 0, 0, 0);
       
   227 
       
   228         // Horizontal
       
   229         setAnchor(anchor, anchor, Qt::AnchorLeft, a, Qt::AnchorLeft, 0);
       
   230         setAnchor(anchor, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0);
       
   231         setAnchor(anchor, b, Qt::AnchorRight, c, Qt::AnchorLeft, 0);
       
   232         setAnchor(anchor, c, Qt::AnchorRight, d, Qt::AnchorLeft, 0);
       
   233         setAnchor(anchor, d, Qt::AnchorRight, anchor, Qt::AnchorRight, 0);
       
   234 
       
   235         // Vertical
       
   236         anchor->addAnchors(anchor, a, Qt::Vertical);
       
   237         anchor->addAnchors(anchor, b, Qt::Vertical);
       
   238         anchor->addAnchors(anchor, c, Qt::Vertical);
       
   239         anchor->addAnchors(anchor, d, Qt::Vertical);
       
   240     }
       
   241 
       
   242     return l;
       
   243 }
       
   244 
       
   245 void tst_QGraphicsAnchorLayout::linearVsAnchorSizeHints_data()
       
   246 {
       
   247     QTest::addColumn<int>("whichLayout");
       
   248     QTest::addColumn<int>("whichSizeHint");
       
   249 
       
   250     QTest::newRow("QGraphicsLinearLayout::minimum")
       
   251         << 0 << int(Qt::MinimumSize);
       
   252     QTest::newRow("QGraphicsLinearLayout::preferred")
       
   253         << 0 << int(Qt::PreferredSize);
       
   254     QTest::newRow("QGraphicsLinearLayout::maximum")
       
   255         << 0 << int(Qt::MaximumSize);
       
   256     QTest::newRow("QGraphicsLinearLayout::noSizeHint")
       
   257         << 0 << -1;
       
   258 
       
   259     QTest::newRow("QGraphicsAnchorLayout::minimum")
       
   260         << 1 << int(Qt::MinimumSize);
       
   261     QTest::newRow("QGraphicsAnchorLayout::preferred")
       
   262         << 1 << int(Qt::PreferredSize);
       
   263     QTest::newRow("QGraphicsAnchorLayout::maximum")
       
   264         << 1 << int(Qt::MaximumSize);
       
   265     QTest::newRow("QGraphicsAnchorLayout::noSizeHint")
       
   266         << 1 << -1;
       
   267 }
       
   268 
       
   269 void tst_QGraphicsAnchorLayout::linearVsAnchorSizeHints()
       
   270 {
       
   271     QFETCH(int, whichSizeHint);
       
   272     QFETCH(int, whichLayout);
       
   273 
       
   274     QGraphicsLayout *l = createLayouts(whichLayout);
       
   275 
       
   276     QSizeF sizeHint;
       
   277     // warm up instruction cache
       
   278     l->invalidate();
       
   279     sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
       
   280     // ...then measure...
       
   281 
       
   282     QBENCHMARK {
       
   283         l->invalidate();
       
   284         sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint);
       
   285     }
       
   286 }
       
   287 
       
   288 void tst_QGraphicsAnchorLayout::linearVsAnchorSetGeometry_data()
       
   289 {
       
   290     QTest::addColumn<int>("whichLayout");
       
   291 
       
   292     QTest::newRow("QGraphicsLinearLayout")
       
   293         << 0;
       
   294     QTest::newRow("QGraphicsAnchorLayout")
       
   295         << 1;
       
   296 }
       
   297 
       
   298 void tst_QGraphicsAnchorLayout::linearVsAnchorSetGeometry()
       
   299 {
       
   300     QFETCH(int, whichLayout);
       
   301 
       
   302     QGraphicsLayout *l = createLayouts(whichLayout);
       
   303 
       
   304     QRectF sizeHint;
       
   305     qreal maxWidth;
       
   306     qreal increment;
       
   307     // warm up instruction cache
       
   308     l->invalidate();
       
   309     sizeHint.setSize(l->effectiveSizeHint(Qt::MinimumSize));
       
   310     maxWidth = l->effectiveSizeHint(Qt::MaximumSize).width();
       
   311     increment = (maxWidth - sizeHint.width()) / 100;
       
   312     l->setGeometry(sizeHint);
       
   313     // ...then measure...
       
   314 
       
   315     QBENCHMARK {
       
   316         l->invalidate();
       
   317         for (qreal width = sizeHint.width(); width <= maxWidth; width += increment) {
       
   318             sizeHint.setWidth(width);
       
   319             l->setGeometry(sizeHint);
       
   320         }
       
   321     }
       
   322 }
       
   323 
       
   324 void tst_QGraphicsAnchorLayout::linearVsAnchorNested_data()
       
   325 {
       
   326     QTest::addColumn<int>("whichLayout");
       
   327     QTest::newRow("LinearLayout")
       
   328         << 0;
       
   329     QTest::newRow("AnchorLayout setup with null-anchors knot")
       
   330         << 1;
       
   331     QTest::newRow("AnchorLayout setup easy to simplificate")
       
   332         << 2;
       
   333 }
       
   334 
       
   335 void tst_QGraphicsAnchorLayout::linearVsAnchorNested()
       
   336 {
       
   337     QFETCH(int, whichLayout);
       
   338 
       
   339     QSizeF min(10, 10);
       
   340     QSizeF pref(80, 80);
       
   341     QSizeF max(150, 150);
       
   342 
       
   343     QGraphicsWidget *a = createItem(min, pref, max, "a");
       
   344     QGraphicsWidget *b = createItem(min, pref, max, "b");
       
   345     QGraphicsWidget *c = createItem(min, pref, max, "c");
       
   346     QGraphicsWidget *d = createItem(min, pref, max, "d");
       
   347 
       
   348     QGraphicsLayout *layout;
       
   349 
       
   350     if (whichLayout == 0) {
       
   351         QGraphicsLinearLayout *linear1 = new QGraphicsLinearLayout;
       
   352         QGraphicsLinearLayout *linear2 = new QGraphicsLinearLayout(Qt::Vertical);
       
   353         QGraphicsLinearLayout *linear3 = new QGraphicsLinearLayout;
       
   354 
       
   355         linear1->addItem(a);
       
   356         linear1->addItem(linear2);
       
   357         linear2->addItem(b);
       
   358         linear2->addItem(linear3);
       
   359         linear3->addItem(c);
       
   360         linear3->addItem(d);
       
   361 
       
   362         layout = linear1;
       
   363     } else if (whichLayout == 1) {
       
   364         QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout;
       
   365 
       
   366         // A
       
   367         anchor->addCornerAnchors(a, Qt::TopLeftCorner, anchor, Qt::TopLeftCorner);
       
   368         anchor->addCornerAnchors(a, Qt::TopRightCorner, b, Qt::TopLeftCorner);
       
   369         anchor->addCornerAnchors(a, Qt::BottomLeftCorner, anchor, Qt::BottomLeftCorner);
       
   370         anchor->addCornerAnchors(a, Qt::BottomRightCorner, c, Qt::BottomLeftCorner);
       
   371 
       
   372         // B
       
   373         anchor->addCornerAnchors(b, Qt::TopRightCorner, anchor, Qt::TopRightCorner);
       
   374         anchor->addCornerAnchors(b, Qt::BottomLeftCorner, c, Qt::TopLeftCorner);
       
   375         anchor->addCornerAnchors(b, Qt::BottomRightCorner, d, Qt::TopRightCorner);
       
   376 
       
   377         // C
       
   378         anchor->addCornerAnchors(c, Qt::TopRightCorner, d, Qt::TopLeftCorner);
       
   379         anchor->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::BottomLeftCorner);
       
   380 
       
   381         // D
       
   382         anchor->addCornerAnchors(d, Qt::BottomRightCorner, anchor, Qt::BottomRightCorner);
       
   383 
       
   384         layout = anchor;
       
   385     } else {
       
   386         QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout;
       
   387 
       
   388         // A
       
   389         anchor->addAnchor(a, Qt::AnchorLeft, anchor, Qt::AnchorLeft);
       
   390         anchor->addAnchors(a, anchor, Qt::Vertical);
       
   391         anchor->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft);
       
   392         anchor->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft);
       
   393 
       
   394         // B
       
   395         anchor->addAnchor(b, Qt::AnchorTop, anchor, Qt::AnchorTop);
       
   396         anchor->addAnchor(b, Qt::AnchorRight, anchor, Qt::AnchorRight);
       
   397         anchor->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop);
       
   398         anchor->addAnchor(b, Qt::AnchorBottom, d, Qt::AnchorTop);
       
   399 
       
   400         // C
       
   401         anchor->addAnchor(c, Qt::AnchorRight, d, Qt::AnchorLeft);
       
   402         anchor->addAnchor(c, Qt::AnchorBottom, anchor, Qt::AnchorBottom);
       
   403 
       
   404         // D
       
   405         anchor->addAnchor(d, Qt::AnchorRight, anchor, Qt::AnchorRight);
       
   406         anchor->addAnchor(d, Qt::AnchorBottom, anchor, Qt::AnchorBottom);
       
   407 
       
   408         layout = anchor;
       
   409     }
       
   410 
       
   411     QSizeF sizeHint;
       
   412     // warm up instruction cache
       
   413     layout->invalidate();
       
   414     sizeHint = layout->effectiveSizeHint(Qt::PreferredSize);
       
   415 
       
   416     // ...then measure...
       
   417     QBENCHMARK {
       
   418         // To ensure that all sizeHints caches are invalidated in
       
   419         // the LinearLayout setup, we must call updateGeometry on the
       
   420         // children. If we didn't, only the top level layout would be
       
   421         // re-calculated.
       
   422         static_cast<QGraphicsLayoutItem *>(a)->updateGeometry();
       
   423         static_cast<QGraphicsLayoutItem *>(b)->updateGeometry();
       
   424         static_cast<QGraphicsLayoutItem *>(c)->updateGeometry();
       
   425         static_cast<QGraphicsLayoutItem *>(d)->updateGeometry();
       
   426         layout->invalidate();
       
   427         sizeHint = layout->effectiveSizeHint(Qt::PreferredSize);
       
   428     }
       
   429 }
       
   430 
       
   431 QTEST_MAIN(tst_QGraphicsAnchorLayout)
       
   432 
       
   433 #include "tst_qgraphicsanchorlayout.moc"