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