File indexing completed on 2024-12-01 03:46:40
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"