source: trunk/demos/qtdemo/mainwindow.cpp@ 1039

Last change on this file since 1039 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 15.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the demonstration applications of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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
56MainWindow::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
74MainWindow::~MainWindow()
75{
76 delete this->companyLogo;
77 delete this->qtLogo;
78}
79
80void 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
99void 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
126void 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
135void 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
167void 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
175void MainWindow::drawItems(QPainter *painter, int numItems, QGraphicsItem **items, const QStyleOptionGraphicsItem* options)
176{
177 QGraphicsView::drawItems(painter, numItems, items, options);
178}
179
180void 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
205bool 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*/
232void 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
249void 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
265void 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(1000);
270 this->fpsLabel->setPos(Colors::stageStartX, 600 - QFontMetricsF(Colors::buttonFont()).height() - 5);
271 }
272
273 this->mainSceneRoot = new QGraphicsWidget();
274 this->scene->addItem(mainSceneRoot);
275 this->companyLogo = new ImageItem(QImage(":/images/trolltech-logo.png"), 1000, 1000, this->scene, mainSceneRoot, true, 0.5f);
276 this->qtLogo = new ImageItem(QImage(":/images/qtlogo_small.png"), 1000, 1000, this->scene, mainSceneRoot, true, 0.5f);
277 this->companyLogo->setZValue(100);
278 this->qtLogo->setZValue(100);
279 this->pausedLabel = new DemoTextItem(QString("PAUSED"), Colors::buttonFont(), Qt::white, -1, this->scene, 0);
280 this->pausedLabel->setZValue(100);
281 QFontMetricsF fm(Colors::buttonFont());
282 this->pausedLabel->setPos(Colors::stageWidth - fm.width("PAUSED"), 590 - fm.height());
283 this->pausedLabel->setRecursiveVisible(false);
284}
285
286void MainWindow::checkAdapt()
287{
288 if (this->doneAdapt
289 || Colors::noTimerUpdate
290 || this->demoStartTime.elapsed() < 2000)
291 return;
292
293 this->doneAdapt = true;
294 this->forceFpsMedianCalculation();
295 Colors::benchmarkFps = this->fpsMedian;
296 if (Colors::verbose)
297 qDebug() << "- benchmark:" << QString::number(Colors::benchmarkFps) << "FPS";
298
299 if (Colors::noAdapt)
300 return;
301
302 if (this->fpsMedian < 30){
303 if (MenuManager::instance()->ticker && MenuManager::instance()->ticker->scene()){
304 this->scene->removeItem(MenuManager::instance()->ticker);
305 Colors::noTimerUpdate = true;
306 this->switchTimerOnOff(false);
307 if (this->fpsLabel)
308 this->fpsLabel->setText(QString("FPS: (") + QString::number(this->fpsMedian) + QString(")"));
309 if (Colors::verbose)
310 qDebug() << "- benchmark adaption: removed ticker (fps < 30)";
311 }
312
313 if (this->fpsMedian < 20){
314 Colors::noAnimations = true;
315 if (Colors::verbose)
316 qDebug() << "- benchmark adaption: animations switched off (fps < 20)";
317 }
318
319 Colors::adapted = true;
320 }
321}
322
323int MainWindow::performBenchmark()
324{
325/*
326 QTime time;
327 time.restart();
328 while (time.elapsed() < 2000)
329 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
330*/
331 return 0;
332}
333
334void MainWindow::drawBackgroundToPixmap()
335{
336 const QRectF r = this->scene->sceneRect();
337 this->background = QPixmap(qRound(r.width()), qRound(r.height()));
338 this->background.fill(Qt::black);
339 QPainter painter(&this->background);
340
341 if (false && Colors::useEightBitPalette){
342 painter.fillRect(r, Colors::sceneBg1);
343 } else {
344 QImage bg(":/images/demobg.png");
345 painter.drawImage(0, 0, bg);
346 }
347}
348
349void MainWindow::drawBackground(QPainter *painter, const QRectF &rect)
350{
351 Q_UNUSED(rect);
352 painter->drawPixmap(QPoint(0, 0), this->background);
353}
354
355void MainWindow::showEvent(QShowEvent * event)
356{
357 Q_UNUSED(event);
358 QGraphicsView::showEvent(event);
359}
360
361void MainWindow::toggleFullscreen()
362{
363 if (this->isFullScreen()){
364 this->enableMask(true);
365 this->showNormal();
366 if (MenuManager::instance()->ticker)
367 MenuManager::instance()->ticker->pause(false);
368 }
369 else {
370 this->enableMask(false);
371 this->showFullScreen();
372 }
373}
374
375void MainWindow::keyPressEvent(QKeyEvent *event)
376{
377 if (event->key() == Qt::Key_Escape){
378 this->loop = false;
379 QApplication::quit();
380 }
381 else if (event->key() == Qt::Key_F1){
382 QString s("");
383 s += "Rendering system: ";
384 if (Colors::openGlRendering)
385 s += "OpenGL";
386 else
387 s += "software";
388
389 s += "\nAdapt: ";
390 s += Colors::noAdapt ? "off" : "on";
391 s += "\nAdaption occurred: ";
392 s += Colors::adapted ? "yes" : "no";
393 s += "\nOpenGL version: ";
394 s += Colors::glVersion;
395 QWidget w;
396 s += "\nColor bit depth: ";
397 s += QString::number(w.depth());
398 s += "\nWanted FPS: ";
399 s += QString::number(Colors::fps);
400 s += "\nBenchmarked FPS: ";
401 s += Colors::benchmarkFps != -1 ? QString::number(Colors::benchmarkFps) : "not calculated";
402 s += "\nAnimations: ";
403 s += Colors::noAnimations ? "off" : "on";
404 s += "\nBlending: ";
405 s += Colors::useEightBitPalette ? "off" : "on";
406 s += "\nTicker: ";
407 s += Colors::noTicker ? "off" : "on";
408 s += "\nPixmaps: ";
409 s += Colors::usePixmaps ? "on" : "off";
410 s += "\nRescale images on resize: ";
411 s += Colors::noRescale ? "off" : "on";
412 s += "\nTimer based updates: ";
413 s += Colors::noTimerUpdate ? "off" : "on";
414 s += "\nSeparate loop: ";
415 s += Colors::useLoop ? "yes" : "no";
416 s += "\nScreen sync: ";
417 s += Colors::noScreenSync ? "no" : "yes";
418 QMessageBox::information(0, QString("Current configuration"), s);
419 }
420 QGraphicsView::keyPressEvent(event);
421}
422
423void MainWindow::focusInEvent(QFocusEvent *)
424{
425 if (!Colors::pause)
426 return;
427
428 if (MenuManager::instance()->ticker)
429 MenuManager::instance()->ticker->pause(false);
430
431 int code = MenuManager::instance()->currentMenuCode;
432 if (code == MenuManager::ROOT || code == MenuManager::MENU1)
433 this->switchTimerOnOff(true);
434
435 this->pausedLabel->setRecursiveVisible(false);
436}
437
438void MainWindow::focusOutEvent(QFocusEvent *)
439{
440 if (!Colors::pause)
441 return;
442
443 if (MenuManager::instance()->ticker)
444 MenuManager::instance()->ticker->pause(true);
445
446 int code = MenuManager::instance()->currentMenuCode;
447 if (code == MenuManager::ROOT || code == MenuManager::MENU1)
448 this->switchTimerOnOff(false);
449
450 this->pausedLabel->setRecursiveVisible(true);
451}
452
453void MainWindow::resizeEvent(QResizeEvent *event)
454{
455 Q_UNUSED(event);
456
457 this->resetMatrix();
458 this->scale(event->size().width() / 800.0, event->size().height() / 600.0);
459 QGraphicsView::resizeEvent(event);
460 DemoItem::setMatrix(this->matrix());
461
462 if (this->companyLogo){
463 const QRectF r = this->scene->sceneRect();
464 QRectF ttb = this->companyLogo->boundingRect();
465 this->companyLogo->setPos(int((r.width() - ttb.width()) / 2), 595 - ttb.height());
466 QRectF qtb = this->qtLogo->boundingRect();
467 this->qtLogo->setPos(802 - qtb.width(), 0);
468 }
469
470 // Changing size will almost always
471 // hurt FPS during the changing. So
472 // ignore it.
473 this->fpsHistory.clear();
474}
475
476
Note: See TracBrowser for help on using the repository browser.