diff options
Diffstat (limited to 'demos/qtdemo/menumanager.cpp')
-rw-r--r-- | demos/qtdemo/menumanager.cpp | 876 |
1 files changed, 876 insertions, 0 deletions
diff --git a/demos/qtdemo/menumanager.cpp b/demos/qtdemo/menumanager.cpp new file mode 100644 index 0000000..bfa2e3f --- /dev/null +++ b/demos/qtdemo/menumanager.cpp @@ -0,0 +1,876 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $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 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); + // 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); + this->window->switchTimerOnOff(true); + } + 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"); + // 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); + // 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); + this->window->switchTimerOnOff(false); + } + 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); + // 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); + this->window->switchTimerOnOff(true); + } + } 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('\0') << 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 + QString curpath = QString::fromLocal8Bit(qgetenv("PATH").constData()); + QString newpath = QString("PATH=%1;%2").arg(QLibraryInfo::location(QLibraryInfo::BinariesPath), curpath); + process->setEnvironment(QStringList(newpath)); +#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::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(); + } +} + +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 twize 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"); +} + +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); + + 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 + ".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"]; + + 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, 0), 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, 0), name + " -info"); +} + +void MenuManager::createLeafMenu(const QDomElement &el) +{ + QString name = el.attribute("name"); + createInfo(new ExampleContent(name, this->window->scene, 0), 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); +} + +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, 0); + 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, 0, 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, 0, 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, 0, 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, 0, 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, 0, 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); +} |