Removing unnecessary chunking and stat'ing when reading QIODevice
[qt-netbsd.git] / demos / qtdemo / mainwindow.cpp
blob2fc4e03a2845d35c429c58890f8f9dd042fb685e
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.
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
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"
51 #ifndef QT_NO_OPENGL
52 #include <QGLWidget>
53 #endif
54 //#define QT_NO_OPENGL
56 MainWindow::MainWindow(QWidget *parent) : QGraphicsView(parent), updateTimer(this)
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();
74 MainWindow::~MainWindow()
76 delete this->companyLogo;
77 delete this->qtLogo;
80 void MainWindow::setupWidget()
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()));
99 void MainWindow::setRenderingSystem()
101 QWidget *viewport = 0;
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
116 // software rendering
117 viewport = new QWidget;
118 setCacheMode(QGraphicsView::CacheBackground);
119 if (Colors::verbose)
120 qDebug() << "- using software rendering";
123 setViewport(viewport);
126 void MainWindow::start()
128 this->switchTimerOnOff(true);
129 this->demoStartTime.restart();
130 MenuManager::instance()->itemSelected(MenuManager::ROOT, Colors::rootMenuName);
131 if (Colors::verbose)
132 qDebug("- starting demo");
135 void MainWindow::enableMask(bool enable)
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));
167 void MainWindow::setupScene()
169 this->scene = new DemoScene(this);
170 this->scene->setSceneRect(0, 0, 800, 600);
171 setScene(this->scene);
172 this->scene->setItemIndexMethod(QGraphicsScene::NoIndex);
175 void MainWindow::drawItems(QPainter *painter, int numItems, QGraphicsItem **items, const QStyleOptionGraphicsItem* options)
177 QGraphicsView::drawItems(painter, numItems, items, options);
180 void MainWindow::switchTimerOnOff(bool on)
182 bool ticker = MenuManager::instance()->ticker && MenuManager::instance()->ticker->scene();
183 if (ticker)
184 MenuManager::instance()->ticker->tickOnPaint = !on || Colors::noTimerUpdate;
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));
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);
205 bool MainWindow::measureFps()
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();
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;
225 return false;
229 Used for adaption in case things are so slow
230 that no median yet has been calculated
232 void MainWindow::forceFpsMedianCalculation()
234 if (this->fpsMedian != -1)
235 return;
237 int size = this->fpsHistory.size();
238 if (size == 0){
239 this->fpsMedian = 0.01f;
240 return;
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;
249 void MainWindow::tick()
251 bool medianChanged = this->measureFps();
252 this->checkAdapt();
254 if (medianChanged && this->fpsLabel && Colors::showFps)
255 this->fpsLabel->setText(QString("FPS: ") + QString::number(int(this->currentFps)));
257 if (MenuManager::instance()->ticker)
258 MenuManager::instance()->ticker->tick();
260 this->viewport()->update();
261 if (this->useTimer)
262 this->updateTimer.start(int(1000 / Colors::fps));
265 void MainWindow::setupSceneItems()
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);
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);
284 void MainWindow::checkAdapt()
286 if (this->doneAdapt
287 || Colors::noTimerUpdate
288 || this->demoStartTime.elapsed() < 2000)
289 return;
291 this->doneAdapt = true;
292 this->forceFpsMedianCalculation();
293 Colors::benchmarkFps = this->fpsMedian;
294 if (Colors::verbose)
295 qDebug() << "- benchmark:" << QString::number(Colors::benchmarkFps) << "FPS";
297 if (Colors::noAdapt)
298 return;
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)";
311 if (this->fpsMedian < 20){
312 Colors::noAnimations = true;
313 if (Colors::verbose)
314 qDebug() << "- benchmark adaption: animations switched off (fps < 20)";
317 Colors::adapted = true;
321 int MainWindow::performBenchmark()
324 QTime time;
325 time.restart();
326 while (time.elapsed() < 2000)
327 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
329 return 0;
332 void MainWindow::drawBackgroundToPixmap()
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);
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);
347 void MainWindow::drawBackground(QPainter *painter, const QRectF &rect)
349 Q_UNUSED(rect);
350 painter->drawPixmap(QPoint(0, 0), this->background);
353 void MainWindow::showEvent(QShowEvent * event)
355 Q_UNUSED(event);
356 QGraphicsView::showEvent(event);
359 void MainWindow::toggleFullscreen()
361 if (this->isFullScreen()){
362 this->enableMask(true);
363 this->showNormal();
364 if (MenuManager::instance()->ticker)
365 MenuManager::instance()->ticker->pause(false);
367 else {
368 this->enableMask(false);
369 this->showFullScreen();
373 void MainWindow::keyPressEvent(QKeyEvent *event)
375 if (event->key() == Qt::Key_Escape){
376 this->loop = false;
377 QApplication::quit();
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";
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);
420 void MainWindow::focusInEvent(QFocusEvent *)
422 if (!Colors::pause)
423 return;
425 if (MenuManager::instance()->ticker)
426 MenuManager::instance()->ticker->pause(false);
428 int code = MenuManager::instance()->currentMenuCode;
429 if (code == MenuManager::ROOT || code == MenuManager::MENU1)
430 this->switchTimerOnOff(true);
432 this->pausedLabel->setRecursiveVisible(false);
435 void MainWindow::focusOutEvent(QFocusEvent *)
437 if (!Colors::pause)
438 return;
440 if (MenuManager::instance()->ticker)
441 MenuManager::instance()->ticker->pause(true);
443 int code = MenuManager::instance()->currentMenuCode;
444 if (code == MenuManager::ROOT || code == MenuManager::MENU1)
445 this->switchTimerOnOff(false);
447 this->pausedLabel->setRecursiveVisible(true);
450 void MainWindow::resizeEvent(QResizeEvent *event)
452 Q_UNUSED(event);
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());
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);
467 // Changing size will almost always
468 // hurt FPS during the changing. So
469 // ignore it.
470 this->fpsHistory.clear();