demos/qtdemo/mainwindow.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 demonstration applications 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 "mainwindow.h"
       
    43 #include "menumanager.h"
       
    44 #include "colors.h"
       
    45 #include "dockitem.h"
       
    46 #include "demotextitem.h"
       
    47 #include "imageitem.h"
       
    48 #include "demoitem.h"
       
    49 #include "demoscene.h"
       
    50 
       
    51 #ifndef QT_NO_OPENGL
       
    52     #include <QGLWidget>
       
    53 #endif
       
    54 //#define QT_NO_OPENGL
       
    55 
       
    56 MainWindow::MainWindow(QWidget *parent) : QGraphicsView(parent), updateTimer(this)
       
    57 {
       
    58     this->currentFps = Colors::fps;
       
    59     this->loop = false;
       
    60     this->fpsMedian = -1;
       
    61     this->fpsLabel = 0;
       
    62     this->pausedLabel = 0;
       
    63     this->doneAdapt = false;
       
    64     this->useTimer = false;
       
    65     this->updateTimer.setSingleShot(true);
       
    66     this->companyLogo = 0;
       
    67     this->qtLogo = 0;
       
    68     this->setupWidget();
       
    69     this->setupScene();
       
    70     this->setupSceneItems();
       
    71     this->drawBackgroundToPixmap();
       
    72 }
       
    73 
       
    74 MainWindow::~MainWindow()
       
    75 {
       
    76     delete this->companyLogo;
       
    77     delete this->qtLogo;
       
    78 }
       
    79 
       
    80 void MainWindow::setupWidget()
       
    81 {
       
    82     QRect screenRect = QApplication::desktop()->screenGeometry(QApplication::desktop()->primaryScreen());
       
    83     QRect windowRect(0, 0, 800, 600);
       
    84     if (screenRect.width() < 800)
       
    85         windowRect.setWidth(screenRect.width());
       
    86     if (screenRect.height() < 600)
       
    87         windowRect.setHeight(screenRect.height());
       
    88     windowRect.moveCenter(screenRect.center());
       
    89     this->setGeometry(windowRect);
       
    90     this->setMinimumSize(80, 60);
       
    91     setWindowTitle(tr("Qt Examples and Demos"));
       
    92     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
    93     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
    94     setFrameStyle(QFrame::NoFrame);
       
    95     this->setRenderingSystem();
       
    96     connect(&this->updateTimer, SIGNAL(timeout()), this, SLOT(tick()));
       
    97 }
       
    98 
       
    99 void MainWindow::setRenderingSystem()
       
   100 {
       
   101     QWidget *viewport = 0;
       
   102 
       
   103 #ifndef QT_NO_OPENGL
       
   104     if (Colors::openGlRendering) {
       
   105         QGLWidget *glw = new QGLWidget(QGLFormat(QGL::SampleBuffers));
       
   106         if (Colors::noScreenSync)
       
   107             glw->format().setSwapInterval(0);
       
   108         glw->setAutoFillBackground(false);
       
   109         viewport = glw;
       
   110         setCacheMode(QGraphicsView::CacheNone);
       
   111         if (Colors::verbose)
       
   112             qDebug() << "- using OpenGL";
       
   113     } else // software rendering
       
   114 #endif
       
   115     {
       
   116         // software rendering
       
   117         viewport = new QWidget;
       
   118         setCacheMode(QGraphicsView::CacheBackground);
       
   119         if (Colors::verbose)
       
   120             qDebug() << "- using software rendering";
       
   121     }
       
   122 
       
   123     setViewport(viewport);
       
   124 }
       
   125 
       
   126 void MainWindow::start()
       
   127 {
       
   128     this->switchTimerOnOff(true);
       
   129     this->demoStartTime.restart();
       
   130     MenuManager::instance()->itemSelected(MenuManager::ROOT, Colors::rootMenuName);
       
   131     if (Colors::verbose)
       
   132         qDebug("- starting demo");
       
   133 }
       
   134 
       
   135 void MainWindow::enableMask(bool enable)
       
   136 {
       
   137     if (!enable || Colors::noWindowMask)
       
   138         this->clearMask();
       
   139     else {
       
   140         QPolygon region;
       
   141         region.setPoints(9,
       
   142                                 // north side:
       
   143                                 0, 0,
       
   144                                 800, 0,
       
   145                                 // east side:
       
   146                                 // 800, 70,
       
   147                                 // 790, 90,
       
   148                                 // 790, 480,
       
   149                                 // 800, 500,
       
   150                                 800, 600,
       
   151                                 // south side:
       
   152                                 700, 600,
       
   153                                 670, 590,
       
   154                                 130, 590,
       
   155                                 100, 600,
       
   156                                 0, 600,
       
   157                                 // west side:
       
   158                                 // 0, 550,
       
   159                                 // 10, 530,
       
   160                                 // 10, 520,
       
   161                                 // 0, 520,
       
   162                                 0, 0);
       
   163         this->setMask(QRegion(region));
       
   164     }
       
   165 }
       
   166 
       
   167 void MainWindow::setupScene()
       
   168 {
       
   169     this->scene = new DemoScene(this);
       
   170     this->scene->setSceneRect(0, 0, 800, 600);
       
   171     setScene(this->scene);
       
   172     this->scene->setItemIndexMethod(QGraphicsScene::NoIndex);
       
   173 }
       
   174 
       
   175 void MainWindow::drawItems(QPainter *painter, int numItems, QGraphicsItem **items, const QStyleOptionGraphicsItem* options)
       
   176 {
       
   177     QGraphicsView::drawItems(painter, numItems, items, options);
       
   178 }
       
   179 
       
   180 void MainWindow::switchTimerOnOff(bool on)
       
   181 {
       
   182     bool ticker = MenuManager::instance()->ticker && MenuManager::instance()->ticker->scene();
       
   183     if (ticker)
       
   184         MenuManager::instance()->ticker->tickOnPaint = !on || Colors::noTimerUpdate;
       
   185 
       
   186     if (on && !Colors::noTimerUpdate){
       
   187         this->useTimer = true;
       
   188         this->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
       
   189         this->fpsTime = QTime::currentTime();
       
   190         this->updateTimer.start(int(1000 / Colors::fps));
       
   191     }
       
   192     else{
       
   193         this->useTimer = false;
       
   194         this->updateTimer.stop();
       
   195         if (Colors::softwareRendering)
       
   196             if (Colors::noTicker)
       
   197                 this->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
       
   198             else
       
   199                 this->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
       
   200         else
       
   201             this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
       
   202     }
       
   203 }
       
   204 
       
   205 bool MainWindow::measureFps()
       
   206 {
       
   207     // Calculate time diff:
       
   208     float t = this->fpsTime.msecsTo(QTime::currentTime());
       
   209     if (t == 0)
       
   210         t = 0.01f;
       
   211     this->currentFps = (1000.0f / t);
       
   212     this->fpsHistory += this->currentFps;
       
   213     this->fpsTime = QTime::currentTime();
       
   214 
       
   215     // Calculate median:
       
   216     int size = this->fpsHistory.size();
       
   217     if (size == 10){
       
   218         qSort(this->fpsHistory.begin(), this->fpsHistory.end());
       
   219         this->fpsMedian = this->fpsHistory.at(int(size/2));
       
   220         if (this->fpsMedian == 0)
       
   221             this->fpsMedian = 0.01f;
       
   222         this->fpsHistory.clear();
       
   223         return true;
       
   224     }
       
   225     return false;
       
   226 }
       
   227 
       
   228 /**
       
   229     Used for adaption in case things are so slow
       
   230     that no median  yet has been calculated
       
   231 */
       
   232 void MainWindow::forceFpsMedianCalculation()
       
   233 {
       
   234     if (this->fpsMedian != -1)
       
   235         return;
       
   236 
       
   237     int size = this->fpsHistory.size();
       
   238     if (size == 0){
       
   239         this->fpsMedian = 0.01f;
       
   240         return;
       
   241     }
       
   242 
       
   243     qSort(this->fpsHistory.begin(), this->fpsHistory.end());
       
   244     this->fpsMedian = this->fpsHistory.at(int(size/2));
       
   245     if (this->fpsMedian == 0)
       
   246         this->fpsMedian = 0.01f;
       
   247 }
       
   248 
       
   249 void MainWindow::tick()
       
   250 {
       
   251     bool medianChanged = this->measureFps();
       
   252     this->checkAdapt();
       
   253 
       
   254     if (medianChanged && this->fpsLabel && Colors::showFps)
       
   255         this->fpsLabel->setText(QString("FPS: ") + QString::number(int(this->currentFps)));
       
   256 
       
   257     if (MenuManager::instance()->ticker)
       
   258         MenuManager::instance()->ticker->tick();
       
   259 
       
   260     this->viewport()->update();
       
   261     if (this->useTimer)
       
   262         this->updateTimer.start(int(1000 / Colors::fps));
       
   263 }
       
   264 
       
   265 void MainWindow::setupSceneItems()
       
   266 {
       
   267     if (Colors::showFps){
       
   268         this->fpsLabel = new DemoTextItem(QString("FPS: --"), Colors::buttonFont(), Qt::white, -1, this->scene, 0, DemoTextItem::DYNAMIC_TEXT);
       
   269         this->fpsLabel->setZValue(100);
       
   270         this->fpsLabel->setPos(Colors::stageStartX, 600 - QFontMetricsF(Colors::buttonFont()).height() - 5);
       
   271     }
       
   272 
       
   273     this->companyLogo = new ImageItem(QImage(":/images/trolltech-logo.png"), 1000, 1000, this->scene, 0, true, 0.5f);
       
   274     this->qtLogo = new ImageItem(QImage(":/images/qtlogo_small.png"), 1000, 1000, this->scene, 0, true, 0.5f);
       
   275     this->companyLogo->setZValue(100);
       
   276     this->qtLogo->setZValue(100);
       
   277     this->pausedLabel = new DemoTextItem(QString("PAUSED"), Colors::buttonFont(), Qt::white, -1, this->scene, 0);
       
   278     this->pausedLabel->setZValue(100);
       
   279     QFontMetricsF fm(Colors::buttonFont());
       
   280     this->pausedLabel->setPos(Colors::stageWidth - fm.width("PAUSED"), 590 - fm.height());
       
   281     this->pausedLabel->setRecursiveVisible(false);
       
   282 }
       
   283 
       
   284 void MainWindow::checkAdapt()
       
   285 {
       
   286     if (this->doneAdapt
       
   287         || Colors::noTimerUpdate
       
   288         || this->demoStartTime.elapsed() < 2000)
       
   289        return;
       
   290 
       
   291     this->doneAdapt = true;
       
   292     this->forceFpsMedianCalculation();
       
   293     Colors::benchmarkFps = this->fpsMedian;
       
   294     if (Colors::verbose)
       
   295         qDebug() << "- benchmark:" << QString::number(Colors::benchmarkFps) << "FPS";
       
   296 
       
   297     if (Colors::noAdapt)
       
   298         return;
       
   299 
       
   300     if (this->fpsMedian < 30){
       
   301         if (MenuManager::instance()->ticker && MenuManager::instance()->ticker->scene()){
       
   302             this->scene->removeItem(MenuManager::instance()->ticker);
       
   303             Colors::noTimerUpdate = true;
       
   304             this->switchTimerOnOff(false);
       
   305             if (this->fpsLabel)
       
   306                this->fpsLabel->setText(QString("FPS: (") + QString::number(this->fpsMedian) + QString(")"));
       
   307             if (Colors::verbose)
       
   308                qDebug() << "- benchmark adaption: removed ticker (fps < 30)";
       
   309         }
       
   310 
       
   311         if (this->fpsMedian < 20){
       
   312             Colors::noAnimations = true;
       
   313             if (Colors::verbose)
       
   314                qDebug() << "- benchmark adaption: animations switched off (fps < 20)";
       
   315         }
       
   316 
       
   317         Colors::adapted = true;
       
   318     }
       
   319 }
       
   320 
       
   321 int MainWindow::performBenchmark()
       
   322 {
       
   323 /*
       
   324     QTime time;
       
   325     time.restart();
       
   326     while (time.elapsed() < 2000)
       
   327         QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
       
   328 */
       
   329     return 0;
       
   330 }
       
   331 
       
   332 void MainWindow::drawBackgroundToPixmap()
       
   333 {
       
   334     const QRectF r = this->scene->sceneRect();
       
   335     this->background = QPixmap(qRound(r.width()), qRound(r.height()));
       
   336     this->background.fill(Qt::black);
       
   337     QPainter painter(&this->background);
       
   338 
       
   339     if (false && Colors::useEightBitPalette){
       
   340         painter.fillRect(r, Colors::sceneBg1);
       
   341     } else {
       
   342         QImage bg(":/images/demobg.png");
       
   343         painter.drawImage(0, 0, bg);
       
   344     }
       
   345 }
       
   346 
       
   347 void MainWindow::drawBackground(QPainter *painter, const QRectF &rect)
       
   348 {
       
   349     Q_UNUSED(rect);
       
   350     painter->drawPixmap(QPoint(0, 0), this->background);
       
   351 }
       
   352 
       
   353 void MainWindow::showEvent(QShowEvent * event)
       
   354 {
       
   355     Q_UNUSED(event);
       
   356     QGraphicsView::showEvent(event);
       
   357 }
       
   358 
       
   359 void MainWindow::toggleFullscreen()
       
   360 {
       
   361     if (this->isFullScreen()){
       
   362         this->enableMask(true);
       
   363         this->showNormal();
       
   364         if (MenuManager::instance()->ticker)
       
   365             MenuManager::instance()->ticker->pause(false);
       
   366     }
       
   367     else {
       
   368         this->enableMask(false);
       
   369         this->showFullScreen();
       
   370     }
       
   371 }
       
   372 
       
   373 void MainWindow::keyPressEvent(QKeyEvent *event)
       
   374 {
       
   375     if (event->key() == Qt::Key_Escape){
       
   376         this->loop = false;
       
   377         QApplication::quit();
       
   378     }
       
   379     else if (event->key() == Qt::Key_1){
       
   380             QString s("");
       
   381             s += "Rendering system: ";
       
   382             if (Colors::openGlRendering)
       
   383                 s += "OpenGL";
       
   384             else
       
   385                 s += "software";
       
   386 
       
   387             s += "\nAdapt: ";
       
   388             s += Colors::noAdapt ? "off" : "on";
       
   389             s += "\nAdaption occured: ";
       
   390             s += Colors::adapted ? "yes" : "no";
       
   391             s += "\nOpenGL version: ";
       
   392             s += Colors::glVersion;
       
   393             QWidget w;
       
   394             s += "\nColor bit depth: ";
       
   395             s += QString::number(w.depth());
       
   396             s += "\nWanted FPS: ";
       
   397             s += QString::number(Colors::fps);
       
   398             s += "\nBenchmarked FPS: ";
       
   399             s += Colors::benchmarkFps != -1 ? QString::number(Colors::benchmarkFps) : "not calculated";
       
   400             s += "\nAnimations: ";
       
   401             s += Colors::noAnimations ? "off" : "on";
       
   402             s += "\nBlending: ";
       
   403             s += Colors::useEightBitPalette ? "off" : "on";
       
   404             s += "\nTicker: ";
       
   405             s += Colors::noTicker ? "off" : "on";
       
   406             s += "\nPixmaps: ";
       
   407             s += Colors::usePixmaps ? "on" : "off";
       
   408             s += "\nRescale images on resize: ";
       
   409             s += Colors::noRescale ? "off" : "on";
       
   410             s += "\nTimer based updates: ";
       
   411             s += Colors::noTimerUpdate ? "off" : "on";
       
   412             s += "\nSeparate loop: ";
       
   413             s += Colors::useLoop ? "yes" : "no";
       
   414             s += "\nScreen sync: ";
       
   415             s += Colors::noScreenSync ? "no" : "yes";
       
   416             QMessageBox::information(0, QString("Current configuration"), s);
       
   417     }
       
   418 }
       
   419 
       
   420 void MainWindow::focusInEvent(QFocusEvent *)
       
   421 {
       
   422     if (!Colors::pause)
       
   423         return;
       
   424 
       
   425     if (MenuManager::instance()->ticker)
       
   426         MenuManager::instance()->ticker->pause(false);
       
   427 
       
   428     int code = MenuManager::instance()->currentMenuCode;
       
   429     if (code == MenuManager::ROOT || code == MenuManager::MENU1)
       
   430         this->switchTimerOnOff(true);
       
   431 
       
   432     this->pausedLabel->setRecursiveVisible(false);
       
   433 }
       
   434 
       
   435 void MainWindow::focusOutEvent(QFocusEvent *)
       
   436 {
       
   437     if (!Colors::pause)
       
   438         return;
       
   439 
       
   440     if (MenuManager::instance()->ticker)
       
   441         MenuManager::instance()->ticker->pause(true);
       
   442 
       
   443     int code = MenuManager::instance()->currentMenuCode;
       
   444     if (code == MenuManager::ROOT || code == MenuManager::MENU1)
       
   445         this->switchTimerOnOff(false);
       
   446 
       
   447     this->pausedLabel->setRecursiveVisible(true);
       
   448 }
       
   449 
       
   450 void MainWindow::resizeEvent(QResizeEvent *event)
       
   451 {
       
   452     Q_UNUSED(event);
       
   453 
       
   454     this->resetMatrix();
       
   455     this->scale(event->size().width() / 800.0, event->size().height() / 600.0);
       
   456     QGraphicsView::resizeEvent(event);
       
   457     DemoItem::setMatrix(this->matrix());
       
   458 
       
   459     if (this->companyLogo){
       
   460         const QRectF r = this->scene->sceneRect();
       
   461         QRectF ttb = this->companyLogo->boundingRect();
       
   462         this->companyLogo->setPos(int((r.width() - ttb.width()) / 2), 595 - ttb.height());
       
   463         QRectF qtb = this->qtLogo->boundingRect();
       
   464         this->qtLogo->setPos(802 - qtb.width(), 0);
       
   465     }
       
   466 
       
   467     // Changing size will almost always
       
   468     // hurt FPS during the changing. So
       
   469     // ignore it.
       
   470     this->fpsHistory.clear();
       
   471 }
       
   472 
       
   473