From 9eabdcd20960924b690d6820691c6159618d18e7 Mon Sep 17 00:00:00 2001 From: louis Date: Sun, 25 Aug 2013 13:57:10 +0200 Subject: [PATCH] Added tvscraper support --- HISTORY | 2 + config.c | 3 + config.h | 2 + detailview.c | 360 +++++++++++++++++++++++++++++++++++++------ detailview.h | 27 +++- imageloader.c | 19 +++ imageloader.h | 2 + po/de_DE.po | 5 +- services/tvscraper.h | 56 +++++++ statusheader.c | 47 +++++- statusheader.h | 2 + tvguide.c | 2 +- tvguideosd.c | 5 +- 13 files changed, 475 insertions(+), 57 deletions(-) create mode 100644 services/tvscraper.h diff --git a/HISTORY b/HISTORY index 4f96383..13c04da 100644 --- a/HISTORY +++ b/HISTORY @@ -63,3 +63,5 @@ VDR Plugin 'tvguide' Revision History - Pimped timeline 2013-07-23: Version 1.0.0 + +- added tvscraper support diff --git a/config.c b/config.c index 6c2c708..4d74d5f 100644 --- a/config.c +++ b/config.c @@ -67,6 +67,7 @@ cTvguideConfig::cTvguideConfig() { fontNameDefault = "VDRSymbols Sans:Book"; FontButtonDelta = 0; FontDetailViewDelta = 0; + FontDetailViewSmallDelta = 0; FontDetailHeaderDelta = 0; FontMessageBoxDelta = 0; FontMessageBoxLargeDelta = 0; @@ -123,6 +124,7 @@ cTvguideConfig::cTvguideConfig() { cTvguideConfig::~cTvguideConfig() { delete FontButton; delete FontDetailView; + delete FontDetailViewSmall; delete FontDetailHeader; delete FontMessageBox; delete FontMessageBoxLarge; @@ -197,6 +199,7 @@ void cTvguideConfig::SetFonts(void){ //Common Fonts FontButton = cFont::CreateFont(*fontname, footerHeight/3 + 4 + FontButtonDelta); FontDetailView = cFont::CreateFont(*fontname, osdHeight/30 + FontDetailViewDelta); + FontDetailViewSmall = cFont::CreateFont(*fontname, osdHeight/40 + FontDetailViewSmallDelta); FontDetailHeader = cFont::CreateFont(*fontname, osdHeight/25 + FontDetailHeaderDelta); FontMessageBox = cFont::CreateFont(*fontname, osdHeight/33 + FontMessageBoxDelta); FontMessageBoxLarge = cFont::CreateFont(*fontname, osdHeight/30 + FontMessageBoxLargeDelta); diff --git a/config.h b/config.h index e7ae176..a92038c 100644 --- a/config.h +++ b/config.h @@ -71,6 +71,7 @@ class cTvguideConfig { const char *fontNameDefault; int FontButtonDelta; int FontDetailViewDelta; + int FontDetailViewSmallDelta; int FontDetailHeaderDelta; int FontMessageBoxDelta; int FontMessageBoxLargeDelta; @@ -108,6 +109,7 @@ class cTvguideConfig { const cFont *FontTimeLineTimeHorizontal; const cFont *FontButton; const cFont *FontDetailView; + const cFont *FontDetailViewSmall; const cFont *FontDetailHeader; const cFont *FontMessageBox; const cFont *FontMessageBoxLarge; diff --git a/detailview.c b/detailview.c index 4f14bba..abb1955 100644 --- a/detailview.c +++ b/detailview.c @@ -4,11 +4,58 @@ cDetailView::cDetailView(const cEvent *event) { this->event = event; imgScrollBar = NULL; - borderWidth = 100; //px + borderWidth = 20; //px, border around window + border = 10; //px, border in view window scrollBarWidth = 40; headerHeight = max (40 + 3 * tvguideConfig.FontDetailHeader->Height(), // border + 3 Lines 40 + tvguideConfig.epgImageHeight); - description.Set(event->Description(), tvguideConfig.FontDetailView, tvguideConfig.osdWidth-2*borderWidth - 50 - 40); + pixmapPoster = NULL; + width = tvguideConfig.osdWidth-2*borderWidth; + contentWidth = width - scrollBarWidth; + contentX = borderWidth; + contentHeight = tvguideConfig.osdHeight-2*borderWidth-headerHeight; + widthPoster = 30 * contentWidth / 100; +} + +cDetailView::~cDetailView(void){ + Cancel(-1); + while (Active()) + cCondWait::SleepMs(10); + delete header; + header = NULL; + osdManager.releasePixmap(headerLogo); + headerLogo = NULL; + osdManager.releasePixmap(headerBack); + headerBack = NULL; + osdManager.releasePixmap(content); + content = NULL; + if (pixmapPoster) + osdManager.releasePixmap(pixmapPoster); + pixmapPoster = NULL; + osdManager.releasePixmap(scrollBar); + scrollBar = NULL; + osdManager.releasePixmap(footer); + footer = NULL; + delete imgScrollBar; +} + +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(), tvguideConfig.FontDetailView, contentWidth - scrollBarWidth - 2*border); if (tvguideConfig.displayRerunsDetailEPGView) { loadReruns(); } @@ -17,45 +64,72 @@ cDetailView::cDetailView(const cEvent *event) { createPixmaps(); } -cDetailView::~cDetailView(void){ - delete header; - osdManager.releasePixmap(headerLogo); - osdManager.releasePixmap(headerBack); - osdManager.releasePixmap(content); - osdManager.releasePixmap(scrollBar); - osdManager.releasePixmap(footer); - delete imgScrollBar; -} - bool cDetailView::setContentDrawportHeight() { - int linesContent = description.Lines() + 1; + int lineHeight = tvguideConfig.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) { - linesContent += reruns.Lines() + 1; + heightReruns = reruns.Lines() * lineHeight; } - heightContent = linesContent * tvguideConfig.FontDetailView->Height(); + //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) { - heightContent += heightEPGPics(); + heightEpgPics = heightEPGPics(); } - if (heightContent > (tvguideConfig.osdHeight - 2 * borderWidth - headerHeight)) + + yBanner = lineHeight; + yEPGText = heightBanner; + yActors = heightBanner + heightEPG; + yFanart = heightBanner + heightEPG + heightActors; + yAddInf = heightBanner + heightEPG + heightActors + heightFanart; + yEPGPics = heightBanner + heightEPG + heightActors + heightFanart + heightReruns; + + int totalHeight = heightBanner + heightEPG + heightActors + heightFanart + heightReruns + heightEpgPics; + //check if pixmap content has to be scrollable + if (totalHeight > contentHeight) { + heightContent = totalHeight; return true; - else + } else { + heightContent = contentHeight; return false; + } + return false; } void cDetailView::createPixmaps() { - header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null)); - headerLogo = osdManager.requestPixmap(6, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null); + header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(borderWidth, borderWidth, width, headerHeight), cRect::Null)); + headerLogo = osdManager.requestPixmap(6, cRect(borderWidth, borderWidth, width, headerHeight), cRect::Null); headerLogo->Fill(clrTransparent); - headerBack = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null); + headerBack = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth, width, headerHeight), cRect::Null); headerBack->Fill(clrBlack); header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); - content = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight, tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth, tvguideConfig.osdHeight-2*borderWidth-headerHeight), - cRect(0,0, tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth, max(heightContent, tvguideConfig.osdHeight-2*borderWidth-headerHeight))); - header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); + content = osdManager.requestPixmap(5, cRect(contentX, borderWidth + headerHeight, contentWidth, contentHeight), + cRect(0,0, contentWidth, max(heightContent, contentHeight))); + if (hasAdditionalMedia) { + pixmapPoster = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth + 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(tvguideConfig.osdWidth-borderWidth-scrollBarWidth, borderWidth + headerHeight, scrollBarWidth, contentHeight)); - scrollBar = osdManager.requestPixmap(5, cRect(tvguideConfig.osdWidth-borderWidth-scrollBarWidth, borderWidth + headerHeight, scrollBarWidth, tvguideConfig.osdHeight-2*borderWidth-headerHeight)); - - footer = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight + content->ViewPort().Height(), tvguideConfig.osdWidth - 2*borderWidth, 3)); + footer = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight + content->ViewPort().Height(), width, 3)); footer->Fill(theme.Color(clrBorder)); } @@ -111,12 +185,12 @@ void cDetailView::drawHeader() { void cDetailView::drawRecIcon() { cString recIconText(" REC "); - int headerWidth = tvguideConfig.osdWidth - 2*borderWidth; - int width = tvguideConfig.FontDetailHeader->Width(*recIconText); + int headerWidth = width; + int widthIcon = tvguideConfig.FontDetailHeader->Width(*recIconText); int height = tvguideConfig.FontDetailHeader->Height()+10; - int posX = headerWidth - width - 20; + int posX = headerWidth - widthIcon - 20; int posY = 20; - header->DrawRectangle( cRect(posX, posY, width, height), theme.Color(clrButtonRed)); + header->DrawRectangle( cRect(posX, posY, widthIcon, height), theme.Color(clrButtonRed)); header->DrawText(cPoint(posX, posY+5), *recIconText, theme.Color(clrFont), theme.Color(clrButtonRed), tvguideConfig.FontDetailHeader); } @@ -127,20 +201,45 @@ void cDetailView::drawContent() { int textHeight = tvguideConfig.FontDetailView->Height(); int textLines = description.Lines(); - int i=0; - for (; iDrawText(cPoint(20, 20 + i*textHeight), description.GetLine(i), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView); + for (int i=0; iDrawText(cPoint(border, yEPGText + i*textHeight), description.GetLine(i), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView); } - i++; if (tvguideConfig.displayRerunsDetailEPGView) { textLines = reruns.Lines(); for (int j=0; jDrawText(cPoint(20, 20 + i*textHeight), reruns.GetLine(j), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView); - i++; + content->DrawText(cPoint(border, yAddInf+ j*textHeight), reruns.GetLine(j), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView); } } - if (!tvguideConfig.hideEpgImages) { - drawEPGPictures((i+1)*textHeight); +} + +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(); } } @@ -149,7 +248,7 @@ void cDetailView::drawScrollbar() { 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() - (tvguideConfig.osdHeight-2*borderWidth-headerHeight)); + scrollBarOffset = (-1.0)*(double)content->DrawPort().Point().Y() / (double)(content->DrawPort().Height() - (contentHeight)); scrollBarOffset *= ( (double)scrollBar->ViewPort().Height()-7.0 - heightScrollbar); scrollBarOffset++; } else { @@ -173,7 +272,7 @@ void cDetailView::scrollUp() { void cDetailView::scrollDown() { if (contentScrollable) { int newDrawportHeight = content->DrawPort().Point().Y() - tvguideConfig.FontDetailView->Height(); - int maxDrawportHeight = (content->DrawPort().Height() - (tvguideConfig.osdHeight-2*borderWidth-headerHeight)); + int maxDrawportHeight = (content->DrawPort().Height() - contentHeight); content->SetDrawPortPoint(cPoint(0, max(newDrawportHeight,(-1)*maxDrawportHeight))); drawScrollbar(); } @@ -274,13 +373,12 @@ void cDetailView::loadReruns(void) { delete list; } } - reruns.Set(sstrReruns.str().c_str(), tvguideConfig.FontDetailView, tvguideConfig.osdWidth-2*borderWidth - 50 - 40); + reruns.Set(sstrReruns.str().c_str(), tvguideConfig.FontDetailView, contentWidth - scrollBarWidth - 2*border); } else - reruns.Set("", tvguideConfig.FontDetailView, tvguideConfig.osdWidth-2*borderWidth - 50 - 40); + reruns.Set("", tvguideConfig.FontDetailView, contentWidth - scrollBarWidth); } int cDetailView::heightEPGPics(void) { - int width = tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth; int border = 5; int numPicsAvailable = 0; for (int i=1; i <= tvguideConfig.numAdditionalEPGPictures; i++) { @@ -294,17 +392,52 @@ int cDetailView::heightEPGPics(void) { } } numEPGPics = numPicsAvailable; - int picsPerLine = width / (tvguideConfig.epgImageWidthLarge + border); + 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*tvguideConfig.FontDetailViewSmall->Height()) + tvguideConfig.FontDetailView->Height() + tvguideConfig.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 width = content->ViewPort().Width(); int border = 5; - int picsPerLine = width / (tvguideConfig.epgImageWidthLarge + border); + int picsPerLine = contentWidth / (tvguideConfig.epgImageWidthLarge + border); int currentX = border; int currentY = height + border; int currentPicsPerLine = 1; @@ -332,6 +465,139 @@ void cDetailView::drawEPGPictures(int height) { } } +void cDetailView::drawPoster(void) { + int border = 10; + if (mediaInfo.posters.size() < 1) + 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()); + } +} + +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.useBlending==0)?theme.Color(clrBackground):clrTransparent; + + cString header = cString::sprintf("%s:", tr("Actors")); + content->DrawText(cPoint(border, height), *header, theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailHeader); + + int picsPerLine = contentWidth / (actorThumbWidth + 2*border); + int picLines = numActors / picsPerLine; + if (numActors%picsPerLine != 0) + picLines++; + int x = 0; + int y = height + tvguideConfig.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 (tvguideConfig.FontDetailViewSmall->Width(name.c_str()) > actorThumbWidth + 2*border) + name = CutText(name, actorThumbWidth + 2*border, tvguideConfig.FontDetailViewSmall); + if (tvguideConfig.FontDetailViewSmall->Width(role.c_str()) > actorThumbWidth + 2*border) + role = CutText(role, actorThumbWidth + 2*border, tvguideConfig.FontDetailViewSmall); + int xName = x + ((actorThumbWidth+2*border) - tvguideConfig.FontDetailViewSmall->Width(name.c_str()))/2; + int xRole = x + ((actorThumbWidth+2*border) - tvguideConfig.FontDetailViewSmall->Width(role.c_str()))/2; + if (Running() && content) { + content->DrawText(cPoint(xName, y + actorThumbHeight), name.c_str(), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailViewSmall); + content->DrawText(cPoint(xRole, y + actorThumbHeight + tvguideConfig.FontDetailViewSmall->Height()), role.c_str(), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailViewSmall); + x += actorThumbWidth + 2*border; + } + actor++; + } + x = 0; + y += actorThumbHeight + 2 * tvguideConfig.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; switch (Key & ~k_Repeat) { diff --git a/detailview.h b/detailview.h index 43c73a6..4cb4ee1 100644 --- a/detailview.h +++ b/detailview.h @@ -5,20 +5,37 @@ class cEpgGrid; -class cDetailView { +class cDetailView : public cThread { private: cStyledPixmap *header; cPixmap *headerLogo; cPixmap *headerBack; cPixmap *content; + cPixmap *pixmapPoster; cPixmap *scrollBar; cPixmap *footer; const cEvent *event; cImage *imgScrollBar; cTextWrapper description; cTextWrapper reruns; + TVScraperGetFullInformation mediaInfo; + bool hasAdditionalMedia; int borderWidth; + int border; 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; @@ -27,16 +44,24 @@ private: 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(); + void Action(void); public: cDetailView(const cEvent *event); virtual ~cDetailView(void); + void setContent(); void createPixmaps(); void drawHeader(); void drawContent(); diff --git a/imageloader.c b/imageloader.c index 292d183..1b8fc71 100644 --- a/imageloader.c +++ b/imageloader.c @@ -59,6 +59,14 @@ bool cImageLoader::LoadAdditionalEPGImage(cString name) { return true; } +bool cImageLoader::LoadPoster(const char *poster, int width, int height) { + if (LoadImage(poster)) { + buffer.sample(Geometry(width, height)); + return true; + } + return false; +} + bool cImageLoader::LoadIcon(const char *cIcon, int size) { if (size==0) return false; @@ -130,3 +138,14 @@ bool cImageLoader::LoadImage(cString FileName, cString Path, cString Extension) } return true; } + +bool cImageLoader::LoadImage(const char *fullpath) { + try { + //dsyslog("tvguide: trying to load: %s", fullpath); + buffer.read(fullpath); + //dsyslog("tvguide: %s sucessfully loaded", fullpath); + } catch (...) { + return false; + } + return true; +} \ No newline at end of file diff --git a/imageloader.h b/imageloader.h index bc2b7dd..8b88ba4 100644 --- a/imageloader.h +++ b/imageloader.h @@ -17,6 +17,7 @@ public: bool LoadLogo(const char *logo, int width, int height); bool LoadEPGImage(int eventID); bool LoadAdditionalEPGImage(cString name); + bool LoadPoster(const char *poster, int width, int height); bool LoadIcon(const char *cIcon, int size); bool DrawBackground(tColor back, tColor blend, int width, int height); private: @@ -24,6 +25,7 @@ private: Color Argb2Color(tColor col); void toLowerCase(std::string &str); bool LoadImage(cString FileName, cString Path, cString Extension); + bool LoadImage(const char *fullpath); }; #endif //_TVGUIDE_IMAGELOADER_H diff --git a/po/de_DE.po b/po/de_DE.po index d279b76..e1f7e70 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: 2013-07-20 12:02+0200\n" +"POT-Creation-Date: 2013-08-25 13:08+0200\n" "PO-Revision-Date: 2012-08-25 17:49+0200\n" "Last-Translator: Horst\n" "Language-Team: \n" @@ -18,6 +18,9 @@ msgstr "Hauptprogramm" msgid "RERUNS OF THIS SHOW" msgstr "Wiederholungen dieser Sendung" +msgid "Actors" +msgstr "" + msgid "No EPG Information available" msgstr "Keine EPG Daten verfügbar" diff --git a/services/tvscraper.h b/services/tvscraper.h new file mode 100644 index 0000000..fc278ad --- /dev/null +++ b/services/tvscraper.h @@ -0,0 +1,56 @@ +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; +}; \ No newline at end of file diff --git a/statusheader.c b/statusheader.c index c798109..0e16d3f 100644 --- a/statusheader.c +++ b/statusheader.c @@ -3,8 +3,7 @@ cStatusHeader::cStatusHeader(void) { color = theme.Color(clrStatusHeader); colorBlending = theme.Color(clrStatusHeaderBlending); - int height = tvguideConfig.statusHeaderHeight; - int width; + height = tvguideConfig.statusHeaderHeight; if (tvguideConfig.scaleVideo) { width = tvguideConfig.osdWidth - height * 16 / 9; } else { @@ -45,7 +44,6 @@ cStatusHeader::~cStatusHeader(void) { void cStatusHeader::ScaleVideo(void) { if (tvguideConfig.scaleVideo) { - int height = tvguideConfig.statusHeaderHeight; int width = height * 16 / 9; int x = osdManager.Left() + tvguideConfig.osdWidth - width; int y = osdManager.Top(); @@ -57,22 +55,28 @@ void cStatusHeader::ScaleVideo(void) { void cStatusHeader::DrawInfoText(cGrid *grid) { int border = 10; + int textWidth = width - 2 * border; tColor colorTextBack = (tvguideConfig.useBlending==0)?color:clrTransparent; pixmapText->Fill(clrTransparent); int x = border; int y = border; if (!grid->isDummy()) { + const cEvent *event = grid->GetEvent(); + int newX = DrawPoster(event, x, y, height-2*border, border); + if (newX > 0) { + textWidth -= (newX - x); + x += newX; + } cString time = grid->getTimeString(); cString title(""); - const cEvent *event = grid->GetEvent(); title = cString::sprintf(": %s", event->Title()); cString header = cString::sprintf("%s%s", *time, *title); - header = CutText(*header, pixmapText->ViewPort().Width() - 2 * border, tvguideConfig.FontStatusHeaderLarge).c_str(); + header = CutText(*header, textWidth, tvguideConfig.FontStatusHeaderLarge).c_str(); pixmapText->DrawText(cPoint(x,y), *header, theme.Color(clrFont), colorTextBack, tvguideConfig.FontStatusHeaderLarge); y += tvguideConfig.FontStatusHeaderLarge->Height() + border; int heightText = pixmapText->ViewPort().Height() - y; cTextWrapper description; - description.Set(event->Description(), tvguideConfig.FontStatusHeader, pixmapText->ViewPort().Width() - 2 * border); + description.Set(event->Description(), tvguideConfig.FontStatusHeader, textWidth); int lineHeight = tvguideConfig.FontStatusHeader->Height(); int textLines = description.Lines(); int maxLines = heightText / lineHeight; @@ -92,3 +96,34 @@ void cStatusHeader::DrawInfoText(cGrid *grid) { pixmapText->DrawText(cPoint(x,y), *grid->getText(), theme.Color(clrFont), colorTextBack, tvguideConfig.FontStatusHeaderLarge); } } + +int cStatusHeader::DrawPoster(const cEvent *event, int x, int y, int height, int border) { + bool hasPoster = false; + TVScraperGetPoster poster; + 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); + } + } + } + } + if (hasPoster) { + cImageLoader imgLoader; + if (imgLoader.LoadPoster(poster.media.path.c_str(), posterWidth, posterHeight)) { + pixmapText->DrawImage(cPoint(x, y), imgLoader.GetImage()); + return posterWidth + border; + } + } + return 0; +} diff --git a/statusheader.h b/statusheader.h index c1acc91..06bd601 100644 --- a/statusheader.h +++ b/statusheader.h @@ -5,8 +5,10 @@ class cStatusHeader : public cStyledPixmap { private: + int width, height; cPixmap *pixmapText; cPixmap *pixmapTVFrame; + int DrawPoster(const cEvent *event, int x, int y, int height, int border); public: cStatusHeader(void); virtual ~cStatusHeader(void); diff --git a/tvguide.c b/tvguide.c index 3b56f55..1d180b0 100644 --- a/tvguide.c +++ b/tvguide.c @@ -21,7 +21,7 @@ -static const char *VERSION = "1.0.0"; +static const char *VERSION = "1.1.0"; static const char *DESCRIPTION = "A fancy 2d EPG Viewer"; static const char *MAINMENUENTRY = "Tvguide"; diff --git a/tvguideosd.c b/tvguideosd.c index 6c0b582..7598118 100644 --- a/tvguideosd.c +++ b/tvguideosd.c @@ -62,7 +62,8 @@ cOsdManager osdManager; #include "services/epgsearch.h" #include "services/remotetimers.h" cPlugin* pRemoteTimers = NULL; - +#include +#include "services/tvscraper.h" #include "tools.c" #include "switchtimer.c" #include "setup.c" @@ -579,9 +580,11 @@ void cTvGuideOsd::DetailedEPG() { if (!activeGrid->isDummy()) { detailViewActive = true; detailView = new cDetailView(activeGrid->GetEvent()); + detailView->setContent(); detailView->drawHeader(); detailView->drawContent(); detailView->drawScrollbar(); + detailView->Start(); osdManager.flush(); } }