diff options
-rw-r--r-- | Directory.cpp | 7 | ||||
-rw-r--r-- | Directory.h | 8 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | MediaContainer.cpp | 21 | ||||
-rw-r--r-- | MediaContainer.h | 5 | ||||
-rw-r--r-- | PVideo.cpp | 33 | ||||
-rw-r--r-- | PVideo.h | 10 | ||||
-rw-r--r-- | PlexServer.cpp | 5 | ||||
-rw-r--r-- | PlexServer.h | 19 | ||||
-rw-r--r-- | Plexservice.cpp | 12 | ||||
-rw-r--r-- | Plexservice.h | 1 | ||||
-rw-r--r-- | SubscriptionManager.cpp | 10 | ||||
-rw-r--r-- | browserGrid.cpp | 29 | ||||
-rw-r--r-- | browserGrid.h | 11 | ||||
-rw-r--r-- | hlsPlayer.cpp | 6 | ||||
-rw-r--r-- | hlsPlayerControl.cpp | 2 | ||||
-rw-r--r-- | pictureCache.cpp | 146 | ||||
-rw-r--r-- | pictureCache.h | 67 | ||||
-rw-r--r-- | plex.cpp | 10 | ||||
-rw-r--r-- | plexSdOsd.cpp | 117 | ||||
-rw-r--r-- | plexSdOsd.h | 10 | ||||
-rw-r--r-- | plexgdm.cpp | 19 | ||||
-rw-r--r-- | plexgdm.h | 1 | ||||
-rw-r--r-- | skins/blackhole/xmlfiles/plug-plex-root.xml | 34 | ||||
-rw-r--r-- | viewGridNavigator.cpp | 32 | ||||
-rw-r--r-- | viewGridNavigator.h | 16 | ||||
-rw-r--r-- | viewHeader.cpp | 13 | ||||
-rw-r--r-- | viewHeader.h | 3 |
28 files changed, 557 insertions, 91 deletions
diff --git a/Directory.cpp b/Directory.cpp index 5102015..e62714f 100644 --- a/Directory.cpp +++ b/Directory.cpp @@ -5,8 +5,9 @@ namespace plexclient { -Directory::Directory(Poco::XML::Node* pNode, MediaContainer* parent) +Directory::Directory(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent) { + m_pServer = Server; if(Poco::icompare(pNode->nodeName(), "Directory") == 0) { Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pNode->attributes(); @@ -41,9 +42,9 @@ std::string Directory::GetTitle() } } -void Directory::AddTokens(std::shared_ptr<cViewGrid> grid) +void Directory::AddTokens(std::shared_ptr<cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached) { - grid->ClearTokens(); + if(clear) grid->ClearTokens(); grid->AddStringToken("title", m_sTitle); } diff --git a/Directory.h b/Directory.h index b4a78d1..f25de85 100644 --- a/Directory.h +++ b/Directory.h @@ -17,6 +17,7 @@ #include "XmlObject.h" #include "MediaContainer.h" #include "viewGridNavigator.h" +#include "PlexServer.h" using Poco::XML::DOMParser; using Poco::XML::Document; @@ -33,7 +34,7 @@ class MediaContainer; class Directory: private XmlObject, public cGridElement { public: - Directory(Poco::XML::Node* pNode, MediaContainer* parent); + Directory(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent); public: bool m_bAllowSync; @@ -51,10 +52,11 @@ public: Poco::Timestamp m_tCreatedAt; std::string m_sKey; MediaType m_eType; - + PlexServer* m_pServer; + virtual std::string GetTitle(); // gridElement - virtual void AddTokens(std::shared_ptr<cViewGrid> grid); + virtual void AddTokens(std::shared_ptr<cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL); }; } @@ -92,6 +92,7 @@ OBJS = $(PLUGIN).o \ viewGridNavigator.o \ browserGrid.o \ viewHeader.o \ + pictureCache.o \ libskindesigner/skindesignerosdbase.o \ libskindesigner/osdelements.o \ diff --git a/MediaContainer.cpp b/MediaContainer.cpp index 6fa92f6..d567dec 100644 --- a/MediaContainer.cpp +++ b/MediaContainer.cpp @@ -1,9 +1,11 @@ #include "MediaContainer.h" +#include "pictureCache.h" namespace plexclient { -MediaContainer::MediaContainer(std::istream* response, PlexServer Server) +MediaContainer::MediaContainer(std::istream* response, PlexServer* Server) { + m_pServer = Server; try { InputSource src(*response); DOMParser parser; @@ -32,9 +34,9 @@ MediaContainer::MediaContainer(std::istream* response, PlexServer Server) pAttribs->release(); } else if(Poco::icompare(pNode->nodeName(), "Directory") == 0) { - m_vDirectories.push_back(Directory(pNode, this)); + m_vDirectories.push_back(Directory(pNode, m_pServer, this)); } else if(Poco::icompare(pNode->nodeName(), "Video") == 0) { - m_vVideos.push_back(Video(pNode, Server, this)); + m_vVideos.push_back(Video(pNode, m_pServer, this)); } pNode = it.nextNode(); @@ -45,4 +47,17 @@ MediaContainer::MediaContainer(std::istream* response, PlexServer Server) } } +void MediaContainer::PreCache() +{ + bool foo; + for(std::vector<plexclient::Video>::iterator it = m_vVideos.begin(); it != m_vVideos.end(); ++it) { + if(!it->m_sThumb.empty()) cPictureCache::GetInstance().GetPath(it->ThumbUri(), 1280, 720, foo); + if(!it->m_sArt.empty()) cPictureCache::GetInstance().GetPath(it->ArtUri(), 1920, 1080, foo); + } +/* for(std::vector<plexclient::Directory>::iterator it = m_vDirectories.begin(); it != m_vDirectories.end(); ++it) { + if(!it->m_sThumb.empty()) cPictureCache::GetInstance().GetPath(it->ThumbUri(), 1280, 720, foo); + if(!it->m_sArt.empty()) cPictureCache::GetInstance().GetPath(it->ArtUri(), 1920, 1080, foo); + }*/ +} + } diff --git a/MediaContainer.h b/MediaContainer.h index 967700f..9f7ca89 100644 --- a/MediaContainer.h +++ b/MediaContainer.h @@ -36,7 +36,7 @@ class Directory; class MediaContainer: XmlObject { public: - MediaContainer(std::istream *response, PlexServer Server); + MediaContainer(std::istream *response, PlexServer* Server); protected: @@ -59,6 +59,9 @@ public: int m_iSize; std::string m_sSummary; int m_iParentIndex; + PlexServer* m_pServer; + + void PreCache(); }; } @@ -2,18 +2,20 @@ #include <Poco/Format.h> #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> +#include <functional> #include <vdr/tools.h> #include "PlexHelper.h" +#include "pictureCache.h" namespace plexclient { -Video::Video(Poco::XML::Node* pNode, PlexServer Server, MediaContainer* parent) +Video::Video(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent) { m_iMyPlayOffset = 0; m_lViewoffset = 0; - m_Server = Server; + m_pServer = Server; Parse(pNode); if (m_iParentIndex < 0) { @@ -24,7 +26,7 @@ Video::Video(Poco::XML::Node* pNode, PlexServer Server, MediaContainer* parent) bool Video::UpdateFromServer() { try { - Poco::URI fileuri(Poco::format("%s/library/metadata/%d", m_Server.GetUri(), m_iRatingKey)); + Poco::URI fileuri(Poco::format("%s/library/metadata/%d", m_pServer->GetUri(), m_iRatingKey)); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, fileuri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); PlexHelper::AddHttpHeader(request); @@ -138,7 +140,7 @@ std::string Video::GetTitle() bool Video::SetStream(Stream* stream) { try { - Poco::Net::HTTPClientSession session(m_Server.GetIpAdress(), m_Server.GetPort()); + Poco::Net::HTTPClientSession session(m_pServer->GetIpAdress(), m_pServer->GetPort()); std::string uri = Poco::format("/library/parts/%d?%s", m_Media.m_iPartId, stream->GetSetStreamQuery()); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, uri); @@ -161,7 +163,7 @@ bool Video::SetStream(Stream* stream) bool Video::SetUnwatched() { try { - Poco::Net::HTTPClientSession session(m_Server.GetIpAdress(), m_Server.GetPort()); + Poco::Net::HTTPClientSession session(m_pServer->GetIpAdress(), m_pServer->GetPort()); std::string uri = Poco::format("/:/unscrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); @@ -184,7 +186,7 @@ bool Video::SetUnwatched() bool Video::SetWatched() { try { - Poco::Net::HTTPClientSession session(m_Server.GetIpAdress(), m_Server.GetPort()); + Poco::Net::HTTPClientSession session(m_pServer->GetIpAdress(), m_pServer->GetPort()); std::string uri = Poco::format("/:/scrobble?key=%d&identifier=com.plexapp.plugins.library", m_iRatingKey); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); @@ -204,11 +206,26 @@ bool Video::SetWatched() } } -void Video::AddTokens(std::shared_ptr<cViewGrid>grid) +void Video::AddTokens(std::shared_ptr<cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached) { - grid->ClearTokens(); + if(clear) grid->ClearTokens(); grid->AddStringToken("title", m_sTitle); + grid->AddIntToken("ismovie", 1); + bool cached = false; + cPictureCache::GetInstance().GetPath(ArtUri(), 1920, 1080, cached); + std::string thumb = cPictureCache::GetInstance().GetPath(ThumbUri(), 1280, 720, cached, OnCached, this); + if (cached) grid->AddStringToken("thumb", thumb); } +std::string Video::ArtUri() +{ + return m_pServer->GetUri() + m_sArt; +} + +std::string Video::ThumbUri() +{ + return m_pServer->GetUri() + m_sThumb; +} } // Namespace + @@ -41,7 +41,7 @@ private: void Parse(Poco::XML::Node* pNode); public: - Video(Poco::XML::Node* pNode, PlexServer Server, MediaContainer* parent); + Video(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent); Video() {}; public: @@ -70,7 +70,7 @@ public: std::vector<std::string> m_vRole; std::string m_sCollection; Media m_Media; - PlexServer m_Server; + PlexServer* m_pServer; int m_iMyPlayOffset; int m_iIndex; int m_iParentIndex; @@ -80,9 +80,11 @@ public: bool UpdateFromServer(); bool SetWatched(); bool SetUnwatched(); - + std::string ThumbUri(); + std::string ArtUri(); + // gridElement - virtual void AddTokens(std::shared_ptr<cViewGrid> grid); + virtual void AddTokens(std::shared_ptr<cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL); }; } diff --git a/PlexServer.cpp b/PlexServer.cpp index b413d7d..70fc1b7 100644 --- a/PlexServer.cpp +++ b/PlexServer.cpp @@ -6,6 +6,11 @@ namespace plexclient PlexServer::PlexServer(std::string data, std::string ip) { + ParseData(data, ip); +} + +void PlexServer::ParseData(std::string data, std::string ip) +{ m_sIpAddress = ip; std::istringstream f(data); std::string s; diff --git a/PlexServer.h b/PlexServer.h index 3879878..8f1b23a 100644 --- a/PlexServer.h +++ b/PlexServer.h @@ -16,14 +16,12 @@ namespace plexclient { - + class PlexServer { -public: - PlexServer(std::string data, std::string ip); - PlexServer(std::string ip, int port); - PlexServer() {}; + friend class plexgdm; +public: int GetMaster() const { return m_nMaster; } @@ -58,11 +56,18 @@ public: const std::string& GetIpAdress() const { return m_sIpAddress; } - + std::string GetUri(); - + void DiscoverSettings(); +protected: + PlexServer(std::string data, std::string ip); + PlexServer(std::string ip, int port); + PlexServer() {}; + + void ParseData(std::string data, std::string ip); + private: std::string m_sDiscovery; diff --git a/Plexservice.cpp b/Plexservice.cpp index 41f9579..b86dac3 100644 --- a/Plexservice.cpp +++ b/Plexservice.cpp @@ -1,6 +1,7 @@ #include "Plexservice.h" #include "PlexHelper.h" +#include "plexgdm.h" #include <memory> namespace plexclient @@ -112,7 +113,7 @@ std::shared_ptr<MediaContainer> Plexservice::GetSection(std::string section, boo dsyslog("[plex] URI: http://%s:%d%s", pServer->GetIpAdress().c_str(), pServer->GetPort(), uri.c_str()); - std::shared_ptr<MediaContainer> pAllsections(new MediaContainer(&rs, *pServer)); + std::shared_ptr<MediaContainer> pAllsections(new MediaContainer(&rs, pServer)); session.abort(); return pAllsections; @@ -135,6 +136,11 @@ std::shared_ptr<MediaContainer> Plexservice::GetLastSection(bool current) return NULL; } +bool Plexservice::IsRoot() +{ + return m_vUriStack.size() <= 1; +} + std::unique_ptr<Poco::Net::HTTPRequest> Plexservice::CreateRequest(std::string path) { std::unique_ptr<Poco::Net::HTTPRequest> pRequest = std::unique_ptr<Poco::Net::HTTPRequest>(new Poco::Net::HTTPRequest(Poco::Net::HTTPRequest::HTTP_GET, @@ -164,7 +170,7 @@ MediaContainer Plexservice::GetMediaContainer(std::string fullUrl) Poco::Net::HTTPResponse response; std::istream &rs = session.receiveResponse(response); - MediaContainer allsections(&rs, PlexServer(fileuri.getHost(), fileuri.getPort())); + MediaContainer allsections(&rs, plexgdm::GetInstance().GetServer(fileuri.getHost(), fileuri.getPort())); session.abort(); return allsections; @@ -180,7 +186,7 @@ std::string Plexservice::encode(std::string message) std::string Plexservice::GetUniversalTranscodeUrl(Video* video, int offset, PlexServer* server) { - PlexServer* pSrv = server ? server : &video->m_Server; + PlexServer* pSrv = server ? server : video->m_pServer; std::stringstream params; params << "/video/:/transcode/universal/start.m3u8?"; params << "path=" << encode(pSrv->GetUri() + video->m_sKey); diff --git a/Plexservice.h b/Plexservice.h index e30e346..4635ccd 100644 --- a/Plexservice.h +++ b/Plexservice.h @@ -45,6 +45,7 @@ public: void DisplaySections(); std::shared_ptr<MediaContainer> GetSection(std::string section, bool putOnStack = true); std::shared_ptr<MediaContainer> GetLastSection(bool current = false); + bool IsRoot(); void GetAuthDetails(); void Authenticate(); PlexServer* GetServer(); diff --git a/SubscriptionManager.cpp b/SubscriptionManager.cpp index 033776a..ce82358 100644 --- a/SubscriptionManager.cpp +++ b/SubscriptionManager.cpp @@ -54,8 +54,8 @@ void SubscriptionManager::NotifyServer() std::string server; int port; if(pVid) { - server = pVid->m_Server.GetIpAdress(); - port = pVid->m_Server.GetPort(); + server = pVid->m_pServer->GetIpAdress(); + port = pVid->m_pServer->GetPort(); } else if ( plexgdm::GetInstance().GetPlexservers().size() > 0) { server = plexgdm::GetInstance().GetPlexservers().at(0).GetIpAdress(); port = plexgdm::GetInstance().GetPlexservers().at(0).GetPort(); @@ -159,10 +159,10 @@ std::string SubscriptionManager::GetTimelineXml() msg << " duration=\"" << total << "\""; msg << " seekRange=\"0-" << total << "\""; msg << " controllable=\"true\""; - msg << " machineIdentifier=\"" << (pVid ? pVid->m_Server.GetUuid() : "") << "\""; + msg << " machineIdentifier=\"" << (pVid ? pVid->m_pServer->GetUuid() : "") << "\""; msg << " protocol=\"http\""; - msg << " address=\"" << (pVid ? pVid->m_Server.GetIpAdress() : "") << "\""; - msg << " port=\"" << (pVid ? pVid->m_Server.GetPort() : 0) << "\""; + msg << " address=\"" << (pVid ? pVid->m_pServer->GetIpAdress() : "") << "\""; + msg << " port=\"" << (pVid ? pVid->m_pServer->GetPort() : 0) << "\""; msg << " guid=\"" << Config::GetInstance().GetUUID() << "\""; msg << " containerKey=\"" << (pVid ? pVid->m_sKey : "/library/metadata/900000") << "\""; msg << " key=\"" << (pVid ? pVid->m_sKey : "/library/metadata/900000") << "\""; diff --git a/browserGrid.cpp b/browserGrid.cpp index 95d74a0..0fef1eb 100644 --- a/browserGrid.cpp +++ b/browserGrid.cpp @@ -3,6 +3,8 @@ #include "XmlObject.h" #include "PVideo.h" #include "Directory.h" +#include "plex.h" +#include "pictureCache.h" cBrowserGrid::cBrowserGrid(cViewGrid* viewGrid) : cViewGridNavigator(viewGrid) { @@ -44,9 +46,11 @@ void cBrowserGrid::ProcessData() cServerElement *elem = &(*it); m_vElements.push_back(elem); } - } else { - m_vElements.push_back(&m_Dummy); - m_Dummy.Dirty(); + } else if (m_pContainer) { + if (!m_pService->IsRoot()) { + m_vElements.push_back(&m_Dummy); + m_Dummy.Dirty(); + } if(m_pContainer->m_vVideos.size() > 0) { for(std::vector<plexclient::Video>::iterator it = m_pContainer->m_vVideos.begin(); it != m_pContainer->m_vVideos.end(); ++it) { @@ -60,9 +64,10 @@ void cBrowserGrid::ProcessData() m_vElements.push_back(elem); } } - + // Cache Images + //m_pContainer->PreCache(); } - + m_firstElementIter = m_vElements.begin(); m_pGrid->Clear(); @@ -85,7 +90,11 @@ eOSState cBrowserGrid::NavigateSelect() m_vServerElements.clear(); ProcessData(); return eOSState::osContinue; - } else return eOSState::osEnd; + } else if(plexclient::Video* vid = dynamic_cast<plexclient::Video*>(SelectedObject())) { + cMyPlugin::PlayFile(*vid); + return eOSState::osEnd; + } + else return eOSState::osEnd; } eOSState cBrowserGrid::NavigateBack() @@ -113,9 +122,9 @@ eOSState cBrowserGrid::NavigateBack() * cDummyElement */ -void cDummyElement::AddTokens(std::shared_ptr<cViewGrid> grid) +void cDummyElement::AddTokens(std::shared_ptr<cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached) { - grid->ClearTokens(); + if(clear) grid->ClearTokens(); grid->AddIntToken("isdummy", 1); grid->AddStringToken("title", "../"); } @@ -136,9 +145,9 @@ cServerElement::cServerElement(plexclient::PlexServer* server, std::string start m_sStartName = startName; } -void cServerElement::AddTokens(std::shared_ptr<cViewGrid> grid) +void cServerElement::AddTokens(std::shared_ptr<cOsdElement> grid, bool clear, std::function<void(cGridElement*)> OnCached) { - grid->ClearTokens(); + if(clear) grid->ClearTokens(); grid->AddIntToken("isserver", 1); grid->AddStringToken("title", m_pServer->GetServerName()); grid->AddStringToken("serverstartpointname", m_sStartName); diff --git a/browserGrid.h b/browserGrid.h index 36fac5c..30ada77 100644 --- a/browserGrid.h +++ b/browserGrid.h @@ -3,6 +3,7 @@ #include <memory> #include <vector> +#include <functional> #include "Plexservice.h" #include "plexgdm.h" #include "PlexServer.h" @@ -13,7 +14,7 @@ class cDummyElement : public cGridElement { public: virtual std::string GetTitle(); - virtual void AddTokens(std::shared_ptr<cViewGrid> grid); + virtual void AddTokens(std::shared_ptr<cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL); }; class cServerElement : public cGridElement @@ -25,17 +26,16 @@ private: public: cServerElement(plexclient::PlexServer* server, std::string startPath, std::string startName); virtual std::string GetTitle(); - virtual void AddTokens(std::shared_ptr<cViewGrid> grid); + virtual void AddTokens(std::shared_ptr<cOsdElement> grid, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL); std::string StartPath() { return m_sStartPath; } plexclient::PlexServer* Server() { return m_pServer; } }; class cBrowserGrid : public cViewGridNavigator { -private: +private: bool m_bServersAreRoot; std::vector<cServerElement> m_vServerElements; - std::shared_ptr<plexclient::MediaContainer> m_pContainer; std::shared_ptr<plexclient::Plexservice> m_pService; cDummyElement m_Dummy; @@ -46,7 +46,8 @@ private: public: cBrowserGrid(cViewGrid* viewGrid); cBrowserGrid(cViewGrid* viewGrid, std::shared_ptr<plexclient::Plexservice> service); - + std::shared_ptr<plexclient::MediaContainer> MediaContainer() { return m_pContainer; } + virtual eOSState NavigateSelect(); virtual eOSState NavigateBack(); }; diff --git a/hlsPlayer.cpp b/hlsPlayer.cpp index 8d714d5..ed3fe2a 100644 --- a/hlsPlayer.cpp +++ b/hlsPlayer.cpp @@ -644,7 +644,7 @@ void cHlsPlayer::SetAudioTrack(eTrackType Type __attribute__((unused)), const tT } // Then do the request if(streamId > 0) { - Poco::Net::HTTPClientSession session(m_Video.m_Server.GetIpAdress(), m_Video.m_Server.GetPort()); + Poco::Net::HTTPClientSession session(m_Video.m_pServer->GetIpAdress(), m_Video.m_pServer->GetPort()); std::string uri = "/library/parts/" + std::string(itoa(m_Video.m_Media.m_iPartId)) + "?audioStreamID=" + std::string(itoa(streamId)); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, uri); @@ -695,7 +695,7 @@ void cHlsPlayer::ReportProgress(bool stopped) state = "paused"; } - Poco::Net::HTTPClientSession session(m_Video.m_Server.GetIpAdress(), m_Video.m_Server.GetPort()); + Poco::Net::HTTPClientSession session(m_Video.m_pServer->GetIpAdress(), m_Video.m_pServer->GetPort()); std::string uri = "/:/progress?key=" + std::string(itoa(m_Video.m_iRatingKey)) + "&identifier=com.plexapp.plugins.library&time=" + std::string(itoa(GetPlayedSeconds()*1000)) + "&state=" + state; Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); session.sendRequest(req); @@ -711,7 +711,7 @@ void cHlsPlayer::ReportProgress(bool stopped) void cHlsPlayer::SetWatched(void) { - Poco::Net::HTTPClientSession session(m_Video.m_Server.GetIpAdress(), m_Video.m_Server.GetPort()); + Poco::Net::HTTPClientSession session(m_Video.m_pServer->GetIpAdress(), m_Video.m_pServer->GetPort()); std::string uri = "/:/scrobble?key=" + std::string(itoa(m_Video.m_iRatingKey)) + "&identifier=com.plexapp.plugins.library"; Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri); session.sendRequest(req); diff --git a/hlsPlayerControl.cpp b/hlsPlayerControl.cpp index 360e3ec..f2348f5 100644 --- a/hlsPlayerControl.cpp +++ b/hlsPlayerControl.cpp @@ -22,7 +22,7 @@ cControl* cHlsPlayerControl::Create(plexclient::Video Video) } // get Metadata - std::string uri = Video.m_Server.GetUri() + Video.m_sKey; + std::string uri = Video.m_pServer->GetUri() + Video.m_sKey; plexclient::MediaContainer pmcontainer = plexclient::Plexservice::GetMediaContainer(uri); std::string transcodeUri = plexclient::Plexservice::GetUniversalTranscodeUrl(&pmcontainer.m_vVideos[0], Video.m_iMyPlayOffset); diff --git a/pictureCache.cpp b/pictureCache.cpp new file mode 100644 index 0000000..67e2fd4 --- /dev/null +++ b/pictureCache.cpp @@ -0,0 +1,146 @@ +#include "pictureCache.h" +#include <Poco/Format.h> +#include <Poco/URIStreamOpener.h> +#include <Poco/StreamCopier.h> +#include <Poco/Path.h> +#include <Poco/File.h> +#include <Poco/StringTokenizer.h> +#include <Poco/URI.h> +#include <Poco/Exception.h> +#include <Poco/Net/HTTPStreamFactory.h> +#include "plexSdOsd.h" +#include "PVideo.h" +#include "Directory.h" + +using Poco::URIStreamOpener; +using Poco::StreamCopier; +using Poco::Path; +using Poco::Exception; +using Poco::Net::HTTPStreamFactory; + +cPictureCache::cPictureCache() +{ + m_cacheDir = cPlugin::CacheDirectory(PLUGIN_NAME_I18N); + + Poco::Path path(m_cacheDir); + Poco::File f(path.toString()); + f.createDirectories(); + HTTPStreamFactory::registerFactory(); +} + +void cPictureCache::Action() +{ + while(Running()) { + while (m_qImagesToLoad.size() > 0) { + //LOCK_THREAD; + CacheInfo info = m_qImagesToLoad.front(); + m_qImagesToLoad.pop_front(); + + std::string transcodeUri = TranscodeUri(info.uri, info.width, info.height); + std::string file = FileName(info.uri, info.width); + if(!Cached(info.uri, info.width)) { + auto stream = DownloadFile(transcodeUri); + if(stream) { + SaveFileToDisk(stream, file); + cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex); + if (info.onCached && info.calle && info.calle->IsVisible()) { + info.onCached(info.calle); + } + } + } + cCondWait::SleepMs(5); + } + cCondWait::SleepMs(100); + } +} + +std::shared_ptr<std::istream> cPictureCache::DownloadFile(std::string uri) +{ + try { + std::shared_ptr<std::istream> pStream(URIStreamOpener::defaultOpener().open(uri)); + return pStream; + } catch (Poco::Exception &exc) { + return NULL; + } +} + +void cPictureCache::SaveFileToDisk(std::shared_ptr<std::istream> file, std::string fileName) +{ + try { + Poco::Path p(fileName); + Poco::File f(p.makeParent().toString()); + f.createDirectories(); + + std::ofstream outFile; + outFile.open(fileName); + Poco::StreamCopier::copyStream(*file, outFile); + outFile.close(); + } catch (Poco::Exception &exc) { + std::cout << "SaveFile Error: " << exc.displayText() << std::endl; + } +} + +std::string cPictureCache::FileName(std::string uri, int width) +{ + Poco::URI u(uri); + std::string file = Poco::format("%s_%d", u.getPath(), width); + + Poco::Path path(m_cacheDir); + path.append(file); + + return path.toString(); +} + +std::string cPictureCache::TranscodeUri(std::string uri, int width, int height) +{ + std::string escapedUri; + Poco::URI::encode(uri, " !\"#$%&'()*+,/:;=?@[]", escapedUri); + Poco::URI u(uri); + int port = u.getPort(); + std::string tUri = Poco::format("http://%s:%d/photo/:/transcode?width=%d&height=%d&url=%s", u.getHost(), port, width, height, escapedUri); + return tUri; +} + +bool cPictureCache::Cached(std::string uri, int width) +{ + return Poco::File(FileName(uri, width)).exists(); +} + +std::string cPictureCache::GetPath(std::string uri, int width, int height, bool& cached, std::function<void(cGridElement*)> OnCached, cGridElement* calle) +{ + cached = Cached(uri, width); + std::string file = FileName(uri, width); + if(cached) { + return file; + } else { + //LOCK_THREAD; + CacheInfo info(uri, width, height, OnCached, calle); + m_qImagesToLoad.push_back(info); + } + + return file; +} + +void cPictureCache::Stop() +{ + Cancel(); +} + +void cPictureCache::Remove(cGridElement* element) +{ + if(!element) return; + if (auto video = dynamic_cast<plexclient::Video*>(element)) { + Remove(video->ThumbUri()); + Remove(video->ArtUri()); + } +} + +void cPictureCache::Remove(std::string uri) +{ + for(std::deque<CacheInfo>::iterator it = m_qImagesToLoad.begin() ; it != m_qImagesToLoad.end(); ++it) { + if(it->uri == uri) { + m_qImagesToLoad.erase(it); + return; + } + } +} diff --git a/pictureCache.h b/pictureCache.h new file mode 100644 index 0000000..e63d44b --- /dev/null +++ b/pictureCache.h @@ -0,0 +1,67 @@ +#ifndef CPICTURECACHE_H +#define CPICTURECACHE_H + +#include <memory> +#include <iostream> +#include <fstream> +#include <deque> +#include <string> + +#include <vdr/thread.h> +#include <vdr/plugin.h> + +#include "viewGridNavigator.h" + +enum ImageResolution { + SD384, + SD480, + HD720, + HD1080 +}; + +class cPictureCache : public cThread +{ +private: + struct CacheInfo { + CacheInfo(std::string Uri, int Width, int Height, std::function<void(cGridElement*)> OnCached, cGridElement* Calle) { + uri = Uri; + width = Width; + height = Height; + onCached = OnCached; + calle = Calle; + }; + std::string uri; + int width; + int height; + std::function<void(cGridElement*)> onCached; + cGridElement* calle; + }; + cPictureCache(); + std::deque<CacheInfo> m_qImagesToLoad; + + + std::string FileName(std::string uri, int width); + + std::shared_ptr<std::istream> DownloadFile(std::string uri); + void SaveFileToDisk(std::shared_ptr<std::istream> file, std::string fileName); + std::string TranscodeUri(std::string uri, int width, int height); + + std::string m_cacheDir; + +protected: + virtual void Action(); + +public: + static cPictureCache& GetInstance() { + static cPictureCache instance; + return instance; + } + void Stop(); + + bool Cached(std::string uri, int width); + std::string GetPath(std::string uri, int width, int height, bool& cached, std::function<void(cGridElement*)> OnCached = NULL, cGridElement* calle = NULL); + void Remove(cGridElement* element); + void Remove(std::string uri); +}; + +#endif // CPICTURECACHE_H @@ -3,6 +3,7 @@ #include "plex.h" #include "plexOsd.h" #include "plexSdOsd.h" +#include "pictureCache.h" #include "libskindesigner/services.h" @@ -62,12 +63,10 @@ bool cMyPlugin::Start(void) reg.SetView(viRootView, "root.xml"); reg.SetViewGrid(eViews::viRootView, eViewGrids::vgBrowser, "browser"); reg.SetViewElement(viRootView, verHeader, "header"); + reg.SetViewElement(viRootView, verBackground, "background"); + reg.SetViewElement(viRootView, verFooter, "footer"); - //reg.SetViewElement(viRootView, verHeader, "header"); - //reg.SetViewElement(viRootView, verFooter, "footer"); - - //reg.SetView(eViews::viBrowserView, "browser.xml"); - + reg.SetSubView(viRootView, viDetailView, "detail.xml"); static cPlugin *pSkinDesigner = cPluginManager::GetPlugin("skindesigner"); if (pSkinDesigner) { @@ -89,6 +88,7 @@ bool cMyPlugin::Initialize(void) plexclient::plexgdm::GetInstance().clientDetails(Config::GetInstance().GetUUID(), Config::GetInstance().GetHostname(), "3200", DESCRIPTION, VERSION); plexclient::plexgdm::GetInstance().Start(); plexclient::ControlServer::GetInstance().Start(); + cPictureCache::GetInstance().Start(); return true; } diff --git a/plexSdOsd.cpp b/plexSdOsd.cpp index e6dc1f9..843eafa 100644 --- a/plexSdOsd.cpp +++ b/plexSdOsd.cpp @@ -1,4 +1,9 @@ #include "plexSdOsd.h" +#include "viewGridNavigator.h" +#include "pictureCache.h" +#include <vdr/thread.h> + +cMutex cPlexSdOsd::RedrawMutex; cPlexSdOsd::cPlexSdOsd() { @@ -16,28 +21,48 @@ void cPlexSdOsd::Show(void) esyslog("[plex]: used skindesigner skin does not support plex"); return; } + m_pBackground = std::shared_ptr<cViewElement>(m_pRootView->GetViewElement(eViewElementsRoot::verBackground)); m_pViewHeader = std::shared_ptr<cViewHeader>( new cViewHeader(m_pRootView->GetViewElement(eViewElementsRoot::verHeader)) ); - m_pBrowserGrid = std::shared_ptr<cBrowserGrid>( - new cBrowserGrid( m_pRootView->GetViewGrid(eViewGrids::vgBrowser)) - ); + m_pfooter = std::shared_ptr<cViewElement>(m_pRootView->GetViewElement(eViewElementsRoot::verFooter)); + + SwitchGrid(m_pViewHeader->CurrentTab()); Flush(); } void cPlexSdOsd::Flush() { + cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex); + DrawBackground(); + m_pViewHeader->Draw(m_pBrowserGrid->SelectedObject()); + + m_pBackground->Display(); + m_pBrowserGrid->Flush(); - - m_pViewHeader->Draw(); - + m_pRootView->Display(); } +void cPlexSdOsd::DrawBackground() +{ + m_pBackground->ClearTokens(); + + if(auto video = dynamic_cast<plexclient::Video*>(m_pBrowserGrid->SelectedObject()) ) { + bool cached = false; + std::string path = cPictureCache::GetInstance().GetPath(video->ArtUri(), 1920, 1080, cached); + m_pBackground->AddStringToken("selecteditembackground", path); + } + + m_pBackground->AddIntToken("isdirectory", 1); + m_pBackground->AddStringToken("currentdirectorybackground", "/path"); +} + eOSState cPlexSdOsd::ProcessKey(eKeys Key) { + eOSState state = eOSState::osContinue; switch (Key & ~k_Repeat) { case kUp: m_pBrowserGrid->NavigateUp(); @@ -57,10 +82,11 @@ eOSState cPlexSdOsd::ProcessKey(eKeys Key) break; case kOk: // Play movie or change dir - m_pBrowserGrid->NavigateSelect(); + state = m_pBrowserGrid->NavigateSelect(); Flush(); break; case kBack: + //state = m_pBrowserGrid->NavigateBack(); Flush(); break; @@ -77,28 +103,91 @@ eOSState cPlexSdOsd::ProcessKey(eKeys Key) default: break; } - return eOSState::osContinue; + return state; } void cPlexSdOsd::SwitchGrid(ePlexMenuTab currentTab) { if(currentTab == ePlexMenuTab::pmtOnDeck) { - - auto service = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice( new plexclient::PlexServer("192.168.1.175", 32400), "/hubs/home/onDeck" ) ); + auto service = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice( plexclient::plexgdm::GetInstance().GetServer("192.168.1.175", 32400), "/hubs/home/onDeck" ) ); m_pBrowserGrid = std::shared_ptr<cBrowserGrid>( new cBrowserGrid( m_pRootView->GetViewGrid(eViewGrids::vgBrowser), service) ); - + m_pBrowserGrid->m_pRootView = m_pRootView; + } else if(currentTab == ePlexMenuTab::pmtRecentlyAdded) { - auto service = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice( new plexclient::PlexServer("192.168.1.175", 32400), "/library/sections" ) ); + auto service = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice( plexclient::plexgdm::GetInstance().GetServer("192.168.1.175", 32400), "/library/sections" ) ); m_pBrowserGrid = std::shared_ptr<cBrowserGrid>( new cBrowserGrid( m_pRootView->GetViewGrid(eViewGrids::vgBrowser), service) ); - + m_pBrowserGrid->m_pRootView = m_pRootView; + } else if(currentTab == ePlexMenuTab::pmtLibrary) { - + m_pBrowserGrid = std::shared_ptr<cBrowserGrid>( new cBrowserGrid( m_pRootView->GetViewGrid(eViewGrids::vgBrowser)) ); + m_pBrowserGrid->m_pRootView = m_pRootView; } } + +void cPlexSdOsd::DrawFooter() +{ + //if (!active) + // return; + + string textGreen = tr("Prev. Tab"); + string textYellow = tr("Next Tab"); + string textRed = ""; + string textBlue = ""; + + if(auto vid = dynamic_cast<plexclient::Video*>(m_pBrowserGrid->SelectedObject()) ) { + if(vid->m_iViewCount > 0) textRed = tr("Unscrobble"); + else textRed = tr("Scrobble"); + textBlue = tr("Info"); + } + + + int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 }; + + m_pfooter->Clear(); + m_pfooter->ClearTokens(); + + m_pfooter->AddStringToken("red", textRed); + m_pfooter->AddStringToken("green", textGreen); + m_pfooter->AddStringToken("yellow", textYellow); + m_pfooter->AddStringToken("blue", textBlue); + + for (int button = 1; button < 5; button++) { + string red = *cString::sprintf("red%d", button); + string green = *cString::sprintf("green%d", button); + string yellow = *cString::sprintf("yellow%d", button); + string blue = *cString::sprintf("blue%d", button); + bool isRed = false; + bool isGreen = false; + bool isYellow = false; + bool isBlue = false; + switch (colorKeys[button-1]) { + case 0: + isRed = true; + break; + case 1: + isGreen = true; + break; + case 2: + isYellow = true; + break; + case 3: + isBlue = true; + break; + default: + break; + } + m_pfooter->AddIntToken(red, isRed); + m_pfooter->AddIntToken(green, isGreen); + m_pfooter->AddIntToken(yellow, isYellow); + m_pfooter->AddIntToken(blue, isBlue); + } + + m_pfooter->Display(); +} diff --git a/plexSdOsd.h b/plexSdOsd.h index 1f7c677..f4f4427 100644 --- a/plexSdOsd.h +++ b/plexSdOsd.h @@ -27,6 +27,7 @@ enum eViews { }; enum eViewElementsRoot { + verBackground, verHeader, verFooter }; @@ -36,20 +37,25 @@ enum eViewGrids { }; class cPlexSdOsd : public cSkindesignerOsdObject -{ +{ private: std::shared_ptr<cBrowserGrid> m_pBrowserGrid; std::shared_ptr<cViewHeader> m_pViewHeader; + std::shared_ptr<cViewElement> m_pBackground; + std::shared_ptr<cViewElement> m_pfooter; cOsdView* m_pRootView; void Flush(); void SwitchGrid(ePlexMenuTab currentTab); + void DrawBackground(); + void DrawFooter(); public: cPlexSdOsd(); virtual void Show(void); virtual eOSState ProcessKey(eKeys Key); - + + static cMutex RedrawMutex; }; #endif // CPLEXSDOSD_H diff --git a/plexgdm.cpp b/plexgdm.cpp index 083e00d..d8da646 100644 --- a/plexgdm.cpp +++ b/plexgdm.cpp @@ -115,7 +115,7 @@ void plexgdm::Action() std::string s = Poco::format("BYE %s\r\n%s", _clientHeader, _clientData); update_sock.sendTo(s.c_str(), s.length(), m_clientRegisterGroup, 0); } catch (Poco::IOException) {} - + m_clientRegistered = false; } @@ -153,7 +153,10 @@ void plexgdm::discover() bool flag = true; // Check for duplicates for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) { - if(s_it->GetIpAdress() == host) flag = false; + if(s_it->GetIpAdress() == host) { + flag = false; + s_it->ParseData(data, host); + } } if(flag) { m_vServers.push_back(PlexServer(data, host)); @@ -171,4 +174,16 @@ void plexgdm::stopRegistration() Cancel(); } } + +PlexServer* plexgdm::GetServer(std::string ip, int port) +{ + for(std::vector<PlexServer>::iterator s_it = m_vServers.begin(); s_it != m_vServers.end(); ++s_it) { + if(s_it->GetIpAdress() == ip && s_it->GetPort() == port) { + return &(*s_it); + } + } + m_vServers.push_back(PlexServer(ip, port)); + return &m_vServers[m_vServers.size()-1]; } + +} // namespace @@ -33,6 +33,7 @@ public: void clientDetails(std::string c_id, std::string c_name, std::string c_port, std::string c_product, std::string c_version); std::string getClientDetails(); PlexServer* getServerList(); + PlexServer* GetServer(std::string ip, int port); void discover(); void checkClientRegistration(); diff --git a/skins/blackhole/xmlfiles/plug-plex-root.xml b/skins/blackhole/xmlfiles/plug-plex-root.xml index c937ce7..18a2c97 100644 --- a/skins/blackhole/xmlfiles/plug-plex-root.xml +++ b/skins/blackhole/xmlfiles/plug-plex-root.xml @@ -2,6 +2,18 @@ <!DOCTYPE displayplugin SYSTEM "../../../dtd/displayplugin.dtd"> <displayplugin x="0" y="0" width="100%" height="100%" fadetime="0" scaletvx="0" scaletvy="0" scaletvwidth="100%" scaletvheight="100%"> + <!-- Tokens available in background + {selecteditembackground} image + + {isdirectory} + {currentdirectorybackground} image + --> + <viewelement name="background"> + <area x="0" y="0" width="100%" height="100%" layer="1"> + <drawimage imagetype="image" path="{selecteditembackground}" x="0" y="0" width="100%" height="100%" /> + </area> + </viewelement> + <!-- Tokens available in header {title} {istab1active} @@ -10,13 +22,26 @@ {tab2name} {istab3active} {tab3name} + + {selectedtitle} + {cover} + + {ismovie} + {isshow} + {banner} + + {isseason} + {banner} + + {isepisode} + {banner} --> <viewelement name="header"> - <area layer="1" x="0" y="0" width="100%" height="15%"> + <area layer="2" x="0" y="0" width="100%" height="15%"> <drawtext x="1%" y="5%" width="98%" font="{light}" fontsize="30%" color="{clrWhite}" text="Plex for VDR" /> <drawtext condition="{istab1active}" x="1%" y="20%" width="98%" font="{light}" fontsize="30%" color="{clrWhite}" text="{tab1name}" /> <drawtext condition="{istab2active}" x="1%" y="20%" width="98%" font="{light}" fontsize="30%" color="{clrWhite}" text="{tab2name}" /> - <drawtext condition="{istab3active}" x="1%" y="20%" width="98%" font="{light}" fontsize="305%" color="{clrWhite}" text="{tab3name}" /> + <drawtext condition="{istab3active}" x="1%" y="20%" width="98%" font="{light}" fontsize="30%" color="{clrWhite}" text="{tab3name}" /> </area> </viewelement> @@ -24,7 +49,7 @@ {current} Currently active element {title} Name of the element {year} - {cover} Image + {thumb} Image/Cover {isdummy} Condition @@ -44,13 +69,14 @@ --> <grid name="browser" x="0" y="15%" width="100%" height="85%"> - <area layer="2"> + <area layer="3"> <drawtext x="1%" y="2%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="{title}" /> <drawtext condition="{current}" x="1%" y="20%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="Active" /> <drawtext condition="{isserver}" x="1%" y="40%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="Server" /> <drawtext condition="{isserver}" x="1%" y="60%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="{serverstartpointname}" /> <drawtext condition="{isdirectory}" x="1%" y="40%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="Directory" /> <drawtext condition="{ismovie}" x="1%" y="40%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="Movie" /> + <drawimage condition="{ismovie}" imagetype="image" path="{thumb}" x="5%" y="5%" width="95%" height="95%" /> <drawtext condition="{isepisode}" x="1%" y="40%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="Episode" /> </area> </grid> diff --git a/viewGridNavigator.cpp b/viewGridNavigator.cpp index 78781ca..75192a9 100644 --- a/viewGridNavigator.cpp +++ b/viewGridNavigator.cpp @@ -1,4 +1,7 @@ #include "viewGridNavigator.h" +#include <iostream> +#include "plexSdOsd.h" +#include "pictureCache.h" unsigned int cGridElement::AbsoluteGridIdCounter = 0; @@ -20,6 +23,26 @@ cViewGridNavigator::cViewGridNavigator(cViewGrid* viewGrid) } +void cViewGridNavigator::ReDraw(cGridElement* element) +{ + if(element) { + cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex); + if (!element->IsVisible()) { + std::cout << "ReDraw element not visible" << std::endl; + return; + } + double x, y; + element->GetPosition(x, y); + element->AddTokens(m_pGrid); + double width = 1.0 / m_columns; + double height = 1.0 / m_rows; + m_pGrid->SetGrid(element->GridElementId(), x, y, width, height); + Flush(); + m_pRootView->Display(); + } +// +} + void cViewGridNavigator::FilterElements(int scrollOffset) { int startOffset = scrollOffset; @@ -60,6 +83,9 @@ void cViewGridNavigator::FilterElements(int scrollOffset) m_pGrid->Delete((*it)->GridElementId()); (*it)->Dirty(); (*it)->Position = -1; + (*it)->SetPosition(-1,-1); + // Remove Queued Downloads + cPictureCache::GetInstance().Remove(*it); } } @@ -81,13 +107,15 @@ void cViewGridNavigator::SetGridElementData(cGridElement *obj) y= height * row; //std::cout << "ID: " << obj->GridElementId() << "\tPos: " << obj->Position << "\t\tx: " << x << "\t\ty: " << y << "\t\twi: " << width << "\t\thei: " << height << "\tCol: " << column << "\tRow: " << row << std::endl; - + cMutexLock MutexLock(&cPlexSdOsd::RedrawMutex); if(obj->IsNew() || m_newDimensions) { // fill data - obj->AddTokens(m_pGrid); + obj->SetPosition(x, y); + obj->AddTokens(m_pGrid, true, std::bind(&cViewGridNavigator::ReDraw, this, std::placeholders::_1)); m_pGrid->SetGrid(obj->GridElementId(), x, y, width, height); obj->InitFinished(); } else { + obj->SetPosition(x, y); m_pGrid->MoveGrid(obj->GridElementId(), x, y, width, height); } } diff --git a/viewGridNavigator.h b/viewGridNavigator.h index cc17dd5..a0fb920 100644 --- a/viewGridNavigator.h +++ b/viewGridNavigator.h @@ -3,15 +3,20 @@ #include <memory> #include <vector> +#include <functional> #include "libskindesigner/osdelements.h" class cGridElement { private: bool m_bInit; - unsigned int m_iGridId; + double m_posX; + double m_posY; static unsigned int AbsoluteGridIdCounter; +protected: + unsigned int m_iGridId; + public: cGridElement(); @@ -20,13 +25,15 @@ public: void InitFinished() { m_bInit = false; }; unsigned int GridElementId() { return m_iGridId; } bool IsVisible() { return Position > -1; } - virtual void AddTokens(std::shared_ptr<cViewGrid> grid) = 0; + void SetPosition(double x, double y) { m_posX = x; m_posY = y; }; + void GetPosition(double &x, double &y) { x = m_posX; y = m_posY; }; + virtual void AddTokens(std::shared_ptr<cOsdElement> osdElem, bool clear = true, std::function<void(cGridElement*)> OnCached = NULL) = 0; int Position; }; class cViewGridNavigator { -protected: +protected: int m_rows; int m_columns; @@ -47,6 +54,7 @@ public: cViewGridNavigator(cViewGrid* viewGrid); void SetGridDimensions(int rows, int columns); void Flush() { m_pGrid->Display(); }; + void Clear() { m_pGrid->Clear(); }; void DrawGrid() { m_pGrid->Display(); } virtual void NavigateLeft(); virtual void NavigateRight(); @@ -55,7 +63,9 @@ public: virtual eOSState NavigateSelect() = 0; virtual eOSState NavigateBack() = 0; cGridElement* SelectedObject() { return *m_activeElementIter; } + void ReDraw(cGridElement* element); + cOsdView* m_pRootView; }; #endif // CVIEWGRIDNAVIGATOR_H diff --git a/viewHeader.cpp b/viewHeader.cpp index 932ef24..6f12bb0 100644 --- a/viewHeader.cpp +++ b/viewHeader.cpp @@ -6,20 +6,29 @@ cViewHeader::cViewHeader(cViewElement* viewElem) m_eCurrentTab = ePlexMenuTab::pmtOnDeck; } -void cViewHeader::Draw() +void cViewHeader::Draw(cGridElement* elem) { + m_pViewElem->Clear(); m_pViewElem->ClearTokens(); - + + elem->AddTokens(m_pViewElem, false); + switch(m_eCurrentTab) { case ePlexMenuTab::pmtOnDeck: m_pViewElem->AddIntToken("istab1active", 1); + m_pViewElem->AddIntToken("istab2active", 0); + m_pViewElem->AddIntToken("istab3active", 0); m_pViewElem->AddStringToken("tab1name", "On Deck"); break; case ePlexMenuTab::pmtRecentlyAdded: + m_pViewElem->AddIntToken("istab1active", 0); m_pViewElem->AddIntToken("istab2active", 1); + m_pViewElem->AddIntToken("istab3active", 0); m_pViewElem->AddStringToken("tab2name", "Recently Added"); break; case ePlexMenuTab::pmtLibrary: + m_pViewElem->AddIntToken("istab1active", 0); + m_pViewElem->AddIntToken("istab2active", 0); m_pViewElem->AddIntToken("istab3active", 1); m_pViewElem->AddStringToken("tab3name", "Library"); break; diff --git a/viewHeader.h b/viewHeader.h index afdb38f..00aacbb 100644 --- a/viewHeader.h +++ b/viewHeader.h @@ -3,6 +3,7 @@ #include <memory> #include "libskindesigner/osdelements.h" +#include "viewGridNavigator.h" enum ePlexMenuTab { pmtOnDeck, @@ -18,7 +19,7 @@ private: public: cViewHeader(cViewElement* viewElem); - void Draw(); + void Draw(cGridElement* elem); ePlexMenuTab NextTab(); ePlexMenuTab PrevTab(); ePlexMenuTab CurrentTab() { return m_eCurrentTab; } |