#include "view.h" #include "../config.h" #include "../libcore/helpers.h" #include "../libcore/imageloader.h" using namespace std; cView::cView(cTemplateView *tmplView) : cPixmapContainer(tmplView->GetNumPixmaps()) { this->tmplView = tmplView; tvScaled = tmplView->GetScalingWindow(scalingWindow); if (tvScaled) { cDevice::PrimaryDevice()->ScaleVideo(scalingWindow); } tmplViewElement = NULL; tmplTab = NULL; Init(); } cView::cView(cTemplateViewElement *tmplViewElement) : cPixmapContainer(tmplViewElement ? tmplViewElement->GetNumPixmaps() : 0) { this->tmplViewElement = tmplViewElement; tmplView = NULL; tmplTab = NULL; tvScaled = false; Init(); } cView::cView(cTemplateViewTab *tmplTab) : cPixmapContainer(1) { this->tmplTab = tmplTab; tmplView = NULL; tmplViewElement = NULL; tvScaled = false; Init(); } cView::~cView() { if (tvScaled) { cDevice::PrimaryDevice()->ScaleVideo(cRect::Null); } for (map::iterator dVeIt = detachedViewElements.begin(); dVeIt != detachedViewElements.end(); dVeIt++) { cViewElement *ve = dVeIt->second; delete ve; } } void cView::Init(void) { viewInit = true; scrolling = false; veScroll = veUndefined; scrollingPix = -1; scrollOrientation = orHorizontal; scrollDelay = 0; scrollMode = smNone; scrollSpeed = ssMedium; currentlyScrolling = false; } void cView::Action(void) { if (scrolling) { DoSleep(scrollDelay); if (scrollOrientation == orHorizontal) { ActivateScrolling(); ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode); } else { ScrollVertical(scrollingPix, scrollDelay, scrollSpeed); } } } void cView::Stop(void) { CancelSave(); } /******************************************************************************** * Protected Functions ********************************************************************************/ void cView::DrawViewElement(eViewElement ve, map *stringTokens, map *intTokens, map < string, vector< map< string, string > > > *loopTokens) { //setting correct ViewElement, depending which constructor was used cTemplateViewElement *viewElement = NULL; if (tmplViewElement) { viewElement = tmplViewElement; } else if (tmplView) { viewElement = tmplView->GetViewElement(ve); } if (!viewElement) return; if (viewElement->DebugTokens()) { DebugTokens(tmplView ? (tmplView->GetViewElementName(ve)) : "current view", stringTokens, intTokens, loopTokens); } //iterate through pixmaps of viewelement int pixCurrent = viewElement->GetPixOffset(); if (pixCurrent < 0) return; viewElement->InitIterator(); cTemplatePixmap *pix = NULL; while(pix = viewElement->GetNextPixmap()) { //check if already drawn background area, this can be skipped if (PixmapExists(pixCurrent) && pix->BackgroundArea()) { pixCurrent++; continue; } //reset Template pix->ClearDynamicParameters(); //create Pixmap if already fully parsed if (!PixmapExists(pixCurrent) && pix->Ready() && pix->DoExecute() && !pix->Scrolling()) { CreateViewPixmap(pixCurrent, pix); } //check if pixmap needs dynamic parameters if ((!pix->Ready() || !pix->DoExecute()) && !pix->Scrolling()) { //parse dynamic parameters and initiate functions pix->ParseDynamicParameters(intTokens, true); if (pix->Ready() && pix->DoExecute()) { CreateViewPixmap(pixCurrent, pix); } } else { //parse dynamic parameters but not initiate functions pix->ParseDynamicParameters(intTokens, false); } //if pixmap still not valid, skip if (!pix->Ready() && !pix->Scrolling()) { pixCurrent++; continue; } //if condition for pixmap set, check if cond is true if (!pix->DoExecute()) { pixCurrent++; continue; } //parse dynamic tokens of pixmap functions pix->ClearDynamicFunctionParameters(); pix->ParseDynamicFunctionParameters(stringTokens, intTokens); if (!PixmapExists(pixCurrent) && pix->Scrolling()) { cSize drawportSize; scrolling = pix->CalculateDrawPortSize(drawportSize, loopTokens); if (scrolling) { CreateScrollingPixmap(pixCurrent, pix, drawportSize); pix->SetScrollingTextWidth(); veScroll = ve; scrollingPix = pixCurrent; scrollOrientation = pix->GetNumericParameter(ptOrientation); scrollMode = pix->GetNumericParameter(ptScrollMode); scrollDelay = pix->GetNumericParameter(ptDelay); scrollSpeed = pix->GetNumericParameter(ptScrollSpeed); } else { CreateViewPixmap(pixCurrent, pix); } } if (pix->DoDebug()) { pix->Debug(); } DrawPixmap(pixCurrent, pix, loopTokens); pixCurrent++; } } void cView::ClearViewElement(eViewElement ve) { cTemplateViewElement *viewElement = NULL; if (tmplViewElement) { viewElement = tmplViewElement; } else if (tmplView) { viewElement = tmplView->GetViewElement(ve); } if (!viewElement) return; int pixCurrent = viewElement->GetPixOffset(); if (pixCurrent < 0) return; cTemplatePixmap *pix = NULL; viewElement->InitIterator(); while(pix = viewElement->GetNextPixmap()) { if (!pix->BackgroundArea()) { Fill(pixCurrent, clrTransparent); } pixCurrent++; } } void cView::DestroyViewElement(eViewElement ve) { if (!tmplView) return; cTemplateViewElement *viewElement = tmplView->GetViewElement(ve); if (!viewElement) return; int pixCurrent = viewElement->GetPixOffset(); if (pixCurrent < 0) return; cTemplatePixmap *pix = NULL; viewElement->InitIterator(); while(pix = viewElement->GetNextPixmap()) { DestroyPixmap(pixCurrent); pixCurrent++; } } void cView::ActivateScrolling(void) { if (veScroll == veUndefined) return; cTemplateViewElement *scrollViewElement = NULL; if (tmplView) { scrollViewElement = tmplView->GetViewElement(veScroll); } if (!scrollViewElement) return; ClearViewElement(veScroll); currentlyScrolling = true; int pixCurrent = scrollViewElement->GetPixOffset(); if (pixCurrent < 0) return; scrollViewElement->InitIterator(); cTemplatePixmap *pix = NULL; while(pix = scrollViewElement->GetNextPixmap()) { DrawPixmap(pixCurrent, pix); pixCurrent++; } } bool cView::ExecuteViewElement(eViewElement ve) { if (!tmplView) return false; bool doExecute = tmplView->ExecuteView(ve); if (!doExecute) return false; return tmplView->GetNumPixmapsViewElement(ve); } bool cView::DetachViewElement(eViewElement ve) { if (!tmplView) return false; return tmplView->DetachViewElement(ve); } bool cView::ViewElementScrolls(eViewElement ve) { if (scrollingPix < 0) return false; if (!tmplView) return false; cTemplateViewElement *viewElement = tmplView->GetViewElement(ve); if (!viewElement) return false; int pixStart = viewElement->GetPixOffset(); int numPixmaps = viewElement->GetNumPixmaps(); if ( (scrollingPix >= pixStart) && (scrollingPix < (pixStart + numPixmaps)) ) return true; return false; } cViewElement *cView::GetViewElement(eViewElement ve) { map < eViewElement, cViewElement* >::iterator hit = detachedViewElements.find(ve); if (hit == detachedViewElements.end()) return NULL; cViewElement *viewElement = hit->second; return viewElement; } void cView::AddViewElement(eViewElement ve, cViewElement *viewElement) { detachedViewElements.insert(pair< eViewElement, cViewElement* >(ve, viewElement)); } void cView::CreateViewPixmap(int num, cTemplatePixmap *pix, cRect *size) { cRect pixSize; if (size) { pixSize = *size; } else { pixSize = pix->GetPixmapSize(); } int layer = pix->GetNumericParameter(ptLayer); int transparency = pix->GetNumericParameter(ptTransparency); SetTransparency(num, transparency); CreatePixmap(num, layer, pixSize); } void cView::CreateScrollingPixmap(int num, cTemplatePixmap *pix, cSize &drawportSize) { cRect pixViewPort = pix->GetPixmapSize(); cRect drawPort; drawPort.SetX(0); drawPort.SetY(0); drawPort.SetWidth(drawportSize.Width()); drawPort.SetHeight(drawportSize.Height()); int layer = pix->GetNumericParameter(ptLayer); int transparency = pix->GetNumericParameter(ptTransparency); SetTransparency(num, transparency); CreatePixmap(num, layer, pixViewPort, drawPort); } void cView::DrawPixmap(int num, cTemplatePixmap *pix, map < string, vector< map< string, string > > > *loopTokens, bool flushPerLoop) { pix->InitIterator(); cTemplateFunction *func = NULL; while(func = pix->GetNextFunction()) { eFuncType type = func->GetType(); if (func->DoDebug()) { func->Debug(); } if (!func->DoExecute()) { continue; } switch (type) { case ftFill: DoFill(num, func); break; case ftDrawText: DoDrawText(num, func); break; case ftDrawTextVertical: DoDrawTextVertical(num, func); break; case ftDrawTextBox: { int floating = func->GetNumericParameter(ptFloat); if (floating > flNone) { DoDrawFloatingTextBox(num, func); } else { DoDrawTextBox(num, func); } break; } case ftDrawRectangle: DoDrawRectangle(num, func); break; case ftDrawEllipse: DoDrawEllipse(num, func); break; case ftDrawSlope: DoDrawSlope(num, func); break; case ftDrawImage: DoDrawImage(num, func); break; case ftLoop: if (loopTokens) DrawLoop(num, func, loopTokens); break; default: break; } if (flushPerLoop) { DoFlush(); } } } void cView::DrawLoop(int numPixmap, cTemplateFunction *func, map < string, vector< map< string, string > > > *loopTokens) { cTemplateLoopFunction *loopFunc = dynamic_cast(func); if (!loopFunc) return; int loopX0 = loopFunc->GetNumericParameter(ptX); if (loopX0 < 0) loopX0 = 0; int loopY0 = loopFunc->GetNumericParameter(ptY); if (loopY0 < 0) loopY0 = 0; int orientation = loopFunc->GetNumericParameter(ptOrientation); int loopWidth = loopFunc->GetNumericParameter(ptWidth); if (loopWidth <= 0) loopWidth = loopFunc->GetContainerWidth(); int loopHeight = loopFunc->GetNumericParameter(ptHeight); if (loopHeight <= 0) loopHeight = loopFunc->GetContainerHeight(); int columnWidth = loopFunc->GetNumericParameter(ptColumnWidth); int rowHeight = loopFunc->GetNumericParameter(ptRowHeight); int overflow = loopFunc->GetNumericParameter(ptOverflow); int x0 = loopX0; int y0 = loopY0; string loopTokenName = loopFunc->GetParameter(ptName); map < string, vector< map< string, string > > >::iterator hit = loopTokens->find(loopTokenName); if (hit == loopTokens->end()) return; vector< map > loopToken = hit->second; int lineNumber=0; for (vector< map >::iterator line = loopToken.begin(); line != loopToken.end(); line++) { //check overflow behaviour if (overflow == otCut) { if (orientation == orHorizontal) { if (lineNumber * columnWidth > loopWidth) { return; } } else if (orientation == orVertical) { if (lineNumber * rowHeight > loopHeight) { return; } } } else if (overflow == otWrap && orientation == orHorizontal) { if (x0 + columnWidth > loopWidth) { x0 = loopX0; if (rowHeight > 0) { y0 += rowHeight; } else { y0 += loopFunc->GetLoopElementsHeight(); } } } map tokens = *line; loopFunc->ClearDynamicParameters(); loopFunc->ParseDynamicParameters(&tokens); loopFunc->InitIterator(); cTemplateFunction *func = NULL; while(func = loopFunc->GetNextFunction()) { //do debug? if (func->DoDebug()) func->Debug(); //check if set condition is true if (!func->DoExecute()) { continue; } //execute eFuncType type = func->GetType(); switch (type) { case ftDrawText: DoDrawText(numPixmap, func, x0, y0); break; case ftDrawTextBox: DoDrawTextBox(numPixmap, func, x0, y0); break; case ftDrawRectangle: DoDrawRectangle(numPixmap, func, x0, y0); break; case ftDrawEllipse: DoDrawEllipse(numPixmap, func, x0, y0); break; case ftDrawSlope: DoDrawSlope(numPixmap, func, x0, y0); break; case ftDrawImage: DoDrawImage(numPixmap, func, x0, y0); break; default: break; } } //calculate position of next loop element if (orientation == orHorizontal) { if (columnWidth > 0) { x0 += columnWidth; } else { x0 += loopFunc->GetLoopElementsWidth(); } } else if (orientation == orVertical) { if (rowHeight > 0) { y0 += rowHeight; } else { y0 += loopFunc->GetLoopElementsHeight(); } } lineNumber++; //DoFlush(); } } void cView::DebugTokens(string viewElement, map *stringTokens, map *intTokens, map < string, vector< map< string, string > > > *loopTokens) { esyslog("skindesigner: ------------------------------ Tokens for %s:", viewElement.c_str()); if (stringTokens) { for (map::iterator st = stringTokens->begin(); st != stringTokens->end(); st++) { esyslog("skindesigner: string var \"%s\" = \"%s\"", (st->first).c_str(), (st->second).c_str()); } } if (intTokens) { for (map::iterator it = intTokens->begin(); it != intTokens->end(); it++) { esyslog("skindesigner: int var \"%s\" = %d", (it->first).c_str(), it->second); } } if (loopTokens) { for(map < string, vector< map< string, string > > >::iterator it1 = loopTokens->begin(); it1 != loopTokens->end(); it1++) { int line = 0; string tokenName = it1->first; vector< map > tokens = it1->second; esyslog("skindesigner: loop token %s", tokenName.c_str()); for (vector< map >::iterator it2 = tokens.begin(); it2 != tokens.end(); it2++) { esyslog("skindesigner: loop tokens line %d:", line++); map element = *it2; for (map::iterator el = element.begin(); el != element.end(); el++) { esyslog("skindesigner: name: %s, value: %s", (el->first).c_str(), (el->second).c_str()); } } } } } /***************************************************************** * Private Functions *****************************************************************/ void cView::DoFill(int num, cTemplateFunction *func) { tColor col = func->GetColorParameter(ptColor); Fill(num, col); } void cView::DoDrawText(int num, cTemplateFunction *func, int x0, int y0) { int x = func->GetNumericParameter(ptX); if (x < 0) x = 0; x += x0; int y = func->GetNumericParameter(ptY); if (y < 0) y = 0; y += y0; cPoint pos(x,y); string fontName = func->GetFontName(); int fontSize = func->GetNumericParameter(ptFontSize); tColor clr = func->GetColorParameter(ptColor); tColor clrBack = clrTransparent; string text = ""; if (!currentlyScrolling) { text = func->GetText(true); } else { text = func->GetText(false); } DrawText(num, pos, text.c_str(), clr, clrBack, fontName, fontSize); } void cView::DoDrawTextVertical(int num, cTemplateFunction *func, int x0, int y0) { string fontName = func->GetFontName(); int fontSize = func->GetNumericParameter(ptFontSize); int direction = func->GetNumericParameter(ptDirection); tColor clr = func->GetColorParameter(ptColor); string text = func->GetText(false); cImage *textVertical = imgCache->GetVerticalText(text, clr, fontName, fontSize, direction); if (!textVertical) return; //align has to be set here because here we know the image size int x = 0; int y = 0; int align = func->GetNumericParameter(ptAlign); if (align == alCenter) { int containerWidth = func->GetContainerWidth(); x = (containerWidth - textVertical->Width()) / 2; } else if (align == alLeft) { x = 0; } else if (align == alRight) { int containerWidth = func->GetContainerWidth(); x = (containerWidth - textVertical->Width()); } else { x = func->GetNumericParameter(ptX); } int valign = func->GetNumericParameter(ptValign); if (valign == alCenter) { int containerHeight = func->GetContainerHeight(); y = (containerHeight - textVertical->Height()) / 2; } else if (align == alTop) { y = 0; } else if (align == alBottom) { int containerHeight = func->GetContainerHeight(); y = (containerHeight - textVertical->Height()); } else { y = func->GetNumericParameter(ptY); } if (x < 0) x = 0; x += x0; if (y < 0) y = func->GetContainerHeight() - textVertical->Height() - 5; y += y0; cPoint pos(x,y); DrawImage(num, pos, *textVertical); } void cView::DoDrawTextBox(int num, cTemplateFunction *func, int x0, int y0) { string text = func->GetText(false); if (text.size() < 3) return; int x = func->GetNumericParameter(ptX); int y = func->GetNumericParameter(ptY); if (x < 0) x = 0; x += x0; if (y < 0) y = 0; y += y0; int width = func->GetNumericParameter(ptWidth); int height = func->GetNumericParameter(ptHeight); string fontName = func->GetFontName(); int fontSize = func->GetNumericParameter(ptFontSize); int align = func->GetNumericParameter(ptAlign); int maxLines = func->GetNumericParameter(ptMaxLines); tColor clr = func->GetColorParameter(ptColor); tColor clrBack = clrTransparent; const cFont *font = fontManager->Font(fontName, fontSize); if (!font) return; cTextWrapper wrapper; wrapper.Set(text.c_str(), font, width); int fontHeight = fontManager->Height(fontName, fontSize); int lines = wrapper.Lines(); int yLine = y; for (int line=0; line < lines; line++) { int xLine = x; if (align == alCenter) { int textWidth = font->Width(wrapper.GetLine(line)); xLine += (width - textWidth)/2; } else if (align == alRight) { int textWidth = font->Width(wrapper.GetLine(line)); xLine += (width - textWidth); } cPoint pos(xLine, yLine); if (maxLines > 0 && line == maxLines-1) { string lastLine = wrapper.GetLine(line); if (lines > maxLines) { lastLine += "..."; } DrawText(num, pos, lastLine.c_str(), clr, clrBack, fontName, fontSize); break; } else if (height > 0 && yLine - y + 2*fontHeight > height) { DrawText(num, pos, "...", clr, clrBack, fontName, fontSize); break; } DrawText(num, pos, wrapper.GetLine(line), clr, clrBack, fontName, fontSize); yLine += fontHeight; } } void cView::DoDrawFloatingTextBox(int num, cTemplateFunction *func) { string text = func->GetText(false); if (text.size() < 3) return; int x = func->GetNumericParameter(ptX); int y = func->GetNumericParameter(ptY); if (x < 0) x = 0; if (y < 0) y = 0; int width = func->GetNumericParameter(ptWidth); int height = func->GetNumericParameter(ptHeight); string fontName = func->GetFontName(); int fontSize = func->GetNumericParameter(ptFontSize); tColor clr = func->GetColorParameter(ptColor); tColor clrBack = clrTransparent; const cFont *font = fontManager->Font(fontName, fontSize); if (!font) return; int floatType = func->GetNumericParameter(ptFloat); int floatWidth = func->GetNumericParameter(ptFloatWidth); int floatHeight = func->GetNumericParameter(ptFloatHeight); cTextWrapper wTextTall; cTextWrapper wTextFull; int fontHeight = fontManager->Height(fontName, fontSize); int linesNarrow = floatHeight / fontHeight; int widthNarrow = width - floatWidth; int linesDrawn = 0; int curY = 0; bool drawNarrow = true; splitstring s(text.c_str()); std::vector flds = s.split('\n', 1); if (flds.size() < 1) return; std::stringstream sstrTextTall; std::stringstream sstrTextFull; for (int i=0; i < (int)flds.size(); i++) { if (!flds[i].size()) { //empty line linesDrawn++; curY += fontHeight; if (drawNarrow) sstrTextTall << "\n"; else sstrTextFull << "\n"; } else { cTextWrapper wrapper; if (drawNarrow) { wrapper.Set((flds[i].c_str()), font, widthNarrow); int newLines = wrapper.Lines(); //check if wrapper fits completely into narrow area if (linesDrawn + newLines < linesNarrow) { for (int line = 0; line < wrapper.Lines(); line++) { sstrTextTall << wrapper.GetLine(line) << " "; } sstrTextTall << "\n"; linesDrawn += newLines; } else { //this wrapper has to be splitted for (int line = 0; line < wrapper.Lines(); line++) { if (line + linesDrawn < linesNarrow) { sstrTextTall << wrapper.GetLine(line) << " "; } else { sstrTextFull << wrapper.GetLine(line) << " "; } } sstrTextFull << "\n"; drawNarrow = false; } } else { wrapper.Set((flds[i].c_str()), font, width); for (int line = 0; line < wrapper.Lines(); line++) { sstrTextFull << wrapper.GetLine(line) << " "; } sstrTextFull << "\n"; } } } //VDRs textwrapper swallows linebreaks at the end, so we have to fix that manually string textTall = sstrTextTall.str(); size_t posLastCarriageReturn = textTall.find_last_not_of("\n"); int numLinesToAddAtTall = 0; if (posLastCarriageReturn != string::npos && (posLastCarriageReturn < textTall.size() - 1)) { numLinesToAddAtTall = textTall.size() - posLastCarriageReturn - 2; } wTextTall.Set(textTall.c_str(), font, widthNarrow); wTextFull.Set(sstrTextFull.str().c_str(), font, width); int textLinesTall = wTextTall.Lines(); int textLinesFull = wTextFull.Lines(); int textXTall = x; if (floatType == flTopLeft) textXTall = x + floatWidth; int yLine = y; for (int line=0; line < textLinesTall; line++) { cPoint pos(textXTall, yLine); DrawText(num, pos, wTextTall.GetLine(line), clr, clrBack, fontName, fontSize); yLine += fontHeight; } if (numLinesToAddAtTall) { yLine += numLinesToAddAtTall * fontHeight; } for (int line=0; line < textLinesFull; line++) { cPoint pos(x, yLine); if (height > 0 && yLine - y + 2*fontHeight > height) { DrawText(num, pos, "...", clr, clrBack, fontName, fontSize); break; } DrawText(num, pos, wTextFull.GetLine(line), clr, clrBack, fontName, fontSize); yLine += fontHeight; } } void cView::DoDrawRectangle(int num, cTemplateFunction *func, int x0, int y0) { int x = func->GetNumericParameter(ptX); int y = func->GetNumericParameter(ptY); if (x < 0) x = 0; x += x0; if (y < 0) y = 0; y += y0; int w = func->GetNumericParameter(ptWidth); int h = func->GetNumericParameter(ptHeight); cRect size(x, y, w, h); tColor clr = func->GetColorParameter(ptColor); DrawRectangle(num, size, clr); } void cView::DoDrawEllipse(int num, cTemplateFunction *func, int x0, int y0) { int x = func->GetNumericParameter(ptX); int y = func->GetNumericParameter(ptY); if (x < 0) x = 0; x += x0; if (y < 0) y = 0; y += y0; int w = func->GetNumericParameter(ptWidth); int h = func->GetNumericParameter(ptHeight); cRect size(x, y, w, h); tColor clr = func->GetColorParameter(ptColor); int quadrant = func->GetNumericParameter(ptQuadrant); if (quadrant < -4 || quadrant > 8) { esyslog("skindesigner: wrong quadrant %d for drawellipse, allowed values are from -4 to 8", quadrant); quadrant = 0; } DrawEllipse(num, size, clr, quadrant); } void cView::DoDrawSlope(int num, cTemplateFunction *func, int x0, int y0) { int x = func->GetNumericParameter(ptX); int y = func->GetNumericParameter(ptY); if (x < 0) x = 0; x += x0; if (y < 0) y = 0; y += y0; int w = func->GetNumericParameter(ptWidth); int h = func->GetNumericParameter(ptHeight); cRect size(x, y, w, h); tColor clr = func->GetColorParameter(ptColor); int type = func->GetNumericParameter(ptType); if (type < 0 || type > 7) { esyslog("skindesigner: wrong type %d for drawslope, allowed values are from 0 to 7", type); type = 0; } DrawSlope(num, size, clr, type); } void cView::DoDrawImage(int num, cTemplateFunction *func, int x0, int y0) { int x = func->GetNumericParameter(ptX); int y = func->GetNumericParameter(ptY); if (x < 0) x = 0; x += x0; if (y < 0) y = 0; y += y0; cPoint pos(x,y); int width = func->GetNumericParameter(ptWidth); int height = func->GetNumericParameter(ptHeight); string path = func->GetImagePath(); eImageType type = (eImageType)func->GetNumericParameter(ptImageType); switch (type) { case itChannelLogo: { cImage *logo = imgCache->GetLogo(path, width, height); if (logo) { DrawImage(num, pos, *logo); } break; } case itSepLogo: { cImage *sepLogo = imgCache->GetSeparatorLogo(path, width, height); if (sepLogo) { DrawImage(num, pos, *sepLogo); } break; } case itSkinPart: { cImage *skinpart = imgCache->GetSkinpart(path, width, height); if (skinpart) { DrawImage(num, pos, *skinpart); } break; } case itIcon: { cImage *icon = imgCache->GetIcon(type, path, width, height); if (icon) { DrawImage(num, pos, *icon); } break; } case itMenuIcon: { cImage *icon = imgCache->GetIcon(type, path, width, height); if (icon) { DrawImage(num, pos, *icon); } break; } case itImage: { cImageLoader imgLoader; if (imgLoader.LoadImage(path.c_str())) { cImage *image = imgLoader.CreateImage(width, height); DrawImage(num, pos, *image); delete(image); } break; } default: break; } } /*********************************************************************** * cViewElement ************************************************************************/ cViewElement::cViewElement(cTemplateViewElement *tmplViewElement) : cView(tmplViewElement) { tmplViewElement->SetPixOffset(0); delay = tmplViewElement->GetNumericParameter(ptDelay); SetFadeTime(tmplViewElement->GetNumericParameter(ptFadeTime)); } cViewElement::~cViewElement() { CancelSave(); } void cViewElement::Action(void) { SetInitFinished(); DoSleep(delay); Render(); FadeIn(); DoFlush(); if (scrolling) { DoSleep(scrollDelay); if (scrollOrientation == orHorizontal) { ScrollHorizontal(scrollingPix, scrollDelay, scrollSpeed, scrollMode); } else { ScrollVertical(scrollingPix, scrollDelay, scrollSpeed); } } } void cViewElement::ClearTokens(void) { stringTokens.clear(); intTokens.clear(); } /*********************************************************************** * cViewListItem ************************************************************************/ cViewListItem::cViewListItem(cTemplateViewElement *tmplItem) : cView(tmplItem) { pos = -1; numTotal = 0; align = alLeft; listOrientation = orVertical; } cViewListItem::~cViewListItem() { } cRect cViewListItem::DrawListItem(map *stringTokens, map *intTokens) { cRect posItem; if (!tmplViewElement) return posItem; if (tmplViewElement->DebugTokens()) { DebugTokens("ListItem", stringTokens, intTokens); } tmplViewElement->InitIterator(); cTemplatePixmap *pix = NULL; int pixCurrent = 0; while(pix = tmplViewElement->GetNextPixmap()) { SetListElementPosition(pix); if (pixCurrent == 0) { posItem = pix->GetPixmapSize(); } if (!PixmapExists(pixCurrent)) { pix->ParseDynamicParameters(intTokens, true); } else { pix->ParseDynamicParameters(intTokens, false); } if (!PixmapExists(pixCurrent) && pix->Ready() && pix->DoExecute() && !pix->Scrolling()) { CreateViewPixmap(pixCurrent, pix); } //if pixmap still not valid, skip if (!pix->Ready() && !pix->Scrolling()) { pixCurrent++; continue; } //if condition for pixmap set, check if cond is true if (!pix->DoExecute()) { pixCurrent++; continue; } pix->ClearDynamicFunctionParameters(); pix->ParseDynamicFunctionParameters(stringTokens, intTokens); if (!PixmapExists(pixCurrent) && pix->Scrolling()) { cSize drawportSize; scrolling = pix->CalculateDrawPortSize(drawportSize); pix->SetScrollingTextWidth(); if (scrolling) { CreateScrollingPixmap(pixCurrent, pix, drawportSize); scrollingPix = pixCurrent; scrollOrientation = pix->GetNumericParameter(ptOrientation); scrollMode = pix->GetNumericParameter(ptScrollMode); scrollDelay = pix->GetNumericParameter(ptDelay); scrollSpeed = pix->GetNumericParameter(ptScrollSpeed); } else { CreateViewPixmap(pixCurrent, pix); } } if (pix->DoDebug()) { pix->Debug(); } DrawPixmap(pixCurrent, pix); pixCurrent++; } return posItem; } void cViewListItem::ClearListItem(void) { int pixMax = NumPixmaps(); for (int pixCurrent = 0; pixCurrent < pixMax; pixCurrent++) { Fill(pixCurrent, clrTransparent); } } void cViewListItem::SetListElementPosition(cTemplatePixmap *pix) { int itemWidth = pix->GetNumericParameter(ptWidth); int itemHeight = pix->GetNumericParameter(ptHeight); int x = 0; int y = 0; if (listOrientation == orHorizontal) { x = container.X(); int totalWidth = numTotal * itemWidth; if (align == alCenter) { y += (container.Width() - totalWidth) / 2; } else if (align == alBottom) { y += (container.Width() - totalWidth); } x += pos * itemWidth; y = pix->GetNumericParameter(ptY); } else if (listOrientation == orVertical) { y = container.Y(); int totalHeight = numTotal * itemHeight; if (align == alCenter) { y += (container.Height() - totalHeight) / 2; } else if (align == alBottom) { y += (container.Height() - totalHeight); } y += pos * itemHeight; x = pix->GetNumericParameter(ptX); } pix->SetX(x); pix->SetY(y); } /*********************************************************************** * cGrid ************************************************************************/ cGrid::cGrid(cTemplateViewElement *tmplGrid) : cView(tmplGrid) { dirty = true; moved = true; resized = true; current = false; x = 0.0; y = 0.0; width = 0.0; height = 0.0; } cGrid::~cGrid() { } void cGrid::Set(double x, double y, double width, double height, map *intTokens, map *stringTokens) { if ((width != this->width) || (height != this->height)) { this->width = width; this->height = height; resized = true; dirty = false; } else { resized = false; } if (this->x != x || this->y != y) { this->x = x; this->y = y; moved = true; } else { moved = false; } if (intTokens) { this->intTokens = *intTokens; SetCurrent(current); dirty = true; } if (stringTokens) { this->stringTokens = *stringTokens; dirty = true; } } void cGrid::SetCurrent(bool current) { this->current = current; if (!resized) dirty = true; intTokens.erase("current"); intTokens.insert(pair("current", current)); } void cGrid::Move(void) { if (!tmplViewElement) return; tmplViewElement->InitIterator(); cTemplatePixmap *pix = NULL; int pixCurrent = 0; while(pix = tmplViewElement->GetNextPixmap()) { PositionPixmap(pix); cRect pixViewPort = pix->GetPixmapSize(); SetViewPort(pixCurrent, pixViewPort); pixCurrent++; } dirty = false; resized = false; moved = false; } void cGrid::Draw(void) { if (!tmplViewElement) return; if (tmplViewElement->DebugTokens()) { DebugTokens("Grid", &stringTokens, &intTokens); } tmplViewElement->InitIterator(); cTemplatePixmap *pix = NULL; int pixCurrent = 0; while(pix = tmplViewElement->GetNextPixmap()) { PositionPixmap(pix); if (!PixmapExists(pixCurrent)) { pix->ParseDynamicParameters(&intTokens, true); } else { pix->ParseDynamicParameters(&intTokens, false); } if (!PixmapExists(pixCurrent) && pix->Ready() && pix->DoExecute() && !pix->Scrolling()) { CreateViewPixmap(pixCurrent, pix); } //if pixmap still not valid, skip if (!pix->Ready() && !pix->Scrolling()) { pixCurrent++; continue; } //if condition for pixmap set, check if cond is true if (!pix->DoExecute()) { pixCurrent++; continue; } pix->ClearDynamicFunctionParameters(); pix->ParseDynamicFunctionParameters(&stringTokens, &intTokens); //pix->Debug(); DrawPixmap(pixCurrent, pix); pixCurrent++; } dirty = false; resized = false; moved = false; } void cGrid::Clear(void) { int pixMax = NumPixmaps(); for (int pixCurrent = 0; pixCurrent < pixMax; pixCurrent++) { Fill(pixCurrent, clrTransparent); } } void cGrid::DeletePixmaps(void) { int pixMax = NumPixmaps(); for (int pixCurrent = 0; pixCurrent < pixMax; pixCurrent++) { DestroyPixmap(pixCurrent); } } void cGrid::PositionPixmap(cTemplatePixmap *pix) { pix->SetXPercent(x); pix->SetYPercent(y); pix->SetWidthPercent(width); pix->SetHeightPercent(height); pix->CalculateParameters(); }