Added tvscraper support

This commit is contained in:
louis 2013-08-25 13:57:10 +02:00
parent c545f6b4cf
commit 9eabdcd209
13 changed files with 475 additions and 57 deletions

View File

@ -63,3 +63,5 @@ VDR Plugin 'tvguide' Revision History
- Pimped timeline - Pimped timeline
2013-07-23: Version 1.0.0 2013-07-23: Version 1.0.0
- added tvscraper support

View File

@ -67,6 +67,7 @@ cTvguideConfig::cTvguideConfig() {
fontNameDefault = "VDRSymbols Sans:Book"; fontNameDefault = "VDRSymbols Sans:Book";
FontButtonDelta = 0; FontButtonDelta = 0;
FontDetailViewDelta = 0; FontDetailViewDelta = 0;
FontDetailViewSmallDelta = 0;
FontDetailHeaderDelta = 0; FontDetailHeaderDelta = 0;
FontMessageBoxDelta = 0; FontMessageBoxDelta = 0;
FontMessageBoxLargeDelta = 0; FontMessageBoxLargeDelta = 0;
@ -123,6 +124,7 @@ cTvguideConfig::cTvguideConfig() {
cTvguideConfig::~cTvguideConfig() { cTvguideConfig::~cTvguideConfig() {
delete FontButton; delete FontButton;
delete FontDetailView; delete FontDetailView;
delete FontDetailViewSmall;
delete FontDetailHeader; delete FontDetailHeader;
delete FontMessageBox; delete FontMessageBox;
delete FontMessageBoxLarge; delete FontMessageBoxLarge;
@ -197,6 +199,7 @@ void cTvguideConfig::SetFonts(void){
//Common Fonts //Common Fonts
FontButton = cFont::CreateFont(*fontname, footerHeight/3 + 4 + FontButtonDelta); FontButton = cFont::CreateFont(*fontname, footerHeight/3 + 4 + FontButtonDelta);
FontDetailView = cFont::CreateFont(*fontname, osdHeight/30 + FontDetailViewDelta); FontDetailView = cFont::CreateFont(*fontname, osdHeight/30 + FontDetailViewDelta);
FontDetailViewSmall = cFont::CreateFont(*fontname, osdHeight/40 + FontDetailViewSmallDelta);
FontDetailHeader = cFont::CreateFont(*fontname, osdHeight/25 + FontDetailHeaderDelta); FontDetailHeader = cFont::CreateFont(*fontname, osdHeight/25 + FontDetailHeaderDelta);
FontMessageBox = cFont::CreateFont(*fontname, osdHeight/33 + FontMessageBoxDelta); FontMessageBox = cFont::CreateFont(*fontname, osdHeight/33 + FontMessageBoxDelta);
FontMessageBoxLarge = cFont::CreateFont(*fontname, osdHeight/30 + FontMessageBoxLargeDelta); FontMessageBoxLarge = cFont::CreateFont(*fontname, osdHeight/30 + FontMessageBoxLargeDelta);

View File

@ -71,6 +71,7 @@ class cTvguideConfig {
const char *fontNameDefault; const char *fontNameDefault;
int FontButtonDelta; int FontButtonDelta;
int FontDetailViewDelta; int FontDetailViewDelta;
int FontDetailViewSmallDelta;
int FontDetailHeaderDelta; int FontDetailHeaderDelta;
int FontMessageBoxDelta; int FontMessageBoxDelta;
int FontMessageBoxLargeDelta; int FontMessageBoxLargeDelta;
@ -108,6 +109,7 @@ class cTvguideConfig {
const cFont *FontTimeLineTimeHorizontal; const cFont *FontTimeLineTimeHorizontal;
const cFont *FontButton; const cFont *FontButton;
const cFont *FontDetailView; const cFont *FontDetailView;
const cFont *FontDetailViewSmall;
const cFont *FontDetailHeader; const cFont *FontDetailHeader;
const cFont *FontMessageBox; const cFont *FontMessageBox;
const cFont *FontMessageBoxLarge; const cFont *FontMessageBoxLarge;

View File

@ -4,11 +4,58 @@
cDetailView::cDetailView(const cEvent *event) { cDetailView::cDetailView(const cEvent *event) {
this->event = event; this->event = event;
imgScrollBar = NULL; imgScrollBar = NULL;
borderWidth = 100; //px borderWidth = 20; //px, border around window
border = 10; //px, border in view window
scrollBarWidth = 40; scrollBarWidth = 40;
headerHeight = max (40 + 3 * tvguideConfig.FontDetailHeader->Height(), // border + 3 Lines headerHeight = max (40 + 3 * tvguideConfig.FontDetailHeader->Height(), // border + 3 Lines
40 + tvguideConfig.epgImageHeight); 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) { if (tvguideConfig.displayRerunsDetailEPGView) {
loadReruns(); loadReruns();
} }
@ -17,45 +64,72 @@ cDetailView::cDetailView(const cEvent *event) {
createPixmaps(); 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() { 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) { 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) { 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; return true;
else } else {
heightContent = contentHeight;
return false; return false;
}
return false;
} }
void cDetailView::createPixmaps() { void cDetailView::createPixmaps() {
header = new cStyledPixmap(osdManager.requestPixmap(5, 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, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null); headerLogo = osdManager.requestPixmap(6, cRect(borderWidth, borderWidth, width, headerHeight), cRect::Null);
headerLogo->Fill(clrTransparent); 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); headerBack->Fill(clrBlack);
header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); 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), content = osdManager.requestPixmap(5, cRect(contentX, borderWidth + headerHeight, contentWidth, contentHeight),
cRect(0,0, tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth, max(heightContent, tvguideConfig.osdHeight-2*borderWidth-headerHeight))); cRect(0,0, contentWidth, max(heightContent, contentHeight)));
header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); 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(), width, 3));
footer = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight + content->ViewPort().Height(), tvguideConfig.osdWidth - 2*borderWidth, 3));
footer->Fill(theme.Color(clrBorder)); footer->Fill(theme.Color(clrBorder));
} }
@ -111,12 +185,12 @@ void cDetailView::drawHeader() {
void cDetailView::drawRecIcon() { void cDetailView::drawRecIcon() {
cString recIconText(" REC "); cString recIconText(" REC ");
int headerWidth = tvguideConfig.osdWidth - 2*borderWidth; int headerWidth = width;
int width = tvguideConfig.FontDetailHeader->Width(*recIconText); int widthIcon = tvguideConfig.FontDetailHeader->Width(*recIconText);
int height = tvguideConfig.FontDetailHeader->Height()+10; int height = tvguideConfig.FontDetailHeader->Height()+10;
int posX = headerWidth - width - 20; int posX = headerWidth - widthIcon - 20;
int posY = 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); 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 textHeight = tvguideConfig.FontDetailView->Height();
int textLines = description.Lines(); int textLines = description.Lines();
int i=0; for (int i=0; i<textLines; i++) {
for (; i<textLines; i++) { content->DrawText(cPoint(border, yEPGText + i*textHeight), description.GetLine(i), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView);
content->DrawText(cPoint(20, 20 + i*textHeight), description.GetLine(i), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView);
} }
i++;
if (tvguideConfig.displayRerunsDetailEPGView) { if (tvguideConfig.displayRerunsDetailEPGView) {
textLines = reruns.Lines(); textLines = reruns.Lines();
for (int j=0; j<textLines; j++) { for (int j=0; j<textLines; j++) {
content->DrawText(cPoint(20, 20 + i*textHeight), reruns.GetLine(j), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView); content->DrawText(cPoint(border, yAddInf+ j*textHeight), reruns.GetLine(j), theme.Color(clrFont), colorTextBack, tvguideConfig.FontDetailView);
i++;
} }
} }
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; double scrollBarOffset = 0.0;
if (contentScrollable) { if (contentScrollable) {
heightScrollbar = ( (double)scrollBar->ViewPort().Height() ) / (double)heightContent * ( (double)scrollBar->ViewPort().Height() ); 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 *= ( (double)scrollBar->ViewPort().Height()-7.0 - heightScrollbar);
scrollBarOffset++; scrollBarOffset++;
} else { } else {
@ -173,7 +272,7 @@ void cDetailView::scrollUp() {
void cDetailView::scrollDown() { void cDetailView::scrollDown() {
if (contentScrollable) { if (contentScrollable) {
int newDrawportHeight = content->DrawPort().Point().Y() - tvguideConfig.FontDetailView->Height(); 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))); content->SetDrawPortPoint(cPoint(0, max(newDrawportHeight,(-1)*maxDrawportHeight)));
drawScrollbar(); drawScrollbar();
} }
@ -274,13 +373,12 @@ void cDetailView::loadReruns(void) {
delete list; 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 } else
reruns.Set("", tvguideConfig.FontDetailView, tvguideConfig.osdWidth-2*borderWidth - 50 - 40); reruns.Set("", tvguideConfig.FontDetailView, contentWidth - scrollBarWidth);
} }
int cDetailView::heightEPGPics(void) { int cDetailView::heightEPGPics(void) {
int width = tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth;
int border = 5; int border = 5;
int numPicsAvailable = 0; int numPicsAvailable = 0;
for (int i=1; i <= tvguideConfig.numAdditionalEPGPictures; i++) { for (int i=1; i <= tvguideConfig.numAdditionalEPGPictures; i++) {
@ -294,17 +392,52 @@ int cDetailView::heightEPGPics(void) {
} }
} }
numEPGPics = numPicsAvailable; numEPGPics = numPicsAvailable;
int picsPerLine = width / (tvguideConfig.epgImageWidthLarge + border); int picsPerLine = contentWidth / (tvguideConfig.epgImageWidthLarge + border);
int picLines = numPicsAvailable / picsPerLine; int picLines = numPicsAvailable / picsPerLine;
if (numPicsAvailable%picsPerLine != 0) if (numPicsAvailable%picsPerLine != 0)
picLines++; picLines++;
return picLines * (tvguideConfig.epgImageHeightLarge + border) + 2*border; 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) { void cDetailView::drawEPGPictures(int height) {
int width = content->ViewPort().Width();
int border = 5; int border = 5;
int picsPerLine = width / (tvguideConfig.epgImageWidthLarge + border); int picsPerLine = contentWidth / (tvguideConfig.epgImageWidthLarge + border);
int currentX = border; int currentX = border;
int currentY = height + border; int currentY = height + border;
int currentPicsPerLine = 1; 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 cDetailView::ProcessKey(eKeys Key) {
eOSState state = osContinue; eOSState state = osContinue;
switch (Key & ~k_Repeat) { switch (Key & ~k_Repeat) {

View File

@ -5,20 +5,37 @@
class cEpgGrid; class cEpgGrid;
class cDetailView { class cDetailView : public cThread {
private: private:
cStyledPixmap *header; cStyledPixmap *header;
cPixmap *headerLogo; cPixmap *headerLogo;
cPixmap *headerBack; cPixmap *headerBack;
cPixmap *content; cPixmap *content;
cPixmap *pixmapPoster;
cPixmap *scrollBar; cPixmap *scrollBar;
cPixmap *footer; cPixmap *footer;
const cEvent *event; const cEvent *event;
cImage *imgScrollBar; cImage *imgScrollBar;
cTextWrapper description; cTextWrapper description;
cTextWrapper reruns; cTextWrapper reruns;
TVScraperGetFullInformation mediaInfo;
bool hasAdditionalMedia;
int borderWidth; int borderWidth;
int border;
int headerHeight; 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; int scrollBarWidth;
bool setContentDrawportHeight(); bool setContentDrawportHeight();
int heightContent; int heightContent;
@ -27,16 +44,24 @@ private:
bool contentScrollable; bool contentScrollable;
void loadReruns(void); void loadReruns(void);
int heightEPGPics(void); int heightEPGPics(void);
int heightActorPics(void);
int heightFanartImg(void);
void drawEPGPictures(int height); void drawEPGPictures(int height);
void drawRecIcon(void); 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); cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend);
void scrollUp(); void scrollUp();
void scrollDown(); void scrollDown();
void pageUp(); void pageUp();
void pageDown(); void pageDown();
void Action(void);
public: public:
cDetailView(const cEvent *event); cDetailView(const cEvent *event);
virtual ~cDetailView(void); virtual ~cDetailView(void);
void setContent();
void createPixmaps(); void createPixmaps();
void drawHeader(); void drawHeader();
void drawContent(); void drawContent();

View File

@ -59,6 +59,14 @@ bool cImageLoader::LoadAdditionalEPGImage(cString name) {
return true; 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) { bool cImageLoader::LoadIcon(const char *cIcon, int size) {
if (size==0) if (size==0)
return false; return false;
@ -130,3 +138,14 @@ bool cImageLoader::LoadImage(cString FileName, cString Path, cString Extension)
} }
return true; 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;
}

View File

@ -17,6 +17,7 @@ public:
bool LoadLogo(const char *logo, int width, int height); bool LoadLogo(const char *logo, int width, int height);
bool LoadEPGImage(int eventID); bool LoadEPGImage(int eventID);
bool LoadAdditionalEPGImage(cString name); bool LoadAdditionalEPGImage(cString name);
bool LoadPoster(const char *poster, int width, int height);
bool LoadIcon(const char *cIcon, int size); bool LoadIcon(const char *cIcon, int size);
bool DrawBackground(tColor back, tColor blend, int width, int height); bool DrawBackground(tColor back, tColor blend, int width, int height);
private: private:
@ -24,6 +25,7 @@ private:
Color Argb2Color(tColor col); Color Argb2Color(tColor col);
void toLowerCase(std::string &str); void toLowerCase(std::string &str);
bool LoadImage(cString FileName, cString Path, cString Extension); bool LoadImage(cString FileName, cString Path, cString Extension);
bool LoadImage(const char *fullpath);
}; };
#endif //_TVGUIDE_IMAGELOADER_H #endif //_TVGUIDE_IMAGELOADER_H

View File

@ -3,7 +3,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: vdr-tvguide 0.0.1\n" "Project-Id-Version: vdr-tvguide 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n" "Report-Msgid-Bugs-To: <see README>\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" "PO-Revision-Date: 2012-08-25 17:49+0200\n"
"Last-Translator: Horst\n" "Last-Translator: Horst\n"
"Language-Team: \n" "Language-Team: \n"
@ -18,6 +18,9 @@ msgstr "Hauptprogramm"
msgid "RERUNS OF THIS SHOW" msgid "RERUNS OF THIS SHOW"
msgstr "Wiederholungen dieser Sendung" msgstr "Wiederholungen dieser Sendung"
msgid "Actors"
msgstr ""
msgid "No EPG Information available" msgid "No EPG Information available"
msgstr "Keine EPG Daten verfügbar" msgstr "Keine EPG Daten verfügbar"

56
services/tvscraper.h Normal file
View File

@ -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<tvMedia> posters;
std::vector<tvMedia> fanart;
std::vector<tvActor> actors;
std::string description;
};

View File

@ -3,8 +3,7 @@
cStatusHeader::cStatusHeader(void) { cStatusHeader::cStatusHeader(void) {
color = theme.Color(clrStatusHeader); color = theme.Color(clrStatusHeader);
colorBlending = theme.Color(clrStatusHeaderBlending); colorBlending = theme.Color(clrStatusHeaderBlending);
int height = tvguideConfig.statusHeaderHeight; height = tvguideConfig.statusHeaderHeight;
int width;
if (tvguideConfig.scaleVideo) { if (tvguideConfig.scaleVideo) {
width = tvguideConfig.osdWidth - height * 16 / 9; width = tvguideConfig.osdWidth - height * 16 / 9;
} else { } else {
@ -45,7 +44,6 @@ cStatusHeader::~cStatusHeader(void) {
void cStatusHeader::ScaleVideo(void) { void cStatusHeader::ScaleVideo(void) {
if (tvguideConfig.scaleVideo) { if (tvguideConfig.scaleVideo) {
int height = tvguideConfig.statusHeaderHeight;
int width = height * 16 / 9; int width = height * 16 / 9;
int x = osdManager.Left() + tvguideConfig.osdWidth - width; int x = osdManager.Left() + tvguideConfig.osdWidth - width;
int y = osdManager.Top(); int y = osdManager.Top();
@ -57,22 +55,28 @@ void cStatusHeader::ScaleVideo(void) {
void cStatusHeader::DrawInfoText(cGrid *grid) { void cStatusHeader::DrawInfoText(cGrid *grid) {
int border = 10; int border = 10;
int textWidth = width - 2 * border;
tColor colorTextBack = (tvguideConfig.useBlending==0)?color:clrTransparent; tColor colorTextBack = (tvguideConfig.useBlending==0)?color:clrTransparent;
pixmapText->Fill(clrTransparent); pixmapText->Fill(clrTransparent);
int x = border; int x = border;
int y = border; int y = border;
if (!grid->isDummy()) { 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 time = grid->getTimeString();
cString title(""); cString title("");
const cEvent *event = grid->GetEvent();
title = cString::sprintf(": %s", event->Title()); title = cString::sprintf(": %s", event->Title());
cString header = cString::sprintf("%s%s", *time, *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); pixmapText->DrawText(cPoint(x,y), *header, theme.Color(clrFont), colorTextBack, tvguideConfig.FontStatusHeaderLarge);
y += tvguideConfig.FontStatusHeaderLarge->Height() + border; y += tvguideConfig.FontStatusHeaderLarge->Height() + border;
int heightText = pixmapText->ViewPort().Height() - y; int heightText = pixmapText->ViewPort().Height() - y;
cTextWrapper description; 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 lineHeight = tvguideConfig.FontStatusHeader->Height();
int textLines = description.Lines(); int textLines = description.Lines();
int maxLines = heightText / lineHeight; 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); 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;
}

View File

@ -5,8 +5,10 @@
class cStatusHeader : public cStyledPixmap { class cStatusHeader : public cStyledPixmap {
private: private:
int width, height;
cPixmap *pixmapText; cPixmap *pixmapText;
cPixmap *pixmapTVFrame; cPixmap *pixmapTVFrame;
int DrawPoster(const cEvent *event, int x, int y, int height, int border);
public: public:
cStatusHeader(void); cStatusHeader(void);
virtual ~cStatusHeader(void); virtual ~cStatusHeader(void);

View File

@ -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 *DESCRIPTION = "A fancy 2d EPG Viewer";
static const char *MAINMENUENTRY = "Tvguide"; static const char *MAINMENUENTRY = "Tvguide";

View File

@ -62,7 +62,8 @@ cOsdManager osdManager;
#include "services/epgsearch.h" #include "services/epgsearch.h"
#include "services/remotetimers.h" #include "services/remotetimers.h"
cPlugin* pRemoteTimers = NULL; cPlugin* pRemoteTimers = NULL;
#include <vector>
#include "services/tvscraper.h"
#include "tools.c" #include "tools.c"
#include "switchtimer.c" #include "switchtimer.c"
#include "setup.c" #include "setup.c"
@ -579,9 +580,11 @@ void cTvGuideOsd::DetailedEPG() {
if (!activeGrid->isDummy()) { if (!activeGrid->isDummy()) {
detailViewActive = true; detailViewActive = true;
detailView = new cDetailView(activeGrid->GetEvent()); detailView = new cDetailView(activeGrid->GetEvent());
detailView->setContent();
detailView->drawHeader(); detailView->drawHeader();
detailView->drawContent(); detailView->drawContent();
detailView->drawScrollbar(); detailView->drawScrollbar();
detailView->Start();
osdManager.flush(); osdManager.flush();
} }
} }