2013-05-26 17:44:04 +02:00
|
|
|
#include <sstream>
|
2013-12-07 15:51:50 +01:00
|
|
|
#include <vdr/plugin.h>
|
|
|
|
#include "imageloader.h"
|
2013-12-21 11:25:03 +01:00
|
|
|
#include "imagecache.h"
|
2013-12-07 15:51:50 +01:00
|
|
|
#include "services/epgsearch.h"
|
|
|
|
#include "services/remotetimers.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "tools.h"
|
2013-01-17 13:16:44 +01:00
|
|
|
#include "detailview.h"
|
|
|
|
|
2014-01-11 16:53:23 +01:00
|
|
|
cDetailView::cDetailView(const cEvent *event, cFooter *footer) {
|
2013-07-09 00:17:42 +02:00
|
|
|
this->event = event;
|
2014-01-11 16:53:23 +01:00
|
|
|
this->footer = footer;
|
2013-05-26 11:38:05 +02:00
|
|
|
imgScrollBar = NULL;
|
2013-12-21 11:25:03 +01:00
|
|
|
border = tvguideConfig.epgViewBorder; //px, border in view window
|
2013-06-03 09:52:54 +02:00
|
|
|
scrollBarWidth = 40;
|
2014-01-11 16:53:23 +01:00
|
|
|
headerWidth = geoManager.headerContentWidth;
|
2013-12-21 11:25:03 +01:00
|
|
|
headerHeight = geoManager.epgViewHeaderHeight;
|
2013-08-25 13:57:10 +02:00
|
|
|
pixmapPoster = NULL;
|
2013-12-21 11:25:03 +01:00
|
|
|
width = geoManager.osdWidth;
|
2013-08-25 13:57:10 +02:00
|
|
|
contentWidth = width - scrollBarWidth;
|
2013-12-21 11:25:03 +01:00
|
|
|
contentX = 0;
|
2014-01-11 16:53:23 +01:00
|
|
|
contentHeight = geoManager.osdHeight - headerHeight - geoManager.footerHeight;
|
2013-08-25 13:57:10 +02:00
|
|
|
widthPoster = 30 * contentWidth / 100;
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
cDetailView::~cDetailView(void){
|
2013-08-25 13:57:10 +02:00
|
|
|
Cancel(-1);
|
|
|
|
while (Active())
|
|
|
|
cCondWait::SleepMs(10);
|
2013-12-21 11:25:03 +01:00
|
|
|
osdManager.releasePixmap(back);
|
2013-05-26 11:38:05 +02:00
|
|
|
delete header;
|
2013-08-25 13:57:10 +02:00
|
|
|
header = NULL;
|
2013-05-26 11:38:05 +02:00
|
|
|
osdManager.releasePixmap(headerLogo);
|
2013-08-25 13:57:10 +02:00
|
|
|
headerLogo = NULL;
|
2013-05-26 11:38:05 +02:00
|
|
|
osdManager.releasePixmap(content);
|
2013-08-25 13:57:10 +02:00
|
|
|
content = NULL;
|
|
|
|
if (pixmapPoster)
|
|
|
|
osdManager.releasePixmap(pixmapPoster);
|
|
|
|
pixmapPoster = NULL;
|
2013-05-26 11:38:05 +02:00
|
|
|
osdManager.releasePixmap(scrollBar);
|
2013-08-25 13:57:10 +02:00
|
|
|
scrollBar = NULL;
|
2013-05-26 11:38:05 +02:00
|
|
|
delete imgScrollBar;
|
2014-01-11 16:53:23 +01:00
|
|
|
footer->LeaveDetailedViewMode(Channels.GetByChannelID(event->ChannelID()));
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
2013-08-25 13:57:10 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2013-12-21 11:25:03 +01:00
|
|
|
description.Set(event->Description(), fontManager.FontDetailView, contentWidth - scrollBarWidth - 2*border);
|
2013-08-25 13:57:10 +02:00
|
|
|
if (tvguideConfig.displayRerunsDetailEPGView) {
|
|
|
|
loadReruns();
|
|
|
|
}
|
|
|
|
numEPGPics = 0;
|
|
|
|
contentScrollable = setContentDrawportHeight();
|
|
|
|
createPixmaps();
|
|
|
|
}
|
|
|
|
|
2013-01-17 13:16:44 +01:00
|
|
|
bool cDetailView::setContentDrawportHeight() {
|
2013-12-21 11:25:03 +01:00
|
|
|
int lineHeight = fontManager.FontDetailView->Height();
|
2013-08-25 13:57:10 +02:00
|
|
|
//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;
|
2013-05-26 17:44:04 +02:00
|
|
|
if (tvguideConfig.displayRerunsDetailEPGView) {
|
2013-12-21 11:25:03 +01:00
|
|
|
heightReruns = (reruns.Lines()+1) * lineHeight;
|
2013-08-25 13:57:10 +02:00
|
|
|
}
|
|
|
|
//Height of actor pictures
|
|
|
|
int heightActors = 0;
|
|
|
|
if (hasAdditionalMedia) {
|
|
|
|
heightActors = heightActorPics();
|
2013-05-26 17:44:04 +02:00
|
|
|
}
|
2013-08-25 13:57:10 +02:00
|
|
|
//Height of fanart
|
|
|
|
int heightFanart = 0;
|
|
|
|
if (hasAdditionalMedia) {
|
|
|
|
heightFanart = heightFanartImg() + lineHeight;
|
|
|
|
}
|
|
|
|
//Height of EPG Pictures
|
|
|
|
int heightEpgPics = 0;
|
2013-06-03 09:52:54 +02:00
|
|
|
if (!tvguideConfig.hideEpgImages) {
|
2013-08-25 13:57:10 +02:00
|
|
|
heightEpgPics = heightEPGPics();
|
2013-06-03 09:52:54 +02:00
|
|
|
}
|
2013-08-25 13:57:10 +02:00
|
|
|
|
2013-12-21 11:25:03 +01:00
|
|
|
yBanner = border;
|
|
|
|
yEPGText = yBanner + heightBanner;
|
|
|
|
yAddInf = yEPGText + heightEPG;
|
|
|
|
yActors = yAddInf + heightReruns;
|
|
|
|
yFanart = yActors + heightActors;
|
|
|
|
yEPGPics = yAddInf + heightFanart;
|
2013-08-25 13:57:10 +02:00
|
|
|
|
2013-12-21 11:25:03 +01:00
|
|
|
int totalHeight = heightBanner + heightEPG + heightReruns + heightActors + heightFanart + heightEpgPics + lineHeight;
|
2013-08-25 13:57:10 +02:00
|
|
|
//check if pixmap content has to be scrollable
|
|
|
|
if (totalHeight > contentHeight) {
|
|
|
|
heightContent = totalHeight;
|
2013-05-26 11:38:05 +02:00
|
|
|
return true;
|
2013-08-25 13:57:10 +02:00
|
|
|
} else {
|
|
|
|
heightContent = contentHeight;
|
2013-05-26 11:38:05 +02:00
|
|
|
return false;
|
2013-08-25 13:57:10 +02:00
|
|
|
}
|
|
|
|
return false;
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cDetailView::createPixmaps() {
|
2014-01-11 16:53:23 +01:00
|
|
|
back = osdManager.requestPixmap(3, cRect(0, 0, width, headerHeight + contentHeight), cRect::Null);
|
2013-12-21 11:25:03 +01:00
|
|
|
back->Fill(clrBlack);
|
2014-01-11 16:53:23 +01:00
|
|
|
header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(0, 0, headerWidth, headerHeight), cRect::Null));
|
2013-12-21 11:25:03 +01:00
|
|
|
headerLogo = osdManager.requestPixmap(6, cRect(0, 0, width, headerHeight), cRect::Null);
|
2013-01-17 16:19:37 +01:00
|
|
|
headerLogo->Fill(clrTransparent);
|
2013-01-27 14:07:53 +01:00
|
|
|
header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending));
|
2013-12-21 11:25:03 +01:00
|
|
|
content = osdManager.requestPixmap(5, cRect(contentX, headerHeight, contentWidth, contentHeight),
|
2013-08-25 13:57:10 +02:00
|
|
|
cRect(0,0, contentWidth, max(heightContent, contentHeight)));
|
|
|
|
if (hasAdditionalMedia) {
|
2013-12-21 11:25:03 +01:00
|
|
|
pixmapPoster = osdManager.requestPixmap(4, cRect(0, 0 + headerHeight, widthPoster, contentHeight));
|
2013-08-25 13:57:10 +02:00
|
|
|
pixmapPoster->Fill(theme.Color(clrBorder));
|
|
|
|
pixmapPoster->DrawRectangle(cRect(2, 0, widthPoster - 2, content->DrawPort().Height()), theme.Color(clrBackground));
|
|
|
|
}
|
2013-12-21 11:25:03 +01:00
|
|
|
scrollBar = osdManager.requestPixmap(5, cRect(geoManager.osdWidth - scrollBarWidth, headerHeight, scrollBarWidth, contentHeight));
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cDetailView::drawHeader() {
|
2014-01-11 16:53:23 +01:00
|
|
|
header->Fill(clrTransparent);
|
2013-12-21 11:25:03 +01:00
|
|
|
if (tvguideConfig.style == eStyleGraphical) {
|
2014-01-11 16:53:23 +01:00
|
|
|
if (tvguideConfig.scaleVideo) {
|
|
|
|
header->drawBackgroundGraphical(bgStatusHeaderWindowed);
|
|
|
|
} else {
|
|
|
|
header->drawBackgroundGraphical(bgStatusHeaderFull);
|
|
|
|
}
|
2013-12-21 11:25:03 +01:00
|
|
|
} else {
|
|
|
|
header->drawBackground();
|
|
|
|
header->drawBoldBorder();
|
|
|
|
}
|
2014-01-11 16:53:23 +01:00
|
|
|
if (tvguideConfig.scaleVideo) {
|
|
|
|
back->DrawRectangle(cRect(headerWidth, 0, geoManager.tvFrameWidth, headerHeight), clrTransparent);
|
|
|
|
}
|
2013-12-21 11:25:03 +01:00
|
|
|
tColor colorTextBack = (tvguideConfig.style == eStyleFlat)?theme.Color(clrHeader):clrTransparent;
|
|
|
|
int logoHeight = 2 * header->Height() / 3;
|
2013-05-24 16:23:23 +02:00
|
|
|
int logoWidth = logoHeight * tvguideConfig.logoWidthRatio / tvguideConfig.logoHeightRatio;
|
2013-12-21 11:25:03 +01:00
|
|
|
int lineHeight = fontManager.FontDetailHeader->Height();
|
2013-05-26 11:38:05 +02:00
|
|
|
cImageLoader imgLoader;
|
2013-05-24 16:23:23 +02:00
|
|
|
bool logoDrawn = false;
|
2013-05-26 11:38:05 +02:00
|
|
|
if (!tvguideConfig.hideChannelLogos) {
|
2013-12-21 11:25:03 +01:00
|
|
|
const cChannel *channel = Channels.GetByChannelID(event->ChannelID());
|
|
|
|
if (imgLoader.LoadLogo(channel, logoWidth, logoHeight)) {
|
2013-05-26 11:38:05 +02:00
|
|
|
cImage logo = imgLoader.GetImage();
|
|
|
|
headerLogo->DrawImage(cPoint(10, (header->Height() - logoHeight)/2), logo);
|
2013-05-24 16:23:23 +02:00
|
|
|
logoDrawn = true;
|
2013-05-26 11:38:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-21 11:25:03 +01:00
|
|
|
bool epgImageDrawn = false;
|
|
|
|
int epgImageWidth = 0;
|
2013-05-26 11:38:05 +02:00
|
|
|
if (!tvguideConfig.hideEpgImages) {
|
2013-12-21 11:25:03 +01:00
|
|
|
int epgImageHeight = 3 * headerHeight / 4;
|
|
|
|
if (tvguideConfig.epgImageHeight > 0)
|
|
|
|
epgImageWidth = epgImageHeight * tvguideConfig.epgImageWidth / tvguideConfig.epgImageHeight;
|
|
|
|
if (imgLoader.LoadEPGImage(event->EventID(), epgImageWidth, epgImageHeight)) {
|
2013-05-26 11:38:05 +02:00
|
|
|
cImage epgImage = imgLoader.GetImage();
|
2014-01-11 16:53:23 +01:00
|
|
|
int epgImageX = headerWidth - border - epgImageWidth;
|
|
|
|
int epgImageY = (headerHeight - epgImageHeight) / 2;
|
2013-12-21 11:25:03 +01:00
|
|
|
header->DrawRectangle(cRect(epgImageX-2, epgImageY-2, epgImageWidth + 4, epgImageHeight + 4), theme.Color(clrBorder));
|
2013-05-26 11:38:05 +02:00
|
|
|
header->DrawImage(cPoint(epgImageX, epgImageY), epgImage);
|
2013-12-21 11:25:03 +01:00
|
|
|
epgImageDrawn = true;
|
2013-05-26 11:38:05 +02:00
|
|
|
}
|
|
|
|
}
|
2013-12-21 11:25:03 +01:00
|
|
|
int textX = logoDrawn?(border + logoWidth + 5):border;
|
2014-01-11 16:53:23 +01:00
|
|
|
int textY = (headerHeight - 7*lineHeight/2)/2;
|
|
|
|
int maxTextWidth = headerWidth - 2 * border;
|
2013-12-21 11:25:03 +01:00
|
|
|
if (logoDrawn)
|
|
|
|
maxTextWidth -= logoWidth;
|
|
|
|
if (epgImageDrawn)
|
|
|
|
maxTextWidth -= epgImageWidth;
|
|
|
|
std::string title = CutText((event->Title())?event->Title():"", maxTextWidth, fontManager.FontDetailHeader);
|
|
|
|
header->DrawText(cPoint(textX, textY), title.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailHeader);
|
|
|
|
std::string datetime = *cString::sprintf("%s, %s - %s (%d min)", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString(), event->Duration()/60);
|
|
|
|
datetime = CutText(datetime, maxTextWidth, fontManager.FontDetailView);
|
|
|
|
textY += 5*lineHeight/4;
|
|
|
|
header->DrawText(cPoint(textX, textY), datetime.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView);
|
|
|
|
std::string shortText = CutText((event->ShortText())?event->ShortText():"", maxTextWidth, fontManager.FontDetailView);
|
|
|
|
textY += 5*lineHeight/4;
|
|
|
|
header->DrawText(cPoint(textX, textY), shortText.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView);
|
2013-07-20 13:46:26 +02:00
|
|
|
|
|
|
|
eTimerMatch timerMatch=tmNone;
|
|
|
|
cTimer *ti;
|
|
|
|
if (tvguideConfig.useRemoteTimers && pRemoteTimers) {
|
|
|
|
RemoteTimers_GetMatch_v1_0 rtMatch;
|
|
|
|
rtMatch.event = event;
|
|
|
|
pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch);
|
|
|
|
timerMatch = (eTimerMatch)rtMatch.timerMatch;
|
|
|
|
ti = rtMatch.timer;
|
|
|
|
} else {
|
|
|
|
ti=Timers.GetMatch(event, &timerMatch);
|
|
|
|
}
|
|
|
|
if (timerMatch == tmFull) {
|
|
|
|
drawRecIcon();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-11 16:53:23 +01:00
|
|
|
void cDetailView::drawRecIcon(void) {
|
2013-07-20 13:46:26 +02:00
|
|
|
cString recIconText(" REC ");
|
2013-12-21 11:25:03 +01:00
|
|
|
int widthIcon = fontManager.FontDetailHeader->Width(*recIconText);
|
|
|
|
int height = fontManager.FontDetailHeader->Height()+10;
|
2013-08-25 13:57:10 +02:00
|
|
|
int posX = headerWidth - widthIcon - 20;
|
2013-07-20 13:46:26 +02:00
|
|
|
int posY = 20;
|
2013-08-25 13:57:10 +02:00
|
|
|
header->DrawRectangle( cRect(posX, posY, widthIcon, height), theme.Color(clrButtonRed));
|
2013-12-21 11:25:03 +01:00
|
|
|
header->DrawText(cPoint(posX, posY+5), *recIconText, theme.Color(clrFont), theme.Color(clrButtonRed), fontManager.FontDetailHeader);
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cDetailView::drawContent() {
|
2013-05-26 11:38:05 +02:00
|
|
|
content->Fill(theme.Color(clrBorder));
|
|
|
|
content->DrawRectangle(cRect(2, 0, content->ViewPort().Width() - 2, content->DrawPort().Height()), theme.Color(clrBackground));
|
2013-12-21 11:25:03 +01:00
|
|
|
tColor colorTextBack = (tvguideConfig.style == eStyleFlat)?theme.Color(clrBackground):clrTransparent;
|
2013-05-26 11:38:05 +02:00
|
|
|
|
2013-12-21 11:25:03 +01:00
|
|
|
int textHeight = fontManager.FontDetailView->Height();
|
2013-05-26 11:38:05 +02:00
|
|
|
int textLines = description.Lines();
|
2013-08-25 13:57:10 +02:00
|
|
|
for (int i=0; i<textLines; i++) {
|
2013-12-21 11:25:03 +01:00
|
|
|
content->DrawText(cPoint(border, yEPGText + i*textHeight), description.GetLine(i), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView);
|
2013-05-26 11:38:05 +02:00
|
|
|
}
|
2013-05-26 17:44:04 +02:00
|
|
|
if (tvguideConfig.displayRerunsDetailEPGView) {
|
|
|
|
textLines = reruns.Lines();
|
|
|
|
for (int j=0; j<textLines; j++) {
|
2013-12-21 11:25:03 +01:00
|
|
|
content->DrawText(cPoint(border, yAddInf + j*textHeight), reruns.GetLine(j), theme.Color(clrFont), colorTextBack, fontManager.FontDetailView);
|
2013-05-26 17:44:04 +02:00
|
|
|
}
|
|
|
|
}
|
2013-08-25 13:57:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
2013-06-03 09:52:54 +02:00
|
|
|
}
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cDetailView::drawScrollbar() {
|
2013-05-26 11:38:05 +02:00
|
|
|
scrollBar->Fill(theme.Color(clrBorder));
|
|
|
|
double scrollBarOffset = 0.0;
|
|
|
|
if (contentScrollable) {
|
|
|
|
heightScrollbar = ( (double)scrollBar->ViewPort().Height() ) / (double)heightContent * ( (double)scrollBar->ViewPort().Height() );
|
2013-08-25 13:57:10 +02:00
|
|
|
scrollBarOffset = (-1.0)*(double)content->DrawPort().Point().Y() / (double)(content->DrawPort().Height() - (contentHeight));
|
2013-05-26 11:38:05 +02:00
|
|
|
scrollBarOffset *= ( (double)scrollBar->ViewPort().Height()-7.0 - heightScrollbar);
|
|
|
|
scrollBarOffset++;
|
|
|
|
} else {
|
|
|
|
heightScrollbar = scrollBar->ViewPort().Height();
|
|
|
|
}
|
|
|
|
scrollBar->DrawRectangle(cRect(3,0,scrollBar->ViewPort().Width()-6, scrollBar->ViewPort().Height()), theme.Color(clrBackground));
|
|
|
|
if (imgScrollBar == NULL) {
|
|
|
|
imgScrollBar = createScrollbar(scrollBar->ViewPort().Width()-10, heightScrollbar, theme.Color(clrHighlight), theme.Color(clrHighlightBlending));
|
|
|
|
}
|
|
|
|
scrollBar->DrawImage(cPoint(5, 2 + scrollBarOffset), *imgScrollBar);
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cDetailView::scrollUp() {
|
2013-05-26 11:38:05 +02:00
|
|
|
if (contentScrollable) {
|
2013-12-21 11:25:03 +01:00
|
|
|
int newDrawportHeight = content->DrawPort().Point().Y() + fontManager.FontDetailView->Height();
|
2013-05-26 11:38:05 +02:00
|
|
|
content->SetDrawPortPoint(cPoint(0, min(newDrawportHeight,0)));
|
|
|
|
drawScrollbar();
|
|
|
|
}
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cDetailView::scrollDown() {
|
2013-05-26 11:38:05 +02:00
|
|
|
if (contentScrollable) {
|
2013-12-21 11:25:03 +01:00
|
|
|
int newDrawportHeight = content->DrawPort().Point().Y() - fontManager.FontDetailView->Height();
|
2013-08-25 13:57:10 +02:00
|
|
|
int maxDrawportHeight = (content->DrawPort().Height() - contentHeight);
|
2013-05-26 11:38:05 +02:00
|
|
|
content->SetDrawPortPoint(cPoint(0, max(newDrawportHeight,(-1)*maxDrawportHeight)));
|
|
|
|
drawScrollbar();
|
|
|
|
}
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
2013-07-17 16:43:57 +02:00
|
|
|
void cDetailView::pageUp() {
|
|
|
|
if (contentScrollable) {
|
|
|
|
int aktHeight = (-1)*content->DrawPort().Point().Y();
|
|
|
|
int totalHeight = content->DrawPort().Height();
|
|
|
|
int screenHeight = content->ViewPort().Height();
|
|
|
|
int newHeight = max(aktHeight - screenHeight, 0);
|
|
|
|
content->SetDrawPortPoint(cPoint(0, (-1)*newHeight));
|
|
|
|
drawScrollbar();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cDetailView::pageDown() {
|
|
|
|
if (contentScrollable) {
|
|
|
|
int aktHeight = (-1)*content->DrawPort().Point().Y();
|
|
|
|
int totalHeight = content->DrawPort().Height();
|
|
|
|
int screenHeight = content->ViewPort().Height();
|
|
|
|
int newHeight = min(aktHeight + screenHeight, totalHeight - screenHeight);
|
|
|
|
content->SetDrawPortPoint(cPoint(0, (-1)*newHeight));
|
|
|
|
drawScrollbar();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-17 13:16:44 +01:00
|
|
|
cImage *cDetailView::createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend) {
|
2013-05-26 11:38:05 +02:00
|
|
|
cImage *image = new cImage(cSize(width, height));
|
|
|
|
image->Fill(clrBgr);
|
2013-12-21 11:25:03 +01:00
|
|
|
if (tvguideConfig.style != eStyleFlat) {
|
2013-05-26 11:38:05 +02:00
|
|
|
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;
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
|
|
|
|
2013-06-03 09:52:54 +02:00
|
|
|
void cDetailView::loadReruns(void) {
|
2013-05-26 17:44:04 +02:00
|
|
|
cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch");
|
|
|
|
if (epgSearchPlugin && !isempty(event->Title())) {
|
|
|
|
std::stringstream sstrReruns;
|
|
|
|
Epgsearch_searchresults_v1_0 data;
|
|
|
|
std::string strQuery = event->Title();
|
|
|
|
if (tvguideConfig.useSubtitleRerun > 0) {
|
|
|
|
if (tvguideConfig.useSubtitleRerun == 2 || !isempty(event->ShortText()))
|
|
|
|
strQuery += "~";
|
|
|
|
if (!isempty(event->ShortText()))
|
|
|
|
strQuery += event->ShortText();
|
|
|
|
data.useSubTitle = true;
|
|
|
|
} else {
|
|
|
|
data.useSubTitle = false;
|
|
|
|
}
|
|
|
|
data.query = (char *)strQuery.c_str();
|
|
|
|
data.mode = 0;
|
|
|
|
data.channelNr = 0;
|
|
|
|
data.useTitle = true;
|
|
|
|
data.useDescription = false;
|
|
|
|
|
|
|
|
if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) {
|
|
|
|
cList<Epgsearch_searchresults_v1_0::cServiceSearchResult>* list = data.pResultList;
|
|
|
|
if (list && (list->Count() > 1)) {
|
|
|
|
sstrReruns << tr("RERUNS OF THIS SHOW") << ':' << std::endl;
|
|
|
|
int i = 0;
|
|
|
|
for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = list->First(); r && i < tvguideConfig.numReruns; r = list->Next(r)) {
|
|
|
|
if ((event->ChannelID() == r->event->ChannelID()) && (event->StartTime() == r->event->StartTime()))
|
|
|
|
continue;
|
|
|
|
i++;
|
|
|
|
sstrReruns << "- "
|
|
|
|
<< *DayDateTime(r->event->StartTime());
|
|
|
|
cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true);
|
|
|
|
if (channel)
|
|
|
|
sstrReruns << " " << channel->ShortName(true);
|
|
|
|
sstrReruns << ": " << r->event->Title();
|
|
|
|
if (!isempty(r->event->ShortText()))
|
|
|
|
sstrReruns << "~" << r->event->ShortText();
|
|
|
|
sstrReruns << std::endl;
|
|
|
|
}
|
|
|
|
delete list;
|
|
|
|
}
|
|
|
|
}
|
2013-12-21 11:25:03 +01:00
|
|
|
reruns.Set(sstrReruns.str().c_str(), fontManager.FontDetailView, contentWidth - scrollBarWidth - 2*border);
|
2013-05-26 17:44:04 +02:00
|
|
|
} else
|
2013-12-21 11:25:03 +01:00
|
|
|
reruns.Set("", fontManager.FontDetailView, contentWidth - scrollBarWidth);
|
2013-05-26 17:44:04 +02:00
|
|
|
}
|
|
|
|
|
2013-06-03 09:52:54 +02:00
|
|
|
int cDetailView::heightEPGPics(void) {
|
|
|
|
int border = 5;
|
|
|
|
int numPicsAvailable = 0;
|
|
|
|
for (int i=1; i <= tvguideConfig.numAdditionalEPGPictures; i++) {
|
|
|
|
cString epgimage = cString::sprintf("%s%d_%d.jpg", *tvguideConfig.epgImagePath, event->EventID(), i);
|
|
|
|
FILE *fp = fopen(*epgimage, "r");
|
|
|
|
if (fp) {
|
|
|
|
numPicsAvailable = i;
|
|
|
|
fclose(fp);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
numEPGPics = numPicsAvailable;
|
2013-08-25 13:57:10 +02:00
|
|
|
int picsPerLine = contentWidth / (tvguideConfig.epgImageWidthLarge + border);
|
2013-06-03 09:52:54 +02:00
|
|
|
int picLines = numPicsAvailable / picsPerLine;
|
|
|
|
if (numPicsAvailable%picsPerLine != 0)
|
|
|
|
picLines++;
|
|
|
|
return picLines * (tvguideConfig.epgImageHeightLarge + border) + 2*border;
|
|
|
|
}
|
|
|
|
|
2013-08-25 13:57:10 +02:00
|
|
|
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++;
|
2013-12-21 11:25:03 +01:00
|
|
|
int actorsHeight = picLines * (actorThumbHeight + 2*fontManager.FontDetailViewSmall->Height()) + fontManager.FontDetailView->Height() + fontManager.FontDetailHeader->Height();
|
2013-08-25 13:57:10 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-06-03 09:52:54 +02:00
|
|
|
void cDetailView::drawEPGPictures(int height) {
|
|
|
|
int border = 5;
|
2013-08-25 13:57:10 +02:00
|
|
|
int picsPerLine = contentWidth / (tvguideConfig.epgImageWidthLarge + border);
|
2013-06-03 09:52:54 +02:00
|
|
|
int currentX = border;
|
|
|
|
int currentY = height + border;
|
|
|
|
int currentPicsPerLine = 1;
|
|
|
|
cImageLoader imgLoader;
|
|
|
|
for (int i=1; i <= numEPGPics; i++) {
|
|
|
|
cString epgimage = cString::sprintf("%d_%d", event->EventID(), i);
|
|
|
|
if (imgLoader.LoadAdditionalEPGImage(epgimage)) {
|
|
|
|
content->DrawImage(cPoint(currentX, currentY), imgLoader.GetImage());
|
|
|
|
int radius = 10;
|
|
|
|
content->DrawEllipse(cRect(currentX,currentY,radius,radius), theme.Color(clrBackground), -2);
|
|
|
|
content->DrawEllipse(cRect(currentX + tvguideConfig.epgImageWidthLarge - radius,currentY,radius,radius), theme.Color(clrBackground), -1);
|
|
|
|
content->DrawEllipse(cRect(currentX,currentY + tvguideConfig.epgImageHeightLarge - radius,radius,radius), theme.Color(clrBackground), -3);
|
|
|
|
content->DrawEllipse(cRect(currentX + tvguideConfig.epgImageWidthLarge - radius,currentY + tvguideConfig.epgImageHeightLarge - radius,radius,radius), theme.Color(clrBackground), -4);
|
|
|
|
if (currentPicsPerLine < picsPerLine) {
|
|
|
|
currentX += tvguideConfig.epgImageWidthLarge + border;
|
|
|
|
currentPicsPerLine++;
|
|
|
|
} else {
|
|
|
|
currentX = border;
|
|
|
|
currentY += tvguideConfig.epgImageHeightLarge + border;
|
|
|
|
currentPicsPerLine = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-25 13:57:10 +02:00
|
|
|
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;
|
2013-12-21 11:25:03 +01:00
|
|
|
tColor colorTextBack = (tvguideConfig.style == eStyleFlat)?theme.Color(clrBackground):clrTransparent;
|
2013-08-25 13:57:10 +02:00
|
|
|
|
|
|
|
cString header = cString::sprintf("%s:", tr("Actors"));
|
2013-12-21 11:25:03 +01:00
|
|
|
content->DrawText(cPoint(border, height), *header, theme.Color(clrFont), colorTextBack, fontManager.FontDetailHeader);
|
2013-08-25 13:57:10 +02:00
|
|
|
|
|
|
|
int picsPerLine = contentWidth / (actorThumbWidth + 2*border);
|
|
|
|
int picLines = numActors / picsPerLine;
|
|
|
|
if (numActors%picsPerLine != 0)
|
|
|
|
picLines++;
|
|
|
|
int x = 0;
|
2013-12-21 11:25:03 +01:00
|
|
|
int y = height + fontManager.FontDetailHeader->Height();
|
2013-08-25 13:57:10 +02:00
|
|
|
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();
|
2013-12-21 11:25:03 +01:00
|
|
|
if (fontManager.FontDetailViewSmall->Width(name.c_str()) > actorThumbWidth + 2*border)
|
|
|
|
name = CutText(name, actorThumbWidth + 2*border, fontManager.FontDetailViewSmall);
|
|
|
|
if (fontManager.FontDetailViewSmall->Width(role.c_str()) > actorThumbWidth + 2*border)
|
|
|
|
role = CutText(role, actorThumbWidth + 2*border, fontManager.FontDetailViewSmall);
|
|
|
|
int xName = x + ((actorThumbWidth+2*border) - fontManager.FontDetailViewSmall->Width(name.c_str()))/2;
|
|
|
|
int xRole = x + ((actorThumbWidth+2*border) - fontManager.FontDetailViewSmall->Width(role.c_str()))/2;
|
2013-08-25 13:57:10 +02:00
|
|
|
if (Running() && content) {
|
2013-12-21 11:25:03 +01:00
|
|
|
content->DrawText(cPoint(xName, y + actorThumbHeight), name.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailViewSmall);
|
|
|
|
content->DrawText(cPoint(xRole, y + actorThumbHeight + fontManager.FontDetailViewSmall->Height()), role.c_str(), theme.Color(clrFont), colorTextBack, fontManager.FontDetailViewSmall);
|
2013-08-25 13:57:10 +02:00
|
|
|
x += actorThumbWidth + 2*border;
|
|
|
|
}
|
|
|
|
actor++;
|
|
|
|
}
|
|
|
|
x = 0;
|
2013-12-21 11:25:03 +01:00
|
|
|
y += actorThumbHeight + 2 * fontManager.FontDetailViewSmall->Height();
|
2013-08-25 13:57:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-09 00:17:42 +02:00
|
|
|
eOSState cDetailView::ProcessKey(eKeys Key) {
|
|
|
|
eOSState state = osContinue;
|
|
|
|
switch (Key & ~k_Repeat) {
|
|
|
|
case kUp:
|
|
|
|
scrollUp();
|
|
|
|
osdManager.flush();
|
|
|
|
break;
|
|
|
|
case kDown:
|
|
|
|
scrollDown();
|
|
|
|
osdManager.flush();
|
|
|
|
break;
|
2013-07-17 16:43:57 +02:00
|
|
|
case kLeft:
|
|
|
|
pageUp();
|
|
|
|
osdManager.flush();
|
|
|
|
break;
|
|
|
|
case kRight:
|
|
|
|
pageDown();
|
|
|
|
osdManager.flush();
|
|
|
|
break;
|
2013-07-09 00:17:42 +02:00
|
|
|
case kOk:
|
|
|
|
case kBack:
|
|
|
|
state = osEnd;
|
2013-05-26 11:38:05 +02:00
|
|
|
break;
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|
2013-07-09 00:17:42 +02:00
|
|
|
return state;
|
2013-01-17 13:16:44 +01:00
|
|
|
}
|