diff options
author | AlTheKiller <AlTheKiller@svn> | 2009-09-23 01:49:50 +0000 |
---|---|---|
committer | AlTheKiller <AlTheKiller@svn> | 2009-09-23 01:49:50 +0000 |
commit | 45285e8a9300cd754a760560640b75b09f98035e (patch) | |
tree | ad9f093885ad5c98e9dd4156674e7691c22ed0a2 /guilib/SkinInfo.cpp |
step 3/4: Move linuxport to trunk. How'd I get roped into this?
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@23097 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
Diffstat (limited to 'guilib/SkinInfo.cpp')
-rw-r--r-- | guilib/SkinInfo.cpp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/guilib/SkinInfo.cpp b/guilib/SkinInfo.cpp new file mode 100644 index 0000000000..8b33ac0159 --- /dev/null +++ b/guilib/SkinInfo.cpp @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2005-2008 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "SkinInfo.h" +#include "GUIWindowManager.h" +#include "GUISettings.h" +#include "FileSystem/File.h" +#include "FileSystem/SpecialProtocol.h" +#include "Key.h" +#include "Util.h" +#include "Settings.h" +#include "StringUtils.h" +#include "utils/log.h" +#include "tinyXML/tinyxml.h" + +using namespace std; +using namespace XFILE; + +#define SKIN_MIN_VERSION 2.1f + +CSkinInfo g_SkinInfo; // global + +CSkinInfo::CSkinInfo() +{ + m_DefaultResolution = RES_INVALID; + m_DefaultResolutionWide = RES_INVALID; + m_strBaseDir = ""; + m_iNumCreditLines = 0; + m_effectsSlowDown = 1.0; + m_onlyAnimateToHome = true; + m_Version = 1.0; + m_skinzoom = 1.0f; +} + +CSkinInfo::~CSkinInfo() +{} + +void CSkinInfo::Load(const CStdString& strSkinDir) +{ + m_strBaseDir = strSkinDir; + m_DefaultResolution = RES_INVALID; // set to INVALID to denote that there is no default res here + m_DefaultResolutionWide = RES_INVALID; + m_effectsSlowDown = 1.0; + // Load from skin.xml + TiXmlDocument xmlDoc; + CStdString strFile = m_strBaseDir + "\\skin.xml"; + if (xmlDoc.LoadFile(strFile)) + { // ok - get the default skin folder out of it... + TiXmlElement* pRootElement = xmlDoc.RootElement(); + CStdString strValue = pRootElement->Value(); + if (strValue != "skin") + { + CLog::Log(LOGERROR, "file :%s doesnt contain <skin>", strFile.c_str()); + } + else + { // get the default resolution + TiXmlNode *pChild = pRootElement->FirstChild("defaultresolution"); + if (pChild) + { // found the defaultresolution tag + CStdString strDefaultDir = pChild->FirstChild()->Value(); + strDefaultDir = strDefaultDir.ToLower(); + if (strDefaultDir == "pal") m_DefaultResolution = RES_PAL_4x3; + else if (strDefaultDir == "pal16x9") m_DefaultResolution = RES_PAL_16x9; + else if (strDefaultDir == "ntsc") m_DefaultResolution = RES_NTSC_4x3; + else if (strDefaultDir == "ntsc16x9") m_DefaultResolution = RES_NTSC_16x9; + else if (strDefaultDir == "720p") m_DefaultResolution = RES_HDTV_720p; + else if (strDefaultDir == "1080i") m_DefaultResolution = RES_HDTV_1080i; + } + CLog::Log(LOGINFO, "Default 4:3 resolution directory is %s", CUtil::AddFileToFolder(m_strBaseDir, GetDirFromRes(m_DefaultResolution)).c_str()); + + pChild = pRootElement->FirstChild("defaultresolutionwide"); + if (pChild && pChild->FirstChild()) + { // found the defaultresolution tag + CStdString strDefaultDir = pChild->FirstChild()->Value(); + strDefaultDir = strDefaultDir.ToLower(); + if (strDefaultDir == "pal") m_DefaultResolutionWide = RES_PAL_4x3; + else if (strDefaultDir == "pal16x9") m_DefaultResolutionWide = RES_PAL_16x9; + else if (strDefaultDir == "ntsc") m_DefaultResolutionWide = RES_NTSC_4x3; + else if (strDefaultDir == "ntsc16x9") m_DefaultResolutionWide = RES_NTSC_16x9; + else if (strDefaultDir == "720p") m_DefaultResolutionWide = RES_HDTV_720p; + else if (strDefaultDir == "1080i") m_DefaultResolutionWide = RES_HDTV_1080i; + } + else + m_DefaultResolutionWide = m_DefaultResolution; // default to same as 4:3 + CLog::Log(LOGINFO, "Default 16:9 resolution directory is %s", CUtil::AddFileToFolder(m_strBaseDir, GetDirFromRes(m_DefaultResolutionWide)).c_str()); + + // get the version + pChild = pRootElement->FirstChild("version"); + if (pChild && pChild->FirstChild()) + { + m_Version = StringUtils::GetFloat(pChild->FirstChild()->Value()); + CLog::Log(LOGINFO, "Skin version is: %s", pChild->FirstChild()->Value()); + } + + // get the effects slowdown parameter + pChild = pRootElement->FirstChild("effectslowdown"); + if (pChild && pChild->FirstChild()) + m_effectsSlowDown = StringUtils::GetFloat(pChild->FirstChild()->Value()); + + // now load the credits information + pChild = pRootElement->FirstChild("credits"); + if (pChild) + { // ok, run through the credits + TiXmlNode *pGrandChild = pChild->FirstChild("skinname"); + if (pGrandChild && pGrandChild->FirstChild()) + { + CStdString strName = pGrandChild->FirstChild()->Value(); +#ifndef _LINUX + swprintf(credits[0], L"%S Skin", strName.Left(44).c_str()); +#else + swprintf(credits[0], CREDIT_LINE_LENGTH - 1, L"%s Skin", strName.Left(44).c_str()); +#endif + } + pGrandChild = pChild->FirstChild("name"); + m_iNumCreditLines = 1; + while (pGrandChild && pGrandChild->FirstChild() && m_iNumCreditLines < 6) + { + CStdString strName = pGrandChild->FirstChild()->Value(); +#ifndef _LINUX + swprintf(credits[m_iNumCreditLines], L"%S", strName.Left(49).c_str()); +#else + swprintf(credits[m_iNumCreditLines], CREDIT_LINE_LENGTH - 1, L"%s", strName.Left(49).c_str()); +#endif + m_iNumCreditLines++; + pGrandChild = pGrandChild->NextSibling("name"); + } + } + + // get the skin zoom parameter. it's how much skin should be enlarged to get rid of overscan + pChild = pRootElement->FirstChild("zoom"); + if (pChild && pChild->FirstChild()) + m_skinzoom = StringUtils::GetFloat(pChild->FirstChild()->Value()); + else + m_skinzoom = 1.0f; + + // now load the startupwindow information + LoadStartupWindows(pRootElement->FirstChildElement("startupwindows")); + } + } + // Load the skin includes + LoadIncludes(); +} + +bool CSkinInfo::Check(const CStdString& strSkinDir) +{ + bool bVersionOK = false; + // Load from skin.xml + TiXmlDocument xmlDoc; + CStdString strFile = CUtil::AddFileToFolder(strSkinDir, "skin.xml"); + CStdString strGoodPath = strSkinDir; + if (xmlDoc.LoadFile(strFile)) + { // ok - get the default res folder out of it... + TiXmlElement* pRootElement = xmlDoc.RootElement(); + CStdString strValue = pRootElement->Value(); + if (strValue == "skin") + { // get the default resolution + TiXmlNode *pChild = pRootElement->FirstChild("defaultresolution"); + if (pChild) + { // found the defaultresolution tag +#ifndef _LINUX + strGoodPath += "\\"; +#else + strGoodPath += "/"; +#endif + CStdString resolution = pChild->FirstChild()->Value(); + if (resolution == "pal") resolution = "PAL"; + else if (resolution == "pal16x9") resolution = "PAL16x9"; + else if (resolution == "ntsc") resolution = "NTSC"; + else if (resolution == "ntsc16x9") resolution = "NTSC16x9"; + strGoodPath = CUtil::AddFileToFolder(strGoodPath, resolution); + } + // get the version + pChild = pRootElement->FirstChild("version"); + if (pChild) + { + float parsedVersion; + parsedVersion = StringUtils::GetFloat(pChild->FirstChild()->Value()); + bVersionOK = parsedVersion >= SKIN_MIN_VERSION; + + CLog::Log(LOGINFO, "Skin version is: %s (%f)", pChild->FirstChild()->Value(), parsedVersion); + } + } + } + // Check to see if we have a good path + CStdString strFontXML = CUtil::AddFileToFolder(strGoodPath, "Font.xml"); + CStdString strHomeXML = CUtil::AddFileToFolder(strGoodPath, "Home.xml"); + if ( CFile::Exists(strFontXML) && + CFile::Exists(strHomeXML) && bVersionOK ) + { + return true; + } + return false; +} + +CStdString CSkinInfo::GetSkinPath(const CStdString& strFile, RESOLUTION *res, const CStdString& strBaseDir /* = "" */) +{ + CStdString strPathToUse = m_strBaseDir; + if (!strBaseDir.IsEmpty()) + strPathToUse = strBaseDir; + // first try and load from the current resolution's directory + int height=0; + *res = g_graphicsContext.GetVideoResolution(); + if (*res >= RES_WINDOW) + { + height = g_settings.m_ResInfo[*res].iHeight; + if (height>=1080 && (g_settings.m_ResInfo[*res].dwFlags & D3DPRESENTFLAG_WIDESCREEN)) + { + *res = RES_HDTV_1080i; + } + else if (height>=720 && (g_settings.m_ResInfo[*res].dwFlags & D3DPRESENTFLAG_WIDESCREEN)) + { + *res = RES_HDTV_720p; + } + else if (g_settings.m_ResInfo[*res].dwFlags & D3DPRESENTFLAG_WIDESCREEN) + { + *res = RES_PAL_16x9; + } + else + { + *res = RES_PAL_4x3; + } + } + CStdString strPath = CUtil::AddFileToFolder(strPathToUse, GetDirFromRes(*res)); + strPath = CUtil::AddFileToFolder(strPath, strFile); + if (CFile::Exists(strPath)) + return strPath; + // if we're in 1080i mode, try 720p next + if (*res == RES_HDTV_1080i) + { + *res = RES_HDTV_720p; + strPath = CUtil::AddFileToFolder(strPathToUse, GetDirFromRes(*res)); + strPath = CUtil::AddFileToFolder(strPath, strFile); + if (CFile::Exists(strPath)) + return strPath; + } + // that failed - drop to the default widescreen resolution if where in a widemode + if (*res == RES_PAL_16x9 || *res == RES_NTSC_16x9 || *res == RES_HDTV_480p_16x9 || *res == RES_HDTV_720p) + { + *res = m_DefaultResolutionWide; + strPath = CUtil::AddFileToFolder(strPathToUse, GetDirFromRes(*res)); + strPath = CUtil::AddFileToFolder(strPath, strFile); + if (CFile::Exists(strPath)) + return strPath; + } + // that failed - drop to the default resolution + *res = m_DefaultResolution; + strPath = CUtil::AddFileToFolder(strPathToUse, GetDirFromRes(*res)); + strPath = CUtil::AddFileToFolder(strPath, strFile); + // check if we don't have any subdirectories + if (*res == RES_INVALID) *res = RES_PAL_4x3; + return strPath; +} + +bool CSkinInfo::HasSkinFile(const CStdString &strFile) +{ + RESOLUTION res = RES_INVALID; + return CFile::Exists(GetSkinPath(strFile, &res)); +} + +CStdString CSkinInfo::GetDirFromRes(RESOLUTION res) +{ + CStdString strRes; + switch (res) + { + case RES_PAL_4x3: + strRes = "PAL"; + break; + case RES_PAL_16x9: + strRes = "PAL16x9"; + break; + case RES_NTSC_4x3: + case RES_HDTV_480p_4x3: + strRes = "NTSC"; + break; + case RES_NTSC_16x9: + case RES_HDTV_480p_16x9: + strRes = "ntsc16x9"; + break; + case RES_HDTV_720p: + strRes = "720p"; + break; + case RES_HDTV_1080i: + strRes = "1080i"; + break; + case RES_INVALID: + default: + strRes = ""; + break; + } + return strRes; +} + +CStdString CSkinInfo::GetBaseDir() +{ + return m_strBaseDir; +} + +wchar_t* CSkinInfo::GetCreditsLine(int i) +{ + if (i < m_iNumCreditLines) + return credits[i]; + else + return NULL; +} + +double CSkinInfo::GetMinVersion() +{ + return SKIN_MIN_VERSION; +} + +void CSkinInfo::LoadIncludes() +{ + RESOLUTION res; + CStdString includesPath = PTH_IC(GetSkinPath("includes.xml", &res)); + CLog::Log(LOGINFO, "Loading skin includes from %s", includesPath.c_str()); + m_includes.ClearIncludes(); + m_includes.LoadIncludes(includesPath); +} + +void CSkinInfo::ResolveIncludes(TiXmlElement *node, const CStdString &type) +{ + m_includes.ResolveIncludes(node, type); +} + +bool CSkinInfo::ResolveConstant(const CStdString &constant, float &value) +{ + return m_includes.ResolveConstant(constant, value); +} + +bool CSkinInfo::ResolveConstant(const CStdString &constant, DWORD &value) +{ + float fValue; + if (m_includes.ResolveConstant(constant, fValue)) + { + value = (DWORD)fValue; + return true; + } + return false; +} + +int CSkinInfo::GetStartWindow() +{ + int windowID = g_guiSettings.GetInt("lookandfeel.startupwindow"); + assert(m_startupWindows.size()); + for (vector<CStartupWindow>::iterator it = m_startupWindows.begin(); it != m_startupWindows.end(); it++) + { + if (windowID == (*it).m_id) + return windowID; + } + // return our first one + return m_startupWindows[0].m_id; +} + +bool CSkinInfo::LoadStartupWindows(const TiXmlElement *startup) +{ + m_startupWindows.clear(); + if (startup) + { // yay, run through and grab the startup windows + const TiXmlElement *window = startup->FirstChildElement("window"); + while (window && window->FirstChild()) + { + int id; + window->Attribute("id", &id); + CStdString name = window->FirstChild()->Value(); + m_startupWindows.push_back(CStartupWindow(id + WINDOW_HOME, name)); + window = window->NextSiblingElement("window"); + } + } + + // ok, now see if we have any startup windows + if (!m_startupWindows.size()) + { // nope - add the default ones + m_startupWindows.push_back(CStartupWindow(WINDOW_HOME, "513")); + m_startupWindows.push_back(CStartupWindow(WINDOW_PROGRAMS, "0")); + m_startupWindows.push_back(CStartupWindow(WINDOW_PICTURES, "1")); + m_startupWindows.push_back(CStartupWindow(WINDOW_MUSIC, "2")); + m_startupWindows.push_back(CStartupWindow(WINDOW_VIDEOS, "3")); + m_startupWindows.push_back(CStartupWindow(WINDOW_FILES, "7")); + m_startupWindows.push_back(CStartupWindow(WINDOW_SETTINGS_MENU, "5")); + m_startupWindows.push_back(CStartupWindow(WINDOW_SCRIPTS, "247")); + m_onlyAnimateToHome = true; + } + else + m_onlyAnimateToHome = false; + return true; +} +void CSkinInfo::SetDefaults() +{ + m_DefaultResolution = RES_PAL_4x3; + m_DefaultResolutionWide = RES_PAL_16x9; +} |