From e8291960bd4b221ff7e55aa55fd45aaeb3c8d37a Mon Sep 17 00:00:00 2001 From: louis Date: Sun, 12 Apr 2015 17:10:06 +0200 Subject: added possibility for blinking images, texts, rectangles, ellipses and slopes --- views/animation.c | 110 ++++++++++++++++++++++++++++++++++++ views/animation.h | 68 +++++++++++++++++++++++ views/view.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++---- views/view.h | 9 +++ 4 files changed, 339 insertions(+), 11 deletions(-) create mode 100644 views/animation.c create mode 100644 views/animation.h (limited to 'views') diff --git a/views/animation.c b/views/animation.c new file mode 100644 index 0000000..f7cedea --- /dev/null +++ b/views/animation.c @@ -0,0 +1,110 @@ +#include "animation.h" + +using namespace std; + +cAnimation::cAnimation(eAnimType animType, int animFreq, cRect &pos, int layer) : cPixmapContainer(1) { + this->animType = animType; + this->animFreq = animFreq; + this->pos = pos; + this->layer = layer; + blinkOn = true; +} + +cAnimation::~cAnimation() { +} + +void cAnimation::Action(void) { + CreatePixmap(0, layer+1, pos); + bool init = true; + while (Running()) { + if (animType == atBlink) { + if (!blinkOn) { + Fill(0, clrTransparent); + blinkOn = true; + } else { + DrawBlink(); + } + } else if (animType == atAnimated) { + esyslog("skindesigner: animationType atAnimated not implemented"); + } + if (init) + FadeIn(); + init = false; + DoFlush(); + DoSleep(animFreq); + } +} + +void cAnimation::Stop(void) { + CancelSave(); +} + +/******************************************************************************************** +* cAnimatedImage +********************************************************************************************/ +cAnimatedImage::cAnimatedImage(eAnimType animType, int animFreq, cRect &pos, int layer) : cAnimation(animType, animFreq, pos, layer) { + image = NULL; +} + +cAnimatedImage::~cAnimatedImage() { + esyslog("skindesigner: killing animation"); +} + +void cAnimatedImage::DrawBlink(void) { + blinkOn = false; + if (!image) + return; + + cPoint posImage(0,0); + if (Running()) + DrawImage(0, posImage, *image); +} + +/******************************************************************************************** +* cAnimatedText +********************************************************************************************/ +cAnimatedText::cAnimatedText(eAnimType animType, int animFreq, cRect &pos, int layer) : cAnimation(animType, animFreq, pos, layer) { + text = ""; + fontName = ""; + fontSize = 1; + fontColor = clrTransparent; +} + +cAnimatedText::~cAnimatedText() { +} + +void cAnimatedText::DrawBlink(void) { + blinkOn = false; + if (text.size() == 0) + return; + + cPoint posText(0,0); + if (Running()) + DrawText(0, posText, text.c_str(), fontColor, clrTransparent, fontName, fontSize); +} + +/******************************************************************************************** +* cAnimatedOsdObject +********************************************************************************************/ +cAnimatedOsdObject::cAnimatedOsdObject(eFuncType type, eAnimType animType, int animFreq, cRect &pos, int layer) : cAnimation(animType, animFreq, pos, layer) { + this->type = type; + color = 0x00000000; + quadrant = 0; +} + +cAnimatedOsdObject::~cAnimatedOsdObject() { +} + +void cAnimatedOsdObject::DrawBlink(void) { + blinkOn = false; + cRect posObject(0, 0, pos.Width(), pos.Height()); + if (Running()) { + if (type == ftDrawRectangle) { + DrawRectangle(0, posObject, color); + } else if (type == ftDrawEllipse) { + DrawEllipse(0, posObject, color, quadrant); + } else if (type == ftDrawSlope) { + DrawSlope(0, posObject, color, quadrant); + } + } +} diff --git a/views/animation.h b/views/animation.h new file mode 100644 index 0000000..1647872 --- /dev/null +++ b/views/animation.h @@ -0,0 +1,68 @@ +#ifndef __ANIMATION_H +#define __ANIMATION_H + +#include "string" +#include "../libcore/pixmapcontainer.h" +#include "../libtemplate/template.h" + +using namespace std; + +class cAnimation : public cPixmapContainer { +protected: + eAnimType animType; + int animFreq; + cRect pos; + int layer; + bool blinkOn; + virtual void DrawBlink(void) {}; + virtual void Action(void); +public: + cAnimation(eAnimType animType, int animFreq, cRect &pos, int layer); + virtual ~cAnimation(); + void SetAnimationFadeTime(int fadeTime) { SetFadeTime(fadeTime); }; + virtual void Stop(void); +}; + +class cAnimatedImage : public cAnimation { +private: + cImage *image; +protected: + void DrawBlink(void); +public: + cAnimatedImage(eAnimType animType, int animFreq, cRect &pos, int layer); + virtual ~cAnimatedImage(); + void SetImage(cImage *i) { image = i; }; +}; + +class cAnimatedText : public cAnimation { +private: + string text; + string fontName; + int fontSize; + tColor fontColor; +protected: + void DrawBlink(void); +public: + cAnimatedText(eAnimType animType, int animFreq, cRect &pos, int layer); + virtual ~cAnimatedText(); + void SetText(string &t) { text = t; }; + void SetFont(string &font) { fontName = font; }; + void SetFontSize(int size) { fontSize = size; }; + void SetFontColor(tColor col) { fontColor = col; }; +}; + +class cAnimatedOsdObject : public cAnimation { +private: + eFuncType type; + tColor color; + int quadrant; +protected: + void DrawBlink(void); +public: + cAnimatedOsdObject(eFuncType type, eAnimType animType, int animFreq, cRect &pos, int layer); + virtual ~cAnimatedOsdObject(); + void SetColor(tColor col) { color = col; }; + void SetQuadrant(int q) { quadrant = q; }; +}; + +#endif //__ANIMATION_H \ No newline at end of file diff --git a/views/view.c b/views/view.c index 1680379..077931a 100644 --- a/views/view.c +++ b/views/view.c @@ -40,6 +40,11 @@ cView::~cView() { cViewElement *ve = dVeIt->second; delete ve; } + for (multimap::iterator animIt = animations.begin(); animIt != animations.end(); animIt++) { + cAnimation *anim = animIt->second; + anim->Stop(); + delete anim; + } } void cView::DrawDebugGrid(void) { @@ -57,6 +62,7 @@ void cView::Init(void) { scrollDelay = 0; scrollMode = smNone; scrollSpeed = ssMedium; + animCat = 0; currentlyScrolling = false; } @@ -85,8 +91,10 @@ void cView::DrawViewElement(eViewElement ve, map *stringTokens, cTemplateViewElement *viewElement = NULL; if (tmplViewElement) { viewElement = tmplViewElement; + animCat = 0; } else if (tmplView) { viewElement = tmplView->GetViewElement(ve); + animCat = ve; } if (!viewElement) return; @@ -164,8 +172,10 @@ void cView::DrawViewElement(eViewElement ve, map *stringTokens, void cView::ClearViewElement(eViewElement ve) { cTemplateViewElement *viewElement = NULL; + int currentAnimCat = ve; if (tmplViewElement) { viewElement = tmplViewElement; + currentAnimCat = 0; } else if (tmplView) { viewElement = tmplView->GetViewElement(ve); } @@ -182,6 +192,7 @@ void cView::ClearViewElement(eViewElement ve) { } pixCurrent++; } + ClearAnimations(currentAnimCat); } void cView::DestroyViewElement(eViewElement ve) { @@ -199,6 +210,21 @@ void cView::DestroyViewElement(eViewElement ve) { DestroyPixmap(pixCurrent); pixCurrent++; } + ClearAnimations(ve); +} + +void cView::ClearAnimations(int cat) { + //stop and delete all animated elements from this viewelement + if (animations.size() == 0) + return; + pair::iterator, multimap::iterator> rangeAnims; + rangeAnims = animations.equal_range(cat); + for (multimap::iterator it = rangeAnims.first; it!=rangeAnims.second; ++it) { + cAnimation *anim = it->second; + anim->Stop(); + delete anim; + } + animations.erase(cat); } void cView::ActivateScrolling(void) { @@ -560,7 +586,11 @@ void cView::DoDrawText(int num, cTemplateFunction *func, int x0, int y0) { } else { text = func->GetText(false); } - DrawText(num, pos, text.c_str(), clr, clrBack, fontName, fontSize); + if (func->IsAnimated()) { + DrawAnimatedText(num, func, pos, text, clr, fontName, fontSize); + } else { + DrawText(num, pos, text.c_str(), clr, clrBack, fontName, fontSize); + } } void cView::DoDrawTextVertical(int num, cTemplateFunction *func, int x0, int y0) { @@ -606,7 +636,13 @@ void cView::DoDrawTextVertical(int num, cTemplateFunction *func, int x0, int y0) if (y < 0) y = func->GetContainerHeight() - textVertical->Height() - 5; y += y0; cPoint pos(x,y); - DrawImage(num, pos, *textVertical); + + if (func->IsAnimated()) { + cRect posAnim(x, y, textVertical->Width(), textVertical->Height()); + DrawAnimatedImage(num, func, posAnim, textVertical); + } else { + DrawImage(num, pos, *textVertical); + } } void cView::DoDrawTextBox(int num, cTemplateFunction *func, int x0, int y0) { @@ -804,7 +840,12 @@ void cView::DoDrawRectangle(int num, cTemplateFunction *func, int x0, int y0) { int h = func->GetNumericParameter(ptHeight); cRect size(x, y, w, h); tColor clr = func->GetColorParameter(ptColor); - DrawRectangle(num, size, clr); + + if (func->IsAnimated()) { + DrawAnimatedOsdObject(num, func, size, clr, 0); + } else { + DrawRectangle(num, size, clr); + } } void cView::DoDrawEllipse(int num, cTemplateFunction *func, int x0, int y0) { @@ -823,7 +864,12 @@ void cView::DoDrawEllipse(int num, cTemplateFunction *func, int x0, int y0) { esyslog("skindesigner: wrong quadrant %d for drawellipse, allowed values are from -4 to 8", quadrant); quadrant = 0; } - DrawEllipse(num, size, clr, quadrant); + + if (func->IsAnimated()) { + DrawAnimatedOsdObject(num, func, size, clr, quadrant); + } else { + DrawEllipse(num, size, clr, quadrant); + } } void cView::DoDrawSlope(int num, cTemplateFunction *func, int x0, int y0) { @@ -842,7 +888,11 @@ void cView::DoDrawSlope(int num, cTemplateFunction *func, int x0, int y0) { esyslog("skindesigner: wrong type %d for drawslope, allowed values are from 0 to 7", type); type = 0; } - DrawSlope(num, size, clr, type); + if (func->IsAnimated()) { + DrawAnimatedOsdObject(num, func, size, clr, type); + } else { + DrawSlope(num, size, clr, type); + } } void cView::DoDrawImage(int num, cTemplateFunction *func, int x0, int y0) { @@ -861,31 +911,56 @@ void cView::DoDrawImage(int num, cTemplateFunction *func, int x0, int y0) { case itChannelLogo: { cImage *logo = imgCache->GetLogo(path, width, height); if (logo) { - DrawImage(num, pos, *logo); + if (func->IsAnimated()) { + cRect posAnim(x, y, width, height); + DrawAnimatedImage(num, func, posAnim, logo); + } else { + DrawImage(num, pos, *logo); + } } break; } case itSepLogo: { cImage *sepLogo = imgCache->GetSeparatorLogo(path, width, height); if (sepLogo) { - DrawImage(num, pos, *sepLogo); + if (func->IsAnimated()) { + cRect posAnim(x, y, width, height); + DrawAnimatedImage(num, func, posAnim, sepLogo); + } else { + DrawImage(num, pos, *sepLogo); + } } break; } case itSkinPart: { cImage *skinpart = imgCache->GetSkinpart(path, width, height); if (skinpart) { - DrawImage(num, pos, *skinpart); + if (func->IsAnimated()) { + cRect posAnim(x, y, width, height); + DrawAnimatedImage(num, func, posAnim, skinpart); + } else { + DrawImage(num, pos, *skinpart); + } } break; } case itIcon: { cImage *icon = imgCache->GetIcon(type, path, width, height); if (icon) { - DrawImage(num, pos, *icon); + if (func->IsAnimated()) { + cRect posAnim(x, y, width, height); + DrawAnimatedImage(num, func, posAnim, icon); + } else { + DrawImage(num, pos, *icon); + } } break; } case itMenuIcon: { cImage *icon = imgCache->GetIcon(type, path, width, height); if (icon) { - DrawImage(num, pos, *icon); + if (func->IsAnimated()) { + cRect posAnim(x, y, width, height); + DrawAnimatedImage(num, func, posAnim, icon); + } else { + DrawImage(num, pos, *icon); + } } break; } case itImage: { @@ -901,6 +976,70 @@ void cView::DoDrawImage(int num, cTemplateFunction *func, int x0, int y0) { } } +void cView::DrawAnimatedImage(int numPix, cTemplateFunction *func, cRect &pos, cImage *image) { + int layer = Layer(numPix); + cRect posAnim = CalculateAnimationClip(numPix, pos); + eAnimType animType = (eAnimType)func->GetNumericParameter(ptAnimType); + int animFreq = func->GetNumericParameter(ptAnimFreq); + + cAnimatedImage *anim = new cAnimatedImage(animType, animFreq, posAnim, layer); + animations.insert(pair(animCat, anim)); + if (tmplView) { + anim->SetAnimationFadeTime(tmplView->GetNumericParameter(ptFadeTime)); + } + anim->SetImage(image); + anim->Start(); +} + +void cView::DrawAnimatedText(int numPix, cTemplateFunction *func, cPoint &pos, string text, tColor col, string fontName, int fontSize) { + int layer = Layer(numPix); + int textWidth = fontManager->Width(fontName, fontSize, text.c_str()); + int textHeight = fontManager->Height(fontName, fontSize); + cRect posOrig(pos.X(), pos.Y(), textWidth, textHeight); + cRect posAnim = CalculateAnimationClip(numPix, posOrig); + eAnimType animType = (eAnimType)func->GetNumericParameter(ptAnimType); + int animFreq = func->GetNumericParameter(ptAnimFreq); + + cAnimatedText *anim = new cAnimatedText(animType, animFreq, posAnim, layer); + animations.insert(pair(animCat, anim)); + if (tmplView) { + anim->SetAnimationFadeTime(tmplView->GetNumericParameter(ptFadeTime)); + } + anim->SetText(text); + anim->SetFont(fontName); + anim->SetFontSize(fontSize); + anim->SetFontColor(col); + anim->Start(); +} + +void cView::DrawAnimatedOsdObject(int numPix, cTemplateFunction *func, cRect &pos, tColor col, int quadrant) { + int layer = Layer(numPix); + cRect posAnim = CalculateAnimationClip(numPix, pos); + eFuncType funcType = func->GetType(); + eAnimType animType = (eAnimType)func->GetNumericParameter(ptAnimType); + int animFreq = func->GetNumericParameter(ptAnimFreq); + + cAnimatedOsdObject *anim = new cAnimatedOsdObject(funcType, animType, animFreq, posAnim, layer); + animations.insert(pair(animCat, anim)); + if (tmplView) { + anim->SetAnimationFadeTime(tmplView->GetNumericParameter(ptFadeTime)); + } + anim->SetColor(col); + anim->SetQuadrant(quadrant); + anim->Start(); +} + +cRect cView::CalculateAnimationClip(int numPix, cRect &pos) { + cPoint posPix; + Pos(numPix, posPix); + cRect posAnim; + posAnim.SetX(posPix.X() + pos.X()); + posAnim.SetY(posPix.Y() + pos.Y()); + posAnim.SetWidth(pos.Width()); + posAnim.SetHeight(pos.Height()); + return posAnim; +} + /*********************************************************************** * cViewElement ************************************************************************/ @@ -1021,6 +1160,7 @@ void cViewListItem::ClearListItem(void) { for (int pixCurrent = 0; pixCurrent < pixMax; pixCurrent++) { Fill(pixCurrent, clrTransparent); } + ClearAnimations(0); } void cViewListItem::SetListElementPosition(cTemplatePixmap *pix) { @@ -1069,7 +1209,6 @@ cGrid::cGrid(cTemplateViewElement *tmplGrid) : cView(tmplGrid) { } cGrid::~cGrid() { - } void cGrid::Set(double x, double y, double width, double height, @@ -1175,6 +1314,7 @@ void cGrid::Clear(void) { for (int pixCurrent = 0; pixCurrent < pixMax; pixCurrent++) { Fill(pixCurrent, clrTransparent); } + ClearAnimations(0); } void cGrid::DeletePixmaps(void) { @@ -1182,6 +1322,7 @@ void cGrid::DeletePixmaps(void) { for (int pixCurrent = 0; pixCurrent < pixMax; pixCurrent++) { DestroyPixmap(pixCurrent); } + ClearAnimations(0); } void cGrid::PositionPixmap(cTemplatePixmap *pix) { diff --git a/views/view.h b/views/view.h index e6ee909..b7918ca 100644 --- a/views/view.h +++ b/views/view.h @@ -5,6 +5,7 @@ #include "map" #include "../libcore/pixmapcontainer.h" #include "../libtemplate/template.h" +#include "animation.h" using namespace std; @@ -23,6 +24,10 @@ private: void DoDrawEllipse(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0); void DoDrawSlope(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0); void DoDrawImage(int num, cTemplateFunction *func, int x0 = 0, int y0 = 0); + void DrawAnimatedImage(int numPix, cTemplateFunction *func, cRect &pos, cImage *image); + void DrawAnimatedText(int numPix, cTemplateFunction *func, cPoint &pos, string text, tColor col, string fontName, int fontSize); + void DrawAnimatedOsdObject(int numPix, cTemplateFunction *func, cRect &pos, tColor col, int quadrant); + cRect CalculateAnimationClip(int numPix, cRect &pos); void ActivateScrolling(void); protected: cTemplateView *tmplView; @@ -30,6 +35,8 @@ protected: cTemplateViewTab *tmplTab; //detached viewelements map < eViewElement, cViewElement* > detachedViewElements; + //animated elements + multimap < int, cAnimation* > animations; //scaling window cRect scalingWindow; bool tvScaled; @@ -44,9 +51,11 @@ protected: int scrollDelay; int scrollMode; int scrollSpeed; + int animCat; void DrawViewElement(eViewElement ve, map *stringTokens = NULL, map *intTokens = NULL, map < string, vector< map< string, string > > > *loopTokens = NULL); void ClearViewElement(eViewElement ve); void DestroyViewElement(eViewElement ve); + void ClearAnimations(int cat); bool ExecuteViewElement(eViewElement ve); bool DetachViewElement(eViewElement ve); bool ViewElementScrolls(eViewElement ve); -- cgit v1.2.3