2014-09-27 09:25:14 +02:00
|
|
|
#include "designer.h"
|
2016-01-26 18:32:38 +01:00
|
|
|
#include "extensions/helpers.h"
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2014-10-03 15:54:23 +02:00
|
|
|
cSkinDesigner::cSkinDesigner(string skin) : cSkin(skin.c_str(), &::Theme) {
|
|
|
|
init = true;
|
|
|
|
this->skin = skin;
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
backupSkin = NULL;
|
|
|
|
useBackupSkin = false;
|
2014-10-18 10:05:32 +02:00
|
|
|
|
2014-10-03 15:54:23 +02:00
|
|
|
globals = NULL;
|
2016-01-26 18:32:38 +01:00
|
|
|
channelView = NULL;
|
|
|
|
menuView = NULL;
|
|
|
|
messageView = NULL;
|
|
|
|
replayView = NULL;
|
|
|
|
volumeView = NULL;
|
|
|
|
tracksView = NULL;
|
2014-11-15 09:47:22 +01:00
|
|
|
currentMenu = NULL;
|
|
|
|
|
2014-10-03 15:54:23 +02:00
|
|
|
dsyslog("skindesigner: skin %s started", skin.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDesigner::~cSkinDesigner(void) {
|
|
|
|
if (globals)
|
|
|
|
delete globals;
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-10-03 15:54:23 +02:00
|
|
|
if (backupSkin)
|
|
|
|
delete backupSkin;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *cSkinDesigner::Description(void) {
|
|
|
|
return skin.c_str();
|
|
|
|
}
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayChannel *cSkinDesigner::DisplayChannel(bool WithInfo) {
|
2014-11-15 09:47:22 +01:00
|
|
|
currentMenu = NULL;
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayChannel *displayChannel = NULL;
|
2016-01-26 18:32:38 +01:00
|
|
|
Init();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!useBackupSkin) {
|
2016-01-26 18:32:38 +01:00
|
|
|
displayChannel = new cSDDisplayChannel(channelView, WithInfo);
|
2014-09-27 09:25:14 +02:00
|
|
|
} else {
|
|
|
|
displayChannel = backupSkin->DisplayChannel(WithInfo);
|
|
|
|
}
|
|
|
|
return displayChannel;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayMenu *cSkinDesigner::DisplayMenu(void) {
|
|
|
|
if (!useBackupSkin) {
|
2014-11-15 09:47:22 +01:00
|
|
|
cSDDisplayMenu *displayMenu = NULL;
|
2014-10-18 10:05:32 +02:00
|
|
|
Init();
|
2016-01-26 18:32:38 +01:00
|
|
|
displayMenu = new cSDDisplayMenu(menuView);
|
2014-11-15 09:47:22 +01:00
|
|
|
currentMenu = displayMenu;
|
|
|
|
return displayMenu;
|
2014-09-27 09:25:14 +02:00
|
|
|
} else {
|
2014-11-15 09:47:22 +01:00
|
|
|
cSkinDisplayMenu *displayMenu = backupSkin->DisplayMenu();
|
|
|
|
currentMenu = NULL;
|
|
|
|
return displayMenu;
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayReplay *cSkinDesigner::DisplayReplay(bool ModeOnly) {
|
2014-11-15 09:47:22 +01:00
|
|
|
currentMenu = NULL;
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayReplay *displayReplay = NULL;
|
|
|
|
if (!useBackupSkin) {
|
2014-10-18 10:05:32 +02:00
|
|
|
Init();
|
2016-01-26 18:32:38 +01:00
|
|
|
displayReplay = new cSDDisplayReplay(replayView, ModeOnly);
|
2014-09-27 09:25:14 +02:00
|
|
|
} else {
|
|
|
|
displayReplay = backupSkin->DisplayReplay(ModeOnly);
|
|
|
|
}
|
|
|
|
return displayReplay;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayVolume *cSkinDesigner::DisplayVolume(void) {
|
2014-11-15 09:47:22 +01:00
|
|
|
currentMenu = NULL;
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayVolume *displayVolume = NULL;
|
|
|
|
if (!useBackupSkin) {
|
2014-10-18 10:05:32 +02:00
|
|
|
Init();
|
2016-01-26 18:32:38 +01:00
|
|
|
displayVolume = new cSDDisplayVolume(volumeView);
|
2014-09-27 09:25:14 +02:00
|
|
|
} else {
|
|
|
|
displayVolume = backupSkin->DisplayVolume();
|
|
|
|
}
|
|
|
|
return displayVolume;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayTracks *cSkinDesigner::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) {
|
2014-11-15 09:47:22 +01:00
|
|
|
currentMenu = NULL;
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayTracks *displayTracks = NULL;
|
|
|
|
if (!useBackupSkin) {
|
2014-10-18 10:05:32 +02:00
|
|
|
Init();
|
2016-01-26 18:32:38 +01:00
|
|
|
displayTracks = new cSDDisplayTracks(tracksView, Title, NumTracks, Tracks);
|
2014-09-27 09:25:14 +02:00
|
|
|
} else {
|
|
|
|
displayTracks = backupSkin->DisplayTracks(Title, NumTracks, Tracks);
|
|
|
|
}
|
|
|
|
return displayTracks;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayMessage *cSkinDesigner::DisplayMessage(void) {
|
2014-11-15 09:47:22 +01:00
|
|
|
currentMenu = NULL;
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayMessage *displayMessage = NULL;
|
|
|
|
if (!useBackupSkin) {
|
2014-10-18 10:05:32 +02:00
|
|
|
Init();
|
2016-01-26 18:32:38 +01:00
|
|
|
displayMessage = new cSDDisplayMessage(messageView);
|
2014-09-27 09:25:14 +02:00
|
|
|
} else {
|
|
|
|
displayMessage = backupSkin->DisplayMessage();
|
|
|
|
}
|
|
|
|
return displayMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::Reload(void) {
|
|
|
|
dsyslog("skindesigner: forcing full reload of templates");
|
|
|
|
if (cOsd::IsOpen()) {
|
|
|
|
esyslog("skindesigner: OSD is open, close first!");
|
|
|
|
return;
|
|
|
|
}
|
2015-06-18 10:21:43 +02:00
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
cStopWatch watch;
|
2016-01-26 18:32:38 +01:00
|
|
|
bool ok = LoadViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
|
|
|
|
if (!backupSkin)
|
|
|
|
backupSkin = new cSkinLCARS();
|
|
|
|
useBackupSkin = true;
|
|
|
|
} else {
|
2016-01-26 18:32:38 +01:00
|
|
|
CacheViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
useBackupSkin = false;
|
|
|
|
watch.Stop("templates reloaded and cache created");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::ListAvailableFonts(void) {
|
|
|
|
fontManager->ListAvailableFonts();
|
|
|
|
}
|
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
bool cSkinDesigner::SetCustomIntToken(string option) {
|
2014-10-11 16:31:39 +02:00
|
|
|
splitstring s(option.c_str());
|
|
|
|
vector<string> flds = s.split('=', 0);
|
|
|
|
if (flds.size() != 2)
|
|
|
|
return false;
|
2016-01-26 18:32:38 +01:00
|
|
|
int key = atoi(trim(flds[0]).c_str());
|
2014-10-11 16:31:39 +02:00
|
|
|
string val = trim(flds[1]);
|
|
|
|
if (!globals)
|
|
|
|
return true;
|
2016-01-26 18:32:38 +01:00
|
|
|
if (key > 0 && isNumber(val)) {
|
2015-01-24 10:47:47 +01:00
|
|
|
globals->AddCustomInt(key, atoi(val.c_str()));
|
2014-12-19 15:39:21 +01:00
|
|
|
} else {
|
2016-01-26 18:32:38 +01:00
|
|
|
return false;
|
2014-10-11 16:31:39 +02:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
bool cSkinDesigner::SetCustomStringToken(string option) {
|
|
|
|
splitstring s(option.c_str());
|
|
|
|
vector<string> flds = s.split('=', 0);
|
|
|
|
if (flds.size() != 2)
|
|
|
|
return false;
|
|
|
|
int key = atoi(trim(flds[0]).c_str());
|
|
|
|
string val = trim(flds[1]);
|
|
|
|
if (!globals)
|
|
|
|
return true;
|
|
|
|
if (key > 0)
|
|
|
|
globals->AddCustomString(key, val);
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-11 16:31:39 +02:00
|
|
|
void cSkinDesigner::ListCustomTokens(void) {
|
|
|
|
if (!globals)
|
|
|
|
return;
|
2015-01-24 10:47:47 +01:00
|
|
|
globals->ListCustomTokens();
|
2014-10-11 16:31:39 +02:00
|
|
|
}
|
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
skindesignerapi::ISkinDisplayPlugin *cSkinDesigner::GetDisplayPlugin(int plugId) {
|
|
|
|
map<int, cViewPlugin*>::iterator hit = pluginViews.find(plugId);
|
|
|
|
if (hit == pluginViews.end())
|
|
|
|
return NULL;
|
|
|
|
return hit->second;
|
|
|
|
}
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
/*********************************************************************************
|
|
|
|
* PRIVATE FUNCTIONS
|
|
|
|
*********************************************************************************/
|
2014-10-18 10:05:32 +02:00
|
|
|
void cSkinDesigner::Init(void) {
|
2016-01-26 18:32:38 +01:00
|
|
|
if ( init
|
|
|
|
|| config.OsdSizeChanged()
|
|
|
|
|| config.SkinChanged()
|
|
|
|
|| config.OsdLanguageChanged() ||
|
|
|
|
config.setupCloseDoReload )
|
|
|
|
{
|
2015-01-31 11:46:06 +01:00
|
|
|
config.setupCloseDoReload = false;
|
2014-10-18 10:05:32 +02:00
|
|
|
if (init) {
|
|
|
|
config.SetSkin();
|
|
|
|
config.SetOSDSize();
|
2014-10-18 10:28:38 +02:00
|
|
|
config.SetOSDFonts();
|
2014-10-18 10:05:32 +02:00
|
|
|
}
|
|
|
|
dsyslog("skindesigner: initializing skin %s", skin.c_str());
|
|
|
|
|
|
|
|
config.CheckDecimalPoint();
|
2016-01-26 18:32:38 +01:00
|
|
|
plgManager->Reset();
|
|
|
|
|
2014-10-18 10:05:32 +02:00
|
|
|
if (fontManager)
|
|
|
|
delete fontManager;
|
|
|
|
fontManager = new cFontManager();
|
|
|
|
if (imgCache)
|
|
|
|
delete imgCache;
|
|
|
|
imgCache = new cImageCache();
|
|
|
|
imgCache->SetPathes();
|
|
|
|
|
|
|
|
cStopWatch watch;
|
2016-01-26 18:32:38 +01:00
|
|
|
bool ok = LoadViews();
|
2014-10-18 10:05:32 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
|
|
|
|
backupSkin = new cSkinLCARS();
|
|
|
|
useBackupSkin = true;
|
|
|
|
} else {
|
2016-01-26 18:32:38 +01:00
|
|
|
CacheViews();
|
|
|
|
watch.Stop("templates loaded and caches created");
|
2014-10-18 10:05:32 +02:00
|
|
|
}
|
|
|
|
init = false;
|
2016-01-26 18:32:38 +01:00
|
|
|
}
|
|
|
|
else if (config.OsdFontsChanged())
|
|
|
|
{
|
2014-10-18 10:28:38 +02:00
|
|
|
dsyslog("skindesigner: reloading fonts");
|
|
|
|
if (fontManager)
|
|
|
|
delete fontManager;
|
|
|
|
fontManager = new cFontManager();
|
|
|
|
cStopWatch watch;
|
2016-01-26 18:32:38 +01:00
|
|
|
bool ok = LoadViews();
|
2014-10-18 10:28:38 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
|
|
|
|
backupSkin = new cSkinLCARS();
|
|
|
|
useBackupSkin = true;
|
|
|
|
} else {
|
2016-01-26 18:32:38 +01:00
|
|
|
CacheViews();
|
|
|
|
watch.Stop("templates loaded and caches created");
|
2014-10-18 10:28:38 +02:00
|
|
|
}
|
2014-10-18 10:05:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
void cSkinDesigner::DeleteViews(void) {
|
|
|
|
delete channelView;
|
|
|
|
channelView = NULL;
|
|
|
|
|
|
|
|
delete menuView;
|
|
|
|
menuView = NULL;
|
|
|
|
|
|
|
|
delete messageView;
|
|
|
|
messageView = NULL;
|
|
|
|
|
|
|
|
delete replayView;
|
|
|
|
replayView = NULL;
|
|
|
|
|
|
|
|
delete volumeView;
|
|
|
|
volumeView = NULL;
|
|
|
|
|
|
|
|
delete tracksView;
|
|
|
|
tracksView = NULL;
|
|
|
|
|
|
|
|
for (map<int,cViewPlugin*>::iterator it = pluginViews.begin(); it != pluginViews.end(); it++) {
|
|
|
|
cViewPlugin *plugView = it->second;
|
|
|
|
delete plugView;
|
2015-02-12 18:50:58 +01:00
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
pluginViews.clear();
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
bool cSkinDesigner::LoadViews(void) {
|
2014-10-18 10:05:32 +02:00
|
|
|
if (globals)
|
|
|
|
delete globals;
|
2014-09-27 09:25:14 +02:00
|
|
|
globals = new cGlobals();
|
|
|
|
bool ok = globals->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error parsing globals, aborting");
|
|
|
|
return false;
|
|
|
|
}
|
2015-01-20 09:29:16 +01:00
|
|
|
config.SetGlobals(globals);
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2015-01-19 10:50:22 +01:00
|
|
|
cSkinSetup *skinSetup = config.GetSkinSetup(skin);
|
|
|
|
if (skinSetup) {
|
|
|
|
skinSetup->AddToGlobals(globals);
|
2015-01-19 09:23:15 +01:00
|
|
|
}
|
2015-01-19 10:50:22 +01:00
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
channelView = new cViewChannel();
|
|
|
|
ok = channelView->ReadFromXML();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displaychannel template, aborting");
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
channelView->SetGlobals(globals);
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
menuView = new cViewMenu();
|
|
|
|
ok = menuView->ReadFromXML();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displaymenu template, aborting");
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
menuView->SetGlobals(globals);
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
messageView = new cViewMessage();
|
|
|
|
ok = messageView->ReadFromXML();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displaymessage template, aborting");
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
messageView->SetGlobals(globals);
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
replayView = new cViewReplay();
|
|
|
|
ok = replayView->ReadFromXML();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displayreplay template, aborting");
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
replayView->SetGlobals(globals);
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
volumeView = new cViewVolume();
|
|
|
|
ok = volumeView->ReadFromXML();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displayvolume template, aborting");
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
volumeView->SetGlobals(globals);
|
2014-09-27 09:25:14 +02:00
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
tracksView = new cViewTracks();
|
|
|
|
ok = tracksView->ReadFromXML();
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displayaudiotracks template, aborting");
|
2016-01-26 18:32:38 +01:00
|
|
|
DeleteViews();
|
2014-09-27 09:25:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
tracksView->SetGlobals(globals);
|
|
|
|
|
|
|
|
LoadPluginViews();
|
2015-02-12 18:50:58 +01:00
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
dsyslog("skindesigner: templates successfully validated and parsed");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-26 18:32:38 +01:00
|
|
|
void cSkinDesigner::LoadPluginViews(void) {
|
|
|
|
plgManager->InitPluginViewIterator();
|
|
|
|
string plugName = "";
|
|
|
|
string viewTpl = "";
|
|
|
|
int plugId = -1;
|
|
|
|
while ( plgManager->GetNextPluginView(plugName, plugId, viewTpl) ) {
|
|
|
|
cViewPlugin *plugView = new cViewPlugin(0, plugId);
|
|
|
|
bool ok = plugView->ReadFromXML(plugName.c_str(), viewTpl.c_str());
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error during loading templates for plugin %s", plugName.c_str());
|
|
|
|
continue;
|
2015-02-12 18:50:58 +01:00
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
ok = plugView->ReadSubViews(plugName.c_str());
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error during loading templates for plugin %s", plugName.c_str());
|
|
|
|
continue;
|
2015-02-12 18:50:58 +01:00
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
plugView->SetGlobals(globals);
|
|
|
|
pluginViews.insert(pair<int, cViewPlugin*>(plugId, plugView));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::CacheViews(void) {
|
|
|
|
channelView->PreCache();
|
|
|
|
menuView->PreCache();
|
|
|
|
messageView->PreCache();
|
|
|
|
replayView->PreCache();
|
|
|
|
volumeView->PreCache();
|
|
|
|
tracksView->PreCache();
|
|
|
|
for (map<int,cViewPlugin*>::iterator it = pluginViews.begin(); it != pluginViews.end(); it++) {
|
|
|
|
cViewPlugin *plugView = it->second;
|
|
|
|
plugView->PreCache();
|
2015-02-12 18:50:58 +01:00
|
|
|
}
|
2016-01-26 18:32:38 +01:00
|
|
|
dsyslog("skindesigner: templates and images cached");
|
2014-09-27 09:25:14 +02:00
|
|
|
imgCache->Debug(false);
|
|
|
|
}
|
|
|
|
|