vdr-plugin-tvguide/view.c
2021-01-11 11:33:16 +01:00

1068 lines
38 KiB
C

#include "detailview.h"
#include "switchtimer.h"
/********************************************************************************************
* cView
********************************************************************************************/
cView::cView(void) : cThread("View") {
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 = config.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 (config.style == eStyleGraphical) {
if (config.scaleVideo) {
pixmapHeader->drawBackgroundGraphical(bgStatusHeaderWindowed);
} else {
pixmapHeader->drawBackgroundGraphical(bgStatusHeaderFull);
}
} else {
pixmapHeader->drawBackground();
pixmapHeader->drawBoldBorder();
}
//Channel Logo
int logoHeight = 2 * headerHeight / 3;
int logoWidth = logoHeight * config.logoWidthRatio / config.logoHeightRatio;
int xText = border / 2;
if (channel && !config.hideChannelLogos) {
cImageLoader imgLoader;
if (imgLoader.LoadLogo(channel, logoWidth, logoHeight)) {
cImage logo = imgLoader.GetImage();
const int logoheight = logo.Height();
pixmapHeaderLogo->DrawImage(cPoint(border / 2, ((headerHeight - logoHeight) / 2 + (logoHeight - logoheight) / 2)), logo);
xText += logoWidth + border / 2;
}
}
//Date and Time, Title, Subtitle
int textWidthMax = headerWidth - xText - border / 2;
wrapper.Set(title.c_str(), fontHeaderLarge, textWidthMax);
int lineHeight = fontHeaderLarge->Height();
int textLines = wrapper.Lines();
int yDateTime = border / 2;
int yTitle = (headerHeight - textLines * lineHeight) / 2;
int ySubtitle = headerHeight - fontHeader->Height() - border / 3;
pixmapHeader->DrawText(cPoint(xText, yDateTime), CutText(dateTime, textWidthMax, fontHeader).c_str(), theme.Color(clrFont), theme.Color(clrStatusHeader), fontHeader);
for (int i = 0; i < textLines; i++) {
pixmapHeader->DrawText(cPoint(xText, yTitle + i * lineHeight), wrapper.GetLine(i), 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;
if (!event)
return;
const cTimer *ti;
if (config.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 {
#if VDRVERSNUM >= 20301
LOCK_TIMERS_READ;
ti = Timers->GetMatch(event, &timerMatch);
#else
ti = Timers.GetMatch(event, &timerMatch);
#endif
}
bool hasSwitchTimer = SwitchTimers.EventInSwitchList(event);
if (hasSwitchTimer || (ti && timerMatch == tmFull)) {
tColor iconColor;
bool switchOnly = false;
bool timerActive = ti && ti->HasFlags(tfActive);
cString recIconText;
#ifdef SWITCHONLYPATCH
switchOnly = ti && ti->HasFlags(tfSwitchOnly);
#endif
(hasSwitchTimer || switchOnly) ? recIconText = "Switch" : recIconText = " REC ";
iconColor = (hasSwitchTimer || switchOnly) ? theme.Color(clrButtonYellow) : timerActive ? theme.Color(clrButtonRed) : theme.Color(clrButtonGreen);
int widthIcon = fontManager.FontDetailHeader->Width(*recIconText) + 10;
int height = fontManager.FontDetailHeader->Height() + 10;
int posX = headerWidth - widthIcon - 25;
int posY = ySubtitle - 5;
pixmapHeader->DrawRectangle( cRect(posX, posY, widthIcon, height), iconColor);
pixmapHeader->DrawText(cPoint(posX + 5, posY + 5), *recIconText, theme.Color(clrFont), iconColor, 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(std::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<std::string> flds = s.split('\n', 1);
if (flds.size() < 1)
return;
std::stringstream sstrTextTall;
std::stringstream sstrTextFull;
for (int i = 0; i < (int)flds.size(); i++) {
if (!flds[i].size()) {
//empty line
linesDrawn++;
y += lineHeight;
if (drawNarrow)
sstrTextTall << "\n";
else
sstrTextFull << "\n";
} else {
cTextWrapper wrapper;
if (drawNarrow) {
wrapper.Set((flds[i].c_str()), font, widthNarrow);
int newLines = wrapper.Lines();
//check if wrapper fits completely into narrow area
if (linesDrawn + newLines < linesNarrow) {
for (int line = 0; line < wrapper.Lines(); line++) {
sstrTextTall << wrapper.GetLine(line) << " ";
}
sstrTextTall << "\n";
linesDrawn += newLines;
} else {
//this wrapper has to be splitted
for (int line = 0; line < wrapper.Lines(); line++) {
if (line + linesDrawn < linesNarrow) {
sstrTextTall << wrapper.GetLine(line) << " ";
} else {
sstrTextFull << wrapper.GetLine(line) << " ";
}
}
sstrTextFull << "\n";
drawNarrow = false;
}
} else {
wrapper.Set((flds[i].c_str()), font, width - 2*border);
for (int line = 0; line < wrapper.Lines(); line++) {
sstrTextFull << wrapper.GetLine(line) << " ";
}
sstrTextFull << "\n";
}
}
}
twNarrow->Set(sstrTextTall.str().c_str(), font, widthNarrow);
twFull->Set(sstrTextFull.str().c_str(), font, width - 2 * border);
}
void cView::DrawActors(std::vector<cActor> *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 (config.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; i<numSteps; i++) {
clr = AlphaBlend(clrBgr, clrBlend, alpha);
for (int y = i*stepY; y < (i+1)*stepY; y++) {
for (int x=0; x<width; x++) {
image->SetPixel(cPoint(x,y), clr);
}
}
alpha += alphaStep;
}
}
return image;
}
bool cView::KeyUp(void) {
if (!scrollable)
return false;
int aktHeight = pixmapContent->DrawPort().Point().Y();
if (aktHeight >= 0) {
return false;
}
int step = config.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 = config.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(2);
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 <= config.numAdditionalEPGPictures; i++) {
cString epgimage;
epgimage = cString::sprintf("%s%d_%d.jpg", *config.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 = config.epgImageWidthLarge;
int imgHeight = config.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(3);
while (Active())
cCondWait::SleepMs(10);
}
void cSeriesView::LoadMedia(void) {
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper || seriesId < 1)
return;
series.seriesId = seriesId;
series.episodeId = episodeId;
pScraper->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(3);
while (Active())
cCondWait::SleepMs(10);
}
void cMovieView::LoadMedia(void) {
static cPlugin *pScraper = GetScraperPlugin();
if (!pScraper || movieId < 1)
return;
movie.movieId = movieId;
pScraper->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();
}