summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Directory.cpp7
-rw-r--r--Directory.h8
-rw-r--r--Makefile1
-rw-r--r--MediaContainer.cpp21
-rw-r--r--MediaContainer.h5
-rw-r--r--PVideo.cpp33
-rw-r--r--PVideo.h10
-rw-r--r--PlexServer.cpp5
-rw-r--r--PlexServer.h19
-rw-r--r--Plexservice.cpp12
-rw-r--r--Plexservice.h1
-rw-r--r--SubscriptionManager.cpp10
-rw-r--r--browserGrid.cpp29
-rw-r--r--browserGrid.h11
-rw-r--r--hlsPlayer.cpp6
-rw-r--r--hlsPlayerControl.cpp2
-rw-r--r--pictureCache.cpp146
-rw-r--r--pictureCache.h67
-rw-r--r--plex.cpp10
-rw-r--r--plexSdOsd.cpp117
-rw-r--r--plexSdOsd.h10
-rw-r--r--plexgdm.cpp19
-rw-r--r--plexgdm.h1
-rw-r--r--skins/blackhole/xmlfiles/plug-plex-root.xml34
-rw-r--r--viewGridNavigator.cpp32
-rw-r--r--viewGridNavigator.h16
-rw-r--r--viewHeader.cpp13
-rw-r--r--viewHeader.h3
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);
};
}
diff --git a/Makefile b/Makefile
index 19ba3de..5372c45 100644
--- a/Makefile
+++ b/Makefile
@@ -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();
};
}
diff --git a/PVideo.cpp b/PVideo.cpp
index f17a9ce..ca8684b 100644
--- a/PVideo.cpp
+++ b/PVideo.cpp
@@ -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
+
diff --git a/PVideo.h b/PVideo.h
index 03e0b0a..7c04bd4 100644
--- a/PVideo.h
+++ b/PVideo.h
@@ -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
diff --git a/plex.cpp b/plex.cpp
index 61fd69b..b03ae75 100644
--- a/plex.cpp
+++ b/plex.cpp
@@ -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
diff --git a/plexgdm.h b/plexgdm.h
index 8aa8ad4..72d3059 100644
--- a/plexgdm.h
+++ b/plexgdm.h
@@ -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; }