diff --git a/HISTORY b/HISTORY index b38439f..6611bea 100644 --- a/HISTORY +++ b/HISTORY @@ -124,9 +124,17 @@ Version 1.2.0 - fixed a bug when scrolling page up and the menu footer is active - order of search timers in search timer list in alphabetical order - changed order of actions on search timer menu items + +Version 1.2.1 + - changed event result lists that it is possible to scroll page up and down directly with left / right. A recording is triggered now with the red key. - Added possibility to create a recording from search timer result list - Set minimum time to display in Plugin Setup from 120 to 60 minutes - made order of search timer list case insensitive + +Version 1.2.2 + +- added scraper2vdr support +- introduced tabbed EPG detail view diff --git a/Makefile b/Makefile index 9e69308..27f6838 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ endif ### The object files (add further files here): -OBJS = $(PLUGIN).o channelcolumn.o channelgroup.o channelgroups.o channeljump.o config.o detailview.o dummygrid.o epggrid.o fontmanager.o footer.o geometrymanager.o grid.o headergrid.o imagecache.o imageloader.o imagemagickwrapper.o imagescaler.o osdmanager.o recmanager.o recmenu.o recmenuitem.o recmenumanager.o recmenus.o searchtimer.o setup.o statusheader.o styledpixmap.o switchtimer.o timeline.o timer.o timerconflict.o tools.o tvguideosd.o +OBJS = $(PLUGIN).o channelcolumn.o channelgroup.o channelgroups.o channeljump.o config.o detailview.o dummygrid.o epggrid.o fontmanager.o footer.o geometrymanager.o grid.o headergrid.o imagecache.o imageloader.o imagemagickwrapper.o imagescaler.o osdmanager.o recmanager.o recmenu.o recmenuitem.o recmenumanager.o recmenus.o searchtimer.o setup.o statusheader.o styledpixmap.o switchtimer.o timeline.o timer.o timerconflict.o tools.o tvguideosd.o view.o ### The main target: diff --git a/config.c b/config.c index 054b9be..76d01c7 100644 --- a/config.c +++ b/config.c @@ -44,6 +44,7 @@ cTvguideConfig::cTvguideConfig() { numAdditionalEPGPictures = 9; epgImageWidthLarge = 525; epgImageHeightLarge = 400; + detailedViewScrollStep = 5; instRecFolderMode = eFolderRoot; instRecFixedFolder = ""; favWhatsOnNow = 1; @@ -272,6 +273,7 @@ bool cTvguideConfig::SetupParse(const char *Name, const char *Value) { else if (strcmp(Name, "numAdditionalEPGPictures") == 0) numAdditionalEPGPictures = atoi(Value); else if (strcmp(Name, "epgImageWidthLarge") == 0) epgImageWidthLarge = atoi(Value); else if (strcmp(Name, "epgImageHeightLarge") == 0) epgImageHeightLarge = atoi(Value); + else if (strcmp(Name, "detailedViewScrollStep") == 0) detailedViewScrollStep = atoi(Value); else if (strcmp(Name, "timeLineWidthPercent") == 0) timeLineWidthPercent = atoi(Value); else if (strcmp(Name, "timeLineHeightPercent") == 0) timeLineHeightPercent = atoi(Value); else if (strcmp(Name, "displayChannelName") == 0) displayChannelName = atoi(Value); diff --git a/config.h b/config.h index 6535ae9..7ebb49f 100644 --- a/config.h +++ b/config.h @@ -93,6 +93,7 @@ class cTvguideConfig { int numAdditionalEPGPictures; int epgImageWidthLarge; int epgImageHeightLarge; + int detailedViewScrollStep; cString epgImagePath; cString iconPath; cString logoPathDefault; @@ -221,7 +222,8 @@ THEME_CLR(theme, clrTimeline1Blending, 0xFF828282); THEME_CLR(theme, clrTimeline2, clrBlack); THEME_CLR(theme, clrTimeline2Blending, 0xFF3F3F3F); THEME_CLR(theme, clrTimeBase, 0xA0FF0000); -THEME_CLR(theme, clrButtonRed, 0x00000000); +THEME_CLR(theme, clrTabInactive, 0xA01F3D7A); +THEME_CLR(theme, clrButtonRed, 0xFFFF0000); THEME_CLR(theme, clrButtonRedBorder, 0x00000000); THEME_CLR(theme, clrButtonGreen, 0x00000000); THEME_CLR(theme, clrButtonGreenBorder, 0x00000000); diff --git a/detailview.c b/detailview.c index 3a93b9d..ca351ab 100644 --- a/detailview.c +++ b/detailview.c @@ -1,650 +1,154 @@ -#include -#include -#include "imageloader.h" -#include "imagecache.h" -#include "services/epgsearch.h" -#include "services/remotetimers.h" -#include "config.h" -#include "tools.h" #include "detailview.h" cDetailView::cDetailView(const cEvent *event, cFooter *footer) { this->event = event; this->footer = footer; - imgScrollBar = NULL; - border = tvguideConfig.epgViewBorder; //px, border in view window - scrollBarWidth = 40; - headerWidth = geoManager.headerContentWidth; - headerHeight = geoManager.epgViewHeaderHeight; - pixmapPoster = NULL; - width = geoManager.osdWidth; - contentWidth = width - scrollBarWidth; - contentX = 0; - contentHeight = geoManager.osdHeight - headerHeight - geoManager.footerHeight; - widthPoster = 30 * contentWidth / 100; } cDetailView::~cDetailView(void){ Cancel(-1); while (Active()) cCondWait::SleepMs(10); - osdManager.releasePixmap(back); - delete header; - header = NULL; - osdManager.releasePixmap(headerLogo); - headerLogo = NULL; - osdManager.releasePixmap(content); - content = NULL; - if (pixmapPoster) - osdManager.releasePixmap(pixmapPoster); - pixmapPoster = NULL; - osdManager.releasePixmap(scrollBar); - scrollBar = NULL; - delete imgScrollBar; footer->LeaveDetailedViewMode(Channels.GetByChannelID(event->ChannelID())); + if (view) + delete view; } -void cDetailView::setContent() { - hasAdditionalMedia = false; - static cPlugin *pTVScraper = cPluginManager::GetPlugin("tvscraper"); - if (pTVScraper) { - mediaInfo.event = event; - mediaInfo.isRecording = false; - if (pTVScraper->Service("TVScraperGetFullInformation", &mediaInfo)) { - hasAdditionalMedia = true; - } - } - if (hasAdditionalMedia) { - if (mediaInfo.posters.size() >= 1) { - contentWidth -= widthPoster; - contentX += widthPoster; - } - } - description.Set(event->Description(), fontManager.FontDetailView, contentWidth - scrollBarWidth - 2*border); - if (tvguideConfig.displayRerunsDetailEPGView) { - loadReruns(); - } - numEPGPics = 0; - contentScrollable = setContentDrawportHeight(); - createPixmaps(); -} - -bool cDetailView::setContentDrawportHeight() { - int lineHeight = fontManager.FontDetailView->Height(); - //Height of banner (only for series) - int heightBanner = 0; - if (hasAdditionalMedia && (mediaInfo.type == typeSeries)) { - heightBanner = mediaInfo.banner.height + 2*lineHeight; - } - //Height of EPG Text - int heightEPG = (description.Lines()+1) * lineHeight; - //Height of rerun information - int heightReruns = 0; - if (tvguideConfig.displayRerunsDetailEPGView) { - heightReruns = (reruns.Lines()+1) * lineHeight; - } - //Height of actor pictures - int heightActors = 0; - if (hasAdditionalMedia) { - heightActors = heightActorPics(); - } - //Height of fanart - int heightFanart = 0; - if (hasAdditionalMedia) { - heightFanart = heightFanartImg() + lineHeight; - } - //Height of EPG Pictures - int heightEpgPics = 0; - if (!tvguideConfig.hideEpgImages) { - heightEpgPics = heightEPGPics(); - } - - yBanner = border; - yEPGText = yBanner + heightBanner; - yAddInf = yEPGText + heightEPG; - yActors = yAddInf + heightReruns; - yFanart = yActors + heightActors; - yEPGPics = yFanart + heightFanart; - - int totalHeight = heightBanner + heightEPG + heightReruns + heightActors + heightFanart + heightEpgPics + lineHeight; - //check if pixmap content has to be scrollable - if (totalHeight > contentHeight) { - heightContent = totalHeight; - return true; - } else { - heightContent = contentHeight; - return false; - } - return false; -} - -void cDetailView::createPixmaps() { - back = osdManager.requestPixmap(3, cRect(0, 0, width, headerHeight + contentHeight), cRect::Null); - back->Fill(clrBlack); - header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(0, 0, headerWidth, headerHeight), cRect::Null)); - headerLogo = osdManager.requestPixmap(6, cRect(0, 0, width, headerHeight), cRect::Null); - headerLogo->Fill(clrTransparent); - header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); - content = osdManager.requestPixmap(5, cRect(contentX, headerHeight, contentWidth, contentHeight), - cRect(0,0, contentWidth, max(heightContent, contentHeight))); - if (hasAdditionalMedia) { - pixmapPoster = osdManager.requestPixmap(4, cRect(0, 0 + headerHeight, widthPoster, contentHeight)); - pixmapPoster->Fill(theme.Color(clrBorder)); - pixmapPoster->DrawRectangle(cRect(2, 0, widthPoster - 2, content->DrawPort().Height()), theme.Color(clrBackground)); - } - scrollBar = osdManager.requestPixmap(5, cRect(geoManager.osdWidth - scrollBarWidth, headerHeight, scrollBarWidth, contentHeight)); -} - -void cDetailView::drawHeader() { - header->Fill(clrTransparent); - if (tvguideConfig.style == eStyleGraphical) { - if (tvguideConfig.scaleVideo) { - header->drawBackgroundGraphical(bgStatusHeaderWindowed); - } else { - header->drawBackgroundGraphical(bgStatusHeaderFull); +void cDetailView::InitiateView(void) { + static cPlugin *pScraper2Vdr = cPluginManager::GetPlugin("scraper2vdr"); + ScraperGetEventType call; + if (!event) + return; + call.event = event; + if (!pScraper2Vdr) { + view = new cEPGView(); + } else if (pScraper2Vdr->Service("GetEventType", &call)) { + if (call.type == tMovie) { + view = new cMovieView(call.movieId); + } else if (call.type == tSeries) { + view = new cSeriesView(call.seriesId, call.episodeId); } } else { - header->drawBackground(); - header->drawBoldBorder(); + view = new cEPGView(); } - if (tvguideConfig.scaleVideo) { - back->DrawRectangle(cRect(headerWidth, 0, geoManager.tvFrameWidth, headerHeight), clrTransparent); - } - tColor colorTextBack = (tvguideConfig.style == eStyleFlat)?theme.Color(clrHeader):clrTransparent; - int logoHeight = 2 * header->Height() / 3; - int logoWidth = logoHeight * tvguideConfig.logoWidthRatio / tvguideConfig.logoHeightRatio; - int lineHeight = fontManager.FontDetailHeader->Height(); - cImageLoader imgLoader; - bool logoDrawn = false; - if (!tvguideConfig.hideChannelLogos) { - const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); - if (imgLoader.LoadLogo(channel, logoWidth, logoHeight)) { - cImage logo = imgLoader.GetImage(); - headerLogo->DrawImage(cPoint(10, (header->Height() - logoHeight)/2), logo); - logoDrawn = true; - } - } - - bool epgImageDrawn = false; - int epgImageWidth = 0; - if (!tvguideConfig.hideEpgImages) { - int epgImageHeight = 3 * headerHeight / 4; - if (tvguideConfig.epgImageHeight > 0) - epgImageWidth = epgImageHeight * tvguideConfig.epgImageWidth / tvguideConfig.epgImageHeight; - if (imgLoader.LoadEPGImage(event->EventID(), epgImageWidth, epgImageHeight)) { - cImage epgImage = imgLoader.GetImage(); - int epgImageX = headerWidth - border - epgImageWidth; - int epgImageY = (headerHeight - epgImageHeight) / 2; - header->DrawRectangle(cRect(epgImageX-2, epgImageY-2, epgImageWidth + 4, epgImageHeight + 4), theme.Color(clrBorder)); - header->DrawImage(cPoint(epgImageX, epgImageY), epgImage); - epgImageDrawn = true; - } - } - int textX = logoDrawn?(border + logoWidth + 5):border; - int textY = (headerHeight - 7*lineHeight/2)/2; - int maxTextWidth = headerWidth - 2 * border; - if (logoDrawn) - maxTextWidth -= logoWidth; - if (epgImageDrawn) - maxTextWidth -= epgImageWidth; - std::string title = CutText((event->Title())?event->Title():"", maxTextWidth, fontManager.FontDetailHeader); - header->DrawText(cPoint(textX, textY), title.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailHeader); - std::string datetime = *cString::sprintf("%s, %s - %s (%d min)", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString(), event->Duration()/60); - datetime = CutText(datetime, maxTextWidth, fontManager.FontDetailView); - textY += 5*lineHeight/4; - header->DrawText(cPoint(textX, textY), datetime.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView); - std::string shortText = CutText((event->ShortText())?event->ShortText():"", maxTextWidth, fontManager.FontDetailView); - textY += 5*lineHeight/4; - header->DrawText(cPoint(textX, textY), shortText.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView); - - eTimerMatch timerMatch=tmNone; - cTimer *ti; - if (tvguideConfig.useRemoteTimers && pRemoteTimers) { - RemoteTimers_GetMatch_v1_0 rtMatch; - rtMatch.event = event; - pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); - timerMatch = (eTimerMatch)rtMatch.timerMatch; - ti = rtMatch.timer; + view->SetTitle(event->Title()); + view->SetSubTitle(event->ShortText()); + view->SetInfoText(event->Description()); + cString dateTime; + time_t vps = event->Vps(); + if (vps) { + dateTime = cString::sprintf("%s %s - %s (%d %s) VPS: %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString(), event->Duration()/60, tr("min"), *TimeString(vps)); } else { - ti=Timers.GetMatch(event, &timerMatch); - } - if (timerMatch == tmFull) { - drawRecIcon(); + dateTime = cString::sprintf("%s %s - %s (%d %s)", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString(), event->Duration()/60, tr("min")); } + view->SetDateTime(*dateTime); + view->SetChannel(Channels.GetByChannelID(event->ChannelID(), true)); + view->SetEventID(event->EventID()); + view->SetEvent(event); } -void cDetailView::drawRecIcon(void) { - cString recIconText(" REC "); - int widthIcon = fontManager.FontDetailHeader->Width(*recIconText); - int height = fontManager.FontDetailHeader->Height()+10; - int posX = headerWidth - widthIcon - 20; - int posY = 20; - header->DrawRectangle( cRect(posX, posY, widthIcon, height), theme.Color(clrButtonRed)); - header->DrawText(cPoint(posX, posY+5), *recIconText, theme.Color(clrFont), theme.Color(clrButtonRed), fontManager.FontDetailHeader); -} - -void cDetailView::drawContent() { - content->Fill(theme.Color(clrBorder)); - content->DrawRectangle(cRect(2, 0, content->ViewPort().Width() - 2, content->DrawPort().Height()), theme.Color(clrBackground)); - tColor colorTextBack = (tvguideConfig.style == eStyleFlat)?theme.Color(clrBackground):clrTransparent; +std::string cDetailView::LoadReruns(void) { + if (!event) + return ""; - int textHeight = fontManager.FontDetailView->Height(); - int textLines = description.Lines(); - for (int i=0; iDrawText(cPoint(border, yEPGText + i*textHeight), description.GetLine(i), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView); + cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch"); + if (!epgSearchPlugin) + return ""; + + if (isempty(event->Title())) + return ""; + + std::stringstream sstrReruns; + sstrReruns << tr("Reruns of ") << "\"" << event->Title() << "\":" << std::endl << std::endl; + + Epgsearch_searchresults_v1_0 data; + std::string strQuery = event->Title(); + + if (tvguideConfig.displayRerunsDetailEPGView > 0) { + if (tvguideConfig.useSubtitleRerun == 2 && !isempty(event->ShortText())) { + strQuery += "~"; + strQuery += event->ShortText(); + } + data.useSubTitle = true; + } else { + data.useSubTitle = false; } - if (tvguideConfig.displayRerunsDetailEPGView) { - textLines = reruns.Lines(); - for (int j=0; jDrawText(cPoint(border, yAddInf + j*textHeight), reruns.GetLine(j), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView); + data.query = (char *)strQuery.c_str(); + data.mode = 0; + data.channelNr = 0; + data.useTitle = true; + data.useDescription = false; + + bool foundRerun = false; + if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) { + cList* list = data.pResultList; + if (list && (list->Count() > 1)) { + foundRerun = true; + int i = 0; + for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = list->First(); r && i < tvguideConfig.numReruns; r = list->Next(r)) { + if ((event->ChannelID() == r->event->ChannelID()) && (event->StartTime() == r->event->StartTime())) + continue; + i++; + sstrReruns << *DayDateTime(r->event->StartTime()); + cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); + if (channel) { + sstrReruns << ", " << trVDR("Channel") << " " << channel->Number() << ":"; + sstrReruns << " " << channel->ShortName(true); + } + sstrReruns << "\n" << r->event->Title(); + if (!isempty(r->event->ShortText())) + sstrReruns << "~" << r->event->ShortText(); + sstrReruns << std::endl << std::endl; + } + delete list; } } + + if (!foundRerun) { + sstrReruns << std::endl << tr("No reruns found"); + } + return sstrReruns.str(); } + void cDetailView::Action(void) { - if (hasAdditionalMedia && Running()) { - drawPoster(); - if (Running()) - osdManager.flush(); - } - //draw banner only for series - if (hasAdditionalMedia && (mediaInfo.type == typeSeries) && Running()) { - drawBanner(yBanner); - if (Running()) - osdManager.flush(); - } - //draw actors - if (hasAdditionalMedia && Running()) { - drawActors(yActors); - if (Running()) - osdManager.flush(); - } - //draw fanart - if (hasAdditionalMedia && Running()) { - drawFanart(yFanart); - if (Running()) - osdManager.flush(); - } - if (!tvguideConfig.hideEpgImages && Running()) { - drawEPGPictures(yEPGPics); - if (Running()) - osdManager.flush(); - } -} - -void cDetailView::drawScrollbar() { - scrollBar->Fill(theme.Color(clrBorder)); - double scrollBarOffset = 0.0; - if (contentScrollable) { - heightScrollbar = ( (double)scrollBar->ViewPort().Height() ) / (double)heightContent * ( (double)scrollBar->ViewPort().Height() ); - scrollBarOffset = (-1.0)*(double)content->DrawPort().Point().Y() / (double)(content->DrawPort().Height() - (contentHeight)); - scrollBarOffset *= ( (double)scrollBar->ViewPort().Height()-7.0 - heightScrollbar); - scrollBarOffset++; - } else { - heightScrollbar = scrollBar->ViewPort().Height(); - } - scrollBar->DrawRectangle(cRect(3,0,scrollBar->ViewPort().Width()-6, scrollBar->ViewPort().Height()), theme.Color(clrBackground)); - if (imgScrollBar == NULL) { - imgScrollBar = createScrollbar(scrollBar->ViewPort().Width()-10, heightScrollbar, theme.Color(clrHighlight), theme.Color(clrHighlightBlending)); - } - scrollBar->DrawImage(cPoint(5, 2 + scrollBarOffset), *imgScrollBar); -} - -void cDetailView::scrollUp() { - if (contentScrollable) { - int newDrawportHeight = content->DrawPort().Point().Y() + fontManager.FontDetailView->Height(); - content->SetDrawPortPoint(cPoint(0, min(newDrawportHeight,0))); - drawScrollbar(); - } -} - -void cDetailView::scrollDown() { - if (contentScrollable) { - int newDrawportHeight = content->DrawPort().Point().Y() - fontManager.FontDetailView->Height(); - int maxDrawportHeight = (content->DrawPort().Height() - contentHeight); - content->SetDrawPortPoint(cPoint(0, max(newDrawportHeight,(-1)*maxDrawportHeight))); - drawScrollbar(); - } -} - -void cDetailView::pageUp() { - if (contentScrollable) { - int aktHeight = (-1)*content->DrawPort().Point().Y(); - int totalHeight = content->DrawPort().Height(); - int screenHeight = content->ViewPort().Height(); - int newHeight = max(aktHeight - screenHeight, 0); - content->SetDrawPortPoint(cPoint(0, (-1)*newHeight)); - drawScrollbar(); - } -} - -void cDetailView::pageDown() { - if (contentScrollable) { - int aktHeight = (-1)*content->DrawPort().Point().Y(); - int totalHeight = content->DrawPort().Height(); - int screenHeight = content->ViewPort().Height(); - int newHeight = min(aktHeight + screenHeight, totalHeight - screenHeight); - content->SetDrawPortPoint(cPoint(0, (-1)*newHeight)); - drawScrollbar(); - } -} - -cImage *cDetailView::createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend) { - cImage *image = new cImage(cSize(width, height)); - image->Fill(clrBgr); - if (tvguideConfig.style != eStyleFlat) { - int numSteps = 64; - int alphaStep = 0x03; - if (height < 30) - return image; - else if (height < 100) { - numSteps = 32; - alphaStep = 0x06; - } - int stepY = 0.5*height / numSteps; - if (stepY == 0) - stepY = 1; - int alpha = 0x40; - tColor clr; - for (int i = 0; iSetPixel(cPoint(x,y), clr); - } - } - alpha += alphaStep; - } - } - return image; -} - -void cDetailView::loadReruns(void) { - cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch"); - if (epgSearchPlugin && !isempty(event->Title())) { - std::stringstream sstrReruns; - Epgsearch_searchresults_v1_0 data; - std::string strQuery = event->Title(); - if (tvguideConfig.useSubtitleRerun > 0) { - if (tvguideConfig.useSubtitleRerun == 2 || !isempty(event->ShortText())) - strQuery += "~"; - if (!isempty(event->ShortText())) - strQuery += event->ShortText(); - data.useSubTitle = true; - } else { - data.useSubTitle = false; - } - data.query = (char *)strQuery.c_str(); - data.mode = 0; - data.channelNr = 0; - data.useTitle = true; - data.useDescription = false; - - if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) { - cList* list = data.pResultList; - if (list && (list->Count() > 1)) { - sstrReruns << tr("RERUNS OF THIS SHOW") << ':' << std::endl; - int i = 0; - for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = list->First(); r && i < tvguideConfig.numReruns; r = list->Next(r)) { - if ((event->ChannelID() == r->event->ChannelID()) && (event->StartTime() == r->event->StartTime())) - continue; - i++; - sstrReruns << "- " - << *DayDateTime(r->event->StartTime()); - cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); - if (channel) - sstrReruns << " " << channel->ShortName(true); - sstrReruns << ": " << r->event->Title(); - if (!isempty(r->event->ShortText())) - sstrReruns << "~" << r->event->ShortText(); - sstrReruns << std::endl; - } - delete list; - } - } - reruns.Set(sstrReruns.str().c_str(), fontManager.FontDetailView, contentWidth - scrollBarWidth - 2*border); - } else - reruns.Set("", fontManager.FontDetailView, contentWidth - scrollBarWidth); -} - -int cDetailView::heightEPGPics(void) { - int border = 5; - int numPicsAvailable = 0; - for (int i=1; i <= tvguideConfig.numAdditionalEPGPictures; i++) { - cString epgimage = cString::sprintf("%s%d_%d.jpg", *tvguideConfig.epgImagePath, event->EventID(), i); - FILE *fp = fopen(*epgimage, "r"); - if (fp) { - numPicsAvailable = i; - fclose(fp); - } else { - break; - } - } - numEPGPics = numPicsAvailable; - int picsPerLine = contentWidth / (tvguideConfig.epgImageWidthLarge + border); - int picLines = numPicsAvailable / picsPerLine; - if (numPicsAvailable%picsPerLine != 0) - picLines++; - return picLines * (tvguideConfig.epgImageHeightLarge + border) + 2*border; -} - -int cDetailView::heightActorPics(void) { - int numActors = mediaInfo.actors.size(); - if (numActors < 1) - return 0; - if (mediaInfo.type == typeMovie) { - actorThumbWidth = mediaInfo.actors[0].thumb.width/2; - actorThumbHeight = mediaInfo.actors[0].thumb.height/2; - } else if (mediaInfo.type == typeSeries) { - actorThumbWidth = mediaInfo.actors[0].thumb.width/2; - actorThumbHeight = mediaInfo.actors[0].thumb.height/2; - } - int picsPerLine = contentWidth / (actorThumbWidth + 2*border); - int picLines = numActors / picsPerLine; - if (numActors%picsPerLine != 0) - picLines++; - int actorsHeight = picLines * (actorThumbHeight + 2*fontManager.FontDetailViewSmall->Height()) + fontManager.FontDetailView->Height() + fontManager.FontDetailHeader->Height(); - return actorsHeight; -} - -int cDetailView::heightFanartImg(void) { - int retVal = 0; - if (mediaInfo.fanart.size() >= 1) { - int fanartWidthOrig = mediaInfo.fanart[0].width; - int fanartHeightOrig = mediaInfo.fanart[0].height; - int fanartWidth = fanartWidthOrig; - int fanartHeight = fanartHeightOrig; - retVal = fanartHeight; - if (fanartWidthOrig > (contentWidth - 2*border)) { - fanartWidth = contentWidth - 2*border; - fanartHeight = fanartHeightOrig * ((double)fanartWidth / (double)fanartWidthOrig); - retVal = fanartHeight; - } - } - return retVal; -} - -void cDetailView::drawEPGPictures(int height) { - int border = 5; - int picsPerLine = contentWidth / (tvguideConfig.epgImageWidthLarge + border); - int currentX = border; - int currentY = height + border; - int currentPicsPerLine = 1; - cImageLoader imgLoader; - for (int i=1; i <= numEPGPics; i++) { - cString epgimage = cString::sprintf("%d_%d", event->EventID(), i); - if (imgLoader.LoadAdditionalEPGImage(epgimage)) { - content->DrawImage(cPoint(currentX, currentY), imgLoader.GetImage()); - int radius = 10; - content->DrawEllipse(cRect(currentX,currentY,radius,radius), theme.Color(clrBackground), -2); - content->DrawEllipse(cRect(currentX + tvguideConfig.epgImageWidthLarge - radius,currentY,radius,radius), theme.Color(clrBackground), -1); - content->DrawEllipse(cRect(currentX,currentY + tvguideConfig.epgImageHeightLarge - radius,radius,radius), theme.Color(clrBackground), -3); - content->DrawEllipse(cRect(currentX + tvguideConfig.epgImageWidthLarge - radius,currentY + tvguideConfig.epgImageHeightLarge - radius,radius,radius), theme.Color(clrBackground), -4); - if (currentPicsPerLine < picsPerLine) { - currentX += tvguideConfig.epgImageWidthLarge + border; - currentPicsPerLine++; - } else { - currentX = border; - currentY += tvguideConfig.epgImageHeightLarge + border; - currentPicsPerLine = 1; - } - } else { - break; - } - } -} - -void cDetailView::drawPoster(void) { - int border = 10; - if (mediaInfo.posters.size() < 1) + InitiateView(); + if (!view) return; - int posterWidthOrig = mediaInfo.posters[0].width; - int posterHeightOrig = mediaInfo.posters[0].height; - if ((posterWidthOrig < 10) || (posterHeightOrig < 10)) - return; - int posterWidth = posterWidthOrig; - int posterHeight = posterHeightOrig; - if ((posterWidthOrig > widthPoster) && (posterHeightOrig < contentHeight)) { - posterWidth = widthPoster - 2*border; - posterHeight = posterHeightOrig * ((double)posterWidth / (double)posterWidthOrig); - } else if ((posterWidthOrig < widthPoster) && (posterHeightOrig > contentHeight)) { - posterHeight = contentHeight - 2*border; - posterWidth = posterWidthOrig * ((double)posterHeight / (double)posterHeightOrig); - } else if ((posterWidthOrig > widthPoster) && (posterHeightOrig > contentHeight)) { - double ratioPoster = posterHeightOrig / posterWidthOrig; - double ratioWindow = contentHeight / widthPoster; - if (ratioPoster >= ratioWindow) { - posterWidth = widthPoster - 2*border; - posterHeight = posterHeightOrig * ((double)posterWidth / (double)posterWidthOrig); - } else { - posterHeight = contentHeight - 2*border; - posterWidth = posterWidthOrig * ((double)posterHeight / (double)posterHeightOrig); - } - } - if (!Running()) - return; - cImageLoader imgLoader; - if (imgLoader.LoadPoster(mediaInfo.posters[0].path.c_str(), posterWidth, posterHeight)) { - int posterX = (widthPoster - posterWidth) / 2; - int posterY = (contentHeight - posterHeight) / 2; - if (Running() && pixmapPoster) - pixmapPoster->DrawImage(cPoint(posterX, posterY), imgLoader.GetImage()); - } + view->SetFonts(); + view->SetGeometry(); + view->LoadMedia(); + view->Start(); + if (event) + view->SetAdditionalInfoText(LoadReruns()); } -void cDetailView::drawBanner(int height) { - int bannerWidthOrig = mediaInfo.banner.width; - int bannerHeightOrig = mediaInfo.banner.height; - int bannerWidth = bannerWidthOrig; - int bannerHeight = bannerHeightOrig; - - if (bannerWidthOrig > contentWidth - 2*border) { - bannerWidth = contentWidth - 2*border; - bannerHeight = bannerHeightOrig * ((double)bannerWidth / (double)bannerWidthOrig); - } - if (!Running()) - return; - cImageLoader imgLoader; - if (imgLoader.LoadPoster(mediaInfo.banner.path.c_str(), bannerWidth, bannerHeight)) { - int bannerX = (contentWidth - bannerWidth) / 2; - if (Running() && content) - content->DrawImage(cPoint(bannerX, height), imgLoader.GetImage()); - } -} - -void cDetailView::drawActors(int height) { - int numActors = mediaInfo.actors.size(); - if (numActors < 1) - return; - tColor colorTextBack = (tvguideConfig.style == eStyleFlat)?theme.Color(clrBackground):clrTransparent; - - cString header = cString::sprintf("%s:", tr("Actors")); - content->DrawText(cPoint(border, height), *header, theme.Color(clrFont), colorTextBack, fontManager.FontDetailHeader); - - int picsPerLine = contentWidth / (actorThumbWidth + 2*border); - int picLines = numActors / picsPerLine; - if (numActors%picsPerLine != 0) - picLines++; - int x = 0; - int y = height + fontManager.FontDetailHeader->Height(); - if (!Running()) - return; - cImageLoader imgLoader; - int actor = 0; - for (int row = 0; row < picLines; row++) { - for (int col = 0; col < picsPerLine; col++) { - if (!Running()) - return; - if (actor == numActors) - break; - std::string path = mediaInfo.actors[actor].thumb.path; - if (imgLoader.LoadPoster(path.c_str(), actorThumbWidth, actorThumbHeight)) { - if (Running() && content) - content->DrawImage(cPoint(x + border, y), imgLoader.GetImage()); - } - std::string name = mediaInfo.actors[actor].name; - std::stringstream sstrRole; - sstrRole << "\"" << mediaInfo.actors[actor].role << "\""; - std::string role = sstrRole.str(); - if (fontManager.FontDetailViewSmall->Width(name.c_str()) > actorThumbWidth + 2*border) - name = CutText(name, actorThumbWidth + 2*border, fontManager.FontDetailViewSmall); - if (fontManager.FontDetailViewSmall->Width(role.c_str()) > actorThumbWidth + 2*border) - role = CutText(role, actorThumbWidth + 2*border, fontManager.FontDetailViewSmall); - int xName = x + ((actorThumbWidth+2*border) - fontManager.FontDetailViewSmall->Width(name.c_str()))/2; - int xRole = x + ((actorThumbWidth+2*border) - fontManager.FontDetailViewSmall->Width(role.c_str()))/2; - if (Running() && content) { - content->DrawText(cPoint(xName, y + actorThumbHeight), name.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailViewSmall); - content->DrawText(cPoint(xRole, y + actorThumbHeight + fontManager.FontDetailViewSmall->Height()), role.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailViewSmall); - x += actorThumbWidth + 2*border; - } - actor++; - } - x = 0; - y += actorThumbHeight + 2 * fontManager.FontDetailViewSmall->Height(); - } -} - -void cDetailView::drawFanart(int height) { - if (mediaInfo.fanart.size() < 1) - return; - int fanartWidthOrig = mediaInfo.fanart[0].width; - int fanartHeightOrig = mediaInfo.fanart[0].height; - int fanartWidth = fanartWidthOrig; - int fanartHeight = fanartHeightOrig; - - if (fanartWidthOrig > contentWidth - 2*border) { - fanartWidth = contentWidth - 2*border; - fanartHeight = fanartHeightOrig * ((double)fanartWidth / (double)fanartWidthOrig); - } - if (!Running()) - return; - cImageLoader imgLoader; - if (imgLoader.LoadPoster(mediaInfo.fanart[0].path.c_str(), fanartWidth, fanartHeight)) { - int fanartX = (contentWidth - fanartWidth) / 2; - if (Running() && content) - content->DrawImage(cPoint(fanartX, height), imgLoader.GetImage()); - } -} - - eOSState cDetailView::ProcessKey(eKeys Key) { eOSState state = osContinue; + if (Running()) + return state; switch (Key & ~k_Repeat) { - case kUp: - scrollUp(); - osdManager.flush(); - break; - case kDown: - scrollDown(); - osdManager.flush(); - break; + case kUp: { + bool scrolled = view->KeyUp(); + if (scrolled) { + view->DrawScrollbar(); + osdManager.flush(); + } + break; } + case kDown: { + bool scrolled = view->KeyDown(); + if (scrolled) { + view->DrawScrollbar(); + osdManager.flush(); + } + break; } case kLeft: - pageUp(); - osdManager.flush(); + view->KeyLeft(); + view->Start(); break; case kRight: - pageDown(); - osdManager.flush(); + view->KeyRight(); + view->Start(); break; case kOk: case kBack: diff --git a/detailview.h b/detailview.h index c7a6c50..58f653e 100644 --- a/detailview.h +++ b/detailview.h @@ -1,78 +1,27 @@ #ifndef __TVGUIDE_DETAILVIEW_H #define __TVGUIDE_DETAILVIEW_H -#include -#include +#include #include -#include "services/tvscraper.h" +#include "config.h" +#include "tools.h" #include "styledpixmap.h" #include "footer.h" +#include "view.h" // --- cDetailView ------------------------------------------------------------- -class cEpgGrid; - class cDetailView : public cThread { private: - cPixmap *back; - cStyledPixmap *header; - cPixmap *headerLogo; - cPixmap *content; - cPixmap *pixmapPoster; - cPixmap *scrollBar; - cFooter *footer; const cEvent *event; - cImage *imgScrollBar; - cTextWrapper description; - cTextWrapper reruns; - TVScraperGetFullInformation mediaInfo; - bool hasAdditionalMedia; - int border; - int headerWidth; - int headerHeight; - int width; - int contentWidth; - int contentHeight; - int contentX; - int widthPoster; - int yBanner; - int yEPGText; - int yActors; - int yFanart; - int yAddInf; - int yEPGPics; - int actorThumbWidth; - int actorThumbHeight; - int scrollBarWidth; - bool setContentDrawportHeight(); - int heightContent; - int heightScrollbar; - int numEPGPics; - bool contentScrollable; - void loadReruns(void); - int heightEPGPics(void); - int heightActorPics(void); - int heightFanartImg(void); - void drawEPGPictures(int height); - void drawRecIcon(void); - void drawPoster(void); - void drawBanner(int height); - void drawActors(int height); - void drawFanart(int height); - cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend); - void scrollUp(); - void scrollDown(); - void pageUp(); - void pageDown(); + cFooter *footer; + cView *view; + void InitiateView(void); + std::string LoadReruns(void); void Action(void); public: cDetailView(const cEvent *event, cFooter *footer); virtual ~cDetailView(void); - void setContent(); - void createPixmaps(); - void drawHeader(); - void drawContent(); - void drawScrollbar(); eOSState ProcessKey(eKeys Key); }; diff --git a/fontmanager.c b/fontmanager.c index 7468190..b55621a 100644 --- a/fontmanager.c +++ b/fontmanager.c @@ -15,7 +15,8 @@ void cFontManager::SetFonts() { FontButton = CreateFont(geoManager.footerHeight/3 + 4 + tvguideConfig.FontButtonDelta); FontDetailView = CreateFont(geoManager.osdHeight/30 + tvguideConfig.FontDetailViewDelta); FontDetailViewSmall = CreateFont(geoManager.osdHeight/40 + tvguideConfig.FontDetailViewSmallDelta); - FontDetailHeader = CreateFont(geoManager.osdHeight/25 + tvguideConfig.FontDetailHeaderDelta); + FontDetailHeader = CreateFont(geoManager.osdHeight/27 + tvguideConfig.FontDetailHeaderDelta); + FontDetailHeaderLarge = CreateFont(geoManager.osdHeight/20 + tvguideConfig.FontDetailHeaderDelta); FontMessageBox = CreateFont(geoManager.osdHeight/33 + tvguideConfig.FontMessageBoxDelta); FontMessageBoxLarge = CreateFont(geoManager.osdHeight/30 + tvguideConfig.FontMessageBoxLargeDelta); FontStatusHeader = CreateFont(geoManager.statusHeaderHeight/6 - 4 + tvguideConfig.FontStatusHeaderDelta); @@ -46,6 +47,7 @@ void cFontManager::DeleteFonts() { delete FontDetailView; delete FontDetailViewSmall; delete FontDetailHeader; + delete FontDetailHeaderLarge; delete FontMessageBox; delete FontMessageBoxLarge; delete FontStatusHeader; diff --git a/fontmanager.h b/fontmanager.h index 423a1be..7253043 100644 --- a/fontmanager.h +++ b/fontmanager.h @@ -31,6 +31,7 @@ class cFontManager { cFont *FontDetailView; cFont *FontDetailViewSmall; cFont *FontDetailHeader; + cFont *FontDetailHeaderLarge; cFont *FontMessageBox; cFont *FontMessageBoxLarge; cFont *FontRecMenuItem; diff --git a/po/ca_ES.po b/po/ca_ES.po index d49b448..6f8c6fb 100644 --- a/po/ca_ES.po +++ b/po/ca_ES.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-07 18:08+0100\n" +"POT-Creation-Date: 2014-05-10 17:24+0200\n" "PO-Revision-Date: 2013-09-21 17:49+0200\n" "Last-Translator: My friend Thanks David \n" "Language-Team: \n" @@ -21,11 +21,14 @@ msgstr "Programa principal" msgid "Channel" msgstr "Canal" -msgid "RERUNS OF THIS SHOW" -msgstr "REEMISSIONS" +msgid "min" +msgstr "min" -msgid "Actors" -msgstr "Actors" +msgid "Reruns of " +msgstr "" + +msgid "No reruns found" +msgstr "" msgid "No EPG Information available" msgstr "No hi ha informació EPG" @@ -72,9 +75,6 @@ msgstr "canal desconegut" msgid "Duration" msgstr "Durada" -msgid "min" -msgstr "min" - msgid "recorded at" msgstr "enregistrat a" @@ -612,6 +612,9 @@ msgstr "Salt (Botons 4 / 6) en hores" msgid "Time Format (12h/24h)" msgstr "Format de temps (12h/24h)" +msgid "EPG Window Text Scrolling Speed" +msgstr "" + msgid "Display Reruns in detailed EPG View" msgstr "Mostre reemissions a l'EPG detallat" @@ -837,6 +840,114 @@ msgstr "" msgid "Recording Menus Icon Cache" msgstr "" +msgid "No Cast available" +msgstr "" + +msgid "Cast" +msgstr "" + +msgid "EPG Info" +msgstr "" + +msgid "Reruns" +msgstr "" + +msgid "Recording Information" +msgstr "" + +msgid "Image Galery" +msgstr "" + +msgid "TheTVDB Info" +msgstr "" + +msgid "TheTVDB Information" +msgstr "" + +msgid "Episode" +msgstr "" + +msgid "Season" +msgstr "" + +msgid "Episode Overview" +msgstr "" + +msgid "First aired" +msgstr "" + +msgid "Guest Stars" +msgstr "" + +msgid "TheMovieDB Rating" +msgstr "" + +msgid "Series Overview" +msgstr "" + +msgid "Genre" +msgstr "" + +msgid "Network" +msgstr "" + +msgid "Status" +msgstr "" + +msgid "TheMovieDB Information" +msgstr "" + +msgid "Original Title" +msgstr "" + +msgid "Tagline" +msgstr "" + +msgid "Overview" +msgstr "" + +msgid "yes" +msgstr "" + +msgid "no" +msgstr "" + +msgid "Adult" +msgstr "" + +msgid "Collection" +msgstr "" + +msgid "Budget" +msgstr "" + +msgid "Revenue" +msgstr "" + +msgid "Homepage" +msgstr "" + +msgid "Release Date" +msgstr "" + +msgid "Runtime" +msgstr "" + +msgid "minutes" +msgstr "" + +msgid "TheMovieDB Popularity" +msgstr "" + +msgid "TheMovieDB Vote Average" +msgstr "" + +#~ msgid "RERUNS OF THIS SHOW" +#~ msgstr "REEMISSIONS" + +#~ msgid "Actors" +#~ msgstr "Actors" + #~ msgid "Use folders for instant records" #~ msgstr "Utilitza carpetes per gravacions a l'instant" diff --git a/po/de_DE.po b/po/de_DE.po index 82acc4f..d2e7cdf 100755 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-07 18:08+0100\n" +"POT-Creation-Date: 2014-05-10 17:24+0200\n" "PO-Revision-Date: 2012-08-25 17:49+0200\n" "Last-Translator: Horst\n" "Language-Team: \n" @@ -18,11 +18,14 @@ msgstr "Hauptprogramm" msgid "Channel" msgstr "Kanal" -msgid "RERUNS OF THIS SHOW" -msgstr "Wiederholungen dieser Sendung" +msgid "min" +msgstr "min" -msgid "Actors" -msgstr "Schauspieler" +msgid "Reruns of " +msgstr "Wiederholungen von " + +msgid "No reruns found" +msgstr "Keine Wiederholungen gefunden" msgid "No EPG Information available" msgstr "Keine EPG Daten verfügbar" @@ -69,9 +72,6 @@ msgstr "unbekannter Kanal" msgid "Duration" msgstr "Dauer" -msgid "min" -msgstr "min" - msgid "recorded at" msgstr "aufgenommen am" @@ -609,6 +609,9 @@ msgstr "Sehr großer Sprung (Tasten 4 / 6) in Stunden" msgid "Time Format (12h/24h)" msgstr "Zeitformat (12h/24h)" +msgid "EPG Window Text Scrolling Speed" +msgstr "Text Scroll Geschwindigkeit des EPG Fensters" + msgid "Display Reruns in detailed EPG View" msgstr "Wiederholungen in der detailierten EPG Ansicht anzeigen" @@ -833,3 +836,106 @@ msgstr "Kanalgruppen Cache" msgid "Recording Menus Icon Cache" msgstr "Recording Menüs Icon Cache" + +msgid "No Cast available" +msgstr "Keine Besetzung vorhanden" + +msgid "Cast" +msgstr "Besetzung" + +msgid "EPG Info" +msgstr "EPG Info" + +msgid "Reruns" +msgstr "Wiederholungen" + +msgid "Recording Information" +msgstr "" + +msgid "Image Galery" +msgstr "Bildergalerie" + +msgid "TheTVDB Info" +msgstr "TheTVDB Info" + +msgid "TheTVDB Information" +msgstr "TheTVDB Information" + +msgid "Episode" +msgstr "Episode" + +msgid "Season" +msgstr "Staffel" + +msgid "Episode Overview" +msgstr "Episodenüberblick" + +msgid "First aired" +msgstr "Erstausstrahlung" + +msgid "Guest Stars" +msgstr "Gast Stars" + +msgid "TheMovieDB Rating" +msgstr "TheMovieDB Wertung" + +msgid "Series Overview" +msgstr "Serienüberblick" + +msgid "Genre" +msgstr "Genre" + +msgid "Network" +msgstr "Sendeanstalt" + +msgid "Status" +msgstr "Status" + +msgid "TheMovieDB Information" +msgstr "TheMovieDB Information" + +msgid "Original Title" +msgstr "Original Titel" + +msgid "Tagline" +msgstr "Zusammenfassung" + +msgid "Overview" +msgstr "Überblick" + +msgid "yes" +msgstr "Ja" + +msgid "no" +msgstr "Nein" + +msgid "Adult" +msgstr "Nur für Erwachsene" + +msgid "Collection" +msgstr "Kollektion" + +msgid "Budget" +msgstr "Budget" + +msgid "Revenue" +msgstr "Einnahmen" + +msgid "Homepage" +msgstr "Homepage" + +msgid "Release Date" +msgstr "Veröffentlicht" + +msgid "Runtime" +msgstr "Laufzeit" + +msgid "minutes" +msgstr "Minuten" + +msgid "TheMovieDB Popularity" +msgstr "TheMovieDB Popularität" + +msgid "TheMovieDB Vote Average" +msgstr "TheMovieDB durchschnittliche Bewertung" + diff --git a/po/ru_RU.po b/po/ru_RU.po index 64f22b8..57bfa4d 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-07 18:08+0100\n" +"POT-Creation-Date: 2014-05-10 17:24+0200\n" "PO-Revision-Date: 2013-09-25 17:49+0400\n" "Last-Translator: AmiD, ilya\n" "Language-Team: Russia-Cherepovets(wm.amid@gmail.com)\n" @@ -18,11 +18,14 @@ msgstr "Основная программа" msgid "Channel" msgstr "Канал" -msgid "RERUNS OF THIS SHOW" -msgstr "ПОВТОРЫ ЭТОЙ ПЕРЕДАЧИ" +msgid "min" +msgstr "мин" -msgid "Actors" -msgstr "Актеры" +msgid "Reruns of " +msgstr "" + +msgid "No reruns found" +msgstr "" msgid "No EPG Information available" msgstr "Нет доступной EPG информации" @@ -69,9 +72,6 @@ msgstr "неизвестный канал" msgid "Duration" msgstr "Продолжительность" -msgid "min" -msgstr "мин" - msgid "recorded at" msgstr "записано" @@ -609,6 +609,9 @@ msgstr "Большой прыжок (Кнопки 4 / 6) в часах" msgid "Time Format (12h/24h)" msgstr "Формат времени (12h/24h)" +msgid "EPG Window Text Scrolling Speed" +msgstr "" + msgid "Display Reruns in detailed EPG View" msgstr "Показывать повторы в подробном EPG" @@ -834,6 +837,114 @@ msgstr "" msgid "Recording Menus Icon Cache" msgstr "" +msgid "No Cast available" +msgstr "" + +msgid "Cast" +msgstr "" + +msgid "EPG Info" +msgstr "" + +msgid "Reruns" +msgstr "" + +msgid "Recording Information" +msgstr "" + +msgid "Image Galery" +msgstr "" + +msgid "TheTVDB Info" +msgstr "" + +msgid "TheTVDB Information" +msgstr "" + +msgid "Episode" +msgstr "" + +msgid "Season" +msgstr "" + +msgid "Episode Overview" +msgstr "" + +msgid "First aired" +msgstr "" + +msgid "Guest Stars" +msgstr "" + +msgid "TheMovieDB Rating" +msgstr "" + +msgid "Series Overview" +msgstr "" + +msgid "Genre" +msgstr "" + +msgid "Network" +msgstr "" + +msgid "Status" +msgstr "" + +msgid "TheMovieDB Information" +msgstr "" + +msgid "Original Title" +msgstr "" + +msgid "Tagline" +msgstr "" + +msgid "Overview" +msgstr "" + +msgid "yes" +msgstr "" + +msgid "no" +msgstr "" + +msgid "Adult" +msgstr "" + +msgid "Collection" +msgstr "" + +msgid "Budget" +msgstr "" + +msgid "Revenue" +msgstr "" + +msgid "Homepage" +msgstr "" + +msgid "Release Date" +msgstr "" + +msgid "Runtime" +msgstr "" + +msgid "minutes" +msgstr "" + +msgid "TheMovieDB Popularity" +msgstr "" + +msgid "TheMovieDB Vote Average" +msgstr "" + +#~ msgid "RERUNS OF THIS SHOW" +#~ msgstr "ПОВТОРЫ ЭТОЙ ПЕРЕДАЧИ" + +#~ msgid "Actors" +#~ msgstr "Актеры" + #~ msgid "Use folders for instant records" #~ msgstr "Использовать директории для быстрой записи" diff --git a/po/sk_SK.po b/po/sk_SK.po index 5d4865c..27cb5f8 100644 --- a/po/sk_SK.po +++ b/po/sk_SK.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 1.1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-07 18:08+0100\n" +"POT-Creation-Date: 2014-05-10 17:24+0200\n" "PO-Revision-Date: 2013-09-15 00:12+0100\n" "Last-Translator: Milan Hrala \n" "Language-Team: \n" @@ -18,11 +18,14 @@ msgstr "Hlavn msgid "Channel" msgstr "Kanl" -msgid "RERUNS OF THIS SHOW" -msgstr "Reprza tohto programu" +msgid "min" +msgstr "min" -msgid "Actors" -msgstr "Herci" +msgid "Reruns of " +msgstr "" + +msgid "No reruns found" +msgstr "" msgid "No EPG Information available" msgstr "iadne EPG daje nie s k dispozcii" @@ -69,9 +72,6 @@ msgstr "nezn msgid "Duration" msgstr "Dka" -msgid "min" -msgstr "min" - msgid "recorded at" msgstr "Zaznamenan" @@ -609,6 +609,9 @@ msgstr "Ve msgid "Time Format (12h/24h)" msgstr "Formt asu (12h/24h)" +msgid "EPG Window Text Scrolling Speed" +msgstr "" + msgid "Display Reruns in detailed EPG View" msgstr "Reprzy v podrobnom zobrazen relcie EPG" @@ -834,6 +837,114 @@ msgstr "" msgid "Recording Menus Icon Cache" msgstr "" +msgid "No Cast available" +msgstr "" + +msgid "Cast" +msgstr "" + +msgid "EPG Info" +msgstr "" + +msgid "Reruns" +msgstr "" + +msgid "Recording Information" +msgstr "" + +msgid "Image Galery" +msgstr "" + +msgid "TheTVDB Info" +msgstr "" + +msgid "TheTVDB Information" +msgstr "" + +msgid "Episode" +msgstr "" + +msgid "Season" +msgstr "" + +msgid "Episode Overview" +msgstr "" + +msgid "First aired" +msgstr "" + +msgid "Guest Stars" +msgstr "" + +msgid "TheMovieDB Rating" +msgstr "" + +msgid "Series Overview" +msgstr "" + +msgid "Genre" +msgstr "" + +msgid "Network" +msgstr "" + +msgid "Status" +msgstr "" + +msgid "TheMovieDB Information" +msgstr "" + +msgid "Original Title" +msgstr "" + +msgid "Tagline" +msgstr "" + +msgid "Overview" +msgstr "" + +msgid "yes" +msgstr "" + +msgid "no" +msgstr "" + +msgid "Adult" +msgstr "" + +msgid "Collection" +msgstr "" + +msgid "Budget" +msgstr "" + +msgid "Revenue" +msgstr "" + +msgid "Homepage" +msgstr "" + +msgid "Release Date" +msgstr "" + +msgid "Runtime" +msgstr "" + +msgid "minutes" +msgstr "" + +msgid "TheMovieDB Popularity" +msgstr "" + +msgid "TheMovieDB Vote Average" +msgstr "" + +#~ msgid "RERUNS OF THIS SHOW" +#~ msgstr "Reprza tohto programu" + +#~ msgid "Actors" +#~ msgstr "Herci" + #~ msgid "Use folders for instant records" #~ msgstr "Poui adresre pre okamit nahrvky" diff --git a/recmanager.c b/recmanager.c index dcb5d0c..7ad6f4c 100644 --- a/recmanager.c +++ b/recmanager.c @@ -7,7 +7,6 @@ #include #include "services/remotetimers.h" -#include "services/tvscraper.h" #include "tools.h" #include "switchtimer.h" #include "timerconflict.h" diff --git a/recmenumanager.c b/recmenumanager.c index 8f100fd..edabf4d 100644 --- a/recmenumanager.c +++ b/recmenumanager.c @@ -851,10 +851,6 @@ void cRecMenuManager::DisplayDetailedView(const cEvent *ev) { activeMenu->Hide(); detailView = new cDetailView(ev, footer); footer->SetDetailedViewMode(true); - detailView->setContent(); - detailView->drawHeader(); - detailView->drawContent(); - detailView->drawScrollbar(); detailView->Start(); detailViewActive = true; } diff --git a/services/scraper2vdr.h b/services/scraper2vdr.h new file mode 100644 index 0000000..703d077 --- /dev/null +++ b/services/scraper2vdr.h @@ -0,0 +1,194 @@ +#ifndef __SCRAPER2VDRSERVICES_H +#define __SCRAPER2VDRSERVICES_H + +#include +#include + +enum tvType { + tSeries, + tMovie, + tNone, +}; + +/********************************************************************* +* Helper Structures +*********************************************************************/ +class cTvMedia { +public: + cTvMedia(void) { + path = ""; + width = height = 0; + }; + std::string path; + int width; + int height; +}; + +class cEpisode { +public: + cEpisode(void) { + number = 0; + season = 0; + name = ""; + firstAired = ""; + guestStars = ""; + overview = ""; + rating = 0.0; + }; + int number; + int season; + std::string name; + std::string firstAired; + std::string guestStars; + std::string overview; + float rating; + cTvMedia episodeImage; +}; + +class cActor { +public: + cActor(void) { + name = ""; + role = ""; + }; + std::string name; + std::string role; + cTvMedia actorThumb; +}; + +/********************************************************************* +* Data Structures for Service Calls +*********************************************************************/ + +// Data structure for service "GetEventType" +class ScraperGetEventType { +public: + ScraperGetEventType(void) { + event = NULL; + recording = NULL; + type = tNone; + movieId = 0; + seriesId = 0; + episodeId = 0; + }; +// in + const cEvent *event; // check type for this event + const cRecording *recording; // or for this recording +//out + tvType type; //typeSeries or typeMovie + int movieId; + int seriesId; + int episodeId; +}; + +//Data structure for full series and episode information +class cMovie { +public: + cMovie(void) { + title = ""; + originalTitle = ""; + tagline = ""; + overview = ""; + adult = false; + collectionName = ""; + budget = 0; + revenue = 0; + genres = ""; + homepage = ""; + releaseDate = ""; + runtime = 0; + popularity = 0.0; + voteAverage = 0.0; + }; +//IN + int movieId; // movieId fetched from ScraperGetEventType +//OUT + std::string title; + std::string originalTitle; + std::string tagline; + std::string overview; + bool adult; + std::string collectionName; + int budget; + int revenue; + std::string genres; + std::string homepage; + std::string releaseDate; + int runtime; + float popularity; + float voteAverage; + cTvMedia poster; + cTvMedia fanart; + cTvMedia collectionPoster; + cTvMedia collectionFanart; + std::vector actors; +}; + +//Data structure for full series and episode information +class cSeries { +public: + cSeries(void) { + seriesId = 0; + episodeId = 0; + name = ""; + overview = ""; + firstAired = ""; + network = ""; + genre = ""; + rating = 0.0; + status = ""; + }; +//IN + int seriesId; // seriesId fetched from ScraperGetEventType + int episodeId; // episodeId fetched from ScraperGetEventType +//OUT + std::string name; + std::string overview; + std::string firstAired; + std::string network; + std::string genre; + float rating; + std::string status; + cEpisode episode; + std::vector actors; + std::vector posters; + std::vector banners; + std::vector fanarts; + cTvMedia seasonPoster; +}; + +// Data structure for service "GetPosterBanner" +class ScraperGetPosterBanner { +public: + ScraperGetPosterBanner(void) { + type = tNone; + }; +// in + const cEvent *event; // check type for this event +//out + tvType type; //typeSeries or typeMovie + cTvMedia poster; + cTvMedia banner; +}; + +// Data structure for service "GetPoster" +class ScraperGetPoster { +public: +// in + const cEvent *event; // check type for this event + const cRecording *recording; // or for this recording +//out + cTvMedia poster; +}; + +// Data structure for service "GetPosterThumb" +class ScraperGetPosterThumb { +public: +// in + const cEvent *event; // check type for this event + const cRecording *recording; // or for this recording +//out + cTvMedia poster; +}; + +#endif //__SCRAPER2VDRSERVICES_H \ No newline at end of file diff --git a/services/tvscraper.h b/services/tvscraper.h deleted file mode 100644 index 9ebb84b..0000000 --- a/services/tvscraper.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __TVGUIDE_TVSCRAPER_H -#define __TVGUIDE_TVSCRAPER_H - -#include -#include -#include - -enum tvMediaType { - typeSeries, - typeMovie, - typeNone, -}; - -struct tvMedia { - std::string path; - int width; - int height; -}; - -struct tvActor { - std::string name; - std::string role; - tvMedia thumb; -}; - -// Data structure for service "TVScraper-GetPosterOrBanner" -struct TVScraperGetPosterOrBanner -{ -// in - const cEvent *event; // search image for this event -//out - tvMediaType type; //typeSeries or typeMovie - tvMedia media; //banner or poster -}; - -// Data structure for service "TVScraper-GetPoster" -struct TVScraperGetPoster -{ -// in - const cEvent *event; // search image for this event - bool isRecording; // search in current EPG or recordings -//out - tvMedia media; //poster -}; - - -/* Data structure for service "TVScraper-GetFullEPGInformation" -if type == typeMovie a poster and a fanart image is delivered -if type == typeSeries a banner and up to three posters and fanarts are delivered -*/ -struct TVScraperGetFullInformation -{ -// in - const cEvent *event; // search all media for this event - bool isRecording; // search in current EPG or recordings -//out - tvMediaType type; - tvMedia banner; - std::vector posters; - std::vector fanart; - std::vector actors; - std::string description; -}; - -#endif //__TVGUIDE_TVSCRAPER_H \ No newline at end of file diff --git a/setup.c b/setup.c index f80eef3..c58af4d 100644 --- a/setup.c +++ b/setup.c @@ -95,6 +95,7 @@ void cTvguideSetup::Store(void) { SetupStore("numAdditionalEPGPictures", tvguideConfig.numAdditionalEPGPictures); SetupStore("epgImageWidthLarge", tvguideConfig.epgImageWidthLarge); SetupStore("epgImageHeightLarge", tvguideConfig.epgImageHeightLarge); + SetupStore("detailedViewScrollStep", tvguideConfig.detailedViewScrollStep); SetupStore("timeLineWidthPercent", tvguideConfig.timeLineWidthPercent); SetupStore("timeLineHeightPercent", tvguideConfig.timeLineHeightPercent); SetupStore("displayChannelName", tvguideConfig.displayChannelName); @@ -217,6 +218,7 @@ void cMenuSetupGeneral::Set(void) { Add(new cMenuEditIntItem(tr("Big Step (Keys 1 / 3) in hours"), &tmpTvguideConfig->bigStepHours, 1, 12)); Add(new cMenuEditIntItem(tr("Huge Step (Keys 4 / 6) in hours"), &tmpTvguideConfig->hugeStepHours, 13, 48)); Add(new cMenuEditStraItem(tr("Time Format (12h/24h)"), &tmpTvguideConfig->timeFormat, 2, timeFormatItems)); + Add(new cMenuEditIntItem(tr("EPG Window Text Scrolling Speed"), &tmpTvguideConfig->detailedViewScrollStep, 1, 30)); Add(new cMenuEditBoolItem(tr("Display Reruns in detailed EPG View"), &tmpTvguideConfig->displayRerunsDetailEPGView)); if (tmpTvguideConfig->displayRerunsDetailEPGView) { Add(new cMenuEditIntItem(cString::sprintf("%s%s", *indent, tr("Number of reruns to display")), &tmpTvguideConfig->numReruns, 1, 10)); diff --git a/statusheader.c b/statusheader.c index 3b04919..cac916e 100644 --- a/statusheader.c +++ b/statusheader.c @@ -1,5 +1,5 @@ #include "tools.h" -#include "services/tvscraper.h" +#include "services/scraper2vdr.h" #include "imageloader.h" #include "statusheader.h" @@ -101,28 +101,26 @@ void cStatusHeader::DrawInfoText(cGrid *grid) { int cStatusHeader::DrawPoster(const cEvent *event, int x, int y, int height, int border) { bool hasPoster = false; - TVScraperGetPoster poster; + ScraperGetPoster posterScraper2Vdr; int posterWidth = 0; int posterHeight = 0; - if (event) { - static cPlugin *pTVScraper = cPluginManager::GetPlugin("tvscraper"); - if (pTVScraper) { - poster.event = event; - poster.isRecording = false; - if (pTVScraper->Service("TVScraperGetPoster", &poster)) { - hasPoster = true; - int posterWidthOrig = poster.media.width; - int posterHeightOrig = poster.media.height; - if ((posterWidthOrig > 10) && (posterHeightOrig > 10)) { - posterHeight = height; - posterWidth = posterWidthOrig * ((double)posterHeight / (double)posterHeightOrig); - } - } + static cPlugin *pScraper2Vdr = cPluginManager::GetPlugin("scraper2vdr"); + if (pScraper2Vdr) { + posterScraper2Vdr.event = event; + posterScraper2Vdr.recording = NULL; + if (pScraper2Vdr->Service("GetPoster", &posterScraper2Vdr)) { + hasPoster = true; + int posterWidthOrig = posterScraper2Vdr.poster.width; + int posterHeightOrig = posterScraper2Vdr.poster.height; + posterHeight = height; + posterWidth = posterWidthOrig * ((double)posterHeight / (double)posterHeightOrig); + } else { + hasPoster = false; } } if (hasPoster) { cImageLoader imgLoader; - if (imgLoader.LoadPoster(poster.media.path.c_str(), posterWidth, posterHeight)) { + if (imgLoader.LoadPoster(posterScraper2Vdr.poster.path.c_str(), posterWidth, posterHeight)) { pixmapText->DrawImage(cPoint(x, y), imgLoader.GetImage()); return posterWidth + border; } diff --git a/themes/tvguide-blue.theme b/themes/tvguide-blue.theme index 5fd6a9e..2aeda4c 100644 --- a/themes/tvguide-blue.theme +++ b/themes/tvguide-blue.theme @@ -24,6 +24,7 @@ clrTimeline1Blending = 90828282 clrTimeline2 = BB000000 clrTimeline2Blending = 903F3F3F clrTimeBase = A0FF0000 +clrTabInactive = 44003DF5 clrButtonRed = 99BB0000 clrButtonRedBorder = FFBB0000 clrButtonGreen = 9900BB00 diff --git a/themes/tvguide-darkblue.theme b/themes/tvguide-darkblue.theme index a52303e..008aa80 100644 --- a/themes/tvguide-darkblue.theme +++ b/themes/tvguide-darkblue.theme @@ -24,6 +24,7 @@ clrTimeline1Blending = FF828282 clrTimeline2 = FF000000 clrTimeline2Blending = FF3F3F3F clrTimeBase = A0FF0000 +clrTabInactive = 99242A38 clrButtonRed = 99BB0000 clrButtonRedBorder = FFBB0000 clrButtonGreen = 9900BB00 diff --git a/themes/tvguide-darkred.theme b/themes/tvguide-darkred.theme index c11d51f..06f7c71 100644 --- a/themes/tvguide-darkred.theme +++ b/themes/tvguide-darkred.theme @@ -24,6 +24,7 @@ clrTimeline1Blending = 90828282 clrTimeline2 = BB000000 clrTimeline2Blending = 903F3F3F clrTimeBase = A0FF0000 +clrTabInactive = 66550000 clrButtonRed = 99BB0000 clrButtonRedBorder = FFBB0000 clrButtonGreen = 9900BB00 diff --git a/themes/tvguide-darkredNG.theme b/themes/tvguide-darkredNG.theme index 2374de8..93ddc41 100644 --- a/themes/tvguide-darkredNG.theme +++ b/themes/tvguide-darkredNG.theme @@ -24,6 +24,7 @@ clrTimeline1Blending = 90828282 clrTimeline2 = FF000000 clrTimeline2Blending = 903F3F3F clrTimeBase = A0FF0000 +clrTabInactive = 66660000 clrButtonRed = 99BB0000 clrButtonRedBorder = FFBB0000 clrButtonGreen = 9900BB00 diff --git a/themes/tvguide-default.theme b/themes/tvguide-default.theme index fdc0346..c8fc9b0 100644 --- a/themes/tvguide-default.theme +++ b/themes/tvguide-default.theme @@ -24,7 +24,8 @@ clrTimeline1Blending = FF828282 clrTimeline2 = FF000000 clrTimeline2Blending = FF3F3F3F clrTimeBase = A0FF0000 -clrButtonRed = 00000000 +clrTabInactive = A01F3D7A +clrButtonRed = FFFF0000 clrButtonRedBorder = 00000000 clrButtonGreen = 00000000 clrButtonGreenBorder = 00000000 diff --git a/themes/tvguide-green.theme b/themes/tvguide-green.theme index 2fb2734..7fca3b0 100644 --- a/themes/tvguide-green.theme +++ b/themes/tvguide-green.theme @@ -24,6 +24,7 @@ clrTimeline1Blending = 90828282 clrTimeline2 = BB000000 clrTimeline2Blending = 903F3F3F clrTimeBase = A0FF0000 +clrTabInactive = 33006600 clrButtonRed = 99BB0000 clrButtonRedBorder = FFBB0000 clrButtonGreen = 9900BB00 diff --git a/themes/tvguide-iceblue.theme b/themes/tvguide-iceblue.theme index 218ad20..310872a 100644 --- a/themes/tvguide-iceblue.theme +++ b/themes/tvguide-iceblue.theme @@ -20,6 +20,7 @@ clrTimeline1Blending = 00000000 clrTimeline2 = FF000000 clrTimeline2Blending = 00000000 clrTimeBase = A0FF0000 +clrTabInactive = 88B8B8E6 clrButtonRed = FFBB0000 clrButtonRedBorder = FF000000 clrButtonGreen = FF00BB00 diff --git a/themes/tvguide-keepitsimple.theme b/themes/tvguide-keepitsimple.theme index 5d7e560..1f325c9 100644 --- a/themes/tvguide-keepitsimple.theme +++ b/themes/tvguide-keepitsimple.theme @@ -20,6 +20,7 @@ clrTimeline1Blending = 00000000 clrTimeline2 = FF2B3856 clrTimeline2Blending = 00000000 clrTimeBase = A0FF0000 +clrTabInactive = 886fac10 clrButtonRed = 99BB0000 clrButtonRedBorder = FFBB0000 clrButtonGreen = 9900BB00 diff --git a/tvguide.c b/tvguide.c index 848026b..029166d 100644 --- a/tvguide.c +++ b/tvguide.c @@ -26,7 +26,7 @@ #error "VDR-2.0.0 API version or greater is required!" #endif -static const char *VERSION = "1.2.1"; +static const char *VERSION = "1.2.2"; static const char *DESCRIPTION = "A fancy 2d EPG Viewer"; static const char *MAINMENUENTRY = "Tvguide"; diff --git a/tvguideosd.c b/tvguideosd.c index 15f84bd..9770d82 100644 --- a/tvguideosd.c +++ b/tvguideosd.c @@ -547,10 +547,6 @@ void cTvGuideOsd::DetailedEPG() { detailView = new cDetailView(activeGrid->GetEvent(), footer); footer->SetDetailedViewMode(); osdManager.flush(); - detailView->setContent(); - detailView->drawHeader(); - detailView->drawContent(); - detailView->drawScrollbar(); detailView->Start(); osdManager.flush(); } diff --git a/view.c b/view.c new file mode 100644 index 0000000..7608c03 --- /dev/null +++ b/view.c @@ -0,0 +1,1046 @@ +#include "detailview.h" + +/******************************************************************************************** +* cView +********************************************************************************************/ + +cView::cView(void) { + activeView = 0; + scrollable = false; + tabbed = false; + font = NULL; + fontSmall = NULL; + fontHeader = NULL; + fontHeaderLarge = NULL; + pixmapBackground = NULL; + pixmapHeader = NULL; + pixmapHeaderLogo = NULL; + pixmapContent = NULL; + pixmapTabs = NULL; + pixmapScrollbar = NULL; + pixmapScrollbarBack = NULL; + imgScrollBar = NULL; + title = ""; + subTitle = ""; + dateTime = ""; + infoText = ""; + channel = NULL; + eventID = 0; + event = NULL; + x = 0; + y = 0; + width = 0; + height = 0; + border = 0; + headerHeight = 0; + contentHeight = 0; + tabHeight = 0; + headerDrawn = false; +} + +cView::~cView(void) { + if (pixmapBackground) + osdManager.releasePixmap(pixmapBackground); + if (pixmapHeader) + delete pixmapHeader; + if (pixmapHeaderLogo) + osdManager.releasePixmap(pixmapHeaderLogo); + if (pixmapContent) + osdManager.releasePixmap(pixmapContent); + if (pixmapTabs) + osdManager.releasePixmap(pixmapTabs); + if (pixmapScrollbar) + osdManager.releasePixmap(pixmapScrollbar); + if (pixmapScrollbarBack) + osdManager.releasePixmap(pixmapScrollbarBack); + if (imgScrollBar) + delete imgScrollBar; +} + +void cView::SetFonts(void) { + font = fontManager.FontDetailView; + fontSmall = fontManager.FontDetailViewSmall; + fontHeaderLarge = fontManager.FontDetailHeaderLarge; + fontHeader = fontManager.FontDetailHeader; +} + +void cView::SetGeometry(void) { + x = 0; + y = 0; + scrollbarWidth = 40; + width = geoManager.osdWidth - scrollbarWidth; + height = geoManager.osdHeight; + border = tvguideConfig.epgViewBorder; + headerWidth = geoManager.headerContentWidth; + headerHeight = geoManager.epgViewHeaderHeight; + if (tabbed) + tabHeight = font->Height() * 3 / 2; + contentHeight = height - headerHeight - tabHeight - geoManager.footerHeight; +} + +void cView::DrawHeader(void) { + if (!pixmapHeader) { + pixmapHeader = new cStyledPixmap(osdManager.requestPixmap(5, cRect(0, 0, headerWidth, headerHeight))); + pixmapHeader->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); + } + if (!pixmapHeaderLogo) { + pixmapHeaderLogo = osdManager.requestPixmap(6, cRect(0, 0, width, headerHeight)); + } + pixmapHeader->Fill(clrTransparent); + pixmapHeaderLogo->Fill(clrTransparent); + if (tvguideConfig.style == eStyleGraphical) { + if (tvguideConfig.scaleVideo) { + pixmapHeader->drawBackgroundGraphical(bgStatusHeaderWindowed); + } else { + pixmapHeader->drawBackgroundGraphical(bgStatusHeaderFull); + } + } else { + pixmapHeader->drawBackground(); + pixmapHeader->drawBoldBorder(); + } + //Channel Logo + int logoHeight = 2 * headerHeight / 3; + int logoWidth = logoHeight * tvguideConfig.logoWidthRatio / tvguideConfig.logoHeightRatio; + int xText = border / 2; + if (channel && !tvguideConfig.hideChannelLogos) { + cImageLoader imgLoader; + if (imgLoader.LoadLogo(channel, logoWidth, logoHeight)) { + cImage logo = imgLoader.GetImage(); + pixmapHeaderLogo->DrawImage(cPoint(border/2, (headerHeight - logoHeight)/2), logo); + xText += logoWidth + border / 2; + } + } + //Date and Time, Title, Subtitle + int yDateTime = border / 2; + int yTitle = (headerHeight - fontHeaderLarge->Height()) / 2; + int ySubtitle = headerHeight - fontHeader->Height() - border / 3; + int textWidthMax = headerWidth - xText; + pixmapHeader->DrawText(cPoint(xText, yDateTime), CutText(dateTime, textWidthMax, fontHeader).c_str(), theme.Color(clrFont), theme.Color(clrStatusHeader), fontHeader); + pixmapHeader->DrawText(cPoint(xText, yTitle), CutText(title, textWidthMax, fontHeaderLarge).c_str(), theme.Color(clrFont), theme.Color(clrStatusHeader), fontHeaderLarge); + pixmapHeader->DrawText(cPoint(xText, ySubtitle), CutText(subTitle, textWidthMax, fontHeader).c_str(), theme.Color(clrFont), theme.Color(clrStatusHeader), fontHeader); + //REC Icon + eTimerMatch timerMatch=tmNone; + cTimer *ti; + if (!event) + return; + if (tvguideConfig.useRemoteTimers && pRemoteTimers) { + RemoteTimers_GetMatch_v1_0 rtMatch; + rtMatch.event = event; + pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); + timerMatch = (eTimerMatch)rtMatch.timerMatch; + ti = rtMatch.timer; + } else { + ti=Timers.GetMatch(event, &timerMatch); + } + if (timerMatch == tmFull) { + cString recIconText(" REC "); + int widthIcon = fontManager.FontDetailHeader->Width(*recIconText); + int height = fontManager.FontDetailHeader->Height()+10; + int posX = headerWidth - widthIcon - 20; + int posY = 20; + pixmapHeader->DrawRectangle( cRect(posX, posY, widthIcon, height), theme.Color(clrButtonRed)); + pixmapHeader->DrawText(cPoint(posX, posY+5), *recIconText, theme.Color(clrFont), theme.Color(clrButtonRed), fontManager.FontDetailHeader); + } +} + +void cView::DrawTabs(void) { + if (!pixmapTabs) { + pixmapTabs = osdManager.requestPixmap(4, cRect(0, y + headerHeight + contentHeight, width + scrollbarWidth, tabHeight)); + } + tColor bgColor = theme.Color(clrTabInactive); + pixmapTabs->Fill(clrTransparent); + pixmapTabs->DrawRectangle(cRect(0, 0, width, 2), bgColor); + int numTabs = tabs.size(); + int xCurrent = 0; + for (int tab = 0; tab < numTabs; tab++) { + std::string tabText = tabs[tab]; + int textWidth = font->Width(tabText.c_str()); + int tabWidth = textWidth + border; + pixmapTabs->DrawRectangle(cRect(xCurrent, (tab == activeView) ? 0 : 2, tabWidth - 2, tabHeight), bgColor); + pixmapTabs->DrawEllipse(cRect(xCurrent, tabHeight - border/2, border/2, border/2), clrTransparent, -3); + pixmapTabs->DrawEllipse(cRect(xCurrent + tabWidth - border / 2 - 2, tabHeight - border/2, border/2, border/2), clrTransparent, -4); + if (tab == activeView) { + pixmapTabs->DrawRectangle(cRect(xCurrent + 2, 0, tabWidth - 6, tabHeight - border/2 - 1), clrTransparent); + pixmapTabs->DrawRectangle(cRect(xCurrent + border / 2, tabHeight - border/2 - 1, tabWidth - border, border/2 - 1), clrTransparent); + pixmapTabs->DrawEllipse(cRect(xCurrent + 2, tabHeight - border/2 - 2, border/2, border/2), clrTransparent, 3); + pixmapTabs->DrawEllipse(cRect(xCurrent + tabWidth - border / 2 - 4, tabHeight - border/2 - 2, border/2, border/2), clrTransparent, 4); + } + pixmapTabs->DrawText(cPoint(xCurrent + (tabWidth - textWidth) / 2, 2 + (tabHeight - font->Height())/2), tabText.c_str(), theme.Color(clrFont), (tab == activeView) ? clrTransparent : bgColor, font); + xCurrent += tabWidth; + } +} + +void cView::ClearContent(void) { + if (pixmapContent && Running()) { + osdManager.releasePixmap(pixmapContent); + pixmapContent = NULL; + } + if (pixmapBackground && Running()) { + osdManager.releasePixmap(pixmapBackground); + pixmapBackground = NULL; + } +} + +void cView::CreateContent(int fullHeight) { + scrollable = false; + pixmapBackground = osdManager.requestPixmap(3, cRect(x, y + headerHeight, width + scrollbarWidth, contentHeight + tabHeight)); + pixmapBackground->Fill(theme.Color(clrBackground)); + + int drawPortHeight = contentHeight; + if (fullHeight > contentHeight) { + drawPortHeight = fullHeight; + scrollable = true; + } + pixmapContent = osdManager.requestPixmap(4, cRect(x, y + headerHeight, width, contentHeight), cRect(0, 0, width, drawPortHeight)); + pixmapContent->Fill(clrTransparent); +} + +void cView::DrawContent(std::string *text) { + cTextWrapper wText; + wText.Set(text->c_str(), font, width - 2 * border); + int lineHeight = font->Height(); + int textLines = wText.Lines(); + int textHeight = lineHeight * textLines + 2*border; + int yText = border; + CreateContent(textHeight); + for (int i=0; i < textLines; i++) { + pixmapContent->DrawText(cPoint(border, yText), wText.GetLine(i), theme.Color(clrFont), clrTransparent, font); + yText += lineHeight; + } +} + +void cView::DrawFloatingContent(std::string *infoText, cTvMedia *img, cTvMedia *img2) { + cTextWrapper wTextTall; + cTextWrapper wTextFull; + int imgWidth = img->width; + int imgHeight = img->height; + int imgWidth2 = 0; + int imgHeight2 = 0; + if (imgHeight > (contentHeight - 2 * border)) { + imgHeight = contentHeight - 2 * border; + imgWidth = imgWidth * ((double)imgHeight / (double)img->height); + } + int imgHeightTotal = imgHeight; + if (img2) { + imgWidth2 = imgWidth; + imgHeight2 = img2->height * ((double)img2->width / (double)imgWidth2); + imgHeightTotal += img2->height + border; + } + CreateFloatingTextWrapper(&wTextTall, &wTextFull, infoText, imgWidth, imgHeightTotal); + int lineHeight = font->Height(); + int textLinesTall = wTextTall.Lines(); + int textLinesFull = wTextFull.Lines(); + int textHeight = lineHeight * (textLinesTall + textLinesFull) + 2*border; + int yText = border; + CreateContent(max(textHeight, imgHeight + 2*border)); + for (int i=0; i < textLinesTall; i++) { + pixmapContent->DrawText(cPoint(border, yText), wTextTall.GetLine(i), theme.Color(clrFont), clrTransparent, font); + yText += lineHeight; + } + for (int i=0; i < textLinesFull; i++) { + pixmapContent->DrawText(cPoint(border, yText), wTextFull.GetLine(i), theme.Color(clrFont), clrTransparent, font); + yText += lineHeight; + } + osdManager.flush(); + cImageLoader imgLoader; + if (imgLoader.LoadPoster(img->path.c_str(), imgWidth, imgHeight)) { + if (Running() && pixmapContent) + pixmapContent->DrawImage(cPoint(width - imgWidth - border, border), imgLoader.GetImage()); + } + if (!img2) + return; + osdManager.flush(); + if (imgLoader.LoadPoster(img2->path.c_str(), imgWidth2, imgHeight2)) { + if (Running() && pixmapContent) + pixmapContent->DrawImage(cPoint(width - imgWidth2 - border, imgHeight + 2*border), imgLoader.GetImage()); + } +} + +void cView::CreateFloatingTextWrapper(cTextWrapper *twNarrow, cTextWrapper *twFull, std::string *text, int widthImg, int heightImg) { + int lineHeight = font->Height(); + int linesNarrow = (heightImg + 2*border)/ lineHeight; + int linesDrawn = 0; + int y = 0; + int widthNarrow = width - 3 * border - widthImg; + 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; iSet(sstrTextTall.str().c_str(), font, widthNarrow); + twFull->Set(sstrTextFull.str().c_str(), font, width - 2 * border); +} + +void cView::DrawActors(std::vector *actors) { + int numActors = actors->size(); + if (numActors < 1) { + CreateContent(100); + pixmapContent->DrawText(cPoint(border, border), tr("No Cast available"), theme.Color(clrFont), clrTransparent, fontHeaderLarge); + return; + } + int thumbWidth = actors->at(0).actorThumb.width; + int thumbHeight = actors->at(0).actorThumb.height; + + int picsPerLine = width / (thumbWidth + 2 * border); + if (picsPerLine < 1) + return; + + int picLines = numActors / picsPerLine; + if (numActors%picsPerLine != 0) + picLines++; + + int totalHeight = picLines * (thumbHeight + 2*fontSmall->Height() + border + border/2) + 2*border + fontHeaderLarge->Height(); + + CreateContent(totalHeight); + cString header = cString::sprintf("%s:", tr("Cast")); + pixmapContent->DrawText(cPoint(border, border), *header, theme.Color(clrFont), clrTransparent, fontHeaderLarge); + + int x = 0; + int y = 2 * border + fontHeaderLarge->Height(); + if (!Running()) + return; + cImageLoader imgLoader; + int actor = 0; + for (int row = 0; row < picLines; row++) { + for (int col = 0; col < picsPerLine; col++) { + if (!Running()) + return; + if (actor == numActors) + break; + std::string path = actors->at(actor).actorThumb.path; + std::string name = actors->at(actor).name; + std::stringstream sstrRole; + sstrRole << "\"" << actors->at(actor).role << "\""; + std::string role = sstrRole.str(); + if (imgLoader.LoadPoster(path.c_str(), thumbWidth, thumbHeight)) { + if (Running() && pixmapContent) + pixmapContent->DrawImage(cPoint(x + border, y), imgLoader.GetImage()); + } + + if (fontSmall->Width(name.c_str()) > thumbWidth + 2*border) + name = CutText(name, thumbWidth + 2*border, fontSmall); + if (fontSmall->Width(role.c_str()) > thumbWidth + 2*border) + role = CutText(role, thumbWidth + 2*border, fontSmall); + int xName = x + ((thumbWidth+2*border) - fontSmall->Width(name.c_str()))/2; + int xRole = x + ((thumbWidth+2*border) - fontSmall->Width(role.c_str()))/2; + if (Running() && pixmapContent) { + pixmapContent->DrawText(cPoint(xName, y + thumbHeight + border/2), name.c_str(), theme.Color(clrFont), clrTransparent, fontSmall); + pixmapContent->DrawText(cPoint(xRole, y + thumbHeight + border/2 + fontSmall->Height()), role.c_str(), theme.Color(clrFont), clrTransparent, fontSmall); + x += thumbWidth + 2*border; + } + actor++; + } + osdManager.flush(); + x = 0; + y += thumbHeight + 2 * fontSmall->Height() + border + border/2; + } +} + +void cView::ClearScrollbar(void) { + if (pixmapScrollbar) + pixmapScrollbar->Fill(clrTransparent); + if (pixmapScrollbarBack) + pixmapScrollbarBack->Fill(clrTransparent); +} + +void cView::ClearScrollbarImage(void) { + if (imgScrollBar) { + delete imgScrollBar; + imgScrollBar = NULL; + } +} + +void cView::DrawScrollbar(void) { + ClearScrollbar(); + if (!scrollable || !pixmapContent) + return; + + if (!pixmapScrollbar) { + pixmapScrollbar = osdManager.requestPixmap(6, cRect(width, y + headerHeight, scrollbarWidth, contentHeight)); + pixmapScrollbar->Fill(clrTransparent); + } + if (!pixmapScrollbarBack) { + pixmapScrollbarBack = osdManager.requestPixmap(5, cRect(width, y + headerHeight, scrollbarWidth, contentHeight)); + pixmapScrollbarBack->Fill(clrTransparent); + } + + int totalBarHeight = pixmapScrollbar->ViewPort().Height() - 6; + + int aktHeight = (-1)*pixmapContent->DrawPort().Point().Y(); + int totalHeight = pixmapContent->DrawPort().Height(); + int screenHeight = pixmapContent->ViewPort().Height(); + + int barHeight = (double)(screenHeight * totalBarHeight) / (double)totalHeight ; + int barTop = (double)(aktHeight * totalBarHeight) / (double)totalHeight ; + + if (!imgScrollBar) { + imgScrollBar = CreateScrollbarImage(pixmapScrollbar->ViewPort().Width()-10, barHeight, theme.Color(clrHighlight), theme.Color(clrHighlightBlending)); + } + + pixmapScrollbarBack->Fill(theme.Color(clrHighlightBlending)); + pixmapScrollbarBack->DrawRectangle(cRect(2, 2, pixmapScrollbar->ViewPort().Width() - 4, pixmapScrollbar->ViewPort().Height() - 4), theme.Color(clrHighlightBlending)); + + pixmapScrollbar->DrawImage(cPoint(3, 3 + barTop), *imgScrollBar); +} + +cImage *cView::CreateScrollbarImage(int width, int height, tColor clrBgr, tColor clrBlend) { + cImage *image = new cImage(cSize(width, height)); + image->Fill(clrBgr); + if (tvguideConfig.style != eStyleFlat) { + int numSteps = 64; + int alphaStep = 0x03; + if (height < 30) + return image; + else if (height < 100) { + numSteps = 32; + alphaStep = 0x06; + } + int stepY = 0.5*height / numSteps; + if (stepY == 0) + stepY = 1; + int alpha = 0x40; + tColor clr; + for (int i = 0; iSetPixel(cPoint(x,y), clr); + } + } + alpha += alphaStep; + } + } + return image; +} + +bool cView::KeyUp(void) { + if (!scrollable) + return false; + int aktHeight = pixmapContent->DrawPort().Point().Y(); + int lineHeight = font->Height(); + if (aktHeight >= 0) { + return false; + } + int step = tvguideConfig.detailedViewScrollStep * font->Height(); + int newY = aktHeight + step; + if (newY > 0) + newY = 0; + pixmapContent->SetDrawPortPoint(cPoint(0, newY)); + return true; +} + +bool cView::KeyDown(void) { + if (!scrollable) + return false; + int aktHeight = pixmapContent->DrawPort().Point().Y(); + int totalHeight = pixmapContent->DrawPort().Height(); + int screenHeight = pixmapContent->ViewPort().Height(); + + if (totalHeight - ((-1)*aktHeight) == screenHeight) { + return false; + } + int step = tvguideConfig.detailedViewScrollStep * font->Height(); + int newY = aktHeight - step; + if ((-1)*newY > totalHeight - screenHeight) + newY = (-1)*(totalHeight - screenHeight); + pixmapContent->SetDrawPortPoint(cPoint(0, newY)); + return true; +} + +/******************************************************************************************** +* cEPGView : cView +********************************************************************************************/ + +cEPGView::cEPGView(void) : cView() { + tabbed = true; + numEPGPics = -1; + numTabs = 0; +} + +cEPGView::~cEPGView(void) { + Cancel(-1); + while (Active()) + cCondWait::SleepMs(10); +} + +void cEPGView::SetTabs(void) { + tabs.push_back(tr("EPG Info")); + if (eventID > 0) + tabs.push_back(tr("Reruns")); + else + tabs.push_back(tr("Recording Information")); + if (numEPGPics > 0) + tabs.push_back(tr("Image Galery")); + numTabs = tabs.size(); +} + +void cEPGView::CheckEPGImages(void) { + if (eventID > 0) { + for (int i=1; i <= tvguideConfig.numAdditionalEPGPictures; i++) { + cString epgimage; + epgimage = cString::sprintf("%s%d_%d.jpg", *tvguideConfig.epgImagePath, eventID, i); + FILE *fp = fopen(*epgimage, "r"); + if (fp) { + std::stringstream ss; + ss << i; + epgPics.push_back(ss.str()); + fclose(fp); + } else { + break; + } + } + } else { + return; + } + numEPGPics = epgPics.size(); +} + +void cEPGView::DrawImages(void) { + int imgWidth = tvguideConfig.epgImageWidthLarge; + int imgHeight = tvguideConfig.epgImageHeightLarge; + + int totalHeight = numEPGPics * (imgHeight + border); + + CreateContent(totalHeight); + + cImageLoader imgLoader; + int yPic = border; + for (int pic = 0; pic < numEPGPics; pic++) { + bool drawPic = false; + if (eventID > 0) { + cString epgimage = cString::sprintf("%d_%d", eventID, atoi(epgPics[pic].c_str())); + if (imgLoader.LoadAdditionalEPGImage(epgimage)) { + drawPic = true; + } + + } + if (drawPic) { + pixmapContent->DrawImage(cPoint((width - imgWidth) / 2, yPic), imgLoader.GetImage()); + yPic += imgHeight + border; + osdManager.flush(); + } + } +} + +void cEPGView::KeyLeft(void) { + if (Running()) + return; + ClearScrollbarImage(); + activeView--; + if (activeView < 0) + activeView = numTabs - 1; +} + +void cEPGView::KeyRight(void) { + if (Running()) + return; + ClearScrollbarImage(); + activeView = (activeView + 1) % numTabs; +} + +void cEPGView::Action(void) { + ClearContent(); + if (!headerDrawn) { + DrawHeader(); + osdManager.flush(); + headerDrawn = true; + } + if (tabs.size() == 0) { + CheckEPGImages(); + SetTabs(); + } + DrawTabs(); + switch (activeView) { + case evtInfo: + DrawContent(&infoText); + break; + case evtAddInfo: + DrawContent(&addInfoText); + break; + case evtImages: + DrawImages(); + break; + } + DrawScrollbar(); + osdManager.flush(); +} + +/******************************************************************************************** +* cSeriesView : cView +********************************************************************************************/ + +cSeriesView::cSeriesView(int seriesId, int episodeId) : cView() { + this->seriesId = seriesId; + this->episodeId = episodeId; + tvdbInfo = ""; + tabbed = true; +} + +cSeriesView::~cSeriesView(void) { + Cancel(-1); + while (Active()) + cCondWait::SleepMs(10); +} + +void cSeriesView::LoadMedia(void) { + static cPlugin *pScraper2Vdr = cPluginManager::GetPlugin("scraper2vdr"); + if (!pScraper2Vdr || seriesId < 1) + return; + series.seriesId = seriesId; + series.episodeId = episodeId; + pScraper2Vdr->Service("GetSeries", &series); +} + +void cSeriesView::SetTabs(void) { + tabs.push_back(tr("EPG Info")); + if (eventID > 0) + tabs.push_back(tr("Reruns")); + else + tabs.push_back(tr("Recording Information")); + tabs.push_back(tr("Cast")); + tabs.push_back(tr("TheTVDB Info")); + tabs.push_back(tr("Image Galery")); +} + +void cSeriesView::CreateTVDBInfo(void) { + if (tvdbInfo.size() > 0) + return; + std::stringstream info; + info << tr("TheTVDB Information") << ":\n\n"; + + if (series.episode.name.size() > 0) { + info << tr("Episode") << ": " << series.episode.name << " (" << tr("Season") << " " << series.episode.season << ", " << tr("Episode") << " " << series.episode.number << ")\n\n"; + } + if (series.episode.overview.size() > 0) { + info << tr("Episode Overview") << ": " << series.episode.overview << "\n\n"; + } + if (series.episode.firstAired.size() > 0) { + info << tr("First aired") << ": " << series.episode.firstAired << "\n\n"; + } + if (series.episode.guestStars.size() > 0) { + info << tr("Guest Stars") << ": " << series.episode.guestStars << "\n\n"; + } + if (series.episode.rating > 0) { + info << tr("TheMovieDB Rating") << ": " << series.episode.rating << "\n\n"; + } + if (series.overview.size() > 0) { + info << tr("Series Overview") << ": " << series.overview << "\n\n"; + } + if (series.firstAired.size() > 0) { + info << tr("First aired") << ": " << series.firstAired << "\n\n"; + } + if (series.genre.size() > 0) { + info << tr("Genre") << ": " << series.genre << "\n\n"; + } + if (series.network.size() > 0) { + info << tr("Network") << ": " << series.network << "\n\n"; + } + if (series.rating > 0) { + info << tr("TheMovieDB Rating") << ": " << series.rating << "\n\n"; + } + if (series.status.size() > 0) { + info << tr("Status") << ": " << series.status << "\n\n"; + } + tvdbInfo = info.str(); +} + +void cSeriesView::DrawImages(void) { + int numPosters = series.posters.size(); + int numFanarts = series.fanarts.size(); + int numBanners = series.banners.size(); + + int totalHeight = border; + //Fanart Height + int fanartWidth = width - 2 * border; + int fanartHeight = 0; + if (numFanarts > 0 && series.fanarts[0].width > 0) { + fanartHeight = series.fanarts[0].height * ((double)fanartWidth / (double)series.fanarts[0].width); + if (fanartHeight > contentHeight - 2 * border) { + int fanartHeightOrig = fanartHeight; + fanartHeight = contentHeight - 2 * border; + fanartWidth = fanartWidth * ((double)fanartHeight / (double)fanartHeightOrig); + } + totalHeight += series.fanarts.size() * (fanartHeight + border); + } + //Poster Height + int posterWidth = (width - 4 * border) / 2; + int posterHeight = 0; + if (numPosters > 0 && series.posters[0].width > 0) { + posterHeight = series.posters[0].height * ((double)posterWidth / (double)series.posters[0].width); + } + if (numPosters > 0) + totalHeight += posterHeight + border; + if (numPosters == 3) + totalHeight += posterHeight + border; + //Banners Height + if (numBanners > 0) + totalHeight += (series.banners[0].height + border) * numBanners; + + CreateContent(totalHeight); + + cImageLoader imgLoader; + int yPic = border; + for (int i=0; i < numFanarts; i++) { + if (numBanners > i) { + if (imgLoader.LoadPoster(series.banners[i].path.c_str(), series.banners[i].width, series.banners[i].height) && Running()) { + pixmapContent->DrawImage(cPoint((width - series.banners[i].width) / 2, yPic), imgLoader.GetImage()); + yPic += series.banners[i].height + border; + osdManager.flush(); + } + } + if (imgLoader.LoadPoster(series.fanarts[i].path.c_str(), fanartWidth, fanartHeight) && Running()) { + pixmapContent->DrawImage(cPoint((width - fanartWidth)/2, yPic), imgLoader.GetImage()); + yPic += fanartHeight + border; + osdManager.flush(); + } + } + if (numPosters >= 1) { + if (imgLoader.LoadPoster(series.posters[0].path.c_str(), posterWidth, posterHeight) && Running()) { + pixmapContent->DrawImage(cPoint(border, yPic), imgLoader.GetImage()); + osdManager.flush(); + yPic += posterHeight + border; + } + } + if (numPosters >= 2) { + if (imgLoader.LoadPoster(series.posters[1].path.c_str(), posterWidth, posterHeight) && Running()) { + pixmapContent->DrawImage(cPoint(2 * border + posterWidth, yPic - posterHeight - border), imgLoader.GetImage()); + osdManager.flush(); + } + } + if (numPosters == 3) { + if (imgLoader.LoadPoster(series.posters[2].path.c_str(), posterWidth, posterHeight) && Running()) { + pixmapContent->DrawImage(cPoint((width - posterWidth) / 2, yPic), imgLoader.GetImage()); + osdManager.flush(); + } + } +} + +int cSeriesView::GetRandomPoster(void) { + int numPosters = series.posters.size(); + if (numPosters == 0) + return -1; + srand((unsigned)time(NULL)); + int randPoster = rand()%numPosters; + return randPoster; +} + +void cSeriesView::KeyLeft(void) { + if (Running()) + return; + ClearScrollbarImage(); + activeView--; + if (activeView < 0) + activeView = mvtCount - 1; +} + +void cSeriesView::KeyRight(void) { + if (Running()) + return; + ClearScrollbarImage(); + activeView = (activeView + 1) % mvtCount; +} + +void cSeriesView::Action(void) { + ClearContent(); + if (!headerDrawn) { + DrawHeader(); + osdManager.flush(); + headerDrawn = true; + } + if (tabs.size() == 0) { + SetTabs(); + } + DrawTabs(); + int randomPoster = GetRandomPoster(); + switch (activeView) { + case mvtInfo: + if (randomPoster >= 0) { + DrawFloatingContent(&infoText, &series.posters[randomPoster]); + } else + DrawContent(&infoText); + break; + case mvtAddInfo: + if (randomPoster >= 0) + DrawFloatingContent(&addInfoText, &series.posters[randomPoster]); + else + DrawContent(&addInfoText); + break; + case mvtCast: + DrawActors(&series.actors); + break; + case mvtOnlineInfo: + CreateTVDBInfo(); + if ((series.seasonPoster.path.size() > 0) && series.episode.episodeImage.path.size() > 0) + DrawFloatingContent(&tvdbInfo, &series.episode.episodeImage, &series.seasonPoster); + else if (series.seasonPoster.path.size() > 0) + DrawFloatingContent(&tvdbInfo, &series.seasonPoster); + else if (series.episode.episodeImage.path.size() > 0) + DrawFloatingContent(&tvdbInfo, &series.episode.episodeImage); + else if (randomPoster >= 0) + DrawFloatingContent(&tvdbInfo, &series.posters[randomPoster]); + else + DrawContent(&tvdbInfo); + break; + case mvtImages: + DrawImages(); + break; + } + DrawScrollbar(); + osdManager.flush(); +} + +/******************************************************************************************** +* cMovieView : cView +********************************************************************************************/ + +cMovieView::cMovieView(int movieId) : cView() { + this->movieId = movieId; + tabbed = true; +} + +cMovieView::~cMovieView(void) { + Cancel(-1); + while (Active()) + cCondWait::SleepMs(10); +} + +void cMovieView::LoadMedia(void) { + static cPlugin *pScraper2Vdr = cPluginManager::GetPlugin("scraper2vdr"); + if (!pScraper2Vdr || movieId < 1) + return; + movie.movieId = movieId; + pScraper2Vdr->Service("GetMovie", &movie); +} + +void cMovieView::SetTabs(void) { + tabs.push_back(tr("EPG Info")); + if (eventID > 0) + tabs.push_back(tr("Reruns")); + else + tabs.push_back(tr("Recording Information")); + tabs.push_back(tr("Cast")); + tabs.push_back(tr("TheTVDB Info")); + tabs.push_back(tr("Image Galery")); +} + +void cMovieView::CreateMovieDBInfo(void) { + if (movieDBInfo.size() > 0) + return; + std::stringstream info; + info << tr("TheMovieDB Information") << ":\n\n"; + if (movie.originalTitle.size() > 0) { + info << tr("Original Title") << ": " << movie.originalTitle << "\n\n"; + } + if (movie.tagline.size() > 0) { + info << tr("Tagline") << ": " << movie.tagline << "\n\n"; + } + if (movie.overview.size() > 0) { + info << tr("Overview") << ": " << movie.overview << "\n\n"; + } + std::string strAdult = (movie.adult)?(tr("yes")):(tr("no")); + info << tr("Adult") << ": " << strAdult << "\n\n"; + if (movie.collectionName.size() > 0) { + info << tr("Collection") << ": " << movie.collectionName << "\n\n"; + } + if (movie.budget > 0) { + info << tr("Budget") << ": " << movie.budget << "$\n\n"; + } + if (movie.revenue > 0) { + info << tr("Revenue") << ": " << movie.revenue << "$\n\n"; + } + if (movie.genres.size() > 0) { + info << tr("Genre") << ": " << movie.genres << "\n\n"; + } + if (movie.homepage.size() > 0) { + info << tr("Homepage") << ": " << movie.homepage << "\n\n"; + } + if (movie.releaseDate.size() > 0) { + info << tr("Release Date") << ": " << movie.releaseDate << "\n\n"; + } + if (movie.runtime > 0) { + info << tr("Runtime") << ": " << movie.runtime << " " << tr("minutes") << "\n\n"; + } + if (movie.popularity > 0) { + info << tr("TheMovieDB Popularity") << ": " << movie.popularity << "\n\n"; + } + if (movie.voteAverage > 0) { + info << tr("TheMovieDB Vote Average") << ": " << movie.voteAverage << "\n\n"; + } + movieDBInfo = info.str(); +} + +void cMovieView::DrawImages(void) { + int totalHeight = border; + //Fanart Height + int fanartWidth = width - 2 * border; + int fanartHeight = 0; + if (movie.fanart.width > 0 && movie.fanart.height > 0 && movie.fanart.path.size() > 0) { + fanartHeight = movie.fanart.height * ((double)fanartWidth / (double)movie.fanart.width); + if (fanartHeight > contentHeight - 2 * border) { + int fanartHeightOrig = fanartHeight; + fanartHeight = contentHeight - 2 * border; + fanartWidth = fanartWidth * ((double)fanartHeight / (double)fanartHeightOrig); + } + totalHeight += fanartHeight + border; + } + //Collection Fanart Height + int collectionFanartWidth = width - 2 * border; + int collectionFanartHeight = 0; + if (movie.collectionFanart.width > 0 && movie.collectionFanart.height > 0 && movie.collectionFanart.path.size() > 0) { + collectionFanartHeight = movie.collectionFanart.height * ((double)collectionFanartWidth / (double)movie.collectionFanart.width); + if (collectionFanartHeight > contentHeight - 2 * border) { + int fanartHeightOrig = collectionFanartHeight; + collectionFanartHeight = contentHeight - 2 * border; + collectionFanartWidth = collectionFanartWidth * ((double)collectionFanartHeight / (double)fanartHeightOrig); + } + totalHeight += collectionFanartHeight + border; + } + //Poster Height + if (movie.poster.width > 0 && movie.poster.height > 0 && movie.poster.path.size() > 0) { + totalHeight += movie.poster.height + border; + } + //Collection Popster Height + if (movie.collectionPoster.width > 0 && movie.collectionPoster.height > 0 && movie.collectionPoster.path.size() > 0) { + totalHeight += movie.collectionPoster.height + border; + } + + CreateContent(totalHeight); + + cImageLoader imgLoader; + int yPic = border; + if (movie.fanart.width > 0 && movie.fanart.height > 0 && movie.fanart.path.size() > 0) { + if (imgLoader.LoadPoster(movie.fanart.path.c_str(), fanartWidth, fanartHeight) && Running()) { + pixmapContent->DrawImage(cPoint((width - fanartWidth)/2, yPic), imgLoader.GetImage()); + yPic += fanartHeight + border; + osdManager.flush(); + } + } + if (movie.collectionFanart.width > 0 && movie.collectionFanart.height > 0 && movie.collectionFanart.path.size() > 0) { + if (imgLoader.LoadPoster(movie.collectionFanart.path.c_str(), collectionFanartWidth, collectionFanartHeight) && Running()) { + pixmapContent->DrawImage(cPoint((width - collectionFanartWidth)/2, yPic), imgLoader.GetImage()); + yPic += collectionFanartHeight + border; + osdManager.flush(); + } + } + if (movie.poster.width > 0 && movie.poster.height > 0 && movie.poster.path.size() > 0) { + if (imgLoader.LoadPoster(movie.poster.path.c_str(), movie.poster.width, movie.poster.height) && Running()) { + pixmapContent->DrawImage(cPoint((width - movie.poster.width) / 2, yPic), imgLoader.GetImage()); + yPic += movie.poster.height + border; + osdManager.flush(); + } + } + if (movie.collectionPoster.width > 0 && movie.collectionPoster.height > 0 && movie.collectionPoster.path.size() > 0) { + if (imgLoader.LoadPoster(movie.collectionPoster.path.c_str(), movie.collectionPoster.width, movie.collectionPoster.height) && Running()) { + pixmapContent->DrawImage(cPoint((width - movie.collectionPoster.width) / 2, yPic), imgLoader.GetImage()); + yPic += movie.collectionPoster.height + border; + osdManager.flush(); + } + } +} + +void cMovieView::KeyLeft(void) { + if (Running()) + return; + ClearScrollbarImage(); + activeView--; + if (activeView < 0) + activeView = mvtCount - 1; +} + +void cMovieView::KeyRight(void) { + if (Running()) + return; + ClearScrollbarImage(); + activeView = (activeView + 1) % mvtCount; +} + +void cMovieView::Action(void) { + ClearContent(); + if (!headerDrawn) { + DrawHeader(); + osdManager.flush(); + headerDrawn = true; + } + if (tabs.size() == 0) { + SetTabs(); + } + DrawTabs(); + bool posterAvailable = (movie.poster.path.size() > 0 && movie.poster.width > 0 && movie.poster.height > 0) ? true : false; + switch (activeView) { + case mvtInfo: + if (posterAvailable) + DrawFloatingContent(&infoText, &movie.poster); + else + DrawContent(&infoText); + break; + case mvtAddInfo: + if (posterAvailable) + DrawFloatingContent(&addInfoText, &movie.poster); + else + DrawContent(&addInfoText); + break; + case mvtCast: + DrawActors(&movie.actors); + break; + case mvtOnlineInfo: + CreateMovieDBInfo(); + if (posterAvailable) + DrawFloatingContent(&movieDBInfo, &movie.poster); + else + DrawContent(&movieDBInfo); + break; + case mvtImages: + DrawImages(); + break; + } + DrawScrollbar(); + osdManager.flush(); +} \ No newline at end of file diff --git a/view.h b/view.h new file mode 100644 index 0000000..5581390 --- /dev/null +++ b/view.h @@ -0,0 +1,149 @@ +#ifndef __TVGUIDE_VIEW_H +#define __TVGUIDE_VIEW_H + +#include +#include +#include +#include +#include "services/scraper2vdr.h" +#include "services/epgsearch.h" +#include "services/remotetimers.h" +#include "config.h" +#include "imagecache.h" +#include "imageloader.h" +#include "tools.h" + +enum eEPGViewTabs { + evtInfo = 0, + evtAddInfo, + evtImages, + evtCount +}; + +enum eMediaViewTabs { + mvtInfo = 0, + mvtAddInfo, + mvtCast, + mvtOnlineInfo, + mvtImages, + mvtCount +}; + +class cView : public cThread { +protected: + const cEvent *event; + cPixmap *pixmapBackground; + cStyledPixmap *pixmapHeader; + cPixmap *pixmapHeaderLogo; + cPixmap *pixmapContent; + cPixmap *pixmapScrollbar; + cPixmap *pixmapScrollbarBack; + cPixmap *pixmapTabs; + cFont *font, *fontSmall, *fontHeader, *fontHeaderLarge; + cImage *imgScrollBar; + int activeView; + bool scrollable; + bool tabbed; + int x, y; + int width, height; + int border; + int headerWidth, headerHeight; + int contentHeight; + int tabHeight; + int scrollbarWidth; + std::vector tabs; + std::string title; + std::string subTitle; + std::string dateTime; + std::string infoText; + std::string addInfoText; + const cChannel *channel; + int eventID; + bool headerDrawn; + void DrawHeader(void); + void ClearContent(void); + void CreateContent(int fullHeight); + void DrawContent(std::string *text); + void DrawFloatingContent(std::string *infoText, cTvMedia *img, cTvMedia *img2 = NULL); + void CreateFloatingTextWrapper(cTextWrapper *twNarrow, cTextWrapper *twFull, std::string *text, int widthImg, int heightImg); + void DrawActors(std::vector *actors); + void ClearScrollbar(void); + void ClearScrollbarImage(void); + cImage *CreateScrollbarImage(int width, int height, tColor clrBgr, tColor clrBlend); + virtual void SetTabs(void) {}; + void DrawTabs(void); +public: + cView(void); + virtual ~cView(void); + void SetTitle(const char *t) { title = t ? t : ""; }; + void SetSubTitle(const char *s) { subTitle = s ? s : ""; }; + void SetDateTime(const char *dt) { dateTime = dt; }; + void SetInfoText(const char *i) { infoText = i ? i : ""; }; + void SetAdditionalInfoText(std::string addInfo) { addInfoText = addInfo; }; + void SetChannel(const cChannel *c) { channel = c; }; + void SetEventID(int id) { eventID = id; }; + void SetEvent(const cEvent *event) { this->event = event; }; + virtual void LoadMedia(void) {}; + void SetGeometry(void); + void SetFonts(void); + virtual bool KeyUp(void); + virtual bool KeyDown(void); + virtual void KeyLeft(void) {}; + virtual void KeyRight(void) {}; + void DrawScrollbar(void); + virtual void Action(void) {}; +}; + +class cEPGView : public cView { +protected: + std::vector epgPics; + int numEPGPics; + int numTabs; + void SetTabs(void); + void CheckEPGImages(void); + void DrawImages(void); +public: + cEPGView(void); + virtual ~cEPGView(void); + void KeyLeft(void); + void KeyRight(void); + void Action(void); +}; + +class cSeriesView : public cView { +protected: + int seriesId; + int episodeId; + cSeries series; + std::string tvdbInfo; + void SetTabs(void); + void CreateTVDBInfo(void); + void DrawImages(void); + int GetRandomPoster(void); +public: + cSeriesView(int seriesId, int episodeId); + virtual ~cSeriesView(void); + void LoadMedia(void); + void KeyLeft(void); + void KeyRight(void); + void Action(void); +}; + +class cMovieView : public cView { +protected: + int movieId; + cMovie movie; + std::string movieDBInfo; + void SetTabs(void); + void CreateMovieDBInfo(void); + void DrawImages(void); +public: + cMovieView(int movieId); + virtual ~cMovieView(void); + void LoadMedia(void); + void KeyLeft(void); + void KeyRight(void); + void Action(void); +}; + +#endif //__TVGUIDE_VIEW_H \ No newline at end of file