diff options
author | louis <louis.braun@gmx.de> | 2016-05-26 10:47:45 +0200 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2016-05-26 10:47:45 +0200 |
commit | a57c44b06874ba146ca27a5c87868c1e3c304875 (patch) | |
tree | 844945c2f05d05ae80eb6fb1126db267253a1deb | |
parent | ffb414cdee209097f19f925c46de9f105cf5358e (diff) | |
download | vdr-plugin-skindesigner-a57c44b06874ba146ca27a5c87868c1e3c304875.tar.gz vdr-plugin-skindesigner-a57c44b06874ba146ca27a5c87868c1e3c304875.tar.bz2 |
introduced zapcockpit extension
31 files changed, 3410 insertions, 165 deletions
diff --git a/coreengine/area.c b/coreengine/area.c index a2a9641..6e4beb1 100644 --- a/coreengine/area.c +++ b/coreengine/area.c @@ -425,8 +425,14 @@ void cArea::SetViewPort(cRect &vp) { void cArea::SetPosition(cPoint &pos, cPoint &ref) { if (!pix) return; - int x = (attribs->X() - ref.X()) + pos.X(); - int y = (attribs->Y() - ref.Y()) + pos.Y(); + int x0 = attribs->X() == -1 ? 0 : attribs->X(); + int y0 = attribs->Y() == -1 ? 0 : attribs->Y(); + int x = (x0 - ref.X()) + pos.X(); + int y = (y0 - ref.Y()) + pos.Y(); +/* Enable for xineliboutput OSD Bug + if (x < 0) x = 0; + if (y < 0) y = 0; +*/ pix->SetViewPort(cRect(x, y, pix->ViewPort().Width(), pix->ViewPort().Height())); } @@ -518,7 +524,7 @@ void cArea::CreatePixmap(cRect drawPort) { } int layer = attribs->Layer(); - cRect viewPort(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + cRect viewPort(attribs->X() == -1 ? 0 : attribs->X(), attribs->Y() == -1 ? 0 : attribs->Y(), attribs->Width(), attribs->Height()); pix = sdOsd->CreatePixmap(layer, viewPort, drawPort); if (pix) pix->Clear(); diff --git a/coreengine/attributes.c b/coreengine/attributes.c index 8e71c1a..4840dbc 100644 --- a/coreengine/attributes.c +++ b/coreengine/attributes.c @@ -126,15 +126,18 @@ void cViewAttribs::SetOrientationDynamic(int id, const char *val) { ***************************************************************************/ cViewElementAttribs::cViewElementAttribs(int numAttributes) : cAttributes(numAttributes) { name = NULL; + clearOnDisplay = NULL; SetAttributesDefs(); } cViewElementAttribs::cViewElementAttribs(const cViewElementAttribs &other) : cAttributes(other) { name = NULL; + clearOnDisplay = NULL; } cViewElementAttribs::~cViewElementAttribs(void) { free(name); + free(clearOnDisplay); } void cViewElementAttribs::Set(vector<stringpair> &attributes) { @@ -158,6 +161,8 @@ void cViewElementAttribs::Set(vector<stringpair> &attributes) { SetOrientation(id, attVal); } else if (IdEqual(id, (int)eViewElementAttribs::name)) { name = strdup(attVal); + } else if (IdEqual(id, (int)eViewElementAttribs::clearondisplay)) { + clearOnDisplay = strdup(attVal); } else { attribCtors[id] = new cNumericExpr(attVal); if (id == (int)eViewElementAttribs::starty + (int)eCommonAttribs::count) { @@ -178,6 +183,7 @@ void cViewElementAttribs::SetAttributesDefs(void) { attribIDs.insert(pair<string, int>("orientation", (int)eViewElementAttribs::orientation)); attribIDs.insert(pair<string, int>("mode", (int)eViewElementAttribs::mode)); attribIDs.insert(pair<string, int>("name", (int)eViewElementAttribs::name)); + attribIDs.insert(pair<string, int>("clearondisplay", (int)eViewElementAttribs::clearondisplay)); attribNames.insert(pair<int, string>((int)eViewElementAttribs::delay, "delay")); attribNames.insert(pair<int, string>((int)eViewElementAttribs::fadetime, "fadetime")); attribNames.insert(pair<int, string>((int)eViewElementAttribs::shifttime, "shifttime")); @@ -188,6 +194,7 @@ void cViewElementAttribs::SetAttributesDefs(void) { attribNames.insert(pair<int, string>((int)eViewElementAttribs::orientation, "orientation")); attribNames.insert(pair<int, string>((int)eViewElementAttribs::mode, "mode")); attribNames.insert(pair<int, string>((int)eViewElementAttribs::name, "name")); + attribNames.insert(pair<int, string>((int)eViewElementAttribs::clearondisplay, "clearondisplay")); } eOrientation cViewElementAttribs::Orientation(void) { @@ -233,6 +240,10 @@ void cViewListAttribs::Set(vector<stringpair> &attributes) { determinateFont = strdup(attVal); } else if (IdEqual(id, (int)eViewListAttribs::orientation)) { SetOrientation(id, attVal); + } else if (IdEqual(id, (int)eViewListAttribs::shifttype)) { + SetShiftType(id, attVal); + } else if (IdEqual(id, (int)eViewListAttribs::shiftmode)) { + SetShiftMode(id, attVal); } else { attribCtors[id] = new cNumericExpr(attVal); } @@ -271,12 +282,24 @@ void cViewListAttribs::SetAttributesDefs(void) { attribIDs.insert(pair<string, int>("determinatefont", (int)eViewListAttribs::determinatefont)); attribIDs.insert(pair<string, int>("numlistelements", (int)eViewListAttribs::numlistelements)); attribIDs.insert(pair<string, int>("orientation", (int)eViewListAttribs::orientation)); + attribIDs.insert(pair<string, int>("fadetime", (int)eViewListAttribs::fadetime)); + attribIDs.insert(pair<string, int>("shifttime", (int)eViewListAttribs::shifttime)); + attribIDs.insert(pair<string, int>("shifttype", (int)eViewListAttribs::shifttype)); + attribIDs.insert(pair<string, int>("shiftmode", (int)eViewListAttribs::shiftmode)); + attribIDs.insert(pair<string, int>("startx", (int)eViewListAttribs::startx)); + attribIDs.insert(pair<string, int>("starty", (int)eViewListAttribs::starty)); attribIDs.insert(pair<string, int>("condition", (int)eViewListAttribs::condition)); attribNames.insert(pair<int, string>((int)eViewListAttribs::align, "align")); attribNames.insert(pair<int, string>((int)eViewListAttribs::menuitemwidth, "menuitemwidth")); attribNames.insert(pair<int, string>((int)eViewListAttribs::determinatefont, "determinatefont")); attribNames.insert(pair<int, string>((int)eViewListAttribs::numlistelements, "numlistelements")); attribNames.insert(pair<int, string>((int)eViewListAttribs::orientation, "orientation")); + attribNames.insert(pair<int, string>((int)eViewListAttribs::fadetime, "fadetime")); + attribNames.insert(pair<int, string>((int)eViewListAttribs::shifttime, "shifttime")); + attribNames.insert(pair<int, string>((int)eViewListAttribs::shifttype, "shifttype")); + attribNames.insert(pair<int, string>((int)eViewListAttribs::shiftmode, "shiftmode")); + attribNames.insert(pair<int, string>((int)eViewListAttribs::startx, "startx")); + attribNames.insert(pair<int, string>((int)eViewListAttribs::starty, "starty")); attribNames.insert(pair<int, string>((int)eViewListAttribs::condition, "condition")); } diff --git a/coreengine/attributes.h b/coreengine/attributes.h index 1af17ef..228964d 100644 --- a/coreengine/attributes.h +++ b/coreengine/attributes.h @@ -30,6 +30,7 @@ public: class cViewElementAttribs : public cAttributes { private: char *name; + char *clearOnDisplay; void SetAttributesDefs(void); public: cViewElementAttribs(int numAttributes); @@ -45,6 +46,7 @@ public: int ShiftType(void) { return GetValue((int)eViewElementAttribs::shifttype); }; int ShiftMode(void) { return GetValue((int)eViewElementAttribs::shiftmode); }; const char *Name(void) { return name; }; + const char *ClearOnDisplay(void) { return clearOnDisplay; }; void Debug(void); }; /****************************************************************** @@ -63,6 +65,11 @@ public: const char *DeterminateFont(void); eAlign Align(void); eOrientation Orientation(void); + int FadeTime(void) { return GetValue((int)eViewListAttribs::fadetime); }; + int ShiftTime(void) { return GetValue((int)eViewListAttribs::shifttime); }; + cPoint ShiftStartpoint(void) { return cPoint(GetValue((int)eViewListAttribs::startx), GetValue((int)eViewListAttribs::starty)); }; + int ShiftType(void) { return GetValue((int)eViewListAttribs::shifttype); }; + int ShiftMode(void) { return GetValue((int)eViewListAttribs::shiftmode); }; void Debug(void); }; /****************************************************************** diff --git a/coreengine/definitions.h b/coreengine/definitions.h index ccb9acb..51f298d 100644 --- a/coreengine/definitions.h +++ b/coreengine/definitions.h @@ -45,6 +45,13 @@ enum class eVeDisplayChannel { signalquality, scrapercontent, ecminfo, + channelhints, + channeldetail, + channellistback, + channellistdetail, + grouplistback, + groupchannellistback, + groupchannellistdetail, count }; /****************************************************************** @@ -276,6 +283,101 @@ enum class eScraperPosterBannerIT { count }; +enum class eScraperST { + movietitle = 0, + movieoriginalTitle, + movietagline, + movieoverview, + moviegenres, + moviehomepage, + moviereleasedate, + moviepopularity, + movievoteaverage, + posterpath, + fanartpath, + moviecollectionName, + collectionposterpath, + collectionfanartpath, + seriesname, + seriesoverview, + seriesfirstaired, + seriesnetwork, + seriesgenre, + seriesrating, + seriesstatus, + episodetitle, + episodefirstaired, + episodegueststars, + episodeoverview, + episoderating, + episodeimagepath, + seasonposterpath, + seriesposter1path, + seriesposter2path, + seriesposter3path, + seriesfanart1path, + seriesfanart2path, + seriesfanart3path, + seriesbanner1path, + seriesbanner2path, + seriesbanner3path, + count +}; + +enum class eScraperIT { + ismovie = 0, + moviebudget, + movierevenue, + movieadult, + movieruntime, + isseries, + posterwidth, + posterheight, + fanartwidth, + fanartheight, + movieiscollection, + collectionposterwidth, + collectionposterheight, + collectionfanartwidth, + collectionfanartheight, + epgpicavailable, + episodenumber, + episodeseason, + episodeimagewidth, + episodeimageheight, + seasonposterwidth, + seasonposterheight, + seriesposter1width, + seriesposter1height, + seriesposter2width, + seriesposter2height, + seriesposter3width, + seriesposter3height, + seriesfanart1width, + seriesfanart1height, + seriesfanart2width, + seriesfanart2height, + seriesfanart3width, + seriesfanart3height, + seriesbanner1width, + seriesbanner1height, + seriesbanner2width, + seriesbanner2height, + seriesbanner3width, + seriesbanner3height, + count +}; + +enum class eScraperLT { + //actors + name = 0, + role, + thumb, + thumbwidth, + thumbheight, + count +}; + /****************************************************************** * Tokens displaychannel viewelements *******************************************************************/ @@ -417,6 +519,46 @@ enum class eDCSignalQualityIT { count }; +enum class eDCChannelHintsIT { + numhints = 0, + count +}; + +enum class eDCChannelHintsLT { + channelnumber = 0, + channelname, + channelid, + channellogoexists, + count +}; + +enum class eDCChannelDetailST { + channelname = (int)eScraperST::count, + currenttitle, + currentshorttext, + currentdescription, + currentstart, + currentstop, + currentdurationminutes, + nexttitle, + nextshorttext, + nextdescription, + nextstart, + nextstop, + nextdurationminutes, + count +}; + +enum class eDCChannelDetailIT { + channelnumber = (int)eScraperIT::count, + currentduration, + currentdurationhours, + currentelapsed, + currentremaining, + nextduration, + nextdurationhours, + count +}; /****************************************************************** * Tokens displaymenu viewelements *******************************************************************/ @@ -601,7 +743,7 @@ enum class eDMTemperaturesIT { }; /****************************************************************** -* Tokens displaymenu listelements +* Tokens listelements *******************************************************************/ enum class eLeMenuDefaultST { column1 = 0, @@ -1057,6 +1199,39 @@ enum class eCeMenuRecordingsIT { count }; +enum class eLeChannelListST { + name = 0, + channelid, + presenteventtitle, + presenteventstart, + presenteventstop, + nexteventtitle, + nexteventstart, + nexteventstop, + count +}; + +enum class eLeChannelListIT { + nummenuitem = 0, + current, + number, + channellogoexists, + presenteventelapsed, + presenteventremaining, + count +}; + +enum class eLeGroupListST { + groupname = 0, + count +}; + +enum class eLeGroupListIT { + nummenuitem = 0, + current, + numchannels, + count +}; /****************************************************************** * Tokens displaymenu detailed views *******************************************************************/ @@ -1151,101 +1326,6 @@ enum class eDmTabsLT { count }; -enum class eScraperST { - movietitle = 0, - movieoriginalTitle, - movietagline, - movieoverview, - moviegenres, - moviehomepage, - moviereleasedate, - moviepopularity, - movievoteaverage, - posterpath, - fanartpath, - moviecollectionName, - collectionposterpath, - collectionfanartpath, - seriesname, - seriesoverview, - seriesfirstaired, - seriesnetwork, - seriesgenre, - seriesrating, - seriesstatus, - episodetitle, - episodefirstaired, - episodegueststars, - episodeoverview, - episoderating, - episodeimagepath, - seasonposterpath, - seriesposter1path, - seriesposter2path, - seriesposter3path, - seriesfanart1path, - seriesfanart2path, - seriesfanart3path, - seriesbanner1path, - seriesbanner2path, - seriesbanner3path, - count -}; - -enum class eScraperIT { - ismovie = 0, - moviebudget, - movierevenue, - movieadult, - movieruntime, - isseries, - posterwidth, - posterheight, - fanartwidth, - fanartheight, - movieiscollection, - collectionposterwidth, - collectionposterheight, - collectionfanartwidth, - collectionfanartheight, - epgpicavailable, - episodenumber, - episodeseason, - episodeimagewidth, - episodeimageheight, - seasonposterwidth, - seasonposterheight, - seriesposter1width, - seriesposter1height, - seriesposter2width, - seriesposter2height, - seriesposter3width, - seriesposter3height, - seriesfanart1width, - seriesfanart1height, - seriesfanart2width, - seriesfanart2height, - seriesfanart3width, - seriesfanart3height, - seriesbanner1width, - seriesbanner1height, - seriesbanner2width, - seriesbanner2height, - seriesbanner3width, - seriesbanner3height, - count -}; - -enum class eScraperLT { - //actors - name = 0, - role, - thumb, - thumbwidth, - thumbheight, - count -}; - enum class eDmDetailedEpgST { title = (int)eScraperST::count, shorttext, @@ -1567,6 +1647,7 @@ enum class eViewElementAttribs { mode, orientation, name, + clearondisplay, count }; @@ -1576,6 +1657,12 @@ enum class eViewListAttribs { determinatefont, numlistelements, orientation, + fadetime, + shifttime, + shifttype, + shiftmode, + startx, + starty, condition, count }; diff --git a/coreengine/listelements.c b/coreengine/listelements.c index e5dfd93..8f7c2ee 100644 --- a/coreengine/listelements.c +++ b/coreengine/listelements.c @@ -2021,3 +2021,130 @@ bool cLeAudioTracks::Parse(bool forced) { tokenContainer->AddStringToken((int)eLeDisplayTracksST::title, text); return true; } + +/****************************************************************** +* cLeChannelList +******************************************************************/ +cLeChannelList::cLeChannelList(void) { + channel = NULL; +} + +cLeChannelList::cLeChannelList(const cLeChannelList &other) : cListElement(other) { + channel = NULL; +} + +cLeChannelList::~cLeChannelList(void) { +} + +void cLeChannelList::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{name}", (int)eLeChannelListST::name); + tokenContainer->DefineStringToken("{channelid}", (int)eLeChannelListST::channelid); + tokenContainer->DefineStringToken("{presenteventtitle}", (int)eLeChannelListST::presenteventtitle); + tokenContainer->DefineStringToken("{presenteventstart}", (int)eLeChannelListST::presenteventstart); + tokenContainer->DefineStringToken("{presenteventstop}", (int)eLeChannelListST::presenteventstop); + tokenContainer->DefineStringToken("{nexteventtitle}", (int)eLeChannelListST::nexteventtitle); + tokenContainer->DefineStringToken("{nexteventstart}", (int)eLeChannelListST::nexteventstart); + tokenContainer->DefineStringToken("{nexteventstop}", (int)eLeChannelListST::nexteventstop); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeChannelListIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeChannelListIT::current); + tokenContainer->DefineIntToken("{number}", (int)eLeChannelListIT::number); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eLeChannelListIT::channellogoexists); + tokenContainer->DefineIntToken("{presenteventelapsed}", (int)eLeChannelListIT::presenteventelapsed); + tokenContainer->DefineIntToken("{presenteventremaining}", (int)eLeChannelListIT::presenteventremaining); + InheritTokenContainer(); +} + +void cLeChannelList::Set(const cChannel *channel) { + dirty = true; + this->channel = channel; +} + +bool cLeChannelList::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeChannelListIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeChannelListIT::current, current); + tokenContainer->AddIntToken((int)eLeChannelListIT::number, channel->Number()); + tokenContainer->AddStringToken((int)eLeChannelListST::name, channel->Name()); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddStringToken((int)eLeChannelListST::channelid, *channelID); + tokenContainer->AddIntToken((int)eLeChannelListIT::channellogoexists, imgCache->LogoExists(*channelID)); + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else + cSchedulesLock schedulesLock; + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + const cSchedule *schedule = schedules->GetSchedule(channel); + if (schedule) { + const cEvent *presentEvent = schedule->GetPresentEvent(); + if (presentEvent) { + tokenContainer->AddStringToken((int)eLeChannelListST::presenteventtitle, presentEvent->Title()); + tokenContainer->AddStringToken((int)eLeChannelListST::presenteventstart, *presentEvent->GetTimeString()); + tokenContainer->AddStringToken((int)eLeChannelListST::presenteventstop, *presentEvent->GetEndTimeString()); + tokenContainer->AddIntToken((int)eLeChannelListIT::presenteventelapsed, (time(0) - presentEvent->StartTime())/60); + tokenContainer->AddIntToken((int)eLeChannelListIT::presenteventremaining, presentEvent->Duration()/60 - (time(0) - presentEvent->StartTime())/60); + } + const cList<cEvent> *events = schedule->Events(); + if (events && presentEvent) { + const cEvent *nextEvent = events->Next(presentEvent); + if (nextEvent) { + tokenContainer->AddStringToken((int)eLeChannelListST::nexteventtitle, nextEvent->Title()); + tokenContainer->AddStringToken((int)eLeChannelListST::nexteventstart, *nextEvent->GetTimeString()); + tokenContainer->AddStringToken((int)eLeChannelListST::nexteventstop, *nextEvent->GetEndTimeString()); + } + } + } + + return true; +} + +/****************************************************************** +* cLeGroupList +******************************************************************/ +cLeGroupList::cLeGroupList(void) { + group = NULL; + numChannels = 0; +} + +cLeGroupList::cLeGroupList(const cLeGroupList &other) : cListElement(other) { + group = NULL; + numChannels = 0; +} + +cLeGroupList::~cLeGroupList(void) { +} + +void cLeGroupList::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{groupname}", (int)eLeGroupListST::groupname); + tokenContainer->DefineIntToken("{numchannels}", (int)eLeGroupListIT::numchannels); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeGroupListIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeGroupListIT::current); + InheritTokenContainer(); +} + +void cLeGroupList::Set(const char *group, int numChannels) { + dirty = true; + this->group = group; + this->numChannels = numChannels; +} + +bool cLeGroupList::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeGroupListIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeGroupListIT::current, current); + tokenContainer->AddIntToken((int)eLeGroupListIT::numchannels, numChannels); + tokenContainer->AddStringToken((int)eLeGroupListST::groupname, group); + return true; +} diff --git a/coreengine/listelements.h b/coreengine/listelements.h index 8f2b5b2..a63fa4d 100644 --- a/coreengine/listelements.h +++ b/coreengine/listelements.h @@ -339,4 +339,35 @@ public: bool Parse(bool forced = true); }; +/****************************************************************** +* cLeChannelList +******************************************************************/ +class cLeChannelList : public cListElement { +private: + const cChannel *channel; +public: + cLeChannelList(void); + cLeChannelList(const cLeChannelList &other); + virtual ~cLeChannelList(void); + void SetTokenContainer(void); + void Set(const cChannel *channel); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cLeGroupList +******************************************************************/ +class cLeGroupList : public cListElement { +private: + const char *group; + int numChannels; +public: + cLeGroupList(void); + cLeGroupList(const cLeGroupList &other); + virtual ~cLeGroupList(void); + void SetTokenContainer(void); + void Set(const char *group, int numChannels); + bool Parse(bool forced = true); +}; + #endif //__LISTELEMENTS_H
\ No newline at end of file diff --git a/coreengine/view.c b/coreengine/view.c index ae7cee5..f9db80d 100644 --- a/coreengine/view.c +++ b/coreengine/view.c @@ -141,6 +141,12 @@ bool cView::ValidViewElement(const char *viewElement) { bool cView::ValidViewList(const char *viewList) { if (!strcmp(viewList, "menuitems")) return true; + else if (!strcmp(viewList, "channellist")) + return true; + else if (!strcmp(viewList, "grouplist")) + return true; + else if (!strcmp(viewList, "groupchannellist")) + return true; return false; } @@ -162,6 +168,8 @@ void cView::PreCache(void) { continue; viewElements[i]->SetContainer(contX, contY, attribs->Width(), attribs->Height()); viewElements[i]->Cache(); + if (const char *clearOnDisplay = viewElements[i]->ClearOnDisplay()) + SetClearOnDisplay(i, clearOnDisplay); } if (viewElementsHorizontal) { for (int i=0; i < numViewElements; i++) { @@ -209,6 +217,13 @@ void cView::Clear(int ve, bool forceClearBackground) { viewElements[ve]->Clear(forceClearBackground); } +void cView::SetDirty(int ve) { + if (!viewElements[ve]) + return; + viewElements[ve]->SetDirty(); + viewElements[ve]->SetRestartAnimation(); +} + void cView::Render(int ve, bool force) { if (!viewElements[ve]) return; @@ -216,6 +231,18 @@ void cView::Render(int ve, bool force) { viewElements[ve]->Render(); } +void cView::Hide(int ve) { + if (!viewElements[ve]) + return; + viewElements[ve]->Hide(); +} + +void cView::Show(int ve) { + if (!viewElements[ve]) + return; + viewElements[ve]->Show(); +} + void cView::Close(void) { delete fader; fader = NULL; @@ -435,3 +462,20 @@ void cView::DoScaleTv(const cRect *frame) { } } } + +void cView::SetClearOnDisplay(int ve, const char *clearOnDisplay) { + if (!strcmp(clearOnDisplay, "all")) { + viewElements[ve]->SetClearAll(); + return; + } + vector<int> clearVEs; + for (map<string,int>::iterator it = viewElementNames.begin(); it != viewElementNames.end(); it++) { + string name = it->first; + int id = it->second; + if (strstr(clearOnDisplay, name.c_str())) { + clearVEs.push_back(id); + } + } + viewElements[ve]->SetClearOnDisplay(clearVEs); +} + diff --git a/coreengine/view.h b/coreengine/view.h index efdd351..a27ed7a 100644 --- a/coreengine/view.h +++ b/coreengine/view.h @@ -26,6 +26,7 @@ using namespace std; class cView : public cFadable, public cShiftable { private: void DoScaleTv(const cRect *frame); + void SetClearOnDisplay(int ve, const char *clearOnDisplay); protected: cSdOsd sdOsd; cViewAttribs *attribs; @@ -76,13 +77,16 @@ public: //View API virtual bool Init(void); void Clear(int ve, bool forceClearBackground = false); + void SetDirty(int ve); void Render(int ve, bool force = false); + void Hide(int ve); + void Show(int ve); virtual void Close(void); virtual void Flush(bool animFlush); virtual void Debug(void); + //Fadable bool Detached(void) { return false; }; int Delay(void) { return 0; }; - //Fadable int FadeTime(void); virtual void SetTransparency(int transparency, bool force = false); //Shiftable diff --git a/coreengine/viewdisplaychannel.c b/coreengine/viewdisplaychannel.c index f8e163a..7ab36ce 100644 --- a/coreengine/viewdisplaychannel.c +++ b/coreengine/viewdisplaychannel.c @@ -24,9 +24,66 @@ cViewChannel::cViewChannel(void) { veStatusInfo = NULL; veScraperContent = NULL; veEcmInfo = NULL; +#ifdef USE_ZAPCOCKPIT + veChannelHints = NULL; + veChannelDetail = NULL; + veChannelListDetail = NULL; + veGroupChannelListDetail = NULL; + channelList = NULL; + groupList = NULL; + groupChannelList = NULL; +#endif } cViewChannel::~cViewChannel() { +#ifdef USE_ZAPCOCKPIT + delete channelList; + delete groupList; + delete groupChannelList; +#endif +} + +void cViewChannel::SetGlobals(cGlobals *globals) { + cView::SetGlobals(globals); +#ifdef USE_ZAPCOCKPIT + if (channelList) + channelList->SetGlobals(globals); + if (groupList) + groupList->SetGlobals(globals); + if (groupChannelList) + groupChannelList->SetGlobals(globals); +#endif +} + +void cViewChannel::PreCache(void) { + cView::PreCache(); +#ifdef USE_ZAPCOCKPIT + if (channelList) { + channelList->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + channelList->PreCache(); + } + if (groupList) { + groupList->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + groupList->PreCache(); + } + if (groupChannelList) { + groupChannelList->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + groupChannelList->PreCache(); + } +#endif +} + +void cViewChannel::AddChannelViewList(const char *listName, cViewList *viewList) { +#ifdef USE_ZAPCOCKPIT + if (!strcmp(listName, "channellist")) + channelList = dynamic_cast<cViewListChannelList*>(viewList); + else if (!strcmp(listName, "grouplist")) + groupList = dynamic_cast<cViewListGroupList*>(viewList); + else if (!strcmp(listName, "groupchannellist")) + groupChannelList = dynamic_cast<cViewListChannelList*>(viewList); + else + esyslog("skindesigner: invalid view list %s in displaychannel", listName); +#endif } void cViewChannel::SetViewElements(void) { @@ -43,6 +100,13 @@ void cViewChannel::SetViewElements(void) { viewElementNames.insert(pair<string, int>("devices", (int)eVeDisplayChannel::devices)); viewElementNames.insert(pair<string, int>("currentweather", (int)eVeDisplayChannel::currentweather)); viewElementNames.insert(pair<string, int>("scrapercontent", (int)eVeDisplayChannel::scrapercontent)); + viewElementNames.insert(pair<string, int>("channelhints", (int)eVeDisplayChannel::channelhints)); + viewElementNames.insert(pair<string, int>("channeldetail", (int)eVeDisplayChannel::channeldetail)); + viewElementNames.insert(pair<string, int>("channellistback", (int)eVeDisplayChannel::channellistback)); + viewElementNames.insert(pair<string, int>("channellistdetail", (int)eVeDisplayChannel::channellistdetail)); + viewElementNames.insert(pair<string, int>("grouplistback", (int)eVeDisplayChannel::grouplistback)); + viewElementNames.insert(pair<string, int>("groupchannellistback", (int)eVeDisplayChannel::groupchannellistback)); + viewElementNames.insert(pair<string, int>("groupchannellistdetail", (int)eVeDisplayChannel::groupchannellistdetail)); viewElementNames.insert(pair<string, int>("datetime", (int)eVeDisplayChannel::datetime)); viewElementNames.insert(pair<string, int>("time", (int)eVeDisplayChannel::time)); viewElementNames.insert(pair<string, int>("message", (int)eVeDisplayChannel::message)); @@ -83,6 +147,24 @@ void cViewChannel::SetViewElementObjects(void) { { veScraperContent = dynamic_cast<cVeDcScraperContent*>(viewElements[i]); } +#ifdef USE_ZAPCOCKPIT + else if (dynamic_cast<cVeDcChannelListDetail*>(viewElements[i])) + { + veChannelListDetail = dynamic_cast<cVeDcChannelListDetail*>(viewElements[i]); + } + else if (dynamic_cast<cVeDcGroupChannelListDetail*>(viewElements[i])) + { + veGroupChannelListDetail = dynamic_cast<cVeDcGroupChannelListDetail*>(viewElements[i]); + } + else if (dynamic_cast<cVeDcChannelHints*>(viewElements[i])) + { + veChannelHints = dynamic_cast<cVeDcChannelHints*>(viewElements[i]); + } + else if (dynamic_cast<cVeDcChannelDetail*>(viewElements[i])) + { + veChannelDetail = dynamic_cast<cVeDcChannelDetail*>(viewElements[i]); + } +#endif else if (dynamic_cast<cVeDcEcmInfo*>(viewElements[i])) { veEcmInfo = dynamic_cast<cVeDcEcmInfo*>(viewElements[i]); @@ -100,8 +182,16 @@ void cViewChannel::SetViewElementObjects(void) { void cViewChannel::ClearVariables(void) { cView::ClearVariables(); +#ifdef USE_ZAPCOCKPIT + viewType = dcDefault; + viewTypeLast = dcDefault; + initExtended = true; + displayList = false; + initList = false; + channelInput = false; +#endif channelChange = false; - displayChannelGroups = false; + mode = dmDefault; if (veCustomTokens) veCustomTokens->Reset(); timersLoaded = false; @@ -114,8 +204,23 @@ void cViewChannel::SetChannel(const cChannel *channel, int number) { globalTimers.LoadTimers(); } channelChange = true; - bool wasChannelGroups = displayChannelGroups; - displayChannelGroups = false; + + //check if channelgroups have to be cleared + bool clearChannelGroups = (mode == dmChannelGroups) ? true : false; + mode = dmDefault; + +#ifdef USE_ZAPCOCKPIT + //check if channel hints have to be cleared + if (number) { + channelInput = true; + } else if (channelInput) { + channelInput = false; + if (veChannelHints) + veChannelHints->Close(); + } + if (veChannelDetail) + veChannelDetail->Clear(true); +#endif if (veChannelInfo) { veChannelInfo->Clear(); @@ -124,24 +229,15 @@ void cViewChannel::SetChannel(const cChannel *channel, int number) { if (channel) { if (!channel->GroupSep()) { - if (wasChannelGroups) + if (clearChannelGroups) Clear((int)eVeDisplayChannel::channelgroup); if (veStatusInfo) veStatusInfo->Set(channel); if (veEcmInfo) veEcmInfo->Set(channel); } else { - displayChannelGroups = true; - Clear((int)eVeDisplayChannel::channelinfo, true); - Clear((int)eVeDisplayChannel::epginfo, true); - Clear((int)eVeDisplayChannel::statusinfo, true); - Clear((int)eVeDisplayChannel::progressbar, true); - Clear((int)eVeDisplayChannel::screenresolution, true); - Clear((int)eVeDisplayChannel::signalquality, true); - Clear((int)eVeDisplayChannel::audioinfo, true); - Clear((int)eVeDisplayChannel::ecminfo, true); - Clear((int)eVeDisplayChannel::devices, true); - Clear((int)eVeDisplayChannel::customtokens, true); + mode = dmChannelGroups; + ClearBasic(false); if (veChannelGroup) veChannelGroup->Set(channel); } @@ -178,31 +274,310 @@ void cViewChannel::SetMessage(eMessageType type, const char *text) { } } +#ifdef USE_ZAPCOCKPIT + +void cViewChannel::SetViewType(eDisplaychannelView viewType) { + viewTypeLast = this->viewType; + this->viewType = viewType; +} + +int cViewChannel::MaxItems(void) { + initList = true; + if (viewType == dcChannelList && channelList) + return channelList->NumItems(); + else if (viewType == dcGroupsList && groupList) + return groupList->NumItems(); + else if (viewType == dcGroupsChannelList && groupChannelList) + return groupChannelList->NumItems(); + return 0; +} + +void cViewChannel::SetChannelInfo(const cChannel *channel) { + if (!channel) + return; + if (viewType == dcChannelInfo && veChannelDetail) { + ClearOnDisplay(); + veChannelDetail->Set(channel); + Render((int)eVeDisplayChannel::channeldetail); + } else if (viewType == dcChannelListInfo && veChannelListDetail) { + veChannelListDetail->Set(channel); + Render((int)eVeDisplayChannel::channellistdetail); + } else if (viewType == dcGroupsChannelListInfo && veGroupChannelListDetail) { + veGroupChannelListDetail->Set(channel); + Render((int)eVeDisplayChannel::groupchannellistdetail); + } +} + +void cViewChannel::SetChannelList(const cChannel *channel, int index, bool current) { + displayList = true; + if (viewType == dcChannelList && channelList) { + channelList->Set(channel, index, current); + } else if (viewType == dcGroupsChannelList && groupChannelList) { + groupChannelList->Set(channel, index, current); + } +} + +void cViewChannel::SetGroupList(const char *group, int numChannels, int index, bool current) { + displayList = true; + if (groupList) { + groupList->Set(group, numChannels, index, current); + } +} + +void cViewChannel::ClearList(void) { + if (viewType == dcChannelList && channelList) + channelList->Clear(); + if (viewType == dcGroupsList && groupList) + groupList->Clear(); +} + +void cViewChannel::SetNumChannelHints(int num) { + if (veChannelHints) + veChannelHints->SetNumHints(num); + channelHints = true; +} + +void cViewChannel::SetChannelHint(const cChannel *channel) { + if (veChannelHints) + veChannelHints->SetHint(channel); +} + +#endif //USE_ZAPCOCKPIT + +void cViewChannel::Close(void) { + delete fader; + fader = NULL; + delete shifter; + shifter = NULL; + if (initFinished && ShiftTime() > 0) { + cRect shiftbox = CoveredArea(); + cPoint ref = cPoint(shiftbox.X(), shiftbox.Y()); + cPoint end = ShiftStart(shiftbox); + shifter = new cAnimation((cShiftable*)this, end, ref, false); + shifter->Shift(); + delete shifter; + shifter = NULL; + } else if (initFinished && FadeTime() > 0) { + fader = new cAnimation((cFadable*)this, false); + fader->Fade(); + delete fader; + fader = NULL; + } + UnScaleTv(); + ClearVariables(); + for (int i=0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + viewElements[i]->Close(); + } +#ifdef USE_ZAPCOCKPIT + if (channelList) + channelList->Close(); + if (groupList) + groupList->Close(); + if (groupChannelList) + groupChannelList->Close(); +#endif + sdOsd.Flush(); + sdOsd.DeleteOsd(); +} + +void cViewChannel::ClearBasic(bool clearBackground) { + if (clearBackground) { + Clear((int)eVeDisplayChannel::background, true); + Clear((int)eVeDisplayChannel::currentweather, true); + } + Clear((int)eVeDisplayChannel::channelinfo, true); + Clear((int)eVeDisplayChannel::epginfo, true); + Clear((int)eVeDisplayChannel::statusinfo, true); + Clear((int)eVeDisplayChannel::scrapercontent, true); + Clear((int)eVeDisplayChannel::progressbar, true); + Clear((int)eVeDisplayChannel::screenresolution, true); + Clear((int)eVeDisplayChannel::signalquality, true); + Clear((int)eVeDisplayChannel::audioinfo, true); + Clear((int)eVeDisplayChannel::ecminfo, true); + Clear((int)eVeDisplayChannel::devices, true); + Clear((int)eVeDisplayChannel::customtokens, true); +} + +void cViewChannel::ClearExtended(void) { +#ifdef USE_ZAPCOCKPIT + //exit from channel list + if ((viewTypeLast == dcChannelList || viewTypeLast == dcChannelListInfo) && viewType == dcDefault && channelList) { + channelList->Clear(); + Clear((int)eVeDisplayChannel::channellistback); + Clear((int)eVeDisplayChannel::channellistdetail); + SetDirty((int)eVeDisplayChannel::channellistback); + initExtended = true; + ShowBasic(); + } + //exit from channellist info to channel list + if (viewTypeLast == dcChannelListInfo && viewType == dcChannelList) { + Clear((int)eVeDisplayChannel::channellistdetail); + SetDirty((int)eVeDisplayChannel::channellistdetail); + } + //exit from group list + if (viewTypeLast == dcGroupsList && viewType == dcDefault && groupList) { + groupList->Clear(); + Clear((int)eVeDisplayChannel::grouplistback); + SetDirty((int)eVeDisplayChannel::grouplistback); + initExtended = true; + ShowBasic(); + } + //exit from group channel list to group list + if (viewTypeLast == dcGroupsChannelList && viewType == dcGroupsList && groupChannelList) { + groupChannelList->Clear(); + Clear((int)eVeDisplayChannel::groupchannellistback); + SetDirty((int)eVeDisplayChannel::groupchannellistback); + } + //exit from groupchannellist info to groupchannel list + if (viewTypeLast == dcGroupsChannelListInfo && viewType == dcGroupsChannelList) { + Clear((int)eVeDisplayChannel::groupchannellistdetail); + SetDirty((int)eVeDisplayChannel::groupchannellistdetail); + } + //exit from channel list + if ((viewTypeLast == dcGroupsChannelList || viewTypeLast == dcGroupsChannelListInfo) && viewType == dcDefault && groupList && groupChannelList) { + groupList->Clear(); + groupChannelList->Clear(); + Clear((int)eVeDisplayChannel::grouplistback); + Clear((int)eVeDisplayChannel::groupchannellistback); + Clear((int)eVeDisplayChannel::groupchannellistdetail); + SetDirty((int)eVeDisplayChannel::groupchannellistback); + SetDirty((int)eVeDisplayChannel::grouplistback); + SetDirty((int)eVeDisplayChannel::groupchannellistdetail); + initExtended = true; + ShowBasic(); + } + //exit from channel info to channel or group list + if (viewTypeLast == dcChannelInfo && (viewType == dcChannelList || viewType == dcGroupsList)) { + Clear((int)eVeDisplayChannel::channeldetail, true); + } + viewTypeLast = dcDefault; +#endif +} + +void cViewChannel::ClearOnDisplay(void) { +#ifdef USE_ZAPCOCKPIT + if (viewType == dcChannelInfo && veChannelDetail) { + vector<int> clear = veChannelDetail->GetClearOnDisplay(); + for (vector<int>::iterator ve = clear.begin(); ve != clear.end(); ve++) { + Hide(*ve); + } + } else { + cViewElement *listBack = NULL; + if (viewType == dcChannelList) + listBack = viewElements[(int)eVeDisplayChannel::channellistback]; + else if (viewType == dcGroupsList) + listBack = viewElements[(int)eVeDisplayChannel::grouplistback]; + if (!listBack) + return; + if (listBack->DoClearAll()) { + HideBasic(); + return; + } + vector<int> clear = listBack->GetClearOnDisplay(); + for (vector<int>::iterator ve = clear.begin(); ve != clear.end(); ve++) { + Hide(*ve); + } + } +#endif +} + +void cViewChannel::DrawBasic(bool initial) { + if (initial) { + Render((int)eVeDisplayChannel::background); + Render((int)eVeDisplayChannel::currentweather); + } + Render((int)eVeDisplayChannel::channelinfo); + Render((int)eVeDisplayChannel::epginfo); + Render((int)eVeDisplayChannel::statusinfo); + Render((int)eVeDisplayChannel::scrapercontent); + Render((int)eVeDisplayChannel::progressbar, channelChange); + Render((int)eVeDisplayChannel::screenresolution); + Render((int)eVeDisplayChannel::signalquality); + Render((int)eVeDisplayChannel::audioinfo); + Render((int)eVeDisplayChannel::ecminfo); + Render((int)eVeDisplayChannel::devices); + Render((int)eVeDisplayChannel::customtokens); + Render((int)eVeDisplayChannel::message); + +#ifdef USE_ZAPCOCKPIT + if (channelHints) { + channelHints = false; + if (veChannelHints) { + if (veChannelHints->Active()) + veChannelHints->Close(); + veChannelHints->Parse(); + veChannelHints->Render(); + } + } +#endif +} + +void cViewChannel::HideBasic(void) { + for (int ve = (int)eVeDisplayChannel::background; ve <= (int)eVeDisplayChannel::ecminfo; ve++) { + Hide(ve); + } +} + +void cViewChannel::ShowBasic(void) { + for (int ve = (int)eVeDisplayChannel::background; ve <= (int)eVeDisplayChannel::ecminfo; ve++) { + Show(ve); + } +} + +void cViewChannel::DrawExtended(void) { +#ifdef USE_ZAPCOCKPIT + if (!displayList) + return; + if (initExtended) { + ClearOnDisplay(); + initExtended = false; + } + if (!init && initList) + sdOsd.LockFlush(); + if (viewType == dcChannelList && channelList) { + Render((int)eVeDisplayChannel::channellistback); + channelList->Draw(mcUndefined); + if (initList) + channelList->StartAnimation(); + } else if (viewType == dcGroupsList && groupList) { + Render((int)eVeDisplayChannel::grouplistback); + groupList->Draw(mcUndefined); + if (initList) + groupList->StartAnimation(); + } else if (viewType == dcGroupsChannelList && groupChannelList) { + Render((int)eVeDisplayChannel::groupchannellistback); + groupChannelList->Draw(mcUndefined); + if (initList) + groupChannelList->StartAnimation(); + } + if (!init && initList) + sdOsd.UnlockFlush(); + displayList = false; + initList = false; +#endif +} + void cViewChannel::Flush(bool animFlush) { if (init) { sdOsd.LockFlush(); - Render((int)eVeDisplayChannel::background); - Render((int)eVeDisplayChannel::currentweather); } - if (!displayChannelGroups) { - //normal display +#ifdef USE_ZAPCOCKPIT + ClearExtended(); +#endif + + //Basic Display Handling + if (mode == dmDefault) { if (!shifting) { - Render((int)eVeDisplayChannel::channelinfo); - Render((int)eVeDisplayChannel::epginfo); - Render((int)eVeDisplayChannel::statusinfo); - Render((int)eVeDisplayChannel::scrapercontent); - Render((int)eVeDisplayChannel::progressbar, channelChange); - Render((int)eVeDisplayChannel::screenresolution); - Render((int)eVeDisplayChannel::signalquality); - Render((int)eVeDisplayChannel::audioinfo); - Render((int)eVeDisplayChannel::ecminfo); - Render((int)eVeDisplayChannel::devices); - Render((int)eVeDisplayChannel::customtokens); - Render((int)eVeDisplayChannel::message); + DrawBasic(init); + } + } else if (mode == dmChannelGroups) { + if (init) { + Render((int)eVeDisplayChannel::background); + Render((int)eVeDisplayChannel::currentweather); } - } else { - //channelgroup display Render((int)eVeDisplayChannel::channelgroup); } if (!shifting) { @@ -210,6 +585,10 @@ void cViewChannel::Flush(bool animFlush) { Render((int)eVeDisplayChannel::time); } channelChange = false; + +#ifdef USE_ZAPCOCKPIT + DrawExtended(); +#endif + cView::Flush(animFlush); } - diff --git a/coreengine/viewdisplaychannel.h b/coreengine/viewdisplaychannel.h index 623ec14..aa7c278 100644 --- a/coreengine/viewdisplaychannel.h +++ b/coreengine/viewdisplaychannel.h @@ -4,30 +4,72 @@ #include "view.h" #include "../extensions/globaltimers.h" +enum eDisplayMode { + dmDefault, + dmChannelGroups +}; + class cViewChannel : public cView { private: - cVeMessage *veMessage; - cVeCustomTokens *veCustomTokens; - cVeDcChannelInfo *veChannelInfo; - cVeDcChannelGroup *veChannelGroup; - cVeDcEpgInfo *veEpgInfo; - cVeDcProgressBar *veProgressBar; - cVeDcStatusInfo *veStatusInfo; - cVeDcScraperContent *veScraperContent; - cVeDcEcmInfo *veEcmInfo; + cVeMessage *veMessage; + cVeCustomTokens *veCustomTokens; + cVeDcChannelInfo *veChannelInfo; + cVeDcChannelGroup *veChannelGroup; + cVeDcEpgInfo *veEpgInfo; + cVeDcProgressBar *veProgressBar; + cVeDcStatusInfo *veStatusInfo; + cVeDcScraperContent *veScraperContent; + cVeDcEcmInfo *veEcmInfo; +#ifdef USE_ZAPCOCKPIT + cVeDcChannelHints *veChannelHints; + cVeDcChannelDetail *veChannelDetail; + cVeDcChannelListDetail *veChannelListDetail; + cVeDcGroupChannelListDetail *veGroupChannelListDetail; + cViewListChannelList *channelList; + cViewListGroupList *groupList; + cViewListChannelList *groupChannelList; + eDisplaychannelView viewType; + eDisplaychannelView viewTypeLast; + bool initExtended; + bool displayList; + bool initList; + bool channelHints; + bool channelInput; +#endif bool channelChange; - bool displayChannelGroups; + eDisplayMode mode; bool timersLoaded; cGlobalTimers globalTimers; void SetViewElements(void); void ClearVariables(void); void SetViewElementObjects(void); + void ClearBasic(bool clearBackground); + void ClearExtended(void); + void ClearOnDisplay(void); + void DrawBasic(bool initial); + void HideBasic(void); + void ShowBasic(void); + void DrawExtended(void); public: cViewChannel(void); virtual ~cViewChannel(void); + void SetGlobals(cGlobals *globals); + void PreCache(void); + void AddChannelViewList(const char *listName, cViewList *viewList); void SetChannel(const cChannel *channel, int number); void SetEvents(const cEvent *present, const cEvent *following); void SetMessage(eMessageType type, const char *text); +#ifdef USE_ZAPCOCKPIT + void SetViewType(eDisplaychannelView viewType); + int MaxItems(void); + void SetChannelInfo(const cChannel *channel); + void SetChannelList(const cChannel *channel, int index, bool current); + void SetGroupList(const char *group, int numChannels, int index, bool current); + void ClearList(void); + void SetNumChannelHints(int num); + void SetChannelHint(const cChannel *channel); +#endif + void Close(void); void Flush(bool animFlush); }; diff --git a/coreengine/viewelement.c b/coreengine/viewelement.c index 06ca23e..eaa9814 100644 --- a/coreengine/viewelement.c +++ b/coreengine/viewelement.c @@ -15,9 +15,11 @@ cViewElement::cViewElement(void) { detached = false; waitOnWakeup = true; startAnimation = true; + restartAnimation = false; globals = NULL; tokenContainer = NULL; attribs = new cViewElementAttribs((int)eViewElementAttribs::count); + clearAll = false; detacher = NULL; fader = NULL; shifter = NULL; @@ -34,10 +36,12 @@ cViewElement::cViewElement(const cViewElement &other) { detached = false; waitOnWakeup = true; startAnimation = true; + restartAnimation = false; globals = other.globals; container.Set(other.container.X(), other.container.Y(), other.container.Width(), other.container.Height()); tokenContainer = NULL; attribs = new cViewElementAttribs(*other.attribs); + clearAll = false; for (const cAreaNode *node = other.areaNodes.First(); node; node = other.areaNodes.Next(node)) { if (cArea *a = dynamic_cast<cArea*>((cAreaNode*)node)) { @@ -101,6 +105,20 @@ cViewElement *cViewElement::CreateViewElement(const char *name, const char *view e = new cVeDcSignalQuality(); else if (!strcmp(name, "scrapercontent") && !strcmp(viewname, "displaychannel")) e = new cVeDcScraperContent(); + else if (!strcmp(name, "channelhints")) + e = new cVeDcChannelHints(); + else if (!strcmp(name, "channeldetail")) + e = new cVeDcChannelDetail(); + else if (!strcmp(name, "channellistback")) + e = new cViewElement(); + else if (!strcmp(name, "grouplistback")) + e = new cViewElement(); + else if (!strcmp(name, "groupchannellistback")) + e = new cViewElement(); + else if (!strcmp(name, "channellistdetail")) + e = new cVeDcChannelListDetail(); + else if (!strcmp(name, "groupchannellistdetail")) + e = new cVeDcGroupChannelListDetail(); else if (!strcmp(name, "ecminfo")) e = new cVeDcEcmInfo(); @@ -326,6 +344,7 @@ void cViewElement::Close(void) { dirty = true; init = true; startAnimation = true; + restartAnimation = false; drawn = false; scrollingStarted = false; blocked = false; @@ -378,8 +397,9 @@ void cViewElement::Render(void) { } dirty = false; drawn = true; - if (startAnimation) { + if (startAnimation || restartAnimation) { startAnimation = false; + restartAnimation = false; StartAnimation(); } } diff --git a/coreengine/viewelement.h b/coreengine/viewelement.h index 9341ddf..fb5e7dd 100644 --- a/coreengine/viewelement.h +++ b/coreengine/viewelement.h @@ -27,9 +27,12 @@ protected: bool waitOnWakeup; bool scrollingStarted; bool startAnimation; + bool restartAnimation; cGlobals *globals; cRect container; cViewElementAttribs *attribs; + vector<int> clearOnDisplay; + bool clearAll; cList<cAreaNode> areaNodes; skindesignerapi::cTokenContainer *tokenContainer; cList<cAnimation> scrollers; @@ -74,6 +77,11 @@ public: void StopScrolling(bool deletePixmaps = true); eOrientation Orientation(void) { return attribs->Orientation(); }; virtual int Delay(void) { return attribs->Delay(); }; + const char *ClearOnDisplay(void) { return attribs->ClearOnDisplay(); }; + void SetClearOnDisplay(vector<int> clearOnDisplay) { this->clearOnDisplay = clearOnDisplay; }; + vector<int> GetClearOnDisplay(void) { return clearOnDisplay; }; + void SetClearAll(void) { clearAll = true; }; + bool DoClearAll(void) { return clearAll; }; void ParseDetached(void); void RenderDetached(void); bool Shifting(void); @@ -82,6 +90,7 @@ public: int ShiftTime(void); int ShiftMode(void); void StartAnimation(void); + void SetRestartAnimation(void) { restartAnimation = true; }; virtual void SetTransparency(int transparency, bool force = false); virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false); void SetStartShifting(void) { }; diff --git a/coreengine/viewelementsdisplaychannel.c b/coreengine/viewelementsdisplaychannel.c index b4a2f89..c73807e 100644 --- a/coreengine/viewelementsdisplaychannel.c +++ b/coreengine/viewelementsdisplaychannel.c @@ -676,3 +676,261 @@ bool cVeDcEcmInfo::CompareECMInfos(sDVBAPIEcmInfo *ecmInfo) { return false; return true; } + +/****************************************************************** +* cVeDcChannelHints +******************************************************************/ +cVeDcChannelHints::cVeDcChannelHints(void) { + hints = NULL; + numHints = 0; + current = 0; + hintsIndex = -1; + active = false; +} + +cVeDcChannelHints::~cVeDcChannelHints(void) { + delete[] hints; +} + +void cVeDcChannelHints::Close(void) { + cViewElement::Close(); +} + +void cVeDcChannelHints::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{numhints}", (int)eDCChannelHintsIT::numhints); + tokenContainer->DefineLoopToken("{hints[channelnumber]}", (int)eDCChannelHintsLT::channelnumber); + tokenContainer->DefineLoopToken("{hints[channelname]}", (int)eDCChannelHintsLT::channelname); + tokenContainer->DefineLoopToken("{hints[channelid]}", (int)eDCChannelHintsLT::channelid); + tokenContainer->DefineLoopToken("{hints[channellogoexists]}", (int)eDCChannelHintsLT::channellogoexists); + hintsIndex = tokenContainer->LoopIndex("hints"); + InheritTokenContainer(); +} + +void cVeDcChannelHints::SetNumHints(int num) { + delete[] hints; + numHints = num; + hints = new const cChannel*[num]; + current = 0; + active = true; + SetDirty(); +} + + +void cVeDcChannelHints::SetHint(const cChannel *c) { + hints[current++] = c; +} + +bool cVeDcChannelHints::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!Dirty()) + return false; + if (!hints) + return false; + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDCChannelHintsIT::numhints, numHints); + + vector<int> loopInfo; + loopInfo.push_back(numHints); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + + for (int i=0; i < numHints; i++) { + if (hints[i]) { + tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channelnumber, *cString::sprintf("%d", hints[i]->Number())); + tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channelname, hints[i]->Name()); + cString channelID = hints[i]->GetChannelID().ToString(); + tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channelid, *channelID); + bool logoExists = imgCache->LogoExists(*channelID); + tokenContainer->AddLoopToken(hintsIndex, i, (int)eDCChannelHintsLT::channellogoexists, *cString::sprintf("%d", logoExists ? 1 : 0)); + } + } + return true; +} + +/****************************************************************** +* cVeDcChannelDetail +******************************************************************/ +cVeDcChannelDetail::cVeDcChannelDetail(void) { + channel = NULL; +} + +cVeDcChannelDetail::~cVeDcChannelDetail(void) { + channel = NULL; +} + +void cVeDcChannelDetail::Close(void) { + channel = NULL; + cViewElement::Close(); +} + +void cVeDcChannelDetail::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{channelname}", (int)eDCChannelDetailST::channelname); + tokenContainer->DefineStringToken("{currenttitle}", (int)eDCChannelDetailST::currenttitle); + tokenContainer->DefineStringToken("{currentshorttext}", (int)eDCChannelDetailST::currentshorttext); + tokenContainer->DefineStringToken("{currentdescription}", (int)eDCChannelDetailST::currentdescription); + tokenContainer->DefineStringToken("{currentstart}", (int)eDCChannelDetailST::currentstart); + tokenContainer->DefineStringToken("{currentstop}", (int)eDCChannelDetailST::currentstop); + tokenContainer->DefineStringToken("{currentdurationminutes}", (int)eDCChannelDetailST::currentdurationminutes); + tokenContainer->DefineStringToken("{nexttitle}", (int)eDCChannelDetailST::nexttitle); + tokenContainer->DefineStringToken("{nextshorttext}", (int)eDCChannelDetailST::nextshorttext); + tokenContainer->DefineStringToken("{nextdescription}", (int)eDCChannelDetailST::nextdescription); + tokenContainer->DefineStringToken("{nextstart}", (int)eDCChannelDetailST::nextstart); + tokenContainer->DefineStringToken("{nextstop}", (int)eDCChannelDetailST::nextstop); + tokenContainer->DefineStringToken("{nextdurationminutes}", (int)eDCChannelDetailST::nextdurationminutes); + tokenContainer->DefineIntToken("{channelnumber}", (int)eDCChannelDetailIT::channelnumber); + tokenContainer->DefineIntToken("{currentduration}", (int)eDCChannelDetailIT::currentduration); + tokenContainer->DefineIntToken("{currentdurationhours}", (int)eDCChannelDetailIT::currentdurationhours); + tokenContainer->DefineIntToken("{currentelapsed}", (int)eDCChannelDetailIT::currentelapsed); + tokenContainer->DefineIntToken("{currentremaining}", (int)eDCChannelDetailIT::currentremaining); + tokenContainer->DefineIntToken("{nextduration}", (int)eDCChannelDetailIT::nextduration); + tokenContainer->DefineIntToken("{nextdurationhours}", (int)eDCChannelDetailIT::nextdurationhours); + tokenContainer->DefineStringToken("{movietitle}", (int)eScraperST::movietitle); + tokenContainer->DefineStringToken("{movieoriginalTitle}", (int)eScraperST::movieoriginalTitle); + tokenContainer->DefineStringToken("{movietagline}", (int)eScraperST::movietagline); + tokenContainer->DefineStringToken("{movieoverview}", (int)eScraperST::movieoverview); + tokenContainer->DefineStringToken("{moviegenres}", (int)eScraperST::moviegenres); + tokenContainer->DefineStringToken("{moviehomepage}", (int)eScraperST::moviehomepage); + tokenContainer->DefineStringToken("{moviereleasedate}", (int)eScraperST::moviereleasedate); + tokenContainer->DefineStringToken("{moviepopularity}", (int)eScraperST::moviepopularity); + tokenContainer->DefineStringToken("{movievoteaverage}", (int)eScraperST::movievoteaverage); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperST::posterpath); + tokenContainer->DefineStringToken("{fanartpath}", (int)eScraperST::fanartpath); + tokenContainer->DefineStringToken("{moviecollectionName}", (int)eScraperST::moviecollectionName); + tokenContainer->DefineStringToken("{collectionposterpath}", (int)eScraperST::collectionposterpath); + tokenContainer->DefineStringToken("{collectionfanartpath}", (int)eScraperST::collectionfanartpath); + tokenContainer->DefineStringToken("{seriesname}", (int)eScraperST::seriesname); + tokenContainer->DefineStringToken("{seriesoverview}", (int)eScraperST::seriesoverview); + tokenContainer->DefineStringToken("{seriesfirstaired}", (int)eScraperST::seriesfirstaired); + tokenContainer->DefineStringToken("{seriesnetwork}", (int)eScraperST::seriesnetwork); + tokenContainer->DefineStringToken("{seriesgenre}", (int)eScraperST::seriesgenre); + tokenContainer->DefineStringToken("{seriesrating}", (int)eScraperST::seriesrating); + tokenContainer->DefineStringToken("{seriesstatus}", (int)eScraperST::seriesstatus); + tokenContainer->DefineStringToken("{episodetitle}", (int)eScraperST::episodetitle); + tokenContainer->DefineStringToken("{episodefirstaired}", (int)eScraperST::episodefirstaired); + tokenContainer->DefineStringToken("{episodegueststars}", (int)eScraperST::episodegueststars); + tokenContainer->DefineStringToken("{episodeoverview}", (int)eScraperST::episodeoverview); + tokenContainer->DefineStringToken("{episoderating}", (int)eScraperST::episoderating); + tokenContainer->DefineStringToken("{episodeimagepath}", (int)eScraperST::episodeimagepath); + tokenContainer->DefineStringToken("{seasonposterpath}", (int)eScraperST::seasonposterpath); + tokenContainer->DefineStringToken("{seriesposter1path}", (int)eScraperST::seriesposter1path); + tokenContainer->DefineStringToken("{seriesposter2path}", (int)eScraperST::seriesposter2path); + tokenContainer->DefineStringToken("{seriesposter3path}", (int)eScraperST::seriesposter3path); + tokenContainer->DefineStringToken("{seriesfanart1path}", (int)eScraperST::seriesfanart1path); + tokenContainer->DefineStringToken("{seriesfanart2path}", (int)eScraperST::seriesfanart2path); + tokenContainer->DefineStringToken("{seriesfanart3path}", (int)eScraperST::seriesfanart3path); + tokenContainer->DefineStringToken("{seriesbanner1path}", (int)eScraperST::seriesbanner1path); + tokenContainer->DefineStringToken("{seriesbanner2path}", (int)eScraperST::seriesbanner2path); + tokenContainer->DefineStringToken("{seriesbanner3path}", (int)eScraperST::seriesbanner3path); + tokenContainer->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie); + tokenContainer->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget); + tokenContainer->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue); + tokenContainer->DefineIntToken("{movieadult}", (int)eScraperIT::movieadult); + tokenContainer->DefineIntToken("{movieruntime}", (int)eScraperIT::movieruntime); + tokenContainer->DefineIntToken("{isseries}", (int)eScraperIT::isseries); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperIT::posterheight); + tokenContainer->DefineIntToken("{fanartwidth}", (int)eScraperIT::fanartwidth); + tokenContainer->DefineIntToken("{fanartheight}", (int)eScraperIT::fanartheight); + tokenContainer->DefineIntToken("{movieiscollection}", (int)eScraperIT::movieiscollection); + tokenContainer->DefineIntToken("{collectionposterwidth}", (int)eScraperIT::collectionposterwidth); + tokenContainer->DefineIntToken("{collectionposterheight}", (int)eScraperIT::collectionposterheight); + tokenContainer->DefineIntToken("{collectionfanartwidth}", (int)eScraperIT::collectionfanartwidth); + tokenContainer->DefineIntToken("{collectionfanartheight}", (int)eScraperIT::collectionfanartheight); + tokenContainer->DefineIntToken("{epgpicavailable}", (int)eScraperIT::epgpicavailable); + tokenContainer->DefineIntToken("{episodenumber}", (int)eScraperIT::episodenumber); + tokenContainer->DefineIntToken("{episodeseason}", (int)eScraperIT::episodeseason); + tokenContainer->DefineIntToken("{episodeimagewidth}", (int)eScraperIT::episodeimagewidth); + tokenContainer->DefineIntToken("{episodeimageheight}", (int)eScraperIT::episodeimageheight); + tokenContainer->DefineIntToken("{seasonposterwidth}", (int)eScraperIT::seasonposterwidth); + tokenContainer->DefineIntToken("{seasonposterheight}", (int)eScraperIT::seasonposterheight); + tokenContainer->DefineIntToken("{seriesposter1width}", (int)eScraperIT::seriesposter1width); + tokenContainer->DefineIntToken("{seriesposter1height}", (int)eScraperIT::seriesposter1height); + tokenContainer->DefineIntToken("{seriesposter2width}", (int)eScraperIT::seriesposter2width); + tokenContainer->DefineIntToken("{seriesposter2height}", (int)eScraperIT::seriesposter2height); + tokenContainer->DefineIntToken("{seriesposter3width}", (int)eScraperIT::seriesposter3width); + tokenContainer->DefineIntToken("{seriesposter3height}", (int)eScraperIT::seriesposter3height); + tokenContainer->DefineIntToken("{seriesfanart1width}", (int)eScraperIT::seriesfanart1width); + tokenContainer->DefineIntToken("{seriesfanart1height}", (int)eScraperIT::seriesfanart1height); + tokenContainer->DefineIntToken("{seriesfanart2width}", (int)eScraperIT::seriesfanart2width); + tokenContainer->DefineIntToken("{seriesfanart2height}", (int)eScraperIT::seriesfanart2height); + tokenContainer->DefineIntToken("{seriesfanart3width}", (int)eScraperIT::seriesfanart3width); + tokenContainer->DefineIntToken("{seriesfanart3height}", (int)eScraperIT::seriesfanart3height); + tokenContainer->DefineIntToken("{seriesbanner1width}", (int)eScraperIT::seriesbanner1width); + tokenContainer->DefineIntToken("{seriesbanner1height}", (int)eScraperIT::seriesbanner1height); + tokenContainer->DefineIntToken("{seriesbanner2width}", (int)eScraperIT::seriesbanner2width); + tokenContainer->DefineIntToken("{seriesbanner2height}", (int)eScraperIT::seriesbanner2height); + tokenContainer->DefineIntToken("{seriesbanner3width}", (int)eScraperIT::seriesbanner3width); + tokenContainer->DefineIntToken("{seriesbanner3height}", (int)eScraperIT::seriesbanner3height); + tokenContainer->DefineLoopToken("{actors[name]}", (int)eScraperLT::name); + tokenContainer->DefineLoopToken("{actors[role]}", (int)eScraperLT::role); + tokenContainer->DefineLoopToken("{actors[thumb]}", (int)eScraperLT::thumb); + tokenContainer->DefineLoopToken("{actors[thumbwidth]}", (int)eScraperLT::thumbwidth); + tokenContainer->DefineLoopToken("{actors[thumbheight]}", (int)eScraperLT::thumbheight); + actorsIndex = tokenContainer->LoopIndex("actors"); + InheritTokenContainer(); +} + +void cVeDcChannelDetail::Set(const cChannel *c) { + channel = c; +} + +bool cVeDcChannelDetail::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!channel) + return false; + + SetDirty(); + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDCChannelDetailIT::channelnumber, channel->Number()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::channelname, channel->Name()); + +#if defined (APIVERSNUM) && (APIVERSNUM >= 20301) + LOCK_SCHEDULES_READ; + const cSchedules* schedules = Schedules; +#else + cSchedulesLock schedulesLock; + const cSchedules* schedules = (cSchedules*)cSchedules::Schedules(schedulesLock); +#endif + const cSchedule *schedule = schedules->GetSchedule(channel); + if (schedule) { + const cEvent *presentEvent = schedule->GetPresentEvent(); + if (presentEvent) { + tokenContainer->AddStringToken((int)eDCChannelDetailST::currenttitle, presentEvent->Title()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::currentshorttext, presentEvent->ShortText()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::currentdescription, presentEvent->Description()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::currentstart, *presentEvent->GetTimeString()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::currentstop, *presentEvent->GetEndTimeString()); + tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentduration, presentEvent->Duration()/60); + tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentelapsed, (time(0) - presentEvent->StartTime())/60); + tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentremaining, presentEvent->Duration()/60 - (time(0) - presentEvent->StartTime())/60); + tokenContainer->AddIntToken((int)eDCChannelDetailIT::currentdurationhours, presentEvent->Duration() / 3600); + tokenContainer->AddStringToken((int)eDCChannelDetailST::currentdurationminutes, *cString::sprintf("%.2d", (presentEvent->Duration() / 60)%60)); + vector<int> loopInfo; + bool scrapInfoAvailable = LoadFullScrapInfo(presentEvent, NULL); + int numActors = NumActors(); + loopInfo.push_back(numActors); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + if (scrapInfoAvailable) { + SetFullScrapInfo(tokenContainer, actorsIndex); + } + } + const cList<cEvent> *events = schedule->Events(); + if (events && presentEvent) { + const cEvent *nextEvent = events->Next(presentEvent); + if (nextEvent) { + tokenContainer->AddStringToken((int)eDCChannelDetailST::nexttitle, nextEvent->Title()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::nextshorttext, nextEvent->ShortText()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::nextdescription, nextEvent->Description()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::nextstart, *nextEvent->GetTimeString()); + tokenContainer->AddStringToken((int)eDCChannelDetailST::nextstop, *nextEvent->GetEndTimeString()); + tokenContainer->AddIntToken((int)eDCChannelDetailIT::nextduration, nextEvent->Duration() / 60); + tokenContainer->AddIntToken((int)eDCChannelDetailIT::nextdurationhours, nextEvent->Duration() / 3600); + tokenContainer->AddStringToken((int)eDCChannelDetailST::nextdurationminutes, *cString::sprintf("%.2d", (nextEvent->Duration() / 60)%60)); + } + } + } + return true; +} diff --git a/coreengine/viewelementsdisplaychannel.h b/coreengine/viewelementsdisplaychannel.h index 799456d..b1a7691 100644 --- a/coreengine/viewelementsdisplaychannel.h +++ b/coreengine/viewelementsdisplaychannel.h @@ -150,4 +150,53 @@ public: bool Parse(bool forced = false); }; +/****************************************************************** +* cVeDcChannelHints +******************************************************************/ +class cVeDcChannelHints : public cViewElement { +private: + const cChannel **hints; + int numHints; + int current; + int hintsIndex; + bool active; +public: + cVeDcChannelHints(void); + virtual ~cVeDcChannelHints(void); + void Close(void); + void SetTokenContainer(void); + void SetNumHints(int num); + void SetHint(const cChannel *c); + bool Parse(bool forced = false); + bool Active(void) { return active; }; +}; + + +/****************************************************************** +* cVeDcChannelDetail +******************************************************************/ +class cVeDcChannelDetail : public cViewElement, public cScrapManager { +private: + const cChannel *channel; + int actorsIndex; +public: + cVeDcChannelDetail(void); + virtual ~cVeDcChannelDetail(void); + void Close(void); + void SetTokenContainer(void); + void Set(const cChannel *c); + bool Parse(bool forced = false); +}; + +class cVeDcChannelListDetail : public cVeDcChannelDetail { +public: + cVeDcChannelListDetail(void) {}; + virtual ~cVeDcChannelListDetail(void) {}; +}; + +class cVeDcGroupChannelListDetail : public cVeDcChannelDetail { +public: + cVeDcGroupChannelListDetail(void) {}; + virtual ~cVeDcGroupChannelListDetail(void) {}; +}; #endif //__VIEWELEMENTSDC_H
\ No newline at end of file diff --git a/coreengine/viewelementsdisplaymenu.c b/coreengine/viewelementsdisplaymenu.c index 4397ffa..8e8599f 100644 --- a/coreengine/viewelementsdisplaymenu.c +++ b/coreengine/viewelementsdisplaymenu.c @@ -411,10 +411,10 @@ bool cVeDmTimers::Parse(bool forced) { } bool isRecording = Timer->Recording(); if (!isRecording) { - if (cEpgTimer_Interface_V1* epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)Timer)) { - if (epgTimer->State() == 'R') - isRecording = true; - } + if (cEpgTimer_Interface_V1* epgTimer = dynamic_cast<cEpgTimer_Interface_V1*>((cTimer*)Timer)) { + if (epgTimer->State() == 'R') + isRecording = true; + } } tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::recording, isRecording ? "1" : "0"); diff --git a/coreengine/viewlist.c b/coreengine/viewlist.c index 83e75f8..1ed5432 100644 --- a/coreengine/viewlist.c +++ b/coreengine/viewlist.c @@ -9,6 +9,8 @@ cViewList::cViewList(void) { listElements = NULL; plugId = -1; plugMenuId = -1; + fader = NULL; + shifter = NULL; } cViewList::~cViewList(void) { @@ -25,6 +27,8 @@ cViewList::~cViewList(void) { } delete[] listElements; delete tokenContainer; + delete fader; + delete shifter; } void cViewList::SetGlobals(cGlobals *globals) { @@ -66,6 +70,12 @@ cViewList *cViewList::CreateViewList(const char *name) { l = new cViewListAudioTracks(); else if (startswith(name, "menuplugin")) l = new cViewListPlugin(); + else if (startswith(name, "channellist")) + l = new cViewListChannelList(); + else if (startswith(name, "grouplist")) + l = new cViewListGroupList(); + else if (startswith(name, "groupchannellist")) + l = new cViewListChannelList(); else esyslog("skindesigner: unknown viewlist %s", name); return l; @@ -91,6 +101,12 @@ cViewElement *cViewList::CreateListElement(const char *name) { le = new cLeAudioTracks(); else if (startswith(name, "menuplugin")) le = new cLeMenuPlugin(); + else if (startswith(name, "channellist")) + le = new cLeChannelList(); + else if (startswith(name, "grouplist")) + le = new cLeGroupList(); + else if (startswith(name, "groupchannellist")) + le = new cLeChannelList(); else esyslog("skindesigner: unknown viewlist %s", name); return le; @@ -207,21 +223,85 @@ void cViewList::Clear(void) { } void cViewList::Close(void) { + delete fader; + fader = NULL; + delete shifter; + shifter = NULL; if (!listElements) return; for (int i = 0; i < numElements; i++) { listElements[i]->StopBlinking(); listElements[i]->StopScrolling(); } - for (int i = 0; i < numElements; i++) { + for (int i = 0; i < numElements; i++) listElements[i]->Close(); +} + +void cViewList::SetTransparency(int transparency, bool force) { + for (int i = 0; i < numElements; i++) { + if (listElements[i]) + listElements[i]->SetTransparency(transparency, force); } } -void cViewList::SetTransparency(int transparency) { +cRect cViewList::CoveredArea(void) { + cRect unionArea; for (int i = 0; i < numElements; i++) { + if (listElements[i]) + unionArea.Combine(listElements[i]->CoveredArea()); + } + return unionArea; +} + +void cViewList::SetPosition(cPoint &position, cPoint &reference, bool force) { + for (int i = 0; i < numElements; i++) { + if (listElements[i]) + listElements[i]->SetPosition(position, reference, force); + } +} + +void cViewList::RegisterAnimation(void) { + for (int i = 0; i < numElements; i++) { if (listElements[i]) { - listElements[i]->SetTransparency(transparency); + listElements[i]->RegisterAnimation(); + break; + } + } +} + +void cViewList::UnregisterAnimation(void) { + for (int i = 0; i < numElements; i++) { + if (listElements[i]) { + listElements[i]->UnregisterAnimation(); + break; + } + } +} + +void cViewList::StartAnimation(void) { + if (ShiftTime() > 0) { + cRect shiftbox = CoveredArea(); + cPoint ref = cPoint(shiftbox.X(), shiftbox.Y()); + cPoint start = ShiftStart(shiftbox); + SetPosition(start, ref); + Flush(false); + delete shifter; + shifter = new cAnimation((cShiftable*)this, start, ref, true); + shifter->Start(); + } else if (FadeTime() > 0) { + SetTransparency(100); + Flush(false); + delete fader; + fader = new cAnimation((cFadable*)this, true); + fader->Start(); + } +} + +void cViewList::Flush(bool animFlush) { + for (int i = 0; i < numElements; i++) { + if (listElements[i]) { + listElements[i]->Flush(animFlush); + break; } } } @@ -231,6 +311,27 @@ void cViewList::Debug(void) { attribs->Debug(); } +cPoint cViewList::ShiftStart(cRect &shiftbox) { + eShiftType type = (eShiftType)attribs->ShiftType(); + cPoint start; + if (type == eShiftType::none) { + start = attribs->ShiftStartpoint(); + } else if (type == eShiftType::left) { + start.SetX(-shiftbox.Width()); + start.SetY(shiftbox.Y()); + } else if (type == eShiftType::right) { + start.SetX(cOsd::OsdWidth()); + start.SetY(shiftbox.Y()); + } else if (type == eShiftType::top) { + start.SetX(shiftbox.X()); + start.SetY(-shiftbox.Height()); + } else if (type == eShiftType::bottom) { + start.SetX(shiftbox.X()); + start.SetY(cOsd::OsdHeight()); + } + return start; +} + /****************************************************************** * cViewListDefault ******************************************************************/ @@ -927,3 +1028,117 @@ void cViewListAudioTracks::Draw(void) { } } } + +/****************************************************************** +* cViewListChannelList +******************************************************************/ +cViewListChannelList::cViewListChannelList(void) { + listChannelList = NULL; +} + +cViewListChannelList::~cViewListChannelList(void) { + delete[] listChannelList; +} + +void cViewListChannelList::Prepare(int start, int step) { + if (!listElement) + return; + + cLeChannelList *tpl = dynamic_cast<cLeChannelList*>(listElement); + if (!tpl) return; + + listChannelList = new cLeChannelList*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listChannelList[i] = new cLeChannelList(*tpl); + listElements[i] = listChannelList[i]; + listChannelList[i]->SetNumber(i); + listChannelList[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listChannelList[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listChannelList[i]->SetAreaWidth(width); + } + listChannelList[i]->SetContainer(x, y, width, height); + listChannelList[i]->Cache(); + pos += step; + } +} + +void cViewListChannelList::Set(const cChannel *channel, int index, bool current) { + if (index < 0 || index >= numElements) + return; + if (!current) + listChannelList[index]->StopScrolling(); + listChannelList[index]->SetCurrent(current); + listChannelList[index]->SetSelectable(true); + listChannelList[index]->Set(channel); +} + +/****************************************************************** +* cViewListGroupList +******************************************************************/ +cViewListGroupList::cViewListGroupList(void) { + listGroupList = NULL; +} + +cViewListGroupList::~cViewListGroupList(void) { + delete[] listGroupList; +} + +void cViewListGroupList::Prepare(int start, int step) { + if (!listElement) + return; + + cLeGroupList *tpl = dynamic_cast<cLeGroupList*>(listElement); + if (!tpl) return; + + listGroupList = new cLeGroupList*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listGroupList[i] = new cLeGroupList(*tpl); + listElements[i] = listGroupList[i]; + listGroupList[i]->SetNumber(i); + listGroupList[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listGroupList[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listGroupList[i]->SetAreaWidth(width); + } + listGroupList[i]->SetContainer(x, y, width, height); + listGroupList[i]->Cache(); + pos += step; + } +} + +void cViewListGroupList::Set(const char *group, int numChannels, int index, bool current) { + if (index < 0 || index >= numElements) + return; + if (!current) + listGroupList[index]->StopScrolling(); + listGroupList[index]->SetCurrent(current); + listGroupList[index]->SetSelectable(true); + listGroupList[index]->Set(group, numChannels); +} diff --git a/coreengine/viewlist.h b/coreengine/viewlist.h index 6c14d03..b72123e 100644 --- a/coreengine/viewlist.h +++ b/coreengine/viewlist.h @@ -6,7 +6,7 @@ #include "listelements.h" #include "area.h" -class cViewList { +class cViewList : public cFadable, public cShiftable { protected: int plugId; int plugMenuId; @@ -19,7 +19,10 @@ protected: cViewElement *listElement; cViewElement *currentElement; cListElement **listElements; + cAnimation *fader; + cAnimation *shifter; virtual void Prepare(int start, int step) {}; + cPoint ShiftStart(cRect &shiftbox); public: cViewList(void); virtual ~cViewList(void); @@ -40,7 +43,22 @@ public: void Draw(eMenuCategory menuCat); void Clear(void); virtual void Close(void); - void SetTransparency(int transparency); + //Fadable + bool Detached(void) { return false; }; + int Delay(void) { return 0; }; + int FadeTime(void) { return attribs->FadeTime(); }; + void SetTransparency(int transparency, bool force = false); + //Shiftable + int ShiftTime(void) { return attribs->ShiftTime(); }; + int ShiftMode(void) { return attribs->ShiftMode(); }; + void SetPosition(cPoint &position, cPoint &reference, bool force = false); + void SetStartShifting(void) { }; + void SetEndShifting(void) { }; + void RegisterAnimation(void); + void UnregisterAnimation(void); + cRect CoveredArea(void); + void StartAnimation(void); + void Flush(bool animFlush); void Debug(void); }; @@ -154,4 +172,26 @@ public: void SetCurrentTrack(int index); void Draw(void); }; + +class cViewListChannelList : public cViewList { +private: + cLeChannelList **listChannelList; +protected: + void Prepare(int start, int step); +public: + cViewListChannelList(void); + virtual ~cViewListChannelList(void); + void Set(const cChannel *channel, int index, bool current); +}; + +class cViewListGroupList : public cViewList { +private: + cLeGroupList **listGroupList; +protected: + void Prepare(int start, int step); +public: + cViewListGroupList(void); + virtual ~cViewListGroupList(void); + void Set(const char *group, int numChannels, int index, bool current); +}; #endif //__VIEWLIST_H
\ No newline at end of file diff --git a/coreengine/xmlparser.c b/coreengine/xmlparser.c index 617313a..aa7be10 100644 --- a/coreengine/xmlparser.c +++ b/coreengine/xmlparser.c @@ -40,6 +40,7 @@ bool cXmlParser::ParseView(void) { view->SetAttributes(rootAttribs); cViewMenu *menuView = dynamic_cast<cViewMenu*>(view); + cViewChannel *channelView = dynamic_cast<cViewChannel*>(view); cViewTracks *tracksView = dynamic_cast<cViewTracks*>(view); if (!LevelDown()) @@ -48,6 +49,13 @@ bool cXmlParser::ParseView(void) { do { if (view->ValidViewElement(NodeName())) { ParseViewElement(NodeName()); + } else if (channelView) { + if (view->ValidViewList(NodeName())) { + ParseViewList(NULL, NodeName()); + } else { + esyslog("skindesigner: unknown node %s", NodeName()); + return false; + } } else if (menuView) { if (menuView->ValidSubView(NodeName())) { ParseSubView(NodeName()); @@ -334,7 +342,7 @@ void cXmlParser::ParsePluginViewElement(bool isScrollbar, bool isTabLabels) { } } -void cXmlParser::ParseViewList(cView *subView) { +void cXmlParser::ParseViewList(cView *subView, const char *listName) { if (!view) return; @@ -345,7 +353,11 @@ void cXmlParser::ParseViewList(cView *subView) { name = view->GetViewName(); vector<stringpair> attribs = ParseAttributes(); - cViewList *viewList = cViewList::CreateViewList(name); + cViewList *viewList = NULL; + if (!listName) + viewList = cViewList::CreateViewList(name); + else + viewList = cViewList::CreateViewList(listName); viewList->SetAttributes(attribs); if (!LevelDown()) @@ -353,7 +365,11 @@ void cXmlParser::ParseViewList(cView *subView) { do { if (CheckNodeName("currentelement")) { - cViewElement *currentElement = cViewList::CreateCurrentElement(name); + cViewElement *currentElement = NULL; + if (!listName) + currentElement = cViewList::CreateCurrentElement(name); + else + currentElement = cViewList::CreateCurrentElement(listName); currentElement->SetOsd(sdOsd); vector<stringpair> attribsList = ParseAttributes(); currentElement->SetAttributes(attribsList); @@ -375,7 +391,11 @@ void cXmlParser::ParseViewList(cView *subView) { LevelUp(); viewList->AddCurrentElement(currentElement); } else if (CheckNodeName("listelement")) { - cViewElement *listElement = cViewList::CreateListElement(name); + cViewElement *listElement = NULL; + if (!listName) + listElement = cViewList::CreateListElement(name); + else + listElement = cViewList::CreateListElement(listName); listElement->SetOsd(sdOsd); vector<stringpair> attribsList = ParseAttributes(); listElement->SetAttributes(attribsList); @@ -402,8 +422,12 @@ void cXmlParser::ParseViewList(cView *subView) { if (subView) subView->AddViewList(viewList); - else - view->AddViewList(viewList); + else if (listName) { + cViewChannel *channelView = dynamic_cast<cViewChannel*>(view); + channelView->AddChannelViewList(listName, viewList); + } else { + view->AddViewList(viewList); + } } diff --git a/coreengine/xmlparser.h b/coreengine/xmlparser.h index 398700e..85bb22a 100644 --- a/coreengine/xmlparser.h +++ b/coreengine/xmlparser.h @@ -29,7 +29,7 @@ private: bool ParseSubView(string name); void ParseViewElement(string name, cView *subView = NULL); void ParsePluginViewElement(bool isScrollbar = false, bool isTabLabels = false); - void ParseViewList(cView *subView = NULL); + void ParseViewList(cView *subView = NULL, const char *listName = NULL); void ParseViewTab(cView *subView); void ParseViewTabPlugin(void); void ParseGrid(void); diff --git a/displaychannel.c b/displaychannel.c index 9eead8f..c9cc832 100644 --- a/displaychannel.c +++ b/displaychannel.c @@ -29,6 +29,63 @@ void cSDDisplayChannel::SetMessage(eMessageType Type, const char *Text) { view->SetMessage(Type, Text); } +#ifdef USE_ZAPCOCKPIT + +void cSDDisplayChannel::SetViewType(eDisplaychannelView ViewType) { + if (!ok) + return; + view->SetViewType(ViewType); +} + +int cSDDisplayChannel::MaxItems(void) { + if (!ok) + return 0; + return view->MaxItems(); +} + +void cSDDisplayChannel::SetChannelInfo(const cChannel *Channel) { + if (!ok) + return; + view->SetChannelInfo(Channel); +} + +void cSDDisplayChannel::SetChannelList(const cChannel *Channel, int Index, bool Current) { + if (!ok) + return; + view->SetChannelList(Channel, Index, Current); +} + +void cSDDisplayChannel::SetGroupList(const char *Group, int NumChannels, int Index, bool Current) { + if (!ok) + return; + view->SetGroupList(Group, NumChannels, Index, Current); +} + +void cSDDisplayChannel::SetGroupChannelList(const cChannel *Channel, int Index, bool Current) { + if (!ok) + return; +} + +void cSDDisplayChannel::ClearList(void) { + if (!ok) + return; + view->ClearList(); +} + +void cSDDisplayChannel::SetNumChannelHints(int Num) { + if (!ok) + return; + view->SetNumChannelHints(Num); +} + +void cSDDisplayChannel::SetChannelHint(const cChannel *Channel) { + if (!ok) + return; + view->SetChannelHint(Channel); +} + +#endif //USE_ZAPCOCKPIT + void cSDDisplayChannel::Flush(void) { if (!ok) return; diff --git a/displaychannel.h b/displaychannel.h index f116f2c..e0f2895 100644 --- a/displaychannel.h +++ b/displaychannel.h @@ -6,7 +6,11 @@ #include "coreengine/definitions.h" #include "coreengine/viewdisplaychannel.h" +#ifdef USE_ZAPCOCKPIT +class cSDDisplayChannel : public cSkinDisplayChannelExtended { +#else class cSDDisplayChannel : public cSkinDisplayChannel { +#endif private: cViewChannel *view; bool ok; @@ -16,6 +20,17 @@ public: virtual void SetChannel(const cChannel *Channel, int Number); virtual void SetEvents(const cEvent *Present, const cEvent *Following); virtual void SetMessage(eMessageType Type, const char *Text); +#ifdef USE_ZAPCOCKPIT + virtual void SetViewType(eDisplaychannelView ViewType); + virtual int MaxItems(void); + virtual void SetChannelInfo(const cChannel *Channel); + virtual void SetChannelList(const cChannel *Channel, int Index, bool Current); + virtual void SetGroupList(const char *Group, int NumChannels, int Index, bool Current); + virtual void SetGroupChannelList(const cChannel *Channel, int Index, bool Current); + virtual void ClearList(void); + virtual void SetNumChannelHints(int Num); + virtual void SetChannelHint(const cChannel *Channel); +#endif virtual void Flush(void); }; #endif //__DISPLAYCHANNEL_H diff --git a/dtd/displaychannel.dtd b/dtd/displaychannel.dtd index 9fb6ada..9ed515c 100644 --- a/dtd/displaychannel.dtd +++ b/dtd/displaychannel.dtd @@ -4,7 +4,10 @@ <!ELEMENT displaychannel (background | channelinfo | epginfo | progressbar | progressbarback |
statusinfo | audioinfo | ecminfo | screenresolution | channelgroup |
- signalquality | signalqualityback | devices | currentweather | scrapercontent |
+ signalquality | signalqualityback | devices | currentweather |
+ scrapercontent | channelhints | channeldetail | channellistdetail |
+ channellistback | channellist | grouplistback | grouplist |
+ groupchannellistback | groupchannellist | groupchannellistdetail |
datetime | time | message | customtokens)* >
<!ATTLIST displaychannel
x CDATA #REQUIRED
@@ -220,6 +223,159 @@ condition CDATA #IMPLIED
>
+<!ELEMENT channelhints (areacontainer|area|areascroll)*>
+<!ATTLIST channelhints
+ delay CDATA #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ debug CDATA #IMPLIED
+ condition CDATA #IMPLIED
+>
+
+<!ELEMENT channeldetail (areacontainer|area|areascroll)*>
+<!ATTLIST channeldetail
+ delay CDATA #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ debug CDATA #IMPLIED
+ condition CDATA #IMPLIED
+ clearondisplay CDATA #IMPLIED
+>
+
+<!ELEMENT channellistback (areacontainer|area|areascroll)*>
+<!ATTLIST channellistback
+ delay CDATA #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ debug CDATA #IMPLIED
+ condition CDATA #IMPLIED
+ clearondisplay CDATA #IMPLIED
+>
+
+<!ELEMENT grouplistback (areacontainer|area|areascroll)*>
+<!ATTLIST grouplistback
+ delay CDATA #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ debug CDATA #IMPLIED
+ condition CDATA #IMPLIED
+ clearondisplay CDATA #IMPLIED
+>
+
+<!ELEMENT groupchannellistback (areacontainer|area|areascroll)*>
+<!ATTLIST groupchannellistback
+ delay CDATA #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ debug CDATA #IMPLIED
+ condition CDATA #IMPLIED
+>
+
+<!ELEMENT channellist (listelement)>
+<!ATTLIST channellist
+ x CDATA #REQUIRED
+ y CDATA #REQUIRED
+ width CDATA #REQUIRED
+ height CDATA #REQUIRED
+ align (left|top|center|bottom|right) #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ numlistelements CDATA #REQUIRED
+ orientation CDATA #REQUIRED
+ condition CDATA #IMPLIED
+>
+
+<!ELEMENT grouplist (listelement)>
+<!ATTLIST grouplist
+ x CDATA #REQUIRED
+ y CDATA #REQUIRED
+ width CDATA #REQUIRED
+ height CDATA #REQUIRED
+ align (left|top|center|bottom|right) #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ numlistelements CDATA #REQUIRED
+ orientation CDATA #REQUIRED
+ condition CDATA #IMPLIED
+>
+
+<!ELEMENT groupchannellist (listelement)>
+<!ATTLIST groupchannellist
+ x CDATA #REQUIRED
+ y CDATA #REQUIRED
+ width CDATA #REQUIRED
+ height CDATA #REQUIRED
+ align (left|top|center|bottom|right) #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ numlistelements CDATA #REQUIRED
+ orientation CDATA #REQUIRED
+ condition CDATA #IMPLIED
+>
+
+<!ELEMENT listelement (areacontainer|area|areascroll)*>
+<!ATTLIST listelement
+ debug CDATA #IMPLIED
+>
+
+<!ELEMENT channellistdetail (areacontainer|area|areascroll)*>
+<!ATTLIST channellistdetail
+ delay CDATA #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ debug CDATA #IMPLIED
+ condition CDATA #IMPLIED
+>
+
+<!ELEMENT groupchannellistdetail (areacontainer|area|areascroll)*>
+<!ATTLIST groupchannellistdetail
+ delay CDATA #IMPLIED
+ fadetime CDATA #IMPLIED
+ shifttime CDATA #IMPLIED
+ shifttype CDATA #IMPLIED
+ shiftmode CDATA #IMPLIED
+ startx CDATA #IMPLIED
+ starty CDATA #IMPLIED
+ debug CDATA #IMPLIED
+ condition CDATA #IMPLIED
+>
+
<!ELEMENT datetime (areacontainer|area|areascroll)*>
<!ATTLIST datetime
delay CDATA #IMPLIED
diff --git a/extensions/globaltimers.c b/extensions/globaltimers.c index 6e7263e..c6b483c 100644 --- a/extensions/globaltimers.c +++ b/extensions/globaltimers.c @@ -26,7 +26,6 @@ cGlobalTimers::~cGlobalTimers(void) { }
void cGlobalTimers::LoadTimers(void) {
- uint64_t start = cTimeMs::Now();
isEpg2VdrTimers = false;
bool epg2vdrOk = false;
if (pEpg2Vdr) {
@@ -38,7 +37,6 @@ void cGlobalTimers::LoadTimers(void) { SetRemoteTimers(initial);
}
}
- esyslog("skindesigner: loaded %d timers, needed %d ms", Size(), cTimeMs::Now() - start);
initial = false;
}
diff --git a/patches/vdr-2.2.0_zapcockpit.patch b/patches/vdr-2.2.0_zapcockpit.patch new file mode 100644 index 0000000..1eda556 --- /dev/null +++ b/patches/vdr-2.2.0_zapcockpit.patch @@ -0,0 +1,1015 @@ +diff -Naur vdr-2.2.0/config.c vdr-2.2.0_zapcockpit/config.c +--- vdr-2.2.0/config.c 2015-02-10 13:24:13.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/config.c 2016-05-26 07:29:05.736117301 +0200 +@@ -414,6 +414,10 @@ + SVDRPTimeout = 300; + ZapTimeout = 3; + ChannelEntryTimeout = 1000; ++ ZapcockpitUseGroups = 1; ++ ZapcockpitUseHints = 1; ++ ZapcockpitUseInfo = 1; ++ ZapcockpitHideLastGroup = 0; + RcRepeatDelay = 300; + RcRepeatDelta = 100; + DefaultPriority = 50; +@@ -636,6 +640,10 @@ + else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value); + else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value); + else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value); ++ else if (!strcasecmp(Name, "ZapcockpitUseGroups")) ZapcockpitUseGroups= atoi(Value); ++ else if (!strcasecmp(Name, "ZapcockpitUseHints")) ZapcockpitUseHints = atoi(Value); ++ else if (!strcasecmp(Name, "ZapcockpitUseInfo")) ZapcockpitUseInfo = atoi(Value); ++ else if (!strcasecmp(Name, "ZapcockpitHideLastGroup")) ZapcockpitHideLastGroup = atoi(Value); + else if (!strcasecmp(Name, "RcRepeatDelay")) RcRepeatDelay = atoi(Value); + else if (!strcasecmp(Name, "RcRepeatDelta")) RcRepeatDelta = atoi(Value); + else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value); +@@ -762,6 +770,10 @@ + Store("SVDRPTimeout", SVDRPTimeout); + Store("ZapTimeout", ZapTimeout); + Store("ChannelEntryTimeout",ChannelEntryTimeout); ++ Store("ZapcockpitUseGroups",ZapcockpitUseGroups); ++ Store("ZapcockpitUseHints", ZapcockpitUseHints); ++ Store("ZapcockpitUseInfo", ZapcockpitUseInfo); ++ Store("ZapcockpitHideLastGroup", ZapcockpitHideLastGroup); + Store("RcRepeatDelay", RcRepeatDelay); + Store("RcRepeatDelta", RcRepeatDelta); + Store("DefaultPriority", DefaultPriority); +diff -Naur vdr-2.2.0/config.h vdr-2.2.0_zapcockpit/config.h +--- vdr-2.2.0/config.h 2015-02-13 16:39:08.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/config.h 2016-05-26 07:29:05.708117300 +0200 +@@ -290,6 +290,10 @@ + int SVDRPTimeout; + int ZapTimeout; + int ChannelEntryTimeout; ++ int ZapcockpitUseGroups; ++ int ZapcockpitUseHints; ++ int ZapcockpitUseInfo; ++ int ZapcockpitHideLastGroup; + int RcRepeatDelay; + int RcRepeatDelta; + int DefaultPriority, DefaultLifetime; +diff -Naur vdr-2.2.0/menu.c vdr-2.2.0_zapcockpit/menu.c +--- vdr-2.2.0/menu.c 2015-02-10 13:37:06.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/menu.c 2016-05-26 07:29:05.880117306 +0200 +@@ -3759,6 +3759,10 @@ + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout)); + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Zap timeout (s)"), &data.ZapTimeout)); + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0)); ++ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: 2nd ok shows info"), &data.ZapcockpitUseInfo)); ++ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: Use extended channel group display"), &data.ZapcockpitUseGroups)); ++ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: Use channel hints"), &data.ZapcockpitUseHints)); ++ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: Hide last channel group"), &data.ZapcockpitHideLastGroup)); + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Remote control repeat delay (ms)"), &data.RcRepeatDelay, 0)); + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Remote control repeat delta (ms)"), &data.RcRepeatDelta, 0)); + Add(new cMenuEditChanItem(tr("Setup.Miscellaneous$Initial channel"), &data.InitialChannel, tr("Setup.Miscellaneous$as before"))); +@@ -4207,7 +4211,7 @@ + lastTime.Set(); + } + +-cDisplayChannel::cDisplayChannel(eKeys FirstKey) ++cDisplayChannel::cDisplayChannel(eKeys FirstKey, bool processKey) + :cOsdObject(true) + { + currentDisplayChannel = this; +@@ -4220,7 +4224,8 @@ + displayChannel = Skins.Current()->DisplayChannel(withInfo); + positioner = NULL; + channel = Channels.GetByNumber(cDevice::CurrentChannel()); +- ProcessKey(FirstKey); ++ if (processKey) ++ ProcessKey(FirstKey); + } + + cDisplayChannel::~cDisplayChannel() +@@ -4461,6 +4466,700 @@ + return osEnd; + } + ++// --- cDisplayChannelExtended ------------------------------------------------------- ++cDisplayChannelExtended::cDisplayChannelExtended(int Number, bool Switched) ++:cDisplayChannel(Number, Switched) ++{ ++ state = esDefault; ++ numItemsChannel = 0; ++ currentChannel = -1; ++ startChannel = -1; ++ numItemsGroup = 0; ++ currentGroup = -1; ++ startGroup = -1; ++} ++ ++cDisplayChannelExtended::cDisplayChannelExtended(eKeys FirstKey) ++:cDisplayChannel(FirstKey, false) ++{ ++ state = esInit; ++ numItemsChannel = 0; ++ currentChannel = -1; ++ startChannel = -1; ++ numItemsGroup = 0; ++ currentGroup = -1; ++ startGroup = -1; ++} ++ ++cDisplayChannelExtended::~cDisplayChannelExtended() ++{ ++} ++ ++eOSState cDisplayChannelExtended::ProcessKey(eKeys Key) ++{ ++ cSkinDisplayChannelExtended *displayChannelExtended = dynamic_cast<cSkinDisplayChannelExtended*>(displayChannel); ++ if (!displayChannelExtended) ++ return cDisplayChannel::ProcessKey(Key); ++ ++ if (Key != kNone) ++ lastTime.Set(); ++ ++ bool keyHandeled = false; ++ //number keys are always handled by default state ++ if ((int)Key >= k0 && (int)Key <= k9) { ++ displayChannelExtended->SetViewType(dcDefault); ++ StateNumberKey((int)Key, displayChannelExtended); ++ state = esDefault; ++ } else if (number <= 0) { ++ switch (state) { ++ case esInit: ++ keyHandeled = StateInit((int)Key, displayChannelExtended); ++ break; ++ case esDefault: ++ keyHandeled = StateDefault((int)Key, displayChannelExtended); ++ break; ++ case esChannelInfo: ++ keyHandeled = StateChannelInfo((int)Key, displayChannelExtended); ++ break; ++ case esChannelList: ++ case esChannelListInfo: ++ keyHandeled = StateChannelList((int)Key, displayChannelExtended); ++ break; ++ case esGroupsList: ++ keyHandeled = StateGroupList((int)Key, displayChannelExtended); ++ break; ++ case esGroupsChannelList: ++ case esGroupsChannelListInfo: ++ keyHandeled = StateGroupChannelList((int)Key, displayChannelExtended); ++ break; ++ default: ++ break; ++ } ++ } ++ //in extended state, no timeout ++ if (state != esDefault) ++ lastTime.Set(); ++ ++ //do own flush for all lists ++ if (keyHandeled || (Key == kNone && state > esChannelInfo)) { ++ SetNeedsFastResponse(false); ++ displayChannel->Flush(); ++ return osContinue; ++ } ++ ++ return cDisplayChannel::ProcessKey(Key); ++} ++ ++void cDisplayChannelExtended::StateNumberKey(int key, cSkinDisplayChannelExtended *dcExt) ++{ ++ if (!Setup.ZapcockpitUseHints) ++ return; ++ if (number < 0) ++ return; ++ int selectedChannel = number > Channels.MaxNumber() ? key - k0 : number * 10 + key - k0; ++ int candidateStartNumber = selectedChannel * 10; ++ channellist.Clear(); ++ cChannel *candidatesStart = Channels.GetByNumber(candidateStartNumber); ++ int numHints = 0; ++ for (cChannel *candidate = candidatesStart; candidate; candidate = Channels.Next(candidate)) { ++ if (candidate->GroupSep()) ++ continue; ++ numHints++; ++ if (candidate->Number() >= candidateStartNumber + 9) ++ break; ++ } ++ if (numHints == 0) ++ return; ++ dcExt->SetNumChannelHints(numHints); ++ for (cChannel *candidate = candidatesStart; candidate; candidate = Channels.Next(candidate)) { ++ if (candidate->GroupSep()) ++ continue; ++ dcExt->SetChannelHint(candidate); ++ if (candidate->Number() >= candidateStartNumber + 9) ++ break; ++ } ++} ++ ++bool cDisplayChannelExtended::StateInit(int key, cSkinDisplayChannelExtended *dcExt) ++{ ++ bool keyHandeled = false; ++ switch (key) { ++ //left openes groups list ++ case kLeft|k_Repeat: case kLeft: ++ case kPrev|k_Repeat: case kPrev: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ cOsdProvider::OsdSizeChanged(osdState); // just to get the current state ++ DisplayChannel(); ++ DisplayInfo(); ++ InitGroupList(dcExt); ++ state = esGroupsList; ++ keyHandeled = true; ++ break; ++ } ++ //right openes channels list ++ case kRight|k_Repeat: case kRight: ++ case kNext|k_Repeat: case kNext: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ cOsdProvider::OsdSizeChanged(osdState); // just to get the current state ++ DisplayChannel(); ++ DisplayInfo(); ++ InitChannelList(dcExt); ++ state = esChannelList; ++ keyHandeled = true; ++ break; ++ } ++ //other keys are handled by cDisplayChannel::ProcessKeys() ++ default: ++ dcExt->SetViewType(dcDefault); ++ state = esDefault; ++ break; ++ } ++ return keyHandeled; ++} ++ ++bool cDisplayChannelExtended::StateDefault(int key, cSkinDisplayChannelExtended *dcExt) ++{ ++ bool keyHandeled = false; ++ switch (key) { ++ //2nd ok opens extended info for current channel ++ case kOk: { ++ if (!Setup.ZapcockpitUseInfo) ++ return false; ++ dcExt->SetViewType(dcChannelInfo); ++ dcExt->SetChannelInfo(channel); ++ state = esChannelInfo; ++ keyHandeled = true; ++ break; ++ } ++ //left openes groups list ++ case kLeft|k_Repeat: case kLeft: ++ case kPrev|k_Repeat: case kPrev: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitGroupList(dcExt); ++ state = esGroupsList; ++ keyHandeled = true; ++ break; ++ } ++ //right openes channels list ++ case kRight|k_Repeat: case kRight: ++ case kNext|k_Repeat: case kNext: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitChannelList(dcExt); ++ state = esChannelList; ++ keyHandeled = true; ++ break; ++ } ++ //other keys are handled by cDisplayChannel::ProcessKeys() ++ default: ++ break; ++ } ++ return keyHandeled; ++} ++ ++bool cDisplayChannelExtended::StateChannelInfo(int key, cSkinDisplayChannelExtended *dcExt) ++{ ++ bool keyHandeled = false; ++ switch (key) { ++ //ok closes here ++ case kOk: ++ state = esDefault; ++ break; ++ //channel switching is handled by default state ++ case kUp|k_Repeat: case kUp: ++ case kDown|k_Repeat: case kDown: ++ case kChanUp|k_Repeat: case kChanUp: ++ case kChanDn|k_Repeat: case kChanDn: ++ dcExt->SetViewType(dcDefault); ++ state = esDefault; ++ break; ++ case kUp|k_Release: case kDown|k_Release: ++ case kChanUp|k_Release: case kChanDn|k_Release: ++ case kNext|k_Release: case kPrev|k_Release: ++ dcExt->SetViewType(dcDefault); ++ state = esDefault; ++ break; ++ //left openes groups list ++ case kLeft|k_Repeat: case kLeft: ++ case kPrev|k_Repeat: case kPrev: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitGroupList(dcExt); ++ state = esGroupsList; ++ keyHandeled = true; ++ break; ++ } ++ //right openes channels list ++ case kRight|k_Repeat: case kRight: ++ case kNext|k_Repeat: case kNext: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitChannelList(dcExt); ++ state = esChannelList; ++ keyHandeled = true; ++ break; ++ } ++ default: ++ break; ++ } ++ return keyHandeled; ++} ++ ++bool cDisplayChannelExtended::StateChannelList(int key, cSkinDisplayChannelExtended *dcExt) ++{ ++ bool keyHandeled = false; ++ switch (key) { ++ //ok switches to the selected channel ++ case kOk: { ++ bool ok = SwitchChannel(); ++ dcExt->SetViewType(dcDefault); ++ if (!ok) ++ keyHandeled = true; ++ state = esDefault; ++ break; ++ } ++ //scrolling up / down ++ case kUp|k_Repeat: case kUp: ++ state = esChannelList; ++ dcExt->SetViewType(dcChannelList); ++ CursorUp(dcExt); ++ keyHandeled = true; ++ break; ++ case kDown|k_Repeat: case kDown: ++ state = esChannelList; ++ dcExt->SetViewType(dcChannelList); ++ CursorDown(dcExt); ++ keyHandeled = true; ++ break; ++ //left closes channel list ++ case kLeft|k_Repeat: case kLeft: { ++ if (state == esChannelList) { ++ keyHandeled = true; ++ dcExt->SetViewType(dcDefault); ++ state = esDefault; ++ } else if (state == esChannelListInfo) { ++ keyHandeled = true; ++ dcExt->SetViewType(dcChannelList); ++ state = esChannelList; ++ } ++ break; } ++ //right shows extended info of currently selected channel ++ case kRight|k_Repeat: case kRight: { ++ keyHandeled = true; ++ if (state != esChannelList) ++ break; ++ cChannelListItem *li = channellist.Get(currentChannel); ++ if (li) { ++ const cChannel *selected = li->Channel(); ++ if (selected) { ++ dcExt->SetViewType(dcChannelListInfo); ++ dcExt->SetChannelInfo(selected); ++ state = esChannelListInfo; ++ } ++ } ++ break; ++ } ++ default: ++ break; ++ } ++ return keyHandeled; ++} ++ ++bool cDisplayChannelExtended::StateGroupList(int key, cSkinDisplayChannelExtended *dcExt) ++{ ++ bool keyHandeled = false; ++ switch (key) { ++ //ok switches to first channel in group ++ case kOk: { ++ bool ok = SwitchChannel(); ++ dcExt->SetViewType(dcDefault); ++ if (!ok) ++ keyHandeled = true; ++ state = esDefault; ++ break; ++ } ++ //scrolling up / down ++ case kUp|k_Repeat: case kUp: ++ state = esGroupsList; ++ CursorUp(dcExt); ++ dcExt->SetViewType(dcGroupsList); ++ keyHandeled = true; ++ break; ++ case kDown|k_Repeat: case kDown: ++ state = esGroupsList; ++ CursorDown(dcExt); ++ dcExt->SetViewType(dcGroupsList); ++ keyHandeled = true; ++ break; ++ //left shows channel list of selected group ++ case kLeft|k_Repeat: case kLeft: ++ state = esGroupsChannelList; ++ InitGroupChannelList(dcExt); ++ keyHandeled = true; ++ break; ++ //right closes group list ++ case kRight|k_Repeat: case kRight: ++ keyHandeled = true; ++ dcExt->SetViewType(dcDefault); ++ state = esDefault; ++ break; ++ default: ++ break; ++ } ++ return keyHandeled; ++} ++ ++bool cDisplayChannelExtended::StateGroupChannelList(int key, cSkinDisplayChannelExtended *dcExt) ++{ ++ bool keyHandeled = false; ++ switch (key) { ++ //ok switches to the selected channel ++ case kOk: { ++ bool ok = SwitchChannel(); ++ dcExt->SetViewType(dcDefault); ++ if (!ok) ++ keyHandeled = true; ++ state = esDefault; ++ break; ++ } ++ //scrolling up / down ++ case kUp|k_Repeat: case kUp: ++ state = esGroupsChannelList; ++ dcExt->SetViewType(dcGroupsChannelList); ++ CursorUp(dcExt); ++ keyHandeled = true; ++ break; ++ case kDown|k_Repeat: case kDown: ++ state = esGroupsChannelList; ++ dcExt->SetViewType(dcGroupsChannelList); ++ CursorDown(dcExt); ++ keyHandeled = true; ++ break; ++ //left shows extended info of currently selected channel ++ case kLeft|k_Repeat: case kLeft: { ++ keyHandeled = true; ++ if (state != esGroupsChannelList) ++ break; ++ cChannelListItem *li = channellist.Get(currentChannel); ++ if (li) { ++ const cChannel *selected = li->Channel(); ++ if (selected) { ++ dcExt->SetViewType(dcGroupsChannelListInfo); ++ dcExt->SetChannelInfo(selected); ++ state = esGroupsChannelListInfo; ++ } ++ } ++ break; ++ } ++ //right closes channel list or channel info ++ case kRight|k_Repeat: case kRight: { ++ if (state == esGroupsChannelList) { ++ state = esGroupsList; ++ dcExt->SetViewType(dcGroupsList); ++ keyHandeled = true; ++ } else if (state == esGroupsChannelListInfo) { ++ state = esGroupsChannelList; ++ dcExt->SetViewType(dcGroupsChannelList); ++ keyHandeled = true; ++ } ++ break; ++ } ++ default: ++ break; ++ } ++ return keyHandeled; ++} ++ ++void cDisplayChannelExtended::InitChannelList(cSkinDisplayChannelExtended *dcExt) ++{ ++ dcExt->SetViewType(dcChannelList); ++ numItemsChannel = dcExt->MaxItems(); ++ if (numItemsChannel < 1) ++ return; ++ SetChannelList(); ++ currentChannel = GetIndexChannel(channel); ++ if (currentChannel < 0) ++ currentChannel = 0; ++ startChannel = max(0, currentChannel - numItemsChannel/2 + 1); ++ DisplayChannelList(dcExt); ++} ++ ++void cDisplayChannelExtended::SetChannelList(void) ++{ ++ channellist.Clear(); ++ cChannel *lastSep = NULL; ++ if (Setup.ZapcockpitHideLastGroup) ++ lastSep = LastChannelSep(); ++ for (cChannel *c = Channels.First(); c; c = Channels.Next(c)) { ++ if (c->GroupSep()) { ++ if (Setup.ZapcockpitHideLastGroup && c == lastSep) ++ break; ++ else ++ continue; ++ } ++ channellist.Add(new cChannelListItem(c)); ++ } ++} ++ ++int cDisplayChannelExtended::GetIndexChannel(cChannel *c) ++{ ++ int i=0; ++ for (cChannelListItem *li = channellist.First(); li; li = channellist.Next(li)) { ++ if (li->Channel() == c) ++ return i; ++ i++; ++ } ++ return -1; ++} ++ ++void cDisplayChannelExtended::InitGroupList(cSkinDisplayChannelExtended *dcExt) ++{ ++ dcExt->SetViewType(dcGroupsList); ++ numItemsGroup = dcExt->MaxItems(); ++ if (numItemsGroup < 1) ++ return; ++ SetGroupList(); ++ currentGroup = GetIndexGroup(channel); ++ if (currentGroup < 0) ++ currentGroup = 0; ++ startGroup = max(0, numItemsGroup >= grouplist.Count() ? 0 : currentGroup - numItemsGroup/2 + 1); ++ DisplayGroupList(dcExt); ++} ++ ++void cDisplayChannelExtended::SetGroupList(void) ++{ ++ grouplist.Clear(); ++ cChannel *lastSep = NULL; ++ if (Setup.ZapcockpitHideLastGroup) ++ lastSep = LastChannelSep(); ++ int numChannels = 0; ++ cGroupListItem *item = NULL; ++ for (cChannel *c = Channels.First(); c; c = Channels.Next(c)) { ++ if (c->GroupSep()) { ++ if (item) { ++ item->SetNumChannels(numChannels); ++ numChannels = 0; ++ } ++ if (Setup.ZapcockpitHideLastGroup && c == lastSep) ++ break; ++ item = new cGroupListItem(c); ++ grouplist.Add(item); ++ } else ++ numChannels++; ++ } ++ if (grouplist.Count() > 0 && numChannels) ++ grouplist.Last()->SetNumChannels(numChannels); ++} ++ ++int cDisplayChannelExtended::GetIndexGroup(cChannel *cur) ++{ ++ cChannel *group = NULL; ++ for (cChannel *c = cur; c; c = Channels.Prev(c)) { ++ if (c->GroupSep()) { ++ group = c; ++ break; ++ } ++ } ++ if (!group) ++ return -1; ++ int i=0; ++ for (cGroupListItem *li = grouplist.First(); li; li = grouplist.Next(li)) { ++ if (li->Channel() == group) ++ return i; ++ i++; ++ } ++ return -1; ++} ++ ++void cDisplayChannelExtended::InitGroupChannelList(cSkinDisplayChannelExtended *dcExt) ++{ ++ dcExt->SetViewType(dcGroupsChannelList); ++ numItemsChannel = dcExt->MaxItems(); ++ if (numItemsChannel < 1) ++ return; ++ SetGroupChannelList(dcExt); ++ currentChannel = 0; ++ startChannel = 0; ++ DisplayChannelList(dcExt); ++} ++ ++void cDisplayChannelExtended::SetGroupChannelList(cSkinDisplayChannelExtended *dcExt) ++{ ++ cGroupListItem *curGroup = grouplist.Get(currentGroup); ++ if (!curGroup) ++ return; ++ cChannel *curChannel = curGroup->Channel(); ++ if (!curChannel) ++ return; ++ channellist.Clear(); ++ for (cChannel *c = dynamic_cast<cChannel*>(curChannel->Next()); c; c = Channels.Next(c)) { ++ if (c->GroupSep()) ++ break; ++ channellist.Add(new cChannelListItem(c)); ++ } ++} ++ ++void cDisplayChannelExtended::CursorUp(cSkinDisplayChannelExtended *dcExt) ++{ ++ int *start, *current, *numItems; ++ if (state == esChannelList || state == esGroupsChannelList) { ++ start = &startChannel; ++ current = ¤tChannel; ++ numItems = &numItemsChannel; ++ } else if (state == esGroupsList) { ++ start = &startGroup; ++ current = ¤tGroup; ++ numItems = &numItemsGroup; ++ } else ++ return; ++ ++ if (*current == 0) { ++ dcExt->ClearList(); ++ int itemsTotal = (state == esChannelList || state == esGroupsChannelList)?channellist.Count():((state == esGroupsList)?grouplist.Count():0); ++ *current = itemsTotal-1; ++ *start = max(0, itemsTotal - *numItems); ++ if (state == esChannelList || state == esGroupsChannelList) ++ DisplayChannelList(dcExt); ++ else if (state == esGroupsList) ++ DisplayGroupList(dcExt); ++ return; ++ } ++ int curRel = *current - *start; ++ if (curRel > 0) { ++ if (state == esChannelList || state == esGroupsChannelList) { ++ const cChannel *prev = channellist.Get(*current-1)->Channel(); ++ dcExt->SetChannelList(channellist.Get(*current)->Channel(), curRel, false); ++ dcExt->SetChannelList(prev, curRel-1, true); ++ (*current)--; ++ return; ++ } else if (state = esGroupsList) { ++ cGroupListItem *prev = grouplist.Get(*current-1); ++ cGroupListItem *old = grouplist.Get(*current); ++ dcExt->SetGroupList(old->GroupName(), old->NumChannels(), curRel, false); ++ dcExt->SetGroupList(prev->GroupName(), prev->NumChannels(), curRel-1, true); ++ (*current)--; ++ return; ++ } ++ } ++ dcExt->ClearList(); ++ (*current)--; ++ *start = max(0, *start-*numItems); ++ ++ if (state == esChannelList || state == esGroupsChannelList) ++ DisplayChannelList(dcExt); ++ else if (state == esGroupsList) ++ DisplayGroupList(dcExt); ++} ++ ++void cDisplayChannelExtended::CursorDown(cSkinDisplayChannelExtended *dcExt) ++{ ++ int *start, *current, *numItems; ++ if (state == esChannelList || state == esGroupsChannelList) { ++ start = &startChannel; ++ current = ¤tChannel; ++ numItems = &numItemsChannel; ++ } else if (state == esGroupsList) { ++ start = &startGroup; ++ current = ¤tGroup; ++ numItems = &numItemsGroup; ++ } else ++ return; ++ ++ int curRel = *current - *start; ++ if (curRel < *numItems - 1) { ++ if (state == esChannelList || state == esGroupsChannelList) { ++ cChannelListItem *next = channellist.Get(*current+1); ++ if (next) { ++ dcExt->SetChannelList(channellist.Get(*current)->Channel(), curRel, false); ++ dcExt->SetChannelList(next->Channel(), curRel+1, true); ++ (*current)++; ++ return; ++ } ++ } else if (state == esGroupsList) { ++ cGroupListItem *next = grouplist.Get(*current+1); ++ if (next) { ++ cGroupListItem *old = grouplist.Get(*current); ++ dcExt->SetGroupList(old->GroupName(), old->NumChannels(), curRel, false); ++ dcExt->SetGroupList(next->GroupName(), next->NumChannels(), curRel+1, true); ++ (*current)++; ++ return; ++ } ++ } ++ } ++ if (((state == esChannelList || state == esGroupsChannelList) && *current+1 == channellist.Count()) || ++ (state == esGroupsList && *current+1 == grouplist.Count())) ++ *start = *current = 0; ++ else ++ *start = *current = *current+1; ++ dcExt->ClearList(); ++ ++ if (state == esChannelList || state == esGroupsChannelList) ++ DisplayChannelList(dcExt); ++ else if (state == esGroupsList) ++ DisplayGroupList(dcExt); ++} ++ ++void cDisplayChannelExtended::DisplayChannelList(cSkinDisplayChannelExtended *dcExt) ++{ ++ int index = 0; ++ for (cChannelListItem *c = channellist.Get(startChannel); c; c = channellist.Next(c)) { ++ dcExt->SetChannelList(c->Channel(), index, (startChannel + index == currentChannel) ? true : false); ++ if (++index == numItemsChannel) ++ break; ++ } ++} ++ ++void cDisplayChannelExtended::DisplayGroupList(cSkinDisplayChannelExtended *dcExt) ++{ ++ int index = 0; ++ for (cGroupListItem *g = grouplist.Get(startGroup); g; g = grouplist.Next(g)) { ++ dcExt->SetGroupList(g->GroupName(), g->NumChannels(), index, (startGroup + index == currentGroup) ? true : false); ++ if (++index == numItemsGroup) ++ break; ++ } ++} ++ ++bool cDisplayChannelExtended::SwitchChannel(void) ++{ ++ cChannel *newChannel = NULL; ++ if ( state == esChannelList || ++ state == esChannelListInfo || ++ state == esGroupsChannelList || ++ state == esGroupsChannelListInfo ) { ++ cChannelListItem *li = channellist.Get(currentChannel); ++ if (li) ++ newChannel = li->Channel(); ++ } else if (state == esGroupsList) { ++ cGroupListItem *item = grouplist.Get(currentGroup); ++ if (!item) ++ return false; ++ cChannel *cGroup = item->Channel(); ++ for (cChannel *c = cGroup; c; c = Channels.Next(c)) ++ if (!c->GroupSep()) { ++ newChannel = c; ++ break; ++ } ++ } ++ if (!newChannel || newChannel == channel) ++ return false; ++ SetTrackDescriptions(newChannel->Number()); // to make them immediately visible in the channel display ++ Channels.SwitchTo(newChannel->Number()); ++ SetTrackDescriptions(newChannel->Number()); // switching the channel has cleared them ++ channel = newChannel; ++ return true; ++} ++ ++cChannel *cDisplayChannelExtended::LastChannelSep(void) ++{ ++ for (cChannel *c = Channels.Last(); c; c = Channels.Prev(c)) ++ if (c->GroupSep()) ++ return c; ++ return NULL; ++} ++ + // --- cDisplayVolume -------------------------------------------------------- + + #define VOLUMETIMEOUT 1000 //ms +diff -Naur vdr-2.2.0/menu.h vdr-2.2.0_zapcockpit/menu.h +--- vdr-2.2.0/menu.h 2015-02-06 10:47:30.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/menu.h 2016-05-26 07:29:05.680117299 +0200 +@@ -115,30 +115,99 @@ + + class cDisplayChannel : public cOsdObject { + private: +- cSkinDisplayChannel *displayChannel; + int group; + bool withInfo; +- cTimeMs lastTime; +- int number; + bool timeout; +- int osdState; + const cPositioner *positioner; +- cChannel *channel; + const cEvent *lastPresent; + const cEvent *lastFollowing; + static cDisplayChannel *currentDisplayChannel; +- void DisplayChannel(void); +- void DisplayInfo(void); + void Refresh(void); + cChannel *NextAvailableChannel(cChannel *Channel, int Direction); ++protected: ++ cSkinDisplayChannel *displayChannel; ++ cTimeMs lastTime; ++ int number; ++ cChannel *channel; ++ int osdState; ++ void DisplayChannel(void); ++ void DisplayInfo(void); + public: + cDisplayChannel(int Number, bool Switched); +- cDisplayChannel(eKeys FirstKey); ++ cDisplayChannel(eKeys FirstKey, bool processKey = true); + virtual ~cDisplayChannel(); + virtual eOSState ProcessKey(eKeys Key); + static bool IsOpen(void) { return currentDisplayChannel != NULL; } + }; + ++enum eExtendedState { ++ esInit = 0, ++ esDefault, ++ esChannelInfo, ++ esChannelList, ++ esChannelListInfo, ++ esGroupsList, ++ esGroupsChannelList, ++ esGroupsChannelListInfo ++ }; ++ ++class cChannelListItem : public cListObject { ++private: ++ cChannel *channel; ++public: ++ cChannelListItem(cChannel *Channel) { channel = Channel; }; ++ virtual ~cChannelListItem(void) { }; ++ cChannel *Channel(void) { return channel; } ++ }; ++ ++class cGroupListItem : public cListObject { ++private: ++ cChannel *channel; ++ int numChannels; ++public: ++ cGroupListItem(cChannel *Channel) { channel = Channel; numChannels = 0; }; ++ virtual ~cGroupListItem(void) { }; ++ const char *GroupName(void) { return channel->Name(); } ++ void SetNumChannels(int NumChannels) { numChannels = NumChannels; }; ++ int NumChannels(void) { return numChannels; }; ++ cChannel *Channel(void) { return channel; } ++ }; ++ ++class cDisplayChannelExtended : public cDisplayChannel { ++private: ++ eExtendedState state; ++ int numItemsChannel, startChannel, currentChannel; ++ int numItemsGroup, startGroup, currentGroup; ++ cList<cChannelListItem> channellist; ++ cList<cGroupListItem> grouplist; ++ void StateNumberKey(int key, cSkinDisplayChannelExtended *dcExt); ++ bool StateInit(int key, cSkinDisplayChannelExtended *dcExt); ++ bool StateDefault(int key, cSkinDisplayChannelExtended *dcExt); ++ bool StateChannelInfo(int key, cSkinDisplayChannelExtended *dcExt); ++ bool StateChannelList(int key, cSkinDisplayChannelExtended *dcExt); ++ bool StateGroupList(int key, cSkinDisplayChannelExtended *dcExt); ++ bool StateGroupChannelList(int key, cSkinDisplayChannelExtended *dcExt); ++ void InitChannelList(cSkinDisplayChannelExtended *dcExt); ++ void SetChannelList(void); ++ int GetIndexChannel(cChannel *c); ++ void InitGroupList(cSkinDisplayChannelExtended *dcExt); ++ void SetGroupList(void); ++ int GetIndexGroup(cChannel *c); ++ void InitGroupChannelList(cSkinDisplayChannelExtended *dcExt); ++ void SetGroupChannelList(cSkinDisplayChannelExtended *dcExt); ++ void CursorUp(cSkinDisplayChannelExtended *dcExt); ++ void CursorDown(cSkinDisplayChannelExtended *dcExt); ++ void DisplayChannelList(cSkinDisplayChannelExtended *dcExt); ++ void DisplayGroupList(cSkinDisplayChannelExtended *dcExt); ++ bool SwitchChannel(void); ++ cChannel *LastChannelSep(void); ++public: ++ cDisplayChannelExtended(int Number, bool Switched); ++ cDisplayChannelExtended(eKeys FirstKey); ++ virtual ~cDisplayChannelExtended(); ++ virtual eOSState ProcessKey(eKeys Key); ++ }; ++ + class cDisplayVolume : public cOsdObject { + private: + cSkinDisplayVolume *displayVolume; +diff -Naur vdr-2.2.0/po/de_DE.po vdr-2.2.0_zapcockpit/po/de_DE.po +--- vdr-2.2.0/po/de_DE.po 2015-02-19 10:12:22.401201125 +0100 ++++ vdr-2.2.0_zapcockpit/po/de_DE.po 2016-05-26 07:29:05.836117304 +0200 +@@ -8,7 +8,7 @@ + msgstr "" + "Project-Id-Version: VDR 2.2.0\n" + "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" +-"POT-Creation-Date: 2015-02-10 13:40+0100\n" ++"POT-Creation-Date: 2016-05-22 09:17+0200\n" + "PO-Revision-Date: 2015-02-10 13:45+0100\n" + "Last-Translator: Klaus Schmidinger <vdr@tvdr.de>\n" + "Language-Team: German <vdr@linuxtv.org>\n" +@@ -1284,6 +1284,18 @@ + msgid "Setup.Miscellaneous$Channel entry timeout (ms)" + msgstr "Zeitlimit für Kanaleingabe (ms)" + ++msgid "Setup.Miscellaneous$Zapcockpit: 2nd ok shows info" ++msgstr "Zapcockpit: zweites OK zeigt Info" ++ ++msgid "Setup.Miscellaneous$Zapcockpit: Use extended channel group display" ++msgstr "Zapcockpit: Erweiterte Kanalgruppen Anzeige benutzen" ++ ++msgid "Setup.Miscellaneous$Zapcockpit: Use channel hints" ++msgstr "Zapcockpit: Kanalhinweise benutzen" ++ ++msgid "Setup.Miscellaneous$Zapcockpit: Hide last channel group" ++msgstr "Zapcockpit: letzte Kanalgruppe ausblenden" ++ + msgid "Setup.Miscellaneous$Remote control repeat delay (ms)" + msgstr "Fernbedienung Wiederholverzögerung (ms)" + +diff -Naur vdr-2.2.0/skins.c vdr-2.2.0_zapcockpit/skins.c +--- vdr-2.2.0/skins.c 2013-08-18 14:07:22.000000000 +0200 ++++ vdr-2.2.0_zapcockpit/skins.c 2016-05-26 07:29:05.788117303 +0200 +@@ -79,6 +79,13 @@ + SetMessage(mtInfo, cString::sprintf(tr("Moving dish to %.1f..."), double(positioner->TargetLongitude()) / 10)); + } + ++cSkinDisplayChannelExtended::cSkinDisplayChannelExtended(void) ++: cSkinDisplayChannel() ++{ ++ ++} ++ ++ + // --- cSkinDisplayMenu ------------------------------------------------------ + + cSkinDisplayMenu::cSkinDisplayMenu(void) +diff -Naur vdr-2.2.0/skins.h vdr-2.2.0_zapcockpit/skins.h +--- vdr-2.2.0/skins.h 2015-01-15 11:45:47.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/skins.h 2016-05-26 07:29:05.740117301 +0200 +@@ -88,6 +88,33 @@ + */ + }; + ++#define USE_ZAPCOCKPIT 1 ++ ++enum eDisplaychannelView { ++ dcDefault = 0, ++ dcChannelInfo, ++ dcChannelList, ++ dcChannelListInfo, ++ dcGroupsList, ++ dcGroupsChannelList, ++ dcGroupsChannelListInfo ++ }; ++ ++class cSkinDisplayChannelExtended : public cSkinDisplayChannel { ++private: ++public: ++ cSkinDisplayChannelExtended(void); ++ virtual void SetViewType(eDisplaychannelView ViewType) = 0; ++ virtual int MaxItems(void) = 0; ++ virtual void SetChannelInfo(const cChannel *Channel) = 0; ++ virtual void SetChannelList(const cChannel *Channel, int Index, bool Current) = 0; ++ virtual void SetGroupList(const char *Group, int NumChannels, int Index, bool Current) = 0; ++ virtual void SetGroupChannelList(const cChannel *Channel, int Index, bool Current) = 0; ++ virtual void ClearList(void) = 0; ++ virtual void SetNumChannelHints(int Num) = 0; ++ virtual void SetChannelHint(const cChannel *Channel) = 0; ++}; ++ + enum eMenuCategory { + mcUndefined = -1, + mcUnknown = 0, +diff -Naur vdr-2.2.0/vdr.c vdr-2.2.0_zapcockpit/vdr.c +--- vdr-2.2.0/vdr.c 2015-02-10 15:13:12.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/vdr.c 2016-05-26 07:29:05.676117299 +0200 +@@ -996,7 +996,7 @@ + // Channel display: + if (!EITScanner.Active() && cDevice::CurrentChannel() != LastChannel) { + if (!Menu) +- Menu = new cDisplayChannel(cDevice::CurrentChannel(), LastChannel >= 0); ++ Menu = new cDisplayChannelExtended(cDevice::CurrentChannel(), LastChannel >= 0); + LastChannel = cDevice::CurrentChannel(); + LastChannelChanged = Now; + } +@@ -1174,8 +1174,10 @@ + case kChanUp: + case kChanDn|k_Repeat: + case kChanDn: +- if (!Interact) +- Menu = new cDisplayChannel(NORMALKEY(key)); ++ if (!Interact) { ++ Menu = new cDisplayChannelExtended(NORMALKEY(key)); ++ Menu->ProcessKey(NORMALKEY(key)); ++ } + else if (cDisplayChannel::IsOpen() || cControl::Control()) { + Interact->ProcessKey(key); + continue; +@@ -1368,7 +1370,8 @@ + case kUp: + case kDown|k_Repeat: + case kDown: +- Menu = new cDisplayChannel(NORMALKEY(key)); ++ Menu = new cDisplayChannelExtended(NORMALKEY(key)); ++ Menu->ProcessKey(NORMALKEY(key)); + break; + // Viewing Control: + case kOk: LastChannel = -1; break; // forces channel display diff --git a/skindesigner.c b/skindesigner.c index 79b3829..2c64ee7 100644 --- a/skindesigner.c +++ b/skindesigner.c @@ -20,7 +20,7 @@ #endif -static const char *VERSION = "1.0.3"; +static const char *VERSION = "1.0.2"; static const char *DESCRIPTION = trNOOP("Skin Designer"); class cPluginSkinDesigner : public cPlugin, public skindesignerapi::SkindesignerAPI { @@ -158,6 +158,9 @@ bool cPluginSkinDesigner::Start(void) { if (!skinAvailable) { esyslog("skindesigner: no skins found! Using default Skin LCARS!"); } +#ifdef USE_ZAPCOCKPIT + dsyslog("skindesigner: zapcockpit patch available"); +#endif return true; } diff --git a/skins/estuary4vdr/setup.xml b/skins/estuary4vdr/setup.xml index 7d5a374..cde1826 100644 --- a/skins/estuary4vdr/setup.xml +++ b/skins/estuary4vdr/setup.xml @@ -14,6 +14,34 @@ <parameter type="int" name="startstopfontsize" min="0" max="100" displaytext="{tr(startstopfontsize)}">40</parameter> <parameter type="int" name="channelnamefontsize" min="0" max="100" displaytext="{tr(channelnamefontsize)}">75</parameter> <parameter type="bool" name="scrollepg" displaytext="{tr(scrollepgtext)}">1</parameter> + <parameter type="separator" name="sepzapcockpit" displaytext="{tr(sepzapcockpit)}"/> + <parameter type="int" name="fadetimezapcockpit" displaytext="{tr(fadetimezapcockpit)}">0</parameter> + <parameter type="int" name="shifttimezapcockpit" displaytext="{tr(shifttimezapcockpit)}">200</parameter> + <parameter type="separator" name="sepzapcockpitdetail" displaytext="{tr(sepzapcockpitdetail)}"/> + <parameter type="int" name="zapdetaildatetimefs" min="0" max="100" displaytext="{tr(zapdetaildatetimefs)}">80</parameter> + <parameter type="int" name="zapdetailheaderfs" min="0" max="100" displaytext="{tr(zapdetailheaderfs)}">80</parameter> + <parameter type="int" name="zapdetailshorttextfs" min="0" max="100" displaytext="{tr(zapdetailshorttextfs)}">80</parameter> + <parameter type="int" name="zapdetaildescfs" min="0" max="100" displaytext="{tr(zapdetaildescfs)}">6</parameter> + <parameter type="separator" name="sepzapcockpitcl" displaytext="{tr(sepzapcockpitcl)}"/> + <parameter type="int" name="zapclchannelfs" min="0" max="100" displaytext="{tr(zapclchannelfs)}">38</parameter> + <parameter type="int" name="zapclchannely" min="0" max="100" displaytext="{tr(zapclchannely)}">3</parameter> + <parameter type="int" name="zapclpresentfs" min="0" max="100" displaytext="{tr(zapclpresentfs)}">38</parameter> + <parameter type="int" name="zapclpresenty" min="0" max="100" displaytext="{tr(zapclpresenty)}">35</parameter> + <parameter type="int" name="zapclnextfs" min="0" max="100" displaytext="{tr(zapclnextfs)}">28</parameter> + <parameter type="int" name="zapclnexty" min="0" max="100" displaytext="{tr(zapclnexty)}">70</parameter> + <parameter type="int" name="zapcldetaildatetimefs" min="0" max="100" displaytext="{tr(zapcldetaildatetimefs)}">80</parameter> + <parameter type="int" name="zapcldetailheaderfs" min="0" max="100" displaytext="{tr(zapcldetailheaderfs)}">80</parameter> + <parameter type="int" name="zapcldetailshorttextfs" min="0" max="100" displaytext="{tr(zapcldetailshorttextfs)}">80</parameter> + <parameter type="int" name="zapcldetaildescfs" min="0" max="100" displaytext="{tr(zapcldetaildescfs)}">4</parameter> + <parameter type="separator" name="sepzapcockpitgl" displaytext="{tr(sepzapcockpitgl)}"/> + <parameter type="int" name="zapglgroupfs" min="0" max="100" displaytext="{tr(zapglgroupfs)}">40</parameter> + <parameter type="int" name="zapgcldetaildatetimefs" min="0" max="100" displaytext="{tr(zapgcldetaildatetimefs)}">80</parameter> + <parameter type="int" name="zapgcldetailheaderfs" min="0" max="100" displaytext="{tr(zapgcldetailheaderfs)}">80</parameter> + <parameter type="int" name="zapgcldetailshorttextfs" min="0" max="100" displaytext="{tr(zapgcldetailshorttextfs)}">80</parameter> + <parameter type="int" name="zapgcldetaildescfs" min="0" max="100" displaytext="{tr(zapgcldetaildescfs)}">4</parameter> + <parameter type="separator" name="sepzapcockpitchannelhint" displaytext="{tr(sepzapcockpitchannelhint)}"/> + <parameter type="int" name="zapchannelhintsheight" min="0" max="100" displaytext="{tr(zapchannelhintsheight)}">30</parameter> + <parameter type="int" name="zapchannelhintswidth" min="0" max="100" displaytext="{tr(zapchannelhintswidth)}">30</parameter> </submenu> <submenu name="subdisplayreplay" displaytext="{tr(subdisplayreplay)}"> <parameter type="int" name="replaytitlesize" min="0" max="100" displaytext="{tr(replaytitlesize)}">80</parameter> @@ -242,6 +270,118 @@ <trans lang="en_EN">Scroll EPG</trans> <trans lang="de_DE">EGP scrollen</trans> </token> + <token name="tr(sepzapcockpit)"> + <trans lang="en_EN">Settings Zapcockpit</trans> + <trans lang="de_DE">Einstellungen Zapcockpit</trans> + </token> + <token name="tr(sepzapcockpitdetail)"> + <trans lang="en_EN">Settings Zapcockpit detail view</trans> + <trans lang="de_DE">Einstellungen Zapcockpit Detailansicht</trans> + </token> + <token name="tr(sepzapcockpitcl)"> + <trans lang="en_EN">Settings Zapcockpit channel list</trans> + <trans lang="de_DE">Einstellungen Zapcockpit Kanalliste</trans> + </token> + <token name="tr(sepzapcockpitgl)"> + <trans lang="en_EN">Settings Zapcockpit channel groups list</trans> + <trans lang="de_DE">Einstellungen Kanalgruppen Liste</trans> + </token> + <token name="tr(sepzapcockpitchannelhint)"> + <trans lang="en_EN">Settings Zapcockpit channel hints</trans> + <trans lang="de_DE">Einstellungen Zapcockpit Kanal Hinweise</trans> + </token> + <token name="tr(fadetimezapcockpit)"> + <trans lang="en_EN">Fade time for zapcockpit elements [ms]</trans> + <trans lang="de_DE">Einblendzeit für Zapcockpit Elemente [ms]</trans> + </token> + <token name="tr(shifttimezapcockpit)"> + <trans lang="en_EN">Shift time for zapcockpit elements [ms]</trans> + <trans lang="de_DE">Einfahrzeit für Zapcockpit Elemente [ms]</trans> + </token> + <token name="tr(zapclchannelfs)"> + <trans lang="en_EN">Font size channel</trans> + <trans lang="de_DE">Schriftgröße Kanal</trans> + </token> + <token name="tr(zapclchannely)"> + <trans lang="en_EN">Vertical position channel</trans> + <trans lang="de_DE">Vertikale Position Kanal</trans> + </token> + <token name="tr(zapclpresentfs)"> + <trans lang="en_EN">Font size present event</trans> + <trans lang="de_DE">Schriftgröße aktuelle Sendung</trans> + </token> + <token name="tr(zapclpresenty)"> + <trans lang="en_EN">Vertical position present event</trans> + <trans lang="de_DE">Vertikale Position aktuelle Sendung</trans> + </token> + <token name="tr(zapclnextfs)"> + <trans lang="en_EN">Font size next event</trans> + <trans lang="de_DE">Schriftgröße nächste Sendung</trans> + </token> + <token name="tr(zapclnexty)"> + <trans lang="en_EN">Vertical position next event</trans> + <trans lang="de_DE">Vertikale Position nächste Sendung</trans> + </token> + <token name="tr(zapglgroupfs)"> + <trans lang="en_EN">Font size groups in channel group list</trans> + <trans lang="de_DE">Schriftgröße Gruppe in Kanalgruppen Liste</trans> + </token> + <token name="tr(zapdetaildatetimefs)"> + <trans lang="en_EN">Font size time</trans> + <trans lang="de_DE">Schriftgröße Zeit</trans> + </token> + <token name="tr(zapdetailheaderfs)"> + <trans lang="en_EN">Font size title</trans> + <trans lang="de_DE">Schriftgröße Titel</trans> + </token> + <token name="tr(zapdetailshorttextfs)"> + <trans lang="en_EN">Font size short text</trans> + <trans lang="de_DE">Schriftgröße Kurztext</trans> + </token> + <token name="tr(zapdetaildescfs)"> + <trans lang="en_EN">Font size description</trans> + <trans lang="de_DE">Schriftgröße Beschreibung</trans> + </token> + <token name="tr(zapcldetaildatetimefs)"> + <trans lang="en_EN">Font size time in channel list detail view</trans> + <trans lang="de_DE">Schriftgröße Zeit in Detailansicht Kanalliste</trans> + </token> + <token name="tr(zapcldetailheaderfs)"> + <trans lang="en_EN">Font size title in channel list detail view</trans> + <trans lang="de_DE">Schriftgröße Titel in Detailansicht Kanalliste</trans> + </token> + <token name="tr(zapcldetailshorttextfs)"> + <trans lang="en_EN">Font size short text in channel list detail view</trans> + <trans lang="de_DE">Schriftgröße Kurztext in Detailansicht Kanalliste</trans> + </token> + <token name="tr(zapcldetaildescfs)"> + <trans lang="en_EN">Font size description in channel list detail view</trans> + <trans lang="de_DE">Schriftgröße Beschreibung in Detailansicht Kanalliste</trans> + </token> + <token name="tr(zapgcldetaildatetimefs)"> + <trans lang="en_EN">Font size time in channel group list detail view</trans> + <trans lang="de_DE">Schriftgröße Zeit in Detailansicht Kanalgruppen Liste</trans> + </token> + <token name="tr(zapgcldetailheaderfs)"> + <trans lang="en_EN">Font size title in channel group list detail view</trans> + <trans lang="de_DE">Schriftgröße Titel in Detailansicht Kanalgruppen Liste</trans> + </token> + <token name="tr(zapgcldetailshorttextfs)"> + <trans lang="en_EN">Font size short text in channel group list detail view</trans> + <trans lang="de_DE">Schriftgröße Kurztext in Detailansicht Kanalgruppen Liste</trans> + </token> + <token name="tr(zapgcldetaildescfs)"> + <trans lang="en_EN">Font size description in channel group list detail view</trans> + <trans lang="de_DE">Schriftgröße Beschreibung in Detailansicht Kanalgruppen Liste</trans> + </token> + <token name="tr(zapchannelhintsheight)"> + <trans lang="en_EN">Height channel hints (% of screen height)</trans> + <trans lang="de_DE">Höhe Kanal Hinweise (% der Bildschirmhöhe)</trans> + </token> + <token name="tr(zapchannelhintswidth)"> + <trans lang="en_EN">Width channel hints (% of screen width)</trans> + <trans lang="de_DE">Breite Kanal Hinweise (% der Bildschirmbreite)</trans> + </token> <!-- recording display --> <token name="tr(replaytitlesize)"> <trans lang="en_EN">Font size title</trans> diff --git a/skins/estuary4vdr/svgtemplates/icons/folder.svg b/skins/estuary4vdr/svgtemplates/icons/folder.svg new file mode 100644 index 0000000..753999a --- /dev/null +++ b/skins/estuary4vdr/svgtemplates/icons/folder.svg @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Capa_1" + x="0px" + y="0px" + width="475.082px" + height="475.082px" + viewBox="0 0 475.082 475.082" + style="enable-background:new 0 0 475.082 475.082;" + xml:space="preserve" + inkscape:version="0.91 r13725" + sodipodi:docname="folder.svg"><metadata + id="metadata41"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs39" /><sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1017" + id="namedview37" + showgrid="false" + inkscape:zoom="0.49675635" + inkscape:cx="-13.084886" + inkscape:cy="237.541" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="Capa_1" /><g + id="g3" + style="fill:#{sdcol(icon)};fill-opacity:1"><path + d="M456.239,128.475c-12.56-12.562-27.597-18.842-45.11-18.842h-191.86v-9.136c0-17.511-6.283-32.548-18.843-45.107 c-12.562-12.562-27.6-18.846-45.111-18.846H63.953c-17.515,0-32.551,6.283-45.111,18.846C6.28,67.949,0,82.986,0,100.497v274.088 c0,17.508,6.28,32.545,18.842,45.104c12.562,12.565,27.6,18.849,45.111,18.849h347.175c17.514,0,32.551-6.283,45.11-18.849 c12.566-12.56,18.843-27.597,18.843-45.104V173.59C475.082,156.078,468.805,141.042,456.239,128.475z M438.536,374.585 c0,7.611-2.662,14.093-7.99,19.417c-5.328,5.325-11.8,7.987-19.417,7.987H63.953c-7.614,0-14.084-2.662-19.414-7.987 c-5.33-5.324-7.993-11.806-7.993-19.417V100.501c0-7.611,2.663-14.084,7.993-19.414c5.326-5.327,11.799-7.993,19.414-7.993h91.365 c7.614,0,14.087,2.663,19.417,7.993c5.327,5.33,7.993,11.803,7.993,19.414v18.274c0,7.616,2.664,14.083,7.994,19.414 c5.327,5.327,11.798,7.994,19.414,7.994h200.993c7.617,0,14.089,2.666,19.417,7.993c5.328,5.326,7.99,11.799,7.99,19.414V374.585 L438.536,374.585z" + id="path5" + style="fill:#{sdcol(icon)};fill-opacity:1" /></g><g + id="g7" /><g + id="g9" /><g + id="g11" /><g + id="g13" /><g + id="g15" /><g + id="g17" /><g + id="g19" /><g + id="g21" /><g + id="g23" /><g + id="g25" /><g + id="g27" /><g + id="g29" /><g + id="g31" /><g + id="g33" /><g + id="g35" /></svg>
\ No newline at end of file diff --git a/skins/estuary4vdr/svgtemplates/icons/folder_active.svg b/skins/estuary4vdr/svgtemplates/icons/folder_active.svg new file mode 100644 index 0000000..72dc8b5 --- /dev/null +++ b/skins/estuary4vdr/svgtemplates/icons/folder_active.svg @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Capa_1" + x="0px" + y="0px" + width="475.082px" + height="475.082px" + viewBox="0 0 475.082 475.082" + style="enable-background:new 0 0 475.082 475.082;" + xml:space="preserve" + inkscape:version="0.91 r13725" + sodipodi:docname="folder.svg"><metadata + id="metadata41"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs39" /><sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1017" + id="namedview37" + showgrid="false" + inkscape:zoom="0.49675635" + inkscape:cx="-13.084886" + inkscape:cy="237.541" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="Capa_1" /><g + id="g3" + style="fill:#{sdcol(iconactive)};fill-opacity:1"><path + d="M456.239,128.475c-12.56-12.562-27.597-18.842-45.11-18.842h-191.86v-9.136c0-17.511-6.283-32.548-18.843-45.107 c-12.562-12.562-27.6-18.846-45.111-18.846H63.953c-17.515,0-32.551,6.283-45.111,18.846C6.28,67.949,0,82.986,0,100.497v274.088 c0,17.508,6.28,32.545,18.842,45.104c12.562,12.565,27.6,18.849,45.111,18.849h347.175c17.514,0,32.551-6.283,45.11-18.849 c12.566-12.56,18.843-27.597,18.843-45.104V173.59C475.082,156.078,468.805,141.042,456.239,128.475z M438.536,374.585 c0,7.611-2.662,14.093-7.99,19.417c-5.328,5.325-11.8,7.987-19.417,7.987H63.953c-7.614,0-14.084-2.662-19.414-7.987 c-5.33-5.324-7.993-11.806-7.993-19.417V100.501c0-7.611,2.663-14.084,7.993-19.414c5.326-5.327,11.799-7.993,19.414-7.993h91.365 c7.614,0,14.087,2.663,19.417,7.993c5.327,5.33,7.993,11.803,7.993,19.414v18.274c0,7.616,2.664,14.083,7.994,19.414 c5.327,5.327,11.798,7.994,19.414,7.994h200.993c7.617,0,14.089,2.666,19.417,7.993c5.328,5.326,7.99,11.799,7.99,19.414V374.585 L438.536,374.585z" + id="path5" + style="fill:#{sdcol(iconactive)};fill-opacity:1" /></g><g + id="g7" /><g + id="g9" /><g + id="g11" /><g + id="g13" /><g + id="g15" /><g + id="g17" /><g + id="g19" /><g + id="g21" /><g + id="g23" /><g + id="g25" /><g + id="g27" /><g + id="g29" /><g + id="g31" /><g + id="g33" /><g + id="g35" /></svg>
\ No newline at end of file diff --git a/skins/estuary4vdr/themes/default/theme.xml b/skins/estuary4vdr/themes/default/theme.xml index f6eda58..0119815 100644 --- a/skins/estuary4vdr/themes/default/theme.xml +++ b/skins/estuary4vdr/themes/default/theme.xml @@ -11,6 +11,7 @@ <color name="menubackactive">FF12B2E7</color> <color name="menubackactivedark">FF0C4759</color> <color name="menumainheader">FF000000</color> + <color name="channelback">B0000000</color> <color name="messageback">D0000000</color> <color name="replayback">B0000000</color> <color name="fontdefault">FFFFFFFF</color> diff --git a/skins/estuary4vdr/xmlfiles/displaychannel.xml b/skins/estuary4vdr/xmlfiles/displaychannel.xml index a91e023..9fb46f9 100644 --- a/skins/estuary4vdr/xmlfiles/displaychannel.xml +++ b/skins/estuary4vdr/xmlfiles/displaychannel.xml @@ -132,6 +132,182 @@ </area> </scrapercontent> + <channelhints> + <area background="true" x="0" y="{areaheight}*0.75 - {numhints}*{areaheight}*{zapchannelhintsheight}/1000 + 1" width="{zapchannelhintswidth}*{areawidth}/100" height="{numhints}*{areaheight}*{zapchannelhintsheight}/1000" layer="1"> + <fill color="{channelback}" /> + </area> + <area x="0" y="{areaheight}*0.75 - {numhints}*{areaheight}*{zapchannelhintsheight}/1000" width="{zapchannelhintswidth}*{areawidth}/100" height="{numhints}*{areaheight}*{zapchannelhintsheight}/1000" layer="2"> + <loop name="hints" x="2%" y="0" width="96%%" orientation="vertical" columnwidth="100%" rowheight="{areaheight}/{numhints}" overflow="cut" > + <drawimage condition="{hints[channellogoexists]}" imagetype="channellogo" path="{hints[channelid]}" width="{rowheight}*1.5" height="{rowheight}" x="0" valign="center" /> + <drawtext x="{rowheight}*2" valign="center" width="{columnwidth} - {rowheight}*2.5" font="{regular}" fontsize="{rowheight}*0.8" color="{fontdefault}" text="{hints[channelnumber]}: {hints[channelname]}" /> + </loop> + </area> + </channelhints> + + <channeldetail clearondisplay="scrapercontent"> + <area background="true" x="5%" y="5%" width="90%" height="65%" layer="1"> + <fill color="{channelback}" /> + </area> + <area x="7%" y="7%" width="41%" height="5%" layer="2"> + <drawtext x="0" valign="center" fontsize="{zapdetaildatetimefs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currentstart} - {currentstop}" /> + </area> + <areascroll condition="{ismovie}||{isseries}" scrollelement="title" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="7%" y="10%" width="41%" height="7%" layer="3"> + <drawtext name="title" x="0" valign="center" fontsize="{zapdetailheaderfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currenttitle}" /> + </areascroll> + <areascroll condition="{ismovie}||{isseries}" scrollelement="shorttext" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="7%" y="15%" width="41%" height="6%" layer="3"> + <drawtext name="shorttext" x="0" valign="center" fontsize="{zapdetailshorttextfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currentshorttext}" /> + </areascroll> + <areascroll condition="{ismovie}||{isseries}" orientation="vertical" scrollelement="desc" mode="forthandback" delay="5000" scrollspeed="medium" x="7%" y="21%" width="41%" height="47%" layer="2"> + <drawtextbox name="desc" x="0" y="0" width="96%" font="{regular}" fontsize="{zapdetaildescfs}*{areaheight}/100" color="{fontdefault}" text="{currentdescription}" /> + </areascroll> + <area condition="{ismovie}" x="52%" y="7%" width="41%" height="30%" layer="1"> + <drawimage imagetype="image" path="{seriesposter1path}" align="center" valign="center" width="100%" height="100%" /> + </area> + <area condition="{isseries}" x="52%" y="7%" width="41%" height="30%" layer="1"> + <drawimage imagetype="image" path="{seriesbanner1path}" align="center" valign="center" width="100%" height="100%" /> + </area> + <areascroll condition="{ismovie}||{isseries}" orientation="vertical" scrollelement="actors" mode="forthandback" delay="5000" scrollspeed="medium" x="52%" y="39%" width="41%" height="30%" layer="2"> + <loop name="actors" x="0" y="0" width="100%" orientation="horizontal" columnwidth="{areawidth}/5" rowheight="{areawidth}/5*1.5" overflow="linewrap" > + <drawimage name="thumb" imagetype="image" path="{actors[thumb]}" x="10" y="0" width="{columnwidth}-20" height="{columnwidth} * {actors[thumbheight]} / {actors[thumbwidth]} - 40 * {actors[thumbheight]} / {actors[thumbwidth]}"/> + <drawtext align="center" y="{height(thumb)} + 10" width="{columnwidth}" name="actorname" font="{regular}" fontsize="6%" color="{fontdefault}" text="{actors[name]}" /> + <drawtext align="center" y="{height(thumb)} + 10 + {height(actorname)}" width="{columnwidth}" font="{regular}" fontsize="6%" color="{fontdefault}" text="{actors[role]}" /> + </loop> + </areascroll> + <areascroll condition="not{ismovie}++not{isseries}" scrollelement="title" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="7%" y="10%" width="86%" height="7%" layer="3"> + <drawtext name="title" x="0" valign="center" fontsize="{zapdetailheaderfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currenttitle}" /> + </areascroll> + <areascroll condition="not{ismovie}++not{isseries}" scrollelement="shorttext" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="7%" y="15%" width="86%" height="6%" layer="3"> + <drawtext name="shorttext" x="0" valign="center" fontsize="{zapdetailshorttextfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currentshorttext}" /> + </areascroll> + <areascroll condition="not{ismovie}++not{isseries}" orientation="vertical" scrollelement="desc" mode="forthandback" delay="5000" scrollspeed="medium" x="7%" y="21%" width="86%" height="47%" layer="2"> + <drawtextbox name="desc" x="0" y="0" width="96%" font="{regular}" fontsize="{zapdetaildescfs}*{areaheight}/100" color="{fontdefault}" text="{currentdescription}" /> + </areascroll> + </channeldetail> + + <channellistback clearondisplay="all" fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" shifttype="left"> + <area x="0" y="0" width="30%" height="100%" layer="3"> + <fill color="{channelback}" /> + </area> + </channellistback> + + <channellist x="0" y="0" orientation="vertical" width="30%" height="100%" align="center" numlistelements="16" fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" shifttype="left"> + <listelement> + <area x="0" width="100%" layer="4"> + <drawrectangle condition="not{current}" x="0" y="0" width="100%" height="100%" color="{menuback}" /> + <drawrectangle condition="not{current}" x="0" y="{areaheight}-1" width="100%" height="1" color="{menubackline}" /> + <drawrectangle condition="{current}" x="0" y="0" width="100%" height="100%" color="{menubackactive}" /> + </area> + <area x="1%" width="25%" layer="5"> + <drawimage name="logo" imagetype="channellogo" path="{channelid}" x="0" width="100%" height="100%" valign="center" /> + </area> + <area condition="not{current}" x="26%" width="73%" layer="4"> + <drawtext x="0" y="{zapclchannely}*{areaheight}/100" font="{regular}" fontsize="{zapclchannelfs}*{areaheight}/100" color="{fontdefault}" text="{number} {name}" /> + <drawtext x="0" y="{zapclpresenty}*{areaheight}/100" font="{regular}" fontsize="{zapclpresentfs}*{areaheight}/100" color="{fontdefault}" text="+{presenteventremaining}min: {presenteventtitle}" /> + <drawtext x="0" y="{zapclnexty}*{areaheight}/100" font="{regular}" fontsize="{zapclnextfs}*{areaheight}/100" color="{fontdefault}" text="{nexteventstart} {nexteventstop}: {nexteventtitle}" /> + </area> + <area condition="{current}" x="26%" width="73%" layer="4"> + <drawtext x="0" y="{zapclchannely}*{areaheight}/100" font="{regular}" fontsize="{zapclchannelfs}*{areaheight}/100" color="{fontmenuactive}" text="{number} {name}" /> + <drawtext x="0" y="{zapclpresenty}*{areaheight}/100" font="{regular}" fontsize="{zapclpresentfs}*{areaheight}/100" color="{fontmenuactive}" text="+{presenteventremaining}min: {presenteventtitle}" /> + <drawtext x="0" y="{zapclnexty}*{areaheight}/100" font="{regular}" fontsize="{zapclnextfs}*{areaheight}/100" color="{fontmenuactive}" text="{nexteventstart} {nexteventstop}: {nexteventtitle}" /> + </area> + </listelement> + </channellist> + + <channellistdetail fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" startx="{areawidth}*0.3 - {areawidth}*0.6" starty="5%"> + <area x="30%" y="5%" width="66%" height="90%" layer="1"> + <fill color="{channelback}" /> + </area> + <area x="32%" y="6%" width="62%" height="5%" layer="2"> + <drawtext x="0" valign="center" fontsize="{zapcldetaildatetimefs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currentstart} - {currentstop}" /> + </area> + <areascroll scrollelement="title" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="32%" y="10%" width="62%" height="7%" layer="3"> + <drawtext name="title" x="0" valign="center" fontsize="{zapcldetailheaderfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currenttitle}" /> + </areascroll> + <areascroll scrollelement="shorttext" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="32%" y="16%" width="62%" height="6%" layer="3"> + <drawtext name="shorttext" x="0" valign="center" fontsize="{zapcldetailshorttextfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currentshorttext}" /> + </areascroll> + <areascroll orientation="vertical" scrollelement="desc" mode="forthandback" delay="5000" scrollspeed="medium" x="32%" y="22%" width="62%" height="71%" layer="2"> + <drawtextbox name="desc" x="0" y="0" width="100%" font="{regular}" fontsize="{zapcldetaildescfs}*{areaheight}/100" color="{fontdefault}" text="{currentdescription}" /> + </areascroll> + </channellistdetail> + + <grouplistback fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" shifttype="right" clearondisplay="all"> + <area x="70%" y="0" width="30%" height="100%" layer="4"> + <fill color="{channelback}" /> + </area> + </grouplistback> + + <grouplist x="70%" y="0" orientation="vertical" width="30%" height="100%" align="center" numlistelements="12" fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" shifttype="right"> + <listelement> + <area x="0" width="100%" layer="5"> + <drawrectangle condition="not{current}" x="0" y="0" width="100%" height="100%" color="{menuback}" /> + <drawrectangle condition="not{current}" x="0" y="{areaheight}-1" width="100%" height="1" color="{menubackline}" /> + <drawrectangle condition="{current}" x="0" y="0" width="100%" height="100%" color="{menubackactive}" /> + </area> + <area x="0" width="24%" layer="5"> + <drawimage condition="not{current}" imagetype="icon" path="folder" align="center" valign="center" width="90%" height="90%" /> + <drawimage condition="{current}" imagetype="icon" path="folder_active" align="center" valign="center" width="90%" height="90%" /> + </area> + <area x="0" width="24%" layer="6"> + <drawtext condition="not{current}" align="center" y="38%" fontsize="40%" font="{regular}" color="{fontdefault}" text="{numchannels}" /> + <drawtext condition="{current}" align="center" y="38%" fontsize="40%" font="{regular}" color="{fontmenuactive}" text="{numchannels}" /> + </area> + <areascroll condition="not{current}" scrollelement="groupname" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="25%" width="74%" layer="5"> + <drawtext name="groupname" x="0" valign="center" fontsize="{zapglgroupfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{groupname}" /> + </areascroll> + <areascroll condition="{current}" scrollelement="groupname" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="25%" width="74%" layer="5"> + <drawtext name="groupname" x="0" valign="center" fontsize="{zapglgroupfs}*{areaheight}/100" font="{regular}" color="{fontmenuactive}" text="{groupname}" /> + </areascroll> + </listelement> + </grouplist> + + <groupchannellistback fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" startx="70%" starty="3%"> + <area x="40%" y="3%" width="30%" height="94%" layer="1"> + <fill color="{channelback}" /> + </area> + </groupchannellistback> + + <groupchannellist x="40%" y="3%" orientation="vertical" width="30%" height="94%" align="center" numlistelements="14" fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" startx="70%" starty="3%"> + <listelement> + <area x="0" width="100%" layer="2"> + <drawrectangle condition="not{current}" x="0" y="0" width="100%" height="100%" color="{menuback}" /> + <drawrectangle condition="not{current}" x="0" y="{areaheight}-1" width="100%" height="1" color="{menubackline}" /> + <drawrectangle condition="{current}" x="0" y="0" width="100%" height="100%" color="{menubackactive}" /> + </area> + <area x="1%" width="25%" layer="3"> + <drawimage name="logo" imagetype="channellogo" path="{channelid}" x="0" width="100%" height="100%" valign="center" /> + </area> + <area condition="not{current}" x="26%" width="73%" layer="3"> + <drawtext x="0" y="{zapclchannely}*{areaheight}/100" font="{regular}" fontsize="{zapclchannelfs}*{areaheight}/100" color="{fontdefault}" text="{number} {name}" /> + <drawtext x="0" y="{zapclpresenty}*{areaheight}/100" font="{regular}" fontsize="{zapclpresentfs}*{areaheight}/100" color="{fontdefault}" text="+{presenteventremaining}min: {presenteventtitle}" /> + <drawtext x="0" y="{zapclnexty}*{areaheight}/100" font="{regular}" fontsize="{zapclnextfs}*{areaheight}/100" color="{fontdefault}" text="{nexteventstart} {nexteventstop}: {nexteventtitle}" /> + </area> + <area condition="{current}" x="26%" width="73%" layer="3"> + <drawtext x="0" y="{zapclchannely}*{areaheight}/100" font="{regular}" fontsize="{zapclchannelfs}*{areaheight}/100" color="{fontmenuactive}" text="{number} {name}" /> + <drawtext x="0" y="{zapclpresenty}*{areaheight}/100" font="{regular}" fontsize="{zapclpresentfs}*{areaheight}/100" color="{fontmenuactive}" text="+{presenteventremaining}min: {presenteventtitle}" /> + <drawtext x="0" y="{zapclnexty}*{areaheight}/100" font="{regular}" fontsize="{zapclnextfs}*{areaheight}/100" color="{fontmenuactive}" text="{nexteventstart} {nexteventstop}: {nexteventtitle}" /> + </area> + </listelement> + </groupchannellist> + + <groupchannellistdetail fadetime="{fadetimezapcockpit}" shifttime="{shifttimezapcockpit}" shiftmode="slowed" startx="40%" starty="6%"> + <area x="2%" y="6%" width="38%" height="88%" layer="1"> + <fill color="{channelback}" /> + </area> + <area x="4%" y="6%" width="36%" height="5%" layer="2"> + <drawtext x="0" valign="center" fontsize="{zapgcldetaildatetimefs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currentstart} - {currentstop}" /> + </area> + <areascroll scrollelement="title" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="4%" y="10%" width="36%" height="7%" layer="3"> + <drawtext name="title" x="0" valign="center" fontsize="{zapgcldetailheaderfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currenttitle}" /> + </areascroll> + <areascroll scrollelement="shorttext" mode="forthandback" orientation="horizontal" delay="1000" scrollspeed="medium" x="4%" y="16%" width="36%" height="6%" layer="3"> + <drawtext name="shorttext" x="0" valign="center" fontsize="{zapgcldetailshorttextfs}*{areaheight}/100" font="{regular}" color="{fontdefault}" text="{currentshorttext}" /> + </areascroll> + <areascroll orientation="vertical" scrollelement="desc" mode="forthandback" delay="5000" scrollspeed="medium" x="4%" y="22%" width="36%" height="70%" layer="2"> + <drawtextbox name="desc" x="0" y="0" width="100%" font="{regular}" fontsize="{zapgcldetaildescfs}*{areaheight}/100" color="{fontdefault}" text="{currentdescription}" /> + </areascroll> + </groupchannellistdetail> + <time> <area x="80%" y="80%" width="20%" height="15%" layer="2"> <drawtext name="clock" x="11%" valign="center" fontsize="70%" font="{digital}" color="{fontdefault}" text="{hour}:{printf('%02d', min)}" /> diff --git a/skinskeleton/xmlfiles/displaychannel.xml b/skinskeleton/xmlfiles/displaychannel.xml index 8bad9f7..bf2ddaa 100644 --- a/skinskeleton/xmlfiles/displaychannel.xml +++ b/skinskeleton/xmlfiles/displaychannel.xml @@ -181,6 +181,195 @@ <scrapercontent> </scrapercontent> + <!-- Available Variables channelhints: + {numhints} number of hints to display + {hints[]} array with available channel hints + {hints[channelnumber]} number of current channel + {hints[channelname]} name of current channel + {hints[channelid]} id of current channel + {hints[channellogoexists]} true if channel logo exists + --> + <channelhints> + </channelhints> + + <!-- Available Variables channeldetail: + {channelname} name of current channel + {channelnumber} number of current channel + {currenttitle} title of current event + {currentshorttext} short text of current event + {currentdescription} description of current event + {currentstart} start time of current event in hh:mm + {currentstop} end time of current event in hh:mm + {currentduration} duration of current Schedule in min + {currentdurationhours} duration, full hours + {currentdurationminutes} duration, rest of minutes + {currentelapsed} elapsed time of current Schedule in min + {currentremaining} remaining time of current Schedule in min + {nexttitle} title of next event + {nextshorttext} short text of next event + {nextdescription} description of next event + {nextstart} start time of next event in hh:mm + {nextstop} end time of next event in hh:mm + {nextduration} duration of next Schedule in min + {nextdurationhours} duration, full hours + {nextdurationminutes} duration, rest of minutes + + {ismovie} true if current event is scraped as a movie + Available variables for movies: + {movietitle} movie title from themoviedb + {movieoriginalTitle} movie original title from themoviedb + {movietagline} movie tagline from themoviedb + {movieoverview} movie overview from themoviedb + {movieadult} true if movie is rated as adult + {moviebudget} movie budget from themoviedb in $ + {movierevenue} movie revenue from themoviedb in $ + {moviegenres} movie genres from themoviedb + {moviehomepage} movie homepage from themoviedb + {moviereleasedate} movie release date from themoviedb + {movieruntime} movie runtime from themoviedb + {moviepopularity} movie popularity from themoviedb + {movievoteaverage} movie vote average from themoviedb + {posterwidth} width of scraped poster + {posterheight} height of scraped poster + {posterpath} absolute path of scraped poster + {fanartwidth} width of scraped fanart + {fanartheight} height of scraped fanart + {fanartpath} absolute path of scraped fanart + {movieiscollection} true if movie is part of a collection + {moviecollectionName} name of movie collection + {collectionposterwidth} width of scraped collection poster + {collectionposterheight} height of scraped collection poster + {collectionposterpath} absolute path of scraped collection poster + {collectionfanartwidth} width of scraped collection fanart + {collectionfanartheight} height of scraped collection fanart + {collectionfanartpath} absolute path of scraped collection fanart + {actors[]} array with movie actors + {actors[name]} real name of actor + {actors[role]} actor role + {actors[thumb]} absolute path of scraped actor thumb + {actors[thumbwidth]} width of scraped actor thumb + {actors[thumbheight]} height of scraped actor thumb + + {isseries} true if current event is scraped as a series + Available variables for series: + {seriesname} name of series + {seriesoverview} series overview + {seriesfirstaired} first aired date + {seriesnetwork} network which produces series + {seriesgenre} series genre + {seriesrating} series thetvdb rating + {seriesstatus} status of series (running / finished) + {episodetitle} title of episode + {episodenumber} number of episode + {episodeseason} season of episode + {episodefirstaired} first aired date of episode + {episodegueststars} guest stars of episode + {episodeoverview} episode overview + {episoderating} user rating for episode + {episodeimagewidth} episode image width + {episodeimageheight} episode image height + {episodeimagepath} episode image path + {seasonposterwidth} episode season poster width + {seasonposterheight} episode season poster height + {seasonposterpath} episode season poster path + {seriesposter1width} width of 1st poster + {seriesposter1height} height of 1st poster + {seriesposter1path} path of 1st poster + {seriesposter2width} width of 2nd poster + {seriesposter2height} height of 2nd poster + {seriesposter2path} path of 2nd poster + {seriesposter3width} width of 3rd poster + {seriesposter3height} height of 3rd poster + {seriesposter3path} path of 3rd poster + {seriesfanart1width} width of 1st fanart + {seriesfanart1height} height of 1st fanart + {seriesfanart1path} path of 1st fanart + {seriesfanart2width} width of 2nd fanart + {seriesfanart2height} height of 2nd fanart + {seriesfanart2path} path of 2nd fanart + {seriesfanart3width} width of 3rd fanart + {seriesfanart3height} height of 3rd fanart + {seriesfanart3path} path of 3rd fanart + {seriesbanner1width} width of 1st banner + {seriesbanner1height} height of 1st banner + {seriesbanner1path} path of 1st banner + {seriesbanner2width} width of 2nd banner + {seriesbanner2height} height of 2nd banner + {seriesbanner2path} path of 2nd banner + {seriesbanner3width} width of 3rd banner + {seriesbanner3height} height of 3rd banner + {seriesbanner3path} path of 3rd fanart + {actors[]} array with movie actors + {actors[name]} real name of actor + {actors[role]} actor role + {actors[thumb]} absolute path of scraped actor thumb + {actors[thumbwidth]} width of scraped actor thumb + {actors[thumbheight]} height of scraped actor thumb + --> + <channeldetail> + </channeldetail> + + <!-- Available Variables channellistback: + --> + <channellistback> + </channellistback> + + <!-- Available Variables channellist: + {nummenuitem} number in list of currently displayed channellist item + {current} true if currently displayed item is active + {name} name of channel + {number} number of channel + {channelid} if of channel + {channellogoexists} true if channel logo exists + {presenteventtitle} title of present event + {presenteventstart} start of present event in hh:mm + {presenteventstop} end of present event in hh:mm + {presenteventelapsed} elapsed minutes of present event + {presenteventremaining} remaining minutes of present event + {nexteventtitle} title of next event + {nexteventstart} start time of next event in hh:mm + {nexteventstop} end time of next event in hh:mm + --> + <channellist> + </channellist> + + <!-- Available Variables channellistdetail: + see <channeldetail> tokens + --> + <channellistdetail> + </channellistdetail> + + <!-- Available Variables grouplistback: + --> + <grouplistback> + </grouplistback> + + <!-- Available Variables grouplist: + {nummenuitem} number in list of currently displayed channelgrouplist item + {current} true if currently displayed item is active + {groupname} name of displayed channel group + {numchannels} number of channels in channel group + --> + <grouplist> + </grouplist> + + <!-- Available Variables groupchannellistback: + --> + <groupchannellistback> + </groupchannellistback> + + <!-- Available Variables groupchannellist: + see <channellist> tokens + --> + <groupchannellist> + </groupchannellist> + + <!-- Available Variables groupchannellistdetail: + see <channeldetail> tokens + --> + <groupchannellistdetail> + </groupchannellistdetail> + <!-- Available Variables datetime: {time} time in hh:mm {day} day in digits |