From 9c276fef6474f4cafc2b46e74653026c09c9c02d Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 14 Sep 2014 11:54:59 +0200 Subject: [PATCH] Add first support for TVScraper in VVideolive also some optimization for raspberry in VEPG --- boxx.cc | 4 +- event.cc | 44 ++++++++++ event.h | 11 +++ objects.mk | 1 + vdr.cc | 50 ++++++++++++ vdr.h | 2 + vdrcommand.h | 2 + vepg.cc | 100 +++++++++++++---------- vepg.h | 7 +- vepgsummary.cc | 212 ++++++++++++++++++++++++++++++++++++++++++++++++ vepgsummary.h | 55 +++++++++++++ vvideolivetv.cc | 97 ++++++++++++++++++++-- vvideolivetv.h | 4 + wselectlist.cc | 6 ++ wselectlist.h | 1 + wtvmedia.cc | 1 + 16 files changed, 544 insertions(+), 53 deletions(-) create mode 100644 vepgsummary.cc create mode 100644 vepgsummary.h diff --git a/boxx.cc b/boxx.cc index 16b8e25..da74206 100644 --- a/boxx.cc +++ b/boxx.cc @@ -297,10 +297,10 @@ int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsig break; } thisCharWidth = charWidth(cur_char); - tester.x = lineWidth; + tester.x = lineWidth + x; tester.w = thisCharWidth + 10; - if ((lineWidth + thisCharWidth) > (int)(area.w - (2 * paraMargin)) + if ((lineWidth + thisCharWidth + x) > (int)(area.w - (2 * paraMargin)) || (haschildren && overlapsVisibleChilds(tester))) { // this character would break the right margin diff --git a/event.cc b/event.cc index 42926d2..cd9ac39 100644 --- a/event.cc +++ b/event.cc @@ -19,6 +19,11 @@ */ #include "event.h" +#include "log.h" +#include "command.h" +#include "movieinfo.h" +#include "seriesinfo.h" +#include "vdr.h" Event::Event() { @@ -29,6 +34,8 @@ Event::Event() title = NULL; subtitle = NULL; description = NULL; + movieInfo = NULL; + seriesInfo = NULL; } Event::~Event() @@ -36,6 +43,8 @@ Event::~Event() if (title) delete[] title; if (subtitle) delete[] subtitle; if (description) delete[] description; + if (movieInfo) delete movieInfo; + if (seriesInfo) delete seriesInfo; } void Event::settitle(const char* s) @@ -59,3 +68,38 @@ void Event::setsubtitle(const char* s) strcpy(subtitle, s); } + +void Event::loadinfos(UINT channelid) +{ + VDR *vdr=VDR::getInstance(); + if (movieInfo) delete movieInfo; + if (seriesInfo) delete seriesInfo; + + movieInfo = NULL; + seriesInfo = NULL; + movieID = 0; + seriesID =0; + + vdr->getScraperEventType(channelid, id, movieID, seriesID, episodeID); + Log::getInstance()->log("Event", Log::DEBUG, "Got Scraper EventType %d %d, %d %d %d", + id, channelid, + movieID, seriesID, episodeID); + + if (!vdr->isConnected()) Command::getInstance()->connectionLost(); + + if (movieID != 0) + { + movieInfo = vdr->getScraperMovieInfo(movieID); + Log::getInstance()->log("Event", Log::DEBUG, "Got Scraper MovieInfo "); + } + else if (seriesID != 0) + { + seriesInfo = vdr->getScraperSeriesInfo(seriesID, episodeID); + Log::getInstance()->log("Event", Log::DEBUG, "Got Scraper SeriesInfo "); + } + + + if (!vdr->isConnected()) Command::getInstance()->connectionLost(); +} + + diff --git a/event.h b/event.h index d118b38..7d8b4e7 100644 --- a/event.h +++ b/event.h @@ -27,6 +27,9 @@ #include "defines.h" +class MovieInfo; +class SeriesInfo; + class Event { public: @@ -37,6 +40,8 @@ class Event void setsubtitle(const char* subtitle); void setdescription(const char* description); + void loadinfos(UINT channelid); + ULONG id; #ifdef WIN32 time_t time; @@ -49,6 +54,12 @@ class Event char* title; char* subtitle; char* description; + + MovieInfo *movieInfo; + SeriesInfo *seriesInfo; + int movieID; + int seriesID; + int episodeID; }; class EventSorter diff --git a/objects.mk b/objects.mk index a6dee51..7b6fec5 100644 --- a/objects.mk +++ b/objects.mk @@ -6,6 +6,7 @@ OBJECTS1 = command.o tcp.o dsock.o thread.o timers.o i18n.o \ demuxer.o demuxervdr.o demuxerts.o stream.o \ region.o colour.o boxstack.o boxx.o tbboxx.o \ vinfo.o vquestion.o vrecordinglist.o vrecordinglistclassic.o vrecordinglistadvanced.o vrecording.o \ + vepgsummary.o \ vmute.o vvolume.o vtimerlist.o vtimeredit.o vrecordingmenu.o \ vchannellist.o vwelcome.o vvideorec.o vepgsettimer.o \ vchannelselect.o vserverselect.o vconnect.o vepg.o vrecmove.o \ diff --git a/vdr.cc b/vdr.cc index d09e12f..e20dda0 100644 --- a/vdr.cc +++ b/vdr.cc @@ -1618,6 +1618,33 @@ void VDR::getScraperEventType(char * fileName, int & movieID, } +void VDR::getScraperEventType(UINT channelid, UINT eventid, int & movieID, + int & seriesID, int & episodeID ) +{ + movieID = 0; + seriesID = 0; + episodeID = 0; + VDR_RequestPacket vrp; + if (!vrp.init(VDR_GETEVENTSCRAPEREVENTTYPE, false, 0)) return; + if (!vrp.addULONG(channelid)) return ; + if (!vrp.addULONG(eventid)) return ; + Log::getInstance()->log("Recording", Log::DEBUG, "Before Response "); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + Log::getInstance()->log("Recording", Log::DEBUG, "After Response "); + if (vresp->noResponse()) { delete vresp; return ; } + int type = vresp->extractUCHAR(); + if (type == 0) //serie + { + seriesID = vresp->extractLONG(); + episodeID = vresp->extractLONG(); + } else if (type == 1) //movie + { + movieID = vresp->extractLONG(); + } + delete vresp; + +} + MovieInfo *VDR::getScraperMovieInfo(int movieID) { VDR_RequestPacket vrp; @@ -1813,6 +1840,29 @@ ULONG VDR::loadTVMediaRecThumb(TVMediaInfo & media) edRegister(vdrpr); + VDR_ResponsePacket* vresp = RequestResponse(&vrp); + //if (vresp->noResponse()) { delete vresp; return -1; } + delete vresp; + + return vrp.getSerial(); +} + +ULONG VDR::loadTVMediaEventThumb(TVMediaInfo & media) +{ + + VDR_RequestPacket vrp; + + if (!vrp.init(VDR_LOADTVMEDIAEVENTTHUMB, false, 0)) return -1; + if (!vrp.addULONG(media.primary_id)) return NULL; + if (!vrp.addULONG(media.secondary_id)) return NULL; + + VDR_PacketReceiver* vdrpr = new VDR_PacketReceiver(); + vdrpr->receiverChannel = VDR::CHANNEL_TVMEDIA; + vdrpr->streamID = vrp.getSerial(); + vdrpr->streamReceiver = NULL; + edRegister(vdrpr); + + VDR_ResponsePacket* vresp = RequestResponse(&vrp); //if (vresp->noResponse()) { delete vresp; return -1; } delete vresp; diff --git a/vdr.h b/vdr.h index 5282f75..f850a72 100644 --- a/vdr.h +++ b/vdr.h @@ -206,10 +206,12 @@ class VDR : public Thread_TYPE, public EventDispatcher, public MediaProvider, pu //TV Scraper support void getScraperEventType(char * fileName, int & movieID, int & seriesID, int & episodeID); + void getScraperEventType(UINT eventid, UINT channelid, int & movieID, int & seriesID, int & episodeID); MovieInfo *getScraperMovieInfo(int movieID); SeriesInfo *getScraperSeriesInfo(int seriesID, int episodeID); ULONG loadTVMedia(TVMediaInfo& tvmedia); ULONG loadTVMediaRecThumb(TVMediaInfo& tvmedia); + ULONG loadTVMediaEventThumb(TVMediaInfo& tvmedia); void invalidateTVMedia(ULONG loadindex); diff --git a/vdrcommand.h b/vdrcommand.h index 9991b1d..21bd2be 100644 --- a/vdrcommand.h +++ b/vdrcommand.h @@ -74,6 +74,8 @@ const static ULONG VDR_GETSCRAPERMOVIEINFO = 39; const static ULONG VDR_GETSCRAPERSERIESINFO = 40; const static ULONG VDR_LOADTVMEDIA = 41; const static ULONG VDR_LOADTVMEDIARECTHUMB = 42; +const static ULONG VDR_GETEVENTSCRAPEREVENTTYPE = 43; +const static ULONG VDR_LOADTVMEDIAEVENTTHUMB = 44; const static ULONG VDR_SHUTDOWN = 666; class VDR_Command : public SerializableList { diff --git a/vepg.cc b/vepg.cc index 7839ca4..5af3e0d 100644 --- a/vepg.cc +++ b/vepg.cc @@ -47,6 +47,7 @@ #include "i18n.h" #include "log.h" + VEpg* VEpg::instance = NULL; VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType) @@ -56,34 +57,40 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType) // PAL / NTSC sizes ----------------------- - int xsize, ysize; int xpos, ypos; - int summaryLines, summaryLowerPadding; - int chanNameYpos; + //int summaryLines, summaryLowerPadding; + //int chanNameYpos; + int fontHeight=getFontHeight() + 4; //UINT gridRows; // is a class member + if (Video::getInstance()->getFormat() == Video::PAL) { - xsize = 632; - ysize = 541; - xpos = 60; + //xsize = 647; + //ysize = 541; + xpos = 30; ypos = 16; - summaryLines = 8; - summaryLowerPadding = 18; - chanNameYpos = 244; + + //summaryLines = 8; + + //chanNameYpos = 244; gridRows = 7; } else { - xsize = 632; - ysize = 452; xpos = 50; - ypos = 10; - summaryLines = 6; - summaryLowerPadding = 28; - chanNameYpos = 206; + ypos = 20; + //summaryLines = 6; + //summaryLowerPadding = 28; + //chanNameYpos = 206; gridRows = 5; } + int screenwidthhalf=Video::getInstance()->getScreenWidth()/2; + int screenheighthalf=Video::getInstance()->getScreenHeight()/2; + // summaryLines = ((float)screenheighthalf)/((float)fontHeight))-1; + // summaryLowerPadding = screenheighthalf-summaryLines*(fontHeight); + gridRows = (screenheighthalf-fontHeight*2-40)/fontHeight; + // initialise variables and pointers boxstack = BoxStack::getInstance(); @@ -92,6 +99,7 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType) chanList = VDR::getInstance()->getChannelsList(streamType); //TODO want to be able to display video and radio together e = 0; + eventLista.resize(gridRows); for(UINT listIndex = 0; listIndex < gridRows; listIndex++) { // initialise array of pointers to eventlist structures @@ -101,9 +109,9 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType) // Create pallet on which to paint our epg view and position it in centre of screen. // Need to reduce size to deal with overscanning TVs. - setSize(xsize, ysize); + setSize(Video::getInstance()->getScreenWidth(), Video::getInstance()->getScreenHeight()); createBuffer(); - setPosition(xpos, ypos); + setPosition(0, 0); // beautify // DrawStyle transparent = DrawStyle(0, 0, 0, 0); @@ -111,31 +119,33 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType) // progTitle.setSurface(surface); progTitle.setPosition(0,0); - progTitle.setSize(300,(getFontHeight() + 4) * 2 + 16); //paragraph line seperation is 4 pixels + progTitle.setSize(screenwidthhalf,(fontHeight) * 1 + ypos); //paragraph line seperation is 4 pixels progTitle.setBackgroundColour(DrawStyle::TITLEBARBACKGROUND); - progTitle.setTextPos(5, 16); + progTitle.setTextPos(xpos, ypos); progTitle.setGap(4); add(&progTitle); // progInfo.setSurface(surface); progInfo.setBackgroundColour(DrawStyle::VIEWBACKGROUND); progInfo.setPosition(0, progTitle.getY2()); - progInfo.setSize(300,((getFontHeight() + 4) * summaryLines) + summaryLowerPadding); + progInfo.setSize(screenwidthhalf,screenheighthalf-progTitle.getY2()+10); + progInfo.setTextPos(xpos, 0); progInfo.setGap(4); add(&progInfo); // chanName.setSurface(surface); - chanName.setSize(510, (getFontHeight() + 4)); - chanName.setPosition(305, chanNameYpos); + chanName.setSize(510, (fontHeight)); + chanName.setPosition(screenwidthhalf, screenheighthalf - 2*fontHeight); DrawStyle t1(0, 0, 0, 90); chanName.setBackgroundColour(t1); add(&chanName); // create area to display list of channels // chanListbox.setSurface(surface); // add channel list - chanListbox.setPosition(0, progInfo.getY2() + getFontHeight() + 8); // position channel list + chanListbox.setPosition(0, progInfo.getY2() + fontHeight + 4); // position channel list chanListbox.setSize(150, ((getFontHeight() + 2) * gridRows) + 5); //listbox line seperation is 2 pixels chanListbox.setGap(2); + chanListbox.addColumn(xpos); add(&chanListbox); // populate channel list @@ -154,6 +164,9 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType) chanName.setText((*chanList)[chanListbox.getCurrentOption()]->name); } + window_x= chanListbox.getRootBoxOffsetX() + chanListbox.getWidth() + 5; + window_width=(Video::getInstance()->getScreenWidth() - window_x +3)/3; + listTop = chanListbox.getTopOption(); chanListbox.draw(); // doing this to allow chanListbox.getBottomOption() in updateEventList() to work time(<ime); // set ltime to now @@ -235,9 +248,10 @@ void VEpg::draw() // Display the status and key stuff at the bottom - UINT keyx = chanListbox.getRootBoxOffsetX(); + UINT keyx = chanListbox.getRootBoxOffsetX() + chanListbox.getColumn(0); UINT keyy = chanListbox.getRootBoxOffsetY() + chanListbox.getHeight() + 2; - rectangle(keyx, keyy, 605, getFontHeight() * 2 + 14, DrawStyle::DARKGREY); + rectangle (0, keyy, Video::getInstance()->getScreenWidth() , + Video::getInstance()->getScreenHeight()-keyy, DrawStyle::DARKGREY); WSymbol w; TEMPADD(&w); @@ -258,7 +272,7 @@ void VEpg::draw() w.setPosition(keyx + 50, keyy + 20); w.draw(); - drawText(tr("OK"), keyx + 18, keyy + 20, DrawStyle::LIGHTTEXT); + drawTextCentre(tr("OK"), keyx + 35, keyy + 20, DrawStyle::LIGHTTEXT); rectangle(keyx + 72, keyy + 4, 104, getFontHeight() + 2, DrawStyle::RED); drawText(tr("Page up"), keyx + 74, keyy + 5, DrawStyle::LIGHTTEXT); @@ -298,11 +312,11 @@ void VEpg::drawData() // Not doing View::draw() every time causes // things not to be cleared off the surface properly // So, blank out the data area first - + int screenwidth=Video::getInstance()->getScreenWidth(); rectangle( chanListbox.getRootBoxOffsetX(), chanListbox.getRootBoxOffsetY() - getFontHeight() - 3, - 155 + WINDOW_WIDTH * MINUTE_SCALE, + window_width * MINUTE_SCALE, chanListbox.getHeight() + getFontHeight() + 4, DrawStyle::BLACK); @@ -512,7 +526,7 @@ void VEpg::drawgrid() // redraws grid and select programme listTop = chanListbox.getTopOption(); updateEventList(); } - if ((selTime >= ltime + WINDOW_WIDTH * 60) || (selTime <= ltime)) + if ((selTime >= ltime + window_width * 60) || (selTime <= ltime)) { // we have cursored back before left time of window //TODO check that this and above don't happen together @@ -522,6 +536,7 @@ void VEpg::drawgrid() // redraws grid and select programme // draw time scale DrawStyle white = DrawStyle(255, 255, 255, 255); + t = ltime; struct tm* tms; tms = localtime(&t); @@ -550,14 +565,14 @@ void VEpg::drawgrid() // redraws grid and select programme time(&t); if ((t >= ltime) && (t < (ltime + 9000))) { - rectangle(155 + (t - ltime) / 20, timey + getFontHeight(), 2, ((getFontHeight() + 2) * 7) + 7 + 2, DrawStyle::RED); + rectangle(155 + (t - ltime) / 20, timey + getFontHeight(), 2, ((getFontHeight() + 2) * gridRows) + 7 + 2, DrawStyle::RED); } // TODO should the above two comditional statements be combined to avoid calling updateEventList() twice? Event* event; Event noevent; // an event to use if there are gaps in the epg thisEvent.setdescription(tr("There are no programme details available for this period")); - thisEvent.duration = WINDOW_WIDTH * 60; + thisEvent.duration = window_width * 60; thisEvent.time = ltime; thisEvent.settitle(tr("No programme details")); thisEvent.id = 0; @@ -570,15 +585,16 @@ void VEpg::drawgrid() // redraws grid and select programme { if (listTop + (int)listIndex >= chanListbox.getBottomOption()) continue; // ensure nothing populates grid below last channel + currentRow = (listTop + (int)listIndex == chanListbox.getCurrentOption()); noevent.time = ltime; - noevent.duration = WINDOW_WIDTH * 60; + noevent.duration = window_width * 60; noevent.settitle(""); paintCell(&noevent, y, DrawStyle::NOPROGRAMME, DrawStyle::LIGHTTEXT); // fill row with no programme colour to be painted ove with valid programmes if (currentRow) { thisEvent.setdescription(tr("There are no programme details available for this period")); - thisEvent.duration = WINDOW_WIDTH * 60; + thisEvent.duration = window_width * 60; thisEvent.time = ltime; thisEvent.settitle(tr("No programme details")); thisEvent.id = 0; @@ -593,7 +609,7 @@ void VEpg::drawgrid() // redraws grid and select programme if (event) { UINT end = event->time + event->duration; // programme end time - if(event->time >= UINT(ltime) + (WINDOW_WIDTH * 60)) // programme starts after RHS of window + if(event->time >= UINT(ltime) + (window_width * 60)) // programme starts after RHS of window continue; // that's enough of this channel's events if(end <= UINT(ltime)) // programme ends before LHS of window continue; // this event is before the window - let's try the next event @@ -658,8 +674,7 @@ void VEpg::updateEventList() if(listTop + listIndex >= UINT(chanListbox.getBottomOption())) continue; chan = (*chanList)[listTop + listIndex]; - - eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, ltime - 1, WINDOW_WIDTH * 60 + 2); // ltime - 1 to get prog before window (allows cursor left past ltime). + 2 to get prog after window + eventLista[listIndex] = VDR::getInstance()->getChannelSchedule(chan->number, ltime - 1, window_width * 60 + 2); // ltime - 1 to get prog before window (allows cursor left past ltime). + 2 to get prog after window } } @@ -676,27 +691,26 @@ void VEpg::paintCell(Event* event, int yOffset, const DrawStyle& bg, const DrawS { int w, x, y, h; w = x = 0; // keep compiler happy - y =yOffset; h = getFontHeight(); // TODO if want border around text, need to increae this and wselectlist line height UINT end = event->time + event->duration; // programme end time if(event->time <= UINT(ltime) && end > UINT(ltime)) // spans start of displayed window { x = 155; // LHS of window - if (end > (UINT(ltime) + (WINDOW_WIDTH * 60))) - w = WINDOW_WIDTH * MINUTE_SCALE; // spans full 2 hour window + if (end > (UINT(ltime) + (window_width * 60))) + w = window_width * MINUTE_SCALE; // spans full 2 hour window else w = MINUTE_SCALE * (event->time + event->duration - ltime ) / 60; // get width of remaining programme } - if((event->time >= UINT(ltime)) && (event->time <= UINT(ltime) + (WINDOW_WIDTH * 60))) // starts within window + if((event->time >= UINT(ltime)) && (event->time <= UINT(ltime) + (window_width * 60))) // starts within window { x = 155 + (MINUTE_SCALE * (event->time - ltime) / 60); w = MINUTE_SCALE * event->duration / 60; //if (w > 155 + MINUTE_SCALE * WINDOW_WIDTH -x) // w = w + x - 155 - MINUTE_SCALE * WINDOW_WIDTH; // ends outside window } - if (w > 155 + WINDOW_WIDTH * MINUTE_SCALE - x) - w = 155 + WINDOW_WIDTH * MINUTE_SCALE -x; // limit cells to RHS of window + if (w > 155 + window_width * MINUTE_SCALE - x) + w = 155 + window_width * MINUTE_SCALE -x; // limit cells to RHS of window rectangle(x, y, w, h, bg); char* tt = new char[strlen(event->title) + 1]; strcpy (tt, event->title); @@ -796,7 +810,7 @@ void VEpg::processMessage(Message* m) } else if ( x>=(chanListbox.getRootBoxOffsetX()) && y>=(chanListbox.getRootBoxOffsetY() + 5) - // &&x<=(chanListbox.getOffsetX()+155 + WINDOW_WIDTH * MINUTE_SCALE) + // &&x<=(chanListbox.getOffsetX()+155 + window_width * MINUTE_SCALE) &&y<=(chanListbox.getRootBoxOffsetY() - getFontHeight() - 3+(int)chanListbox.getHeight() + getFontHeight() + 3) ) diff --git a/vepg.h b/vepg.h index 2f37e3f..b3bbf09 100644 --- a/vepg.h +++ b/vepg.h @@ -23,6 +23,7 @@ #include #include +#include #include "boxx.h" #include "defines.h" @@ -36,7 +37,7 @@ class Message; class VVideoLive; class BoxStack; -#define WINDOW_WIDTH (150) +//#define WINDOW_WIDTH (150) #define MINUTE_SCALE (3) class VVideoLive; @@ -75,7 +76,7 @@ class VEpg : public Boxx, public TimerReceiver time_t ltime; // time of LHS of epg view time_t lastEnd; // end time of last painted cell - used to look for gaps in epg WTextbox chanName; - EventList* eventLista[7]; + std::vector eventLista; int listTop; int listWindowSize; void updateChanList(); @@ -86,6 +87,8 @@ class VEpg : public Boxx, public TimerReceiver BoxStack* boxstack; UINT gridRows; UINT currentChannelIndex; + UINT window_width; + UINT window_x; }; #endif diff --git a/vepgsummary.cc b/vepgsummary.cc new file mode 100644 index 0000000..023ab18 --- /dev/null +++ b/vepgsummary.cc @@ -0,0 +1,212 @@ +/* + Copyright 2004-2008 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "vepgsummary.h" + +#include "remote.h" +#include "vquestion.h" +#include "vinfo.h" +#include "vdr.h" +#include "colour.h" +#include "video.h" +#include "i18n.h" +#include "command.h" +#include "boxstack.h" +#include "event.h" +#include "message.h" +#include "log.h" +#include "wmovieview.h" +#include "wseriesview.h" +#include "wpictureview.h" + +#include + +VEpgSummary::VEpgSummary(Event *tevent) +{ + event = tevent; + + + if (Video::getInstance()->getFormat() == Video::PAL) + { + setSize(640, 500); + createBuffer(); + } + else + { + setSize(560, 400); + createBuffer(); + } + setPosition(40, 40); + + setTitleBarOn(1); + setBorderOn(1); + setTitleText(event->title); + + setTitleBarColour(DrawStyle::TITLEBARBACKGROUND); + + tabbar.setPosition(10+10, 30 + 5); + tabbar.setSize(area.w - 20-10, area.h - 30 - 10); + add(&tabbar); + + + WTextbox * summary=new WTextbox(); + summary->setParaMode(true); + + std::string summary_text = std::string(event->subtitle)+ "\n" +std::string(event->description); + + summary->setText(summary_text.c_str()); + OsdVector *osdv=dynamic_cast(Osd::getInstance()); + + tabbar.addTab(tr("EPG"), summary); + if (event->movieInfo) { + WMovieView *movieview = new WMovieView(event->movieInfo); + movieview->setParaMode(true); + tabbar.addTab(tr("TheTVDB Info"), movieview); + if (osdv) { + if (event->movieInfo->actors.size() > 0 && osdv) + { + WActorGallery *gallery= new WActorGallery(event->movieInfo->actors); + tabbar.addTab(tr("Cast"),gallery); + } + WArtworkGallery *artgallery= new WArtworkGallery(*event->movieInfo); + tabbar.addTab(tr("Gallery"),artgallery); + } + } else if (event->seriesInfo) { + WSeriesView *seriesview = new WSeriesView(event->seriesInfo); + seriesview->setParaMode(true); + tabbar.addTab(tr("TheTVDB Info"), seriesview); + if (osdv) { + if (event->seriesInfo->actors.size() > 0 && osdv) + { + WActorGallery *gallery= new WActorGallery(event->seriesInfo->actors); + tabbar.addTab(tr("Cast"),gallery); + } + WArtworkGallery *artgallery= new WArtworkGallery(*event->seriesInfo); + tabbar.addTab(tr("Gallery"),artgallery); + } + + } + + epgTVmedia.setPosition(summary->getRegionR().w-130-10,0); + epgTVmedia.setSize(130,195/Osd::getInstance()->getPixelAspect()); + summary->add(&epgTVmedia); + TVMedia poster; + poster.height=0; + if (event->movieInfo) { + poster=event->movieInfo->poster; + } + if (event->seriesInfo) { + if (event->seriesInfo->seasonposter.height) { + poster=event->seriesInfo->seasonposter; + } + else + if (event->seriesInfo->posters.size()) { + poster=event->seriesInfo->posters[0]; + } + } + if (poster.height) { + epgTVmedia.setTVMedia(poster.info, WTVMedia::ZoomHorizontal); + epgTVmedia.setVisible(true); + } else { + epgTVmedia.setVisible(false); + } + + + /* + int sfh = getFontHeight(); + buttonRegion.x = 10; + buttonRegion.y = 10+30; + buttonRegion.w = 130; + buttonRegion.h = sfh*2*last; + + button[PLAY].setText(tr("Play")); + button[RESUME].setText(tr("Resume")); + button[MOVE].setText(tr("Move")); + button[A_DELETE].setText(tr("Delete")); + + for (int i=PLAY, ver=10+30; iupdate(this); + return 2; + } + else if (retval == 2) + { + + return 2; + } + + + + // stop command getting to any more views + return 1; +} + + + +void VEpgSummary::processMessage(Message* m) +{ + if (m->message == Message::MOUSE_MOVE) + { + // todo + } + else if (m->message == Message::MOUSE_LBDOWN) + { + int cancel = true; + if (cancel) + { + //check if press is outside this view! then simulate cancel + int x=(m->parameter>>16)-getScreenX(); + int y=(m->parameter&0xFFFF)-getScreenY(); + if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) + { + BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press + } + } + } +} + + diff --git a/vepgsummary.h b/vepgsummary.h new file mode 100644 index 0000000..b52df1e --- /dev/null +++ b/vepgsummary.h @@ -0,0 +1,55 @@ +/* + Copyright 2004-2008 Chris Tallon, 2014 Marten Richter + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef VEPGSUMMARY_H +#define VEPGSUMMARY_H + +#include +#include + +#include "tbboxx.h" +#include "wtvmedia.h" +#include "wtextbox.h" +#include "wtabbar.h" +#include "movieinfo.h" +#include "seriesinfo.h" + +class VRecordingList; +class Event; +class Message; + +class VEpgSummary : public TBBoxx +{ + public: + VEpgSummary(Event* event); + ~VEpgSummary(); + + + + int handleCommand(int command); + void processMessage(Message* m); + + private: + Event* event; + WTabBar tabbar; + WTVMedia epgTVmedia; +}; + +#endif diff --git a/vvideolivetv.cc b/vvideolivetv.cc index d3b6109..efc1cd7 100644 --- a/vvideolivetv.cc +++ b/vvideolivetv.cc @@ -42,6 +42,7 @@ #include "bitmap.h" #include "log.h" #include "vteletextview.h" +#include "vepgsummary.h" VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, VChannelList* tvchannelList) : osdBack(0, 0, 0, 128) @@ -121,8 +122,13 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V // This variable is set to true if the user pressed OK to bring the OSD on screen // This is only used on old remotes to stop up/down buttons being used for osd-epg scrolling okTriggeredOSD = false; - - + + osdposterbanner.setPosition(20,20); + osdposterbanner.setBackgroundColour(osdBack); + osdposterbanner.setSize(video->getScreenWidth()*4/10,video->getScreenHeight()*4/10); + osdposterbanner.setVisible(false); + add(&osdposterbanner); + osd.setBackgroundColour(osdBack); osd.setPosition(0, video->getScreenHeight() - 150); @@ -130,6 +136,7 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V osd.setVisible(false); add(&osd); + clock.setBackgroundColour(osdBack); clock.setPosition(osd.getWidth() - 100, 4); clock.setSize(90, 30); @@ -520,6 +527,24 @@ void VVideoLiveTV::doOK() void VVideoLiveTV::doSummary() { + displayOSD(false); + Channel* currentChannel = (*chanList)[osdChannelIndex]; + eventList = VDR::getInstance()->getChannelSchedule(currentChannel->number); + if (!eventList) + { + return; + } + sort(eventList->begin(), eventList->end(), EventSorter()); + + if (eventList->size() < 1) return; + Event* event = (*eventList)[0]; + event->loadinfos(currentChannel->number); + + VEpgSummary* vr = new VEpgSummary(event); + vr->draw(); + boxstack->add(vr); + boxstack->update(vr); +/* if (summary.getVisible()) { summary.setVisible(false); @@ -539,7 +564,7 @@ void VVideoLiveTV::doSummary() else { displayOSD(true); - } + }*/ } void VVideoLiveTV::doKey(int command) @@ -547,6 +572,7 @@ void VVideoLiveTV::doKey(int command) if (!osd.getVisible()) // First key. prep the data { setNowNextData(); + updatePosterBanner(); keying = 0; } @@ -760,19 +786,29 @@ void VVideoLiveTV::displayOSD(bool newNowNextData) if (newNowNextData) { setNowNextData(); + updatePosterBanner(); keying = 0; } osd.draw(); + if (osdposterbanner.getVisible()) osdposterbanner.draw(); + + Region toupdate; if (summary.getVisible()) { setSummaryData(); summary.draw(); - boxstack->update(this, &osdSummaryRegion); + toupdate=osdSummaryRegion; } else { - boxstack->update(this, osd.getRegion()); + toupdate=*osd.getRegion(); + } + + if (osdposterbanner.getVisible()) { + boxstack->update(this); + } else { + boxstack->update(this, &toupdate); } bool setTimer = true; @@ -790,6 +826,7 @@ void VVideoLiveTV::clearScreen() textUnavailable.setVisible(false); osd.setVisible(false); summary.setVisible(false); + osdposterbanner.setVisible(false); okTriggeredOSD = false; @@ -855,13 +892,16 @@ void VVideoLiveTV::timercall(int ref) Timers::getInstance()->setTimerD(this, 1, 2); // reset timer for another 2s return; } + bool osdpbvisible=osdposterbanner.getVisible(); Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Timer Call 1 notkey 1."); osd.setVisible(false); + osdposterbanner.setVisible(false); okTriggeredOSD = false; Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Timer Call 1 notkey 2."); draw(); Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Timer Call 1 notkey 4."); - boxstack->update(this, osd.getRegion()); + if (osdpbvisible) boxstack->update(this); + else boxstack->update(this, osd.getRegion()); Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Timer Call 1 notkey 3."); (static_cast(player))->tellSubtitlesOSDVisible(false); @@ -1196,6 +1236,51 @@ void VVideoLiveTV::toggleChopSides() } } +void VVideoLiveTV::updatePosterBanner() +{ + OsdVector *osdv=dynamic_cast(Osd::getInstance()); + if (!osdv) { + osdposterbanner.setVisible(false); + return; + } + Event* toShow = NULL; + if (eventList && eventList->size()) { + toShow = (*eventList)[0]; + Channel* currentChannel = (*chanList)[osdChannelIndex]; + toShow->loadinfos(currentChannel->number); + } + + if (toShow) + { + TVMedia poster; + poster.height=0; + bool posterscale=true; + if (toShow->movieInfo) { + poster=toShow->movieInfo->poster; + } + if (toShow->seriesInfo) { + if (toShow->seriesInfo->banners.size()) { + poster=toShow->seriesInfo->banners[0]; + posterscale=false; + } else if (toShow->seriesInfo->seasonposter.height) { + poster=toShow->seriesInfo->seasonposter; + } else if (toShow->seriesInfo->posters.size()) { + poster=toShow->seriesInfo->posters[0]; + } + } + if (poster.height) { + osdposterbanner.setTVMedia(poster.info, posterscale ? WTVMedia::ZoomVertical : WTVMedia::ZoomHorizontal); + osdposterbanner.setVisible(true); + } else { + osdposterbanner.setVisible(false); + } + } else { + osdposterbanner.setVisible(false); + } + +} + + void VVideoLiveTV::drawOSDBitmap(UINT posX, UINT posY, const Bitmap& bm, const DisplayRegion& region) { drawBitmap(posX, posY, bm,region); diff --git a/vvideolivetv.h b/vvideolivetv.h index 9f1f767..a84cf89 100644 --- a/vvideolivetv.h +++ b/vvideolivetv.h @@ -34,6 +34,7 @@ #include "wsymbol.h" #include "wprogressbar.h" #include "osdreceiver.h" +#include "wtvmedia.h" #ifdef PAL_WSS #include "wwss.h" @@ -111,6 +112,8 @@ class VVideoLiveTV : public Boxx, public TimerReceiver, public OSDReceiver UINT downChannel(UINT index); void toggleChopSides(); + void updatePosterBanner(); + void displayOSD(bool newNowNextData); void clearScreen(); void setClock(); @@ -144,6 +147,7 @@ class VVideoLiveTV : public Boxx, public TimerReceiver, public OSDReceiver WProgressBar bufferBar; WSymbol sAudioChannels; WTextbox textUnavailable; + WTVMedia osdposterbanner; Boxx summary; WTextbox textSummary; diff --git a/wselectlist.cc b/wselectlist.cc index 2799639..f8ecc13 100644 --- a/wselectlist.cc +++ b/wselectlist.cc @@ -145,6 +145,12 @@ void WSelectList::addColumn(int x) columns[numColumns++] = x; } +int WSelectList::getColumn(int x) +{ + if (x>= numColumns) return 0; + return columns[x]; +} + void WSelectList::drawOptionLine(char* text, int xpos, int ypos, int width, const DrawStyle& colour, TVMediaInfo* pict) { UINT curline = 0; diff --git a/wselectlist.h b/wselectlist.h index 212f21e..455622b 100644 --- a/wselectlist.h +++ b/wselectlist.h @@ -45,6 +45,7 @@ class WSelectList : public Boxx virtual ~WSelectList(); void clear(); void addColumn(int x); + int getColumn(int x); void setNoLoop(); void setShowSelOption(bool set) { showseloption = set; }; diff --git a/wtvmedia.cc b/wtvmedia.cc index 4e16e6c..ca59b11 100644 --- a/wtvmedia.cc +++ b/wtvmedia.cc @@ -45,6 +45,7 @@ void WTVMedia::draw() { + //Boxx::draw(); if (!media) return; float w=0; float h=0; -- 2.39.2