/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "menumanager.h" #include "colors.h" #include "menucontent.h" #include "examplecontent.h" MenuManager *MenuManager::pInstance = 0; MenuManager * MenuManager::instance() { if (!MenuManager::pInstance) MenuManager::pInstance = new MenuManager(); return MenuManager::pInstance; } MenuManager::MenuManager() { this->ticker = 0; this->tickerInAnim = 0; this->upButton = 0; this->downButton = 0; this->helpEngine = 0; this->score = new Score(); this->currentMenu = QLatin1String("[no menu visible]"); this->currentCategory = QLatin1String("[no category visible]"); this->currentMenuButtons = QLatin1String("[no menu buttons visible]"); this->currentInfo = QLatin1String("[no info visible]"); this->currentMenuCode = -1; this->readXmlDocument(); this->initHelpEngine(); } MenuManager::~MenuManager() { delete this->score; delete this->contentsDoc; delete this->helpEngine; } QByteArray MenuManager::getResource(const QString &name) { QByteArray ba = this->helpEngine->fileData(name); if (Colors::verbose && ba.isEmpty()) qDebug() << " - WARNING: Could not get " << name; return ba; } void MenuManager::readXmlDocument() { this->contentsDoc = new QDomDocument(); QString errorStr; int errorLine; int errorColumn; QFile file(":/xml/examples.xml"); bool statusOK = this->contentsDoc->setContent(&file, true, &errorStr, &errorLine, &errorColumn); if (!statusOK){ QMessageBox::critical(0, QObject::tr("DOM Parser"), QObject::tr("Could not read or find the contents document. Error at line %1, column %2:\n%3") .arg(errorLine).arg(errorColumn).arg(errorStr) ); exit(-1); } } void MenuManager::initHelpEngine() { this->helpRootUrl = QString("qthelp://com.trolltech.qt.%1%2%3/qdoc/") .arg(QT_VERSION >> 16).arg((QT_VERSION >> 8) & 0xFF) .arg(QT_VERSION & 0xFF); // Store help collection file in cache dir of assistant QString cacheDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/Trolltech/Assistant/"); QString helpDataFile = QString(QLatin1String("qtdemo_%1.qhc")).arg(QLatin1String(QT_VERSION_STR)); QDir dir; if (!dir.exists(cacheDir)) dir.mkpath(cacheDir); // Create help engine (and new // helpDataFile if it does not exist): this->helpEngine = new QHelpEngineCore(cacheDir + helpDataFile); this->helpEngine->setupData(); QString qtDocRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath) + QLatin1String("/qch"); qtDocRoot = QDir(qtDocRoot).absolutePath(); QStringList qchFiles; qchFiles << QLatin1String("/qt.qch") << QLatin1String("/designer.qch") << QLatin1String("/linguist.qch"); QString oldDir = helpEngine->customValue(QLatin1String("docDir"), QString()).toString(); if (oldDir != qtDocRoot) { foreach (const QString &qchFile, qchFiles) helpEngine->unregisterDocumentation(QHelpEngineCore::namespaceName(qtDocRoot + qchFile)); } // If the data that the engine will work // on is not yet registered, do it now: foreach (const QString &qchFile, qchFiles) helpEngine->registerDocumentation(qtDocRoot + qchFile); helpEngine->setCustomValue(QLatin1String("docDir"), qtDocRoot); } void MenuManager::itemSelected(int userCode, const QString &menuName) { switch (userCode){ case LAUNCH: this->launchExample(this->currentInfo); break; case LAUNCH_QML: this->launchQmlExample(this->currentInfo); break; case DOCUMENTATION: this->showDocInAssistant(this->currentInfo); break; case QUIT: this->window->loop = false; QCoreApplication::quit(); break; case FULLSCREEN: this->window->toggleFullscreen(); break; case ROOT: // out: this->score->queueMovie(this->currentMenu + " -out", Score::FROM_START, Score::LOCK_ITEMS); this->score->queueMovie(this->currentMenuButtons + " -out", Score::FROM_START, Score::LOCK_ITEMS); this->score->queueMovie(this->currentInfo + " -out"); this->score->queueMovie(this->currentInfo + " -buttons -out", Score::NEW_ANIMATION_ONLY); this->score->queueMovie("back -out", Score::ONLY_IF_VISIBLE); if(qmlRoot) qmlRoot->setProperty("show", QVariant(false)); // book-keeping: this->currentMenuCode = ROOT; this->currentMenu = menuName + " -menu1"; this->currentMenuButtons = menuName + " -buttons"; this->currentInfo = menuName + " -info"; // in: this->score->queueMovie("upndown -shake"); this->score->queueMovie(this->currentMenu, Score::FROM_START, Score::UNLOCK_ITEMS); this->score->queueMovie(this->currentMenuButtons, Score::FROM_START, Score::UNLOCK_ITEMS); this->score->queueMovie(this->currentInfo); if (!Colors::noTicker){ this->ticker->doIntroTransitions = true; this->tickerInAnim->startDelay = 2000; this->ticker->useGuideQt(); this->score->queueMovie("ticker", Score::NEW_ANIMATION_ONLY); } break; case MENU1: // out: this->score->queueMovie(this->currentMenu + " -out", Score::FROM_START, Score::LOCK_ITEMS); this->score->queueMovie(this->currentMenuButtons + " -out", Score::FROM_START, Score::LOCK_ITEMS); this->score->queueMovie(this->currentInfo + " -out"); if(qmlRoot) qmlRoot->setProperty("show", QVariant(false)); // book-keeping: this->currentMenuCode = MENU1; this->currentCategory = menuName; this->currentMenu = menuName + " -menu1"; this->currentInfo = menuName + " -info"; // in: this->score->queueMovie("upndown -shake"); this->score->queueMovie("back -in"); this->score->queueMovie(this->currentMenu, Score::FROM_START, Score::UNLOCK_ITEMS); this->score->queueMovie(this->currentInfo); if (!Colors::noTicker) this->ticker->useGuideTt(); break; case MENU2: // out: this->score->queueMovie(this->currentInfo + " -out", Score::NEW_ANIMATION_ONLY); this->score->queueMovie(this->currentInfo + " -buttons -out", Score::NEW_ANIMATION_ONLY); if(qmlRoot) qmlRoot->setProperty("show", QVariant(false)); // book-keeping: this->currentMenuCode = MENU2; this->currentInfo = menuName; // in / shake: this->score->queueMovie("upndown -shake"); this->score->queueMovie("back -shake"); this->score->queueMovie(this->currentMenu + " -shake"); this->score->queueMovie(this->currentInfo, Score::NEW_ANIMATION_ONLY); this->score->queueMovie(this->currentInfo + " -buttons", Score::NEW_ANIMATION_ONLY); if (!Colors::noTicker){ this->score->queueMovie("ticker -out", Score::NEW_ANIMATION_ONLY); } break; case UP:{ QString backMenu = this->info[this->currentMenu]["back"]; if (!backMenu.isNull()){ this->score->queueMovie(this->currentMenu + " -top_out", Score::FROM_START, Score::LOCK_ITEMS); this->score->queueMovie(backMenu + " -bottom_in", Score::FROM_START, Score::UNLOCK_ITEMS); this->currentMenu = backMenu; } break; } case DOWN:{ QString moreMenu = this->info[this->currentMenu]["more"]; if (!moreMenu.isNull()){ this->score->queueMovie(this->currentMenu + " -bottom_out", Score::FROM_START, Score::LOCK_ITEMS); this->score->queueMovie(moreMenu + " -top_in", Score::FROM_START, Score::UNLOCK_ITEMS); this->currentMenu = moreMenu; } break; } case BACK:{ if (this->currentMenuCode == MENU2){ // out: this->score->queueMovie(this->currentInfo + " -out", Score::NEW_ANIMATION_ONLY); this->score->queueMovie(this->currentInfo + " -buttons -out", Score::NEW_ANIMATION_ONLY); if(qmlRoot) qmlRoot->setProperty("show", QVariant(false)); // book-keeping: this->currentMenuCode = MENU1; this->currentMenuButtons = this->currentCategory + " -buttons"; this->currentInfo = this->currentCategory + " -info"; // in / shake: this->score->queueMovie("upndown -shake"); this->score->queueMovie(this->currentMenu + " -shake"); this->score->queueMovie(this->currentInfo, Score::NEW_ANIMATION_ONLY); this->score->queueMovie(this->currentInfo + " -buttons", Score::NEW_ANIMATION_ONLY); if (!Colors::noTicker){ this->ticker->doIntroTransitions = false; this->tickerInAnim->startDelay = 500; this->score->queueMovie("ticker", Score::NEW_ANIMATION_ONLY); } } else if (this->currentMenuCode != ROOT) itemSelected(ROOT, Colors::rootMenuName); break; } } // update back- and more buttons bool noBackMenu = this->info[this->currentMenu]["back"].isNull(); bool noMoreMenu = this->info[this->currentMenu]["more"].isNull(); this->upButton->setState(noBackMenu ? TextButton::DISABLED : TextButton::OFF); this->downButton->setState(noMoreMenu ? TextButton::DISABLED : TextButton::OFF); if (this->score->hasQueuedMovies()){ this->score->playQue(); // Playing new movies might include // loading etc. So ignore the FPS // at this point this->window->fpsHistory.clear(); } } void MenuManager::showDocInAssistant(const QString &name) { QString url = this->resolveDocUrl(name); if (Colors::verbose) qDebug() << "Sending URL to Assistant:" << url; // Start assistant if it's not already running: if (this->assistantProcess.state() != QProcess::Running){ QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator(); #if !defined(Q_OS_MAC) app += QLatin1String("assistant"); #else app += QLatin1String("Assistant.app/Contents/MacOS/Assistant"); #endif QStringList args; args << QLatin1String("-enableRemoteControl"); this->assistantProcess.start(app, args); if (!this->assistantProcess.waitForStarted()) { QMessageBox::critical(0, tr("Qt Demo"), tr("Could not start Qt Assistant.").arg(app)); return; } } // Send command through remote control even if the process // was started to activate assistant and bring it to front: QTextStream str(&this->assistantProcess); str << "SetSource " << url << QLatin1Char('\n') << endl; } void MenuManager::launchExample(const QString &name) { QString executable = this->resolveExeFile(name); #ifdef Q_OS_MAC if (Colors::verbose) qDebug() << "Launching:" << executable; bool success = QDesktopServices::openUrl(QUrl::fromLocalFile(executable)); if (!success){ QMessageBox::critical(0, tr("Failed to launch the example"), tr("Could not launch the example. Ensure that it has been built."), QMessageBox::Cancel); } #else // Not mac. To not break anything regarding dll's etc, keep it the way it was before: QProcess *process = new QProcess(this); connect(process, SIGNAL(finished(int)), this, SLOT(exampleFinished())); connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(exampleError(QProcess::ProcessError))); #ifdef Q_OS_WIN //make sure it finds the dlls on windows QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert(QLatin1String("PATH"), QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1Char(';') + env.value(QLatin1String("Path"))); process->setProcessEnvironment(env); #endif if (info[name]["changedirectory"] != "false"){ QString workingDirectory = resolveDataDir(name); process->setWorkingDirectory(workingDirectory); if (Colors::verbose) qDebug() << "Setting working directory:" << workingDirectory; } if (Colors::verbose) qDebug() << "Launching:" << executable; process->start(executable); #endif } void MenuManager::launchQmlExample(const QString &name) { #ifndef QT_NO_DECLARATIVE if(!qmlRoot){ exampleError(QProcess::UnknownError); return; } //resolveQmlFilename - refactor to separate fn? QString dirName = this->info[name]["dirname"]; QString category = this->info[name]["category"]; QString fileName = this->info[name]["filename"]; QDir dir; if (category == "demos") dir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath)); else dir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath)); QFile file(dir.path() + "/" + dirName + "/" + fileName + "/" + "main.qml"); if(!file.exists()){ //try dirname.qml as well file.setFileName(dir.path() + "/" + dirName + "/" + fileName + "/" + fileName.split('/').last() + ".qml"); if(!file.exists()){ exampleError(QProcess::UnknownError); return; } } qmlRoot->setProperty("qmlFile", QVariant(""));//unload component qmlRoot->setProperty("show", QVariant(true)); qmlRoot->setProperty("qmlFile", QUrl::fromLocalFile(file.fileName())); #else exampleError(QProcess::UnknownError); #endif } void MenuManager::quitQML() { if(qmlRoot) qmlRoot->setProperty("show", QVariant(false)); } void MenuManager::exampleFinished() { } void MenuManager::exampleError(QProcess::ProcessError error) { if (error != QProcess::Crashed) QMessageBox::critical(0, tr("Failed to launch the example"), tr("Could not launch the example. Ensure that it has been built."), QMessageBox::Cancel); } void MenuManager::init(MainWindow *window) { this->window = window; // Create div: this->createTicker(); this->createUpnDownButtons(); this->createBackButton(); // Create first level menu: QDomElement rootElement = this->contentsDoc->documentElement(); this->createRootMenu(rootElement); // Create second level menus: QDomNode level2MenuNode = rootElement.firstChild(); while (!level2MenuNode.isNull()){ QDomElement level2MenuElement = level2MenuNode.toElement(); this->createSubMenu(level2MenuElement); // create leaf menu and example info: QDomNode exampleNode = level2MenuElement.firstChild(); while (!exampleNode.isNull()){ QDomElement exampleElement = exampleNode.toElement(); this->readInfoAboutExample(exampleElement); this->createLeafMenu(exampleElement); exampleNode = exampleNode.nextSibling(); } level2MenuNode = level2MenuNode.nextSibling(); } qmlRoot = 0; #ifndef QT_NO_DECLARATIVE // Create QML Loader declarativeEngine = new QDeclarativeEngine(this); connect(declarativeEngine, SIGNAL(quit()), this, SLOT(quitQML())); QDeclarativeComponent component(declarativeEngine, QUrl("qrc:qml/qmlShell.qml"), this); QDeclarativeItem* qmlRootItem = 0; if(component.isReady()){ qmlRoot = component.create(); qmlRootItem = qobject_cast(qmlRoot); }else{ qDebug() << component.status() << component.errorString(); } if(qmlRootItem){ qmlRootItem->setHeight(this->window->scene->sceneRect().height()); qmlRootItem->setWidth(this->window->scene->sceneRect().width()); qmlRootItem->setZValue(101);//Above other items qmlRootItem->setCursor(Qt::ArrowCursor); window->scene->addItem(qmlRootItem); //Note that QML adds key handling to the app. window->viewport()->setFocusPolicy(Qt::NoFocus);//Correct keyboard focus handling window->setFocusPolicy(Qt::StrongFocus); window->scene->setStickyFocus(true); window->setFocus(); }else{ qDebug() << "Error initializing QML subsystem, Declarative examples will not work"; } #endif } void MenuManager::readInfoAboutExample(const QDomElement &example) { QString name = example.attribute("name"); if (this->info.contains(name)) qWarning() << "__WARNING: MenuManager::readInfoAboutExample: Demo/example with name" << name << "appears twice in the xml-file!__"; this->info[name]["filename"] = example.attribute("filename"); this->info[name]["category"] = example.parentNode().toElement().tagName(); this->info[name]["dirname"] = example.parentNode().toElement().attribute("dirname"); this->info[name]["changedirectory"] = example.attribute("changedirectory"); this->info[name]["image"] = example.attribute("image"); this->info[name]["qml"] = example.attribute("qml"); } QString MenuManager::resolveDataDir(const QString &name) { QString dirName = this->info[name]["dirname"]; QString category = this->info[name]["category"]; QString fileName = this->info[name]["filename"]; QDir dir; if (category == "demos") dir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath)); else dir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath)); dir.cd(dirName); dir.cd(fileName); return dir.absolutePath(); } QString MenuManager::resolveExeFile(const QString &name) { QString dirName = this->info[name]["dirname"]; QString category = this->info[name]["category"]; QString fileName = this->info[name]["filename"]; QDir dir; if (category == "demos") dir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath)); else dir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath)); dir.cd(dirName); dir.cd(fileName); fileName = fileName.split("/").last(); QFile unixFile(dir.path() + "/" + fileName); if (unixFile.exists()) return unixFile.fileName(); QFile winR(dir.path() + "\\release\\" + fileName + ".exe"); if (winR.exists()) return winR.fileName(); QFile winD(dir.path() + "\\debug\\" + fileName + ".exe"); if (winD.exists()) return winD.fileName(); QFile mac(dir.path() + "/" + fileName + ".app"); if (mac.exists()) return mac.fileName(); if (Colors::verbose) qDebug() << "- WARNING: Could not resolve executable:" << dir.path() << fileName; return "__executable not found__"; } QString MenuManager::resolveDocUrl(const QString &name) { QString dirName = this->info[name]["dirname"]; QString category = this->info[name]["category"]; QString fileName = this->info[name]["filename"]; if (category == "demos") return this->helpRootUrl + "demos-" + fileName.replace("/", "-") + ".html"; else return this->helpRootUrl + dirName.replace("/", "-") + "-" + fileName + ".html"; } QString MenuManager::resolveImageUrl(const QString &name) { return this->helpRootUrl + "images/" + name; } QByteArray MenuManager::getHtml(const QString &name) { return getResource(this->resolveDocUrl(name)); } QByteArray MenuManager::getImage(const QString &name) { QString imageName = this->info[name]["image"]; QString category = this->info[name]["category"]; QString fileName = this->info[name]["filename"]; bool qml = (this->info[name]["qml"] == QLatin1String("true")); if(qml) fileName = QLatin1String("qml-") + fileName.split('/').last(); if (imageName.isEmpty()){ if (category == "demos") imageName = fileName + "-demo.png"; else imageName = fileName + "-example.png"; if ((getResource(resolveImageUrl(imageName))).isEmpty()) imageName = fileName + ".png"; if ((getResource(resolveImageUrl(imageName))).isEmpty()) imageName = fileName + "example.png"; } return getResource(resolveImageUrl(imageName)); } void MenuManager::createRootMenu(const QDomElement &el) { QString name = el.attribute("name"); createMenu(el, MENU1); createInfo(new MenuContentItem(el, this->window->scene, this->window->mainSceneRoot), name + " -info"); Movie *menuButtonsIn = this->score->insertMovie(name + " -buttons"); Movie *menuButtonsOut = this->score->insertMovie(name + " -buttons -out"); createLowLeftButton(QLatin1String("Quit"), QUIT, menuButtonsIn, menuButtonsOut, 0); createLowRightButton("Toggle fullscreen", FULLSCREEN, menuButtonsIn, menuButtonsOut, 0); } void MenuManager::createSubMenu(const QDomElement &el) { QString name = el.attribute("name"); createMenu(el, MENU2); createInfo(new MenuContentItem(el, this->window->scene, this->window->mainSceneRoot), name + " -info"); } void MenuManager::createLeafMenu(const QDomElement &el) { QString name = el.attribute("name"); createInfo(new ExampleContent(name, this->window->scene, this->window->mainSceneRoot), name); Movie *infoButtonsIn = this->score->insertMovie(name + " -buttons"); Movie *infoButtonsOut = this->score->insertMovie(name + " -buttons -out"); createLowRightLeafButton("Documentation", 600, DOCUMENTATION, infoButtonsIn, infoButtonsOut, 0); if (el.attribute("executable") != "false") createLowRightLeafButton("Launch", 405, LAUNCH, infoButtonsIn, infoButtonsOut, 0); else if(el.attribute("qml") == "true") createLowRightLeafButton("Display", 405, LAUNCH_QML, infoButtonsIn, infoButtonsOut, 0); } void MenuManager::createMenu(const QDomElement &category, BUTTON_TYPE type) { qreal sw = this->window->scene->sceneRect().width(); int xOffset = 15; int yOffset = 10; int maxExamples = Colors::menuCount; int menuIndex = 1; QString name = category.attribute("name"); QDomNode currentNode = category.firstChild(); QString currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex); while (!currentNode.isNull()){ Movie *movieIn = this->score->insertMovie(currentMenu); Movie *movieOut = this->score->insertMovie(currentMenu + " -out"); Movie *movieNextTopOut = this->score->insertMovie(currentMenu + " -top_out"); Movie *movieNextBottomOut = this->score->insertMovie(currentMenu + " -bottom_out"); Movie *movieNextTopIn = this->score->insertMovie(currentMenu + " -top_in"); Movie *movieNextBottomIn = this->score->insertMovie(currentMenu + " -bottom_in"); Movie *movieShake = this->score->insertMovie(currentMenu + " -shake"); int i = 0; while (!currentNode.isNull() && i < maxExamples){ TextButton *item; // create normal menu button QString label = currentNode.toElement().attribute("name"); item = new TextButton(label, TextButton::LEFT, type, this->window->scene, this->window->mainSceneRoot); currentNode = currentNode.nextSibling(); #ifndef QT_OPENGL_SUPPORT if (currentNode.toElement().attribute("dirname") == "opengl") currentNode = currentNode.nextSibling(); #endif item->setRecursiveVisible(false); item->setZValue(10); qreal ih = item->sceneBoundingRect().height(); qreal iw = item->sceneBoundingRect().width(); qreal ihp = ih + 3; // create in-animation: DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN); anim->setDuration(float(1000 + (i * 20)) * Colors::animSpeedButtons); anim->setStartPos(QPointF(xOffset, -ih)); anim->setPosAt(0.20, QPointF(xOffset, -ih)); anim->setPosAt(0.50, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (10 * float(i / 4.0f)))); anim->setPosAt(0.60, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(0.70, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (5 * float(i / 4.0f)))); anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(0.90, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY + (2 * float(i / 4.0f)))); anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); movieIn->append(anim); // create out-animation: anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT); anim->hideOnFinished = true; anim->setDuration((700 + (30 * i)) * Colors::animSpeedButtons); anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(0.60, QPointF(xOffset, 600 - ih - ih)); anim->setPosAt(0.65, QPointF(xOffset + 20, 600 - ih)); anim->setPosAt(1.00, QPointF(sw + iw, 600 - ih)); movieOut->append(anim); // create shake-animation: anim = new DemoItemAnimation(item); anim->setDuration(700 * Colors::animSpeedButtons); anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(0.55, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*2.0)); anim->setPosAt(0.70, QPointF(xOffset - 10, (i * ihp) + yOffset + Colors::contentStartY - i*1.5)); anim->setPosAt(0.80, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY - i*1.0)); anim->setPosAt(0.90, QPointF(xOffset - 2, (i * ihp) + yOffset + Colors::contentStartY - i*0.5)); anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); movieShake->append(anim); // create next-menu top-out-animation: anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT); anim->hideOnFinished = true; anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons); anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(0.70, QPointF(xOffset, yOffset + Colors::contentStartY)); anim->setPosAt(1.00, QPointF(-iw, yOffset + Colors::contentStartY)); movieNextTopOut->append(anim); // create next-menu bottom-out-animation: anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT); anim->hideOnFinished = true; anim->setDuration((200 + (30 * i)) * Colors::animSpeedButtons); anim->setStartPos(QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(0.70, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(1.00, QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY)); movieNextBottomOut->append(anim); // create next-menu top-in-animation: anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN); anim->setDuration((700 - (30 * i)) * Colors::animSpeedButtons); anim->setStartPos(QPointF(-iw, yOffset + Colors::contentStartY)); anim->setPosAt(0.30, QPointF(xOffset, yOffset + Colors::contentStartY)); anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); movieNextTopIn->append(anim); // create next-menu bottom-in-animation: int reverse = maxExamples - i; anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN); anim->setDuration((1000 - (30 * reverse)) * Colors::animSpeedButtons); anim->setStartPos(QPointF(-iw, (maxExamples * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(0.30, QPointF(xOffset, (maxExamples * ihp) + yOffset + Colors::contentStartY)); anim->setPosAt(1.00, QPointF(xOffset, (i * ihp) + yOffset + Colors::contentStartY)); movieNextBottomIn->append(anim); i++; } if (!currentNode.isNull() && i == maxExamples){ // We need another menu, so register for 'more' and 'back' buttons ++menuIndex; this->info[currentMenu]["more"] = name + QLatin1String(" -menu") + QString::number(menuIndex); currentMenu = name + QLatin1String(" -menu") + QString::number(menuIndex); this->info[currentMenu]["back"] = name + QLatin1String(" -menu") + QString::number(menuIndex - 1); } } } void MenuManager::createLowLeftButton(const QString &label, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie *movieShake, const QString &menuString) { TextButton *button = new TextButton(label, TextButton::RIGHT, type, this->window->scene, this->window->mainSceneRoot, TextButton::PANEL); if (!menuString.isNull()) button->setMenuString(menuString); button->setRecursiveVisible(false); button->setZValue(10); qreal iw = button->sceneBoundingRect().width(); int xOffset = 15; // create in-animation: DemoItemAnimation *buttonIn = new DemoItemAnimation(button, DemoItemAnimation::ANIM_IN); buttonIn->setDuration(1800 * Colors::animSpeedButtons); buttonIn->setStartPos(QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35)); buttonIn->setPosAt(0.5, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 35)); buttonIn->setPosAt(0.7, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35)); buttonIn->setPosAt(1.0, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26)); movieIn->append(buttonIn); // create out-animation: DemoItemAnimation *buttonOut = new DemoItemAnimation(button, DemoItemAnimation::ANIM_OUT); buttonOut->hideOnFinished = true; buttonOut->setDuration(400 * Colors::animSpeedButtons); buttonOut->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26)); buttonOut->setPosAt(1.0, QPointF(-iw, Colors::contentStartY + Colors::contentHeight - 26)); movieOut->append(buttonOut); if (movieShake){ DemoItemAnimation *shakeAnim = new DemoItemAnimation(button, DemoItemAnimation::ANIM_UNSPECIFIED); shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve); shakeAnim->setDuration(650); shakeAnim->setStartPos(buttonIn->posAt(1.0f)); shakeAnim->setPosAt(0.60, buttonIn->posAt(1.0f)); shakeAnim->setPosAt(0.70, buttonIn->posAt(1.0f) + QPointF(-3, 0)); shakeAnim->setPosAt(0.80, buttonIn->posAt(1.0f) + QPointF(2, 0)); shakeAnim->setPosAt(0.90, buttonIn->posAt(1.0f) + QPointF(-1, 0)); shakeAnim->setPosAt(1.00, buttonIn->posAt(1.0f)); movieShake->append(shakeAnim); } } void MenuManager::createLowRightButton(const QString &label, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/) { TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, this->window->mainSceneRoot, TextButton::PANEL); item->setRecursiveVisible(false); item->setZValue(10); qreal sw = this->window->scene->sceneRect().width(); int xOffset = 70; // create in-animation: DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN); anim->setDuration(1800 * Colors::animSpeedButtons); anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.5, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.7, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(1.0, QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26)); movieIn->append(anim); // create out-animation: anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT); anim->hideOnFinished = true; anim->setDuration(400 * Colors::animSpeedButtons); anim->setStartPos(QPointF(xOffset + 535, Colors::contentStartY + Colors::contentHeight - 26)); anim->setPosAt(1.0, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 26)); movieOut->append(anim); } void MenuManager::createLowRightLeafButton(const QString &label, int xOffset, BUTTON_TYPE type, Movie *movieIn, Movie *movieOut, Movie * /*movieShake*/) { TextButton *item = new TextButton(label, TextButton::RIGHT, type, this->window->scene, this->window->mainSceneRoot, TextButton::PANEL); item->setRecursiveVisible(false); item->setZValue(10); qreal sw = this->window->scene->sceneRect().width(); qreal sh = this->window->scene->sceneRect().height(); // create in-animation: DemoItemAnimation *anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN); anim->setDuration(1050 * Colors::animSpeedButtons); anim->setStartPos(QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.10, QPointF(sw, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.30, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.35, QPointF(xOffset + 30, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.40, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.45, QPointF(xOffset + 5, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(0.50, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 35)); anim->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26)); movieIn->append(anim); // create out-animation: anim = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT); anim->hideOnFinished = true; anim->setDuration(300 * Colors::animSpeedButtons); anim->setStartPos(QPointF(xOffset, Colors::contentStartY + Colors::contentHeight - 26)); anim->setPosAt(1.0, QPointF(xOffset, sh)); movieOut->append(anim); } void MenuManager::createInfo(DemoItem *item, const QString &name) { Movie *movie_in = this->score->insertMovie(name); Movie *movie_out = this->score->insertMovie(name + " -out"); item->setZValue(8); item->setRecursiveVisible(false); float xOffset = 230.0f; DemoItemAnimation *infoIn = new DemoItemAnimation(item, DemoItemAnimation::ANIM_IN); infoIn->timeline->setCurveShape(QTimeLine::LinearCurve); infoIn->setDuration(650); infoIn->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY)); infoIn->setPosAt(0.60, QPointF(xOffset, Colors::contentStartY)); infoIn->setPosAt(0.70, QPointF(xOffset + 20, Colors::contentStartY)); infoIn->setPosAt(0.80, QPointF(xOffset, Colors::contentStartY)); infoIn->setPosAt(0.90, QPointF(xOffset + 7, Colors::contentStartY)); infoIn->setPosAt(1.00, QPointF(xOffset, Colors::contentStartY)); movie_in->append(infoIn); DemoItemAnimation *infoOut = new DemoItemAnimation(item, DemoItemAnimation::ANIM_OUT); infoOut->timeline->setCurveShape(QTimeLine::EaseInCurve); infoOut->setDuration(300); infoOut->hideOnFinished = true; infoOut->setStartPos(QPointF(xOffset, Colors::contentStartY)); infoOut->setPosAt(1.0, QPointF(-600, Colors::contentStartY)); movie_out->append(infoOut); } void MenuManager::createTicker() { if (!Colors::noTicker){ Movie *movie_in = this->score->insertMovie("ticker"); Movie *movie_out = this->score->insertMovie("ticker -out"); Movie *movie_activate = this->score->insertMovie("ticker -activate"); Movie *movie_deactivate = this->score->insertMovie("ticker -deactivate"); this->ticker = new ItemCircleAnimation(this->window->scene, 0); this->ticker->setZValue(50); this->ticker->hide(); // Move ticker in: int qtendpos = 485; int qtPosY = 120; this->tickerInAnim = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_IN); this->tickerInAnim->setDuration(500); this->tickerInAnim->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY)); this->tickerInAnim->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY)); this->tickerInAnim->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY)); this->tickerInAnim->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY)); this->tickerInAnim->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY)); this->tickerInAnim->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY)); movie_in->append(this->tickerInAnim); // Move ticker out: DemoItemAnimation *qtOut = new DemoItemAnimation(this->ticker, DemoItemAnimation::ANIM_OUT); qtOut->hideOnFinished = true; qtOut->setDuration(500); qtOut->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY)); qtOut->setPosAt(1.00, QPointF(this->window->scene->sceneRect().width() + 700, Colors::contentStartY + qtPosY)); movie_out->append(qtOut); // Move ticker in on activate: DemoItemAnimation *qtActivate = new DemoItemAnimation(this->ticker); qtActivate->setDuration(400); qtActivate->setStartPos(QPointF(this->window->scene->sceneRect().width(), Colors::contentStartY + qtPosY)); qtActivate->setPosAt(0.60, QPointF(qtendpos, Colors::contentStartY + qtPosY)); qtActivate->setPosAt(0.70, QPointF(qtendpos + 30, Colors::contentStartY + qtPosY)); qtActivate->setPosAt(0.80, QPointF(qtendpos, Colors::contentStartY + qtPosY)); qtActivate->setPosAt(0.90, QPointF(qtendpos + 5, Colors::contentStartY + qtPosY)); qtActivate->setPosAt(1.00, QPointF(qtendpos, Colors::contentStartY + qtPosY)); movie_activate->append(qtActivate); // Move ticker out on deactivate: DemoItemAnimation *qtDeactivate = new DemoItemAnimation(this->ticker); qtDeactivate->hideOnFinished = true; qtDeactivate->setDuration(400); qtDeactivate->setStartPos(QPointF(qtendpos, Colors::contentStartY + qtPosY)); qtDeactivate->setPosAt(1.00, QPointF(qtendpos, 800)); movie_deactivate->append(qtDeactivate); } } void MenuManager::createUpnDownButtons() { float xOffset = 15.0f; float yOffset = 450.0f; this->upButton = new TextButton("", TextButton::LEFT, MenuManager::UP, this->window->scene, this->window->mainSceneRoot, TextButton::UP); this->upButton->prepare(); this->upButton->setPos(xOffset, yOffset); this->upButton->setState(TextButton::DISABLED); this->downButton = new TextButton("", TextButton::LEFT, MenuManager::DOWN, this->window->scene, this->window->mainSceneRoot, TextButton::DOWN); this->downButton->prepare(); this->downButton->setPos(xOffset + 10 + this->downButton->sceneBoundingRect().width(), yOffset); Movie *movieShake = this->score->insertMovie("upndown -shake"); DemoItemAnimation *shakeAnim = new DemoItemAnimation(this->upButton, DemoItemAnimation::ANIM_UNSPECIFIED); shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve); shakeAnim->setDuration(650); shakeAnim->setStartPos(this->upButton->pos()); shakeAnim->setPosAt(0.60, this->upButton->pos()); shakeAnim->setPosAt(0.70, this->upButton->pos() + QPointF(-2, 0)); shakeAnim->setPosAt(0.80, this->upButton->pos() + QPointF(1, 0)); shakeAnim->setPosAt(0.90, this->upButton->pos() + QPointF(-1, 0)); shakeAnim->setPosAt(1.00, this->upButton->pos()); movieShake->append(shakeAnim); shakeAnim = new DemoItemAnimation(this->downButton, DemoItemAnimation::ANIM_UNSPECIFIED); shakeAnim->timeline->setCurveShape(QTimeLine::LinearCurve); shakeAnim->setDuration(650); shakeAnim->setStartPos(this->downButton->pos()); shakeAnim->setPosAt(0.60, this->downButton->pos()); shakeAnim->setPosAt(0.70, this->downButton->pos() + QPointF(-5, 0)); shakeAnim->setPosAt(0.80, this->downButton->pos() + QPointF(-3, 0)); shakeAnim->setPosAt(0.90, this->downButton->pos() + QPointF(-1, 0)); shakeAnim->setPosAt(1.00, this->downButton->pos()); movieShake->append(shakeAnim); } void MenuManager::createBackButton() { Movie *backIn = this->score->insertMovie("back -in"); Movie *backOut = this->score->insertMovie("back -out"); Movie *backShake = this->score->insertMovie("back -shake"); createLowLeftButton(QLatin1String("Back"), ROOT, backIn, backOut, backShake, Colors::rootMenuName); }