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

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

qtdemo: Make it find demo and example executables on OS/2.

File size: 38.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 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 os2File(dir.path() + "\\" + fileName + ".exe");
439 if (os2File.exists()) return os2File.fileName();
440 QFile winR(dir.path() + "\\release\\" + fileName + ".exe");
441 if (winR.exists()) return winR.fileName();
442 QFile winD(dir.path() + "\\debug\\" + fileName + ".exe");
443 if (winD.exists()) return winD.fileName();
444 QFile mac(dir.path() + "/" + fileName + ".app");
445 if (mac.exists()) return mac.fileName();
446
447 if (Colors::verbose)
448 qDebug() << "- WARNING: Could not resolve executable:" << dir.path() << fileName;
449 return "__executable not found__";
450}
451
452QString MenuManager::resolveDocUrl(const QString &name)
453{
454 QString dirName = this->info[name]["dirname"];
455 QString category = this->info[name]["category"];
456 QString fileName = this->info[name]["filename"];
457
458 if (category == "demos")
459 return this->helpRootUrl + "demos-" + fileName + ".html";
460 else
461 return this->helpRootUrl + dirName.replace("/", "-") + "-" + fileName + ".html";
462}
463
464QString MenuManager::resolveImageUrl(const QString &name)
465{
466 return this->helpRootUrl + "images/" + name;
467}
468
469QByteArray MenuManager::getHtml(const QString &name)
470{
471 return getResource(this->resolveDocUrl(name));
472}
473
474QByteArray MenuManager::getImage(const QString &name)
475{
476 QString imageName = this->info[name]["image"];
477 QString category = this->info[name]["category"];
478 QString fileName = this->info[name]["filename"];
479
480 if (imageName.isEmpty()){
481 if (category == "demos")
482 imageName = fileName + "-demo.png";
483 else
484 imageName = fileName + "-example.png";
485 if ((getResource(resolveImageUrl(imageName))).isEmpty())
486 imageName = fileName + ".png";
487 if ((getResource(resolveImageUrl(imageName))).isEmpty())
488 imageName = fileName + "example.png";
489 }
490 return getResource(resolveImageUrl(imageName));
491}
492
493
494void MenuManager::createRootMenu(const QDomElement &el)
495{
496 QString name = el.attribute("name");
497 createMenu(el, MENU1);
498 createInfo(new MenuContentItem(el, this->window->scene, 0), name + " -info");
499
500 Movie *menuButtonsIn = this->score->insertMovie(name + " -buttons");
501 Movie *menuButtonsOut = this->score->insertMovie(name + " -buttons -out");
502 createLowLeftButton(QLatin1String("Quit"), QUIT, menuButtonsIn, menuButtonsOut, 0);
503 createLowRightButton("Toggle fullscreen", FULLSCREEN, menuButtonsIn, menuButtonsOut, 0);
504}
505
506void MenuManager::createSubMenu(const QDomElement &el)
507{
508 QString name = el.attribute("name");
509 createMenu(el, MENU2);
510 createInfo(new MenuContentItem(el, this->window->scene, 0), name + " -info");
511}
512
513void MenuManager::createLeafMenu(const QDomElement &el)
514{
515 QString name = el.attribute("name");
516 createInfo(new ExampleContent(name, this->window->scene, 0), name);
517
518 Movie *infoButtonsIn = this->score->insertMovie(name + " -buttons");
519 Movie *infoButtonsOut = this->score->insertMovie(name + " -buttons -out");
520 createLowRightLeafButton("Documentation", 600, DOCUMENTATION, infoButtonsIn, infoButtonsOut, 0);
521 if (el.attribute("executable") != "false")
522 createLowRightLeafButton("Launch", 405, LAUNCH, infoButtonsIn, infoButtonsOut, 0);
523}
524
525void MenuManager::createMenu(const QDomElement &category, BUTTON_TYPE type)
526{
527 qreal sw = this->window->scene->sceneRect().width();
528 int xOffset = 15;
529 int yOffset = 10;
530 int maxExamples = Colors::menuCount;
531 int menuIndex = 1;
532 QString name = category.attribute("name");
533 QDomNode currentNode = category.firstChild();
534 QString currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex);
535
536 while (!currentNode.isNull()){
537 Movie *movieIn = this->score->insertMovie(currentMenu);
538 Movie *movieOut = this->score->insertMovie(currentMenu + " -out");
539 Movie *movieNextTopOut = this->score->insertMovie(currentMenu + " -top_out");
540 Movie *movieNextBottomOut = this->score->insertMovie(currentMenu + " -bottom_out");
541 Movie *movieNextTopIn = this->score->insertMovie(currentMenu + " -top_in");
542 Movie *movieNextBottomIn = this->score->insertMovie(currentMenu + " -bottom_in");
543 Movie *movieShake = this->score->insertMovie(currentMenu + " -shake");
544
545 int i = 0;
546 while (!currentNode.isNull() && i < maxExamples){
547 TextButton *item;
548
549 // create normal menu button
550 QString label = currentNode.toElement().attribute("name");
551 item = new TextButton(label, TextButton::LEFT, type, this->window->scene, 0);
552 currentNode = currentNode.nextSibling();
553
554#ifndef QT_OPENGL_SUPPORT
555 if (currentNode.toElement().attribute("dirname") == "opengl")
556 currentNode = currentNode.nextSibling();
557#endif
558
559 item->setRecursiveVisible(false);
560 item->setZValue(10);
561 qreal ih = item->sceneBoundingRect().height();
562 qreal iw = item->sceneBoundingRect().width();
563 qreal ihp = ih + 3;
564
565 // create in-animation:
566 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
567 anim->setDuration(float(1000 + (i * 20)) * Colors::animSpeedButtons);
568 anim->setStartPos(QPointF(xOffset, -ih));
569 anim->setPosAt(0.20, QPointF(xOffset, -ih));
570 anim->setPosAt(0.50, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (10 * float(i / 4.0f))));
571 anim->setPosAt(0.60, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
572 anim->setPosAt(0.70, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (5 * float(i / 4.0f))));
573 anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
574 anim->setPosAt(0.90, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (2 * float(i / 4.0f))));
575 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
576 movieIn->append(anim);
577
578 // create out-animation:
579 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
580 anim->hideOnFinished = true;
581 anim->setDuration((700 + (30 * i)) * Colors::animSpeedButtons);
582 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
583 anim->setPosAt(0.60, QPointF(xOffset, 600 - ih - ih));
584 anim->setPosAt(0.65, QPointF(xOffset + 20, 600 - ih));
585 anim->setPosAt(1.00, QPointF(sw + iw, 600 - ih));
586 movieOut->append(anim);
587
588 // create shake-animation:
589 anim = new DemoItemAnimation(item);
590 anim->setDuration(700 * Colors::animSpeedButtons);
591 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
592 anim->setPosAt(0.55, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*2.0));
593 anim->setPosAt(0.70, QPointF(xOffset - 10, (i * ihp) + yOffset + Colors::contentStartY - i*1.5));
594 anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*1.0));
595 anim->setPosAt(0.90, QPointF(xOffset - 2, (i * ihp) + yOffset + Colors::contentStartY - i*0.5));
596 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
597 movieShake->append(anim);
598
599 // create next-menu top-out-animation:
600 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
601 anim->hideOnFinished = true;
602 anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons);
603 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
604 anim->setPosAt(0.70, QPointF(xOffset, yOffset + Colors::contentStartY));
605 anim->setPosAt(1.00, QPointF(-iw, yOffset + Colors::contentStartY));
606 movieNextTopOut->append(anim);
607
608 // create next-menu bottom-out-animation:
609 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
610 anim->hideOnFinished = true;
611 anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons);
612 anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
613 anim->setPosAt(0.70, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY));
614 anim->setPosAt(1.00, QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY));
615 movieNextBottomOut->append(anim);
616
617 // create next-menu top-in-animation:
618 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
619 anim->setDuration((700 - (30 * i)) * Colors::animSpeedButtons);
620 anim->setStartPos(QPointF(-iw, yOffset + Colors::contentStartY));
621 anim->setPosAt(0.30, QPointF(xOffset, yOffset + Colors::contentStartY));
622 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
623 movieNextTopIn->append(anim);
624
625 // create next-menu bottom-in-animation:
626 int reverse = maxExamples - i;
627 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
628 anim->setDuration((1000 - (30 * reverse)) * Colors::animSpeedButtons);
629 anim->setStartPos(QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY));
630 anim->setPosAt(0.30, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY));
631 anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY));
632 movieNextBottomIn->append(anim);
633
634 i++;
635 }
636
637 if (!currentNode.isNull() && i == maxExamples){
638 // We need another menu, so register for 'more' and 'back' buttons
639 ++menuIndex;
640 this->info[currentMenu]["more"] = name + QLatin1String(" -menu") + QString::number(menuIndex);
641 currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex);
642 this->info[currentMenu]["back"] = name + QLatin1String(" -menu") + QString::number(menuIndex - 1);
643 }
644 }
645}
646
647
648void MenuManager::createLowLeftButton(const QString &label, BUTTON_TYPE type,
649 Movie *movieIn, Movie *movieOut, Movie *movieShake, const QString &menuString)
650{
651 TextButton *button = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
652 if (!menuString.isNull())
653 button->setMenuString(menuString);
654 button->setRecursiveVisible(false);
655 button->setZValue(10);
656
657 qreal iw = button->sceneBoundingRect().width();
658 int xOffset = 15;
659
660 // create in-animation:
661 DemoItemAnimation *buttonIn = new DemoItemAnimation(button, DemoItemAnimation::ANIM_IN);
662 buttonIn->setDuration(1800 * Colors::animSpeedButtons);
663 buttonIn->setStartPos(QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35));
664 buttonIn->setPosAt(0.5, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35));
665 buttonIn->setPosAt(0.7, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
666 buttonIn->setPosAt(1.0, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
667 movieIn->append(buttonIn);
668
669 // create out-animation:
670 DemoItemAnimation *buttonOut = new DemoItemAnimation(button, DemoItemAnimation::ANIM_OUT);
671 buttonOut->hideOnFinished = true;
672 buttonOut->setDuration(400 * Colors::animSpeedButtons);
673 buttonOut->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
674 buttonOut->setPosAt(1.0, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 26));
675 movieOut->append(buttonOut);
676
677 if (movieShake){
678 DemoItemAnimation *shakeAnim = new DemoItemAnimation(button, DemoItemAnimation::ANIM_UNSPECIFIED);
679 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
680 shakeAnim->setDuration(650);
681 shakeAnim->setStartPos(buttonIn->posAt(1.0f));
682 shakeAnim->setPosAt(0.60, buttonIn->posAt(1.0f));
683 shakeAnim->setPosAt(0.70, buttonIn->posAt(1.0f) + QPointF(-3, 0));
684 shakeAnim->setPosAt(0.80, buttonIn->posAt(1.0f) + QPointF(2, 0));
685 shakeAnim->setPosAt(0.90, buttonIn->posAt(1.0f) + QPointF(-1, 0));
686 shakeAnim->setPosAt(1.00, buttonIn->posAt(1.0f));
687 movieShake->append(shakeAnim);
688 }
689}
690
691void MenuManager::createLowRightButton(const QString &label, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/)
692{
693 TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
694 item->setRecursiveVisible(false);
695 item->setZValue(10);
696
697 qreal sw = this->window->scene->sceneRect().width();
698 int xOffset = 70;
699
700 // create in-animation:
701 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
702 anim->setDuration(1800 * Colors::animSpeedButtons);
703 anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
704 anim->setPosAt(0.5, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
705 anim->setPosAt(0.7, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 35));
706 anim->setPosAt(1.0, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26));
707 movieIn->append(anim);
708
709 // create out-animation:
710 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
711 anim->hideOnFinished = true;
712 anim->setDuration(400 * Colors::animSpeedButtons);
713 anim->setStartPos(QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26));
714 anim->setPosAt(1.0, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 26));
715 movieOut->append(anim);
716}
717
718void MenuManager::createLowRightLeafButton(const QString &label, int xOffset, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/)
719{
720 TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, 0, TextButton::PANEL);
721 item->setRecursiveVisible(false);
722 item->setZValue(10);
723
724 qreal sw = this->window->scene->sceneRect().width();
725 qreal sh = this->window->scene->sceneRect().height();
726
727 // create in-animation:
728 DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
729 anim->setDuration(1050 * Colors::animSpeedButtons);
730 anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
731 anim->setPosAt(0.10, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35));
732 anim->setPosAt(0.30, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
733 anim->setPosAt(0.35, QPointF(xOffset + 30, Colors::contentStartY + Colors::contentHeight - 35));
734 anim->setPosAt(0.40, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
735 anim->setPosAt(0.45, QPointF(xOffset + 5, Colors::contentStartY + Colors::contentHeight - 35));
736 anim->setPosAt(0.50, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35));
737 anim->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
738 movieIn->append(anim);
739
740 // create out-animation:
741 anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
742 anim->hideOnFinished = true;
743 anim->setDuration(300 * Colors::animSpeedButtons);
744 anim->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26));
745 anim->setPosAt(1.0, QPointF(xOffset, sh));
746 movieOut->append(anim);
747}
748
749void MenuManager::createInfo(DemoItem *item, const QString &name)
750{
751 Movie *movie_in = this->score->insertMovie(name);
752 Movie *movie_out = this->score->insertMovie(name + " -out");
753 item->setZValue(8);
754 item->setRecursiveVisible(false);
755
756 float xOffset = 230.0f;
757 DemoItemAnimation *infoIn = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN);
758 infoIn->timeline->setCurveShape(QTimeLine::LinearCurve);
759 infoIn->setDuration(650);
760 infoIn->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY));
761 infoIn->setPosAt(0.60, QPointF(xOffset, Colors::contentStartY));
762 infoIn->setPosAt(0.70, QPointF(xOffset + 20, Colors::contentStartY));
763 infoIn->setPosAt(0.80, QPointF(xOffset, Colors::contentStartY));
764 infoIn->setPosAt(0.90, QPointF(xOffset + 7, Colors::contentStartY));
765 infoIn->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY));
766 movie_in->append(infoIn);
767
768 DemoItemAnimation *infoOut = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT);
769 infoOut->timeline->setCurveShape(QTimeLine::EaseInCurve);
770 infoOut->setDuration(300);
771 infoOut->hideOnFinished = true;
772 infoOut->setStartPos(QPointF(xOffset, Colors::contentStartY));
773 infoOut->setPosAt(1.0, QPointF(-600, Colors::contentStartY));
774 movie_out->append(infoOut);
775}
776
777void MenuManager::createTicker()
778{
779 if (!Colors::noTicker){
780 Movie *movie_in = this->score->insertMovie("ticker");
781 Movie *movie_out = this->score->insertMovie("ticker -out");
782 Movie *movie_activate = this->score->insertMovie("ticker -activate");
783 Movie *movie_deactivate = this->score->insertMovie("ticker -deactivate");
784
785 this->ticker = new ItemCircleAnimation(this->window->scene, 0);
786 this->ticker->setZValue(50);
787 this->ticker->hide();
788
789 // Move ticker in:
790 int qtendpos = 485;
791 int qtPosY = 120;
792 this->tickerInAnim = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_IN);
793 this->tickerInAnim->setDuration(500);
794 this->tickerInAnim->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY));
795 this->tickerInAnim->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY));
796 this->tickerInAnim->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY));
797 this->tickerInAnim->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY));
798 this->tickerInAnim->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY));
799 this->tickerInAnim->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY));
800 movie_in->append(this->tickerInAnim);
801
802 // Move ticker out:
803 DemoItemAnimation *qtOut = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_OUT);
804 qtOut->hideOnFinished = true;
805 qtOut->setDuration(500);
806 qtOut->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY));
807 qtOut->setPosAt(1.00, QPointF(this->window->scene->sceneRect().width() + 700, Colors::contentStartY + qtPosY));
808 movie_out->append(qtOut);
809
810 // Move ticker in on activate:
811 DemoItemAnimation *qtActivate = new DemoItemAnimation(this->ticker);
812 qtActivate->setDuration(400);
813 qtActivate->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY));
814 qtActivate->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY));
815 qtActivate->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY));
816 qtActivate->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY));
817 qtActivate->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY));
818 qtActivate->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY));
819 movie_activate->append(qtActivate);
820
821 // Move ticker out on deactivate:
822 DemoItemAnimation *qtDeactivate = new DemoItemAnimation(this->ticker);
823 qtDeactivate->hideOnFinished = true;
824 qtDeactivate->setDuration(400);
825 qtDeactivate->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY));
826 qtDeactivate->setPosAt(1.00, QPointF(qtendpos, 800));
827 movie_deactivate->append(qtDeactivate);
828 }
829}
830
831void MenuManager::createUpnDownButtons()
832{
833 float xOffset = 15.0f;
834 float yOffset = 450.0f;
835
836 this->upButton = new TextButton("", TextButton::LEFT, MenuManager::UP, this->window->scene, 0, TextButton::UP);
837 this->upButton->prepare();
838 this->upButton->setPos(xOffset, yOffset);
839 this->upButton->setState(TextButton::DISABLED);
840
841 this->downButton = new TextButton("", TextButton::LEFT, MenuManager::DOWN, this->window->scene, 0, TextButton::DOWN);
842 this->downButton->prepare();
843 this->downButton->setPos(xOffset + 10 + this->downButton->sceneBoundingRect().width(), yOffset);
844
845 Movie *movieShake = this->score->insertMovie("upndown -shake");
846
847 DemoItemAnimation *shakeAnim = new DemoItemAnimation(this->upButton, DemoItemAnimation::ANIM_UNSPECIFIED);
848 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
849 shakeAnim->setDuration(650);
850 shakeAnim->setStartPos(this->upButton->pos());
851 shakeAnim->setPosAt(0.60, this->upButton->pos());
852 shakeAnim->setPosAt(0.70, this->upButton->pos() + QPointF(-2, 0));
853 shakeAnim->setPosAt(0.80, this->upButton->pos() + QPointF(1, 0));
854 shakeAnim->setPosAt(0.90, this->upButton->pos() + QPointF(-1, 0));
855 shakeAnim->setPosAt(1.00, this->upButton->pos());
856 movieShake->append(shakeAnim);
857
858 shakeAnim = new DemoItemAnimation(this->downButton, DemoItemAnimation::ANIM_UNSPECIFIED);
859 shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve);
860 shakeAnim->setDuration(650);
861 shakeAnim->setStartPos(this->downButton->pos());
862 shakeAnim->setPosAt(0.60, this->downButton->pos());
863 shakeAnim->setPosAt(0.70, this->downButton->pos() + QPointF(-5, 0));
864 shakeAnim->setPosAt(0.80, this->downButton->pos() + QPointF(-3, 0));
865 shakeAnim->setPosAt(0.90, this->downButton->pos() + QPointF(-1, 0));
866 shakeAnim->setPosAt(1.00, this->downButton->pos());
867 movieShake->append(shakeAnim);
868}
869
870void MenuManager::createBackButton()
871{
872 Movie *backIn = this->score->insertMovie("back -in");
873 Movie *backOut = this->score->insertMovie("back -out");
874 Movie *backShake = this->score->insertMovie("back -shake");
875 createLowLeftButton(QLatin1String("Back"), ROOT, backIn, backOut, backShake, Colors::rootMenuName);
876}
Note: See TracBrowser for help on using the repository browser.