95 int supportInfo; |
97 int supportInfo; |
96 int newMajorSkinId; |
98 int newMajorSkinId; |
97 int newMinorSkinId; |
99 int newMinorSkinId; |
98 } partMapEntry; |
100 } partMapEntry; |
99 |
101 |
|
102 AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part), |
|
103 m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping) |
|
104 { |
|
105 } |
|
106 |
|
107 AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval), |
|
108 m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0) |
|
109 { |
|
110 } |
|
111 AnimationDataV2::~AnimationDataV2() |
|
112 { |
|
113 delete m_animation; |
|
114 } |
|
115 |
|
116 QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval) |
|
117 { |
|
118 QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval)); |
|
119 QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData)); |
|
120 } |
|
121 |
|
122 QS60StyleAnimation::~QS60StyleAnimation() |
|
123 { |
|
124 delete m_currentData; |
|
125 delete m_defaultData; |
|
126 } |
|
127 |
|
128 void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation) |
|
129 { |
|
130 Q_ASSERT(animation); |
|
131 if (m_currentData->m_animation) |
|
132 delete m_currentData->m_animation; |
|
133 m_currentData->m_animation = animation; |
|
134 } |
|
135 |
|
136 void QS60StyleAnimation::resetToDefaults() |
|
137 { |
|
138 delete m_currentData; |
|
139 m_currentData = 0; |
|
140 QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData)); |
|
141 } |
|
142 |
100 class QS60StyleModeSpecifics |
143 class QS60StyleModeSpecifics |
101 { |
144 { |
102 public: |
145 public: |
103 static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart, |
146 static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart, |
104 const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
147 const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
111 static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame); |
154 static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame); |
112 static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
155 static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
113 static QSize naviPaneSize(); |
156 static QSize naviPaneSize(); |
114 static TAknsItemID partSpecificThemeId(int part); |
157 static TAknsItemID partSpecificThemeId(int part); |
115 |
158 |
|
159 static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part); |
|
160 |
116 private: |
161 private: |
117 static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part, |
162 static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part, |
118 const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
163 const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
119 static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
164 static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags); |
120 static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart, |
165 static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart, |
126 // Array to match the skin ID, fallback graphics and Qt widget graphics. |
171 // Array to match the skin ID, fallback graphics and Qt widget graphics. |
127 static const partMapEntry m_partMap[]; |
172 static const partMapEntry m_partMap[]; |
128 }; |
173 }; |
129 |
174 |
130 const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { |
175 const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { |
131 /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1}, |
176 /* SP_QgnGrafBarWaitAnim */ {KAknsIIDQgnGrafBarWaitAnim, EDrawAnimation, ES60_All, -1,-1}, |
132 /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1}, |
177 /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1}, |
133 /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1}, |
178 /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1}, |
134 /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1}, |
179 /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1}, |
135 /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1}, |
180 /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1}, |
136 /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1}, |
181 /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1}, |
707 |
757 |
708 CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext |
758 CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext |
709 // QS60WindowSurface::lockBitmapHeap(); |
759 // QS60WindowSurface::lockBitmapHeap(); |
710 break; |
760 break; |
711 } |
761 } |
|
762 case EDrawAnimation: { |
|
763 CFbsBitmap* animationFrame; |
|
764 CFbsBitmap* frameMask; |
|
765 CAknBitmapAnimation* aknAnimation = 0; |
|
766 TBool constructedFromTheme = ETrue; |
|
767 |
|
768 QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed |
|
769 if (animation) { |
|
770 if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation |
|
771 CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL(); |
|
772 CleanupStack::PushL(newAnimation); |
|
773 if (newAnimation) |
|
774 constructedFromTheme = newAnimation->ConstructFromSkinL(skinId); |
|
775 if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) { |
|
776 animation->setResourceBased(false); |
|
777 animation->setAnimationObject(newAnimation); //animation takes ownership |
|
778 } |
|
779 CleanupStack::Pop(newAnimation); |
|
780 } |
|
781 //fill-in stored information |
|
782 aknAnimation = animation->animationObject(); |
|
783 constructedFromTheme = !animation->isResourceBased(); |
|
784 } |
|
785 |
|
786 const int currentFrame = QS60StylePrivate::currentAnimationFrame(part); |
|
787 if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) { |
|
788 //Animation was created succesfully and contains frames, just fetch current frame |
|
789 if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count()) |
|
790 User::Leave(KErrOverflow); |
|
791 const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame); |
|
792 if (frameData) { |
|
793 animationFrame = frameData->Bitmap(); |
|
794 frameMask = frameData->Mask(); |
|
795 } |
|
796 } else { |
|
797 //Theme does not contain animation theming, create frames from resource file |
|
798 TInt fallbackGraphicID = -1; |
|
799 fallbackInfo(part, fallbackGraphicID); |
|
800 fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks |
|
801 TInt fallbackGraphicsMaskID = |
|
802 (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files |
|
803 if (fallbackGraphicsMaskID != KErrNotFound) |
|
804 fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics |
|
805 |
|
806 //Then draw animation frame |
|
807 AknsUtils::CreateIconL( |
|
808 skinInstance, |
|
809 KAknsIIDDefault, //animation is not themed, lets force fallback graphics |
|
810 animationFrame, |
|
811 frameMask, |
|
812 AknIconUtils::AvkonIconFileName(), |
|
813 fallbackGraphicID , |
|
814 fallbackGraphicsMaskID); |
|
815 } |
|
816 result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize); |
|
817 if (!constructedFromTheme) { |
|
818 delete animationFrame; |
|
819 animationFrame = 0; |
|
820 delete frameMask; |
|
821 frameMask = 0; |
|
822 } |
|
823 break; |
|
824 } |
712 } |
825 } |
713 if (!result) |
826 if (!result) |
714 result = QPixmap(); |
827 result = QPixmap(); |
715 |
828 |
716 return result; |
829 return result; |
729 rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size); |
842 rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size); |
730 |
843 |
731 MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); |
844 MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); |
732 QPixmap result; |
845 QPixmap result; |
733 |
846 |
734 // QS60WindowSurface::unlockBitmapHeap(); |
|
735 static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA; |
847 static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA; |
736 static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly; |
848 static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly; |
737 |
849 |
738 CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen |
850 CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen |
739 CleanupStack::PushL(frame); |
851 CleanupStack::PushL(frame); |
983 } |
1095 } |
984 |
1096 |
985 m_pmPointer = data[activeLayoutIndex]; |
1097 m_pmPointer = data[activeLayoutIndex]; |
986 } |
1098 } |
987 |
1099 |
|
1100 Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations) |
|
1101 |
988 QS60StylePrivate::QS60StylePrivate() |
1102 QS60StylePrivate::QS60StylePrivate() |
989 { |
1103 { |
|
1104 //Animation defaults need to be created when style is instantiated |
|
1105 QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100); |
|
1106 m_animations()->append(progressBarAnimation); |
990 // No need to set active layout, if dynamic metrics API is available |
1107 // No need to set active layout, if dynamic metrics API is available |
991 setActiveLayout(); |
1108 setActiveLayout(); |
992 } |
1109 } |
993 |
1110 |
994 QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list, |
1111 QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list, |
1185 QEvent e(QEvent::StyleChange); |
1302 QEvent e(QEvent::StyleChange); |
1186 QApplication::sendEvent(topLevelWidget, &e); |
1303 QApplication::sendEvent(topLevelWidget, &e); |
1187 setThemePalette(topLevelWidget); |
1304 setThemePalette(topLevelWidget); |
1188 topLevelWidget->ensurePolished(); |
1305 topLevelWidget->ensurePolished(); |
1189 } |
1306 } |
|
1307 #ifndef QT_NO_PROGRESSBAR |
|
1308 //re-start animation timer |
|
1309 stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones" |
|
1310 startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones" |
|
1311 #endif |
1190 } |
1312 } |
1191 |
1313 |
1192 QSize QS60StylePrivate::naviPaneSize() |
1314 QSize QS60StylePrivate::naviPaneSize() |
1193 { |
1315 { |
1194 return QS60StyleModeSpecifics::naviPaneSize(); |
1316 return QS60StyleModeSpecifics::naviPaneSize(); |
1204 return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight); |
1326 return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight); |
1205 } |
1327 } |
1206 return QSize(0,0); |
1328 return QSize(0,0); |
1207 } |
1329 } |
1208 |
1330 |
|
1331 int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part) |
|
1332 { |
|
1333 QS60StyleAnimation *animation = animationDefinition(part); |
|
1334 // todo: looping could be done in QS60Style::timerEvent |
|
1335 if (animation->frameCount() == animation->currentFrame()) |
|
1336 animation->setCurrentFrame(0); |
|
1337 return animation->currentFrame(); |
|
1338 } |
|
1339 |
|
1340 QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part) |
|
1341 { |
|
1342 int i = 0; |
|
1343 const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count(); |
|
1344 for(; i < animationsCount; i++) { |
|
1345 if (part == m_animations()->at(i)->animationId()) |
|
1346 break; |
|
1347 } |
|
1348 return m_animations()->at(i); |
|
1349 } |
|
1350 |
|
1351 void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart) |
|
1352 { |
|
1353 Q_Q(QS60Style); |
|
1354 |
|
1355 //Query animation data from theme and store values to local struct. |
|
1356 QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition( |
|
1357 QS60StyleEnums::TD_AnimationData, animationPart); |
|
1358 QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList(); |
|
1359 |
|
1360 QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart); |
|
1361 if (animation) { |
|
1362 if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0) |
|
1363 animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt()); |
|
1364 |
|
1365 if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0) |
|
1366 animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt()); |
|
1367 |
|
1368 //todo: playmode is ignored for now, since it seems to return invalid data on some themes |
|
1369 //lets use the table values for play mode |
|
1370 |
|
1371 animation->setCurrentFrame(0); //always initialize |
|
1372 const int timerId = q->startTimer(animation->interval()); |
|
1373 animation->setTimerId(timerId); |
|
1374 } |
|
1375 } |
|
1376 |
|
1377 void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart) |
|
1378 { |
|
1379 Q_Q(QS60Style); |
|
1380 |
|
1381 QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart); |
|
1382 if (animation) { |
|
1383 animation->setCurrentFrame(0); |
|
1384 if (animation->timerId() != 0) { |
|
1385 q->killTimer(animation->timerId()); |
|
1386 animation->setTimerId(0); |
|
1387 } |
|
1388 animation->resetToDefaults(); |
|
1389 } |
|
1390 } |
|
1391 |
|
1392 QVariant QS60StyleModeSpecifics::themeDefinition( |
|
1393 QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part) |
|
1394 { |
|
1395 MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); |
|
1396 |
|
1397 Q_ASSERT(skinInstance); |
|
1398 |
|
1399 switch(definition) { |
|
1400 //Animation definitions |
|
1401 case QS60StyleEnums::TD_AnimationData: |
|
1402 { |
|
1403 CAknsBmpAnimItemData *animationData; |
|
1404 TAknsItemID animationSkinId = partSpecificThemeId(part); |
|
1405 QList<QVariant> list; |
|
1406 |
|
1407 TRAPD( error, QT_TRYCATCH_LEAVING( |
|
1408 animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL( |
|
1409 animationSkinId, EAknsITBmpAnim)))); |
|
1410 if (error) |
|
1411 return list; |
|
1412 |
|
1413 if (animationData) { |
|
1414 list.append((int)animationData->FrameInterval()); |
|
1415 list.append((int)animationData->NumberOfImages()); |
|
1416 |
|
1417 QS60StyleEnums::AnimationMode playMode; |
|
1418 switch(animationData->PlayMode()) { |
|
1419 case CBitmapAnimClientData::EPlay: |
|
1420 playMode = QS60StyleEnums::AM_PlayOnce; |
|
1421 break; |
|
1422 case CBitmapAnimClientData::ECycle: |
|
1423 playMode = QS60StyleEnums::AM_Looping; |
|
1424 break; |
|
1425 case CBitmapAnimClientData::EBounce: |
|
1426 playMode = QS60StyleEnums::AM_Bounce; |
|
1427 break; |
|
1428 default: |
|
1429 break; |
|
1430 } |
|
1431 list.append(QVariant((int)playMode)); |
|
1432 delete animationData; |
|
1433 } else { |
|
1434 list.append(0); |
|
1435 list.append(0); |
|
1436 } |
|
1437 return list; |
|
1438 } |
|
1439 break; |
|
1440 default: |
|
1441 break; |
|
1442 } |
|
1443 return QVariant(); |
|
1444 } |
|
1445 |
1209 #endif // Q_WS_S60 |
1446 #endif // Q_WS_S60 |
1210 |
1447 |
1211 QT_END_NAMESPACE |
1448 QT_END_NAMESPACE |
1212 |
1449 |
1213 #endif // QT_NO_STYLE_S60 || QT_PLUGIN |
1450 #endif // QT_NO_STYLE_S60 || QT_PLUGIN |