Warning, file /games/kfourinline/src/displayintro.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     This file is part of the KDE games kwin4 program
0003     SPDX-FileCopyrightText: 2006 Martin Heni <kde@heni-online.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "displayintro.h"
0009 
0010 // own
0011 #include "buttonsprite.h"
0012 #include "introsprite.h"
0013 #include "kfontutils.h"
0014 #include "kfourinline_debug.h"
0015 #include "pixmapsprite.h"
0016 #include "prefs.h"
0017 // KF
0018 #include <KLocalizedString>
0019 // Qt
0020 #include <QColor>
0021 #include <QElapsedTimer>
0022 #include <QFont>
0023 #include <QGraphicsView>
0024 #include <QMouseEvent>
0025 #include <QPixmap>
0026 #include <QPoint>
0027 #include <QStringList>
0028 #include <QTextDocument>
0029 // Std
0030 #include <cmath>
0031 
0032 // Constructor for the intro display
0033 DisplayIntro::DisplayIntro(QGraphicsScene *scene, ThemeManager *theme, QGraphicsView *parent)
0034     : Themeable(QStringLiteral("introdisplay"), theme)
0035     , QObject(parent)
0036 {
0037     // Choose a background color
0038     scene->setBackgroundBrush(QColor(0, 0, 128));
0039 
0040     // Store the theme manager and other attributes
0041     mLastMoveEvent = nullptr;
0042     mTheme = theme;
0043     mScene = scene;
0044     mView = parent;
0045 
0046     // Storage of all sprites
0047     mSprites.clear();
0048 
0049     // Create all sprites used for intro
0050     for (int i = 0; i < 42; i++) {
0051         IntroSprite *sprite = new IntroSprite(QStringLiteral("intro_piece"), mTheme, i, mScene);
0052         mSprites.append(sprite);
0053         if ((i / 1) % 2 == 0)
0054             sprite->setFrame(0);
0055         else
0056             sprite->setFrame(1);
0057         sprite->setZValue(i);
0058         sprite->hide();
0059     }
0060 
0061     // Create board
0062     PixmapSprite *pixmap = new PixmapSprite(QStringLiteral("introboard"), mTheme, 0, mScene);
0063     mSprites.append(pixmap);
0064     pixmap->show();
0065 
0066     // Create quicklaunch. We align text horizontally using QTextDocument
0067     mQuickLaunch = new PixmapSprite(QStringLiteral("quicklaunch"), mTheme, 0, mScene);
0068     mSprites.append(mQuickLaunch);
0069     mQuickLaunch->show();
0070     mTextQuicklaunch = new QGraphicsTextItem(mQuickLaunch);
0071     mTextQuicklaunch->setPlainText(i18nc("Name of quicklaunch field", "Quick Launch"));
0072     QTextDocument *text_document = mTextQuicklaunch->document();
0073     text_document->setDefaultTextOption(QTextOption(Qt::AlignHCenter));
0074     mTextQuicklaunch->setDocument(text_document);
0075     mTextQuicklaunch->show();
0076     mTextStartplayer = new QGraphicsTextItem(mQuickLaunch);
0077     mTextStartplayer->setPlainText(i18nc("Ask player who should start game", "Who starts?"));
0078     mTextStartplayer->show();
0079     mTextColor = new QGraphicsTextItem(mQuickLaunch);
0080     mTextColor->setPlainText(i18nc("Ask player which color he wants to play", "Your color?"));
0081     mTextColor->show();
0082 
0083     // Static decoration
0084     KConfigGroup config = thememanager()->config(id());
0085     QStringList deco = config.readEntry("decoration", QStringList());
0086     for (int i = 0; i < deco.size(); i++) {
0087         PixmapSprite *sprite = new PixmapSprite(deco.at(i), mTheme, i, mScene);
0088         mSprites.append(sprite);
0089         sprite->show();
0090     }
0091 
0092     // Color buttons
0093     mStartButton[0] = new ButtonSprite(false, QStringLiteral("button0_start"), mTheme, 0, mScene);
0094     mSprites.append(mStartButton[0]);
0095     mStartButton[0]->show();
0096     connect(mStartButton[0]->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0097     if (Prefs::startcolouryellow())
0098         mStartButton[0]->setStatus(true);
0099 
0100     mStartButton[1] = new ButtonSprite(false, QStringLiteral("button1_start"), mTheme, 1, mScene);
0101     mSprites.append(mStartButton[1]);
0102     mStartButton[1]->show();
0103     connect(mStartButton[1]->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0104     if (Prefs::startcolourred())
0105         mStartButton[1]->setStatus(true);
0106 
0107     mPlayerButton[0] = new ButtonSprite(false, QStringLiteral("button0_color"), mTheme, 2, mScene);
0108     mSprites.append(mPlayerButton[0]);
0109     mPlayerButton[0]->show();
0110     connect(mPlayerButton[0]->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0111     if (Prefs::input0mouse() || Prefs::input0key())
0112         mPlayerButton[0]->setStatus(true);
0113 
0114     mPlayerButton[1] = new ButtonSprite(false, QStringLiteral("button1_color"), mTheme, 3, mScene);
0115     mSprites.append(mPlayerButton[1]);
0116     mPlayerButton[1]->show();
0117     connect(mPlayerButton[1]->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0118     if ((Prefs::input1mouse() || Prefs::input1key()) && !mPlayerButton[0]->status())
0119         mPlayerButton[0]->setStatus(true);
0120 
0121     // Start game buttons
0122     ButtonSprite *button = new ButtonSprite(true, QStringLiteral("button_aieasy"), mTheme, 10, mScene);
0123     mSprites.append(button);
0124     button->setText(i18nc("quick start button - player versus AI level easy", "Easy Game"));
0125     button->show();
0126     connect(button->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0127 
0128     button = new ButtonSprite(true, QStringLiteral("button_ainormal"), mTheme, 11, mScene);
0129     mSprites.append(button);
0130     button->setText(i18nc("quick start button - player versus AI level normal", "Normal Game"));
0131     button->show();
0132     connect(button->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0133 
0134     button = new ButtonSprite(true, QStringLiteral("button_aihard"), mTheme, 12, mScene);
0135     mSprites.append(button);
0136     button->setText(i18nc("quick start button - player versus AI level hard", "Hard Game"));
0137     button->show();
0138     connect(button->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0139 
0140     button = new ButtonSprite(true, QStringLiteral("button_player"), mTheme, 13, mScene);
0141     mSprites.append(button);
0142     button->setText(i18nc("quick start button - player versus player", "Two Player Game"));
0143     button->show();
0144     connect(button->notify(), &SpriteNotify::signalNotify, this, &DisplayIntro::buttonPressed);
0145 
0146     // Animation timer
0147     mTimer = new QTimer(this);
0148     connect(mTimer, &QTimer::timeout, this, &DisplayIntro::advance);
0149 
0150     // Redraw
0151     if (theme)
0152         theme->updateTheme(this);
0153     qCDebug(KFOURINLINE_LOG) << "CONSTRUCTOR DONE";
0154 }
0155 
0156 // One of the graphical sprite buttons was pressed. Item and its id are delivered
0157 void DisplayIntro::buttonPressed(QGraphicsItem *item, int id)
0158 {
0159     int status = id >> 8;
0160     int no = id & 0xff;
0161     // qCDebug(KFOURINLINE_LOG) << "Button" << no  << "pressed status="<<status;
0162     ButtonSprite *button = dynamic_cast<ButtonSprite *>(item);
0163     Q_ASSERT(button);
0164     if (button == mStartButton[0]) {
0165         mStartButton[1]->setStatus(!button->status());
0166         Prefs::setStartcolouryellow(button->status());
0167         Prefs::setStartcolourred(!button->status());
0168     }
0169     if (button == mStartButton[1]) {
0170         mStartButton[0]->setStatus(!button->status());
0171         Prefs::setStartcolouryellow(!button->status());
0172         Prefs::setStartcolourred(button->status());
0173     }
0174     if (button == mPlayerButton[0]) {
0175         mPlayerButton[1]->setStatus(!button->status());
0176         Prefs::setStartcolouryellow(button->status());
0177         Prefs::setStartcolourred(!button->status());
0178     }
0179     if (button == mPlayerButton[1]) {
0180         mPlayerButton[0]->setStatus(!button->status());
0181         Prefs::setStartcolouryellow(!button->status());
0182         Prefs::setStartcolourred(button->status());
0183     }
0184 
0185     // Start game from button
0186     if (no >= 10 && no <= 13 && status == 1) {
0187         // Emit quick start with status (start player color, player color, AI level, two player?
0188 
0189         // Color
0190         COLOUR startPlayer;
0191         if (mStartButton[0]->status())
0192             startPlayer = Yellow;
0193         else
0194             startPlayer = Red;
0195 
0196         // Inputs
0197         KGameIO::IOMode input0 = KGameIO::ProcessIO;
0198         KGameIO::IOMode input1 = KGameIO::ProcessIO;
0199         if (mPlayerButton[0]->status())
0200             input0 = KGameIO::MouseIO;
0201         if (mPlayerButton[1]->status())
0202             input1 = KGameIO::MouseIO;
0203 
0204         // Level
0205         int level = -1;
0206         if (no == 10)
0207             level = 2;
0208         else if (no == 11)
0209             level = 4;
0210         else if (no == 12)
0211             level = 6;
0212         if (no == 13) {
0213             input0 = KGameIO::MouseIO;
0214             input1 = KGameIO::MouseIO;
0215         }
0216 
0217         // Emit signal
0218         Q_EMIT signalQuickStart(startPlayer, input0, input1, level);
0219     }
0220 }
0221 
0222 // Desctruct the intro and all sprites
0223 DisplayIntro::~DisplayIntro()
0224 {
0225     delete mTimer;
0226     qDeleteAll(mSprites);
0227 }
0228 
0229 // Master theme change function. Redraw the display
0230 void DisplayIntro::changeTheme()
0231 {
0232     qCDebug(KFOURINLINE_LOG) << "THEME CHANGE " << thememanager()->themefileChanged();
0233     // Measure time for resize
0234     QElapsedTimer time;
0235     time.restart();
0236 
0237     // Retrieve theme data
0238     KConfigGroup config = thememanager()->config(id());
0239 
0240     // Retrieve background pixmap
0241     QString bgsvgid = config.readEntry("background-svgid");
0242     QPixmap pixmap = thememanager()->getPixmap(bgsvgid, mScene->sceneRect().size().toSize());
0243     mScene->setBackgroundBrush(pixmap);
0244     mView->update();
0245 
0246     // Process quicklaunch sprite (could be own class...)
0247     double width = mQuickLaunch->boundingRect().width();
0248     double height = mQuickLaunch->boundingRect().height();
0249     // Retrieve theme data
0250     config = thememanager()->config(mQuickLaunch->id());
0251     QPointF posQuickstart = config.readEntry("posQuickstart", QPointF(1.0, 1.0));
0252     QPointF posStartplayer = config.readEntry("posStartplayer", QPointF(1.0, 1.0));
0253     QPointF posColor = config.readEntry("posColor", QPointF(1.0, 1.0));
0254 
0255     // HEADER
0256     // Calculate proper font size
0257     double fontHeight = config.readEntry("fontHeightHeader", 1.0);
0258     fontHeight *= height;
0259     double textHeight = config.readEntry("textHeightHeader", 1.0);
0260     textHeight *= height;
0261     double textWidth = config.readEntry("textWidthHeader", 1.0);
0262     textWidth *= width;
0263 
0264     // Retrieve font color
0265     QColor fontColor;
0266     fontColor = config.readEntry("fontColorHeader", QColor(Qt::white));
0267 
0268     // Create and set current font
0269     QFont font;
0270     fontHeight = KFontUtils::adaptFontSize(mTextQuicklaunch, textWidth, textHeight, fontHeight, 8.0);
0271     font.setPointSizeF(fontHeight);
0272 
0273     // Set font and color for all text items
0274     mTextQuicklaunch->setFont(font);
0275     mTextQuicklaunch->setDefaultTextColor(fontColor);
0276     mTextQuicklaunch->setTextWidth(textWidth);
0277 
0278     // Set position of sub sprites, we centered horizontally at creation time,
0279     // now we center it vertically
0280     QRectF bounding = mTextQuicklaunch->boundingRect();
0281     mTextQuicklaunch->setPos(posQuickstart.x() * width, posQuickstart.y() * height + (textHeight - bounding.height()) / 2);
0282 
0283     // TEXT
0284     // Calculate proper font size
0285     fontHeight = config.readEntry("fontHeight", 1.0);
0286     fontHeight *= height;
0287     textHeight = config.readEntry("textHeight", 1.0);
0288     textHeight *= height;
0289     textWidth = config.readEntry("textWidth", 1.0);
0290     textWidth *= width;
0291 
0292     // Retrieve font color
0293     fontColor = config.readEntry("fontColor", QColor(Qt::white));
0294 
0295     // Create and set current font
0296     // Calculate proper font point size to not wrap translations.
0297     double newFontHeight0 = KFontUtils::adaptFontSize(mTextStartplayer, textWidth, textHeight, fontHeight, 8.0);
0298     double newFontHeight1 = KFontUtils::adaptFontSize(mTextColor, textWidth, textHeight, fontHeight, 8.0);
0299     font.setPointSizeF(qMin(newFontHeight0, newFontHeight1));
0300 
0301     // Set font and color for all text items
0302     mTextStartplayer->setFont(font);
0303     mTextStartplayer->setDefaultTextColor(fontColor);
0304     mTextStartplayer->setTextWidth(textWidth);
0305 
0306     mTextColor->setFont(font);
0307     mTextColor->setDefaultTextColor(fontColor);
0308     mTextColor->setTextWidth(textWidth);
0309 
0310     // Set position of sub sprites, we centered horizontally at creation time,
0311     // now we center it vertically
0312     bounding = mTextStartplayer->boundingRect();
0313     mTextStartplayer->setPos(posStartplayer.x() * width, posStartplayer.y() * height + (textHeight - bounding.height()) / 2);
0314     bounding = mTextColor->boundingRect();
0315     mTextColor->setPos(posColor.x() * width, posColor.y() * height + (textHeight - bounding.height()) / 2);
0316 
0317     int elapsed = time.elapsed();
0318     qCDebug(KFOURINLINE_LOG) << "THEME CHANGE took " << elapsed << " ms";
0319 
0320     // Renew animation on theme change?
0321     if (thememanager()->themefileChanged()) {
0322         start(0);
0323     } else {
0324         delaySprites(elapsed);
0325     }
0326 }
0327 
0328 // Start the animation
0329 void DisplayIntro::start(int delay)
0330 {
0331     qCDebug(KFOURINLINE_LOG) << "START TIMER";
0332     // Do the timer
0333     mTimer->stop();
0334     mTimer->setSingleShot(true);
0335     mTimer->start(delay);
0336 }
0337 
0338 // Delay all sprite animation by the given time
0339 void DisplayIntro::delaySprites(int duration)
0340 {
0341     // Setup sprites
0342     for (int i = 0; i < mSprites.size(); ++i) {
0343         // Use only intro sprites
0344         if (mSprites.at(i)->type() != QGraphicsItem::UserType + 1)
0345             continue;
0346 
0347         IntroSprite *sprite = (IntroSprite *)mSprites.at(i);
0348         sprite->delayAnimation(duration);
0349     }
0350 }
0351 
0352 // Animation main routine to advance the animation. Called
0353 // by a timer
0354 void DisplayIntro::advance()
0355 {
0356     QElapsedTimer time;
0357     time.restart();
0358     int duration = createAnimation(true);
0359 
0360     qCDebug(KFOURINLINE_LOG) << "ADVANCE: Restarting timer in " << (duration + 5000) << " creation time " << time.elapsed();
0361     mTimer->start(duration + 5000); // [ms]
0362 }
0363 
0364 // Animation main routine to advance the animation. Called
0365 // by a timer
0366 int DisplayIntro::createAnimation(bool restartTime)
0367 {
0368     // Columns for the moves in the intro. Results in a drawn game
0369     // Note: Once could load the last played game here or so.
0370     static int moves[] = {3, 4, 4, 3, 3, 4, 4, 1, 3, 5, 3, 3, 6, 6, 6, 6, 6, 0, 6, 4, 5, 5, 2, 2, 5, 5, 1, 4, 5, 0, 0, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 0};
0371     // How many moves to perform (size of moves array)
0372     static int maxMoves = 42;
0373 
0374     // Config data
0375     KConfigGroup config = thememanager()->config(id());
0376     QPointF piece0_pos = config.readEntry("piece0-pos", QPointF(1.0, 1.0));
0377     QPointF piece1_pos = config.readEntry("piece1-pos", QPointF(1.0, 1.0));
0378     double piece_spread = config.readEntry("piece-spread", 0.1);
0379     QPointF board_pos = config.readEntry("board-pos", QPointF(1.0, 1.0));
0380     QPointF board_spread = config.readEntry("board-spread", QPointF(1.0, 1.0));
0381     double move_velocity = config.readEntry("move-velocity", 0.1);
0382 
0383     // Local variables
0384     double dura, delay, rad;
0385     QPointF start, end;
0386     int maxDuration = 0;
0387     int addWaitTime = 0;
0388 
0389     // ============================================================================
0390     // Setup sprites
0391     for (int i = 0; i < mSprites.size(); ++i) {
0392         // Use only intro sprites
0393         if (mSprites.at(i)->type() != QGraphicsItem::UserType + 1)
0394             continue;
0395 
0396         IntroSprite *sprite = (IntroSprite *)mSprites.at(i);
0397         int no = sprite->number();
0398         sprite->setZValue(no);
0399         sprite->hide();
0400 
0401         sprite->clearAnimation(restartTime);
0402     }
0403 
0404     // ============================================================================
0405     // First part of intro animation. Move sprites into window
0406     // Loop all sprites
0407     for (int i = 0; i < mSprites.size(); ++i) {
0408         // Move only intro sprites
0409         if (mSprites.at(i)->type() != QGraphicsItem::UserType + 1)
0410             continue;
0411         IntroSprite *sprite = (IntroSprite *)mSprites.at(i);
0412 
0413         int no = sprite->number();
0414         {
0415             if (no % 2 == 0) {
0416                 start = QPointF(1.05, 0.5);
0417                 end = QPointF(piece0_pos.x() + piece_spread * no, piece0_pos.y());
0418                 dura = 3000.0;
0419                 delay = 80.0 * no;
0420                 rad = 0.1;
0421             } else {
0422                 start = QPointF(-0.05, 0.5);
0423                 end = QPointF(piece1_pos.x() + piece_spread * (no - 1), piece1_pos.y());
0424                 dura = 3000.0;
0425                 delay = 80.0 * (no - 1);
0426                 rad = 0.1;
0427             }
0428 
0429             sprite->addPosition(start);
0430             sprite->addShow();
0431             sprite->addPause(int(delay));
0432             sprite->addLinear(start, (start + end) * 0.5, int(dura / 4.0));
0433             sprite->addCircle((start + end) * 0.5, rad, int(dura / 2.0));
0434             sprite->addLinear((start + end) * 0.5, end, int(dura / 4.0));
0435             if (sprite->animationDuration() > maxDuration)
0436                 maxDuration = sprite->animationDuration();
0437         }
0438     } // end list loop
0439     // ============================================================================
0440 
0441     // ============================================================================
0442     // Second part of intro animation. Move sprites inwards
0443     int moveCnt = 0;
0444     delay = 0.0;
0445     // Reset height
0446     int height[7];
0447     addWaitTime = maxDuration;
0448     for (int i = 0; i <= 6; i++)
0449         height[i] = 6;
0450     // Loop all sprites
0451     for (int i = mSprites.size() - 1; i >= 0; --i) {
0452         // Move only intro sprites
0453         if (mSprites.at(i)->type() != QGraphicsItem::UserType + 1)
0454             continue;
0455         IntroSprite *sprite = (IntroSprite *)mSprites.at(i);
0456 
0457         // No more moves left
0458         if (moveCnt >= maxMoves)
0459             continue;
0460         int ix = moves[moveCnt];
0461         moveCnt++;
0462 
0463         int iy = height[ix];
0464         height[ix]--;
0465         double x = board_pos.x() + ix * board_spread.x();
0466         double y = board_pos.y() + iy * board_spread.y();
0467 
0468         sprite->addWait(addWaitTime);
0469         sprite->addPause(3000);
0470         sprite->addPause(int(delay));
0471         AnimationCommand *anim = sprite->addRelativeManhatten(QPointF(x, y), move_velocity);
0472 
0473         delay += sprite->duration(anim);
0474 
0475         if (sprite->animationDuration() > maxDuration)
0476             maxDuration = sprite->animationDuration();
0477     } // end for
0478     // ============================================================================
0479 
0480     // ============================================================================
0481     // Third part of intro animation. Move sprites outwards
0482     addWaitTime = maxDuration;
0483     // Loop all sprites
0484     for (int i = 0; i < mSprites.size(); ++i) {
0485         // Move only intro sprites
0486         if (mSprites.at(i)->type() != QGraphicsItem::UserType + 1)
0487             continue;
0488         IntroSprite *sprite = (IntroSprite *)mSprites.at(i);
0489 
0490         int no = sprite->number();
0491         double xc = board_pos.x() + 3.0 * board_spread.x();
0492         double yc = board_pos.y() + 3.5 * board_spread.y();
0493 
0494         double x = xc + 1.50 * cos(no / 42.0 * 2.0 * M_PI);
0495         double y = yc + 1.50 * sin(no / 42.0 * 2.0 * M_PI);
0496 
0497         sprite->addWait(addWaitTime);
0498         sprite->addPause(8000);
0499         sprite->addRelativeLinear(QPointF(x, y), 800);
0500 
0501         if (sprite->animationDuration() > maxDuration)
0502             maxDuration = sprite->animationDuration();
0503     } // end for
0504     // ============================================================================
0505 
0506     return maxDuration;
0507 }
0508 
0509 // Find the sprite on the given position (buttons)
0510 QGraphicsItem *DisplayIntro::findSprite(QPoint pos)
0511 {
0512     QGraphicsItem *found = nullptr;
0513 
0514     for (int i = 0; i < mSprites.size(); ++i) {
0515         QGraphicsItem *item = mSprites[i];
0516         if (!item)
0517             continue;
0518         if (!item->isVisible())
0519             continue;
0520         // Map position to local
0521         QPointF p = item->mapFromScene(QPointF(pos));
0522         // Take highest zValue item
0523         if (item->contains(p) && (!found || (found->zValue() < item->zValue())))
0524             found = item;
0525     }
0526     return found;
0527 }
0528 
0529 // Handle view events and forward them to the sprites
0530 void DisplayIntro::viewEvent(QEvent *event)
0531 {
0532     // Only process some mouse events
0533     QEvent::Type type = event->type();
0534     if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove)
0535         return;
0536 
0537     // Cast items and find right sprite
0538     QMouseEvent *e = dynamic_cast<QMouseEvent *>(event);
0539     QGraphicsItem *item = findSprite(e->pos());
0540 
0541     // Which event type? Forward them to Button sprites only!
0542     switch (event->type()) {
0543     case QEvent::MouseButtonPress:
0544         if (item != nullptr && item->type() == QGraphicsItem::UserType + 100)
0545             (dynamic_cast<ButtonSprite *>(item))->mousePressEvent(e);
0546         break;
0547     case QEvent::MouseButtonRelease:
0548         if (item != nullptr && item->type() == QGraphicsItem::UserType + 100)
0549             (dynamic_cast<ButtonSprite *>(item))->mouseReleaseEvent(e);
0550         break;
0551     case QEvent::MouseMove:
0552         if (item != mLastMoveEvent) {
0553             if (mLastMoveEvent != nullptr && mLastMoveEvent->type() == QGraphicsItem::UserType + 100) {
0554                 (dynamic_cast<ButtonSprite *>(mLastMoveEvent))->hoverLeaveEvent(e);
0555             }
0556             if (item != nullptr && item->type() == QGraphicsItem::UserType + 100) {
0557                 (dynamic_cast<ButtonSprite *>(item))->hoverEnterEvent(e);
0558             }
0559             mLastMoveEvent = item;
0560         }
0561         break;
0562     default:
0563         break;
0564     }
0565     return;
0566 }
0567 
0568 #include "moc_displayintro.cpp"