source: trunk/demos/qtdemo/menumanager.cpp@ 569

Last change on this file since 569 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 38.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 "menumanager.h"
43#include "colors.h"
44#include "menucontent.h"
45#include "examplecontent.h"
46
47MenuManager *MenuManager::pInstance = 0;
48
49MenuManager * MenuManager::instance()
50{
51 if (!MenuManager::pInstance)
52 MenuManager::pInstance = new MenuManager();
53 return MenuManager::pInstance;
54}
55
56MenuManager::MenuManager()
57{
58 this->ticker = 0;
59 this->tickerInAnim = 0;
60 this->upButton = 0;
61 this->downButton = 0;
62 this->helpEngine = 0;
63 this->score = new Score();
64 this->currentMenu = QLatin1String("[no menu visible]");
65 this->currentCategory = QLatin1String("[no category visible]");
66 this->currentMenuButtons = QLatin1String("[no menu buttons visible]");
67 this->currentInfo = QLatin1String("[no info visible]");
68 this->currentMenuCode = -1;
69 this->readXmlDocument();
70 this->initHelpEngine();
71}
72
73MenuManager::~MenuManager()
74{
75 delete this->score;
76 delete this->contentsDoc;
77 delete this->helpEngine;
78}
79
80QByteArray MenuManager::getResource(const QString &name)
81{
82 QByteArray ba = this->helpEngine->fileData(name);
83 if (Colors::verbose && ba.isEmpty())
84 qDebug() << " - WARNING: Could not get " << name;
85 return ba;
86}
87
88void MenuManager::readXmlDocument()
89{
90 this->contentsDoc = new QDomDocument();
91 QString errorStr;
92 int errorLine;
93 int errorColumn;
94
95 QFile file(":/xml/examples.xml");
96 bool statusOK = this->contentsDoc->setContent(&file, true, &errorStr, &errorLine, &errorColumn);
97 if (!statusOK){
98 QMessageBox::critical(0,
99 QObject::tr("DOM Parser"),
100 QObject::tr("Could not read or find the contents document. Error at line %1, column %2:\n%3")
101 .arg(errorLine).arg(errorColumn).arg(errorStr)
102 );
103 exit(-1);
104 }
105}
106
107void MenuManager::initHelpEngine()
108{
109 this->helpRootUrl = QString("qthelp://com.trolltech.qt.%1%2%3/qdoc/")
110 .arg(QT_VERSION >> 16).arg((QT_VERSION >> 8) & 0xFF)
111 .arg(QT_VERSION & 0xFF);
112
113 // Store help collection file in cache dir of assistant
114 QString cacheDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation)
115 + QLatin1String("/Trolltech/Assistant/");
116 QString helpDataFile = QString(QLatin1String("qtdemo_%1.qhc")).arg(QLatin1String(QT_VERSION_STR));
117
118 QDir dir;
119 if (!dir.exists(cacheDir))
120 dir.mkpath(cacheDir);
121
122 // Create help engine (and new
123 // helpDataFile if it does not exist):
124 this->helpEngine = new QHelpEngineCore(cacheDir + helpDataFile);
125 this->helpEngine->setupData();
126
127 QString qtDocRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/qch");
128 qtDocRoot = QDir(qtDocRoot).absolutePath();
129
130 QStringList qchFiles;
131 qchFiles << QLatin1String("/qt.qch")
132 << QLatin1String("/designer.qch")
133 << QLatin1String("/linguist.qch");
134
135 QString oldDir = helpEngine->customValue(QLatin1String("docDir"), QString()).toString();
136 if (oldDir != qtDocRoot) {
137 foreach (const QString &qchFile, qchFiles)
138 helpEngine->unregisterDocumentation(QHelpEngineCore::namespaceName(qtDocRoot + qchFile));
139 }
140
141 // If the data that the engine will work
142 // on is not yet registered, do it now:
143 foreach (const QString &qchFile, qchFiles)
144 helpEngine->registerDocumentation(qtDocRoot + qchFile);
145
146 helpEngine->setCustomValue(QLatin1String("docDir"), qtDocRoot);
147}
148
149void MenuManager::itemSelected(int userCode, const QString &menuName)
150{
151 switch (userCode){
152 case LAUNCH:
153 this->launchExample(this->currentInfo);
154 break;
155 case DOCUMENTATION:
156 this->showDocInAssistant(this->currentInfo);
157 break;
158 case QUIT:
159 this->window->loop = false;
160 QCoreApplication::quit();
161 break;
162 case FULLSCREEN:
163 this->window->toggleFullscreen();
164 break;
165 case ROOT:
166 // out:
167 this->score->queueMovie(this->currentMenu + " -out", Score::FROM_START, Score::LOCK_ITEMS);
168 this->score->queueMovie(this->currentMenuButtons + " -out", Score::FROM_START, Score::LOCK_ITEMS);
169 this->score->queueMovie(this->currentInfo + " -out");
170 this->score->queueMovie(this->currentInfo + " -buttons -out", Score::NEW_ANIMATION_ONLY);
171 this->score->queueMovie("back -out", Score::ONLY_IF_VISIBLE);
172 // book-keeping:
173 this->currentMenuCode = ROOT;
174 this->currentMenu = menuName + " -menu1";
175 this->currentMenuButtons = menuName + " -buttons";
176 this->currentInfo = menuName + " -info";
177 // in:
178 this->score->queueMovie("upndown -shake");
179 this->score->queueMovie(this->currentMenu, Score::FROM_START, Score::UNLOCK_ITEMS);
180 this->score->queueMovie(this->currentMenuButtons, Score::FROM_START, Score::UNLOCK_ITEMS);
181 this->score->queueMovie(this->currentInfo);
182 if (!Colors::noTicker){
183 this->ticker->doIntroTransitions = true;
184 this->tickerInAnim->startDelay = 2000;
185 this->ticker->useGuideQt();
186 this->score->queueMovie("ticker", Score::NEW_ANIMATION_ONLY);
187 }
188 break;
189 case MENU1:
190 // out:
191 this->score->queueMovie(this->currentMenu + " -out", Score::FROM_START, Score::LOCK_ITEMS);
192 this->score->queueMovie(this->currentMenuButtons + " -out", Score::FROM_START, Score::LOCK_ITEMS);
193 this->score->queueMovie(this->currentInfo + " -out");
194 // book-keeping:
195 this->currentMenuCode = MENU1;
196 this->currentCategory = menuName;
197 this->currentMenu = menuName + " -menu1";
198 this->currentInfo = menuName + " -info";
199 // in:
200 this->score->queueMovie("upndown -shake");
201 this->score->queueMovie("back -in");
202 this->score->queueMovie(this->currentMenu, Score::FROM_START, Score::UNLOCK_ITEMS);
203 this->score->queueMovie(this->currentInfo);
204 if (!Colors::noTicker)
205 this->ticker->useGuideTt();
206 break;
207 case MENU2:
208 // out:
209 this->score->queueMovie(this->currentInfo + " -out", Score::NEW_ANIMATION_ONLY);
210 this->score->queueMovie(this->currentInfo + " -buttons -out", Score::NEW_ANIMATION_ONLY);
211 // book-keeping:
212 this->currentMenuCode = MENU2;
213 this->currentInfo = menuName;
214 // in / shake:
215 this->score->queueMovie("upndown -shake");
216 this->score->queueMovie("back -shake");
217 this->score->queueMovie(this->currentMenu + " -shake");
218 this->score->queueMovie(this->currentInfo, Score::NEW_ANIMATION_ONLY);
219 this->score->queueMovie(this->currentInfo + " -buttons", Score::NEW_ANIMATION_ONLY);
220 if (!Colors::noTicker){
221 this->score->queueMovie("ticker -out", Score::NEW_ANIMATION_ONLY);
222 }
223 break;
224 case UP:{
225 QString backMenu = this->info[this->currentMenu]["back"];
226 if (!backMenu.isNull()){
227 this->score->queueMovie(this->currentMenu + " -top_out", Score::FROM_START, Score::LOCK_ITEMS);
228 this->score->queueMovie(backMenu + " -bottom_in", Score::FROM_START, Score::UNLOCK_ITEMS);
229 this->currentMenu = backMenu;
230 }
231 break; }
232 case DOWN:{
233 QString moreMenu = this->info[this->currentMenu]["more"];
234 if (!moreMenu.isNull()){
235 this->score->queueMovie(this->currentMenu + " -bottom_out", Score::FROM_START, Score::LOCK_ITEMS);
236 this->score->queueMovie(moreMenu + " -top_in", Score::FROM_START, Score::UNLOCK_ITEMS);
237 this->currentMenu = moreMenu;
238 }
239 break; }
240 case BACK:{
241 if (this->currentMenuCode == MENU2){
242 // out:
243 this->score->queueMovie(this->currentInfo + " -out", Score::NEW_ANIMATION_ONLY);
244 this->score->queueMovie(this->currentInfo + " -buttons -out", Score::NEW_ANIMATION_ONLY);
245 // book-keeping:
246 this->currentMenuCode = MENU1;
247 this->currentMenuButtons = this->currentCategory + " -buttons";
248 this->currentInfo = this->currentCategory + " -info";
249 // in / shake:
250 this->score->queueMovie("upndown -shake");
251 this->score->queueMovie(this->currentMenu + " -shake");
252 this->score->queueMovie(this->currentInfo, Score::NEW_ANIMATION_ONLY);
253 this->score->queueMovie(this->currentInfo + " -buttons", Score::NEW_ANIMATION_ONLY);
254 if (!Colors::noTicker){
255 this->ticker->doIntroTransitions = false;
256 this->tickerInAnim->startDelay = 500;
257 this->score->queueMovie("ticker", Score::NEW_ANIMATION_ONLY);
258 }
259 } else if (this->currentMenuCode != ROOT)
260 itemSelected(ROOT, Colors::rootMenuName);
261 break; }
262 }
263
264 // update back- and more buttons
265 bool noBackMenu = this->info[this->currentMenu]["back"].isNull();
266 bool noMoreMenu = this->info[this->currentMenu]["more"].isNull();
267 this->upButton->setState(noBackMenu ? TextButton::DISABLED : TextButton::OFF);
268 this->downButton->setState(noMoreMenu ? TextButton::DISABLED : TextButton::OFF);
269
270 if (this->score->hasQueuedMovies()){
271 this->score->playQue();
272 // Playing new movies might include
273 // loading etc. So ignore the FPS
274 // at this point
275 this->window->fpsHistory.clear();
276 }
277}
278
279void MenuManager::showDocInAssistant(const QString &name)
280{
281 QString url = this->resolveDocUrl(name);
282 if (Colors::verbose)
283 qDebug() << "Sending URL to Assistant:" << url;
284
285 // Start assistant if it's not already running:
286 if (this->assistantProcess.state() != QProcess::Running){
287 QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator();
288#if !defined(Q_OS_MAC)
289 app += QLatin1String("assistant");
290#else
291 app += QLatin1String("Assistant.app/Contents/MacOS/Assistant");
292#endif
293 QStringList args;
294 args << QLatin1String("-enableRemoteControl");
295 this->assistantProcess.start(app, args);
296 if (!this->assistantProcess.waitForStarted()) {
297 QMessageBox::critical(0, tr("Qt Demo"), tr("Could not start Qt Assistant.").arg(app));
298 return;
299 }
300 }
301
302 // Send command through remote control even if the process
303 // was started to activate assistant and bring it to front:
304 QTextStream str(&this->assistantProcess);
305 str << "SetSource " << url << QLatin1Char('\0') << endl;
306}
307
308void MenuManager::launchExample(const QString &name)
309{
310 QString executable = this->resolveExeFile(name);
311#ifdef Q_OS_MAC
312 if (Colors::verbose)
313 qDebug() << "Launching:" << executable;
314 bool success = QDesktopServices::openUrl(QUrl::fromLocalFile(executable));
315 if (!success){
316 QMessageBox::critical(0, tr("Failed to launch the example"),
317 tr("Could not launch the example. Ensure that it has been built."),
318 QMessageBox::Cancel);
319 }
320#else // Not mac. To not break anything regarding dll's etc, keep it the way it was before:
321 QProcess *process = new QProcess(this);
322 connect(process, SIGNAL(finished(int)), this, SLOT(exampleFinished()));
323 connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(exampleError(QProcess::ProcessError)));
324
325#ifdef Q_OS_WIN
326 //make sure it finds the dlls on windows
327 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
328 env.insert(QLatin1String("PATH"), QLibraryInfo::location(QLibraryInfo::BinariesPath)
329 + QLatin1Char(';') + env.value(QLatin1String("Path")));
330 process->setProcessEnvironment(env);
331#endif
332
333 if (info[name]["changedirectory"] != "false"){
334 QString workingDirectory = resolveDataDir(name);
335 process->setWorkingDirectory(workingDirectory);
336 if (Colors::verbose)
337 qDebug() << "Setting working directory:" << workingDirectory;
338 }
339
340 if (Colors::verbose)
341 qDebug() << "Launching:" << executable;
342 process->start(executable);
343#endif
344}
345
346void MenuManager::exampleFinished()
347{
348}
349
350void MenuManager::exampleError(QProcess::ProcessError error)
351{
352 if (error != QProcess::Crashed)
353 QMessageBox::critical(0, tr("Failed to launch the example"),
354 tr("Could not launch the example. Ensure that it has been built."),
355 QMessageBox::Cancel);
356}
357
358void MenuManager::init(MainWindow *window)
359{
360 this->window = window;
361
362 // Create div:
363 this->createTicker();
364 this->createUpnDownButtons();
365 this->createBackButton();
366
367 // Create first level menu:
368 QDomElement rootElement = this->contentsDoc->documentElement();
369 this->createRootMenu(rootElement);
370
371 // Create second level menus:
372 QDomNode level2MenuNode = rootElement.firstChild();
373 while (!level2MenuNode.isNull()){
374 QDomElement level2MenuElement = level2MenuNode.toElement();
375 this->createSubMenu(level2MenuElement);
376
377 // create leaf menu and example info:
378 QDomNode exampleNode = level2MenuElement.firstChild();
379 while (!exampleNode.isNull()){
380 QDomElement exampleElement = exampleNode.toElement();
381 this->readInfoAboutExample(exampleElement);
382 this->createLeafMenu(exampleElement);
383 exampleNode = exampleNode.nextSibling();
384 }
385
386 level2MenuNode = level2MenuNode.nextSibling();
387 }
388}
389
390void MenuManager::readInfoAboutExample(const QDomElement &example)
391{
392 QString name = example.attribute("name");
393 if (this->info.contains(name))
394 qWarning() << "__WARNING: MenuManager::readInfoAboutExample: Demo/example with name"
395 << name << "appears twize in the xml-file!__";
396
397 this->info[name]["filename"] = example.attribute("filename");
398 this->info[name]["category"] = example.parentNode().toElement().tagName();
399 this->info[name]["dirname"] = example.parentNode().toElement().attribute("dirname");
400 this->info[name]["changedirectory"] = example.attribute("changedirectory");
401 this->info[name]["image"] = example.attribute("image");
402}
403
404QString MenuManager::resolveDataDir(const QString &name)
405{
406 QString dirName = this->info[name]["dirname"];
407 QString category = this->info[name]["category"];
408 QString fileName = this->info[name]["filename"];
409
410 QDir dir;
411 if (category == "demos")
412 dir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath));
413 else
414 dir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath));
415
416 dir.cd(dirName);
417 dir.cd(fileName);
418 return dir.absolutePath();
419}
420
421QString MenuManager::resolveExeFile(const QString &name)
422{
423 QString dirName = this->info[name]["dirname"];
424 QString category = this->info[name]["category"];
425 QString fileName = this->info[name]["filename"];
426
427 QDir dir;
428 if (category == "demos")
429 dir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath));
430 else
431 dir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath));
432
433 dir.cd(dirName);
434 dir.cd(fileName);
435
436 QFile unixFile(dir.path() + "/" + fileName);
437 if (unixFile.exists()) return unixFile.fileName();
438 QFile winR(dir.path() + "\\release\\" + fileName + ".exe");
439 if (winR.exists()) return winR.fileName();
440 QFile winD(dir.path() + "\\debug\\" + fileName + ".exe");
441 if (winD.exists()) return winD.fileName();
442 QFile mac(dir.path() + "/" + fileName + ".app");
443 if (mac.exists()) return mac.fileName();
444
445 if (Colors::verbose)
446 qDebug() << "- WARNING: Could not resolve executable:" << dir.path() << fileName;
447 return "__executable not found__";
448}
449
450QString MenuManager::resolveDocUrl(const QString &name)
451{
452 QString dirName = this->info[name]["dirname"];
453 QString category = this->info[name]["category"];
454 QString fileName = this->info[name]["filename"];
455
456 if (category == "demos")
457 return this->helpRootUrl + "demos-" + fileName + ".html";
458 else
459 return this->helpRootUrl + dirName.replace("/", "-") + "-" + fileName + ".html";
460}
461
462QString MenuManager::resolveImageUrl(const QString &name)
463{
464 return this->helpRootUrl + "images/" + name;
465}
466
467QByteArray MenuManager::getHtml(const QString &name)
468{
469 return getResource(this->resolveDocUrl(name));
470}
471
472QByteArray MenuManager::getImage(const QString &name)
473{
474 QString imageName = this->info[name]["image"];
475 QString category = this->info[name]["category"];
476 QString fileName = this->info[name]["filename"];
477
478 if (imageName.isEmpty()){
479 if (category == "demos")
480 imageName = fileName + "-demo.png";
481 else
482 imageName = fileName + "-example.png";
483 if ((getResource(resolveImageUrl(imageName))).isEmpty())
484 imageName = fileName + ".png";
485 if ((getResource(resolveImageUrl(imageName))).isEmpty())
486 imageName = fileName + "example.png";
487 }
488 return getResource(resolveImageUrl(imageName));
489}
490
491
492void MenuManager::createRootMenu(const QDomElement &el)
493{
494 QString name = el.attribute("name");
495 createMenu(el, MENU1);
496 createInfo(new MenuContentItem(el, this->window->scene, 0), name + " -info");
497
498 Movie *menuButtonsIn = this->score->insertMovie(name + " -buttons");
499 Movie *menuButtonsOut = this->score->insertMovie(name + " -buttons -out");
500 createLowLeftButton(QLatin1String("Quit"), QUIT, menuButtonsIn, menuButtonsOut, 0);
501 createLowRightButton("Toggle fullscreen", FULLSCREEN, menuButtonsIn, menuButtonsOut, 0);
502}
503
504void MenuManager::createSubMenu(const QDomElement &el)
505{
506 QString name = el.attribute("name");
507 createMenu(el, MENU2);
508 createInfo(new MenuContentItem(el, this->window->scene, 0), name + " -info");
509}
510
511void MenuManager::createLeafMenu(const QDomElement &el)
512{
513 QString name = el.attribute("name");
514 createInfo(new ExampleContent(name, this->window->scene, 0), name);
515
516 Movie *infoButtonsIn = this->score->insertMovie(name + " -buttons");
517 Movie *infoButtonsOut = this->score->insertMovie(name + " -buttons -out");
518 createLowRightLeafButton("Documentation", 600, DOCUMENTATION, infoButtonsIn, infoButtonsOut, 0);
519 if (el.attribute("executable") != "false")
520 createLowRightLeafButton("Launch", 405, LAUNCH, infoButtonsIn, infoButtonsOut, 0);
521}
522
523void MenuManager::createMenu(const QDomElement &category, BUTTON_TYPE type)
524{
525 qreal sw = this->window->scene->sceneRect().width();
526 int xOffset = 15;
527 int yOffset = 10;
528 int maxExamples = Colors::menuCount;
529 int menuIndex = 1;
530 QString name = category.attribute("name");
531 QDomNode currentNode = category.firstChild();
532 QString currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex);
533
534 while (!currentNode.isNull()){
535 Movie *movieIn = this->score->insertMovie(currentMenu);
536 Movie *movieOut = this->score->insertMovie(currentMenu + " -out");
537 Movie *movieNextTopOut = this->score->insertMovie(currentMenu + " -top_out");
538 Movie *movieNextBottomOut = this->score->insertMovie(currentMenu + " -bottom_out");
539 Movie *movieNextTopIn = this->score->insertMovie(currentMenu + " -top_in");
540 Movie *movieNextBottomIn = this->score->insertMovie(currentMenu + " -bottom_in");
541 Movie *movieShake = this->score->insertMovie(currentMenu + " -shake");
542
543 int i = 0;
544 while (!currentNode.isNull() && i < maxExamples){
545 TextButton *item;
546
547 // create normal menu button
548 QString label = currentNode.toElement().attribute("name");
549 item = new TextButton(label, TextButton::LEFT, type, this->window->scene, 0);
550 currentNode = currentNode.nextSibling();
551
552#ifndef QT_OPENGL_SUPPORT
553 if (currentNode.toElement().attribute("dirname") == "opengl")
554 currentNode = currentNode.nextSibling();
555#endif
556
557 item->setRecursiveVisible(false);
558 item->setZValue(10);
559 qreal ih = item->sceneBoundingRect().height();
560 qreal iw = item->sceneBoundingRect().width();
561 qreal ihp = ih + 3;
562
563 // create in-animation:
564 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
565 anim->setDuration(float(1000 + (i * 20)) * Colors::animSpeedButtons);
566 anim->setStartPos(QPointF(xOffset, -ih));
567 anim->setPosAt(0.20, QPointF(xOffset, -ih));
568 anim->setPosAt(0.50, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (10 * float(i / 4.0f))));
569 anim->setPosAt(0.60, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
570 anim->setPosAt(0.70, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (5 * float(i / 4.0f))));
571 anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
572 anim->setPosAt(0.90, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (2 * float(i / 4.0f))));
573 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
574 movieIn->append(anim);
575
576 // create out-animation:
577 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
578 anim->hideOnFinished = true;
579 anim->setDuration((700 + (30 * i)) * Colors::animSpeedButtons);
580 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
581 anim->setPosAt(0.60, QPointF(xOffset, 600 - ih - ih));
582 anim->setPosAt(0.65, QPointF(xOffset + 20, 600 - ih));
583 anim->setPosAt(1.00, QPointF(sw + iw, 600 - ih));
584 movieOut->append(anim);
585
586 // create shake-animation:
587 anim = new DemoItemAnimation(item);
588 anim->setDuration(700 * Colors::animSpeedButtons);
589 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
590 anim->setPosAt(0.55, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*2.0));
591 anim->setPosAt(0.70, QPointF(xOffset - 10, (i * ihp) + yOffset + Colors::contentStartY - i*1.5));
592 anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*1.0));
593 anim->setPosAt(0.90, QPointF(xOffset - 2, (i * ihp) + yOffset + Colors::contentStartY - i*0.5));
594 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
595 movieShake->append(anim);
596
597 // create next-menu top-out-animation:
598 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
599 anim->hideOnFinished = true;
600 anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons);
601 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
602 anim->setPosAt(0.70, QPointF(xOffset, yOffset + Colors::contentStartY));
603 anim->setPosAt(1.00, QPointF(-iw, yOffset + Colors::contentStartY));
604 movieNextTopOut->append(anim);
605
606 // create next-menu bottom-out-animation:
607 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
608 anim->hideOnFinished = true;
609 anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons);
610 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
611 anim->setPosAt(0.70, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY));
612 anim->setPosAt(1.00, QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY));
613 movieNextBottomOut->append(anim);
614
615 // create next-menu top-in-animation:
616 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
617 anim->setDuration((700 - (30 * i)) * Colors::animSpeedButtons);
618 anim->setStartPos(QPointF(-iw, yOffset + Colors::contentStartY));
619 anim->setPosAt(0.30, QPointF(xOffset, yOffset + Colors::contentStartY));
620 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
621 movieNextTopIn->append(anim);
622
623 // create next-menu bottom-in-animation:
624 int reverse = maxExamples - i;
625 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
626 anim->setDuration((1000 - (30 * reverse)) * Colors::animSpeedButtons);
627 anim->setStartPos(QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY));
628 anim->setPosAt(0.30, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY));
629 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
630 movieNextBottomIn->append(anim);
631
632 i++;
633 }
634
635 if (!currentNode.isNull() && i == maxExamples){
636 // We need another menu, so register for 'more' and 'back' buttons
637 ++menuIndex;
638 this->info[currentMenu]["more"] = name + QLatin1String(" -menu") + QString::number(menuIndex);
639 currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex);
640 this->info[currentMenu]["back"] = name + QLatin1String(" -menu") + QString::number(menuIndex - 1);
641 }
642 }
643}
644
645
646void MenuManager::createLowLeftButton(const QString &label, BUTTON_TYPE type,
647 Movie *movieIn, Movie *movieOut, Movie *movieShake, const QString &menuString)
648{
649 TextButton *button = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
650 if (!menuString.isNull())
651 button->setMenuString(menuString);
652 button->setRecursiveVisible(false);
653 button->setZValue(10);
654
655 qreal iw = button->sceneBoundingRect().width();
656 int xOffset = 15;
657
658 // create in-animation:
659 DemoItemAnimation *buttonIn = new DemoItemAnimation(button, DemoItemAnimation::ANIM_IN);
660 buttonIn->setDuration(1800 * Colors::animSpeedButtons);
661 buttonIn->setStartPos(QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35));
662 buttonIn->setPosAt(0.5, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35));
663 buttonIn->setPosAt(0.7, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
664 buttonIn->setPosAt(1.0, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
665 movieIn->append(buttonIn);
666
667 // create out-animation:
668 DemoItemAnimation *buttonOut = new DemoItemAnimation(button, DemoItemAnimation::ANIM_OUT);
669 buttonOut->hideOnFinished = true;
670 buttonOut->setDuration(400 * Colors::animSpeedButtons);
671 buttonOut->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
672 buttonOut->setPosAt(1.0, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 26));
673 movieOut->append(buttonOut);
674
675 if (movieShake){
676 DemoItemAnimation *shakeAnim = new DemoItemAnimation(button, DemoItemAnimation::ANIM_UNSPECIFIED);
677 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
678 shakeAnim->setDuration(650);
679 shakeAnim->setStartPos(buttonIn->posAt(1.0f));
680 shakeAnim->setPosAt(0.60, buttonIn->posAt(1.0f));
681 shakeAnim->setPosAt(0.70, buttonIn->posAt(1.0f) + QPointF(-3, 0));
682 shakeAnim->setPosAt(0.80, buttonIn->posAt(1.0f) + QPointF(2, 0));
683 shakeAnim->setPosAt(0.90, buttonIn->posAt(1.0f) + QPointF(-1, 0));
684 shakeAnim->setPosAt(1.00, buttonIn->posAt(1.0f));
685 movieShake->append(shakeAnim);
686 }
687}
688
689void MenuManager::createLowRightButton(const QString &label, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/)
690{
691 TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
692 item->setRecursiveVisible(false);
693 item->setZValue(10);
694
695 qreal sw = this->window->scene->sceneRect().width();
696 int xOffset = 70;
697
698 // create in-animation:
699 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
700 anim->setDuration(1800 * Colors::animSpeedButtons);
701 anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
702 anim->setPosAt(0.5, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
703 anim->setPosAt(0.7, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 35));
704 anim->setPosAt(1.0, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26));
705 movieIn->append(anim);
706
707 // create out-animation:
708 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
709 anim->hideOnFinished = true;
710 anim->setDuration(400 * Colors::animSpeedButtons);
711 anim->setStartPos(QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26));
712 anim->setPosAt(1.0, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 26));
713 movieOut->append(anim);
714}
715
716void MenuManager::createLowRightLeafButton(const QString &label, int xOffset, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/)
717{
718 TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
719 item->setRecursiveVisible(false);
720 item->setZValue(10);
721
722 qreal sw = this->window->scene->sceneRect().width();
723 qreal sh = this->window->scene->sceneRect().height();
724
725 // create in-animation:
726 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
727 anim->setDuration(1050 * Colors::animSpeedButtons);
728 anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
729 anim->setPosAt(0.10, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
730 anim->setPosAt(0.30, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
731 anim->setPosAt(0.35, QPointF(xOffset + 30, Colors::contentStartY + Colors::contentHeight - 35));
732 anim->setPosAt(0.40, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
733 anim->setPosAt(0.45, QPointF(xOffset + 5, Colors::contentStartY + Colors::contentHeight - 35));
734 anim->setPosAt(0.50, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
735 anim->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
736 movieIn->append(anim);
737
738 // create out-animation:
739 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
740 anim->hideOnFinished = true;
741 anim->setDuration(300 * Colors::animSpeedButtons);
742 anim->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
743 anim->setPosAt(1.0, QPointF(xOffset, sh));
744 movieOut->append(anim);
745}
746
747void MenuManager::createInfo(DemoItem *item, const QString &name)
748{
749 Movie *movie_in = this->score->insertMovie(name);
750 Movie *movie_out = this->score->insertMovie(name + " -out");
751 item->setZValue(8);
752 item->setRecursiveVisible(false);
753
754 float xOffset = 230.0f;
755 DemoItemAnimation *infoIn = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
756 infoIn->timeline->setCurveShape(QTimeLine::LinearCurve);
757 infoIn->setDuration(650);
758 infoIn->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY));
759 infoIn->setPosAt(0.60, QPointF(xOffset, Colors::contentStartY));
760 infoIn->setPosAt(0.70, QPointF(xOffset + 20, Colors::contentStartY));
761 infoIn->setPosAt(0.80, QPointF(xOffset, Colors::contentStartY));
762 infoIn->setPosAt(0.90, QPointF(xOffset + 7, Colors::contentStartY));
763 infoIn->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY));
764 movie_in->append(infoIn);
765
766 DemoItemAnimation *infoOut = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
767 infoOut->timeline->setCurveShape(QTimeLine::EaseInCurve);
768 infoOut->setDuration(300);
769 infoOut->hideOnFinished = true;
770 infoOut->setStartPos(QPointF(xOffset, Colors::contentStartY));
771 infoOut->setPosAt(1.0, QPointF(-600, Colors::contentStartY));
772 movie_out->append(infoOut);
773}
774
775void MenuManager::createTicker()
776{
777 if (!Colors::noTicker){
778 Movie *movie_in = this->score->insertMovie("ticker");
779 Movie *movie_out = this->score->insertMovie("ticker -out");
780 Movie *movie_activate = this->score->insertMovie("ticker -activate");
781 Movie *movie_deactivate = this->score->insertMovie("ticker -deactivate");
782
783 this->ticker = new ItemCircleAnimation(this->window->scene, 0);
784 this->ticker->setZValue(50);
785 this->ticker->hide();
786
787 // Move ticker in:
788 int qtendpos = 485;
789 int qtPosY = 120;
790 this->tickerInAnim = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_IN);
791 this->tickerInAnim->setDuration(500);
792 this->tickerInAnim->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY));
793 this->tickerInAnim->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY));
794 this->tickerInAnim->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY));
795 this->tickerInAnim->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY));
796 this->tickerInAnim->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY));
797 this->tickerInAnim->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY));
798 movie_in->append(this->tickerInAnim);
799
800 // Move ticker out:
801 DemoItemAnimation *qtOut = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_OUT);
802 qtOut->hideOnFinished = true;
803 qtOut->setDuration(500);
804 qtOut->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY));
805 qtOut->setPosAt(1.00, QPointF(this->window->scene->sceneRect().width() + 700, Colors::contentStartY + qtPosY));
806 movie_out->append(qtOut);
807
808 // Move ticker in on activate:
809 DemoItemAnimation *qtActivate = new DemoItemAnimation(this->ticker);
810 qtActivate->setDuration(400);
811 qtActivate->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY));
812 qtActivate->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY));
813 qtActivate->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY));
814 qtActivate->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY));
815 qtActivate->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY));
816 qtActivate->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY));
817 movie_activate->append(qtActivate);
818
819 // Move ticker out on deactivate:
820 DemoItemAnimation *qtDeactivate = new DemoItemAnimation(this->ticker);
821 qtDeactivate->hideOnFinished = true;
822 qtDeactivate->setDuration(400);
823 qtDeactivate->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY));
824 qtDeactivate->setPosAt(1.00, QPointF(qtendpos, 800));
825 movie_deactivate->append(qtDeactivate);
826 }
827}
828
829void MenuManager::createUpnDownButtons()
830{
831 float xOffset = 15.0f;
832 float yOffset = 450.0f;
833
834 this->upButton = new TextButton("", TextButton::LEFT, MenuManager::UP, this->window->scene, 0, TextButton::UP);
835 this->upButton->prepare();
836 this->upButton->setPos(xOffset, yOffset);
837 this->upButton->setState(TextButton::DISABLED);
838
839 this->downButton = new TextButton("", TextButton::LEFT, MenuManager::DOWN, this->window->scene, 0, TextButton::DOWN);
840 this->downButton->prepare();
841 this->downButton->setPos(xOffset + 10 + this->downButton->sceneBoundingRect().width(), yOffset);
842
843 Movie *movieShake = this->score->insertMovie("upndown -shake");
844
845 DemoItemAnimation *shakeAnim = new DemoItemAnimation(this->upButton, DemoItemAnimation::ANIM_UNSPECIFIED);
846 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
847 shakeAnim->setDuration(650);
848 shakeAnim->setStartPos(this->upButton->pos());
849 shakeAnim->setPosAt(0.60, this->upButton->pos());
850 shakeAnim->setPosAt(0.70, this->upButton->pos() + QPointF(-2, 0));
851 shakeAnim->setPosAt(0.80, this->upButton->pos() + QPointF(1, 0));
852 shakeAnim->setPosAt(0.90, this->upButton->pos() + QPointF(-1, 0));
853 shakeAnim->setPosAt(1.00, this->upButton->pos());
854 movieShake->append(shakeAnim);
855
856 shakeAnim = new DemoItemAnimation(this->downButton, DemoItemAnimation::ANIM_UNSPECIFIED);
857 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
858 shakeAnim->setDuration(650);
859 shakeAnim->setStartPos(this->downButton->pos());
860 shakeAnim->setPosAt(0.60, this->downButton->pos());
861 shakeAnim->setPosAt(0.70, this->downButton->pos() + QPointF(-5, 0));
862 shakeAnim->setPosAt(0.80, this->downButton->pos() + QPointF(-3, 0));
863 shakeAnim->setPosAt(0.90, this->downButton->pos() + QPointF(-1, 0));
864 shakeAnim->setPosAt(1.00, this->downButton->pos());
865 movieShake->append(shakeAnim);
866}
867
868void MenuManager::createBackButton()
869{
870 Movie *backIn = this->score->insertMovie("back -in");
871 Movie *backOut = this->score->insertMovie("back -out");
872 Movie *backShake = this->score->insertMovie("back -shake");
873 createLowLeftButton(QLatin1String("Back"), ROOT, backIn, backOut, backShake, Colors::rootMenuName);
874}
Note: See TracBrowser for help on using the repository browser.