summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian <zerov83@gmail.com>2016-03-08 22:14:49 +0100
committerChristian <zerov83@gmail.com>2016-03-08 22:14:49 +0100
commite63b1337cb98ddfa136de78628f5048b682276ff (patch)
treef164267d8b4171a21a8a264cc41226e53f4ef056
parent662171f45281deacdf2db255909be11ec869122c (diff)
downloadvdr-plugin-plex-e63b1337cb98ddfa136de78628f5048b682276ff.tar.gz
vdr-plugin-plex-e63b1337cb98ddfa136de78628f5048b682276ff.tar.bz2
Skindesigner "DetailView" in development
-rw-r--r--Config.cpp2
-rw-r--r--Config.h3
-rw-r--r--Directory.cpp4
-rw-r--r--Makefile3
-rw-r--r--MediaContainer.cpp2
-rw-r--r--MediaContainer.h3
-rw-r--r--PVideo.cpp30
-rw-r--r--PVideo.h3
-rw-r--r--Stream.cpp6
-rw-r--r--XmlObject.cpp64
-rw-r--r--XmlObject.h8
-rw-r--r--browserGrid.cpp7
-rw-r--r--detailView.cpp166
-rw-r--r--detailView.h30
-rw-r--r--hlsPlayer.cpp4
-rw-r--r--hlsPlayerControl.cpp6
-rw-r--r--plex.cpp27
-rw-r--r--plexSdOsd.cpp188
-rw-r--r--plexSdOsd.h9
-rw-r--r--templates/plug-plex-root.xml2
-rw-r--r--tokendefinitions.h27
-rw-r--r--viewGridNavigator.h1
22 files changed, 506 insertions, 89 deletions
diff --git a/Config.cpp b/Config.cpp
index 62728ba..30baac8 100644
--- a/Config.cpp
+++ b/Config.cpp
@@ -17,6 +17,8 @@ Config::Config() {
ListGridRows = 12;
DetailGridColumns = 1;
DetailGridRows = 4;
+ ExtrasGridColumns = 4;
+ ExtrasGridRows = 1;
UseMpv = false;
UseAc3 = true;
diff --git a/Config.h b/Config.h
index 9673503..0a31ae1 100644
--- a/Config.h
+++ b/Config.h
@@ -57,6 +57,9 @@ public:
int DetailGridColumns;
int DetailGridRows;
+
+ int ExtrasGridColumns;
+ int ExtrasGridRows;
ViewMode DefaultViewMode;
diff --git a/Directory.cpp b/Directory.cpp
index 100b830..d4cbb09 100644
--- a/Directory.cpp
+++ b/Directory.cpp
@@ -65,7 +65,7 @@ std::string Directory::GetTitle()
seriesTitle = m_pParent->m_sParentTitle;
switch(m_eType) {
- case SEASON:
+ case MediaType::SEASON:
return Poco::format(tr("%s - Season %d"), seriesTitle, m_iIndex);
default:
return m_sTitle;
@@ -78,7 +78,7 @@ void Directory::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bo
if(clear) grid->ClearTokens();
grid->AddIntToken((int)(eTokenGridInt::viewmode), Config::GetInstance().DefaultViewMode);
grid->AddStringToken((int)(eTokenGridStr::title), m_sTitle.c_str());
- grid->AddIntToken((int)(eTokenGridInt::viewgroup), m_pParent->m_eViewGroup);
+ grid->AddIntToken((int)(eTokenGridInt::viewgroup), (int)m_pParent->m_eViewGroup);
// Thumb, Cover, Episodepicture
bool cached = false;
diff --git a/Makefile b/Makefile
index 53cc053..1eed6d1 100644
--- a/Makefile
+++ b/Makefile
@@ -94,7 +94,8 @@ OBJS = $(PLUGIN).o \
Stream.o \
Media.o \
plexOsd.o \
- device.o
+ device.o \
+ playlist.o
ifneq ($(DISABLESKINDESIGNER),1)
OBJS += plexSdOsd.o \
diff --git a/MediaContainer.cpp b/MediaContainer.cpp
index 4ad2a52..c7d4e5c 100644
--- a/MediaContainer.cpp
+++ b/MediaContainer.cpp
@@ -50,6 +50,8 @@ MediaContainer::MediaContainer(std::istream* response, PlexServer* Server)
m_vVideos.push_back(Video(pNode, m_pServer, this));
} else if(Poco::icompare(pNode->nodeName(), "Device") == 0) {
m_vDevices.push_back(Device(pNode, this));
+ } else if(Poco::icompare(pNode->nodeName(), "Playlist") == 0) {
+ m_vPlaylists.push_back(Playlist(pNode, this));
}
pNode = it.nextNode();
diff --git a/MediaContainer.h b/MediaContainer.h
index 978311c..0f385be 100644
--- a/MediaContainer.h
+++ b/MediaContainer.h
@@ -20,6 +20,7 @@
#include "PlexServer.h"
#include "Config.h"
#include "device.h"
+#include "playlist.h"
using Poco::XML::DOMParser;
using Poco::XML::InputSource;
@@ -35,6 +36,7 @@ namespace plexclient
class Video;
class Directory;
class Device;
+class Playlist;
class MediaContainer: XmlObject
{
@@ -49,6 +51,7 @@ public:
std::vector<Directory> m_vDirectories;
std::vector<Video> m_vVideos;
std::vector<Device> m_vDevices;
+ std::vector<Playlist> m_vPlaylists;
bool m_bAllowSync;
std::string m_sArt;
diff --git a/PVideo.cpp b/PVideo.cpp
index d130a09..11f48ad 100644
--- a/PVideo.cpp
+++ b/PVideo.cpp
@@ -20,7 +20,7 @@ Video::Video(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent)
Parse(pNode);
m_pParent = parent;
- if (m_iParentIndex < 0) {
+ if (m_iParentIndex < 0 && m_pParent) {
m_iParentIndex = parent->m_iParentIndex;
}
}
@@ -28,7 +28,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_pServer->GetUri(), m_iRatingKey));
+ Poco::URI fileuri(Poco::format("%s/library/metadata/%d?includeExtras=1", 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);
@@ -101,6 +101,7 @@ void Video::Parse(Poco::XML::Node* pNode)
m_tAddedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("addedAt"));
m_tUpdatedAt = GetNodeValueAsTimeStamp(pAttribs->getNamedItem("updatedAt"));
m_tOriginallyAvailableAt = GetNodeValueAsDateTime(pAttribs->getNamedItem("originallyAvailableAt"));
+ m_eExtraType = GetNodeValueAsExtraType(pAttribs->getNamedItem("extraType"));
pAttribs->release();
@@ -135,11 +136,26 @@ void Video::Parse(Poco::XML::Node* pNode)
Poco::XML::AutoPtr<Poco::XML::NamedNodeMap> pAttribs = pChildNode->attributes();
m_sCollection = GetNodeValue(pAttribs->getNamedItem("tag"));
pAttribs->release();
+ } else if(Poco::icompare(pChildNode->nodeName(), "Extras") == 0) {
+ ParseExtras(pChildNode);
}
pChildNode = it.nextNode();
}
}
+void Video::ParseExtras(Poco::XML::Node* pNode)
+{
+ NodeIterator it(pNode, Poco::XML::NodeFilter::SHOW_ALL);
+ Poco::XML::Node* pChildNode = it.nextNode();
+
+ while(pChildNode) {
+ if(Poco::icompare(pChildNode->nodeName(), "Video") == 0) {
+ m_vExtras.push_back(Video(pChildNode, m_pServer, NULL));
+ }
+ pChildNode = it.nextNode();
+ }
+}
+
std::string Video::GetTitle()
{
std::string res = m_sTitle;
@@ -149,14 +165,14 @@ std::string Video::GetTitle()
seriesTitle = m_pParent->m_sGrandparentTitle;
switch(m_tType) {
- case MOVIE:
+ case MediaType::MOVIE:
if(m_iYear > 0) {
res = Poco::format("%s (%d)", m_sTitle, m_iYear);
} else {
res = m_sTitle;
}
break;
- case EPISODE:
+ case MediaType::EPISODE:
res = Poco::format("%s - %02dx%02d - %s", seriesTitle, m_iParentIndex, m_iIndex, m_sTitle);
break;
default:
@@ -248,7 +264,7 @@ void Video::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool c
grid->AddIntToken((int)(eTokenGridInt::viewoffsetpercent), 0);
grid->AddIntToken((int)(eTokenGridInt::duration), m_iDuration/1000/60);
grid->AddIntToken((int)(eTokenGridInt::year), m_iYear);
- grid->AddIntToken((int)(eTokenGridInt::viewgroup), m_pParent->m_eViewGroup);
+ if(m_pParent) grid->AddIntToken((int)(eTokenGridInt::viewgroup), (int)m_pParent->m_eViewGroup);
// Thumb, Cover, Episodepicture
bool cached = false;
@@ -262,8 +278,10 @@ void Video::AddTokens(std::shared_ptr<skindesignerapi::cOsdElement> grid, bool c
grid->AddIntToken((int)(eTokenGridInt::hasart), cached);
if (cached) grid->AddStringToken((int)(eTokenGridStr::art), art.c_str());
- if(m_tType == MediaType::MOVIE || m_tType == MediaType::CLIP) {
+ if(m_tType == MediaType::MOVIE) {
grid->AddIntToken((int)(eTokenGridInt::ismovie), true);
+ } else if (m_tType == MediaType::CLIP) {
+ grid->AddIntToken((int)(eTokenGridInt::isclip), true);
}
vector<int> loopInfo;
diff --git a/PVideo.h b/PVideo.h
index f4d8e0c..8330d53 100644
--- a/PVideo.h
+++ b/PVideo.h
@@ -47,6 +47,7 @@ class Video: private XmlObject
private:
MediaContainer* m_pParent;
void Parse(Poco::XML::Node* pNode);
+ void ParseExtras(Poco::XML::Node* pNode);
public:
Video(Poco::XML::Node* pNode, PlexServer* Server, MediaContainer* parent);
@@ -87,6 +88,8 @@ public:
int m_iMyPlayOffset;
int m_iIndex;
int m_iParentIndex;
+ std::vector<Video> m_vExtras;
+ ExtraType m_eExtraType;
virtual std::string GetTitle();
bool SetStream(Stream* stream);
diff --git a/Stream.cpp b/Stream.cpp
index 7c02b5e..3f466f4 100644
--- a/Stream.cpp
+++ b/Stream.cpp
@@ -27,9 +27,9 @@ Stream::Stream(Poco::XML::Node* pNode)
std::string Stream::GetSetStreamQuery()
{
- if(m_eStreamType == sAUDIO) return Poco::format("audioStreamID=%d", m_iID);
- else if(m_eStreamType == sSUBTITLE && m_iID >= 0) return Poco::format("subtitleStreamID=%d", m_iID);
- else if(m_eStreamType == sSUBTITLE && m_iID < 0) return "subtitleStreamID=";
+ if(m_eStreamType == StreamType::sAUDIO) return Poco::format("audioStreamID=%d", m_iID);
+ else if(m_eStreamType == StreamType::sSUBTITLE && m_iID >= 0) return Poco::format("subtitleStreamID=%d", m_iID);
+ else if(m_eStreamType == StreamType::sSUBTITLE && m_iID < 0) return "subtitleStreamID=";
else return "";
}
diff --git a/XmlObject.cpp b/XmlObject.cpp
index e934980..8c01dd7 100644
--- a/XmlObject.cpp
+++ b/XmlObject.cpp
@@ -82,24 +82,24 @@ Poco::DateTime XmlObject::GetNodeValueAsDateTime(Poco::XML::Node* pNode)
MediaType XmlObject::GetNodeValueAsMediaType(Poco::XML::Node* pNode)
{
- MediaType type = UNDEF;
+ MediaType type = MediaType::UNDEF;
if(pNode != 0) {
std::string sType = pNode->nodeValue();
if (Poco::icompare(sType, "photo") == 0) {
- type = PHOTO;
+ type = MediaType::PHOTO;
} else if (Poco::icompare(sType, "movie") == 0) {
- type = MOVIE;
+ type = MediaType::MOVIE;
} else if (Poco::icompare(sType, "music") == 0) {
- type = MUSIC;
+ type = MediaType::MUSIC;
} else if (Poco::icompare(sType, "show") == 0) {
- type = SHOW;
+ type = MediaType::SHOW;
} else if (Poco::icompare(sType, "season") == 0) {
- type = SEASON;
+ type = MediaType::SEASON;
} else if (Poco::icompare(sType, "episode") == 0) {
- type = EPISODE;
+ type = MediaType::EPISODE;
} else if (Poco::icompare(sType, "clip") == 0) {
- type = CLIP;
+ type = MediaType::CLIP;
}
}
return type;
@@ -107,22 +107,60 @@ MediaType XmlObject::GetNodeValueAsMediaType(Poco::XML::Node* pNode)
StreamType XmlObject::GetNodeValueAsStreamType(Poco::XML::Node* pNode)
{
- StreamType type = sUNDEF;
+ StreamType type = StreamType::sUNDEF;
if(pNode != 0) {
int iType = GetNodeValueAsInt(pNode);
switch(iType) {
case 1:
- type = sVIDEO;
+ type = StreamType::sVIDEO;
break;
case 2:
- type = sAUDIO;
+ type = StreamType::sAUDIO;
break;
case 3:
- type = sSUBTITLE;
+ type = StreamType::sSUBTITLE;
break;
default:
- type = sUNDEF;
+ type = StreamType::sUNDEF;
+ break;
+ }
+ }
+ return type;
+}
+
+PlaylistType XmlObject::GetNodeValueAsPlaylistType(Poco::XML::Node* pNode)
+{
+ PlaylistType type = PlaylistType::Undef;
+
+ if(pNode != 0) {
+ std::string sType = pNode->nodeValue();
+ if (Poco::icompare(sType, "photo") == 0) {
+ type = PlaylistType::Photo;
+ } else if (Poco::icompare(sType, "video") == 0) {
+ type = PlaylistType::Video;
+ } else if (Poco::icompare(sType, "audio") == 0) {
+ type = PlaylistType::Audio;
+ }
+ }
+ return type;
+}
+
+ExtraType XmlObject::GetNodeValueAsExtraType(Poco::XML::Node* pNode)
+{
+ ExtraType type = ExtraType::Unkown;
+
+ if(pNode != 0) {
+ int iType = GetNodeValueAsInt(pNode);
+ switch(iType) {
+ case 1:
+ type = ExtraType::Trailer;
+ break;
+ case 5:
+ type = ExtraType::BehindTheScenes;
+ break;
+ default:
+ type = ExtraType::Unkown;
break;
}
}
diff --git a/XmlObject.h b/XmlObject.h
index 9e65984..4c64a6c 100644
--- a/XmlObject.h
+++ b/XmlObject.h
@@ -13,8 +13,10 @@
namespace plexclient
{
-enum MediaType {UNDEF = 0, MOVIE, SHOW, SEASON, EPISODE, MUSIC, PHOTO, CLIP};
-enum StreamType {sUNDEF = 0, sVIDEO = 1, sAUDIO = 2, sSUBTITLE = 3};
+enum class MediaType {UNDEF = 0, MOVIE, SHOW, SEASON, EPISODE, MUSIC, PHOTO, CLIP, PLAYLIST};
+enum class PlaylistType { Undef, Video, Audio, Photo };
+enum class StreamType {sUNDEF = 0, sVIDEO = 1, sAUDIO = 2, sSUBTITLE = 3};
+enum class ExtraType { Unkown = 0, Trailer = 1, BehindTheScenes = 5 };
class XmlObject
{
@@ -28,6 +30,8 @@ protected:
static Poco::DateTime GetNodeValueAsDateTime(Poco::XML::Node* pNode);
static MediaType GetNodeValueAsMediaType(Poco::XML::Node* pNode);
static StreamType GetNodeValueAsStreamType(Poco::XML::Node* pNode);
+ static PlaylistType GetNodeValueAsPlaylistType(Poco::XML::Node* pNode);
+ static ExtraType GetNodeValueAsExtraType(Poco::XML::Node* pNode);
private:
};
diff --git a/browserGrid.cpp b/browserGrid.cpp
index 4163c08..b3ddb83 100644
--- a/browserGrid.cpp
+++ b/browserGrid.cpp
@@ -301,12 +301,9 @@ void cBrowserGrid::DrawFooter()
} else if(m_viewEntryIndex + 1 == (int)Config::GetInstance().m_viewentries.size() + 1) {
nextTab = Config::GetInstance().m_viewentries[0].Name.c_str();
}
- cString prevTab = "Library";
- if(m_viewEntryIndex - 1 >= 0) {
- prevTab = Config::GetInstance().m_viewentries[m_viewEntryIndex - 1].Name.c_str();
- }
+ cString details = "Details";
- string textGreen = tr(prevTab);
+ string textGreen = tr(details);
string textYellow = tr(nextTab);
string textRed = "";
string textBlue = tr("Switch View");
diff --git a/detailView.cpp b/detailView.cpp
index ec7aee3..ef84179 100644
--- a/detailView.cpp
+++ b/detailView.cpp
@@ -1,10 +1,172 @@
#include "detailView.h"
+#include "Config.h"
-cDetailView::cDetailView(skindesignerapi::cOsdView *detailView, const cGridElement *element)
+cDetailView::cDetailView(std::shared_ptr<skindesignerapi::cOsdView> detailView, plexclient::Video *video)
+ : cViewGridNavigator(detailView)
{
+ m_pBackground = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::background));
+ m_pfooter = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::footer));
+ m_pInfo = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::info));
+ m_pScrollbar = std::shared_ptr<skindesignerapi::cViewElement>(detailView->GetViewElement((int)eViewElementsDetail::scrollbar));
+
+ m_pVideo = video;
+ m_drawall = true;
+
+ m_pGrid = NULL;
+ SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid>(detailView->GetViewGrid((int)eViewDetailViewGrids::extras)));
+ SetGridDimensions(Config::GetInstance().ExtrasGridColumns, Config::GetInstance().ExtrasGridRows);
+}
+
+void cDetailView::Flush()
+{
+ if (m_drawall) {
+ m_pBackground->Display();
+ m_pInfo->Display();
+ m_drawall = false;
+ }
+ m_pfooter->Display();
+ m_pGrid->Display();
+ m_pScrollbar->Display();
+}
+
+void cDetailView::Draw()
+{
+ // Draw Grid
+ m_vElements.clear();
+
+ int pos = 0;
+ for(auto it = m_pVideo->m_vExtras.begin(); it != m_pVideo->m_vExtras.end(); ++it) {
+ plexclient::Video *elem = &(*it);
+ elem->AbsolutePosition = pos++;;
+ m_vElements.push_back(elem);
+ }
+
+ m_startIndex = 0;
+
+// m_pGrid->Clear();
+ m_setIterator = true;
+ FilterElements(0);
+
+ DrawBackground();
+ DrawFooter();
+ DrawInfo();
+ DrawScrollbar();
+}
+
+void cDetailView::Clear()
+{
+ m_pBackground->Clear();
+ m_pInfo->Clear();
+ m_pScrollbar->Clear();
+ m_pfooter->Clear();
+ m_pGrid->Clear();
+}
+
+void cDetailView::DrawBackground()
+{
+ m_pBackground->ClearTokens();
+ bool art = m_pVideo->m_sArt.empty() == false;
+ m_pBackground->AddIntToken((int)eTokenDetailBackgroundInt::hasfanart, art);
+ if(art) m_pBackground->AddStringToken((int)eTokenDetailBackgroundStr::fanartpath, m_pVideo->m_sArt.c_str());
+
+ bool cover = m_pVideo->m_sThumb.empty() == false;
+ m_pBackground->AddIntToken((int)eTokenDetailBackgroundInt::hascover, cover);
+ if(Cover) m_pBackground->AddStringToken((int)eTokenDetailBackgroundStr::coverpath, m_pVideo->m_sThumb.c_str());
+}
+
+void cDetailView::DrawFooter()
+{
+ string textGreen = "";
+ string textYellow = "";
+ string textRed = "";
+ string textBlue = "Play";
+
+ if(auto vid = dynamic_cast<plexclient::Video*>(SelectedObject()) ) {
+ if(vid->m_iViewCount > 0) textRed = tr("Unscrobble");
+ else textRed = tr("Scrobble");
+ }
+
+
+ int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 };
+
+ m_pfooter->Clear();
+ m_pfooter->ClearTokens();
+
+ m_pfooter->AddStringToken((int)eTokenFooterStr::red, textRed.c_str());
+ m_pfooter->AddStringToken((int)eTokenFooterStr::green, textGreen.c_str());
+ m_pfooter->AddStringToken((int)eTokenFooterStr::yellow, textYellow.c_str());
+ m_pfooter->AddStringToken((int)eTokenFooterStr::blue, textBlue.c_str());
+
+ for (int button = 0; button < 4; button++) {
+ bool isRed = false;
+ bool isGreen = false;
+ bool isYellow = false;
+ bool isBlue = false;
+ switch (colorKeys[button]) {
+ 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(0 + button, isRed);
+ m_pfooter->AddIntToken(4 + button, isGreen);
+ m_pfooter->AddIntToken(8 + button, isYellow);
+ m_pfooter->AddIntToken(12 + button, isBlue);
+ }
+
+ m_pfooter->Display();
}
-cDetailView::~cDetailView()
+void cDetailView::DrawInfo()
{
+ m_pInfo->Clear();
+ m_pVideo->AddTokens(m_pInfo, true);
+ m_pInfo->Display();
}
+void cDetailView::DrawScrollbar()
+{
+ if (m_vElements.size() == 0)
+ return;
+
+ int currentRow = SelectedObject()->AbsolutePosition / m_columns;
+ int totalRows = m_vElements.size() / m_columns;
+
+ int scrollBarHeight = 100.0 / totalRows * m_rows;
+
+ int offset = 100.0 / totalRows * currentRow;
+ if(offset >= 100 - scrollBarHeight) {
+ offset = 100.0 - scrollBarHeight;
+ }
+ m_pScrollbar->Clear();
+ m_pScrollbar->ClearTokens();
+
+ m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::height, scrollBarHeight);
+ m_pScrollbar->AddIntToken((int)eTokenScrollbarInt::offset, offset);
+ m_pScrollbar->Display();
+}
+
+eOSState cDetailView::NavigateSelect()
+{
+ if(m_setIterator) return eOSState::osContinue;
+
+ if(dynamic_cast<plexclient::Video*>(SelectedObject())) {
+ return eOSState::osUser1;
+ } else return eOSState::osBack;
+}
+
+eOSState cDetailView::NavigateBack()
+{
+ if(m_setIterator) return eOSState::osContinue;;
+ return eOSState::osBack;
+}
diff --git a/detailView.h b/detailView.h
index d72e6d4..cc5f156 100644
--- a/detailView.h
+++ b/detailView.h
@@ -2,13 +2,37 @@
#define CDETAILVIEW_H
#include "viewGridNavigator.h"
+#include "PVideo.h"
-class cDetailView
+#include "tokendefinitions.h"
+#include <libskindesignerapi/osdelements.h>
+#include <libskindesignerapi/skindesignerosdbase.h>
+
+class cDetailView : public cViewGridNavigator
{
public:
- cDetailView(skindesignerapi::cOsdView *detailView, const cGridElement *element);
- ~cDetailView();
+ cDetailView(std::shared_ptr<skindesignerapi::cOsdView> detailView, plexclient::Video *video);
+
+ void Draw();
+ void Flush();
+ virtual eOSState NavigateSelect();
+ virtual eOSState NavigateBack();
+ plexclient::Video* GetVideo() { return m_pVideo; };
+ virtual void Clear();
+
+private:
+ std::shared_ptr<skindesignerapi::cViewElement> m_pBackground;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pfooter;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pInfo;
+ std::shared_ptr<skindesignerapi::cViewElement> m_pScrollbar;
+
+ plexclient::Video *m_pVideo;
+ bool m_drawall;
+ void DrawBackground();
+ void DrawFooter();
+ void DrawInfo();
+ void DrawScrollbar();
};
#endif // CDETAILVIEW_H
diff --git a/hlsPlayer.cpp b/hlsPlayer.cpp
index fc05479..e58eb28 100644
--- a/hlsPlayer.cpp
+++ b/hlsPlayer.cpp
@@ -484,7 +484,7 @@ void cHlsPlayer::SetAudioAndSubtitleTracks(void)
std::vector<plexclient::Stream> streams = m_Video.m_Media.m_vStreams;
for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::sAUDIO) {
+ if(pStream->m_eStreamType == plexclient::StreamType::sAUDIO) {
DeviceSetAvailableTrack(ttDolby, pStream->m_iIndex, pStream->m_iIndex + AudioIndexOffset, pStream->m_sLanguage.c_str(), pStream->m_sCodec.c_str());
}
}
@@ -668,7 +668,7 @@ void cHlsPlayer::SetAudioTrack(eTrackType Type __attribute__((unused)), const tT
std::vector<plexclient::Stream> streams = m_Video.m_Media.m_vStreams;
for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::sAUDIO && pStream->m_iIndex + AudioIndexOffset == TrackId->id) {
+ if(pStream->m_eStreamType == plexclient::StreamType::sAUDIO && pStream->m_iIndex + AudioIndexOffset == TrackId->id) {
streamId = pStream->m_iID;
break;
}
diff --git a/hlsPlayerControl.cpp b/hlsPlayerControl.cpp
index b7acd24..7a2467b 100644
--- a/hlsPlayerControl.cpp
+++ b/hlsPlayerControl.cpp
@@ -332,7 +332,7 @@ void cStreamSelectMenu::CreateMenu()
Add(new cOsdItem(tr("Audiostreams"), osUnknown, false));
for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::sAUDIO) {
+ if(pStream->m_eStreamType == plexclient::StreamType::sAUDIO) {
// Audio
cString item = cString::sprintf(tr("%s%s - %s %d Channels"), pStream->m_bSelected ? "[*] ":"", pStream->m_sLanguage.c_str(), pStream->m_sCodecId.c_str(), pStream->m_iChannels);
Add(new cPlexOsdItem(item, pStream));
@@ -341,12 +341,12 @@ void cStreamSelectMenu::CreateMenu()
Add(new cOsdItem(tr("Subtitlestreams"), osUnknown, false));
plexclient::Stream stre;
- stre.m_eStreamType = plexclient::sSUBTITLE;
+ stre.m_eStreamType = plexclient::StreamType::sSUBTITLE;
stre.m_iID = -1;
Add(new cPlexOsdItem(tr("None"), &stre));
for(std::vector<plexclient::Stream>::iterator it = streams.begin(); it != streams.end(); ++it) {
plexclient::Stream *pStream = &(*it);
- if(pStream->m_eStreamType == plexclient::sSUBTITLE) {
+ if(pStream->m_eStreamType == plexclient::StreamType::sSUBTITLE) {
// Subtitle
cString item = cString::sprintf("%s%s", pStream->m_bSelected ? "[*] ":"", pStream->m_sLanguage.c_str());
Add(new cPlexOsdItem(item, pStream));
diff --git a/plex.cpp b/plex.cpp
index 8ee152c..d890959 100644
--- a/plex.cpp
+++ b/plex.cpp
@@ -109,7 +109,32 @@ bool cMyPlugin::Start(void)
m_pPlugStruct->RegisterViewGrid((int)eViews::rootView, (int)eViewGrids::cover, "coverbrowser", tkGridCover);
m_pPlugStruct->RegisterViewGrid((int)eViews::rootView, (int)eViewGrids::detail, "detailbrowser", tkGridDetail);
m_pPlugStruct->RegisterViewGrid((int)eViews::rootView, (int)eViewGrids::list, "listbrowser", tkGridList);
-
+
+ // DetailsView
+ m_pPlugStruct->RegisterSubView((int)eViews::detailView, "detail.xml");
+ skindesignerapi::cTokenContainer *tkBackgroundDetail = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::background, tkBackgroundDetail);
+ m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::background, "background", tkBackgroundDetail);
+
+ skindesignerapi::cTokenContainer *tkDetailInfo = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::info, tkDetailInfo);
+ m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::info, "info", tkDetailInfo);
+
+ skindesignerapi::cTokenContainer *tkDetailFooter = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::footer, tkDetailFooter);
+ m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::footer, "footer", tkDetailFooter);
+
+ skindesignerapi::cTokenContainer *tkDetailScrollbar = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::scrollbar, tkDetailScrollbar);
+ m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::scrollbar, "scrollbar", tkDetailScrollbar);
+
+ skindesignerapi::cTokenContainer *tkDetailMessage = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail::message, tkDetailMessage);
+ m_pPlugStruct->RegisterViewElement((int)eViews::detailView, (int)eViewElementsDetail::message, "message", tkDetailMessage);
+
+ skindesignerapi::cTokenContainer *tkDetailExtraGrid = new skindesignerapi::cTokenContainer();
+ cPlexSdOsd::DefineGridTokens(tkDetailExtraGrid);
+ m_pPlugStruct->RegisterViewGrid((int)eViews::detailView, (int)eViewDetailViewGrids::extras, "extragrid", tkDetailExtraGrid);
if (!skindesignerapi::SkindesignerAPI::RegisterPlugin(m_pPlugStruct)) {
esyslog("[plex]: skindesigner not available");
diff --git a/plexSdOsd.cpp b/plexSdOsd.cpp
index b078879..1515ccd 100644
--- a/plexSdOsd.cpp
+++ b/plexSdOsd.cpp
@@ -50,13 +50,20 @@ void cPlexSdOsd::Show(void)
m_pBrowserGrid = std::shared_ptr<cBrowserGrid>(new cBrowserGrid(m_pRootView));
m_pMessage = std::shared_ptr<skindesignerapi::cViewElement>(m_pRootView->GetViewElement((int)eViewElementsRoot::message));
m_messageDisplayed = false;
+ m_detailsActive = false;
Flush();
}
void cPlexSdOsd::Flush()
{
- m_pBrowserGrid->DrawGrid();
- m_pBrowserGrid->Flush();
+ if(m_detailsActive) {
+ m_pDetailGrid->Draw();
+ m_pDetailGrid->Flush();
+ }
+ else {
+ m_pBrowserGrid->DrawGrid();
+ m_pBrowserGrid->Flush();
+ }
}
eOSState cPlexSdOsd::ProcessKey(eKeys Key)
@@ -97,6 +104,50 @@ eOSState cPlexSdOsd::ProcessKey(eKeys Key)
default:
break;
}
+ } else if(m_detailsActive) {
+ switch (Key & ~k_Repeat) {
+ case kUp:
+ if(m_pDetailGrid->NavigateUp()) Flush();
+ break;
+ case kDown:
+ if(m_pDetailGrid->NavigateDown()) Flush();
+ break;
+ case kLeft:
+ if(m_pDetailGrid->NavigateLeft()) Flush();
+ break;
+ case kRight:
+ if(m_pDetailGrid->NavigateRight()) Flush();
+ break;
+ case kOk:
+ state = m_pDetailGrid->NavigateSelect();
+ Flush();
+ break;
+ case kBack:
+ state = m_pDetailGrid->NavigateBack();
+ m_pDetailGrid->Clear();
+ m_pDetailsView->Deactivate(true);
+ m_pDetailGrid = nullptr;
+ m_pDetailsView = nullptr;
+ m_detailsActive = false;
+ m_pRootView->Activate();
+ break;
+ case kBlue:
+ vid = m_pDetailGrid->GetVideo();
+ state = eOSState::osUser1;
+ break;
+ case kRed:
+ if(m_pDetailGrid->GetVideo()) {
+ if(m_pDetailGrid->GetVideo()->m_iViewCount > 0) m_pDetailGrid->GetVideo()->SetUnwatched();
+ else m_pDetailGrid->GetVideo()->SetWatched();
+ m_pDetailGrid->GetVideo()->UpdateFromServer();
+ Flush();
+ }
+ break;
+ case kGreen:
+ case kYellow:
+ default:
+ break;
+ }
} else {
switch (Key & ~k_Repeat) {
@@ -115,6 +166,9 @@ eOSState cPlexSdOsd::ProcessKey(eKeys Key)
case kOk:
// Play movie or change dir
state = m_pBrowserGrid->NavigateSelect();
+ if(state == eOSState::osUser1) {
+ vid = dynamic_cast<plexclient::Video*>(m_pBrowserGrid->SelectedObject());
+ }
Flush();
break;
case kBack:
@@ -134,9 +188,13 @@ eOSState cPlexSdOsd::ProcessKey(eKeys Key)
Flush();
}
break;
- case kGreen:
- m_pBrowserGrid->PrevTab();
- Flush();
+ case kGreen: // Show Details OSD
+ vid = dynamic_cast<plexclient::Video*>(m_pBrowserGrid->SelectedObject());
+ if(vid) {
+ vid->UpdateFromServer();
+ ShowDetails(vid);
+ //Flush();
+ }
break;
case kYellow:
m_pBrowserGrid->NextTab();
@@ -149,7 +207,6 @@ eOSState cPlexSdOsd::ProcessKey(eKeys Key)
}
if(state == eOSState::osUser1) {
- vid = dynamic_cast<plexclient::Video*>(m_pBrowserGrid->SelectedObject());
if(vid->m_iMyPlayOffset == 0 && vid->m_lViewoffset > 0 ) {
cString message = cString::sprintf(tr("'Ok' to start from %ld minutes, 'Back' to start from beginning."), vid->m_lViewoffset / 60000);
DrawMessage(std::string(message));
@@ -162,6 +219,20 @@ eOSState cPlexSdOsd::ProcessKey(eKeys Key)
return state;
}
+void cPlexSdOsd::ShowDetails(plexclient::Video *vid)
+{
+ if(m_detailsActive) return;
+
+ m_pRootView->Deactivate(true);
+ m_pDetailsView = std::shared_ptr<skindesignerapi::cOsdView>(GetOsdView((int)eViews::detailView));
+ m_pDetailGrid = std::shared_ptr<cDetailView>(new cDetailView(m_pDetailsView, vid));
+
+ m_pDetailGrid->Draw();
+ m_pDetailGrid->Flush();
+ m_detailsActive = true;
+
+}
+
void cPlexSdOsd::DrawMessage(std::string message)
{
m_pMessage->ClearTokens();
@@ -186,41 +257,10 @@ void cPlexSdOsd::DefineTokens(eViewElementsRoot ve, skindesignerapi::cTokenConta
tk->DefineStringToken("{tabname}", (int)eTokenGridStr::tabname);
break;
case eViewElementsRoot::footer:
- tk->DefineIntToken("{red1}", (int)eTokenFooterInt::red1);
- tk->DefineIntToken("{red2}", (int)eTokenFooterInt::red2);
- tk->DefineIntToken("{red3}", (int)eTokenFooterInt::red3);
- tk->DefineIntToken("{red4}", (int)eTokenFooterInt::red4);
- tk->DefineIntToken("{green1}", (int)eTokenFooterInt::green1);
- tk->DefineIntToken("{green2}", (int)eTokenFooterInt::green2);
- tk->DefineIntToken("{green3}", (int)eTokenFooterInt::green3);
- tk->DefineIntToken("{green4}", (int)eTokenFooterInt::green4);
- tk->DefineIntToken("{yellow1}", (int)eTokenFooterInt::yellow1);
- tk->DefineIntToken("{yellow2}", (int)eTokenFooterInt::yellow2);
- tk->DefineIntToken("{yellow3}", (int)eTokenFooterInt::yellow3);
- tk->DefineIntToken("{yellow4}", (int)eTokenFooterInt::yellow4);
- tk->DefineIntToken("{blue1}", (int)eTokenFooterInt::blue1);
- tk->DefineIntToken("{blue2}", (int)eTokenFooterInt::blue2);
- tk->DefineIntToken("{blue3}", (int)eTokenFooterInt::blue3);
- tk->DefineIntToken("{blue4}", (int)eTokenFooterInt::blue4);
- tk->DefineStringToken("{red}", (int)eTokenFooterStr::red);
- tk->DefineStringToken("{green}", (int)eTokenFooterStr::green);
- tk->DefineStringToken("{yellow}", (int)eTokenFooterStr::yellow);
- tk->DefineStringToken("{blue}", (int)eTokenFooterStr::blue);
+ DefineFooterTokens(tk);
break;
case eViewElementsRoot::watch:
- tk->DefineIntToken("{sec}", (int)eTokenTimeInt::sec);
- tk->DefineIntToken("{min}", (int)eTokenTimeInt::min);
- tk->DefineIntToken("{hour}", (int)eTokenTimeInt::hour);
- tk->DefineIntToken("{hmins}", (int)eTokenTimeInt::hmins);
- tk->DefineIntToken("{day}", (int)eTokenTimeInt::day);
- tk->DefineIntToken("{year}", (int)eTokenTimeInt::year);
- tk->DefineStringToken("{time}", (int)eTokenTimeStr::time);
- tk->DefineStringToken("{dayname}", (int)eTokenTimeStr::dayname);
- tk->DefineStringToken("{daynameshort}", (int)eTokenTimeStr::daynameshort);
- tk->DefineStringToken("{dayleadingzero}", (int)eTokenTimeStr::dayleadingzero);
- tk->DefineStringToken("{month}", (int)eTokenTimeStr::month);
- tk->DefineStringToken("{monthname}", (int)eTokenTimeStr::monthname);
- tk->DefineStringToken("{monthnameshort}", (int)eTokenTimeStr::monthnameshort);
+ DefineWatchTokens(tk);
break;
case eViewElementsRoot::message:
tk->DefineIntToken("{displaymessage}", (int)eTokenMessageInt::displaymessage);
@@ -250,6 +290,7 @@ void cPlexSdOsd::DefineGridTokens(skindesignerapi::cTokenContainer* tk)
tk->DefineIntToken("{isdirectory}", (int)eTokenGridInt::isdirectory);
tk->DefineIntToken("{isshow}", (int)eTokenGridInt::isshow);
tk->DefineIntToken("{isseason}", (int)eTokenGridInt::isseason);
+ tk->DefineIntToken("{isclip}", (int)eTokenGridInt::isclip);
tk->DefineIntToken("{originallyAvailableYear}", (int)eTokenGridInt::originallyAvailableYear);
tk->DefineIntToken("{originallyAvailableMonth}", (int)eTokenGridInt::originallyAvailableMonth);
tk->DefineIntToken("{originallyAvailableDay}", (int)eTokenGridInt::originallyAvailableDay);
@@ -297,3 +338,72 @@ void cPlexSdOsd::DefineGridTokens(skindesignerapi::cTokenContainer* tk)
tk->DefineLoopToken("{roles[actor]}", (int)eTokenGridActorLst::roles);
tk->DefineLoopToken("{genres[genre]}", (int)eTokenGridGenresLst::genres);
}
+
+void cPlexSdOsd::DefineFooterTokens(skindesignerapi::cTokenContainer *tk)
+{
+ tk->DefineIntToken("{red1}", (int)eTokenFooterInt::red1);
+ tk->DefineIntToken("{red2}", (int)eTokenFooterInt::red2);
+ tk->DefineIntToken("{red3}", (int)eTokenFooterInt::red3);
+ tk->DefineIntToken("{red4}", (int)eTokenFooterInt::red4);
+ tk->DefineIntToken("{green1}", (int)eTokenFooterInt::green1);
+ tk->DefineIntToken("{green2}", (int)eTokenFooterInt::green2);
+ tk->DefineIntToken("{green3}", (int)eTokenFooterInt::green3);
+ tk->DefineIntToken("{green4}", (int)eTokenFooterInt::green4);
+ tk->DefineIntToken("{yellow1}", (int)eTokenFooterInt::yellow1);
+ tk->DefineIntToken("{yellow2}", (int)eTokenFooterInt::yellow2);
+ tk->DefineIntToken("{yellow3}", (int)eTokenFooterInt::yellow3);
+ tk->DefineIntToken("{yellow4}", (int)eTokenFooterInt::yellow4);
+ tk->DefineIntToken("{blue1}", (int)eTokenFooterInt::blue1);
+ tk->DefineIntToken("{blue2}", (int)eTokenFooterInt::blue2);
+ tk->DefineIntToken("{blue3}", (int)eTokenFooterInt::blue3);
+ tk->DefineIntToken("{blue4}", (int)eTokenFooterInt::blue4);
+ tk->DefineStringToken("{red}", (int)eTokenFooterStr::red);
+ tk->DefineStringToken("{green}", (int)eTokenFooterStr::green);
+ tk->DefineStringToken("{yellow}", (int)eTokenFooterStr::yellow);
+ tk->DefineStringToken("{blue}", (int)eTokenFooterStr::blue);
+}
+
+void cPlexSdOsd::DefineWatchTokens(skindesignerapi::cTokenContainer *tk)
+{
+ tk->DefineIntToken("{sec}", (int)eTokenTimeInt::sec);
+ tk->DefineIntToken("{min}", (int)eTokenTimeInt::min);
+ tk->DefineIntToken("{hour}", (int)eTokenTimeInt::hour);
+ tk->DefineIntToken("{hmins}", (int)eTokenTimeInt::hmins);
+ tk->DefineIntToken("{day}", (int)eTokenTimeInt::day);
+ tk->DefineIntToken("{year}", (int)eTokenTimeInt::year);
+ tk->DefineStringToken("{time}", (int)eTokenTimeStr::time);
+ tk->DefineStringToken("{dayname}", (int)eTokenTimeStr::dayname);
+ tk->DefineStringToken("{daynameshort}", (int)eTokenTimeStr::daynameshort);
+ tk->DefineStringToken("{dayleadingzero}", (int)eTokenTimeStr::dayleadingzero);
+ tk->DefineStringToken("{month}", (int)eTokenTimeStr::month);
+ tk->DefineStringToken("{monthname}", (int)eTokenTimeStr::monthname);
+ tk->DefineStringToken("{monthnameshort}", (int)eTokenTimeStr::monthnameshort);
+}
+
+void cPlexSdOsd::DefineDetailsTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk)
+{
+ switch(ve) {
+ case eViewElementsDetail::background:
+ tk->DefineIntToken("{hasfanart}", (int)eTokenDetailBackgroundInt::hasfanart);
+ tk->DefineIntToken("{hascover}", (int)eTokenDetailBackgroundInt::hascover);
+ tk->DefineStringToken("{fanartpath}", (int)eTokenDetailBackgroundStr::fanartpath);
+ tk->DefineStringToken("{coverpath}", (int)eTokenDetailBackgroundStr::coverpath);
+ break;
+ case eViewElementsDetail::footer:
+ DefineFooterTokens(tk);
+ break;
+ case eViewElementsDetail::info:
+ DefineGridTokens(tk);
+ break;
+ case eViewElementsDetail::message:
+ tk->DefineIntToken("{displaymessage}", (int)eTokenMessageInt::displaymessage);
+ tk->DefineStringToken("{message}", (int)eTokenMessageStr::message);
+ break;
+ case eViewElementsDetail::scrollbar:
+ tk->DefineIntToken("{height}", (int)eTokenScrollbarInt::height);
+ tk->DefineIntToken("{offset}", (int)eTokenScrollbarInt::offset);
+ break;
+ default:
+ break;
+ }
+} \ No newline at end of file
diff --git a/plexSdOsd.h b/plexSdOsd.h
index 0899869..73c7885 100644
--- a/plexSdOsd.h
+++ b/plexSdOsd.h
@@ -17,6 +17,7 @@
#include "hlsPlayerControl.h"
#include "browserGrid.h"
+#include "detailView.h"
#include "tokendefinitions.h"
#include <libskindesignerapi/osdelements.h>
#include <libskindesignerapi/skindesignerosdbase.h>
@@ -25,10 +26,13 @@ class cPlexSdOsd : public skindesignerapi::cSkindesignerOsdObject
{
private:
std::shared_ptr<cBrowserGrid> m_pBrowserGrid;
+ std::shared_ptr<cDetailView> m_pDetailGrid;
std::shared_ptr<skindesignerapi::cViewElement> m_pMessage;
bool m_messageDisplayed;
+ bool m_detailsActive;
std::shared_ptr<skindesignerapi::cOsdView> m_pRootView;
+ std::shared_ptr<skindesignerapi::cOsdView> m_pDetailsView;
void Flush();
//void SwitchGrid(ePlexMenuTab currentTab);
@@ -36,6 +40,8 @@ private:
void DrawFooter();
void DrawMessage(std::string message);
+ void ShowDetails(plexclient::Video *vid);
+
public:
cPlexSdOsd(skindesignerapi::cPluginStructure *plugStruct);
~cPlexSdOsd();
@@ -46,6 +52,9 @@ public:
static cMutex RedrawMutex;
static void DefineTokens(eViewElementsRoot ve, skindesignerapi::cTokenContainer *tk);
static void DefineGridTokens(skindesignerapi::cTokenContainer *tk);
+ static void DefineFooterTokens(skindesignerapi::cTokenContainer *tk);
+ static void DefineWatchTokens(skindesignerapi::cTokenContainer *tk);
+ static void DefineDetailsTokens(eViewElementsDetail ve, skindesignerapi::cTokenContainer *tk);
};
#endif // CPLEXSDOSD_H
diff --git a/templates/plug-plex-root.xml b/templates/plug-plex-root.xml
index a6c3e30..efa8ae1 100644
--- a/templates/plug-plex-root.xml
+++ b/templates/plug-plex-root.xml
@@ -110,7 +110,7 @@
If the item is a video following tokens are avaliable
- The item is a video if one of the following tokens are set: {ismovie}, {isepisode}
+ The item is a video if one of the following tokens are set: {ismovie}, {isepisode}, {isclip}
{contentrating} string, FSK, PEGI -> eg. de/16
{rating} int, starrating 0.0 - 10.0 multiplied by 10 -> 0 - 100
{ratingstring} string, rating formated as double %.1f
diff --git a/tokendefinitions.h b/tokendefinitions.h
index 52f17cd..55dd270 100644
--- a/tokendefinitions.h
+++ b/tokendefinitions.h
@@ -6,6 +6,14 @@ enum class eViews {
detailView
};
+enum class eViewElementsDetail {
+ background,
+ footer,
+ info,
+ message,
+ scrollbar
+};
+
enum class eViewElementsRoot {
background,
header,
@@ -19,13 +27,11 @@ enum class eViewElementsRoot {
enum class eViewGrids {
cover,
detail,
- list
+ list,
};
-enum class eViewElementsDetail {
- background,
- header,
- footer
+enum class eViewDetailViewGrids {
+ extras
};
enum class eTokenGridInt {
@@ -43,6 +49,7 @@ enum class eTokenGridInt {
isdirectory,
isshow,
isseason,
+ isclip,
originallyAvailableYear,
originallyAvailableMonth,
originallyAvailableDay,
@@ -122,6 +129,16 @@ enum class eTokenBackgroundStr {
currentdirectorybackground
};
+enum class eTokenDetailBackgroundInt {
+ hasfanart = 0,
+ hascover
+};
+
+enum class eTokenDetailBackgroundStr {
+ fanartpath = 0,
+ coverpath
+};
+
enum class eTokenTimeInt {
sec = 0,
min,
diff --git a/viewGridNavigator.h b/viewGridNavigator.h
index 2622c48..ea5a3f5 100644
--- a/viewGridNavigator.h
+++ b/viewGridNavigator.h
@@ -48,7 +48,6 @@ protected:
int m_startIndex;
int m_endIndex;
- void GenerateServerElements();
void FilterElements(int scrollOffset);
void SetGridElementData(cGridElement *obj);
void SetViewGrid(std::shared_ptr<skindesignerapi::cViewGrid> grid);