Warning, file /games/kfourinline/src/pixmapsprite.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 "pixmapsprite.h"
0009 
0010 // own
0011 #include "kfourinline_debug.h"
0012 // KF
0013 #include <KConfig>
0014 #include <KConfigGroup>
0015 // Qt
0016 #include <QGraphicsScene>
0017 // Std
0018 #include <cmath>
0019 
0020 // Constructor for the sprite
0021 PixmapSprite::PixmapSprite(const QString &id, ThemeManager *theme, int no, QGraphicsScene *canvas)
0022     : Themeable(id, theme)
0023     , QGraphicsPixmapItem()
0024 {
0025     canvas->addItem(this);
0026     hide();
0027     setAcceptHoverEvents(false);
0028 
0029     mAnimationState = Idle;
0030     mNo = no;
0031     mCurrentFrame = 0;
0032     mOffsetStatus = true;
0033 
0034     if (theme)
0035         theme->updateTheme(this);
0036 }
0037 
0038 // Constructor for the sprite
0039 PixmapSprite::PixmapSprite(int no, QGraphicsScene *canvas)
0040     : Themeable()
0041     , QGraphicsPixmapItem()
0042 {
0043     canvas->addItem(this);
0044     hide();
0045 
0046     mAnimationState = Idle;
0047     mNo = no;
0048     mCurrentFrame = 0;
0049     mOffsetStatus = true;
0050 }
0051 
0052 // Main themeable function. Called for any theme change. The sprites needs to
0053 // resize and redraw here.
0054 void PixmapSprite::changeTheme()
0055 {
0056     // Clear data
0057     mFrames.clear();
0058     mHotspots.clear();
0059 
0060     // Get scaling change
0061     double oldscale = this->getScale();
0062     double scale = thememanager()->getScale();
0063     Themeable::setScale(scale);
0064 
0065     // Retrieve theme data from configuration
0066     KConfigGroup config = thememanager()->config(id());
0067     double width = config.readEntry("width", 1.0);
0068     double height = config.readEntry("height", 0.0);
0069     width *= scale;
0070     height *= scale;
0071     QPointF pos = config.readEntry("pos", QPointF(1.0, 1.0));
0072     pos *= scale;
0073     // Set fixed z value?
0074     if (config.hasKey("zValue")) {
0075         double zValue = config.readEntry("zValue", 0.0);
0076         setZValue(zValue);
0077     }
0078 
0079     // Centering
0080     bool center = config.readEntry("center", false);
0081 
0082     // Animation
0083     mStartFrame = config.readEntry("start-frame", 0);
0084     mEndFrame = config.readEntry("end-frame", 0);
0085     mDelay = config.readEntry("animation-delay", 0);
0086     QString refframe = config.readEntry("ref-frame", QString());
0087 
0088     // Set fixed position or modify current position
0089     if (config.hasKey("pos")) {
0090         setPos(pos.x(), pos.y());
0091     } else {
0092         setPos(x() * scale / oldscale, y() * scale / oldscale);
0093     }
0094 
0095     // SVG graphics
0096     QString svgid = config.readEntry("svgid");
0097     // Read sequence of frame pixmaps when auto ID given
0098     QPixmap pixmap;
0099     if (svgid == QLatin1String("auto")) {
0100         for (int i = mStartFrame; i <= mEndFrame; i++) {
0101             QString name = QStringLiteral("frame%1").arg(i);
0102             svgid = config.readEntry(name);
0103             if (!refframe.isNull()) {
0104                 pixmap = thememanager()->getPixmap(svgid, refframe, width);
0105             } else if (config.hasKey("height")) {
0106                 pixmap = thememanager()->getPixmap(svgid, QSize(int(width), int(height)));
0107             } else {
0108                 pixmap = thememanager()->getPixmap(svgid, width);
0109             }
0110             mFrames.append(pixmap);
0111             if (center)
0112                 mHotspots.append(QPointF(pixmap.width() / 2, pixmap.height() / 2));
0113             else
0114                 mHotspots.append(QPointF(0.0, 0.0));
0115         }
0116     }
0117     // Read only one named pixmap
0118     else {
0119         if (config.hasKey("height")) {
0120             pixmap = thememanager()->getPixmap(svgid, QSize(int(width), int(height)));
0121         } else {
0122             pixmap = thememanager()->getPixmap(svgid, width);
0123         }
0124         mFrames.append(pixmap);
0125         if (center)
0126             mHotspots.append(QPointF(pixmap.width() / 2, pixmap.height() / 2));
0127         else
0128             mHotspots.append(QPointF(0.0, 0.0));
0129     }
0130 
0131     // Set theme offset (probably not really necessary here)
0132     QPoint offset = thememanager()->getOffset();
0133     resetTransform();
0134     if (mOffsetStatus)
0135         setTransform(QTransform::fromTranslate(offset.x(), offset.y()), true);
0136 
0137     // Set pixmap to sprite
0138     setFrame(mCurrentFrame, true);
0139     update();
0140 }
0141 
0142 // Debug only: Retrieve double value from configuration file
0143 double PixmapSprite::getDoubleValue(const QString &item)
0144 {
0145     KConfigGroup config = thememanager()->config(id());
0146     return config.readEntry(item, 0.0);
0147 }
0148 
0149 // Move the sprite to the given relative position
0150 void PixmapSprite::setPosition(QPointF pos)
0151 {
0152     mStart = pos;
0153     setPos(mStart.x() * getScale(), mStart.y() * getScale());
0154 }
0155 
0156 // Handle the offset status (true: theme offset, false: no offset)
0157 void PixmapSprite::setOffsetStatus(bool status)
0158 {
0159     mOffsetStatus = status;
0160     changeTheme();
0161 }
0162 
0163 // Store the logical board coordinates for theme changes
0164 void PixmapSprite::setLogicalPos(QPoint pos)
0165 {
0166     mLPos = pos;
0167 }
0168 
0169 // Retrieve the logical board coordinates for theme changes
0170 QPoint PixmapSprite::logicalPos()
0171 {
0172     return mLPos;
0173 }
0174 
0175 // Start or stop a frame animation
0176 void PixmapSprite::setAnimation(bool status)
0177 {
0178     if (status)
0179         mAnimationState = Animated;
0180     else
0181         mAnimationState = Idle;
0182     mTime.start();
0183     setFrame(mStartFrame);
0184 }
0185 
0186 // Specify and start a frame animation
0187 void PixmapSprite::setAnimation(int start, int end, int delay)
0188 {
0189     mDelay = delay;
0190     mStartFrame = start;
0191     mEndFrame = end;
0192     setAnimation(true);
0193 }
0194 
0195 // Set a new bitmap into the sprite. If the number is the same as the
0196 // current one, nothing is done unless forcing is set to true.
0197 void PixmapSprite::setFrame(int no, bool force)
0198 {
0199     if (!force && no == mCurrentFrame)
0200         return;
0201     if (no < 0 || no >= mFrames.count())
0202         return;
0203     setPixmap(mFrames.at(no));
0204 
0205     QPoint offset = thememanager()->getOffset();
0206 
0207     // Set new item's scene transformation: Hotspot plus global theme offset
0208     resetTransform();
0209     if (mOffsetStatus) {
0210         setTransform(QTransform::fromTranslate(-mHotspots.at(no).x() + offset.x(), -mHotspots.at(no).y() + offset.y()), true);
0211     } else {
0212         setTransform(QTransform::fromTranslate(-mHotspots.at(no).x(), -mHotspots.at(no).y()), true);
0213     }
0214     mCurrentFrame = no;
0215     update();
0216 }
0217 
0218 // Standard QGI advance method
0219 void PixmapSprite::advance(int phase)
0220 {
0221     int elapsed = mTime.elapsed();
0222 
0223     // Ignore phase 0 (collisions)
0224     if (phase == 0) {
0225         QGraphicsItem::advance(phase);
0226         return;
0227     }
0228 
0229     // Handle animation
0230     if (mAnimationState == Animated) {
0231         // Frame delay passed?
0232         int frames = elapsed / mDelay;
0233         int curFrame = frames % (mEndFrame - mStartFrame) + mStartFrame;
0234         setFrame(curFrame);
0235     }
0236 
0237     QGraphicsItem::advance(phase);
0238 }