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