vdr-plugin-skindesigner/designer.c

395 lines
11 KiB
C

#include "designer.h"
#include "extensions/helpers.h"
cSkinDesigner::cSkinDesigner(string skin, cTheme *theme) : cSkin(skin.c_str(), theme) {
init = true;
initialized = false;
this->skin = skin;
backupSkin = NULL;
useBackupSkin = false;
globals = NULL;
channelView = NULL;
menuView = NULL;
messageView = NULL;
replayView = NULL;
volumeView = NULL;
tracksView = NULL;
currentMenu = NULL;
dsyslog("skindesigner: skin %s started", skin.c_str());
}
cSkinDesigner::~cSkinDesigner(void) {
if (globals)
delete globals;
DeleteViews();
if (backupSkin)
delete backupSkin;
}
const char *cSkinDesigner::Description(void) {
return skin.c_str();
}
cSkinDisplayChannel *cSkinDesigner::DisplayChannel(bool WithInfo) {
currentMenu = NULL;
cSkinDisplayChannel *displayChannel = NULL;
Init();
if (!useBackupSkin) {
displayChannel = new cSDDisplayChannel(channelView, WithInfo);
} else {
displayChannel = backupSkin->DisplayChannel(WithInfo);
}
return displayChannel;
}
cSkinDisplayMenu *cSkinDesigner::DisplayMenu(void) {
if (!useBackupSkin) {
cSDDisplayMenu *displayMenu = NULL;
Init();
displayMenu = new cSDDisplayMenu(menuView);
currentMenu = displayMenu;
return displayMenu;
} else {
cSkinDisplayMenu *displayMenu = backupSkin->DisplayMenu();
currentMenu = NULL;
return displayMenu;
}
}
cSkinDisplayReplay *cSkinDesigner::DisplayReplay(bool ModeOnly) {
currentMenu = NULL;
cSkinDisplayReplay *displayReplay = NULL;
if (!useBackupSkin) {
Init();
displayReplay = new cSDDisplayReplay(replayView, ModeOnly);
} else {
displayReplay = backupSkin->DisplayReplay(ModeOnly);
}
return displayReplay;
}
cSkinDisplayVolume *cSkinDesigner::DisplayVolume(void) {
currentMenu = NULL;
cSkinDisplayVolume *displayVolume = NULL;
if (!useBackupSkin) {
Init();
displayVolume = new cSDDisplayVolume(volumeView);
} else {
displayVolume = backupSkin->DisplayVolume();
}
return displayVolume;
}
cSkinDisplayTracks *cSkinDesigner::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) {
currentMenu = NULL;
cSkinDisplayTracks *displayTracks = NULL;
if (!useBackupSkin) {
Init();
displayTracks = new cSDDisplayTracks(tracksView, Title, NumTracks, Tracks);
} else {
displayTracks = backupSkin->DisplayTracks(Title, NumTracks, Tracks);
}
return displayTracks;
}
cSkinDisplayMessage *cSkinDesigner::DisplayMessage(void) {
currentMenu = NULL;
cSkinDisplayMessage *displayMessage = NULL;
if (!useBackupSkin) {
Init();
displayMessage = new cSDDisplayMessage(messageView);
} else {
displayMessage = backupSkin->DisplayMessage();
}
return displayMessage;
}
int cSkinDesigner::Reload(void) {
dsyslog("skindesigner: forcing full reload of templates");
if (cOsd::IsOpen()) {
esyslog("skindesigner: OSD is open, close first!");
return 2;
}
cStopWatch watch;
bool ok = LoadViews();
if (!ok) {
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
if (!backupSkin)
backupSkin = new cSkinLCARS();
useBackupSkin = true;
return 1;
} else {
CacheViews();
useBackupSkin = false;
watch.Stop("templates reloaded and cache created");
}
return 0;
}
void cSkinDesigner::ListAvailableFonts(void) {
fontManager->ListAvailableFonts();
}
bool cSkinDesigner::SetCustomIntToken(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 && isNumber(val)) {
globals->AddCustomInt(key, atoi(val.c_str()));
} else {
return false;
}
return true;
}
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;
}
void cSkinDesigner::ListCustomTokens(void) {
if (!globals)
return;
globals->ListCustomTokens();
}
skindesignerapi::ISkinDisplayPlugin *cSkinDesigner::GetDisplayPlugin(int plugId) {
Init();
map<int, cViewPlugin*>::iterator hit = pluginViews.find(plugId);
if (hit == pluginViews.end())
return NULL;
return hit->second;
}
/*********************************************************************************
* PRIVATE FUNCTIONS
*********************************************************************************/
void cSkinDesigner::Init(void) {
if ( init
|| config.OsdSizeChanged()
|| config.SkinChanged()
|| config.OsdLanguageChanged() ||
config.setupCloseDoReload )
{
config.setupCloseDoReload = false;
if (init) {
config.SetSkin();
config.SetOSDSize();
config.SetOSDFonts();
}
dsyslog("skindesigner: initializing skin %s", skin.c_str());
config.CheckDecimalPoint();
plgManager->Reset();
if (fontManager)
delete fontManager;
fontManager = new cFontManager();
if (imgCache)
delete imgCache;
imgCache = new cImageCache();
imgCache->SetPathes();
cStopWatch watch;
bool ok = LoadViews();
if (!ok) {
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
backupSkin = new cSkinLCARS();
useBackupSkin = true;
initialized = true;
} else {
CacheViews();
watch.Stop("templates loaded and caches created");
}
init = false;
initialized = true;
}
else if (config.OsdFontsChanged())
{
dsyslog("skindesigner: reloading fonts");
if (fontManager)
delete fontManager;
fontManager = new cFontManager();
cStopWatch watch;
bool ok = LoadViews();
if (!ok) {
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
backupSkin = new cSkinLCARS();
useBackupSkin = true;
} else {
CacheViews();
watch.Stop("templates loaded and caches created");
}
}
else if (config.PlayModeChanged())
{
dsyslog ("skindesigner: drop image cache");
if (imgCache)
delete imgCache;
imgCache = new cImageCache();
imgCache->SetPathes();
}
}
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;
}
pluginViews.clear();
}
bool cSkinDesigner::LoadViews(void) {
if (globals)
delete globals;
globals = new cGlobals();
bool ok = globals->ReadFromXML();
if (!ok) {
esyslog("skindesigner: error parsing globals, aborting");
return false;
}
config.SetGlobals(globals);
cSkinSetup *skinSetup = config.GetSkinSetup(skin);
if (skinSetup) {
skinSetup->AddToGlobals(globals);
}
DeleteViews();
channelView = new cViewChannel();
ok = channelView->ReadFromXML();
if (!ok) {
esyslog("skindesigner: error reading displaychannel template, aborting");
DeleteViews();
return false;
}
channelView->SetGlobals(globals);
menuView = new cViewMenu();
ok = menuView->ReadFromXML();
if (!ok) {
esyslog("skindesigner: error reading displaymenu template, aborting");
DeleteViews();
return false;
}
menuView->SetGlobals(globals);
messageView = new cViewMessage();
ok = messageView->ReadFromXML();
if (!ok) {
esyslog("skindesigner: error reading displaymessage template, aborting");
DeleteViews();
return false;
}
messageView->SetGlobals(globals);
replayView = new cViewReplay();
ok = replayView->ReadFromXML();
if (!ok) {
esyslog("skindesigner: error reading displayreplay template, aborting");
DeleteViews();
return false;
}
replayView->SetGlobals(globals);
volumeView = new cViewVolume();
ok = volumeView->ReadFromXML();
if (!ok) {
esyslog("skindesigner: error reading displayvolume template, aborting");
DeleteViews();
return false;
}
volumeView->SetGlobals(globals);
tracksView = new cViewTracks();
ok = tracksView->ReadFromXML();
if (!ok) {
esyslog("skindesigner: error reading displayaudiotracks template, aborting");
DeleteViews();
return false;
}
tracksView->SetGlobals(globals);
LoadPluginViews();
dsyslog("skindesigner: templates successfully validated and parsed");
return true;
}
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;
}
ok = plugView->ReadSubViews(plugName.c_str());
if (!ok) {
esyslog("skindesigner: error during loading templates for plugin %s", plugName.c_str());
continue;
}
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();
}
dsyslog("skindesigner: templates and images cached");
imgCache->Debug(false);
}