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

Last change on this file since 452 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 38.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the demonstration applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department 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 QString curpath = QString::fromLocal8Bit(qgetenv("PATH").constData());
328 QString newpath = QString("PATH=%1;%2").arg(QLibraryInfo::location(QLibraryInfo::BinariesPath), curpath);
329 process->setEnvironment(QStringList(newpath));
330#endif
331
332 if (info[name]["changedirectory"] != "false"){
333 QString workingDirectory = resolveDataDir(name);
334 process->setWorkingDirectory(workingDirectory);
335 if (Colors::verbose)
336 qDebug() << "Setting working directory:" << workingDirectory;
337 }
338
339 if (Colors::verbose)
340 qDebug() << "Launching:" << executable;
341 process->start(executable);
342#endif
343}
344
345void MenuManager::exampleFinished()
346{
347}
348
349void MenuManager::exampleError(QProcess::ProcessError error)
350{
351 if (error != QProcess::Crashed)
352 QMessageBox::critical(0, tr("Failed to launch the example"),
353 tr("Could not launch the example. Ensure that it has been built."),
354 QMessageBox::Cancel);
355}
356
357void MenuManager::init(MainWindow *window)
358{
359 this->window = window;
360
361 // Create div:
362 this->createTicker();
363 this->createUpnDownButtons();
364 this->createBackButton();
365
366 // Create first level menu:
367 QDomElement rootElement = this->contentsDoc->documentElement();
368 this->createRootMenu(rootElement);
369
370 // Create second level menus:
371 QDomNode level2MenuNode = rootElement.firstChild();
372 while (!level2MenuNode.isNull()){
373 QDomElement level2MenuElement = level2MenuNode.toElement();
374 this->createSubMenu(level2MenuElement);
375
376 // create leaf menu and example info:
377 QDomNode exampleNode = level2MenuElement.firstChild();
378 while (!exampleNode.isNull()){
379 QDomElement exampleElement = exampleNode.toElement();
380 this->readInfoAboutExample(exampleElement);
381 this->createLeafMenu(exampleElement);
382 exampleNode = exampleNode.nextSibling();
383 }
384
385 level2MenuNode = level2MenuNode.nextSibling();
386 }
387}
388
389void MenuManager::readInfoAboutExample(const QDomElement &example)
390{
391 QString name = example.attribute("name");
392 if (this->info.contains(name))
393 qWarning() << "__WARNING: MenuManager::readInfoAboutExample: Demo/example with name"
394 << name << "appears twize in the xml-file!__";
395
396 this->info[name]["filename"] = example.attribute("filename");
397 this->info[name]["category"] = example.parentNode().toElement().tagName();
398 this->info[name]["dirname"] = example.parentNode().toElement().attribute("dirname");
399 this->info[name]["changedirectory"] = example.attribute("changedirectory");
400 this->info[name]["image"] = example.attribute("image");
401}
402
403QString MenuManager::resolveDataDir(const QString &name)
404{
405 QString dirName = this->info[name]["dirname"];
406 QString category = this->info[name]["category"];
407 QString fileName = this->info[name]["filename"];
408
409 QDir dir;
410 if (category == "demos")
411 dir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath));
412 else
413 dir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath));
414
415 dir.cd(dirName);
416 dir.cd(fileName);
417 return dir.absolutePath();
418}
419
420QString MenuManager::resolveExeFile(const QString &name)
421{
422 QString dirName = this->info[name]["dirname"];
423 QString category = this->info[name]["category"];
424 QString fileName = this->info[name]["filename"];
425
426 QDir dir;
427 if (category == "demos")
428 dir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath));
429 else
430 dir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath));
431
432 dir.cd(dirName);
433 dir.cd(fileName);
434
435 QFile unixFile(dir.path() + "/" + fileName);
436 if (unixFile.exists()) return unixFile.fileName();
437 QFile winR(dir.path() + "\\release\\" + fileName + ".exe");
438 if (winR.exists()) return winR.fileName();
439 QFile winD(dir.path() + "\\debug\\" + fileName + ".exe");
440 if (winD.exists()) return winD.fileName();
441 QFile mac(dir.path() + "/" + fileName + ".app");
442 if (mac.exists()) return mac.fileName();
443
444 if (Colors::verbose)
445 qDebug() << "- WARNING: Could not resolve executable:" << dir.path() << fileName;
446 return "__executable not found__";
447}
448
449QString MenuManager::resolveDocUrl(const QString &name)
450{
451 QString dirName = this->info[name]["dirname"];
452 QString category = this->info[name]["category"];
453 QString fileName = this->info[name]["filename"];
454
455 if (category == "demos")
456 return this->helpRootUrl + "demos-" + fileName + ".html";
457 else
458 return this->helpRootUrl + dirName.replace("/", "-") + "-" + fileName + ".html";
459}
460
461QString MenuManager::resolveImageUrl(const QString &name)
462{
463 return this->helpRootUrl + "images/" + name;
464}
465
466QByteArray MenuManager::getHtml(const QString &name)
467{
468 return getResource(this->resolveDocUrl(name));
469}
470
471QByteArray MenuManager::getImage(const QString &name)
472{
473 QString imageName = this->info[name]["image"];
474 QString category = this->info[name]["category"];
475 QString fileName = this->info[name]["filename"];
476
477 if (imageName.isEmpty()){
478 if (category == "demos")
479 imageName = fileName + "-demo.png";
480 else
481 imageName = fileName + "-example.png";
482 if ((getResource(resolveImageUrl(imageName))).isEmpty())
483 imageName = fileName + ".png";
484 if ((getResource(resolveImageUrl(imageName))).isEmpty())
485 imageName = fileName + "example.png";
486 }
487 return getResource(resolveImageUrl(imageName));
488}
489
490
491void MenuManager::createRootMenu(const QDomElement &el)
492{
493 QString name = el.attribute("name");
494 createMenu(el, MENU1);
495 createInfo(new MenuContentItem(el, this->window->scene, 0), name + " -info");
496
497 Movie *menuButtonsIn = this->score->insertMovie(name + " -buttons");
498 Movie *menuButtonsOut = this->score->insertMovie(name + " -buttons -out");
499 createLowLeftButton(QLatin1String("Quit"), QUIT, menuButtonsIn, menuButtonsOut, 0);
500 createLowRightButton("Toggle fullscreen", FULLSCREEN, menuButtonsIn, menuButtonsOut, 0);
501}
502
503void MenuManager::createSubMenu(const QDomElement &el)
504{
505 QString name = el.attribute("name");
506 createMenu(el, MENU2);
507 createInfo(new MenuContentItem(el, this->window->scene, 0), name + " -info");
508}
509
510void MenuManager::createLeafMenu(const QDomElement &el)
511{
512 QString name = el.attribute("name");
513 createInfo(new ExampleContent(name, this->window->scene, 0), name);
514
515 Movie *infoButtonsIn = this->score->insertMovie(name + " -buttons");
516 Movie *infoButtonsOut = this->score->insertMovie(name + " -buttons -out");
517 createLowRightLeafButton("Documentation", 600, DOCUMENTATION, infoButtonsIn, infoButtonsOut, 0);
518 if (el.attribute("executable") != "false")
519 createLowRightLeafButton("Launch", 405, LAUNCH, infoButtonsIn, infoButtonsOut, 0);
520}
521
522void MenuManager::createMenu(const QDomElement &category, BUTTON_TYPE type)
523{
524 qreal sw = this->window->scene->sceneRect().width();
525 int xOffset = 15;
526 int yOffset = 10;
527 int maxExamples = Colors::menuCount;
528 int menuIndex = 1;
529 QString name = category.attribute("name");
530 QDomNode currentNode = category.firstChild();
531 QString currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex);
532
533 while (!currentNode.isNull()){
534 Movie *movieIn = this->score->insertMovie(currentMenu);
535 Movie *movieOut = this->score->insertMovie(currentMenu + " -out");
536 Movie *movieNextTopOut = this->score->insertMovie(currentMenu + " -top_out");
537 Movie *movieNextBottomOut = this->score->insertMovie(currentMenu + " -bottom_out");
538 Movie *movieNextTopIn = this->score->insertMovie(currentMenu + " -top_in");
539 Movie *movieNextBottomIn = this->score->insertMovie(currentMenu + " -bottom_in");
540 Movie *movieShake = this->score->insertMovie(currentMenu + " -shake");
541
542 int i = 0;
543 while (!currentNode.isNull() && i < maxExamples){
544 TextButton *item;
545
546 // create normal menu button
547 QString label = currentNode.toElement().attribute("name");
548 item = new TextButton(label, TextButton::LEFT, type, this->window->scene, 0);
549 currentNode = currentNode.nextSibling();
550
551#ifndef QT_OPENGL_SUPPORT
552 if (currentNode.toElement().attribute("dirname") == "opengl")
553 currentNode = currentNode.nextSibling();
554#endif
555
556 item->setRecursiveVisible(false);
557 item->setZValue(10);
558 qreal ih = item->sceneBoundingRect().height();
559 qreal iw = item->sceneBoundingRect().width();
560 qreal ihp = ih + 3;
561
562 // create in-animation:
563 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
564 anim->setDuration(float(1000 + (i * 20)) * Colors::animSpeedButtons);
565 anim->setStartPos(QPointF(xOffset, -ih));
566 anim->setPosAt(0.20, QPointF(xOffset, -ih));
567 anim->setPosAt(0.50, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (10 * float(i / 4.0f))));
568 anim->setPosAt(0.60, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
569 anim->setPosAt(0.70, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (5 * float(i / 4.0f))));
570 anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
571 anim->setPosAt(0.90, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (2 * float(i / 4.0f))));
572 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
573 movieIn->append(anim);
574
575 // create out-animation:
576 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
577 anim->hideOnFinished = true;
578 anim->setDuration((700 + (30 * i)) * Colors::animSpeedButtons);
579 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
580 anim->setPosAt(0.60, QPointF(xOffset, 600 - ih - ih));
581 anim->setPosAt(0.65, QPointF(xOffset + 20, 600 - ih));
582 anim->setPosAt(1.00, QPointF(sw + iw, 600 - ih));
583 movieOut->append(anim);
584
585 // create shake-animation:
586 anim = new DemoItemAnimation(item);
587 anim->setDuration(700 * Colors::animSpeedButtons);
588 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
589 anim->setPosAt(0.55, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*2.0));
590 anim->setPosAt(0.70, QPointF(xOffset - 10, (i * ihp) + yOffset + Colors::contentStartY - i*1.5));
591 anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*1.0));
592 anim->setPosAt(0.90, QPointF(xOffset - 2, (i * ihp) + yOffset + Colors::contentStartY - i*0.5));
593 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
594 movieShake->append(anim);
595
596 // create next-menu top-out-animation:
597 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
598 anim->hideOnFinished = true;
599 anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons);
600 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
601 anim->setPosAt(0.70, QPointF(xOffset, yOffset + Colors::contentStartY));
602 anim->setPosAt(1.00, QPointF(-iw, yOffset + Colors::contentStartY));
603 movieNextTopOut->append(anim);
604
605 // create next-menu bottom-out-animation:
606 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
607 anim->hideOnFinished = true;
608 anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons);
609 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
610 anim->setPosAt(0.70, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY));
611 anim->setPosAt(1.00, QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY));
612 movieNextBottomOut->append(anim);
613
614 // create next-menu top-in-animation:
615 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
616 anim->setDuration((700 - (30 * i)) * Colors::animSpeedButtons);
617 anim->setStartPos(QPointF(-iw, yOffset + Colors::contentStartY));
618 anim->setPosAt(0.30, QPointF(xOffset, yOffset + Colors::contentStartY));
619 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
620 movieNextTopIn->append(anim);
621
622 // create next-menu bottom-in-animation:
623 int reverse = maxExamples - i;
624 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
625 anim->setDuration((1000 - (30 * reverse)) * Colors::animSpeedButtons);
626 anim->setStartPos(QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY));
627 anim->setPosAt(0.30, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY));
628 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
629 movieNextBottomIn->append(anim);
630
631 i++;
632 }
633
634 if (!currentNode.isNull() && i == maxExamples){
635 // We need another menu, so register for 'more' and 'back' buttons
636 ++menuIndex;
637 this->info[currentMenu]["more"] = name + QLatin1String(" -menu") + QString::number(menuIndex);
638 currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex);
639 this->info[currentMenu]["back"] = name + QLatin1String(" -menu") + QString::number(menuIndex - 1);
640 }
641 }
642}
643
644
645void MenuManager::createLowLeftButton(const QString &label, BUTTON_TYPE type,
646 Movie *movieIn, Movie *movieOut, Movie *movieShake, const QString &menuString)
647{
648 TextButton *button = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
649 if (!menuString.isNull())
650 button->setMenuString(menuString);
651 button->setRecursiveVisible(false);
652 button->setZValue(10);
653
654 qreal iw = button->sceneBoundingRect().width();
655 int xOffset = 15;
656
657 // create in-animation:
658 DemoItemAnimation *buttonIn = new DemoItemAnimation(button, DemoItemAnimation::ANIM_IN);
659 buttonIn->setDuration(1800 * Colors::animSpeedButtons);
660 buttonIn->setStartPos(QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35));
661 buttonIn->setPosAt(0.5, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35));
662 buttonIn->setPosAt(0.7, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
663 buttonIn->setPosAt(1.0, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
664 movieIn->append(buttonIn);
665
666 // create out-animation:
667 DemoItemAnimation *buttonOut = new DemoItemAnimation(button, DemoItemAnimation::ANIM_OUT);
668 buttonOut->hideOnFinished = true;
669 buttonOut->setDuration(400 * Colors::animSpeedButtons);
670 buttonOut->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
671 buttonOut->setPosAt(1.0, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 26));
672 movieOut->append(buttonOut);
673
674 if (movieShake){
675 DemoItemAnimation *shakeAnim = new DemoItemAnimation(button, DemoItemAnimation::ANIM_UNSPECIFIED);
676 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
677 shakeAnim->setDuration(650);
678 shakeAnim->setStartPos(buttonIn->posAt(1.0f));
679 shakeAnim->setPosAt(0.60, buttonIn->posAt(1.0f));
680 shakeAnim->setPosAt(0.70, buttonIn->posAt(1.0f) + QPointF(-3, 0));
681 shakeAnim->setPosAt(0.80, buttonIn->posAt(1.0f) + QPointF(2, 0));
682 shakeAnim->setPosAt(0.90, buttonIn->posAt(1.0f) + QPointF(-1, 0));
683 shakeAnim->setPosAt(1.00, buttonIn->posAt(1.0f));
684 movieShake->append(shakeAnim);
685 }
686}
687
688void MenuManager::createLowRightButton(const QString &label, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/)
689{
690 TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
691 item->setRecursiveVisible(false);
692 item->setZValue(10);
693
694 qreal sw = this->window->scene->sceneRect().width();
695 int xOffset = 70;
696
697 // create in-animation:
698 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
699 anim->setDuration(1800 * Colors::animSpeedButtons);
700 anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
701 anim->setPosAt(0.5, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
702 anim->setPosAt(0.7, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 35));
703 anim->setPosAt(1.0, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26));
704 movieIn->append(anim);
705
706 // create out-animation:
707 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
708 anim->hideOnFinished = true;
709 anim->setDuration(400 * Colors::animSpeedButtons);
710 anim->setStartPos(QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26));
711 anim->setPosAt(1.0, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 26));
712 movieOut->append(anim);
713}
714
715void MenuManager::createLowRightLeafButton(const QString &label, int xOffset, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/)
716{
717 TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
718 item->setRecursiveVisible(false);
719 item->setZValue(10);
720
721 qreal sw = this->window->scene->sceneRect().width();
722 qreal sh = this->window->scene->sceneRect().height();
723
724 // create in-animation:
725 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
726 anim->setDuration(1050 * Colors::animSpeedButtons);
727 anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
728 anim->setPosAt(0.10, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
729 anim->setPosAt(0.30, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
730 anim->setPosAt(0.35, QPointF(xOffset + 30, Colors::contentStartY + Colors::contentHeight - 35));
731 anim->setPosAt(0.40, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
732 anim->setPosAt(0.45, QPointF(xOffset + 5, Colors::contentStartY + Colors::contentHeight - 35));
733 anim->setPosAt(0.50, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
734 anim->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
735 movieIn->append(anim);
736
737 // create out-animation:
738 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
739 anim->hideOnFinished = true;
740 anim->setDuration(300 * Colors::animSpeedButtons);
741 anim->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
742 anim->setPosAt(1.0, QPointF(xOffset, sh));
743 movieOut->append(anim);
744}
745
746void MenuManager::createInfo(DemoItem *item, const QString &name)
747{
748 Movie *movie_in = this->score->insertMovie(name);
749 Movie *movie_out = this->score->insertMovie(name + " -out");
750 item->setZValue(8);
751 item->setRecursiveVisible(false);
752
753 float xOffset = 230.0f;
754 DemoItemAnimation *infoIn = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
755 infoIn->timeline->setCurveShape(QTimeLine::LinearCurve);
756 infoIn->setDuration(650);
757 infoIn->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY));
758 infoIn->setPosAt(0.60, QPointF(xOffset, Colors::contentStartY));
759 infoIn->setPosAt(0.70, QPointF(xOffset + 20, Colors::contentStartY));
760 infoIn->setPosAt(0.80, QPointF(xOffset, Colors::contentStartY));
761 infoIn->setPosAt(0.90, QPointF(xOffset + 7, Colors::contentStartY));
762 infoIn->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY));
763 movie_in->append(infoIn);
764
765 DemoItemAnimation *infoOut = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
766 infoOut->timeline->setCurveShape(QTimeLine::EaseInCurve);
767 infoOut->setDuration(300);
768 infoOut->hideOnFinished = true;
769 infoOut->setStartPos(QPointF(xOffset, Colors::contentStartY));
770 infoOut->setPosAt(1.0, QPointF(-600, Colors::contentStartY));
771 movie_out->append(infoOut);
772}
773
774void MenuManager::createTicker()
775{
776 if (!Colors::noTicker){
777 Movie *movie_in = this->score->insertMovie("ticker");
778 Movie *movie_out = this->score->insertMovie("ticker -out");
779 Movie *movie_activate = this->score->insertMovie("ticker -activate");
780 Movie *movie_deactivate = this->score->insertMovie("ticker -deactivate");
781
782 this->ticker = new ItemCircleAnimation(this->window->scene, 0);
783 this->ticker->setZValue(50);
784 this->ticker->hide();
785
786 // Move ticker in:
787 int qtendpos = 485;
788 int qtPosY = 120;
789 this->tickerInAnim = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_IN);
790 this->tickerInAnim->setDuration(500);
791 this->tickerInAnim->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY));
792 this->tickerInAnim->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY));
793 this->tickerInAnim->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY));
794 this->tickerInAnim->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY));
795 this->tickerInAnim->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY));
796 this->tickerInAnim->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY));
797 movie_in->append(this->tickerInAnim);
798
799 // Move ticker out:
800 DemoItemAnimation *qtOut = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_OUT);
801 qtOut->hideOnFinished = true;
802 qtOut->setDuration(500);
803 qtOut->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY));
804 qtOut->setPosAt(1.00, QPointF(this->window->scene->sceneRect().width() + 700, Colors::contentStartY + qtPosY));
805 movie_out->append(qtOut);
806
807 // Move ticker in on activate:
808 DemoItemAnimation *qtActivate = new DemoItemAnimation(this->ticker);
809 qtActivate->setDuration(400);
810 qtActivate->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY));
811 qtActivate->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY));
812 qtActivate->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY));
813 qtActivate->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY));
814 qtActivate->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY));
815 qtActivate->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY));
816 movie_activate->append(qtActivate);
817
818 // Move ticker out on deactivate:
819 DemoItemAnimation *qtDeactivate = new DemoItemAnimation(this->ticker);
820 qtDeactivate->hideOnFinished = true;
821 qtDeactivate->setDuration(400);
822 qtDeactivate->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY));
823 qtDeactivate->setPosAt(1.00, QPointF(qtendpos, 800));
824 movie_deactivate->append(qtDeactivate);
825 }
826}
827
828void MenuManager::createUpnDownButtons()
829{
830 float xOffset = 15.0f;
831 float yOffset = 450.0f;
832
833 this->upButton = new TextButton("", TextButton::LEFT, MenuManager::UP, this->window->scene, 0, TextButton::UP);
834 this->upButton->prepare();
835 this->upButton->setPos(xOffset, yOffset);
836 this->upButton->setState(TextButton::DISABLED);
837
838 this->downButton = new TextButton("", TextButton::LEFT, MenuManager::DOWN, this->window->scene, 0, TextButton::DOWN);
839 this->downButton->prepare();
840 this->downButton->setPos(xOffset + 10 + this->downButton->sceneBoundingRect().width(), yOffset);
841
842 Movie *movieShake = this->score->insertMovie("upndown -shake");
843
844 DemoItemAnimation *shakeAnim = new DemoItemAnimation(this->upButton, DemoItemAnimation::ANIM_UNSPECIFIED);
845 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
846 shakeAnim->setDuration(650);
847 shakeAnim->setStartPos(this->upButton->pos());
848 shakeAnim->setPosAt(0.60, this->upButton->pos());
849 shakeAnim->setPosAt(0.70, this->upButton->pos() + QPointF(-2, 0));
850 shakeAnim->setPosAt(0.80, this->upButton->pos() + QPointF(1, 0));
851 shakeAnim->setPosAt(0.90, this->upButton->pos() + QPointF(-1, 0));
852 shakeAnim->setPosAt(1.00, this->upButton->pos());
853 movieShake->append(shakeAnim);
854
855 shakeAnim = new DemoItemAnimation(this->downButton, DemoItemAnimation::ANIM_UNSPECIFIED);
856 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
857 shakeAnim->setDuration(650);
858 shakeAnim->setStartPos(this->downButton->pos());
859 shakeAnim->setPosAt(0.60, this->downButton->pos());
860 shakeAnim->setPosAt(0.70, this->downButton->pos() + QPointF(-5, 0));
861 shakeAnim->setPosAt(0.80, this->downButton->pos() + QPointF(-3, 0));
862 shakeAnim->setPosAt(0.90, this->downButton->pos() + QPointF(-1, 0));
863 shakeAnim->setPosAt(1.00, this->downButton->pos());
864 movieShake->append(shakeAnim);
865}
866
867void MenuManager::createBackButton()
868{
869 Movie *backIn = this->score->insertMovie("back -in");
870 Movie *backOut = this->score->insertMovie("back -out");
871 Movie *backShake = this->score->insertMovie("back -shake");
872 createLowLeftButton(QLatin1String("Back"), ROOT, backIn, backOut, backShake, Colors::rootMenuName);
873}
Note: See TracBrowser for help on using the repository browser.