summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Directory.cpp6
-rw-r--r--Directory.h10
-rw-r--r--Makefile11
-rw-r--r--PVideo.cpp6
-rw-r--r--PVideo.h10
-rw-r--r--PlexServer.h5
-rw-r--r--Plexservice.cpp6
-rw-r--r--Plexservice.h1
-rw-r--r--XmlObject.h4
-rw-r--r--browserGrid.cpp153
-rw-r--r--browserGrid.h54
-rw-r--r--hlsPlayer.cpp3
-rw-r--r--libskindesigner/osdelements.cpp205
-rw-r--r--libskindesigner/osdelements.h93
-rw-r--r--libskindesigner/services.h131
-rw-r--r--libskindesigner/skindesignerosdbase.cpp211
-rw-r--r--libskindesigner/skindesignerosdbase.h86
-rw-r--r--plex.cpp32
-rw-r--r--plexOsd.cpp46
-rw-r--r--plexOsd.h12
-rw-r--r--plexSdOsd.cpp104
-rw-r--r--plexSdOsd.h55
-rw-r--r--po/de_DE.po10
-rw-r--r--skins/blackhole/xmlfiles/plug-plex-root.xml58
-rw-r--r--viewGridNavigator.cpp158
-rw-r--r--viewGridNavigator.h61
-rw-r--r--viewHeader.cpp61
-rw-r--r--viewHeader.h27
28 files changed, 1549 insertions, 70 deletions
diff --git a/Directory.cpp b/Directory.cpp
index e6e240b..5102015 100644
--- a/Directory.cpp
+++ b/Directory.cpp
@@ -41,4 +41,10 @@ std::string Directory::GetTitle()
}
}
+void Directory::AddTokens(std::shared_ptr<cViewGrid> grid)
+{
+ grid->ClearTokens();
+ grid->AddStringToken("title", m_sTitle);
+}
+
}
diff --git a/Directory.h b/Directory.h
index 19bd17f..b4a78d1 100644
--- a/Directory.h
+++ b/Directory.h
@@ -11,8 +11,12 @@
#include <Poco/Timestamp.h>
#include <Poco/String.h>
+#include <memory>
+#include "libskindesigner/osdelements.h"
+
#include "XmlObject.h"
#include "MediaContainer.h"
+#include "viewGridNavigator.h"
using Poco::XML::DOMParser;
using Poco::XML::Document;
@@ -26,7 +30,7 @@ namespace plexclient
{
class MediaContainer;
-class Directory: XmlObject
+class Directory: private XmlObject, public cGridElement
{
public:
Directory(Poco::XML::Node* pNode, MediaContainer* parent);
@@ -48,7 +52,9 @@ public:
std::string m_sKey;
MediaType m_eType;
- std::string GetTitle();
+ virtual std::string GetTitle();
+ // gridElement
+ virtual void AddTokens(std::shared_ptr<cViewGrid> grid);
};
}
diff --git a/Makefile b/Makefile
index 705cb85..19ba3de 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,7 @@ PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(s
LIBDIR = $(call PKGCFG,libdir)
LOCDIR = $(call PKGCFG,locdir)
PLGCFG = $(call PKGCFG,plgcfg)
+PLGRESDIR = $(call PKGCFG,resdir)/plugins/skindesigner
#
TMPDIR ?= /tmp
@@ -87,6 +88,12 @@ OBJS = $(PLUGIN).o \
Stream.o \
Media.o \
plexOsd.o \
+ plexSdOsd.o \
+ viewGridNavigator.o \
+ browserGrid.o \
+ viewHeader.o \
+ libskindesigner/skindesignerosdbase.o \
+ libskindesigner/osdelements.o \
SRCS = $(wildcard $(OBJS:.o=.c)) $(PLUGIN).cpp
@@ -144,6 +151,10 @@ $(SOFILE): $(OBJS)
install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
+install-skins:
+ mkdir -p $(DESTDIR)$(PLGRESDIR)/skins
+ cp -r skins/* $(DESTDIR)$(PLGRESDIR)/skins
+
install: install-lib install-i18n
dist: $(I18Npo) clean
diff --git a/PVideo.cpp b/PVideo.cpp
index 8949666..f17a9ce 100644
--- a/PVideo.cpp
+++ b/PVideo.cpp
@@ -204,5 +204,11 @@ bool Video::SetWatched()
}
}
+void Video::AddTokens(std::shared_ptr<cViewGrid>grid)
+{
+ grid->ClearTokens();
+ grid->AddStringToken("title", m_sTitle);
+}
+
} // Namespace
diff --git a/PVideo.h b/PVideo.h
index c419fff..03e0b0a 100644
--- a/PVideo.h
+++ b/PVideo.h
@@ -14,6 +14,9 @@
#include <vector>
#include <iostream>
+#include <memory>
+#include "libskindesigner/osdelements.h"
+#include "viewGridNavigator.h"
#include "XmlObject.h"
#include "MediaContainer.h"
@@ -32,7 +35,7 @@ namespace plexclient
{
class MediaContainer;
-class Video: XmlObject
+class Video: private XmlObject, public cGridElement
{
private:
void Parse(Poco::XML::Node* pNode);
@@ -72,11 +75,14 @@ public:
int m_iIndex;
int m_iParentIndex;
- std::string GetTitle();
+ virtual std::string GetTitle();
bool SetStream(Stream* stream);
bool UpdateFromServer();
bool SetWatched();
bool SetUnwatched();
+
+ // gridElement
+ virtual void AddTokens(std::shared_ptr<cViewGrid> grid);
};
}
diff --git a/PlexServer.h b/PlexServer.h
index a3d6ee1..3879878 100644
--- a/PlexServer.h
+++ b/PlexServer.h
@@ -6,6 +6,7 @@
#include <sstream>
#include <iostream>
#include <vector>
+#include <memory>
#include <Poco/String.h>
#include <Poco/Net/HTTPClientSession.h>
@@ -15,7 +16,7 @@
namespace plexclient
{
-
+
class PlexServer
{
public:
@@ -59,7 +60,7 @@ public:
}
std::string GetUri();
-
+
void DiscoverSettings();
private:
diff --git a/Plexservice.cpp b/Plexservice.cpp
index dc01721..41f9579 100644
--- a/Plexservice.cpp
+++ b/Plexservice.cpp
@@ -11,6 +11,12 @@ Plexservice::Plexservice(PlexServer *server)
pServer = server;
}
+Plexservice::Plexservice(PlexServer *server, std::string startUri)
+{
+ pServer = server;
+ StartUri = startUri;
+}
+
std::string Plexservice::GetMyPlexToken()
{
static bool done;
diff --git a/Plexservice.h b/Plexservice.h
index d20c5ee..e30e346 100644
--- a/Plexservice.h
+++ b/Plexservice.h
@@ -40,6 +40,7 @@ class Plexservice
{
public:
Plexservice(PlexServer *server);
+ Plexservice(PlexServer *server, std::string startUri);
void DisplaySections();
std::shared_ptr<MediaContainer> GetSection(std::string section, bool putOnStack = true);
diff --git a/XmlObject.h b/XmlObject.h
index 5b8b2ca..22626b4 100644
--- a/XmlObject.h
+++ b/XmlObject.h
@@ -15,9 +15,7 @@ enum MediaType {UNDEF = 0, PHOTO, MOVIE, MUSIC, SHOW, SEASON, EPISODE};
enum StreamType {sUNDEF = 0, sVIDEO = 1, sAUDIO = 2, sSUBTITLE = 3};
class XmlObject
-{
-public:
-
+{
protected:
static std::string GetNodeValue(Poco::XML::Node* pNode);
static int GetNodeValueAsInt(Poco::XML::Node* pNode);
diff --git a/browserGrid.cpp b/browserGrid.cpp
new file mode 100644
index 0000000..95d74a0
--- /dev/null
+++ b/browserGrid.cpp
@@ -0,0 +1,153 @@
+#include "browserGrid.h"
+#include "plexSdOsd.h"
+#include "XmlObject.h"
+#include "PVideo.h"
+#include "Directory.h"
+
+cBrowserGrid::cBrowserGrid(cViewGrid* viewGrid) : cViewGridNavigator(viewGrid)
+{
+ m_rows = 2;
+ m_columns = 5;
+ m_pService = NULL;
+ m_pContainer = NULL;
+ m_bServersAreRoot = true;
+ SetServerElements();
+ ProcessData();
+}
+
+cBrowserGrid::cBrowserGrid(cViewGrid* viewGrid, std::shared_ptr<plexclient::Plexservice> service) : cViewGridNavigator(viewGrid)
+{
+ m_rows = 2;
+ m_columns = 5;
+ m_bServersAreRoot = false;
+ m_pService = service;
+ m_pContainer = m_pService->GetSection(m_pService->StartUri);
+ ProcessData();
+}
+
+void cBrowserGrid::SetServerElements()
+{
+ m_vServerElements.clear();
+
+ for(std::vector<plexclient::PlexServer>::iterator it = plexclient::plexgdm::GetInstance().GetPlexservers().begin(); it != plexclient::plexgdm::GetInstance().GetPlexservers().end(); ++it) {
+ m_vServerElements.push_back(cServerElement(&(*it), "/library/sections", "Bibliothek"));
+ m_vServerElements.push_back(cServerElement(&(*it), "/video", "Video Channels"));
+ }
+}
+
+void cBrowserGrid::ProcessData()
+{
+ m_vElements.clear();
+
+ if(m_vServerElements.size() > 0) {
+ for(auto it = m_vServerElements.begin(); it !=m_vServerElements.end(); ++it) {
+ cServerElement *elem = &(*it);
+ m_vElements.push_back(elem);
+ }
+ } else {
+ 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) {
+ plexclient::Video *elem = &(*it);
+ m_vElements.push_back(elem);
+ }
+ }
+ if(m_pContainer->m_vDirectories.size() > 0) {
+ for(std::vector<plexclient::Directory>::iterator it = m_pContainer->m_vDirectories.begin(); it != m_pContainer->m_vDirectories.end(); ++it) {
+ plexclient::Directory *elem = &(*it);
+ m_vElements.push_back(elem);
+ }
+ }
+
+ }
+
+ m_firstElementIter = m_vElements.begin();
+
+ m_pGrid->Clear();
+ m_setIterator = true;
+ FilterElements(0);
+}
+
+eOSState cBrowserGrid::NavigateSelect()
+{
+ plexclient::Directory* dir = dynamic_cast<plexclient::Directory*>(SelectedObject());
+ if(dir) {
+ m_pContainer = m_pService->GetSection(dir->m_sKey);
+ ProcessData();
+ return eOSState::osContinue;
+ } else if(dynamic_cast<cDummyElement*>(SelectedObject())) {
+ return NavigateBack();
+ } else if(cServerElement* srv = dynamic_cast<cServerElement*>(SelectedObject())) {
+ m_pService = std::shared_ptr<plexclient::Plexservice>(new plexclient::Plexservice( srv->Server() ) );
+ m_pContainer = m_pService->GetSection(srv->StartPath());
+ m_vServerElements.clear();
+ ProcessData();
+ return eOSState::osContinue;
+ } else return eOSState::osEnd;
+}
+
+eOSState cBrowserGrid::NavigateBack()
+{
+ std::shared_ptr<plexclient::MediaContainer> pCont = NULL;
+ if(m_pService) {
+ pCont = m_pService->GetLastSection();
+ }
+
+ if(pCont) {
+ m_pContainer = pCont;
+ ProcessData();
+ return eOSState::osBack;
+
+ } else if(m_bServersAreRoot) {
+ m_pContainer = NULL;
+ m_pService = NULL;
+ SetServerElements();
+ ProcessData();
+ }
+ return eOSState::osEnd;
+}
+
+/*
+ * cDummyElement
+ */
+
+void cDummyElement::AddTokens(std::shared_ptr<cViewGrid> grid)
+{
+ grid->ClearTokens();
+ grid->AddIntToken("isdummy", 1);
+ grid->AddStringToken("title", "../");
+}
+
+std::string cDummyElement::GetTitle()
+{
+ return "Dummy";
+}
+
+/*
+ * cServerElement
+ */
+
+cServerElement::cServerElement(plexclient::PlexServer* server, std::string startPath, std::string startName)
+{
+ m_pServer = server;
+ m_sStartPath = startPath;
+ m_sStartName = startName;
+}
+
+void cServerElement::AddTokens(std::shared_ptr<cViewGrid> grid)
+{
+ grid->ClearTokens();
+ grid->AddIntToken("isserver", 1);
+ grid->AddStringToken("title", m_pServer->GetServerName());
+ grid->AddStringToken("serverstartpointname", m_sStartName);
+ grid->AddStringToken("serverip", m_pServer->GetIpAdress());
+ grid->AddIntToken("serverport", m_pServer->GetPort());
+ grid->AddStringToken("serverversion", m_pServer->GetVersion());
+}
+
+std::string cServerElement::GetTitle()
+{
+ return "Server";
+}
diff --git a/browserGrid.h b/browserGrid.h
new file mode 100644
index 0000000..36fac5c
--- /dev/null
+++ b/browserGrid.h
@@ -0,0 +1,54 @@
+#ifndef CBROWSERGRID_H
+#define CBROWSERGRID_H
+
+#include <memory>
+#include <vector>
+#include "Plexservice.h"
+#include "plexgdm.h"
+#include "PlexServer.h"
+#include "viewGridNavigator.h"
+#include "libskindesigner/osdelements.h"
+
+class cDummyElement : public cGridElement
+{
+public:
+ virtual std::string GetTitle();
+ virtual void AddTokens(std::shared_ptr<cViewGrid> grid);
+};
+
+class cServerElement : public cGridElement
+{
+private:
+ plexclient::PlexServer* m_pServer;
+ std::string m_sStartPath;
+ std::string m_sStartName;
+public:
+ cServerElement(plexclient::PlexServer* server, std::string startPath, std::string startName);
+ virtual std::string GetTitle();
+ virtual void AddTokens(std::shared_ptr<cViewGrid> grid);
+ std::string StartPath() { return m_sStartPath; }
+ plexclient::PlexServer* Server() { return m_pServer; }
+};
+
+class cBrowserGrid : public cViewGridNavigator
+{
+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;
+
+ void ProcessData();
+ void SetServerElements();
+
+public:
+ cBrowserGrid(cViewGrid* viewGrid);
+ cBrowserGrid(cViewGrid* viewGrid, std::shared_ptr<plexclient::Plexservice> service);
+
+ virtual eOSState NavigateSelect();
+ virtual eOSState NavigateBack();
+};
+
+#endif // CBROWSERGRID_H
diff --git a/hlsPlayer.cpp b/hlsPlayer.cpp
index ca1d91f..8d714d5 100644
--- a/hlsPlayer.cpp
+++ b/hlsPlayer.cpp
@@ -6,6 +6,7 @@
#include <Poco/Exception.h>
#include <pcrecpp.h>
+#include <algorithm>
#include "Plexservice.h"
#include "XmlObject.h"
@@ -210,7 +211,7 @@ int cHlsSegmentLoader::EstimateSegmentSize()
int len = m_indexParser.TargetDuration;
double estSize = (bandw) * len;
- estSize = max(estSize, 1.0);
+ estSize = std::max(estSize, 1.0);
// default
if(estSize <= 1) {
estSize = 32;
diff --git a/libskindesigner/osdelements.cpp b/libskindesigner/osdelements.cpp
new file mode 100644
index 0000000..3722cbf
--- /dev/null
+++ b/libskindesigner/osdelements.cpp
@@ -0,0 +1,205 @@
+#include "osdelements.h"
+
+using namespace std;
+
+/**********************************************************************
+* cOsdElement
+**********************************************************************/
+cOsdElement::cOsdElement(cSkinDisplayPlugin *view) {
+ this->view = view;
+}
+
+cOsdElement::~cOsdElement() {
+}
+
+void cOsdElement::ClearTokens(void) {
+ stringTokens.clear();
+ intTokens.clear();
+ loopTokens.clear();
+}
+
+void cOsdElement::AddStringToken(string key, string value) {
+ stringTokens.insert(pair<string,string>(key, value));
+}
+
+void cOsdElement::AddIntToken(string key, int value) {
+ intTokens.insert(pair<string,int>(key, value));
+}
+
+void cOsdElement::AddLoopToken(string loopName, map<string, string> &tokens) {
+ map<string, vector<map<string, string> > >::iterator hitLoop = loopTokens.find(loopName);
+ if (hitLoop == loopTokens.end()) {
+ vector<map<string, string> > tokenVector;
+ tokenVector.push_back(tokens);
+ loopTokens.insert(pair<string, vector<map<string, string> > >(loopName, tokenVector));
+ } else {
+ vector<map<string, string> > *tokenVector = &hitLoop->second;
+ tokenVector->push_back(tokens);
+ }
+}
+
+bool cOsdElement::ChannelLogoExists(string channelId) {
+ return view->ChannelLogoExists(channelId);
+}
+
+string cOsdElement::GetEpgImagePath(void) {
+ return view->GetEpgImagePath();
+}
+
+
+/**********************************************************************
+* cViewElement
+**********************************************************************/
+cViewElement::cViewElement(cSkinDisplayPlugin *view, int viewElementID) : cOsdElement(view) {
+ this->viewElementID = viewElementID;
+}
+
+cViewElement::~cViewElement() {
+}
+
+void cViewElement::Clear(void) {
+ if (!view)
+ return;
+ view->ClearViewElement(viewElementID);
+}
+
+void cViewElement::Display(void) {
+ if (!view)
+ return;
+ view->SetViewElementIntTokens(&intTokens);
+ view->SetViewElementStringTokens(&stringTokens);
+ view->SetViewElementLoopTokens(&loopTokens);
+ view->DisplayViewElement(viewElementID);
+}
+
+/**********************************************************************
+* cViewGrid
+**********************************************************************/
+cViewGrid::cViewGrid(cSkinDisplayPlugin *view, int viewGridID) : cOsdElement(view) {
+ this->viewGridID = viewGridID;
+}
+
+cViewGrid::~cViewGrid() {
+}
+
+void cViewGrid::SetGrid(long gridID, double x, double y, double width, double height) {
+ if (!view)
+ return;
+ view->SetGrid(viewGridID, gridID, x, y, width, height, &intTokens, &stringTokens);
+}
+
+void cViewGrid::SetCurrent(long gridID, bool current) {
+ if (!view)
+ return;
+ view->SetGridCurrent(viewGridID, gridID, current);
+}
+
+void cViewGrid::MoveGrid(long gridID, double x, double y, double width, double height) {
+ if (!view)
+ return;
+ view->SetGrid(viewGridID, gridID, x, y, width, height, NULL, NULL);
+}
+
+void cViewGrid::Delete(long gridID) {
+ if (!view)
+ return;
+ view->DeleteGrid(viewGridID, gridID);
+}
+
+void cViewGrid::Clear(void) {
+ if (!view)
+ return;
+ view->ClearGrids(viewGridID);
+}
+
+void cViewGrid::Display(void) {
+ if (!view)
+ return;
+ view->DisplayGrids(viewGridID);
+}
+
+/**********************************************************************
+* cViewTab
+**********************************************************************/
+cViewTab::cViewTab(cSkinDisplayPlugin *view) : cOsdElement(view) {
+}
+
+cViewTab::~cViewTab() {
+}
+
+void cViewTab::Init(void) {
+ view->SetTabIntTokens(&intTokens);
+ view->SetTabStringTokens(&stringTokens);
+ view->SetTabLoopTokens(&loopTokens);
+ view->SetTabs();
+}
+
+void cViewTab::Left(void) {
+ view->TabLeft();
+}
+
+void cViewTab::Right(void) {
+ view->TabRight();
+}
+
+void cViewTab::Up(void) {
+ view->TabUp();
+}
+
+void cViewTab::Down(void) {
+ view->TabDown();
+}
+
+void cViewTab::Display(void) {
+ if (!view)
+ return;
+ view->DisplayTabs();
+}
+
+/**********************************************************************
+* cOsdView
+**********************************************************************/
+cOsdView::cOsdView(cSkinDisplayPlugin *displayPlugin) {
+ this->displayPlugin = displayPlugin;
+}
+
+cOsdView::~cOsdView() {
+ delete displayPlugin;
+}
+
+void cOsdView::Deactivate(bool hide) {
+ if (!displayPlugin)
+ return;
+ displayPlugin->Deactivate(hide);
+}
+
+void cOsdView::Activate(void) {
+ if (!displayPlugin)
+ return;
+ displayPlugin->Activate();
+}
+
+cViewElement *cOsdView::GetViewElement(int viewElementID) {
+ if (!displayPlugin)
+ return NULL;
+ return new cViewElement(displayPlugin, viewElementID);
+}
+
+cViewGrid *cOsdView::GetViewGrid(int viewGridID) {
+ if (!displayPlugin)
+ return NULL;
+ displayPlugin->InitGrids(viewGridID);
+ return new cViewGrid(displayPlugin, viewGridID);
+}
+
+cViewTab *cOsdView::GetViewTabs(void) {
+ if (!displayPlugin)
+ return NULL;
+ return new cViewTab(displayPlugin);
+}
+
+void cOsdView::Display(void) {
+ if (!displayPlugin)
+ return;
+ displayPlugin->Flush();
+}
diff --git a/libskindesigner/osdelements.h b/libskindesigner/osdelements.h
new file mode 100644
index 0000000..147de7a
--- /dev/null
+++ b/libskindesigner/osdelements.h
@@ -0,0 +1,93 @@
+#ifndef __OSDELEMENTS_H
+#define __OSDELEMENTS_H
+
+using namespace std;
+
+#include <vdr/plugin.h>
+#include "services.h"
+
+/**********************************************************************
+* cOsdElement
+**********************************************************************/
+
+class cOsdElement {
+protected:
+ cSkinDisplayPlugin *view;
+ map < string, string > stringTokens;
+ map < string, int > intTokens;
+ map < string, vector< map< string, string > > > loopTokens;
+public:
+ cOsdElement(cSkinDisplayPlugin *view);
+ virtual ~cOsdElement();
+ void AddLoopToken(string loopName, map<string, string> &tokens);
+ void AddStringToken(string key, string value);
+ void AddIntToken(string key, int value);
+ void ClearTokens(void);
+ bool ChannelLogoExists(string channelId);
+ string GetEpgImagePath(void);
+};
+
+/**********************************************************************
+* cViewElement
+**********************************************************************/
+class cViewElement : public cOsdElement {
+private:
+ int viewElementID;
+public:
+ cViewElement(cSkinDisplayPlugin *view, int viewElementID);
+ virtual ~cViewElement();
+ void Clear(void);
+ void Display(void);
+};
+
+/**********************************************************************
+* cViewGrid
+**********************************************************************/
+class cViewGrid : public cOsdElement {
+private:
+ int viewGridID;
+public:
+ cViewGrid(cSkinDisplayPlugin *view, int viewGridID);
+ virtual ~cViewGrid();
+ void SetGrid(long gridID, double x, double y, double width, double height);
+ void SetCurrent(long gridID, bool current);
+ void MoveGrid(long gridID, double x, double y, double width, double height);
+ void Delete(long gridID);
+ void Clear(void);
+ void Display(void);
+};
+
+/**********************************************************************
+* cViewTab
+**********************************************************************/
+class cViewTab : public cOsdElement {
+private:
+public:
+ cViewTab(cSkinDisplayPlugin *view);
+ virtual ~cViewTab();
+ void Init(void);
+ void Left(void);
+ void Right(void);
+ void Up(void);
+ void Down(void);
+ void Display(void);
+};
+
+/**********************************************************************
+* cOsdView
+**********************************************************************/
+class cOsdView {
+private:
+ cSkinDisplayPlugin *displayPlugin;
+public:
+ cOsdView(cSkinDisplayPlugin *displayPlugin);
+ virtual ~cOsdView();
+ void Deactivate(bool hide);
+ void Activate(void);
+ cViewElement *GetViewElement(int viewElementID);
+ cViewGrid *GetViewGrid(int viewGridID);
+ cViewTab *GetViewTabs(void);
+ void Display(void);
+};
+
+#endif // __OSDELEMENTS_H \ No newline at end of file
diff --git a/libskindesigner/services.h b/libskindesigner/services.h
new file mode 100644
index 0000000..8fa9c69
--- /dev/null
+++ b/libskindesigner/services.h
@@ -0,0 +1,131 @@
+#ifndef __SKINDESIGNERSERVICES_H
+#define __SKINDESIGNERSERVICES_H
+
+using namespace std;
+
+#include <string>
+#include <vector>
+#include <map>
+
+enum eMenuType {
+ mtList,
+ mtText
+};
+
+class cSDDisplayMenu : public cSkinDisplayMenu {
+public:
+ virtual void SetTitle(const char *Title);
+ virtual void SetPluginMenu(string name, int menu, int type, bool init);
+ virtual bool SetItemPlugin(map<string,string> *stringTokens, map<string,int> *intTokens, map<string,vector<map<string,string> > > *loopTokens, int Index, bool Current, bool Selectable);
+ virtual bool SetPluginText(map<string,string> *stringTokens, map<string,int> *intTokens, map<string,vector<map<string,string> > > *loopTokens);
+};
+
+class cSkinDisplayPlugin {
+public:
+ cSkinDisplayPlugin(void);
+ virtual ~cSkinDisplayPlugin(void);
+ virtual void Deactivate(bool hide);
+ virtual void Activate(void);
+ virtual void ClearViewElement(int id);
+ virtual void DisplayViewElement(int id);
+ virtual void SetViewElementIntTokens(map<string,int> *intTokens);
+ virtual void SetViewElementStringTokens(map<string,string> *stringTokens);
+ virtual void SetViewElementLoopTokens(map<string,vector<map<string,string> > > *loopTokens);
+ virtual void InitGrids(int viewGridID);
+ virtual void SetGrid(int viewGridID, long gridID, double x, double y, double width, double height, map<string,int> *intTokens, map<string,string> *stringTokens);
+ virtual void SetGridCurrent(int viewGridID, long gridID, bool current);
+ virtual void DeleteGrid(int viewGridID, long gridID);
+ virtual void DisplayGrids(int viewGridID);
+ virtual void ClearGrids(int viewGridID);
+ virtual void SetTabIntTokens(map<string,int> *intTokens);
+ virtual void SetTabStringTokens(map<string,string> *stringTokens);
+ virtual void SetTabLoopTokens(map<string,vector<map<string,string> > > *loopTokens);
+ virtual void SetTabs(void);
+ virtual void TabLeft(void);
+ virtual void TabRight(void);
+ virtual void TabUp(void);
+ virtual void TabDown(void);
+ virtual void DisplayTabs(void);
+ virtual void Flush(void);
+ virtual bool ChannelLogoExists(string channelId);
+ virtual string GetEpgImagePath(void);
+};
+
+/*********************************************************************
+* Data Structures for Service Calls
+*********************************************************************/
+
+// Data structure for service "RegisterPlugin"
+class RegisterPlugin {
+public:
+ RegisterPlugin(void) {
+ name = "";
+ };
+ void SetMenu(int key, string templateName) {
+ menus.insert(pair<int, string>(key, templateName));
+ }
+ void SetView(int key, string templateName) {
+ views.insert(pair<int, string>(key, templateName));
+ }
+ void SetSubView(int view, int subView, string templateName) {
+ pair<int, string> sub = make_pair(subView, templateName);
+ subViews.insert(pair<int, pair<int, string> >(view, sub));
+ }
+ void SetViewElement(int view, int viewElement, string name) {
+ map< int, map<int, string> >::iterator hit = viewElements.find(view);
+ if (hit == viewElements.end()) {
+ map<int, string> vE;
+ vE.insert(pair<int, string >(viewElement, name));
+ viewElements.insert(pair<int, map < int, string > >(view, vE));
+ } else {
+ (hit->second).insert(pair<int, string >(viewElement, name));
+ }
+ }
+ void SetViewGrid(int view, int viewGrid, string name) {
+ map< int, map<int, string> >::iterator hit = viewGrids.find(view);
+ if (hit == viewGrids.end()) {
+ map<int, string> vG;
+ vG.insert(pair<int, string >(viewGrid, name));
+ viewGrids.insert(pair<int, map < int, string > >(view, vG));
+ } else {
+ (hit->second).insert(pair<int, string >(viewGrid, name));
+ }
+ }
+// in
+ string name; //name of plugin
+ map< int, string > menus; //menus as key -> templatename hashmap
+ map< int, string> views; //standalone views as key -> templatename hashmap
+ multimap< int, pair <int, string> > subViews; //subviews of standalone views as view -> (subview, templatename) multimap
+ map< int, map <int, string> > viewElements; //viewelements as key -> (viewelement, viewelementname) hashmap
+ map< int, map <int, string> > viewGrids; //viewgrids as key -> (viewgrid, viewgridname) hashmap
+//out
+};
+
+// Data structure for service "GetDisplayMenu"
+class GetDisplayMenu {
+public:
+ GetDisplayMenu(void) {
+ displayMenu = NULL;
+ };
+// in
+//out
+ cSDDisplayMenu *displayMenu;
+};
+
+// Data structure for service "GetDisplayPlugin"
+class GetDisplayPlugin {
+public:
+ GetDisplayPlugin(void) {
+ pluginName = "";
+ viewID = -1;
+ subViewID = -1;
+ displayPlugin = NULL;
+ };
+// in
+ string pluginName;
+ int viewID;
+ int subViewID;
+//out
+ cSkinDisplayPlugin *displayPlugin;
+};
+#endif //__SKINDESIGNERSERVICES_H
diff --git a/libskindesigner/skindesignerosdbase.cpp b/libskindesigner/skindesignerosdbase.cpp
new file mode 100644
index 0000000..02e1558
--- /dev/null
+++ b/libskindesigner/skindesignerosdbase.cpp
@@ -0,0 +1,211 @@
+#include "skindesignerosdbase.h"
+#include "osdelements.h"
+
+using namespace std;
+
+/**********************************************************************
+* cSkindesignerOsdObject
+**********************************************************************/
+
+cSkindesignerOsdObject::cSkindesignerOsdObject(void) {
+ pSkinDesigner = NULL;
+ pluginName = "";
+}
+
+cSkindesignerOsdObject::~cSkindesignerOsdObject() {
+}
+
+bool cSkindesignerOsdObject::InitSkindesignerInterface(string pluginName) {
+ this->pluginName = pluginName;
+ pSkinDesigner = cPluginManager::GetPlugin("skindesigner");
+ if (!pSkinDesigner) {
+ return false;
+ }
+ return true;
+}
+
+cOsdView *cSkindesignerOsdObject::GetOsdView(int viewID, int subViewID) {
+ cSkinDisplayPlugin *displayPlugin = NULL;
+ cOsdView *view = NULL;
+ GetDisplayPlugin call;
+ call.pluginName = pluginName;
+ call.viewID = viewID;
+ call.subViewID = subViewID;
+ bool ok = pSkinDesigner->Service("GetDisplayPlugin", &call);
+ if (ok) {
+ displayPlugin = call.displayPlugin;
+ view = new cOsdView(displayPlugin);
+ }
+ return view;
+}
+
+/**********************************************************************
+* cSkindesignerOsdItem
+**********************************************************************/
+cSkindesignerOsdItem::cSkindesignerOsdItem(eOSState State) : cOsdItem(State) {
+ sdDisplayMenu = NULL;
+}
+
+cSkindesignerOsdItem::cSkindesignerOsdItem(const char *Text, eOSState State, bool Selectable) : cOsdItem(Text, State, Selectable) {
+ sdDisplayMenu = NULL;
+}
+
+cSkindesignerOsdItem::~cSkindesignerOsdItem() {
+
+}
+
+void cSkindesignerOsdItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable) {
+ if (sdDisplayMenu) {
+ if (!sdDisplayMenu->SetItemPlugin(&stringTokens, &intTokens, &loopTokens, Index, Current, Selectable)) {
+ DisplayMenu->SetItem(Text(), Index, Current, Selectable);
+ }
+ } else {
+ DisplayMenu->SetItem(Text(), Index, Current, Selectable);
+ }
+}
+
+void cSkindesignerOsdItem::AddStringToken(string key, string value) {
+ stringTokens.insert(pair<string,string>(key, value));
+}
+
+void cSkindesignerOsdItem::AddIntToken(string key, int value) {
+ intTokens.insert(pair<string,int>(key, value));
+}
+
+void cSkindesignerOsdItem::AddLoopToken(string loopName, map<string, string> &tokens) {
+ map<string, vector<map<string, string> > >::iterator hitLoop = loopTokens.find(loopName);
+ if (hitLoop == loopTokens.end()) {
+ vector<map<string, string> > tokenVector;
+ tokenVector.push_back(tokens);
+ loopTokens.insert(pair<string, vector<map<string, string> > >(loopName, tokenVector));
+ } else {
+ vector<map<string, string> > *tokenVector = &hitLoop->second;
+ tokenVector->push_back(tokens);
+ }
+}
+
+
+/**********************************************************************
+* cSkindesignerOsdMenu
+**********************************************************************/
+cSkindesignerOsdMenu::cSkindesignerOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4) : cOsdMenu(Title, c0, c1, c2, c3, c4) {
+ init = true;
+ displayText = false;
+ sdDisplayMenu = NULL;
+ pluginName = "";
+ SetMenuCategory(mcPlugin);
+ SetSkinDesignerDisplayMenu();
+}
+
+cSkindesignerOsdMenu::~cSkindesignerOsdMenu() {
+
+}
+
+void cSkindesignerOsdMenu::SetPluginMenu(int menu, eMenuType type) {
+ if (type == mtList)
+ displayText = false;
+ else if (type == mtText)
+ displayText = true;
+
+ if (sdDisplayMenu) {
+ sdDisplayMenu->SetPluginMenu(pluginName, menu, type, init);
+ }
+ init = false;
+}
+
+bool cSkindesignerOsdMenu::SetSkinDesignerDisplayMenu(void) {
+ static cPlugin *pSkinDesigner = cPluginManager::GetPlugin("skindesigner");
+ if (!pSkinDesigner) {
+ return false;
+ }
+ GetDisplayMenu call;
+ bool ok = pSkinDesigner->Service("GetDisplayMenu", &call);
+ if (ok && call.displayMenu) {
+ sdDisplayMenu = call.displayMenu;
+ return true;
+ }
+ return false;
+}
+
+void cSkindesignerOsdMenu::ClearTokens(void) {
+ text = "";
+ stringTokens.clear();
+ intTokens.clear();
+ loopTokens.clear();
+}
+
+void cSkindesignerOsdMenu::AddStringToken(string key, string value) {
+ stringTokens.insert(pair<string,string>(key, value));
+}
+
+void cSkindesignerOsdMenu::AddIntToken(string key, int value) {
+ intTokens.insert(pair<string,int>(key, value));
+}
+
+void cSkindesignerOsdMenu::AddLoopToken(string loopName, map<string, string> &tokens) {
+ map<string, vector<map<string, string> > >::iterator hitLoop = loopTokens.find(loopName);
+ if (hitLoop == loopTokens.end()) {
+ vector<map<string, string> > tokenVector;
+ tokenVector.push_back(tokens);
+ loopTokens.insert(pair<string, vector<map<string, string> > >(loopName, tokenVector));
+ } else {
+ vector<map<string, string> > *tokenVector = &hitLoop->second;
+ tokenVector->push_back(tokens);
+ }
+}
+
+void cSkindesignerOsdMenu::TextKeyLeft(void) {
+ if (!displayText)
+ return;
+ DisplayMenu()->Scroll(true, true);
+}
+
+void cSkindesignerOsdMenu::TextKeyRight(void) {
+ if (!displayText)
+ return;
+ DisplayMenu()->Scroll(false, true);
+}
+
+void cSkindesignerOsdMenu::TextKeyUp(void) {
+ if (!displayText)
+ return;
+ DisplayMenu()->Scroll(true, false);
+}
+
+void cSkindesignerOsdMenu::TextKeyDown(void) {
+ if (!displayText)
+ return;
+ DisplayMenu()->Scroll(false, false);
+}
+
+void cSkindesignerOsdMenu::Display(void) {
+ if (displayText) {
+ if (sdDisplayMenu) {
+ sdDisplayMenu->SetTitle(Title());
+ if (sdDisplayMenu->SetPluginText(&stringTokens, &intTokens, &loopTokens)) {
+ sdDisplayMenu->Flush();
+ } else {
+ DisplayMenu()->Clear();
+ DisplayMenu()->SetTitle(Title());
+ DisplayMenu()->SetText(text.c_str(), false);
+ DisplayMenu()->Flush();
+ }
+ } else {
+ DisplayMenu()->Clear();
+ DisplayMenu()->SetTitle(Title());
+ DisplayMenu()->SetText(text.c_str(), false);
+ DisplayMenu()->Flush();
+ }
+ return;
+ }
+ if (sdDisplayMenu) {
+ sdDisplayMenu->SetTitle(Title());
+ for (cOsdItem *item = First(); item; item = Next(item)) {
+ cSkindesignerOsdItem *sdItem = dynamic_cast<cSkindesignerOsdItem*>(item);
+ if (sdItem) {
+ sdItem->SetDisplayMenu(sdDisplayMenu);
+ }
+ }
+ }
+ cOsdMenu::Display();
+}
diff --git a/libskindesigner/skindesignerosdbase.h b/libskindesigner/skindesignerosdbase.h
new file mode 100644
index 0000000..4c992f4
--- /dev/null
+++ b/libskindesigner/skindesignerosdbase.h
@@ -0,0 +1,86 @@
+#ifndef __SKINDESIGNEROSDBASE_H
+#define __SKINDESIGNEROSDBASE_H
+
+using namespace std;
+
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+#include <vdr/osdbase.h>
+#include <vdr/plugin.h>
+#include "services.h"
+
+class cOsdView;
+
+/**********************************************************************
+* cSkindesignerOsdObject
+**********************************************************************/
+class cSkindesignerOsdObject : public cOsdObject {
+protected:
+ string pluginName;
+ cPlugin *pSkinDesigner;
+ bool InitSkindesignerInterface(string pluginName);
+ cOsdView *GetOsdView(int viewID, int subViewID = -1);
+public:
+ cSkindesignerOsdObject(void);
+ virtual ~cSkindesignerOsdObject();
+ virtual void Show(void) {};
+};
+
+/**********************************************************************
+* cSkindesignerOsdItem
+**********************************************************************/
+class cSkindesignerOsdItem : public cOsdItem {
+private:
+ cSDDisplayMenu *sdDisplayMenu;
+ map < string, string > stringTokens;
+ map < string, int > intTokens;
+ map < string, vector< map< string, string > > > loopTokens;
+protected:
+public:
+ cSkindesignerOsdItem(eOSState State = osUnknown);
+ cSkindesignerOsdItem(const char *Text, eOSState State = osUnknown, bool Selectable = true);
+ virtual ~cSkindesignerOsdItem();
+ virtual void SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable);
+ void SetDisplayMenu(cSDDisplayMenu *sdDisplayMenu) { this->sdDisplayMenu = sdDisplayMenu; };
+ void AddStringToken(string key, string value);
+ void AddIntToken(string key, int value);
+ void AddLoopToken(string loopName, map<string, string> &tokens);
+};
+
+/**********************************************************************
+* cSkindesignerOsdMenu
+**********************************************************************/
+class cSkindesignerOsdMenu : public cOsdMenu {
+private:
+ bool init;
+ bool displayText;
+ string pluginName;
+ cSDDisplayMenu *sdDisplayMenu;
+ string text;
+ map < string, string > stringTokens;
+ map < string, int > intTokens;
+ map < string, vector< map< string, string > > > loopTokens;
+ bool SetSkinDesignerDisplayMenu(void);
+protected:
+ void ClearTokens(void);
+ void SetPluginName(string name) {pluginName = name; };
+ void SetPluginMenu(int menu, eMenuType type);
+ void SetText(string text) { this->text = text; };
+ void AddStringToken(string key, string value);
+ void AddIntToken(string key, int value);
+ void AddLoopToken(string loopName, map<string, string> &tokens);
+ void TextKeyLeft(void);
+ void TextKeyRight(void);
+ void TextKeyUp(void);
+ void TextKeyDown(void);
+public:
+ cSkindesignerOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
+ virtual ~cSkindesignerOsdMenu();
+ virtual void Display(void);
+};
+
+#endif // __SKINDESIGNEROSDBASE_H
+
diff --git a/plex.cpp b/plex.cpp
index ed8af98..61fd69b 100644
--- a/plex.cpp
+++ b/plex.cpp
@@ -2,6 +2,9 @@
#include "SubscriptionManager.h"
#include "plex.h"
#include "plexOsd.h"
+#include "plexSdOsd.h"
+
+#include "libskindesigner/services.h"
//////////////////////////////////////////////////////////////////////////////
// cPlugin
@@ -51,6 +54,27 @@ const char *cMyPlugin::Description(void)
bool cMyPlugin::Start(void)
{
+ std::string cacheDir = cPlugin::CacheDirectory(PLUGIN_NAME_I18N);
+
+ RegisterPlugin reg;
+ reg.name = "plex";
+
+ reg.SetView(viRootView, "root.xml");
+ reg.SetViewGrid(eViews::viRootView, eViewGrids::vgBrowser, "browser");
+ reg.SetViewElement(viRootView, verHeader, "header");
+
+ //reg.SetViewElement(viRootView, verHeader, "header");
+ //reg.SetViewElement(viRootView, verFooter, "footer");
+
+ //reg.SetView(eViews::viBrowserView, "browser.xml");
+
+
+ static cPlugin *pSkinDesigner = cPluginManager::GetPlugin("skindesigner");
+ if (pSkinDesigner) {
+ pSkinDesigner->Service("RegisterPlugin", &reg);
+ } else {
+ esyslog("[plex]: skindesigner not available");
+ }
return true;
}
@@ -83,7 +107,13 @@ const char *cMyPlugin::MainMenuEntry(void)
cOsdObject *cMyPlugin::MainMenuAction(void)
{
//dsyslog("[plex]%s:\n", __FUNCTION__);
- return cPlexMenu::ProcessMenu();
+ /*bool skinDesignerAvailable = InitSkindesignerInterface("plex");
+ if (skinDesignerAvailable) {
+ //cOsdView *rootView = GetOsdView(viRootView);
+ return new cPlexSdOsd();
+ }
+ return cPlexMenu::ProcessMenu();*/
+ return new cPlexSdOsd();
}
/**
diff --git a/plexOsd.cpp b/plexOsd.cpp
index 55f26b3..8a54cc8 100644
--- a/plexOsd.cpp
+++ b/plexOsd.cpp
@@ -165,48 +165,6 @@ eOSState cPlexBrowser::ProcessSelected()
}
-cPlexInfo::cPlexInfo(plexclient::Video* video) : cOsdMenu(video->GetTitle().c_str())
-{
- cOsdMenu::Display();
-
- Add(new cOsdItem(video->m_sSummary.c_str()));
-}
-
-eOSState cPlexInfo::ProcessKey(eKeys Key)
-{
- switch (int(Key)) {
- case kUp|k_Repeat:
- case kUp:
- case kDown|k_Repeat:
- case kDown:
- case kLeft|k_Repeat:
- case kLeft:
- case kRight|k_Repeat:
- case kRight:
- DisplayMenu()->Scroll(NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft, NORMALKEY(Key) == kLeft || NORMALKEY(Key) == kRight);
- cStatus::MsgOsdTextItem(NULL, NORMALKEY(Key) == kUp || NORMALKEY(Key) == kLeft);
- return osContinue;
- case kInfo:
- return osBack;
- default:
- break;
- }
-
- eOSState state = cOsdMenu::ProcessKey(Key);
-
- if (state == osUnknown) {
- switch (Key) {
- case kGreen:
- cRemote::Put(Key, true);
- case kOk:
- return osBack;
- default:
- break;
- }
- }
- return state;
-}
-
//////////////////////////////////////////////////////////////////////////////
// cOsdMenu
//////////////////////////////////////////////////////////////////////////////
@@ -214,10 +172,10 @@ eOSState cPlexInfo::ProcessKey(eKeys Key)
menuShow cPlexMenu::eShow = MAIN;
/**
-** Play menu constructor.
+** Plex menu constructor.
*/
cPlexMenu::cPlexMenu(const char *title, int c0, int c1, int c2, int c3, int c4)
- :cOsdMenu(title, c0, c1, c2, c3, c4)
+ :cOsdMenu(title)
{
SetHasHotkeys();
diff --git a/plexOsd.h b/plexOsd.h
index d6a14f4..b044b10 100644
--- a/plexOsd.h
+++ b/plexOsd.h
@@ -19,11 +19,9 @@
enum menuShow {
MAIN,
- BROWSER,
- INFO
+ BROWSER
};
-
/*
* Plex Browser
*/
@@ -56,13 +54,6 @@ public:
};
-class cPlexInfo : public cOsdMenu
-{
-
-public:
- cPlexInfo(plexclient::Video* video);
- virtual eOSState ProcessKey(eKeys Keys);
-};
/**
** Play plugin menu class.
@@ -71,6 +62,7 @@ class cPlexMenu:public cOsdMenu
{
private:
+ void SetRootMenu();
public:
cPlexMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0);
virtual eOSState ProcessKey(eKeys);
diff --git a/plexSdOsd.cpp b/plexSdOsd.cpp
new file mode 100644
index 0000000..e6dc1f9
--- /dev/null
+++ b/plexSdOsd.cpp
@@ -0,0 +1,104 @@
+#include "plexSdOsd.h"
+
+cPlexSdOsd::cPlexSdOsd()
+{
+}
+
+void cPlexSdOsd::Show(void)
+{
+ bool skinDesignerAvailable = InitSkindesignerInterface("plex");
+ if (!skinDesignerAvailable) {
+ return;
+ }
+
+ m_pRootView = GetOsdView(eViews::viRootView);
+ if (!m_pRootView) {
+ esyslog("[plex]: used skindesigner skin does not support plex");
+ return;
+ }
+
+ 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))
+ );
+
+ Flush();
+}
+
+void cPlexSdOsd::Flush()
+{
+ m_pBrowserGrid->Flush();
+
+ m_pViewHeader->Draw();
+
+ m_pRootView->Display();
+}
+
+eOSState cPlexSdOsd::ProcessKey(eKeys Key)
+{
+ switch (Key & ~k_Repeat) {
+ case kUp:
+ m_pBrowserGrid->NavigateUp();
+ Flush();
+ break;
+ case kDown:
+ m_pBrowserGrid->NavigateDown();
+ Flush();
+ break;
+ case kLeft:
+ m_pBrowserGrid->NavigateLeft();
+ Flush();
+ break;
+ case kRight:
+ m_pBrowserGrid->NavigateRight();
+ Flush();
+ break;
+ case kOk:
+ // Play movie or change dir
+ m_pBrowserGrid->NavigateSelect();
+ Flush();
+ break;
+ case kBack:
+ m_pBrowserGrid->NavigateBack();
+ Flush();
+ break;
+ case kRed:
+ // Prev Tab
+ SwitchGrid(m_pViewHeader->NextTab());
+ Flush();
+ break;
+ case kGreen:
+ // Next Tab
+ SwitchGrid(m_pViewHeader->PrevTab());
+ Flush();
+ break;
+ default:
+ break;
+ }
+ return eOSState::osContinue;
+}
+
+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" ) );
+ m_pBrowserGrid = std::shared_ptr<cBrowserGrid>(
+ new cBrowserGrid( m_pRootView->GetViewGrid(eViewGrids::vgBrowser), service)
+ );
+
+ } 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" ) );
+ m_pBrowserGrid = std::shared_ptr<cBrowserGrid>(
+ new cBrowserGrid( m_pRootView->GetViewGrid(eViewGrids::vgBrowser), service)
+ );
+
+ } else if(currentTab == ePlexMenuTab::pmtLibrary) {
+
+ m_pBrowserGrid = std::shared_ptr<cBrowserGrid>(
+ new cBrowserGrid( m_pRootView->GetViewGrid(eViewGrids::vgBrowser))
+ );
+ }
+}
diff --git a/plexSdOsd.h b/plexSdOsd.h
new file mode 100644
index 0000000..1f7c677
--- /dev/null
+++ b/plexSdOsd.h
@@ -0,0 +1,55 @@
+#ifndef CPLEXSDOSD_H
+#define CPLEXSDOSD_H
+
+#include <vdr/osdbase.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <memory>
+
+#include "Config.h"
+#include "Plexservice.h"
+
+#include "plexgdm.h"
+#include "hlsPlayerControl.h"
+
+#include "browserGrid.h"
+#include "viewHeader.h"
+#include "libskindesigner/osdelements.h"
+#include "libskindesigner/skindesignerosdbase.h"
+
+enum eViews {
+ viRootView,
+ viDetailView
+};
+
+enum eViewElementsRoot {
+ verHeader,
+ verFooter
+};
+
+enum eViewGrids {
+ vgBrowser
+};
+
+class cPlexSdOsd : public cSkindesignerOsdObject
+{
+private:
+ std::shared_ptr<cBrowserGrid> m_pBrowserGrid;
+ std::shared_ptr<cViewHeader> m_pViewHeader;
+ cOsdView* m_pRootView;
+
+ void Flush();
+ void SwitchGrid(ePlexMenuTab currentTab);
+
+public:
+ cPlexSdOsd();
+ virtual void Show(void);
+ virtual eOSState ProcessKey(eKeys Key);
+
+};
+
+#endif // CPLEXSDOSD_H
diff --git a/po/de_DE.po b/po/de_DE.po
index a283e4e..ce76e7d 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-plex 0.1.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2015-03-05 20:04+0100\n"
+"POT-Creation-Date: 2015-03-15 11:38+0100\n"
"PO-Revision-Date: 2015-03-05 20:08+0200\n"
"Last-Translator: Chris <zerov83@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -60,6 +60,10 @@ msgstr "Untertitelspuren"
msgid "None"
msgstr "Leer"
+#, c-format
+msgid "To start from %ld minutes, press Ok."
+msgstr "Wiedergabe ab Minute %ld starten?"
+
msgid "Info"
msgstr "Info"
@@ -87,10 +91,6 @@ msgstr "Kein Plexmediaserver gefunden."
msgid "Browse Plex"
msgstr "Durchsuche Plex"
-#, c-format
-msgid "To start from %ld minutes, press Ok."
-msgstr "Wiedergabe ab Minute %ld starten?"
-
msgid "All Movies"
msgstr "Alle Filme"
diff --git a/skins/blackhole/xmlfiles/plug-plex-root.xml b/skins/blackhole/xmlfiles/plug-plex-root.xml
new file mode 100644
index 0000000..c937ce7
--- /dev/null
+++ b/skins/blackhole/xmlfiles/plug-plex-root.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!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 header
+ {title}
+ {istab1active}
+ {tab1name}
+ {istab2active}
+ {tab2name}
+ {istab3active}
+ {tab3name}
+ -->
+ <viewelement name="header">
+ <area layer="1" 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}" />
+ </area>
+ </viewelement>
+
+ <!-- Tokens available in browser
+ {current} Currently active element
+ {title} Name of the element
+ {year}
+ {cover} Image
+
+ {isdummy} Condition
+
+ {isserver} Condition
+ {serverstartpointname}
+ {serverip}
+ {serverport}
+ {serverversion}
+
+ {isdirectory} Condition
+ {isshow} Condition
+ {isseason} Condition
+
+ {ismovie}
+
+ {isepisode}
+
+ -->
+ <grid name="browser" x="0" y="15%" width="100%" height="85%">
+ <area layer="2">
+ <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" />
+ <drawtext condition="{isepisode}" x="1%" y="40%" width="98%" font="{light}" fontsize="5%" color="{clrWhite}" text="Episode" />
+ </area>
+ </grid>
+
+</displayplugin>
diff --git a/viewGridNavigator.cpp b/viewGridNavigator.cpp
new file mode 100644
index 0000000..78781ca
--- /dev/null
+++ b/viewGridNavigator.cpp
@@ -0,0 +1,158 @@
+#include "viewGridNavigator.h"
+
+unsigned int cGridElement::AbsoluteGridIdCounter = 0;
+
+cGridElement::cGridElement()
+{
+ m_iGridId = AbsoluteGridIdCounter++;
+ Position = -1;
+ m_bInit = true;
+}
+
+cViewGridNavigator::cViewGridNavigator(cViewGrid* viewGrid)
+{
+ m_columns = 2;
+ m_rows = 2;
+ m_newDimensions = true;
+ m_setIterator = true;
+
+ m_pGrid = std::shared_ptr<cViewGrid>(viewGrid);
+}
+
+
+void cViewGridNavigator::FilterElements(int scrollOffset)
+{
+ int startOffset = scrollOffset;
+ int endOffset = startOffset + (m_rows * m_columns);
+ if(scrollOffset < 0) {
+ endOffset = (m_rows * m_columns) + scrollOffset;
+ }
+
+ std::vector<cGridElement*>::iterator begin = m_firstElementIter + startOffset;
+ std::vector<cGridElement*>::iterator end = m_firstElementIter + endOffset;
+ if(end > m_vElements.end()) end = m_vElements.end();
+
+ int pos = 0;
+ for(std::vector<cGridElement*>::iterator it = begin; it != end; ++it) {
+ cGridElement *elem = *it;
+ elem->Position = pos++;
+ SetGridElementData(elem);
+ }
+
+ if(m_setIterator) {
+ m_activeElementIter = begin;
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), true);
+ m_setIterator = false;
+ }
+
+ //remove non visible elements from grid
+ if(scrollOffset !=0 ) {
+ auto startIt = m_firstElementIter;
+ auto endIt = m_firstElementIter + scrollOffset;
+ if(scrollOffset < 0) {
+ startIt = m_lastElementIter + scrollOffset;
+ endIt = m_lastElementIter;
+ }
+ if(startIt < m_vElements.begin()) startIt = m_vElements.begin();
+ if(endIt > m_vElements.end()) endIt = m_vElements.end();
+
+ for(std::vector<cGridElement*>::iterator it = startIt; it != endIt; ++it) {
+ m_pGrid->Delete((*it)->GridElementId());
+ (*it)->Dirty();
+ (*it)->Position = -1;
+ }
+ }
+
+ m_firstElementIter = begin;
+ m_lastElementIter = end;
+ m_newDimensions = false;
+}
+
+void cViewGridNavigator::SetGridElementData(cGridElement *obj)
+{
+ // calculate position
+ double row, column, x, y, height, width;
+
+ row = floor(obj->Position / m_columns);
+ column = obj->Position - (row * m_columns);
+ width = 1.0 / m_columns;
+ height = 1.0 / m_rows;
+ x = width * column;
+ 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;
+
+ if(obj->IsNew() || m_newDimensions) {
+ // fill data
+ obj->AddTokens(m_pGrid);
+ m_pGrid->SetGrid(obj->GridElementId(), x, y, width, height);
+ obj->InitFinished();
+ } else {
+ m_pGrid->MoveGrid(obj->GridElementId(), x, y, width, height);
+ }
+}
+
+void cViewGridNavigator::SetGridDimensions(int rows, int columns)
+{
+ m_rows = rows;
+ m_columns = columns;
+ m_newDimensions = true;
+}
+
+void cViewGridNavigator::NavigateDown()
+{
+ if(m_activeElementIter + m_columns >= m_vElements.end()) return;
+ auto next = m_activeElementIter + m_columns;
+ // scroll down?
+ if(!(*next)->IsVisible()) {
+ FilterElements(m_columns);
+ }
+
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+}
+
+void cViewGridNavigator::NavigateUp()
+{
+ if(m_activeElementIter - m_columns < m_vElements.begin()) return;
+ auto next = m_activeElementIter - m_columns;
+ //scroll up?
+ if(!(*next)->IsVisible()) {
+ FilterElements(-m_columns);
+ }
+
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+}
+
+void cViewGridNavigator::NavigateLeft()
+{
+ auto next = m_activeElementIter - 1;
+ if(next < m_vElements.begin()) next = m_vElements.begin();
+
+ if(!(*next)->IsVisible()) {
+ auto temp = m_activeElementIter;
+ FilterElements(-m_columns);
+ m_activeElementIter = temp;
+ }
+
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+}
+
+void cViewGridNavigator::NavigateRight()
+{
+ auto next = m_activeElementIter + 1;
+ if(next >= m_vElements.end()) next = m_vElements.end()-1;
+
+ if(!(*next)->IsVisible()) {
+ FilterElements(m_columns);
+ }
+
+ m_pGrid->SetCurrent((*m_activeElementIter)->GridElementId(), false);
+ m_pGrid->SetCurrent((*next)->GridElementId(), true);
+ m_activeElementIter = next;
+}
diff --git a/viewGridNavigator.h b/viewGridNavigator.h
new file mode 100644
index 0000000..cc17dd5
--- /dev/null
+++ b/viewGridNavigator.h
@@ -0,0 +1,61 @@
+#ifndef CVIEWGRIDNAVIGATOR_H
+#define CVIEWGRIDNAVIGATOR_H
+
+#include <memory>
+#include <vector>
+#include "libskindesigner/osdelements.h"
+
+class cGridElement
+{
+private:
+ bool m_bInit;
+ unsigned int m_iGridId;
+ static unsigned int AbsoluteGridIdCounter;
+
+public:
+ cGridElement();
+
+ bool IsNew() { return m_bInit; };
+ void Dirty() { m_bInit = true; };
+ 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;
+ int Position;
+};
+
+class cViewGridNavigator
+{
+protected:
+ int m_rows;
+ int m_columns;
+
+ std::shared_ptr<cViewGrid> m_pGrid;
+
+ bool m_newDimensions;
+ bool m_setIterator;
+ std::vector<cGridElement*> m_vElements;
+ std::vector<cGridElement*>::iterator m_activeElementIter;
+ std::vector<cGridElement*>::iterator m_firstElementIter;
+ std::vector<cGridElement*>::iterator m_lastElementIter;
+
+ void GenerateServerElements();
+ void FilterElements(int scrollOffset);
+ void SetGridElementData(cGridElement *obj);
+
+public:
+ cViewGridNavigator(cViewGrid* viewGrid);
+ void SetGridDimensions(int rows, int columns);
+ void Flush() { m_pGrid->Display(); };
+ void DrawGrid() { m_pGrid->Display(); }
+ virtual void NavigateLeft();
+ virtual void NavigateRight();
+ virtual void NavigateUp();
+ virtual void NavigateDown();
+ virtual eOSState NavigateSelect() = 0;
+ virtual eOSState NavigateBack() = 0;
+ cGridElement* SelectedObject() { return *m_activeElementIter; }
+
+};
+
+#endif // CVIEWGRIDNAVIGATOR_H
diff --git a/viewHeader.cpp b/viewHeader.cpp
new file mode 100644
index 0000000..932ef24
--- /dev/null
+++ b/viewHeader.cpp
@@ -0,0 +1,61 @@
+#include "viewHeader.h"
+
+cViewHeader::cViewHeader(cViewElement* viewElem)
+{
+ m_pViewElem = std::shared_ptr<cViewElement>(viewElem);
+ m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
+}
+
+void cViewHeader::Draw()
+{
+ m_pViewElem->ClearTokens();
+
+ switch(m_eCurrentTab) {
+ case ePlexMenuTab::pmtOnDeck:
+ m_pViewElem->AddIntToken("istab1active", 1);
+ m_pViewElem->AddStringToken("tab1name", "On Deck");
+ break;
+ case ePlexMenuTab::pmtRecentlyAdded:
+ m_pViewElem->AddIntToken("istab2active", 1);
+ m_pViewElem->AddStringToken("tab2name", "Recently Added");
+ break;
+ case ePlexMenuTab::pmtLibrary:
+ m_pViewElem->AddIntToken("istab3active", 1);
+ m_pViewElem->AddStringToken("tab3name", "Library");
+ break;
+ }
+
+ m_pViewElem->Display();
+}
+
+ePlexMenuTab cViewHeader::NextTab()
+{
+ switch(m_eCurrentTab) {
+ case ePlexMenuTab::pmtOnDeck:
+ m_eCurrentTab = ePlexMenuTab::pmtRecentlyAdded;
+ break;
+ case ePlexMenuTab::pmtRecentlyAdded:
+ m_eCurrentTab = ePlexMenuTab::pmtLibrary;
+ break;
+ case ePlexMenuTab::pmtLibrary:
+ m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
+ break;
+ }
+ return m_eCurrentTab;
+}
+
+ePlexMenuTab cViewHeader::PrevTab()
+{
+ switch(m_eCurrentTab) {
+ case ePlexMenuTab::pmtOnDeck:
+ m_eCurrentTab = ePlexMenuTab::pmtLibrary;
+ break;
+ case ePlexMenuTab::pmtRecentlyAdded:
+ m_eCurrentTab = ePlexMenuTab::pmtOnDeck;
+ break;
+ case ePlexMenuTab::pmtLibrary:
+ m_eCurrentTab = ePlexMenuTab::pmtRecentlyAdded;
+ break;
+ }
+ return m_eCurrentTab;
+}
diff --git a/viewHeader.h b/viewHeader.h
new file mode 100644
index 0000000..afdb38f
--- /dev/null
+++ b/viewHeader.h
@@ -0,0 +1,27 @@
+#ifndef CVIEWHEADER_H
+#define CVIEWHEADER_H
+
+#include <memory>
+#include "libskindesigner/osdelements.h"
+
+enum ePlexMenuTab {
+ pmtOnDeck,
+ pmtRecentlyAdded,
+ pmtLibrary
+};
+
+class cViewHeader
+{
+private:
+ ePlexMenuTab m_eCurrentTab;
+ std::shared_ptr<cViewElement> m_pViewElem;
+
+public:
+ cViewHeader(cViewElement* viewElem);
+ void Draw();
+ ePlexMenuTab NextTab();
+ ePlexMenuTab PrevTab();
+ ePlexMenuTab CurrentTab() { return m_eCurrentTab; }
+};
+
+#endif // CVIEWHEADER_H